Skip to content

Commit

Permalink
fix(editor): Fix pin data showing up in production executions on new …
Browse files Browse the repository at this point in the history
…canvas (#11951)
  • Loading branch information
alexgrozav authored Nov 29, 2024
1 parent 40a7445 commit 5f6f8a1
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 19 deletions.
64 changes: 63 additions & 1 deletion packages/editor-ui/src/composables/useCanvasOperations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import type {
IWebhookDescription,
Workflow,
INodeConnections,
WorkflowExecuteMode,
} from 'n8n-workflow';
import { NodeConnectionType, NodeHelpers } from 'n8n-workflow';
import { useCanvasOperations } from '@/composables/useCanvasOperations';
import type { CanvasConnection, CanvasNode } from '@/types';
import { CanvasConnectionMode } from '@/types';
import type { ICredentialsResponse, INodeUi, IWorkflowDb } from '@/Interface';
import type { ICredentialsResponse, IExecutionResponse, INodeUi, IWorkflowDb } from '@/Interface';
import { RemoveNodeCommand } from '@/models/history';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useUIStore } from '@/stores/ui.store';
Expand Down Expand Up @@ -2174,6 +2175,67 @@ describe('useCanvasOperations', () => {
});
});
});

describe('openExecution', () => {
it('should initialize workspace and set execution data when execution is found', async () => {
const workflowsStore = mockedStore(useWorkflowsStore);
const uiStore = mockedStore(useUIStore);
const { openExecution } = useCanvasOperations({ router });

const executionId = '123';
const executionData: IExecutionResponse = {
id: executionId,
finished: true,
status: 'success',
startedAt: new Date(),
createdAt: new Date(),
workflowData: createTestWorkflow(),
mode: 'manual' as WorkflowExecuteMode,
};

workflowsStore.getExecution.mockResolvedValue(executionData);

const result = await openExecution(executionId);

expect(workflowsStore.setWorkflowExecutionData).toHaveBeenCalledWith(executionData);
expect(uiStore.stateIsDirty).toBe(false);
expect(result).toEqual(executionData);
});

it('should throw error when execution data is undefined', async () => {
const workflowsStore = mockedStore(useWorkflowsStore);
const executionId = '123';
const { openExecution } = useCanvasOperations({ router });

workflowsStore.getExecution.mockResolvedValue(undefined);

await expect(openExecution(executionId)).rejects.toThrow(
`Execution with id "${executionId}" could not be found!`,
);
});

it('should clear workflow pin data if execution mode is not manual', async () => {
const workflowsStore = mockedStore(useWorkflowsStore);
const { openExecution } = useCanvasOperations({ router });

const executionId = '123';
const executionData: IExecutionResponse = {
id: executionId,
finished: true,
status: 'success',
startedAt: new Date(),
createdAt: new Date(),
workflowData: createTestWorkflow(),
mode: 'trigger' as WorkflowExecuteMode,
};

workflowsStore.getExecution.mockResolvedValue(executionData);

await openExecution(executionId);

expect(workflowsStore.setWorkflowPinData).toHaveBeenCalledWith({});
});
});
});

function buildImportNodes() {
Expand Down
28 changes: 28 additions & 0 deletions packages/editor-ui/src/composables/useCanvasOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import type {
AddedNodesAndConnections,
IExecutionResponse,
INodeUi,
ITag,
IUsedCredential,
Expand Down Expand Up @@ -1849,6 +1850,32 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
deleteNodes(ids);
}

async function openExecution(executionId: string) {
let data: IExecutionResponse | undefined;
try {
data = await workflowsStore.getExecution(executionId);
} catch (error) {
toast.showError(error, i18n.baseText('nodeView.showError.openExecution.title'));
return;
}

if (data === undefined) {
throw new Error(`Execution with id "${executionId}" could not be found!`);
}

initializeWorkspace(data.workflowData);

workflowsStore.setWorkflowExecutionData(data);

if (data.mode !== 'manual') {
workflowsStore.setWorkflowPinData({});
}

uiStore.stateIsDirty = false;

return data;
}

return {
lastClickPosition,
editableWorkflow,
Expand Down Expand Up @@ -1891,5 +1918,6 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
resetWorkspace,
initializeWorkspace,
resolveNodeWebhook,
openExecution,
};
}
25 changes: 7 additions & 18 deletions packages/editor-ui/src/views/NodeView.v2.vue
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ const {
fetchWorkflowDataFromUrl,
resetWorkspace,
initializeWorkspace,
openExecution,
editableWorkflow,
editableWorkflowObject,
lastClickPosition,
Expand Down Expand Up @@ -1051,30 +1052,18 @@ function trackRunWorkflowToNode(node: INodeUi) {
void externalHooks.run('nodeView.onRunNode', telemetryPayload);
}
async function openExecution(executionId: string) {
async function onOpenExecution(executionId: string) {
canvasStore.startLoading();
resetWorkspace();
await initializeData();
let data: IExecutionResponse | undefined;
try {
data = await workflowsStore.getExecution(executionId);
} catch (error) {
toast.showError(error, i18n.baseText('nodeView.showError.openExecution.title'));
const data = await openExecution(executionId);
if (!data) {
return;
}
if (data === undefined) {
throw new Error(`Execution with id "${executionId}" could not be found!`);
}
await initializeData();
initializeWorkspace(data.workflowData);
workflowsStore.setWorkflowExecutionData(data);
uiStore.stateIsDirty = false;
canvasStore.stopLoading();
fitView();
canvasEventBus.emit('open:execution', data);
Expand Down Expand Up @@ -1320,7 +1309,7 @@ async function onPostMessageReceived(messageEvent: MessageEvent) {
// so everything it needs has to be sent using post messages and passed down to child components
isProductionExecutionPreview.value = json.executionMode !== 'manual';
await openExecution(json.executionId);
await onOpenExecution(json.executionId);
canOpenNDV.value = json.canOpenNDV ?? true;
hideNodeIssues.value = json.hideNodeIssues ?? false;
isExecutionPreview.value = true;
Expand Down

0 comments on commit 5f6f8a1

Please sign in to comment.