mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 20:24:05 -08:00
refactor(core): Remove Onboarding call prompts (no-changelog) (#9933)
This commit is contained in:
parent
31163e1da5
commit
9e92a5774e
|
@ -1232,15 +1232,6 @@ export const schema = {
|
||||||
env: 'N8N_DEFAULT_LOCALE',
|
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: {
|
license: {
|
||||||
serverUrl: {
|
serverUrl: {
|
||||||
format: String,
|
format: String,
|
||||||
|
|
|
@ -163,7 +163,6 @@ export class FrontendService {
|
||||||
enabled: config.getEnv('templates.enabled'),
|
enabled: config.getEnv('templates.enabled'),
|
||||||
host: config.getEnv('templates.host'),
|
host: config.getEnv('templates.host'),
|
||||||
},
|
},
|
||||||
onboardingCallPromptEnabled: config.getEnv('onboardingCallPrompt.enabled'),
|
|
||||||
executionMode: config.getEnv('executions.mode'),
|
executionMode: config.getEnv('executions.mode'),
|
||||||
pushBackend: config.getEnv('push.backend'),
|
pushBackend: config.getEnv('push.backend'),
|
||||||
communityNodesEnabled: config.getEnv('nodes.communityPackages.enabled'),
|
communityNodesEnabled: config.getEnv('nodes.communityPackages.enabled'),
|
||||||
|
|
|
@ -1332,7 +1332,6 @@ export interface ISettingsState {
|
||||||
mfa: {
|
mfa: {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
};
|
};
|
||||||
onboardingCallPromptEnabled: boolean;
|
|
||||||
saveDataErrorExecution: WorkflowSettings.SaveDataExecution;
|
saveDataErrorExecution: WorkflowSettings.SaveDataExecution;
|
||||||
saveDataSuccessExecution: WorkflowSettings.SaveDataExecution;
|
saveDataSuccessExecution: WorkflowSettings.SaveDataExecution;
|
||||||
saveManualExecutions: boolean;
|
saveManualExecutions: boolean;
|
||||||
|
@ -1428,16 +1427,6 @@ export interface IInviteResponse {
|
||||||
error?: string;
|
error?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IOnboardingCallPromptResponse {
|
|
||||||
nextPrompt: IOnboardingCallPrompt;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IOnboardingCallPrompt {
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
toast_sequence_number: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ITab {
|
export interface ITab {
|
||||||
value: string | number;
|
value: string | number;
|
||||||
label?: string;
|
label?: string;
|
||||||
|
|
|
@ -51,7 +51,6 @@ export const defaultSettings: IN8nUISettings = {
|
||||||
logLevel: 'info',
|
logLevel: 'info',
|
||||||
maxExecutionTimeout: 0,
|
maxExecutionTimeout: 0,
|
||||||
oauthCallbackUrls: { oauth1: '', oauth2: '' },
|
oauthCallbackUrls: { oauth1: '', oauth2: '' },
|
||||||
onboardingCallPromptEnabled: false,
|
|
||||||
personalizationSurveyEnabled: false,
|
personalizationSurveyEnabled: false,
|
||||||
releaseChannel: 'stable',
|
releaseChannel: 'stable',
|
||||||
posthog: {
|
posthog: {
|
||||||
|
|
|
@ -65,7 +65,6 @@ export const SETTINGS_STORE_DEFAULT_STATE: ISettingsState = {
|
||||||
mfa: {
|
mfa: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
onboardingCallPromptEnabled: false,
|
|
||||||
saveDataErrorExecution: 'all',
|
saveDataErrorExecution: 'all',
|
||||||
saveDataSuccessExecution: 'all',
|
saveDataSuccessExecution: 'all',
|
||||||
saveDataProgressExecution: false,
|
saveDataProgressExecution: false,
|
||||||
|
|
|
@ -1,40 +1,9 @@
|
||||||
import type { IOnboardingCallPrompt, IUser } from '@/Interface';
|
import type { IUser } from '@/Interface';
|
||||||
import { get, post } from '@/utils/apiUtils';
|
import { post } from '@/utils/apiUtils';
|
||||||
import { isUserGlobalOwner } from '@/utils/userUtils';
|
|
||||||
|
|
||||||
const N8N_API_BASE_URL = 'https://api.n8n.io/api';
|
const N8N_API_BASE_URL = 'https://api.n8n.io/api';
|
||||||
const ONBOARDING_PROMPTS_ENDPOINT = '/prompts/onboarding';
|
|
||||||
const CONTACT_EMAIL_SUBMISSION_ENDPOINT = '/accounts/onboarding';
|
const CONTACT_EMAIL_SUBMISSION_ENDPOINT = '/accounts/onboarding';
|
||||||
|
|
||||||
export async function fetchNextOnboardingPrompt(
|
|
||||||
instanceId: string,
|
|
||||||
currentUser: IUser,
|
|
||||||
): Promise<IOnboardingCallPrompt> {
|
|
||||||
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<string> {
|
|
||||||
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(
|
export async function submitEmailOnSignup(
|
||||||
instanceId: string,
|
instanceId: string,
|
||||||
currentUser: IUser,
|
currentUser: IUser,
|
||||||
|
|
|
@ -11,7 +11,6 @@ import {
|
||||||
DELETE_USER_MODAL_KEY,
|
DELETE_USER_MODAL_KEY,
|
||||||
DUPLICATE_MODAL_KEY,
|
DUPLICATE_MODAL_KEY,
|
||||||
INVITE_USER_MODAL_KEY,
|
INVITE_USER_MODAL_KEY,
|
||||||
ONBOARDING_CALL_SIGNUP_MODAL_KEY,
|
|
||||||
PERSONALIZATION_MODAL_KEY,
|
PERSONALIZATION_MODAL_KEY,
|
||||||
TAGS_MANAGER_MODAL_KEY,
|
TAGS_MANAGER_MODAL_KEY,
|
||||||
NPS_SURVEY_MODAL_KEY,
|
NPS_SURVEY_MODAL_KEY,
|
||||||
|
@ -44,7 +43,6 @@ import InviteUsersModal from '@/components/InviteUsersModal.vue';
|
||||||
import CredentialsSelectModal from '@/components/CredentialsSelectModal.vue';
|
import CredentialsSelectModal from '@/components/CredentialsSelectModal.vue';
|
||||||
import DuplicateWorkflowDialog from '@/components/DuplicateWorkflowDialog.vue';
|
import DuplicateWorkflowDialog from '@/components/DuplicateWorkflowDialog.vue';
|
||||||
import ModalRoot from '@/components/ModalRoot.vue';
|
import ModalRoot from '@/components/ModalRoot.vue';
|
||||||
import OnboardingCallSignupModal from '@/components/OnboardingCallSignupModal.vue';
|
|
||||||
import PersonalizationModal from '@/components/PersonalizationModal.vue';
|
import PersonalizationModal from '@/components/PersonalizationModal.vue';
|
||||||
import TagsManager from '@/components/TagsManager/TagsManager.vue';
|
import TagsManager from '@/components/TagsManager/TagsManager.vue';
|
||||||
import UpdatesPanel from '@/components/UpdatesPanel.vue';
|
import UpdatesPanel from '@/components/UpdatesPanel.vue';
|
||||||
|
@ -152,10 +150,6 @@ import ProjectMoveResourceConfirmModal from '@/components/Projects/ProjectMoveRe
|
||||||
</template>
|
</template>
|
||||||
</ModalRoot>
|
</ModalRoot>
|
||||||
|
|
||||||
<ModalRoot :name="ONBOARDING_CALL_SIGNUP_MODAL_KEY">
|
|
||||||
<OnboardingCallSignupModal />
|
|
||||||
</ModalRoot>
|
|
||||||
|
|
||||||
<ModalRoot :name="COMMUNITY_PACKAGE_INSTALL_MODAL_KEY">
|
<ModalRoot :name="COMMUNITY_PACKAGE_INSTALL_MODAL_KEY">
|
||||||
<CommunityPackageInstallModal />
|
<CommunityPackageInstallModal />
|
||||||
</ModalRoot>
|
</ModalRoot>
|
||||||
|
|
|
@ -1,131 +0,0 @@
|
||||||
<template>
|
|
||||||
<Modal
|
|
||||||
:name="ONBOARDING_CALL_SIGNUP_MODAL_KEY"
|
|
||||||
:title="$locale.baseText('onboardingCallSignupModal.title')"
|
|
||||||
:event-bus="modalBus"
|
|
||||||
:center="true"
|
|
||||||
:show-close="false"
|
|
||||||
:before-close="onModalClose"
|
|
||||||
width="460px"
|
|
||||||
>
|
|
||||||
<template #content>
|
|
||||||
<div class="pb-m">
|
|
||||||
<n8n-text>
|
|
||||||
{{ $locale.baseText('onboardingCallSignupModal.description') }}
|
|
||||||
</n8n-text>
|
|
||||||
</div>
|
|
||||||
<div @keyup.enter="onSignup">
|
|
||||||
<n8n-input
|
|
||||||
v-model="email"
|
|
||||||
:placeholder="$locale.baseText('onboardingCallSignupModal.emailInput.placeholder')"
|
|
||||||
/>
|
|
||||||
<n8n-text v-if="showError" size="small" class="mt-4xs" tag="div" color="danger">
|
|
||||||
{{ $locale.baseText('onboardingCallSignupModal.infoText.emailError') }}
|
|
||||||
</n8n-text>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template #footer>
|
|
||||||
<div :class="$style.buttonsContainer">
|
|
||||||
<n8n-button
|
|
||||||
:label="$locale.baseText('onboardingCallSignupModal.cancelButton.label')"
|
|
||||||
:disabled="loading"
|
|
||||||
float="right"
|
|
||||||
type="outline"
|
|
||||||
@click="onCancel"
|
|
||||||
/>
|
|
||||||
<n8n-button
|
|
||||||
:disabled="email === '' || loading"
|
|
||||||
:label="$locale.baseText('onboardingCallSignupModal.signupButton.label')"
|
|
||||||
float="right"
|
|
||||||
:loading="loading"
|
|
||||||
@click="onSignup"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</Modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { ONBOARDING_CALL_SIGNUP_MODAL_KEY, VALID_EMAIL_REGEX } from '@/constants';
|
|
||||||
import Modal from './Modal.vue';
|
|
||||||
|
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
import { useToast } from '@/composables/useToast';
|
|
||||||
import { mapStores } from 'pinia';
|
|
||||||
import { useUIStore } from '@/stores/ui.store';
|
|
||||||
import { createEventBus } from 'n8n-design-system/utils';
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'OnboardingCallSignupModal',
|
|
||||||
components: {
|
|
||||||
Modal,
|
|
||||||
},
|
|
||||||
props: ['modalName'],
|
|
||||||
setup() {
|
|
||||||
return {
|
|
||||||
toast: useToast(),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
email: '',
|
|
||||||
modalBus: createEventBus(),
|
|
||||||
ONBOARDING_CALL_SIGNUP_MODAL_KEY,
|
|
||||||
showError: false,
|
|
||||||
okToClose: false,
|
|
||||||
loading: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapStores(useUIStore),
|
|
||||||
isEmailValid(): boolean {
|
|
||||||
return VALID_EMAIL_REGEX.test(String(this.email).toLowerCase());
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async onSignup() {
|
|
||||||
if (!this.isEmailValid) {
|
|
||||||
this.showError = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.showError = false;
|
|
||||||
this.loading = true;
|
|
||||||
this.okToClose = false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.uiStore.applyForOnboardingCall(this.email);
|
|
||||||
this.toast.showMessage({
|
|
||||||
type: 'success',
|
|
||||||
title: this.$locale.baseText('onboardingCallSignupSucess.title'),
|
|
||||||
message: this.$locale.baseText('onboardingCallSignupSucess.message'),
|
|
||||||
});
|
|
||||||
this.okToClose = true;
|
|
||||||
this.modalBus.emit('close');
|
|
||||||
} catch (e) {
|
|
||||||
this.toast.showError(
|
|
||||||
e,
|
|
||||||
this.$locale.baseText('onboardingCallSignupFailed.title'),
|
|
||||||
this.$locale.baseText('onboardingCallSignupFailed.message'),
|
|
||||||
);
|
|
||||||
this.loading = false;
|
|
||||||
this.okToClose = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async onCancel() {
|
|
||||||
this.okToClose = true;
|
|
||||||
this.modalBus.emit('close');
|
|
||||||
},
|
|
||||||
onModalClose() {
|
|
||||||
return this.okToClose;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" module>
|
|
||||||
.buttonsContainer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
column-gap: var(--spacing-xs);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -90,9 +90,6 @@ import {
|
||||||
PERSONAL_COMPANY_TYPE,
|
PERSONAL_COMPANY_TYPE,
|
||||||
COMPANY_INDUSTRY_EXTENDED_KEY,
|
COMPANY_INDUSTRY_EXTENDED_KEY,
|
||||||
OTHER_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_GOAL_KEY,
|
||||||
MARKETING_AUTOMATION_LEAD_GENERATION_GOAL,
|
MARKETING_AUTOMATION_LEAD_GENERATION_GOAL,
|
||||||
MARKETING_AUTOMATION_CUSTOMER_COMMUNICATION,
|
MARKETING_AUTOMATION_CUSTOMER_COMMUNICATION,
|
||||||
|
@ -141,8 +138,7 @@ import {
|
||||||
} from '@/constants';
|
} from '@/constants';
|
||||||
import { useToast } from '@/composables/useToast';
|
import { useToast } from '@/composables/useToast';
|
||||||
import Modal from '@/components/Modal.vue';
|
import Modal from '@/components/Modal.vue';
|
||||||
import type { IFormInputs, IPersonalizationLatestVersion, IUser } from '@/Interface';
|
import type { IFormInputs, IPersonalizationLatestVersion } from '@/Interface';
|
||||||
import { getAccountAge } from '@/utils/userUtils';
|
|
||||||
import type { GenericValue } from 'n8n-workflow';
|
import type { GenericValue } from 'n8n-workflow';
|
||||||
import { useUIStore } from '@/stores/ui.store';
|
import { useUIStore } from '@/stores/ui.store';
|
||||||
import { useSettingsStore } from '@/stores/settings.store';
|
import { useSettingsStore } from '@/stores/settings.store';
|
||||||
|
@ -715,8 +711,6 @@ export default defineComponent({
|
||||||
if (Object.keys(values).length === 0) {
|
if (Object.keys(values).length === 0) {
|
||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.fetchOnboardingPrompt();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.showError(e, 'Error while submitting results');
|
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);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -54,7 +54,6 @@ export const PERSONALIZATION_MODAL_KEY = 'personalization';
|
||||||
export const CONTACT_PROMPT_MODAL_KEY = 'contactPrompt';
|
export const CONTACT_PROMPT_MODAL_KEY = 'contactPrompt';
|
||||||
export const NPS_SURVEY_MODAL_KEY = 'npsSurvey';
|
export const NPS_SURVEY_MODAL_KEY = 'npsSurvey';
|
||||||
export const WORKFLOW_ACTIVE_MODAL_KEY = 'activation';
|
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_INSTALL_MODAL_KEY = 'communityPackageInstall';
|
||||||
export const COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY = 'communityPackageManageConfirm';
|
export const COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY = 'communityPackageManageConfirm';
|
||||||
export const IMPORT_CURL_MODAL_KEY = 'importCurl';
|
export const IMPORT_CURL_MODAL_KEY = 'importCurl';
|
||||||
|
@ -502,9 +501,6 @@ export const enum FAKE_DOOR_FEATURES {
|
||||||
SSO = 'sso',
|
SSO = 'sso',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ONBOARDING_PROMPT_TIMEBOX = 14;
|
|
||||||
export const FIRST_ONBOARDING_PROMPT_TIMEOUT = 300000;
|
|
||||||
|
|
||||||
export const TEST_PIN_DATA = [
|
export const TEST_PIN_DATA = [
|
||||||
{
|
{
|
||||||
name: 'First item',
|
name: 'First item',
|
||||||
|
|
|
@ -1293,17 +1293,6 @@
|
||||||
"nodeWebhooks.webhookUrls": "Webhook URLs",
|
"nodeWebhooks.webhookUrls": "Webhook URLs",
|
||||||
"nodeWebhooks.webhookUrls.formTrigger": "Form URLs",
|
"nodeWebhooks.webhookUrls.formTrigger": "Form URLs",
|
||||||
"nodeWebhooks.webhookUrls.chatTrigger": "Chat URL",
|
"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)",
|
"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.workflowImportError": "Could not import workflow",
|
||||||
"openWorkflow.workflowNotFoundError": "Could not find workflow",
|
"openWorkflow.workflowNotFoundError": "Could not find workflow",
|
||||||
|
|
|
@ -64,7 +64,6 @@ export const useSettingsStore = defineStore(STORES.SETTINGS, {
|
||||||
mfa: {
|
mfa: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
onboardingCallPromptEnabled: false,
|
|
||||||
saveDataErrorExecution: 'all',
|
saveDataErrorExecution: 'all',
|
||||||
saveDataSuccessExecution: 'all',
|
saveDataSuccessExecution: 'all',
|
||||||
saveManualExecutions: false,
|
saveManualExecutions: false,
|
||||||
|
@ -265,7 +264,6 @@ export const useSettingsStore = defineStore(STORES.SETTINGS, {
|
||||||
this.userManagement.showSetupOnFirstLoad = !!settings.userManagement.showSetupOnFirstLoad;
|
this.userManagement.showSetupOnFirstLoad = !!settings.userManagement.showSetupOnFirstLoad;
|
||||||
}
|
}
|
||||||
this.api = settings.publicApi;
|
this.api = settings.publicApi;
|
||||||
this.onboardingCallPromptEnabled = settings.onboardingCallPromptEnabled;
|
|
||||||
if (settings.sso?.ldap) {
|
if (settings.sso?.ldap) {
|
||||||
this.ldap.loginEnabled = settings.sso.ldap.loginEnabled;
|
this.ldap.loginEnabled = settings.sso.ldap.loginEnabled;
|
||||||
this.ldap.loginLabel = settings.sso.ldap.loginLabel;
|
this.ldap.loginLabel = settings.sso.ldap.loginLabel;
|
||||||
|
|
|
@ -16,7 +16,6 @@ import {
|
||||||
INVITE_USER_MODAL_KEY,
|
INVITE_USER_MODAL_KEY,
|
||||||
LOG_STREAM_MODAL_KEY,
|
LOG_STREAM_MODAL_KEY,
|
||||||
MFA_SETUP_MODAL_KEY,
|
MFA_SETUP_MODAL_KEY,
|
||||||
ONBOARDING_CALL_SIGNUP_MODAL_KEY,
|
|
||||||
PERSONALIZATION_MODAL_KEY,
|
PERSONALIZATION_MODAL_KEY,
|
||||||
STORES,
|
STORES,
|
||||||
TAGS_MANAGER_MODAL_KEY,
|
TAGS_MANAGER_MODAL_KEY,
|
||||||
|
@ -103,7 +102,6 @@ export const useUIStore = defineStore(STORES.UI, () => {
|
||||||
CONTACT_PROMPT_MODAL_KEY,
|
CONTACT_PROMPT_MODAL_KEY,
|
||||||
CREDENTIAL_SELECT_MODAL_KEY,
|
CREDENTIAL_SELECT_MODAL_KEY,
|
||||||
DUPLICATE_MODAL_KEY,
|
DUPLICATE_MODAL_KEY,
|
||||||
ONBOARDING_CALL_SIGNUP_MODAL_KEY,
|
|
||||||
PERSONALIZATION_MODAL_KEY,
|
PERSONALIZATION_MODAL_KEY,
|
||||||
INVITE_USER_MODAL_KEY,
|
INVITE_USER_MODAL_KEY,
|
||||||
TAGS_MANAGER_MODAL_KEY,
|
TAGS_MANAGER_MODAL_KEY,
|
||||||
|
@ -453,24 +451,6 @@ export const useUIStore = defineStore(STORES.UI, () => {
|
||||||
openModal(CREDENTIAL_EDIT_MODAL_KEY);
|
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 submitContactEmail = async (email: string, agree: boolean) => {
|
||||||
const instanceId = rootStore.instanceId;
|
const instanceId = rootStore.instanceId;
|
||||||
const { currentUser } = userStore;
|
const { currentUser } = userStore;
|
||||||
|
@ -668,8 +648,6 @@ export const useUIStore = defineStore(STORES.UI, () => {
|
||||||
openDeleteUserModal,
|
openDeleteUserModal,
|
||||||
openExistingCredential,
|
openExistingCredential,
|
||||||
openNewCredential,
|
openNewCredential,
|
||||||
getNextOnboardingPrompt,
|
|
||||||
applyForOnboardingCall,
|
|
||||||
submitContactEmail,
|
submitContactEmail,
|
||||||
openCommunityPackageUninstallConfirmModal,
|
openCommunityPackageUninstallConfirmModal,
|
||||||
openCommunityPackageUpdateConfirmModal,
|
openCommunityPackageUpdateConfirmModal,
|
||||||
|
|
|
@ -110,16 +110,6 @@ export function getPersonalizedNodeTypes(
|
||||||
return getPersonalizationSurveyV1(answers);
|
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(
|
function getPersonalizationSurveyV2OrLater(
|
||||||
answers:
|
answers:
|
||||||
| IPersonalizationSurveyAnswersV2
|
| IPersonalizationSurveyAnswersV2
|
||||||
|
|
|
@ -222,12 +222,9 @@ import {
|
||||||
import type { NotificationHandle } from 'element-plus';
|
import type { NotificationHandle } from 'element-plus';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
FIRST_ONBOARDING_PROMPT_TIMEOUT,
|
|
||||||
MAIN_HEADER_TABS,
|
MAIN_HEADER_TABS,
|
||||||
MODAL_CANCEL,
|
MODAL_CANCEL,
|
||||||
MODAL_CONFIRM,
|
MODAL_CONFIRM,
|
||||||
ONBOARDING_CALL_SIGNUP_MODAL_KEY,
|
|
||||||
ONBOARDING_PROMPT_TIMEBOX,
|
|
||||||
PLACEHOLDER_EMPTY_WORKFLOW_ID,
|
PLACEHOLDER_EMPTY_WORKFLOW_ID,
|
||||||
QUICKSTART_NOTE_NAME,
|
QUICKSTART_NOTE_NAME,
|
||||||
START_NODE_TYPE,
|
START_NODE_TYPE,
|
||||||
|
@ -332,7 +329,6 @@ import { useUsersStore } from '@/stores/users.store';
|
||||||
import { useWorkflowsEEStore } from '@/stores/workflows.ee.store';
|
import { useWorkflowsEEStore } from '@/stores/workflows.ee.store';
|
||||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||||
import * as NodeViewUtils from '@/utils/nodeViewUtils';
|
import * as NodeViewUtils from '@/utils/nodeViewUtils';
|
||||||
import { getAccountAge } from '@/utils/userUtils';
|
|
||||||
import { getConnectionInfo, getNodeViewTab } from '@/utils/canvasUtils';
|
import { getConnectionInfo, getNodeViewTab } from '@/utils/canvasUtils';
|
||||||
import {
|
import {
|
||||||
AddConnectionCommand,
|
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
|
// TODO: This currently breaks since front-end hooks are still not updated to work with pinia store
|
||||||
void this.externalHooks.run('nodeView.mount').catch(() => {});
|
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);
|
sourceControlEventBus.on('pull', this.onSourceControlPull);
|
||||||
|
|
||||||
this.registerCustomAction({
|
this.registerCustomAction({
|
||||||
|
|
|
@ -2651,7 +2651,6 @@ export interface IN8nUISettings {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
host: string;
|
host: string;
|
||||||
};
|
};
|
||||||
onboardingCallPromptEnabled: boolean;
|
|
||||||
missingPackages?: boolean;
|
missingPackages?: boolean;
|
||||||
executionMode: 'regular' | 'queue';
|
executionMode: 'regular' | 'queue';
|
||||||
pushBackend: 'sse' | 'websocket';
|
pushBackend: 'sse' | 'websocket';
|
||||||
|
|
Loading…
Reference in a new issue