refactor(editor): Detangle ui store from settings store (no-changelog) (#16384)

This commit is contained in:
Alex Grozav
2025-06-17 12:07:46 +02:00
committed by GitHub
parent dd2ed90b95
commit 5caf7a2660
5 changed files with 47 additions and 30 deletions

View File

@@ -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<typeof useNodeTypesStore>;
let versionsStore: ReturnType<typeof useVersionsStore>;
let ssoStore: ReturnType<typeof useSSOStore>;
let uiStore: ReturnType<typeof useUIStore>;
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()', () => {

View File

@@ -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) {

View File

@@ -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']) => {

View File

@@ -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,
};
});

View File

@@ -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');
});