feat(editor): Add more onboarding options experiment (no-changelog) (#10478)

This commit is contained in:
Milorad FIlipović 2024-08-21 10:37:02 +02:00 committed by GitHub
parent ee7bbbddf2
commit 03c19723d2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 82 additions and 26 deletions

View file

@ -282,7 +282,7 @@ export default defineComponent({
icon: 'graduation-cap',
label: this.$locale.baseText('mainSidebar.helpMenuItems.course'),
link: {
href: 'https://www.youtube.com/watch?v=1MwSoB0gnM4',
href: 'https://docs.n8n.io/courses/',
target: '_blank',
},
},

View file

@ -135,6 +135,7 @@ import {
REPORTED_SOURCE_OTHER,
REPORTED_SOURCE_OTHER_KEY,
VIEWS,
MORE_ONBOARDING_OPTIONS_EXPERIMENT,
} from '@/constants';
import { useToast } from '@/composables/useToast';
import Modal from '@/components/Modal.vue';
@ -674,9 +675,12 @@ export default defineComponent({
methods: {
closeDialog() {
this.modalBus.emit('close');
const isPartOfOnboardingExperiment =
this.posthogStore.getVariant(MORE_ONBOARDING_OPTIONS_EXPERIMENT.name) ===
MORE_ONBOARDING_OPTIONS_EXPERIMENT.control;
// In case the redirect to homepage for new users didn't happen
// we try again after closing the modal
if (this.$route.name !== VIEWS.HOMEPAGE) {
if (this.$route.name !== VIEWS.HOMEPAGE && !isPartOfOnboardingExperiment) {
void this.$router.replace({ name: VIEWS.HOMEPAGE });
}
},

View file

@ -680,11 +680,18 @@ export const AI_ASSISTANT_EXPERIMENT = {
variant: 'variant',
};
export const MORE_ONBOARDING_OPTIONS_EXPERIMENT = {
name: '022_more_onboarding_options',
control: 'control',
variant: 'variant',
};
export const EXPERIMENTS_TO_TRACK = [
ASK_AI_EXPERIMENT.name,
TEMPLATE_CREDENTIAL_SETUP_EXPERIMENT,
CANVAS_AUTO_ADD_MANUAL_TRIGGER_EXPERIMENT.name,
AI_ASSISTANT_EXPERIMENT.name,
MORE_ONBOARDING_OPTIONS_EXPERIMENT.name,
];
export const MFA_FORM = {

View file

@ -2202,7 +2202,8 @@
"workflows.empty.description.readOnlyEnv": "No workflows here yet",
"workflows.empty.description.noPermission": "There are currently no workflows to view",
"workflows.empty.startFromScratch": "Start from scratch",
"workflows.empty.browseTemplates": "Browse {category} templates",
"workflows.empty.browseTemplates": "Explore workflow templates",
"workflows.empty.learnN8n": "Learn n8n",
"workflows.empty.button.disabled.tooltip": "Your current role in the project does not allow you to create workflows",
"workflows.shareModal.title": "Share '{name}'",
"workflows.shareModal.title.static": "Shared with {projectName}",

View file

@ -13,11 +13,12 @@ import { defineComponent } from 'vue';
import { useToast } from '@/composables/useToast';
import type { IFormBoxConfig } from '@/Interface';
import { VIEWS } from '@/constants';
import { MORE_ONBOARDING_OPTIONS_EXPERIMENT, VIEWS } from '@/constants';
import { mapStores } from 'pinia';
import { useUIStore } from '@/stores/ui.store';
import { useSettingsStore } from '@/stores/settings.store';
import { useUsersStore } from '@/stores/users.store';
import { usePostHog } from '@/stores/posthog.store';
export default defineComponent({
name: 'SetupView',
@ -91,12 +92,15 @@ export default defineComponent({
};
},
computed: {
...mapStores(useSettingsStore, useUIStore, useUsersStore),
...mapStores(useSettingsStore, useUIStore, useUsersStore, usePostHog),
},
methods: {
async onSubmit(values: { [key: string]: string | boolean }) {
try {
const forceRedirectedHere = this.settingsStore.showSetupPage;
const isPartOfOnboardingExperiment =
this.posthogStore.getVariant(MORE_ONBOARDING_OPTIONS_EXPERIMENT.name) ===
MORE_ONBOARDING_OPTIONS_EXPERIMENT.variant;
this.loading = true;
await this.usersStore.createOwner(
values as { firstName: string; lastName: string; email: string; password: string },
@ -109,7 +113,11 @@ export default defineComponent({
}
if (forceRedirectedHere) {
await this.$router.push({ name: VIEWS.HOMEPAGE });
if (isPartOfOnboardingExperiment) {
await this.$router.push({ name: VIEWS.WORKFLOWS });
} else {
await this.$router.push({ name: VIEWS.NEW_WORKFLOW });
}
} else {
await this.$router.push({ name: VIEWS.USERS_SETTINGS });
}

View file

@ -61,29 +61,14 @@
: $locale.baseText('workflows.empty.heading.userNotSetup')
}}
</n8n-heading>
<n8n-text size="large" color="text-base">{{ emptyListDescription }}</n8n-text>
<n8n-text v-if="!isOnboardingExperimentEnabled" size="large" color="text-base">
{{ emptyListDescription }}
</n8n-text>
</div>
<div
v-if="!readOnlyEnv && projectPermissions.workflow.create"
:class="['text-center', 'mt-2xl', $style.actionsContainer]"
>
<a
v-if="isSalesUser"
:href="getTemplateRepositoryURL()"
:class="$style.emptyStateCard"
target="_blank"
>
<n8n-card
hoverable
data-test-id="browse-sales-templates-card"
@click="trackCategoryLinkClick('Sales')"
>
<n8n-icon :class="$style.emptyStateCardIcon" icon="box-open" />
<n8n-text size="large" class="mt-xs" color="text-base">
{{ $locale.baseText('workflows.empty.browseTemplates') }}
</n8n-text>
</n8n-card>
</a>
<n8n-card
:class="$style.emptyStateCard"
hoverable
@ -91,10 +76,44 @@
@click="addWorkflow"
>
<n8n-icon :class="$style.emptyStateCardIcon" icon="file" />
<n8n-text size="large" class="mt-xs" color="text-base">
<n8n-text size="large" class="mt-xs" color="text-dark">
{{ $locale.baseText('workflows.empty.startFromScratch') }}
</n8n-text>
</n8n-card>
<a
v-if="isSalesUser || isOnboardingExperimentEnabled"
href="https://docs.n8n.io/courses/#available-courses"
:class="$style.emptyStateCard"
target="_blank"
>
<n8n-card
hoverable
data-test-id="browse-sales-templates-card"
@click="trackEmptyCardClick('courses')"
>
<n8n-icon :class="$style.emptyStateCardIcon" icon="graduation-cap" />
<n8n-text size="large" class="mt-xs" color="text-dark">
{{ $locale.baseText('workflows.empty.learnN8n') }}
</n8n-text>
</n8n-card>
</a>
<a
v-if="isSalesUser || isOnboardingExperimentEnabled"
:href="getTemplateRepositoryURL()"
:class="$style.emptyStateCard"
target="_blank"
>
<n8n-card
hoverable
data-test-id="browse-sales-templates-card"
@click="trackEmptyCardClick('templates')"
>
<n8n-icon :class="$style.emptyStateCardIcon" icon="box-open" />
<n8n-text size="large" class="mt-xs" color="text-dark">
{{ $locale.baseText('workflows.empty.browseTemplates') }}
</n8n-text>
</n8n-card>
</a>
</div>
</template>
<template #filters="{ setKeyValue }">
@ -144,7 +163,7 @@
import { defineComponent } from 'vue';
import ResourcesListLayout, { type IResource } from '@/components/layouts/ResourcesListLayout.vue';
import WorkflowCard from '@/components/WorkflowCard.vue';
import { EnterpriseEditionFeature, VIEWS } from '@/constants';
import { EnterpriseEditionFeature, MORE_ONBOARDING_OPTIONS_EXPERIMENT, VIEWS } from '@/constants';
import type { ITag, IUser, IWorkflowDb } from '@/Interface';
import TagsDropdown from '@/components/TagsDropdown.vue';
import { mapStores } from 'pinia';
@ -158,6 +177,7 @@ import { useProjectsStore } from '@/stores/projects.store';
import ProjectTabs from '@/components/Projects/ProjectTabs.vue';
import { useTemplatesStore } from '@/stores/templates.store';
import { getResourcePermissions } from '@/permissions';
import { usePostHog } from '@/stores/posthog.store';
interface Filters {
search: string;
@ -202,6 +222,7 @@ const WorkflowsView = defineComponent({
useTagsStore,
useProjectsStore,
useTemplatesStore,
usePostHog,
),
readOnlyEnv(): boolean {
return this.sourceControlStore.preferences.branchReadOnly;
@ -245,6 +266,12 @@ const WorkflowsView = defineComponent({
return undefined;
},
isOnboardingExperimentEnabled() {
return (
this.posthogStore.getVariant(MORE_ONBOARDING_OPTIONS_EXPERIMENT.name) ===
MORE_ONBOARDING_OPTIONS_EXPERIMENT.variant
);
},
isSalesUser() {
if (!this.userRole) {
return false;
@ -312,10 +339,19 @@ const WorkflowsView = defineComponent({
this.$telemetry.track('User clicked add workflow button', {
source: 'Workflows list',
});
this.trackEmptyCardClick('blank');
},
getTemplateRepositoryURL() {
return this.templatesStore.websiteTemplateRepositoryURL;
},
trackEmptyCardClick(option: 'blank' | 'templates' | 'courses') {
this.$telemetry.track('User clicked empty page option', {
option,
});
if (option === 'templates' && this.isSalesUser) {
this.trackCategoryLinkClick('Sales');
}
},
trackCategoryLinkClick(category: string) {
this.$telemetry.track(`User clicked Browse ${category} Templates`, {
role: this.usersStore.currentUserCloudInfo?.role,