diff --git a/src/components/shared/ReactFlow/FlowCanvas/utils/addTask.ts b/src/components/shared/ReactFlow/FlowCanvas/utils/addTask.ts index 412b0e39e..f753b78ca 100644 --- a/src/components/shared/ReactFlow/FlowCanvas/utils/addTask.ts +++ b/src/components/shared/ReactFlow/FlowCanvas/utils/addTask.ts @@ -13,7 +13,7 @@ import { deepClone } from "@/utils/deepClone"; import { getUniqueInputName, getUniqueOutputName, - getUniqueTaskName, + getUniqueTaskId, } from "@/utils/unique"; const addTask = ( @@ -62,7 +62,7 @@ const addTask = ( arguments: taskArguments ?? {}, }; - const taskId = getUniqueTaskName( + const uniqueTaskId = getUniqueTaskId( graphSpec, taskSpec.componentRef.spec?.name ?? "Task", ); @@ -71,7 +71,7 @@ const addTask = ( ...graphSpec, tasks: { ...graphSpec.tasks, - [taskId]: updatedTaskSpec, + [uniqueTaskId]: updatedTaskSpec, }, }; @@ -79,9 +79,9 @@ const addTask = ( } if (nodeType === "input") { - const inputId = getUniqueInputName(newComponentSpec); + const inputName = getUniqueInputName(newComponentSpec); const inputSpec: InputSpec = { - name: inputId, + name: inputName, annotations: positionAnnotations, }; const inputs = (newComponentSpec.inputs ?? []).concat([inputSpec]); @@ -90,9 +90,9 @@ const addTask = ( } if (nodeType === "output") { - const outputId = getUniqueOutputName(newComponentSpec); + const outputName = getUniqueOutputName(newComponentSpec); const outputSpec: OutputSpec = { - name: outputId, + name: outputName, annotations: positionAnnotations, }; diff --git a/src/components/shared/ReactFlow/FlowCanvas/utils/duplicateNodes.ts b/src/components/shared/ReactFlow/FlowCanvas/utils/duplicateNodes.ts index ebe8fc082..948bdacad 100644 --- a/src/components/shared/ReactFlow/FlowCanvas/utils/duplicateNodes.ts +++ b/src/components/shared/ReactFlow/FlowCanvas/utils/duplicateNodes.ts @@ -32,7 +32,7 @@ import { convertTaskCallbacksToNodeCallbacks } from "@/utils/nodes/taskCallbackU import { getUniqueInputName, getUniqueOutputName, - getUniqueTaskName, + getUniqueTaskId, } from "@/utils/unique"; const OFFSET = 10; @@ -78,7 +78,7 @@ export const duplicateNodes = ( if (isTaskNode(node)) { const oldTaskId = nodeIdToTaskId(oldNodeId); - const newTaskId = getUniqueTaskName(graphSpec, oldTaskId); + const newTaskId = getUniqueTaskId(graphSpec, oldTaskId); const newNodeId = taskIdToNodeId(newTaskId); nodeIdMap[oldNodeId] = newNodeId; @@ -101,9 +101,8 @@ export const duplicateNodes = ( (input) => input.name === node.data.label, ); - const newInputId = getUniqueInputName(componentSpec, inputSpec?.name); - - const newNodeId = inputNameToNodeId(newInputId); + const newInputName = getUniqueInputName(componentSpec, inputSpec?.name); + const newNodeId = inputNameToNodeId(newInputName); nodeIdMap[oldNodeId] = newNodeId; @@ -116,19 +115,21 @@ export const duplicateNodes = ( const newInputSpec = { ...inputSpec, - name: newInputId, + name: newInputName, annotations: updatedAnnotations, }; - newInputs[newInputId] = newInputSpec; + newInputs[newInputName] = newInputSpec; } else if (isOutputNode(node)) { const outputSpec = componentSpec.outputs?.find( (output) => output.name === node.data.label, ); - const newOutputId = getUniqueOutputName(componentSpec, outputSpec?.name); - - const newNodeId = outputNameToNodeId(newOutputId); + const newOutputName = getUniqueOutputName( + componentSpec, + outputSpec?.name, + ); + const newNodeId = outputNameToNodeId(newOutputName); nodeIdMap[oldNodeId] = newNodeId; @@ -141,11 +142,11 @@ export const duplicateNodes = ( const newOutputSpec = { ...outputSpec, - name: newOutputId, + name: newOutputName, annotations: updatedAnnotations, }; - newOutputs[newOutputId] = newOutputSpec; + newOutputs[newOutputName] = newOutputSpec; } }); @@ -191,8 +192,8 @@ export const duplicateNodes = ( if (connection !== "none") { /* Reconfigure Outputs */ Object.entries(newOutputs).forEach((output) => { - const [outputId] = output; - const newNodeId = outputNameToNodeId(outputId); + const [outputName] = output; + const newNodeId = outputNameToNodeId(outputName); const oldNodeId = Object.keys(nodeIdMap).find( (key) => nodeIdMap[key] === newNodeId, ); @@ -201,13 +202,13 @@ export const duplicateNodes = ( return; } - const oldOutputId = nodeIdToOutputName(oldNodeId); + const oldOutputName = nodeIdToOutputName(oldNodeId); if (!graphSpec.outputValues) { return; } - const outputValue = graphSpec.outputValues[oldOutputId]; + const outputValue = graphSpec.outputValues[oldOutputName]; if (!outputValue) { return; @@ -242,7 +243,7 @@ export const duplicateNodes = ( (!isInternal && connection === "external") || connection === "all" ) { - updatedGraphOutputs[outputId] = updatedOutputValue; + updatedGraphOutputs[outputName] = updatedOutputValue; } }); } @@ -307,9 +308,9 @@ export const duplicateNodes = ( return newNode; } else if (isInputNode(originalNode)) { - const newInputId = nodeIdToInputName(newNodeId); + const newInputName = nodeIdToInputName(newNodeId); const newInputSpec = updatedInputs.find( - (input) => input.name === newInputId, + (input) => input.name === newInputName, ); if (!newInputSpec) { @@ -337,9 +338,9 @@ export const duplicateNodes = ( return newNode; } else if (isOutputNode(originalNode)) { - const newOutputId = nodeIdToOutputName(newNodeId); + const newOutputName = nodeIdToOutputName(newNodeId); const newOutputSpec = updatedOutputs.find( - (output) => output.name === newOutputId, + (output) => output.name === newOutputName, ); if (!newOutputSpec) { @@ -406,9 +407,11 @@ export const duplicateNodes = ( updatedGraphSpec.tasks[taskId] = newTaskSpec; } else if (isInputNode(node)) { - const inputId = nodeIdToInputName(node.id); + const newInputName = nodeIdToInputName(node.id); - const inputSpec = updatedInputs.find((input) => input.name === inputId); + const inputSpec = updatedInputs.find( + (input) => input.name === newInputName, + ); if (!inputSpec) { return; @@ -427,17 +430,17 @@ export const duplicateNodes = ( }; const updatedInputIndex = updatedInputs.findIndex( - (input) => input.name === inputId, + (input) => input.name === newInputName, ); if (updatedInputIndex !== -1) { updatedInputs[updatedInputIndex] = newInputSpec; } } else if (isOutputNode(node)) { - const outputId = nodeIdToOutputName(node.id); + const newOutputName = nodeIdToOutputName(node.id); const outputSpec = updatedOutputs.find( - (output) => output.name === outputId, + (output) => output.name === newOutputName, ); if (!outputSpec) { @@ -457,7 +460,7 @@ export const duplicateNodes = ( }; const updatedOutputIndex = updatedOutputs.findIndex( - (output) => output.name === outputId, + (output) => output.name === newOutputName, ); if (updatedOutputIndex !== -1) { @@ -516,15 +519,15 @@ function reconfigureConnections( newArgId = newTaskId; } else if ("graphInput" in argument) { - const oldInputId = argument.graphInput.inputName; - oldNodeId = inputNameToNodeId(oldInputId); + const oldInputName = argument.graphInput.inputName; + oldNodeId = inputNameToNodeId(oldInputName); if (!("inputs" in componentSpec)) { throw new Error("ComponentSpec does not contain inputs."); } const inputs = componentSpec.inputs || []; - isExternal = inputs.some((input) => input.name === oldInputId); + isExternal = inputs.some((input) => input.name === oldInputName); const newNodeId = nodeIdMap[oldNodeId]; @@ -532,9 +535,9 @@ function reconfigureConnections( return reconfigureExternalConnection(taskSpec, argKey, mode); } - const newInputId = nodeIdToInputName(newNodeId); + const newInputName = nodeIdToInputName(newNodeId); - newArgId = newInputId; + newArgId = newInputName; } if (!newArgId) { diff --git a/src/components/shared/ReactFlow/FlowCanvas/utils/removeEdge.ts b/src/components/shared/ReactFlow/FlowCanvas/utils/removeEdge.ts index 5654807c8..2aacc0289 100644 --- a/src/components/shared/ReactFlow/FlowCanvas/utils/removeEdge.ts +++ b/src/components/shared/ReactFlow/FlowCanvas/utils/removeEdge.ts @@ -1,7 +1,11 @@ import type { Edge } from "@xyflow/react"; import type { ComponentSpec, GraphImplementation } from "@/utils/componentSpec"; -import { nodeIdToOutputName, nodeIdToTaskId } from "@/utils/nodes/nodeIdUtils"; +import { + nodeIdToInputName, + nodeIdToOutputName, + nodeIdToTaskId, +} from "@/utils/nodes/nodeIdUtils"; import { setGraphOutputValue } from "./setGraphOutputValue"; import { setTaskArgument } from "./setTaskArgument"; @@ -10,7 +14,11 @@ export const removeEdge = (edge: Edge, componentSpec: ComponentSpec) => { const graphSpec = (componentSpec.implementation as GraphImplementation) ?.graph; - const inputName = edge.targetHandle?.replace(/^input_/, ""); + if (!edge.targetHandle) { + return componentSpec; + } + + const inputName = nodeIdToInputName(edge.targetHandle); const updatedComponentSpec = { ...componentSpec, diff --git a/src/components/shared/ReactFlow/FlowCanvas/utils/replaceTaskNode.ts b/src/components/shared/ReactFlow/FlowCanvas/utils/replaceTaskNode.ts index e0b9cf89f..5ccfb83fe 100644 --- a/src/components/shared/ReactFlow/FlowCanvas/utils/replaceTaskNode.ts +++ b/src/components/shared/ReactFlow/FlowCanvas/utils/replaceTaskNode.ts @@ -6,7 +6,7 @@ import type { TaskSpec, } from "@/utils/componentSpec"; import { deepClone } from "@/utils/deepClone"; -import { getUniqueTaskName } from "@/utils/unique"; +import { getUniqueTaskId } from "@/utils/unique"; export const replaceTaskNode = ( taskId: string, @@ -15,15 +15,14 @@ export const replaceTaskNode = ( ) => { const updatedGraphSpec = deepClone(graphSpec); - const taskName = newComponentRef.spec?.name; - const newTaskInputs = newComponentRef.spec?.inputs; - const newTaskOutputs = newComponentRef.spec?.outputs; - const newTaskId = getUniqueTaskName(graphSpec, taskName); - const oldTaskId = taskId; const oldTask = deepClone(updatedGraphSpec.tasks[oldTaskId]) as TaskSpec; const oldTaskInputs = oldTask.componentRef.spec?.inputs; + const newTaskInputs = newComponentRef.spec?.inputs; + const newTaskOutputs = newComponentRef.spec?.outputs; + const newTaskId = getUniqueTaskId(graphSpec, oldTaskId); + // Migrate the task to the new componentRef const updatedTask = { ...oldTask, diff --git a/src/hooks/useComponentSpecToEdges.ts b/src/hooks/useComponentSpecToEdges.ts index 48c9c3190..e3bad6e17 100644 --- a/src/hooks/useComponentSpecToEdges.ts +++ b/src/hooks/useComponentSpecToEdges.ts @@ -6,13 +6,14 @@ import { } from "@xyflow/react"; import { useEffect } from "react"; -import type { - ArgumentType, - ComponentSpec, - GraphInputArgument, - GraphSpec, - TaskOutputArgument, - TaskSpec, +import { + type ArgumentType, + type ComponentSpec, + type GraphInputArgument, + type GraphSpec, + isGraphImplementation, + type TaskOutputArgument, + type TaskSpec, } from "@/utils/componentSpec"; import { inputNameToNodeId, @@ -42,7 +43,7 @@ const useComponentSpecToEdges = ( }; const getEdges = (componentSpec: ComponentSpec) => { - if (!("graph" in componentSpec.implementation)) { + if (!isGraphImplementation(componentSpec.implementation)) { return []; } diff --git a/src/utils/unique.ts b/src/utils/unique.ts index e5ab4149c..d353ab240 100644 --- a/src/utils/unique.ts +++ b/src/utils/unique.ts @@ -33,7 +33,7 @@ export const getUniqueOutputName = ( ); }; -export const getUniqueTaskName = ( +export const getUniqueTaskId = ( graphSpec: GraphSpec, name: string = "Task", ) => {