diff --git a/packages/frontend/editor-ui/src/init.test.ts b/packages/frontend/editor-ui/src/init.test.ts index eb6180fea9a..20cd7a3d6a5 100644 --- a/packages/frontend/editor-ui/src/init.test.ts +++ b/packages/frontend/editor-ui/src/init.test.ts @@ -15,6 +15,7 @@ import { STORES } from '@n8n/stores'; import { useSSOStore } from '@/stores/sso.store'; import { UserManagementAuthenticationMethod } from '@/Interface'; import { EnterpriseEditionFeature } from '@/constants'; +import { useUIStore } from '@/stores/ui.store'; const showMessage = vi.fn(); @@ -38,6 +39,7 @@ describe('Init', () => { let nodeTypesStore: ReturnType; let versionsStore: ReturnType; let ssoStore: ReturnType; + let uiStore: ReturnType; beforeEach(() => { setActivePinia( @@ -56,6 +58,7 @@ describe('Init', () => { versionsStore = useVersionsStore(); versionsStore = useVersionsStore(); ssoStore = useSSOStore(); + uiStore = useUIStore(); }); describe('initializeCore()', () => { @@ -104,6 +107,18 @@ describe('Init', () => { }, }); }); + + it('should initialize uiStore with banners based on settings', async () => { + settingsStore.isEnterpriseFeatureEnabled.showNonProdBanner = true; + settingsStore.settings.banners = { dismissed: [] }; + settingsStore.settings.versionCli = '1.2.3'; + + await initializeCore(); + + expect(uiStore.initialize).toHaveBeenCalledWith({ + banners: ['NON_PRODUCTION_LICENSE', 'V1'], + }); + }); }); describe('initializeAuthenticatedFeatures()', () => { diff --git a/packages/frontend/editor-ui/src/init.ts b/packages/frontend/editor-ui/src/init.ts index 430953e99ee..65561756dc5 100644 --- a/packages/frontend/editor-ui/src/init.ts +++ b/packages/frontend/editor-ui/src/init.ts @@ -16,6 +16,8 @@ import SourceControlInitializationErrorMessage from '@/components/SourceControlI import { useSSOStore } from '@/stores/sso.store'; import { EnterpriseEditionFeature } from '@/constants'; import type { UserManagementAuthenticationMethod } from '@/Interface'; +import { useUIStore } from '@/stores/ui.store'; +import type { BannerName } from '@n8n/api-types'; export const state = { initialized: false, @@ -35,6 +37,7 @@ export async function initializeCore() { const usersStore = useUsersStore(); const versionsStore = useVersionsStore(); const ssoStore = useSSOStore(); + const uiStore = useUIStore(); await settingsStore.initialize(); @@ -49,6 +52,20 @@ export async function initializeCore() { }, }); + const banners: BannerName[] = []; + if (settingsStore.isEnterpriseFeatureEnabled.showNonProdBanner) { + banners.push('NON_PRODUCTION_LICENSE'); + } + if ( + !(settingsStore.settings.banners?.dismissed || []).includes('V1') && + settingsStore.settings.versionCli.startsWith('1.') + ) { + banners.push('V1'); + } + uiStore.initialize({ + banners, + }); + void useExternalHooks().run('app.mount'); if (!settingsStore.isPreviewMode) { diff --git a/packages/frontend/editor-ui/src/stores/settings.store.ts b/packages/frontend/editor-ui/src/stores/settings.store.ts index df9633a6859..3b45c0edf80 100644 --- a/packages/frontend/editor-ui/src/stores/settings.store.ts +++ b/packages/frontend/editor-ui/src/stores/settings.store.ts @@ -15,7 +15,6 @@ import { UserManagementAuthenticationMethod } from '@/Interface'; import type { IDataObject, WorkflowSettings } from 'n8n-workflow'; import { defineStore } from 'pinia'; import { useRootStore } from '@n8n/stores/useRootStore'; -import { useUIStore } from './ui.store'; import { useUsersStore } from './users.store'; import { useVersionsStore } from './versions.store'; import { makeRestApiRequest } from '@n8n/rest-api-client'; @@ -190,10 +189,6 @@ export const useSettingsStore = defineStore(STORES.SETTINGS, () => { mfa.value.enabled = settings.value.mfa?.enabled; folders.value.enabled = settings.value.folders?.enabled; - if (settings.value.enterprise?.showNonProdBanner) { - useUIStore().pushBannerToStack('NON_PRODUCTION_LICENSE'); - } - if (settings.value.versionCli) { useRootStore().setVersionCli(settings.value.versionCli); } @@ -208,11 +203,6 @@ export const useSettingsStore = defineStore(STORES.SETTINGS, () => { return; } } - - const isV1BannerDismissedPermanently = (settings.value.banners?.dismissed || []).includes('V1'); - if (!isV1BannerDismissedPermanently && settings.value.versionCli.startsWith('1.')) { - useUIStore().pushBannerToStack('V1'); - } }; const setAllowedModules = (allowedModules: FrontendSettings['allowedModules']) => { diff --git a/packages/frontend/editor-ui/src/stores/ui.store.ts b/packages/frontend/editor-ui/src/stores/ui.store.ts index 5a22779e5c4..9676a33c6be 100644 --- a/packages/frontend/editor-ui/src/stores/ui.store.ts +++ b/packages/frontend/editor-ui/src/stores/ui.store.ts @@ -526,6 +526,10 @@ export const useUIStore = defineStore(STORES.UI, () => { processingExecutionResults.value = value; }; + const initialize = (options: { banners: BannerName[] }) => { + options.banners.forEach(pushBannerToStack); + }; + return { appGridDimensions, appliedTheme, @@ -579,6 +583,7 @@ export const useUIStore = defineStore(STORES.UI, () => { setProcessingExecutionResults, openDeleteFolderModal, openMoveToFolderModal, + initialize, }; }); diff --git a/packages/frontend/editor-ui/src/stores/ui.test.ts b/packages/frontend/editor-ui/src/stores/ui.test.ts index c69ade230f0..d300422f802 100644 --- a/packages/frontend/editor-ui/src/stores/ui.test.ts +++ b/packages/frontend/editor-ui/src/stores/ui.test.ts @@ -70,34 +70,24 @@ describe('UI store', () => { }); it('should add non-production license banner to stack based on enterprise settings', () => { - settingsStore.setSettings( - merge({}, defaultSettings, { - enterprise: { - showNonProdBanner: true, - }, - }), - ); + uiStore.initialize({ + banners: ['NON_PRODUCTION_LICENSE'], + }); expect(uiStore.bannerStack).toContain('NON_PRODUCTION_LICENSE'); }); it("should add V1 banner to stack if it's not dismissed", () => { - settingsStore.setSettings( - merge({}, defaultSettings, { - versionCli: '1.0.0', - }), - ); + uiStore.initialize({ + banners: ['V1'], + }); expect(uiStore.bannerStack).toContain('V1'); }); it("should not add V1 banner to stack if it's dismissed", () => { - settingsStore.setSettings( - merge({}, defaultSettings, { - versionCli: '1.0.0', - banners: { - dismissed: ['V1'], - }, - }), - ); + uiStore.initialize({ + banners: [], + }); + expect(uiStore.bannerStack).not.toContain('V1'); });