feat(editor): Add ability to add a node between two nodes in new canvas (no-changelog) (#10006)

This commit is contained in:
Alex Grozav
2024-07-11 17:05:51 +03:00
committed by GitHub
parent d651be4e01
commit 1aae65dfdc
12 changed files with 517 additions and 146 deletions

View File

@@ -1,11 +1,13 @@
import type { IConnection, IConnections, INodeTypeDescription } from 'n8n-workflow';
import type { INodeUi } from '@/Interface';
import type { CanvasConnection, CanvasConnectionPortType, CanvasConnectionPort } from '@/types';
import type { CanvasConnection, CanvasConnectionPort } from '@/types';
import { CanvasConnectionMode } from '@/types';
import type { Connection } from '@vue-flow/core';
import { v4 as uuid } from 'uuid';
import { isValidCanvasConnectionMode, isValidNodeConnectionType } from '@/utils/typeGuards';
import { NodeConnectionType } from 'n8n-workflow';
import type { Connection as VueFlowConnection } from '@vue-flow/core/dist/types/connection';
import { PUSH_NODES_OFFSET } from '@/utils/nodeViewUtils';
export function mapLegacyConnectionsToCanvasConnections(
legacyConnections: IConnections,
@@ -14,33 +16,54 @@ export function mapLegacyConnectionsToCanvasConnections(
const mappedConnections: CanvasConnection[] = [];
Object.keys(legacyConnections).forEach((fromNodeName) => {
const fromId = nodes.find((node) => node.name === fromNodeName)?.id;
const fromConnectionTypes = Object.keys(legacyConnections[fromNodeName]);
const fromId = nodes.find((node) => node.name === fromNodeName)?.id ?? '';
const fromConnectionTypes = Object.keys(
legacyConnections[fromNodeName],
) as NodeConnectionType[];
fromConnectionTypes.forEach((fromConnectionType) => {
const fromPorts = legacyConnections[fromNodeName][fromConnectionType];
fromPorts.forEach((toPorts, fromIndex) => {
toPorts.forEach((toPort) => {
const toId = nodes.find((node) => node.name === toPort.node)?.id;
const toConnectionType = toPort.type;
const toId = nodes.find((node) => node.name === toPort.node)?.id ?? '';
const toConnectionType = toPort.type as NodeConnectionType;
const toIndex = toPort.index;
const sourceHandle = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Output,
type: fromConnectionType,
index: fromIndex,
});
const targetHandle = createCanvasConnectionHandleString({
mode: CanvasConnectionMode.Input,
type: toConnectionType,
index: toIndex,
});
const connectionId = createCanvasConnectionId({
source: fromId,
sourceHandle,
target: toId,
targetHandle,
});
if (fromId && toId) {
mappedConnections.push({
id: `[${fromId}/${fromConnectionType}/${fromIndex}][${toId}/${toConnectionType}/${toIndex}]`,
id: connectionId,
source: fromId,
target: toId,
sourceHandle: `${CanvasConnectionMode.Output}/${fromConnectionType}/${fromIndex}`,
targetHandle: `${CanvasConnectionMode.Input}/${toConnectionType}/${toIndex}`,
sourceHandle,
targetHandle,
data: {
fromNodeName,
source: {
index: fromIndex,
type: fromConnectionType as CanvasConnectionPortType,
type: fromConnectionType,
},
target: {
index: toIndex,
type: toConnectionType as CanvasConnectionPortType,
type: toConnectionType,
},
},
});
@@ -71,6 +94,21 @@ export function parseCanvasConnectionHandleString(handle: string | null | undefi
};
}
/**
* Get the width and height of a connection
*
* @TODO See whether this is actually needed or just a legacy jsPlumb check
*/
export function getVueFlowConnectorLengths(connection: VueFlowConnection): [number, number] {
const connectionId = createCanvasConnectionId(connection);
const edgeRef = document.getElementById(connectionId);
if (!edgeRef) {
return [PUSH_NODES_OFFSET, PUSH_NODES_OFFSET];
}
return [edgeRef.clientWidth, edgeRef.clientHeight];
}
export function createCanvasConnectionHandleString({
mode,
type = NodeConnectionType.Main,
@@ -83,6 +121,10 @@ export function createCanvasConnectionHandleString({
return `${mode}/${type}/${index}`;
}
export function createCanvasConnectionId(connection: Connection) {
return `[${connection.source}/${connection.sourceHandle}][${connection.target}/${connection.targetHandle}]`;
}
export function mapCanvasConnectionToLegacyConnection(
sourceNode: INodeUi,
targetNode: INodeUi,