diff --git a/packages/editor-ui/src/constants.ts b/packages/editor-ui/src/constants.ts index 1c4aaef204473..f600da467ac3a 100644 --- a/packages/editor-ui/src/constants.ts +++ b/packages/editor-ui/src/constants.ts @@ -538,6 +538,12 @@ export const KEEP_AUTH_IN_NDV_FOR_NODES = [HTTP_REQUEST_NODE_TYPE, WEBHOOK_NODE_ export const MAIN_AUTH_FIELD_NAME = 'authentication'; export const NODE_RESOURCE_FIELD_NAME = 'resource'; -export const EXPERIMENTS_TO_TRACK = []; +export const TEMPLATE_EXPERIMENT = { + name: '002_remove_templates', + control: 'control', + variant: 'variant', +}; + +export const EXPERIMENTS_TO_TRACK = [TEMPLATE_EXPERIMENT.name]; export const NODE_TYPES_EXCLUDED_FROM_OUTPUT_NAME_APPEND = [FILTER_NODE_TYPE]; diff --git a/packages/editor-ui/src/router.ts b/packages/editor-ui/src/router.ts index dacfc5db92464..1fb6f0059a650 100644 --- a/packages/editor-ui/src/router.ts +++ b/packages/editor-ui/src/router.ts @@ -32,7 +32,7 @@ import VariablesView from '@/views/VariablesView.vue'; import { IPermissions } from './Interface'; import { LOGIN_STATUS, ROLE } from '@/utils'; import { RouteConfigSingleView } from 'vue-router/types/router'; -import { VIEWS } from './constants'; +import { TEMPLATE_EXPERIMENT, VIEWS } from './constants'; import { useSettingsStore } from './stores/settings'; import { useTemplatesStore } from './stores/templates'; import { useSSOStore } from './stores/sso'; @@ -41,6 +41,7 @@ import SettingsSso from './views/SettingsSso.vue'; import SignoutView from '@/views/SignoutView.vue'; import SamlOnboarding from '@/views/SamlOnboarding.vue'; import SettingsVersionControl from './views/SettingsVersionControl.vue'; +import { usePostHog } from './stores/posthog'; Vue.use(Router); @@ -60,8 +61,12 @@ interface IRouteConfig extends RouteConfigSingleView { function getTemplatesRedirect() { const settingsStore = useSettingsStore(); + const posthog = usePostHog(); const isTemplatesEnabled: boolean = settingsStore.isTemplatesEnabled; - if (!isTemplatesEnabled) { + if ( + !posthog.isVariantEnabled(TEMPLATE_EXPERIMENT.name, TEMPLATE_EXPERIMENT.variant) && + !isTemplatesEnabled + ) { return { name: VIEWS.NOT_FOUND }; } diff --git a/packages/editor-ui/src/stores/posthog.ts b/packages/editor-ui/src/stores/posthog.ts index 1076d0eb7b2f1..8c9d088b465a6 100644 --- a/packages/editor-ui/src/stores/posthog.ts +++ b/packages/editor-ui/src/stores/posthog.ts @@ -1,12 +1,15 @@ -import { ref, Ref, watch } from 'vue'; +import { ref, Ref } from 'vue'; import { defineStore } from 'pinia'; import { useUsersStore } from '@/stores/users'; import { useRootStore } from '@/stores/n8nRootStore'; import { useSettingsStore } from '@/stores/settings'; import { FeatureFlags } from 'n8n-workflow'; -import { EXPERIMENTS_TO_TRACK, LOCAL_STORAGE_EXPERIMENT_OVERRIDES } from '@/constants'; +import { + EXPERIMENTS_TO_TRACK, + LOCAL_STORAGE_EXPERIMENT_OVERRIDES, + TEMPLATE_EXPERIMENT, +} from '@/constants'; import { useTelemetryStore } from './telemetry'; -import { useSegment } from './segment'; import { debounce } from 'lodash-es'; const EVENTS = { @@ -18,7 +21,6 @@ export const usePostHog = defineStore('posthog', () => { const settingsStore = useSettingsStore(); const telemetryStore = useTelemetryStore(); const rootStore = useRootStore(); - const segmentStore = useSegment(); const featureFlags: Ref = ref(null); const trackedDemoExp: Ref = ref({}); @@ -44,8 +46,11 @@ export const usePostHog = defineStore('posthog', () => { const cachedOverrdies = localStorage.getItem(LOCAL_STORAGE_EXPERIMENT_OVERRIDES); if (cachedOverrdies) { try { + console.log('Overriding feature flags', cachedOverrdies); overrides.value = JSON.parse(cachedOverrdies); - } catch (e) {} + } catch (e) { + console.log('Could not override experiment', e); + } } window.featureFlags = { @@ -121,21 +126,38 @@ export const usePostHog = defineStore('posthog', () => { distinctId, featureFlags: evaluatedFeatureFlags, }; - trackExperiments(evaluatedFeatureFlags); + + // does not need to be debounced really, but tracking does not fire without delay on page load addExperimentOverrides(); + trackExperimentsDebounced(featureFlags.value); + evaluateExperiments(featureFlags.value); } else { // depend on client side evaluation if serverside evaluation fails window.posthog?.onFeatureFlags?.((keys: string[], map: FeatureFlags) => { featureFlags.value = map; addExperimentOverrides(); - trackExperiments(map); + + // must be debounced because it is called multiple times by posthog + trackExperimentsDebounced(featureFlags.value); + evaluateExperimentsDebounced(featureFlags.value); }); } }; - const trackExperiments = debounce((featureFlags: FeatureFlags) => { + const evaluateExperiments = (featureFlags: FeatureFlags) => { + Object.keys(featureFlags).forEach((name) => { + const variant = featureFlags[name]; + if (name === TEMPLATE_EXPERIMENT.name && variant === TEMPLATE_EXPERIMENT.variant) { + settingsStore.disableTemplates(); + } + }); + }; + const evaluateExperimentsDebounced = debounce(evaluateExperiments, 2000); + + const trackExperiments = (featureFlags: FeatureFlags) => { EXPERIMENTS_TO_TRACK.forEach((name) => trackExperiment(featureFlags, name)); - }, 2000); + }; + const trackExperimentsDebounced = debounce(trackExperiments, 2000); const trackExperiment = (featureFlags: FeatureFlags, name: string) => { const variant = featureFlags[name]; diff --git a/packages/editor-ui/src/stores/settings.ts b/packages/editor-ui/src/stores/settings.ts index c328e7a476930..24e48f5a1fbae 100644 --- a/packages/editor-ui/src/stores/settings.ts +++ b/packages/editor-ui/src/stores/settings.ts @@ -229,6 +229,9 @@ export const useSettingsStore = defineStore(STORES.SETTINGS, { stopShowingSetupPage(): void { Vue.set(this.userManagement, 'showSetupOnFirstLoad', false); }, + disableTemplates(): void { + Vue.set(this.settings.templates, 'enabled', false); + }, setPromptsData(promptsData: IN8nPrompts): void { Vue.set(this, 'promptsData', promptsData); }, diff --git a/packages/editor-ui/src/utils/nodeTypesUtils.ts b/packages/editor-ui/src/utils/nodeTypesUtils.ts index cd3515ead5070..2d07bf93e95e4 100644 --- a/packages/editor-ui/src/utils/nodeTypesUtils.ts +++ b/packages/editor-ui/src/utils/nodeTypesUtils.ts @@ -545,7 +545,6 @@ export const getCredentialsRelatedFields = ( credentialType.displayOptions.show ) { Object.keys(credentialType.displayOptions.show).forEach((option) => { - console.log(option); fields = fields.concat(nodeType.properties.filter((prop) => prop.name === option)); }); }