mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-20 11:22:15 +00:00
fix(editor): Delete all connections of nodes with multiple ones when removed from canvas (#15713)
This commit is contained in:
@@ -2419,6 +2419,82 @@ describe('useCanvasOperations', () => {
|
|||||||
|
|
||||||
expect(workflowsStore.removeConnection).not.toHaveBeenCalled();
|
expect(workflowsStore.removeConnection).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should delete all connections of a node with multiple connections', () => {
|
||||||
|
const workflowsStore = mockedStore(useWorkflowsStore);
|
||||||
|
const { deleteConnectionsByNodeId } = useCanvasOperations({ router });
|
||||||
|
|
||||||
|
const sourceNode = createTestNode({ id: 'source', name: 'Source Node' });
|
||||||
|
const targetNode = createTestNode({ id: 'target', name: 'Target Node' });
|
||||||
|
|
||||||
|
workflowsStore.workflow.nodes = [sourceNode, targetNode];
|
||||||
|
workflowsStore.workflow.connections = {
|
||||||
|
[sourceNode.name]: {
|
||||||
|
[NodeConnectionTypes.Main]: [
|
||||||
|
[
|
||||||
|
{ node: targetNode.name, type: NodeConnectionTypes.Main, index: 0 },
|
||||||
|
{ node: targetNode.name, type: NodeConnectionTypes.Main, index: 1 },
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
[targetNode.name]: {
|
||||||
|
[NodeConnectionTypes.Main]: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
workflowsStore.getNodeById = vi.fn().mockImplementation((id) => {
|
||||||
|
if (id === sourceNode.id) return sourceNode;
|
||||||
|
if (id === targetNode.id) return targetNode;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
workflowsStore.getNodeByName = vi.fn().mockImplementation((name) => {
|
||||||
|
if (name === sourceNode.name) return sourceNode;
|
||||||
|
if (name === targetNode.name) return targetNode;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
workflowsStore.removeConnection = vi
|
||||||
|
.fn()
|
||||||
|
.mockImplementation((data: { connection: IConnection[] }) => {
|
||||||
|
const sourceData = data.connection[0];
|
||||||
|
const destinationData = data.connection[1];
|
||||||
|
|
||||||
|
const connections =
|
||||||
|
workflowsStore.workflow.connections[sourceData.node][sourceData.type][sourceData.index];
|
||||||
|
|
||||||
|
for (const index in connections) {
|
||||||
|
if (
|
||||||
|
connections[+index].node === destinationData.node &&
|
||||||
|
connections[+index].type === destinationData.type &&
|
||||||
|
connections[+index].index === destinationData.index
|
||||||
|
) {
|
||||||
|
connections.splice(parseInt(index, 10), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
deleteConnectionsByNodeId(targetNode.id);
|
||||||
|
|
||||||
|
expect(workflowsStore.removeConnection).toHaveBeenCalledTimes(2);
|
||||||
|
|
||||||
|
expect(workflowsStore.removeConnection).toHaveBeenCalledWith({
|
||||||
|
connection: [
|
||||||
|
{ node: sourceNode.name, type: NodeConnectionTypes.Main, index: 0 },
|
||||||
|
{ node: targetNode.name, type: NodeConnectionTypes.Main, index: 0 },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(workflowsStore.removeConnection).toHaveBeenCalledWith({
|
||||||
|
connection: [
|
||||||
|
{ node: sourceNode.name, type: NodeConnectionTypes.Main, index: 0 },
|
||||||
|
{ node: targetNode.name, type: NodeConnectionTypes.Main, index: 1 },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
workflowsStore.workflow.connections[sourceNode.name][NodeConnectionTypes.Main][0],
|
||||||
|
).toEqual([]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('duplicateNodes', () => {
|
describe('duplicateNodes', () => {
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ import type { CanvasLayoutEvent } from './useCanvasLayout';
|
|||||||
import { chatEventBus } from '@n8n/chat/event-buses';
|
import { chatEventBus } from '@n8n/chat/event-buses';
|
||||||
import { isChatNode } from '@/components/CanvasChat/utils';
|
import { isChatNode } from '@/components/CanvasChat/utils';
|
||||||
import { useLogsStore } from '@/stores/logs.store';
|
import { useLogsStore } from '@/stores/logs.store';
|
||||||
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
|
||||||
type AddNodeData = Partial<INodeUi> & {
|
type AddNodeData = Partial<INodeUi> & {
|
||||||
type: string;
|
type: string;
|
||||||
@@ -1122,7 +1123,7 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
|
|||||||
);
|
);
|
||||||
for (const nodeName of checkNodes) {
|
for (const nodeName of checkNodes) {
|
||||||
const node = workflowsStore.nodesByName[nodeName];
|
const node = workflowsStore.nodesByName[nodeName];
|
||||||
if (node.position[0] < sourceNode.position[0]) {
|
if (!node || !sourceNode || node.position[0] < sourceNode.position[0]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1210,7 +1211,7 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
|
|||||||
historyStore.startRecordingUndo();
|
historyStore.startRecordingUndo();
|
||||||
}
|
}
|
||||||
|
|
||||||
const connections = workflowsStore.workflow.connections;
|
const connections = cloneDeep(workflowsStore.workflow.connections);
|
||||||
for (const nodeName of Object.keys(connections)) {
|
for (const nodeName of Object.keys(connections)) {
|
||||||
const node = workflowsStore.getNodeByName(nodeName);
|
const node = workflowsStore.getNodeByName(nodeName);
|
||||||
if (!node) {
|
if (!node) {
|
||||||
|
|||||||
Reference in New Issue
Block a user