Skip to content

Commit

Permalink
fix(editor): Import copy-pasted workflow only after nodes are added t…
Browse files Browse the repository at this point in the history
…o new canvas (no-changelog) (#11434)
  • Loading branch information
alexgrozav authored Oct 28, 2024
1 parent d4c4db8 commit ad29235
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { IConnection, Workflow } from 'n8n-workflow';
import { NodeConnectionType, NodeHelpers } from 'n8n-workflow';
import { useCanvasOperations } from '@/composables/useCanvasOperations';
import type { CanvasNode } from '@/types';
import { CanvasConnectionMode } from '@/types';
import type { ICredentialsResponse, INodeUi, IWorkflowDb } from '@/Interface';
import { RemoveNodeCommand } from '@/models/history';
import { useWorkflowsStore } from '@/stores/workflows.store';
Expand All @@ -25,6 +26,7 @@ import { mockedStore } from '@/__tests__/utils';
import { SET_NODE_TYPE, STICKY_NODE_TYPE, STORES } from '@/constants';
import type { Connection } from '@vue-flow/core';
import { useClipboard } from '@/composables/useClipboard';
import { createCanvasConnectionHandleString } from '@/utils/canvasUtilsV2';

vi.mock('vue-router', async (importOriginal) => {
const actual = await importOriginal<{}>();
Expand Down Expand Up @@ -966,15 +968,35 @@ describe('useCanvasOperations', () => {
const connections = [
{
source: nodes[0].id,
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
index: 0,
type: NodeConnectionType.Main,
}),
target: nodes[1].id,
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
index: 0,
type: NodeConnectionType.Main,
}),
data: {
source: { type: NodeConnectionType.Main, index: 0 },
target: { type: NodeConnectionType.Main, index: 0 },
},
},
{
source: nodes[1].id,
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
index: 0,
type: NodeConnectionType.Main,
}),
target: nodes[2].id,
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
index: 0,
type: NodeConnectionType.Main,
}),
data: {
source: { type: NodeConnectionType.Main, index: 0 },
target: { type: NodeConnectionType.Main, index: 0 },
Expand All @@ -993,7 +1015,7 @@ describe('useCanvasOperations', () => {
nodeTypesStore.getNodeType = vi.fn().mockReturnValue(nodeType);

const { addConnections } = useCanvasOperations({ router });
addConnections(connections);
await addConnections(connections);

expect(workflowsStore.addConnection).toHaveBeenCalledWith({
connection: [
Expand Down
31 changes: 6 additions & 25 deletions packages/editor-ui/src/composables/useCanvasOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ import {
generateOffsets,
PUSH_NODES_OFFSET,
} from '@/utils/nodeViewUtils';
import { isValidNodeConnectionType } from '@/utils/typeGuards';
import type { Connection } from '@vue-flow/core';
import type {
IConnection,
Expand Down Expand Up @@ -1374,36 +1373,18 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
return targetNodeHasInputConnectionOfType && targetNodeHasInputConnectionPortOfType;
}

function addConnections(
async function addConnections(
connections: CanvasConnectionCreateData[] | CanvasConnection[],
{ trackBulk = true, trackHistory = false } = {},
) {
await nextTick(); // Connection creation relies on the nodes being already added to the store

if (trackBulk && trackHistory) {
historyStore.startRecordingUndo();
}

for (const { source, target, data } of connections) {
createConnection(
{
source,
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: isValidNodeConnectionType(data?.source.type)
? data?.source.type
: NodeConnectionType.Main,
index: data?.source.index ?? 0,
}),
target,
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: isValidNodeConnectionType(data?.target.type)
? data?.target.type
: NodeConnectionType.Main,
index: data?.target.index ?? 0,
}),
},
{ trackHistory },
);
for (const connection of connections) {
createConnection(connection, { trackHistory });
}

if (trackBulk && trackHistory) {
Expand Down Expand Up @@ -1621,7 +1602,7 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
}

await addNodes(Object.values(tempWorkflow.nodes), { trackBulk: false, trackHistory });
addConnections(
await addConnections(
mapLegacyConnectionsToCanvasConnections(
tempWorkflow.connectionsBySourceNode,
Object.values(tempWorkflow.nodes),
Expand Down
2 changes: 2 additions & 0 deletions packages/editor-ui/src/types/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ export type CanvasConnection = DefaultEdge<CanvasConnectionData>;

export type CanvasConnectionCreateData = {
source: string;
sourceHandle: string;
target: string;
targetHandle: string;
data: {
source: PartialBy<IConnection, 'node'>;
target: PartialBy<IConnection, 'node'>;
Expand Down
16 changes: 14 additions & 2 deletions packages/editor-ui/src/views/NodeView.v2.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import type {
CanvasNodeMoveEvent,
ConnectStartEvent,
} from '@/types';
import { CanvasNodeRenderType } from '@/types';
import { CanvasNodeRenderType, CanvasConnectionMode } from '@/types';
import {
CHAT_TRIGGER_NODE_TYPE,
EnterpriseEditionFeature,
Expand Down Expand Up @@ -105,6 +105,8 @@ import { useClipboard } from '@/composables/useClipboard';
import { useBeforeUnload } from '@/composables/useBeforeUnload';
import { getResourcePermissions } from '@/permissions';
import NodeViewUnfinishedWorkflowMessage from '@/components/NodeViewUnfinishedWorkflowMessage.vue';
import { createCanvasConnectionHandleString } from '@/utils/canvasUtilsV2';
import { isValidNodeConnectionType } from '@/utils/typeGuards';
const LazyNodeCreation = defineAsyncComponent(
async () => await import('@/components/Node/NodeCreation.vue'),
Expand Down Expand Up @@ -879,7 +881,17 @@ async function onAddNodesAndConnections(
return {
source: fromNode.id,
sourceHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: isValidNodeConnectionType(type) ? type : NodeConnectionType.Main,
index: from.outputIndex ?? 0,
}),
target: toNode.id,
targetHandle: createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: isValidNodeConnectionType(type) ? type : NodeConnectionType.Main,
index: to.inputIndex ?? 0,
}),
data: {
source: {
index: from.outputIndex ?? 0,
Expand All @@ -893,7 +905,7 @@ async function onAddNodesAndConnections(
};
});
addConnections(mappedConnections);
await addConnections(mappedConnections);
uiStore.resetLastInteractedWith();
selectNodes([addedNodes[addedNodes.length - 1].id]);
Expand Down

0 comments on commit ad29235

Please sign in to comment.