(
nodes: FlowNode[],
edges: FlowEdge[],
targetNodeId: string,
nodeDimensions: Map<string, { width: number; height: number }>,
pad: number = DEFAULT_PADDING
)
| 229 | * @returns Updated nodes with overlaps resolved |
| 230 | */ |
| 231 | export function resolveOverlapsForNode( |
| 232 | nodes: FlowNode[], |
| 233 | edges: FlowEdge[], |
| 234 | targetNodeId: string, |
| 235 | nodeDimensions: Map<string, { width: number; height: number }>, |
| 236 | pad: number = DEFAULT_PADDING |
| 237 | ): FlowNode[] { |
| 238 | const targetNode = nodes.find((n) => n.id === targetNodeId); |
| 239 | if (!targetNode) return nodes; |
| 240 | |
| 241 | const inSameFlow = getConnectedNodeIds(targetNodeId, edges); |
| 242 | |
| 243 | const targetDim = nodeDimensions.get(targetNodeId) || { width: DEFAULT_NODE_WIDTH, height: DEFAULT_NODE_HEIGHT }; |
| 244 | const targetBox: Box = { |
| 245 | id: targetNodeId, |
| 246 | x: targetNode.position.x, |
| 247 | y: targetNode.position.y, |
| 248 | w: targetDim.width, |
| 249 | h: targetDim.height, |
| 250 | }; |
| 251 | |
| 252 | // Only consider nodes in the same flow for overlap with target |
| 253 | const overlappingInFlow: FlowNode[] = []; |
| 254 | nodes.forEach((node) => { |
| 255 | if (node.id === targetNodeId || !inSameFlow.has(node.id)) return; |
| 256 | const nodeDim = nodeDimensions.get(node.id) || { width: DEFAULT_NODE_WIDTH, height: DEFAULT_NODE_HEIGHT }; |
| 257 | const nodeBox: Box = { |
| 258 | id: node.id, |
| 259 | x: node.position.x, |
| 260 | y: node.position.y, |
| 261 | w: nodeDim.width, |
| 262 | h: nodeDim.height, |
| 263 | }; |
| 264 | if (boxesOverlap(targetBox, nodeBox, pad)) overlappingInFlow.push(node); |
| 265 | }); |
| 266 | |
| 267 | if (overlappingInFlow.length === 0) { |
| 268 | return nodes; |
| 269 | } |
| 270 | |
| 271 | // Push down only nodes that overlap with target AND are in the same flow |
| 272 | let updatedNodes = nodes.map((node) => { |
| 273 | if (node.id === targetNodeId) return node; |
| 274 | if (!inSameFlow.has(node.id)) return node; |
| 275 | |
| 276 | const nodeDim = nodeDimensions.get(node.id) || { width: DEFAULT_NODE_WIDTH, height: DEFAULT_NODE_HEIGHT }; |
| 277 | const nodeBox: Box = { |
| 278 | id: node.id, |
| 279 | x: node.position.x, |
| 280 | y: node.position.y, |
| 281 | w: nodeDim.width, |
| 282 | h: nodeDim.height, |
| 283 | }; |
| 284 | |
| 285 | let newY = node.position.y; |
| 286 | if (boxesOverlap(targetBox, nodeBox, pad)) { |
| 287 | newY = Math.max(newY, targetBox.y + targetBox.h + pad); |
| 288 | } |
no test coverage detected