feat(editor): Clean up lead enrichment experiment (no-changelog) (#9572)
This commit is contained in:
@@ -1325,7 +1325,6 @@ export interface UIState {
|
||||
bannersHeight: number;
|
||||
bannerStack: BannerName[];
|
||||
theme: ThemeOption;
|
||||
suggestedTemplates?: SuggestedTemplates;
|
||||
pendingNotificationsForViews: {
|
||||
[key in VIEWS]?: NotificationOptions[];
|
||||
};
|
||||
@@ -1917,24 +1916,6 @@ export type ToggleNodeCreatorOptions = {
|
||||
export type AppliedThemeOption = 'light' | 'dark';
|
||||
export type ThemeOption = AppliedThemeOption | 'system';
|
||||
|
||||
export type SuggestedTemplates = {
|
||||
sections: SuggestedTemplatesSection[];
|
||||
};
|
||||
|
||||
export type SuggestedTemplatesSection = {
|
||||
name: string;
|
||||
title: string;
|
||||
description: string;
|
||||
workflows: SuggestedTemplatesWorkflowPreview[];
|
||||
};
|
||||
|
||||
export type SuggestedTemplatesWorkflowPreview = {
|
||||
title: string;
|
||||
description: string;
|
||||
preview: IWorkflowData;
|
||||
nodes: Array<Pick<ITemplatesNode, 'id' | 'displayName' | 'icon' | 'defaults' | 'iconData'>>;
|
||||
};
|
||||
|
||||
export type NewConnectionInfo = {
|
||||
sourceId: string;
|
||||
index: number;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Cloud, IRestApiContext, InstanceUsage, LeadEnrichmentTemplates } from '@/Interface';
|
||||
import type { Cloud, IRestApiContext, InstanceUsage } from '@/Interface';
|
||||
import { get, post } from '@/utils/apiUtils';
|
||||
|
||||
export async function getCurrentPlan(context: IRestApiContext): Promise<Cloud.PlanData> {
|
||||
@@ -20,9 +20,3 @@ export async function confirmEmail(context: IRestApiContext): Promise<Cloud.User
|
||||
export async function getAdminPanelLoginCode(context: IRestApiContext): Promise<{ code: string }> {
|
||||
return await get(context.baseUrl, '/cloud/proxy/login/code');
|
||||
}
|
||||
|
||||
export async function fetchSuggestedTemplates(
|
||||
context: IRestApiContext,
|
||||
): Promise<LeadEnrichmentTemplates> {
|
||||
return await get(context.baseUrl, '/cloud/proxy/templates');
|
||||
}
|
||||
|
||||
@@ -157,15 +157,6 @@
|
||||
/>
|
||||
</template>
|
||||
</ModalRoot>
|
||||
<ModalRoot :name="SUGGESTED_TEMPLATES_PREVIEW_MODAL_KEY">
|
||||
<template #default="{ modalName, data }">
|
||||
<SuggestedTemplatesPreviewModal
|
||||
data-test-id="suggested-templates-preview-modal"
|
||||
:modal-name="modalName"
|
||||
:data="data"
|
||||
/>
|
||||
</template>
|
||||
</ModalRoot>
|
||||
|
||||
<ModalRoot :name="SETUP_CREDENTIALS_MODAL_KEY">
|
||||
<template #default="{ modalName, data }">
|
||||
@@ -210,7 +201,6 @@ import {
|
||||
DEBUG_PAYWALL_MODAL_KEY,
|
||||
MFA_SETUP_MODAL_KEY,
|
||||
WORKFLOW_HISTORY_VERSION_RESTORE,
|
||||
SUGGESTED_TEMPLATES_PREVIEW_MODAL_KEY,
|
||||
SETUP_CREDENTIALS_MODAL_KEY,
|
||||
GENERATE_CURL_MODAL_KEY,
|
||||
} from '@/constants';
|
||||
@@ -245,7 +235,6 @@ import SourceControlPullModal from '@/components/SourceControlPullModal.ee.vue';
|
||||
import ExternalSecretsProviderModal from '@/components/ExternalSecretsProviderModal.ee.vue';
|
||||
import DebugPaywallModal from '@/components/DebugPaywallModal.vue';
|
||||
import WorkflowHistoryVersionRestoreModal from '@/components/WorkflowHistory/WorkflowHistoryVersionRestoreModal.vue';
|
||||
import SuggestedTemplatesPreviewModal from '@/components/SuggestedTemplates/SuggestedTemplatesPreviewModal.vue';
|
||||
import SetupWorkflowCredentialsModal from '@/components/SetupWorkflowCredentialsModal/SetupWorkflowCredentialsModal.vue';
|
||||
|
||||
export default defineComponent({
|
||||
@@ -281,7 +270,6 @@ export default defineComponent({
|
||||
DebugPaywallModal,
|
||||
MfaSetupModal,
|
||||
WorkflowHistoryVersionRestoreModal,
|
||||
SuggestedTemplatesPreviewModal,
|
||||
SetupWorkflowCredentialsModal,
|
||||
},
|
||||
data: () => ({
|
||||
@@ -314,7 +302,6 @@ export default defineComponent({
|
||||
DEBUG_PAYWALL_MODAL_KEY,
|
||||
MFA_SETUP_MODAL_KEY,
|
||||
WORKFLOW_HISTORY_VERSION_RESTORE,
|
||||
SUGGESTED_TEMPLATES_PREVIEW_MODAL_KEY,
|
||||
SETUP_CREDENTIALS_MODAL_KEY,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router';
|
||||
import { computed } from 'vue';
|
||||
import { useUsersStore } from '@/stores/users.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { VIEWS } from '@/constants';
|
||||
import type { ITemplatesCollection, IUser } from '@/Interface';
|
||||
import SuggestedTemplatesSection from '@/components/SuggestedTemplates/SuggestedTemplatesSection.vue';
|
||||
|
||||
const usersStore = useUsersStore();
|
||||
const uiStore = useUIStore();
|
||||
const router = useRouter();
|
||||
|
||||
const currentUser = computed(() => usersStore.currentUser);
|
||||
|
||||
const upperCaseFirstName = (user: IUser | null) => {
|
||||
if (!user?.firstName) return;
|
||||
return user.firstName?.charAt(0)?.toUpperCase() + user?.firstName?.slice(1);
|
||||
};
|
||||
|
||||
const defaultSection = computed(() => {
|
||||
if (!uiStore.suggestedTemplates) {
|
||||
return null;
|
||||
}
|
||||
return uiStore.suggestedTemplates.sections[0];
|
||||
});
|
||||
|
||||
const suggestedTemplates = computed(() => {
|
||||
const carouselCollections = Array<ITemplatesCollection>();
|
||||
if (!uiStore.suggestedTemplates || !defaultSection.value) {
|
||||
return carouselCollections;
|
||||
}
|
||||
defaultSection.value.workflows.forEach((workflow, index) => {
|
||||
carouselCollections.push({
|
||||
id: index,
|
||||
name: workflow.title,
|
||||
workflows: [{ id: index }],
|
||||
nodes: workflow.nodes,
|
||||
});
|
||||
});
|
||||
return carouselCollections;
|
||||
});
|
||||
|
||||
function openCanvas() {
|
||||
uiStore.nodeViewInitialized = false;
|
||||
void router.push({ name: VIEWS.NEW_WORKFLOW });
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
currentUser,
|
||||
openCanvas,
|
||||
suggestedTemplates,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="$style.container" data-test-id="suggested-templates-page-container">
|
||||
<div :class="$style.header">
|
||||
<n8n-heading tag="h1" size="2xlarge" class="mb-2xs">
|
||||
{{
|
||||
$locale.baseText('suggestedTemplates.heading', {
|
||||
interpolate: {
|
||||
name: upperCaseFirstName(currentUser) || $locale.baseText('generic.welcome'),
|
||||
},
|
||||
})
|
||||
}}
|
||||
</n8n-heading>
|
||||
<n8n-text
|
||||
size="large"
|
||||
color="text-base"
|
||||
data-test-id="suggested-template-section-description"
|
||||
>
|
||||
{{ defaultSection?.description }}
|
||||
</n8n-text>
|
||||
</div>
|
||||
<div :class="$style.content">
|
||||
<SuggestedTemplatesSection
|
||||
v-for="section in uiStore.suggestedTemplates?.sections"
|
||||
:key="section.title"
|
||||
:section="section"
|
||||
:show-title="false"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<n8n-button
|
||||
:label="$locale.baseText('suggestedTemplates.newWorkflowButton')"
|
||||
type="secondary"
|
||||
size="medium"
|
||||
icon="plus"
|
||||
data-test-id="suggested-templates-new-workflow-button"
|
||||
@click="openCanvas"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" module>
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-l);
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: var(--spacing-l);
|
||||
}
|
||||
</style>
|
||||
@@ -1,109 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useUsersStore } from '@/stores/users.store';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import {
|
||||
SUGGESTED_TEMPLATES_FLAG,
|
||||
SUGGESTED_TEMPLATES_PREVIEW_MODAL_KEY,
|
||||
VIEWS,
|
||||
} from '@/constants';
|
||||
import type { IWorkflowDb, SuggestedTemplatesWorkflowPreview } from '@/Interface';
|
||||
import Modal from '@/components/Modal.vue';
|
||||
import WorkflowPreview from '@/components/WorkflowPreview.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
modalName: string;
|
||||
data: {
|
||||
workflow: SuggestedTemplatesWorkflowPreview;
|
||||
};
|
||||
}>();
|
||||
|
||||
const i18n = useI18n();
|
||||
const router = useRouter();
|
||||
const uiStore = useUIStore();
|
||||
const usersStore = useUsersStore();
|
||||
const toast = useToast();
|
||||
const telemetry = useTelemetry();
|
||||
|
||||
function showConfirmationMessage(event: PointerEvent) {
|
||||
if (event.target instanceof HTMLAnchorElement) {
|
||||
event.preventDefault();
|
||||
// @ts-expect-error Additional parameters are not necessary for this function
|
||||
toast.showMessage({
|
||||
title: i18n.baseText('suggestedTemplates.notification.confirmation.title'),
|
||||
message: i18n.baseText('suggestedTemplates.notification.confirmation.message'),
|
||||
type: 'success',
|
||||
});
|
||||
telemetry.track(
|
||||
'User wants to be notified once template is ready',
|
||||
{ templateName: props.data.workflow.title, email: usersStore.currentUser?.email },
|
||||
{
|
||||
withPostHog: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function openCanvas() {
|
||||
uiStore.setNotificationsForView(VIEWS.WORKFLOW, [
|
||||
{
|
||||
title: i18n.baseText('suggestedTemplates.notification.comingSoon.title'),
|
||||
message: i18n.baseText('suggestedTemplates.notification.comingSoon.message'),
|
||||
type: 'info',
|
||||
duration: 10000,
|
||||
onClick: showConfirmationMessage,
|
||||
},
|
||||
]);
|
||||
localStorage.setItem(SUGGESTED_TEMPLATES_FLAG, 'false');
|
||||
uiStore.deleteSuggestedTemplates();
|
||||
uiStore.closeModal(SUGGESTED_TEMPLATES_PREVIEW_MODAL_KEY);
|
||||
uiStore.nodeViewInitialized = false;
|
||||
void router.push({ name: VIEWS.NEW_WORKFLOW });
|
||||
telemetry.track(
|
||||
'User clicked Use Template button',
|
||||
{ templateName: props.data.workflow.title },
|
||||
{ withPostHog: true },
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal width="900px" height="640px" :name="props.modalName">
|
||||
<template #header>
|
||||
<n8n-heading tag="h2" size="xlarge">
|
||||
{{ $props.data.workflow.title }}
|
||||
</n8n-heading>
|
||||
</template>
|
||||
<template #content>
|
||||
<WorkflowPreview
|
||||
:loading="false"
|
||||
:workflow="$props.data.workflow.preview as IWorkflowDb"
|
||||
:can-open-n-d-v="false"
|
||||
:hide-node-issues="true"
|
||||
@close="uiStore.closeModal(SUGGESTED_TEMPLATES_PREVIEW_MODAL_KEY)"
|
||||
/>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div>
|
||||
<n8n-text> {{ $props.data.workflow.description }} </n8n-text>
|
||||
</div>
|
||||
<div :class="$style.footerButtons">
|
||||
<n8n-button
|
||||
float="right"
|
||||
data-test-id="use-template-button"
|
||||
:label="$locale.baseText('suggestedTemplates.modal.button.label')"
|
||||
@click="openCanvas"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style module lang="scss">
|
||||
.footerButtons {
|
||||
margin-top: var(--spacing-xl);
|
||||
}
|
||||
</style>
|
||||
@@ -1,82 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { type PropType, computed } from 'vue';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import type { ITemplatesCollection, ITemplatesNode, SuggestedTemplatesSection } from '@/Interface';
|
||||
import TemplatesInfoCarousel from '@/components/TemplatesInfoCarousel.vue';
|
||||
import { SUGGESTED_TEMPLATES_PREVIEW_MODAL_KEY } from '@/constants';
|
||||
|
||||
const uiStore = useUIStore();
|
||||
const telemetry = useTelemetry();
|
||||
|
||||
const props = defineProps({
|
||||
section: {
|
||||
type: Object as PropType<SuggestedTemplatesSection>,
|
||||
required: true,
|
||||
},
|
||||
title: {
|
||||
type: String as PropType<string>,
|
||||
required: false,
|
||||
},
|
||||
showTitle: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
|
||||
const sectionTemplates = computed(() => {
|
||||
const carouselCollections = Array<ITemplatesCollection>();
|
||||
if (!uiStore.suggestedTemplates) {
|
||||
return carouselCollections;
|
||||
}
|
||||
props.section.workflows.forEach((workflow, index) => {
|
||||
carouselCollections.push({
|
||||
id: index,
|
||||
name: workflow.title,
|
||||
workflows: [{ id: index }],
|
||||
nodes: workflow.nodes as ITemplatesNode[],
|
||||
});
|
||||
});
|
||||
return carouselCollections;
|
||||
});
|
||||
|
||||
function onOpenCollection({ id }: { event: Event; id: number }) {
|
||||
uiStore.openModalWithData({
|
||||
name: SUGGESTED_TEMPLATES_PREVIEW_MODAL_KEY,
|
||||
data: { workflow: props.section.workflows[id] },
|
||||
});
|
||||
telemetry.track(
|
||||
'User clicked template recommendation',
|
||||
{ templateName: props.section.workflows[id].title },
|
||||
{ withPostHog: true },
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="$style.container" data-test-id="suggested-templates-section-container">
|
||||
<div v-if="showTitle" :class="$style.header">
|
||||
<n8n-text size="large" color="text-base" :bold="true">
|
||||
{{ props.title ?? section.title }}
|
||||
</n8n-text>
|
||||
</div>
|
||||
<div :class="$style.content">
|
||||
<TemplatesInfoCarousel
|
||||
:collections="sectionTemplates"
|
||||
:loading="false"
|
||||
:show-item-count="false"
|
||||
:show-navigation="false"
|
||||
cards-width="24%"
|
||||
@open-collection="onOpenCollection"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" module>
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-l);
|
||||
}
|
||||
</style>
|
||||
@@ -114,9 +114,6 @@
|
||||
<template #default="{ item, updateItemSize }">
|
||||
<slot :data="item" :update-item-size="updateItemSize" />
|
||||
</template>
|
||||
<template #postListContent>
|
||||
<slot name="postListContent" />
|
||||
</template>
|
||||
</n8n-recycle-scroller>
|
||||
<n8n-datatable
|
||||
v-if="type === 'datatable'"
|
||||
|
||||
@@ -63,7 +63,6 @@ export const SOURCE_CONTROL_PULL_MODAL_KEY = 'sourceControlPull';
|
||||
export const DEBUG_PAYWALL_MODAL_KEY = 'debugPaywall';
|
||||
export const MFA_SETUP_MODAL_KEY = 'mfaSetup';
|
||||
export const WORKFLOW_HISTORY_VERSION_RESTORE = 'workflowHistoryVersionRestore';
|
||||
export const SUGGESTED_TEMPLATES_PREVIEW_MODAL_KEY = 'suggestedTemplatePreview';
|
||||
export const SETUP_CREDENTIALS_MODAL_KEY = 'setupCredentials';
|
||||
|
||||
export const EXTERNAL_SECRETS_PROVIDER_MODAL_KEY = 'externalSecretsProvider';
|
||||
@@ -769,8 +768,6 @@ export const TIME = {
|
||||
DAY: 24 * 60 * 60 * 1000,
|
||||
};
|
||||
|
||||
export const SUGGESTED_TEMPLATES_FLAG = 'SHOW_N8N_SUGGESTED_TEMPLATES';
|
||||
|
||||
/**
|
||||
* Mouse button codes
|
||||
*/
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
"generic.seePlans": "See plans",
|
||||
"generic.loading": "Loading",
|
||||
"generic.and": "and",
|
||||
"generic.welcome": "Welcome",
|
||||
"generic.ownedByMe": "Owned by me",
|
||||
"generic.moreInfo": "More info",
|
||||
"about.aboutN8n": "About n8n",
|
||||
@@ -817,14 +816,6 @@
|
||||
"genericHelpers.minShort": "m",
|
||||
"genericHelpers.sec": "sec",
|
||||
"genericHelpers.secShort": "s",
|
||||
"suggestedTemplates.heading": "{name}, get started with n8n 👇",
|
||||
"suggestedTemplates.sectionTitle": "Explore {sectionName} workflow templates",
|
||||
"suggestedTemplates.newWorkflowButton": "Create blank workflow",
|
||||
"suggestedTemplates.modal.button.label": "Use Template",
|
||||
"suggestedTemplates.notification.comingSoon.title": "Template coming soon!",
|
||||
"suggestedTemplates.notification.confirmation.title": "Got it!",
|
||||
"suggestedTemplates.notification.confirmation.message": "We will contact you via email once this template is released.",
|
||||
"suggestedTemplates.notification.comingSoon.message": "This template is still in the works. <b><a href=\"#\">Notify me when it's available</a></b>",
|
||||
"readOnly.showMessage.executions.message": "Executions are read-only. Make changes from the <b>Workflow</b> tab.",
|
||||
"readOnly.showMessage.executions.title": "Cannot edit execution",
|
||||
"readOnlyEnv.showMessage.executions.message": "Executions are read-only.",
|
||||
|
||||
@@ -5,14 +5,9 @@ import { useRootStore } from '@/stores/n8nRoot.store';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useUsersStore } from '@/stores/users.store';
|
||||
import {
|
||||
getAdminPanelLoginCode,
|
||||
getCurrentPlan,
|
||||
getCurrentUsage,
|
||||
fetchSuggestedTemplates,
|
||||
} from '@/api/cloudPlans';
|
||||
import { getAdminPanelLoginCode, getCurrentPlan, getCurrentUsage } from '@/api/cloudPlans';
|
||||
import { DateTime } from 'luxon';
|
||||
import { CLOUD_TRIAL_CHECK_INTERVAL, SUGGESTED_TEMPLATES_FLAG, STORES } from '@/constants';
|
||||
import { CLOUD_TRIAL_CHECK_INTERVAL, STORES } from '@/constants';
|
||||
import { hasPermission } from '@/rbac/permissions';
|
||||
|
||||
const DEFAULT_STATE: CloudPlanState = {
|
||||
@@ -166,17 +161,6 @@ export const useCloudPlanStore = defineStore(STORES.CLOUD_PLAN, () => {
|
||||
window.location.href = `https://${adminPanelHost}/login?code=${code}`;
|
||||
};
|
||||
|
||||
const loadSuggestedTemplates = async () => {
|
||||
try {
|
||||
const additionalTemplates = await fetchSuggestedTemplates(rootStore.getRestApiContext);
|
||||
if (additionalTemplates.sections && additionalTemplates.sections.length > 0) {
|
||||
useUIStore().setSuggestedTemplates(additionalTemplates);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Error checking for lead enrichment templates:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const initialize = async () => {
|
||||
if (state.initialized) {
|
||||
return;
|
||||
@@ -194,12 +178,6 @@ export const useCloudPlanStore = defineStore(STORES.CLOUD_PLAN, () => {
|
||||
console.warn('Error fetching user cloud account:', error);
|
||||
}
|
||||
|
||||
const localStorageFlag = localStorage.getItem(SUGGESTED_TEMPLATES_FLAG);
|
||||
// Don't show if users already opted in
|
||||
if (localStorageFlag !== 'false' && hasPermission(['instanceOwner'])) {
|
||||
await loadSuggestedTemplates();
|
||||
}
|
||||
|
||||
state.initialized = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ import {
|
||||
DEBUG_PAYWALL_MODAL_KEY,
|
||||
N8N_PRICING_PAGE_URL,
|
||||
WORKFLOW_HISTORY_VERSION_RESTORE,
|
||||
SUGGESTED_TEMPLATES_PREVIEW_MODAL_KEY,
|
||||
SETUP_CREDENTIALS_MODAL_KEY,
|
||||
GENERATE_CURL_MODAL_KEY,
|
||||
} from '@/constants';
|
||||
@@ -54,7 +53,6 @@ import type {
|
||||
NewCredentialsModal,
|
||||
ThemeOption,
|
||||
AppliedThemeOption,
|
||||
SuggestedTemplates,
|
||||
NotificationOptions,
|
||||
ModalState,
|
||||
} from '@/Interface';
|
||||
@@ -119,7 +117,6 @@ export const useUIStore = defineStore(STORES.UI, {
|
||||
EXTERNAL_SECRETS_PROVIDER_MODAL_KEY,
|
||||
DEBUG_PAYWALL_MODAL_KEY,
|
||||
WORKFLOW_HISTORY_VERSION_RESTORE,
|
||||
SUGGESTED_TEMPLATES_PREVIEW_MODAL_KEY,
|
||||
SETUP_CREDENTIALS_MODAL_KEY,
|
||||
].map((modalKey) => [modalKey, { open: false }]),
|
||||
),
|
||||
@@ -190,7 +187,6 @@ export const useUIStore = defineStore(STORES.UI, {
|
||||
addFirstStepOnLoad: false,
|
||||
bannersHeight: 0,
|
||||
bannerStack: [],
|
||||
suggestedTemplates: undefined,
|
||||
// Notifications that should show when a view is initialized
|
||||
// This enables us to set a queue of notifications form outside (another component)
|
||||
// and then show them when the view is initialized
|
||||
@@ -615,12 +611,6 @@ export const useUIStore = defineStore(STORES.UI, {
|
||||
clearBannerStack() {
|
||||
this.bannerStack = [];
|
||||
},
|
||||
setSuggestedTemplates(templates: SuggestedTemplates) {
|
||||
this.suggestedTemplates = templates;
|
||||
},
|
||||
deleteSuggestedTemplates() {
|
||||
this.suggestedTemplates = undefined;
|
||||
},
|
||||
getNotificationsForView(view: VIEWS): NotificationOptions[] {
|
||||
return this.pendingNotificationsForViews[view] ?? [];
|
||||
},
|
||||
|
||||
@@ -49,71 +49,56 @@
|
||||
@click:tag="onClickTag"
|
||||
/>
|
||||
</template>
|
||||
<template #postListContent>
|
||||
<SuggestedTemplatesSection
|
||||
v-for="(section, key) in suggestedTemplates?.sections"
|
||||
:key="key"
|
||||
:section="section"
|
||||
:title="
|
||||
$locale.baseText('suggestedTemplates.sectionTitle', {
|
||||
interpolate: { sectionName: section.name.toLocaleLowerCase() },
|
||||
})
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
<template #empty>
|
||||
<SuggestedTemplatesPage v-if="suggestedTemplates" />
|
||||
<div v-else>
|
||||
<div class="text-center mt-s">
|
||||
<n8n-heading tag="h2" size="xlarge" class="mb-2xs">
|
||||
{{
|
||||
currentUser.firstName
|
||||
? $locale.baseText('workflows.empty.heading', {
|
||||
interpolate: { name: currentUser.firstName },
|
||||
})
|
||||
: $locale.baseText('workflows.empty.heading.userNotSetup')
|
||||
}}
|
||||
</n8n-heading>
|
||||
<n8n-text size="large" color="text-base">
|
||||
{{
|
||||
$locale.baseText(
|
||||
readOnlyEnv
|
||||
? 'workflows.empty.description.readOnlyEnv'
|
||||
: 'workflows.empty.description',
|
||||
)
|
||||
}}
|
||||
</n8n-text>
|
||||
</div>
|
||||
<div v-if="!readOnlyEnv" :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>
|
||||
<div class="text-center mt-s">
|
||||
<n8n-heading tag="h2" size="xlarge" class="mb-2xs">
|
||||
{{
|
||||
currentUser.firstName
|
||||
? $locale.baseText('workflows.empty.heading', {
|
||||
interpolate: { name: currentUser.firstName },
|
||||
})
|
||||
: $locale.baseText('workflows.empty.heading.userNotSetup')
|
||||
}}
|
||||
</n8n-heading>
|
||||
<n8n-text size="large" color="text-base">
|
||||
{{
|
||||
$locale.baseText(
|
||||
readOnlyEnv
|
||||
? 'workflows.empty.description.readOnlyEnv'
|
||||
: 'workflows.empty.description',
|
||||
)
|
||||
}}
|
||||
</n8n-text>
|
||||
</div>
|
||||
<div v-if="!readOnlyEnv" :class="['text-center', 'mt-2xl', $style.actionsContainer]">
|
||||
<a
|
||||
v-if="isSalesUser"
|
||||
:href="getTemplateRepositoryURL()"
|
||||
:class="$style.emptyStateCard"
|
||||
target="_blank"
|
||||
>
|
||||
<n8n-card
|
||||
:class="$style.emptyStateCard"
|
||||
hoverable
|
||||
data-test-id="new-workflow-card"
|
||||
@click="addWorkflow"
|
||||
data-test-id="browse-sales-templates-card"
|
||||
@click="trackCategoryLinkClick('Sales')"
|
||||
>
|
||||
<n8n-icon :class="$style.emptyStateCardIcon" icon="file" />
|
||||
<n8n-icon :class="$style.emptyStateCardIcon" icon="box-open" />
|
||||
<n8n-text size="large" class="mt-xs" color="text-base">
|
||||
{{ $locale.baseText('workflows.empty.startFromScratch') }}
|
||||
{{ $locale.baseText('workflows.empty.browseTemplates') }}
|
||||
</n8n-text>
|
||||
</n8n-card>
|
||||
</div>
|
||||
</a>
|
||||
<n8n-card
|
||||
:class="$style.emptyStateCard"
|
||||
hoverable
|
||||
data-test-id="new-workflow-card"
|
||||
@click="addWorkflow"
|
||||
>
|
||||
<n8n-icon :class="$style.emptyStateCardIcon" icon="file" />
|
||||
<n8n-text size="large" class="mt-xs" color="text-base">
|
||||
{{ $locale.baseText('workflows.empty.startFromScratch') }}
|
||||
</n8n-text>
|
||||
</n8n-card>
|
||||
</div>
|
||||
</template>
|
||||
<template #filters="{ setKeyValue }">
|
||||
@@ -166,8 +151,6 @@ import WorkflowCard from '@/components/WorkflowCard.vue';
|
||||
import { EnterpriseEditionFeature, VIEWS } from '@/constants';
|
||||
import type { ITag, IUser, IWorkflowDb } from '@/Interface';
|
||||
import TagsDropdown from '@/components/TagsDropdown.vue';
|
||||
import SuggestedTemplatesPage from '@/components/SuggestedTemplates/SuggestedTemplatesPage.vue';
|
||||
import SuggestedTemplatesSection from '@/components/SuggestedTemplates/SuggestedTemplatesSection.vue';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
@@ -200,8 +183,6 @@ const WorkflowsView = defineComponent({
|
||||
ResourcesListLayout,
|
||||
WorkflowCard,
|
||||
TagsDropdown,
|
||||
SuggestedTemplatesPage,
|
||||
SuggestedTemplatesSection,
|
||||
ProjectTabs,
|
||||
},
|
||||
data() {
|
||||
@@ -254,9 +235,6 @@ const WorkflowsView = defineComponent({
|
||||
},
|
||||
];
|
||||
},
|
||||
suggestedTemplates() {
|
||||
return this.uiStore.suggestedTemplates;
|
||||
},
|
||||
userRole() {
|
||||
const role = this.usersStore.currentUserCloudInfo?.role;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user