diff --git a/packages/cli/src/config/schema.ts b/packages/cli/src/config/schema.ts index 0b48753001..e99cdf4908 100644 --- a/packages/cli/src/config/schema.ts +++ b/packages/cli/src/config/schema.ts @@ -1232,15 +1232,6 @@ export const schema = { env: 'N8N_DEFAULT_LOCALE', }, - onboardingCallPrompt: { - enabled: { - doc: 'Whether onboarding call prompt feature is available', - format: Boolean, - default: true, - env: 'N8N_ONBOARDING_CALL_PROMPTS_ENABLED', - }, - }, - license: { serverUrl: { format: String, diff --git a/packages/cli/src/services/frontend.service.ts b/packages/cli/src/services/frontend.service.ts index f977d1e0b2..260fde5f52 100644 --- a/packages/cli/src/services/frontend.service.ts +++ b/packages/cli/src/services/frontend.service.ts @@ -163,7 +163,6 @@ export class FrontendService { enabled: config.getEnv('templates.enabled'), host: config.getEnv('templates.host'), }, - onboardingCallPromptEnabled: config.getEnv('onboardingCallPrompt.enabled'), executionMode: config.getEnv('executions.mode'), pushBackend: config.getEnv('push.backend'), communityNodesEnabled: config.getEnv('nodes.communityPackages.enabled'), diff --git a/packages/editor-ui/src/Interface.ts b/packages/editor-ui/src/Interface.ts index 51bca44e14..cc2db3e999 100644 --- a/packages/editor-ui/src/Interface.ts +++ b/packages/editor-ui/src/Interface.ts @@ -1332,7 +1332,6 @@ export interface ISettingsState { mfa: { enabled: boolean; }; - onboardingCallPromptEnabled: boolean; saveDataErrorExecution: WorkflowSettings.SaveDataExecution; saveDataSuccessExecution: WorkflowSettings.SaveDataExecution; saveManualExecutions: boolean; @@ -1428,16 +1427,6 @@ export interface IInviteResponse { error?: string; } -export interface IOnboardingCallPromptResponse { - nextPrompt: IOnboardingCallPrompt; -} - -export interface IOnboardingCallPrompt { - title: string; - description: string; - toast_sequence_number: number; -} - export interface ITab { value: string | number; label?: string; diff --git a/packages/editor-ui/src/__tests__/defaults.ts b/packages/editor-ui/src/__tests__/defaults.ts index 950409d78a..2a1d029155 100644 --- a/packages/editor-ui/src/__tests__/defaults.ts +++ b/packages/editor-ui/src/__tests__/defaults.ts @@ -51,7 +51,6 @@ export const defaultSettings: IN8nUISettings = { logLevel: 'info', maxExecutionTimeout: 0, oauthCallbackUrls: { oauth1: '', oauth2: '' }, - onboardingCallPromptEnabled: false, personalizationSurveyEnabled: false, releaseChannel: 'stable', posthog: { diff --git a/packages/editor-ui/src/__tests__/utils.ts b/packages/editor-ui/src/__tests__/utils.ts index 4e94ec57f4..8090227ee5 100644 --- a/packages/editor-ui/src/__tests__/utils.ts +++ b/packages/editor-ui/src/__tests__/utils.ts @@ -65,7 +65,6 @@ export const SETTINGS_STORE_DEFAULT_STATE: ISettingsState = { mfa: { enabled: false, }, - onboardingCallPromptEnabled: false, saveDataErrorExecution: 'all', saveDataSuccessExecution: 'all', saveDataProgressExecution: false, diff --git a/packages/editor-ui/src/api/workflow-webhooks.ts b/packages/editor-ui/src/api/workflow-webhooks.ts index a84de1c922..c90ca0964a 100644 --- a/packages/editor-ui/src/api/workflow-webhooks.ts +++ b/packages/editor-ui/src/api/workflow-webhooks.ts @@ -1,40 +1,9 @@ -import type { IOnboardingCallPrompt, IUser } from '@/Interface'; -import { get, post } from '@/utils/apiUtils'; -import { isUserGlobalOwner } from '@/utils/userUtils'; +import type { IUser } from '@/Interface'; +import { post } from '@/utils/apiUtils'; const N8N_API_BASE_URL = 'https://api.n8n.io/api'; -const ONBOARDING_PROMPTS_ENDPOINT = '/prompts/onboarding'; const CONTACT_EMAIL_SUBMISSION_ENDPOINT = '/accounts/onboarding'; -export async function fetchNextOnboardingPrompt( - instanceId: string, - currentUser: IUser, -): Promise { - return await get(N8N_API_BASE_URL, ONBOARDING_PROMPTS_ENDPOINT, { - instance_id: instanceId, - user_id: `${instanceId}#${currentUser.id}`, - is_owner: isUserGlobalOwner(currentUser), - survey_results: currentUser.personalizationAnswers, - }); -} - -export async function applyForOnboardingCall( - instanceId: string, - currentUser: IUser, - email: string, -): Promise { - try { - const response = await post(N8N_API_BASE_URL, ONBOARDING_PROMPTS_ENDPOINT, { - instance_id: instanceId, - user_id: `${instanceId}#${currentUser.id}`, - email, - }); - return response; - } catch (e) { - throw e; - } -} - export async function submitEmailOnSignup( instanceId: string, currentUser: IUser, diff --git a/packages/editor-ui/src/components/Modals.vue b/packages/editor-ui/src/components/Modals.vue index 8acf73be79..5fe424edb8 100644 --- a/packages/editor-ui/src/components/Modals.vue +++ b/packages/editor-ui/src/components/Modals.vue @@ -11,7 +11,6 @@ import { DELETE_USER_MODAL_KEY, DUPLICATE_MODAL_KEY, INVITE_USER_MODAL_KEY, - ONBOARDING_CALL_SIGNUP_MODAL_KEY, PERSONALIZATION_MODAL_KEY, TAGS_MANAGER_MODAL_KEY, NPS_SURVEY_MODAL_KEY, @@ -44,7 +43,6 @@ import InviteUsersModal from '@/components/InviteUsersModal.vue'; import CredentialsSelectModal from '@/components/CredentialsSelectModal.vue'; import DuplicateWorkflowDialog from '@/components/DuplicateWorkflowDialog.vue'; import ModalRoot from '@/components/ModalRoot.vue'; -import OnboardingCallSignupModal from '@/components/OnboardingCallSignupModal.vue'; import PersonalizationModal from '@/components/PersonalizationModal.vue'; import TagsManager from '@/components/TagsManager/TagsManager.vue'; import UpdatesPanel from '@/components/UpdatesPanel.vue'; @@ -152,10 +150,6 @@ import ProjectMoveResourceConfirmModal from '@/components/Projects/ProjectMoveRe - - - - diff --git a/packages/editor-ui/src/components/OnboardingCallSignupModal.vue b/packages/editor-ui/src/components/OnboardingCallSignupModal.vue deleted file mode 100644 index f960cb6a34..0000000000 --- a/packages/editor-ui/src/components/OnboardingCallSignupModal.vue +++ /dev/null @@ -1,131 +0,0 @@ - - - - - diff --git a/packages/editor-ui/src/components/PersonalizationModal.vue b/packages/editor-ui/src/components/PersonalizationModal.vue index e53428d8cb..4e19f943da 100644 --- a/packages/editor-ui/src/components/PersonalizationModal.vue +++ b/packages/editor-ui/src/components/PersonalizationModal.vue @@ -90,9 +90,6 @@ import { PERSONAL_COMPANY_TYPE, COMPANY_INDUSTRY_EXTENDED_KEY, OTHER_COMPANY_INDUSTRY_EXTENDED_KEY, - ONBOARDING_PROMPT_TIMEBOX, - FIRST_ONBOARDING_PROMPT_TIMEOUT, - ONBOARDING_CALL_SIGNUP_MODAL_KEY, MARKETING_AUTOMATION_GOAL_KEY, MARKETING_AUTOMATION_LEAD_GENERATION_GOAL, MARKETING_AUTOMATION_CUSTOMER_COMMUNICATION, @@ -141,8 +138,7 @@ import { } from '@/constants'; import { useToast } from '@/composables/useToast'; import Modal from '@/components/Modal.vue'; -import type { IFormInputs, IPersonalizationLatestVersion, IUser } from '@/Interface'; -import { getAccountAge } from '@/utils/userUtils'; +import type { IFormInputs, IPersonalizationLatestVersion } from '@/Interface'; import type { GenericValue } from 'n8n-workflow'; import { useUIStore } from '@/stores/ui.store'; import { useSettingsStore } from '@/stores/settings.store'; @@ -715,8 +711,6 @@ export default defineComponent({ if (Object.keys(values).length === 0) { this.closeDialog(); } - - await this.fetchOnboardingPrompt(); } catch (e) { this.showError(e, 'Error while submitting results'); } @@ -755,40 +749,6 @@ export default defineComponent({ ); } }, - async fetchOnboardingPrompt() { - if ( - this.settingsStore.onboardingCallPromptEnabled && - getAccountAge(this.usersStore.currentUser || ({} as IUser)) <= ONBOARDING_PROMPT_TIMEBOX - ) { - const onboardingResponse = await this.uiStore.getNextOnboardingPrompt(); - - if (!onboardingResponse) { - return; - } - - const promptTimeout = - onboardingResponse.toast_sequence_number === 1 ? FIRST_ONBOARDING_PROMPT_TIMEOUT : 1000; - - setTimeout(async () => { - this.showToast({ - type: 'info', - title: onboardingResponse.title, - message: onboardingResponse.description, - duration: 0, - customClass: 'clickable', - closeOnClick: true, - onClick: () => { - this.$telemetry.track('user clicked onboarding toast', { - seq_num: onboardingResponse.toast_sequence_number, - title: onboardingResponse.title, - description: onboardingResponse.description, - }); - this.uiStore.openModal(ONBOARDING_CALL_SIGNUP_MODAL_KEY); - }, - }); - }, promptTimeout); - } - }, }, }); diff --git a/packages/editor-ui/src/constants.ts b/packages/editor-ui/src/constants.ts index 37374fecca..074b87a420 100644 --- a/packages/editor-ui/src/constants.ts +++ b/packages/editor-ui/src/constants.ts @@ -54,7 +54,6 @@ export const PERSONALIZATION_MODAL_KEY = 'personalization'; export const CONTACT_PROMPT_MODAL_KEY = 'contactPrompt'; export const NPS_SURVEY_MODAL_KEY = 'npsSurvey'; export const WORKFLOW_ACTIVE_MODAL_KEY = 'activation'; -export const ONBOARDING_CALL_SIGNUP_MODAL_KEY = 'onboardingCallSignup'; export const COMMUNITY_PACKAGE_INSTALL_MODAL_KEY = 'communityPackageInstall'; export const COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY = 'communityPackageManageConfirm'; export const IMPORT_CURL_MODAL_KEY = 'importCurl'; @@ -502,9 +501,6 @@ export const enum FAKE_DOOR_FEATURES { SSO = 'sso', } -export const ONBOARDING_PROMPT_TIMEBOX = 14; -export const FIRST_ONBOARDING_PROMPT_TIMEOUT = 300000; - export const TEST_PIN_DATA = [ { name: 'First item', diff --git a/packages/editor-ui/src/plugins/i18n/locales/en.json b/packages/editor-ui/src/plugins/i18n/locales/en.json index e395c50add..e4eae1e4e3 100644 --- a/packages/editor-ui/src/plugins/i18n/locales/en.json +++ b/packages/editor-ui/src/plugins/i18n/locales/en.json @@ -1293,17 +1293,6 @@ "nodeWebhooks.webhookUrls": "Webhook URLs", "nodeWebhooks.webhookUrls.formTrigger": "Form URLs", "nodeWebhooks.webhookUrls.chatTrigger": "Chat URL", - "onboardingCallSignupModal.title": "Your onboarding session", - "onboardingCallSignupModal.description": "Pop in your email and we'll send you some scheduling options", - "onboardingCallSignupModal.emailInput.placeholder": "Your work email", - "onboardingCallSignupModal.signupButton.label": "Submit", - "onboardingCallSignupModal.cancelButton.label": "Cancel", - "onboardingCallSignupModal.infoText.emailError": "This doesn't seem to be a valid email address", - "onboardingCallSignupSucess.title": "Check your email for the final step", - "onboardingCallSignupSucess.message": "You should receive a message from us shortly", - "onboardingCallSignupFailed.title": "Something went wrong", - "onboardingCallSignupFailed.message": "Your request could not be sent", - "onboardingCallSignupModal.confirmExit.title": "Are you sure?", "onboardingWorkflow.stickyContent": "## 👇 Get started faster \nLightning tour of the key concepts [4 min] \n\n[![n8n quickstart video](/static/quickstart_thumbnail.png#full-width)](https://www.youtube.com/watch?v=1MwSoB0gnM4)", "openWorkflow.workflowImportError": "Could not import workflow", "openWorkflow.workflowNotFoundError": "Could not find workflow", diff --git a/packages/editor-ui/src/stores/settings.store.ts b/packages/editor-ui/src/stores/settings.store.ts index 6e9ae2bbdb..c565c696fe 100644 --- a/packages/editor-ui/src/stores/settings.store.ts +++ b/packages/editor-ui/src/stores/settings.store.ts @@ -64,7 +64,6 @@ export const useSettingsStore = defineStore(STORES.SETTINGS, { mfa: { enabled: false, }, - onboardingCallPromptEnabled: false, saveDataErrorExecution: 'all', saveDataSuccessExecution: 'all', saveManualExecutions: false, @@ -265,7 +264,6 @@ export const useSettingsStore = defineStore(STORES.SETTINGS, { this.userManagement.showSetupOnFirstLoad = !!settings.userManagement.showSetupOnFirstLoad; } this.api = settings.publicApi; - this.onboardingCallPromptEnabled = settings.onboardingCallPromptEnabled; if (settings.sso?.ldap) { this.ldap.loginEnabled = settings.sso.ldap.loginEnabled; this.ldap.loginLabel = settings.sso.ldap.loginLabel; diff --git a/packages/editor-ui/src/stores/ui.store.ts b/packages/editor-ui/src/stores/ui.store.ts index 1f4ed1b7c0..3d6d8002c6 100644 --- a/packages/editor-ui/src/stores/ui.store.ts +++ b/packages/editor-ui/src/stores/ui.store.ts @@ -16,7 +16,6 @@ import { INVITE_USER_MODAL_KEY, LOG_STREAM_MODAL_KEY, MFA_SETUP_MODAL_KEY, - ONBOARDING_CALL_SIGNUP_MODAL_KEY, PERSONALIZATION_MODAL_KEY, STORES, TAGS_MANAGER_MODAL_KEY, @@ -103,7 +102,6 @@ export const useUIStore = defineStore(STORES.UI, () => { CONTACT_PROMPT_MODAL_KEY, CREDENTIAL_SELECT_MODAL_KEY, DUPLICATE_MODAL_KEY, - ONBOARDING_CALL_SIGNUP_MODAL_KEY, PERSONALIZATION_MODAL_KEY, INVITE_USER_MODAL_KEY, TAGS_MANAGER_MODAL_KEY, @@ -453,24 +451,6 @@ export const useUIStore = defineStore(STORES.UI, () => { openModal(CREDENTIAL_EDIT_MODAL_KEY); }; - const getNextOnboardingPrompt = async () => { - const instanceId = rootStore.instanceId; - const { currentUser } = userStore; - if (currentUser) { - return await onboardingApi.fetchNextOnboardingPrompt(instanceId, currentUser); - } - return null; - }; - - const applyForOnboardingCall = async (email: string) => { - const instanceId = rootStore.instanceId; - const { currentUser } = userStore; - if (currentUser) { - return await onboardingApi.applyForOnboardingCall(instanceId, currentUser, email); - } - return null; - }; - const submitContactEmail = async (email: string, agree: boolean) => { const instanceId = rootStore.instanceId; const { currentUser } = userStore; @@ -668,8 +648,6 @@ export const useUIStore = defineStore(STORES.UI, () => { openDeleteUserModal, openExistingCredential, openNewCredential, - getNextOnboardingPrompt, - applyForOnboardingCall, submitContactEmail, openCommunityPackageUninstallConfirmModal, openCommunityPackageUpdateConfirmModal, diff --git a/packages/editor-ui/src/utils/userUtils.ts b/packages/editor-ui/src/utils/userUtils.ts index a3925b7534..3d8aa21637 100644 --- a/packages/editor-ui/src/utils/userUtils.ts +++ b/packages/editor-ui/src/utils/userUtils.ts @@ -110,16 +110,6 @@ export function getPersonalizedNodeTypes( return getPersonalizationSurveyV1(answers); } -export function getAccountAge(currentUser: IUser): number { - if (currentUser.createdAt) { - const accountCreatedAt = new Date(currentUser.createdAt); - const today = new Date(); - - return Math.ceil((today.getTime() - accountCreatedAt.getTime()) / (1000 * 3600 * 24)); - } - return -1; -} - function getPersonalizationSurveyV2OrLater( answers: | IPersonalizationSurveyAnswersV2 diff --git a/packages/editor-ui/src/views/NodeView.vue b/packages/editor-ui/src/views/NodeView.vue index e1b04f692e..ca40d6cf4c 100644 --- a/packages/editor-ui/src/views/NodeView.vue +++ b/packages/editor-ui/src/views/NodeView.vue @@ -222,12 +222,9 @@ import { import type { NotificationHandle } from 'element-plus'; import { - FIRST_ONBOARDING_PROMPT_TIMEOUT, MAIN_HEADER_TABS, MODAL_CANCEL, MODAL_CONFIRM, - ONBOARDING_CALL_SIGNUP_MODAL_KEY, - ONBOARDING_PROMPT_TIMEBOX, PLACEHOLDER_EMPTY_WORKFLOW_ID, QUICKSTART_NOTE_NAME, START_NODE_TYPE, @@ -332,7 +329,6 @@ import { useUsersStore } from '@/stores/users.store'; import { useWorkflowsEEStore } from '@/stores/workflows.ee.store'; import { useWorkflowsStore } from '@/stores/workflows.store'; import * as NodeViewUtils from '@/utils/nodeViewUtils'; -import { getAccountAge } from '@/utils/userUtils'; import { getConnectionInfo, getNodeViewTab } from '@/utils/canvasUtils'; import { AddConnectionCommand, @@ -891,38 +887,6 @@ export default defineComponent({ // TODO: This currently breaks since front-end hooks are still not updated to work with pinia store void this.externalHooks.run('nodeView.mount').catch(() => {}); - if ( - this.currentUser?.personalizationAnswers !== null && - this.settingsStore.onboardingCallPromptEnabled && - this.currentUser && - getAccountAge(this.currentUser) <= ONBOARDING_PROMPT_TIMEBOX - ) { - const onboardingResponse = await this.uiStore.getNextOnboardingPrompt(); - const promptTimeout = - onboardingResponse?.toast_sequence_number === 1 ? FIRST_ONBOARDING_PROMPT_TIMEOUT : 1000; - - if (onboardingResponse?.title && onboardingResponse?.description) { - setTimeout(async () => { - this.showToast({ - type: 'info', - title: onboardingResponse.title, - message: onboardingResponse.description, - duration: 0, - customClass: 'clickable', - closeOnClick: true, - onClick: () => { - this.$telemetry.track('user clicked onboarding toast', { - seq_num: onboardingResponse.toast_sequence_number, - title: onboardingResponse.title, - description: onboardingResponse.description, - }); - this.uiStore.openModal(ONBOARDING_CALL_SIGNUP_MODAL_KEY); - }, - }); - }, promptTimeout); - } - } - sourceControlEventBus.on('pull', this.onSourceControlPull); this.registerCustomAction({ diff --git a/packages/workflow/src/Interfaces.ts b/packages/workflow/src/Interfaces.ts index 68d7e6993b..f752905edb 100644 --- a/packages/workflow/src/Interfaces.ts +++ b/packages/workflow/src/Interfaces.ts @@ -2651,7 +2651,6 @@ export interface IN8nUISettings { enabled: boolean; host: string; }; - onboardingCallPromptEnabled: boolean; missingPackages?: boolean; executionMode: 'regular' | 'queue'; pushBackend: 'sse' | 'websocket';