mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-23 10:32:17 -08:00
feat(editor): Add disable template experiment (#5963)
* Add remove templates experiments * Add track experiment without debouncing * Allow to go to templates route even when experiment is active * Add missing import * Fix linting issue * Remove unused constant * Add timeout to track "User is part of experiment" event * fix: split experiment evaluation from tracking * fix: fix overrides * chore: remove console --------- Co-authored-by: Mutasem <mutdmour@gmail.com>
This commit is contained in:
parent
b8cb5d7f0b
commit
a74284bac3
|
@ -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];
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
|
||||
|
|
|
@ -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<FeatureFlags | null> = ref(null);
|
||||
const trackedDemoExp: Ref<FeatureFlags> = 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];
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue