n8n/packages/editor-ui/src/composables/useCanvasTraversal.ts
Alex Grozav 6cd9b996af
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
feat(editor): Add selection navigation using the keyboard on new canvas (#11679)
2024-11-18 19:50:42 +02:00

69 lines
1.8 KiB
TypeScript

import type { CanvasNode } from '@/types';
import type { VueFlowStore } from '@vue-flow/core';
export function useCanvasTraversal({ getIncomers, getOutgoers }: VueFlowStore) {
function sortNodesByVerticalPosition(nodes: CanvasNode[]) {
return nodes.sort((a, b) => a.position.y - b.position.y);
}
function getIncomingNodes(id: string) {
return sortNodesByVerticalPosition(getIncomers(id));
}
function getOutgoingNodes(id: string) {
return sortNodesByVerticalPosition(getOutgoers(id));
}
function getSiblingNodes(id: string) {
const incomingSiblings = getIncomers(id).flatMap((incomingNode) =>
getOutgoers(incomingNode.id),
);
const outgoingSiblings = getOutgoers(id).flatMap((outgoingNode) =>
getIncomers(outgoingNode.id),
);
return sortNodesByVerticalPosition(
[...incomingSiblings, ...outgoingSiblings].filter(
(node, index, nodes) => nodes.findIndex((n) => n.id === node.id) === index,
),
);
}
function getDownstreamNodes(id: string, visited: string[] = []): CanvasNode[] {
if (visited.includes(id)) {
return [];
}
visited.push(id);
const downstreamNodes = getOutgoers(id);
return [
...downstreamNodes,
...downstreamNodes.flatMap((node) => getDownstreamNodes(node.id, visited)),
].filter((node, index, nodes) => nodes.findIndex((n) => n.id === node.id) === index);
}
function getUpstreamNodes(id: string, visited: string[] = []): CanvasNode[] {
if (visited.includes(id)) {
return [];
}
visited.push(id);
const upstreamNodes = getIncomers(id);
return [
...upstreamNodes,
...upstreamNodes.flatMap((node) => getUpstreamNodes(node.id, visited)),
].filter((node, index, nodes) => nodes.findIndex((n) => n.id === node.id) === index);
}
return {
sortNodesByVerticalPosition,
getIncomingNodes,
getOutgoingNodes,
getSiblingNodes,
getDownstreamNodes,
getUpstreamNodes,
};
}