fix(n8n Form Node): Duplicate popup in manual mode (#11925)

Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
Michael Kret
2024-11-27 15:19:06 +02:00
committed by GitHub
parent 9669380097
commit 2c34bf4ea6
3 changed files with 24 additions and 28 deletions

View File

@@ -84,7 +84,7 @@ import { TelemetryHelpers } from 'n8n-workflow';
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers'; import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { useSettingsStore } from './settings.store'; import { useSettingsStore } from './settings.store';
import { openPopUpWindow } from '@/utils/executionUtils'; import { closeFormPopupWindow, openFormPopupWindow } from '@/utils/executionUtils';
import { useNodeHelpers } from '@/composables/useNodeHelpers'; import { useNodeHelpers } from '@/composables/useNodeHelpers';
const defaults: Omit<IWorkflowDb, 'id'> & { settings: NonNullable<IWorkflowDb['settings']> } = { const defaults: Omit<IWorkflowDb, 'id'> & { settings: NonNullable<IWorkflowDb['settings']> } = {
@@ -143,7 +143,6 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
const chatMessages = ref<string[]>([]); const chatMessages = ref<string[]>([]);
const isChatPanelOpen = ref(false); const isChatPanelOpen = ref(false);
const isLogsPanelOpen = ref(false); const isLogsPanelOpen = ref(false);
const formPopupWindow = ref<Window | null>(null);
const workflowName = computed(() => workflow.value.name); const workflowName = computed(() => workflow.value.name);
@@ -1319,12 +1318,7 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
(node.type === WAIT_NODE_TYPE && node.parameters.resume === 'form') (node.type === WAIT_NODE_TYPE && node.parameters.resume === 'form')
) { ) {
const testUrl = getFormResumeUrl(node, executionId); const testUrl = getFormResumeUrl(node, executionId);
if (!formPopupWindow.value || formPopupWindow.value.closed) { openFormPopupWindow(testUrl);
formPopupWindow.value = openPopUpWindow(testUrl);
} else {
formPopupWindow.value.location = testUrl;
formPopupWindow.value.focus();
}
} }
} else { } else {
if (tasksData.length && tasksData[tasksData.length - 1].executionStatus === 'waiting') { if (tasksData.length && tasksData[tasksData.length - 1].executionStatus === 'waiting') {
@@ -1577,8 +1571,7 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
uiStore.removeActiveAction('workflowRunning'); uiStore.removeActiveAction('workflowRunning');
workflowHelpers.setDocumentTitle(workflowName.value, 'IDLE'); workflowHelpers.setDocumentTitle(workflowName.value, 'IDLE');
formPopupWindow.value?.close(); closeFormPopupWindow();
formPopupWindow.value = null;
const runData = workflowExecutionData.value?.data?.resultData.runData ?? {}; const runData = workflowExecutionData.value?.data?.resultData.runData ?? {};
for (const nodeName in runData) { for (const nodeName in runData) {

View File

@@ -1,7 +1,7 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'; import { describe, it, expect, vi, beforeEach } from 'vitest';
import { import {
displayForm, displayForm,
openPopUpWindow, openFormPopupWindow,
executionFilterToQueryFilter, executionFilterToQueryFilter,
waitingNodeTooltip, waitingNodeTooltip,
} from './executionUtils'; } from './executionUtils';
@@ -15,7 +15,7 @@ vi.mock('./executionUtils', async () => {
const actual = await vi.importActual('./executionUtils'); const actual = await vi.importActual('./executionUtils');
return { return {
...actual, ...actual,
openPopUpWindow: vi.fn(), openFormPopupWindow: vi.fn(),
}; };
}); });
@@ -86,7 +86,7 @@ describe('displayForm', () => {
getTestUrl: getTestUrlMock, getTestUrl: getTestUrlMock,
}); });
expect(openPopUpWindow).not.toHaveBeenCalled(); expect(openFormPopupWindow).not.toHaveBeenCalled();
}); });
it('should skip nodes if destinationNode does not match and node is not a directParentNode', () => { it('should skip nodes if destinationNode does not match and node is not a directParentNode', () => {
@@ -119,7 +119,7 @@ describe('displayForm', () => {
getTestUrl: getTestUrlMock, getTestUrl: getTestUrlMock,
}); });
expect(openPopUpWindow).not.toHaveBeenCalled(); expect(openFormPopupWindow).not.toHaveBeenCalled();
}); });
it('should not open pop-up if source is "RunData.ManualChatMessage"', () => { it('should not open pop-up if source is "RunData.ManualChatMessage"', () => {
@@ -146,7 +146,7 @@ describe('displayForm', () => {
getTestUrl: getTestUrlMock, getTestUrl: getTestUrlMock,
}); });
expect(openPopUpWindow).not.toHaveBeenCalled(); expect(openFormPopupWindow).not.toHaveBeenCalled();
}); });
describe('executionFilterToQueryFilter()', () => { describe('executionFilterToQueryFilter()', () => {

View File

@@ -82,25 +82,28 @@ export const executionFilterToQueryFilter = (
return queryFilter; return queryFilter;
}; };
export const openPopUpWindow = ( let formPopupWindow: Window | null = null;
url: string,
options?: { width?: number; height?: number; alwaysInNewTab?: boolean }, export const openFormPopupWindow = (url: string) => {
) => { if (!formPopupWindow || formPopupWindow.closed) {
const windowWidth = window.innerWidth; const height = 700;
const smallScreen = windowWidth <= 800; const width = window.innerHeight - 50;
if (options?.alwaysInNewTab || smallScreen) {
return window.open(url, '_blank');
} else {
const height = options?.width || 700;
const width = options?.height || window.innerHeight - 50;
const left = (window.innerWidth - height) / 2; const left = (window.innerWidth - height) / 2;
const top = 50; const top = 50;
const features = `width=${height},height=${width},left=${left},top=${top},resizable=yes,scrollbars=yes`; const features = `width=${height},height=${width},left=${left},top=${top},resizable=yes,scrollbars=yes`;
const windowName = `form-waiting-since-${Date.now()}`; const windowName = `form-waiting-since-${Date.now()}`;
return window.open(url, windowName, features); formPopupWindow = window.open(url, windowName, features);
} else {
formPopupWindow.location = url;
formPopupWindow.focus();
} }
}; };
export const closeFormPopupWindow = () => {
formPopupWindow?.close();
formPopupWindow = null;
};
export function displayForm({ export function displayForm({
nodes, nodes,
runData, runData,
@@ -131,7 +134,7 @@ export function displayForm({
if (node.name === destinationNode || !node.disabled) { if (node.name === destinationNode || !node.disabled) {
let testUrl = ''; let testUrl = '';
if (node.type === FORM_TRIGGER_NODE_TYPE) testUrl = getTestUrl(node); if (node.type === FORM_TRIGGER_NODE_TYPE) testUrl = getTestUrl(node);
if (testUrl && source !== 'RunData.ManualChatMessage') openPopUpWindow(testUrl); if (testUrl && source !== 'RunData.ManualChatMessage') openFormPopupWindow(testUrl);
} }
} }
} }