mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
feat: Redirect users without feature flag from template cred setup (no-changelog) (#8302)
This commit is contained in:
@@ -35,7 +35,7 @@ export const usePostHog = defineStore('posthog', () => {
|
||||
};
|
||||
|
||||
const getVariant = (experiment: keyof FeatureFlags): FeatureFlags[keyof FeatureFlags] => {
|
||||
return featureFlags.value?.[experiment];
|
||||
return overrides.value[experiment] ?? featureFlags.value?.[experiment];
|
||||
};
|
||||
|
||||
const isVariantEnabled = (experiment: string, variant: string) => {
|
||||
@@ -46,7 +46,7 @@ export const usePostHog = defineStore('posthog', () => {
|
||||
* Checks if the given feature flag is enabled. Should only be used for boolean flags
|
||||
*/
|
||||
const isFeatureEnabled = (experiment: keyof FeatureFlags) => {
|
||||
return featureFlags.value?.[experiment] === true;
|
||||
return getVariant(experiment) === true;
|
||||
};
|
||||
|
||||
if (!window.featureFlags) {
|
||||
@@ -55,7 +55,10 @@ export const usePostHog = defineStore('posthog', () => {
|
||||
if (cachedOverrides) {
|
||||
try {
|
||||
console.log('Overriding feature flags', cachedOverrides);
|
||||
overrides.value = JSON.parse(cachedOverrides);
|
||||
const parsedOverrides = JSON.parse(cachedOverrides);
|
||||
if (typeof parsedOverrides === 'object') {
|
||||
overrides.value = JSON.parse(cachedOverrides);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('Could not override experiment', e);
|
||||
}
|
||||
@@ -65,10 +68,6 @@ export const usePostHog = defineStore('posthog', () => {
|
||||
// since features are evaluated serverside, regular posthog mechanism to override clientside does not work
|
||||
override: (name: string, value: string | boolean) => {
|
||||
overrides.value[name] = value;
|
||||
featureFlags.value = {
|
||||
...featureFlags.value,
|
||||
[name]: value,
|
||||
};
|
||||
try {
|
||||
useStorage(LOCAL_STORAGE_EXPERIMENT_OVERRIDES).value = JSON.stringify(overrides.value);
|
||||
} catch (e) {}
|
||||
@@ -93,13 +92,6 @@ export const usePostHog = defineStore('posthog', () => {
|
||||
window.posthog?.identify?.(id, traits);
|
||||
};
|
||||
|
||||
const addExperimentOverrides = () => {
|
||||
featureFlags.value = {
|
||||
...featureFlags.value,
|
||||
...overrides.value,
|
||||
};
|
||||
};
|
||||
|
||||
const trackExperiment = (featFlags: FeatureFlags, name: string) => {
|
||||
const variant = featFlags[name];
|
||||
if (!variant || trackedDemoExp.value[name] === variant) {
|
||||
@@ -160,13 +152,11 @@ export const usePostHog = defineStore('posthog', () => {
|
||||
};
|
||||
|
||||
// does not need to be debounced really, but tracking does not fire without delay on page load
|
||||
addExperimentOverrides();
|
||||
trackExperimentsDebounced(featureFlags.value);
|
||||
} else {
|
||||
// depend on client side evaluation if serverside evaluation fails
|
||||
window.posthog?.onFeatureFlags?.((keys: string[], map: FeatureFlags) => {
|
||||
featureFlags.value = map;
|
||||
addExperimentOverrides();
|
||||
|
||||
// must be debounced because it is called multiple times by posthog
|
||||
trackExperimentsDebounced(featureFlags.value);
|
||||
|
||||
@@ -67,6 +67,7 @@ describe('templateActions', () => {
|
||||
templateId,
|
||||
templatesStore,
|
||||
router,
|
||||
source: 'workflow',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -76,18 +77,6 @@ describe('templateActions', () => {
|
||||
params: { id: templateId },
|
||||
});
|
||||
});
|
||||
|
||||
it("should track 'User inserted workflow template'", async () => {
|
||||
expect(telemetry.track).toHaveBeenCalledWith(
|
||||
'User inserted workflow template',
|
||||
{
|
||||
source: 'workflow',
|
||||
template_id: templateId,
|
||||
wf_template_repo_session_id: '',
|
||||
},
|
||||
{ withPostHog: true },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When feature flag is enabled and template has nodes requiring credentials', () => {
|
||||
@@ -111,6 +100,7 @@ describe('templateActions', () => {
|
||||
templateId,
|
||||
templatesStore,
|
||||
router,
|
||||
source: 'workflow',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -144,6 +134,7 @@ describe('templateActions', () => {
|
||||
templateId,
|
||||
templatesStore,
|
||||
router,
|
||||
source: 'workflow',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -98,9 +98,8 @@ async function openTemplateWorkflowOnNodeView(opts: {
|
||||
templatesStore: TemplatesStore;
|
||||
router: Router;
|
||||
inNewBrowserTab?: boolean;
|
||||
telemetry: Telemetry;
|
||||
}) {
|
||||
const { externalHooks, templateId, templatesStore, telemetry, inNewBrowserTab, router } = opts;
|
||||
const { externalHooks, templateId, templatesStore, inNewBrowserTab, router } = opts;
|
||||
const routeLocation: RouteLocationRaw = {
|
||||
name: VIEWS.TEMPLATE_IMPORT,
|
||||
params: { id: templateId },
|
||||
@@ -111,9 +110,6 @@ async function openTemplateWorkflowOnNodeView(opts: {
|
||||
wf_template_repo_session_id: templatesStore.currentSessionId,
|
||||
};
|
||||
|
||||
telemetry.track('User inserted workflow template', telemetryPayload, {
|
||||
withPostHog: true,
|
||||
});
|
||||
await externalHooks.run('templatesWorkflowView.openWorkflow', telemetryPayload);
|
||||
|
||||
if (inNewBrowserTab) {
|
||||
|
||||
@@ -1308,6 +1308,18 @@ export default defineComponent({
|
||||
return;
|
||||
}
|
||||
|
||||
this.$telemetry.track(
|
||||
'User inserted workflow template',
|
||||
{
|
||||
source: 'workflow',
|
||||
template_id: templateId,
|
||||
wf_template_repo_session_id: this.templatesStore.previousSessionId,
|
||||
},
|
||||
{
|
||||
withPostHog: true,
|
||||
},
|
||||
);
|
||||
|
||||
this.blankRedirect = true;
|
||||
await this.$router.replace({ name: VIEWS.NEW_WORKFLOW, query: { templateId } });
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, watch } from 'vue';
|
||||
import { computed, onBeforeMount, onMounted, watch } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { useSetupTemplateStore } from './setupTemplate.store';
|
||||
import N8nHeading from 'n8n-design-system/components/N8nHeading';
|
||||
@@ -7,14 +7,14 @@ import N8nLink from 'n8n-design-system/components/N8nLink';
|
||||
import AppsRequiringCredsNotice from './AppsRequiringCredsNotice.vue';
|
||||
import SetupTemplateFormStep from './SetupTemplateFormStep.vue';
|
||||
import TemplatesView from '../TemplatesView.vue';
|
||||
import { VIEWS } from '@/constants';
|
||||
import { TEMPLATE_CREDENTIAL_SETUP_EXPERIMENT, VIEWS } from '@/constants';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import { usePostHog } from '@/stores/posthog.store';
|
||||
|
||||
// Store
|
||||
const setupTemplateStore = useSetupTemplateStore();
|
||||
const i18n = useI18n();
|
||||
const telemetry = useTelemetry();
|
||||
const posthogStore = usePostHog();
|
||||
|
||||
// Router
|
||||
const route = useRoute();
|
||||
@@ -79,6 +79,15 @@ const skipIfTemplateHasNoCreds = async () => {
|
||||
|
||||
setupTemplateStore.setTemplateId(templateId.value);
|
||||
|
||||
onBeforeMount(async () => {
|
||||
if (!posthogStore.isFeatureEnabled(TEMPLATE_CREDENTIAL_SETUP_EXPERIMENT)) {
|
||||
void router.replace({
|
||||
name: VIEWS.TEMPLATE_IMPORT,
|
||||
params: { id: templateId.value },
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
await setupTemplateStore.init();
|
||||
await skipIfTemplateHasNoCreds();
|
||||
|
||||
@@ -153,16 +153,6 @@ export const useSetupTemplateStore = defineStore('setupTemplate', () => {
|
||||
wf_template_repo_session_id: templatesStore.currentSessionId,
|
||||
});
|
||||
|
||||
telemetry.track(
|
||||
'User inserted workflow template',
|
||||
{
|
||||
source: 'workflow',
|
||||
template_id: templateId.value,
|
||||
wf_template_repo_session_id: templatesStore.currentSessionId,
|
||||
},
|
||||
{ withPostHog: true },
|
||||
);
|
||||
|
||||
telemetry.track('User closed cred setup', {
|
||||
completed: false,
|
||||
creds_filled: 0,
|
||||
|
||||
Reference in New Issue
Block a user