mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
fix(editor): Fix notification toast offset outside of NodeView if chat/logs were opened (#15622)
This commit is contained in:
@@ -2,6 +2,12 @@ import { screen, waitFor, within } from '@testing-library/vue';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import { h, defineComponent } from 'vue';
|
||||
import { useToast } from './useToast';
|
||||
import { mockedStore } from '@/__tests__/utils';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useLogsStore } from '@/stores/logs.store';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { EDITABLE_CANVAS_VIEWS, VIEWS } from '@/constants';
|
||||
|
||||
describe('useToast', () => {
|
||||
let toast: ReturnType<typeof useToast>;
|
||||
@@ -87,4 +93,65 @@ describe('useToast', () => {
|
||||
expect(screen.getByRole('alert')).toContainHTML('<p>Test <strong>content</strong></p>');
|
||||
});
|
||||
});
|
||||
describe('determineToastOffset', () => {
|
||||
let settingsStore: ReturnType<typeof mockedStore<typeof useSettingsStore>>;
|
||||
let logsStore: ReturnType<typeof mockedStore<typeof useLogsStore>>;
|
||||
let ndvStore: ReturnType<typeof mockedStore<typeof useNDVStore>>;
|
||||
let uiStore: ReturnType<typeof mockedStore<typeof useUIStore>>;
|
||||
|
||||
beforeEach(() => {
|
||||
settingsStore = mockedStore(useSettingsStore);
|
||||
settingsStore.isAiAssistantEnabled = false;
|
||||
|
||||
logsStore = mockedStore(useLogsStore);
|
||||
logsStore.height = 100;
|
||||
logsStore.state = 'attached';
|
||||
|
||||
ndvStore = mockedStore(useNDVStore);
|
||||
ndvStore.activeNode = null;
|
||||
|
||||
uiStore = mockedStore(useUIStore);
|
||||
uiStore.currentView = VIEWS.WORKFLOW;
|
||||
});
|
||||
|
||||
it('applies logsStore offset on applicable views', () => {
|
||||
for (const view of EDITABLE_CANVAS_VIEWS) {
|
||||
uiStore.currentView = view;
|
||||
const offset = toast.determineToastOffset();
|
||||
expect(offset).toBe(100);
|
||||
}
|
||||
});
|
||||
|
||||
it('does not apply logsStore offset on unrelated view', () => {
|
||||
uiStore.currentView = VIEWS.HOMEPAGE;
|
||||
const offset = toast.determineToastOffset();
|
||||
expect(offset).toBe(0);
|
||||
});
|
||||
|
||||
it('does not apply logsStore offset if we have an activeNode', () => {
|
||||
ndvStore.activeNode = { name: 'myActiveNode' } as never;
|
||||
const offset = toast.determineToastOffset();
|
||||
expect(offset).toBe(0);
|
||||
});
|
||||
|
||||
it('applies assistant offset with logsOffset', () => {
|
||||
settingsStore.isAiAssistantEnabled = true;
|
||||
const offset = toast.determineToastOffset();
|
||||
expect(offset).toBe(100 + 64);
|
||||
});
|
||||
|
||||
it('does not apply logsStore offset if floating', () => {
|
||||
logsStore.state = 'floating';
|
||||
const offset = toast.determineToastOffset();
|
||||
expect(offset).toBe(0);
|
||||
});
|
||||
|
||||
it('does apply logsStore offset if closed', () => {
|
||||
logsStore.state = 'closed';
|
||||
logsStore.height = 32;
|
||||
settingsStore.isAiAssistantEnabled = true;
|
||||
const offset = toast.determineToastOffset();
|
||||
expect(offset).toBe(32 + 64);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,12 +7,13 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useI18n } from './useI18n';
|
||||
import { useExternalHooks } from './useExternalHooks';
|
||||
import { VIEWS } from '@/constants';
|
||||
import { VIEWS, VISIBLE_LOGS_VIEWS } from '@/constants';
|
||||
import type { ApplicationError } from 'n8n-workflow';
|
||||
import { useStyles } from './useStyles';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useLogsStore } from '@/stores/logs.store';
|
||||
import { LOGS_PANEL_STATE } from '@/components/CanvasChat/types/logs';
|
||||
|
||||
export interface NotificationErrorWithNodeAndDescription extends ApplicationError {
|
||||
node: {
|
||||
@@ -34,14 +35,24 @@ export function useToast() {
|
||||
const logsStore = useLogsStore();
|
||||
const ndvStore = useNDVStore();
|
||||
|
||||
function determineToastOffset() {
|
||||
const assistantOffset = settingsStore.isAiAssistantEnabled ? 64 : 0;
|
||||
const logsOffset =
|
||||
VISIBLE_LOGS_VIEWS.includes(uiStore.currentView as VIEWS) &&
|
||||
ndvStore.activeNode === null &&
|
||||
logsStore.state !== LOGS_PANEL_STATE.FLOATING
|
||||
? logsStore.height
|
||||
: 0;
|
||||
|
||||
return assistantOffset + logsOffset;
|
||||
}
|
||||
|
||||
function showMessage(messageData: Partial<NotificationOptions>, track = true) {
|
||||
const messageDefaults: Partial<Omit<NotificationOptions, 'message'>> = {
|
||||
dangerouslyUseHTMLString: true,
|
||||
position: 'bottom-right',
|
||||
zIndex: APP_Z_INDEXES.TOASTS, // above NDV and modal overlays
|
||||
offset:
|
||||
(settingsStore.isAiAssistantEnabled ? 64 : 0) +
|
||||
(ndvStore.activeNode === null ? logsStore.height : 0),
|
||||
offset: determineToastOffset(),
|
||||
appendTo: '#app-grid',
|
||||
customClass: 'content-toast',
|
||||
};
|
||||
@@ -203,5 +214,6 @@ export function useToast() {
|
||||
showError,
|
||||
clearAllStickyNotifications,
|
||||
showNotificationForViews,
|
||||
determineToastOffset,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -575,6 +575,7 @@ export const enum VIEWS {
|
||||
}
|
||||
|
||||
export const EDITABLE_CANVAS_VIEWS = [VIEWS.WORKFLOW, VIEWS.NEW_WORKFLOW, VIEWS.EXECUTION_DEBUG];
|
||||
export const VISIBLE_LOGS_VIEWS = [...EDITABLE_CANVAS_VIEWS, VIEWS.EXECUTION_PREVIEW];
|
||||
|
||||
export const TEST_PIN_DATA = [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user