feat(workflow): add node duplication
This commit is contained in:
@@ -328,6 +328,50 @@ export function WorkflowCanvas({
|
||||
[editingNodeId, nodes, onEditingNodeIdChange, setNodes, setEdges],
|
||||
);
|
||||
|
||||
const duplicateNode = useCallback(
|
||||
(id: string) => {
|
||||
const source = nodes.find((node) => node.id === id);
|
||||
if (!source || source.type === "start") return;
|
||||
|
||||
const spec = specsByType[source.type as string];
|
||||
if (!spec) return;
|
||||
const limit = spec.constraints.maxInstances;
|
||||
if (
|
||||
limit !== undefined &&
|
||||
nodes.filter((node) => node.type === source.type).length >= limit
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
nodeSeq += 1;
|
||||
const duplicateId = `${source.type}-${Date.now()}-${nodeSeq}`;
|
||||
const sourceData = source.data as WorkflowNodeData;
|
||||
const duplicateData = structuredClone(sourceData);
|
||||
duplicateData.name = `${sourceData.name || spec.displayName}(副本)`;
|
||||
|
||||
setNodes((currentNodes) => [
|
||||
...currentNodes.map((node) => ({ ...node, selected: false })),
|
||||
{
|
||||
id: duplicateId,
|
||||
type: source.type,
|
||||
position: {
|
||||
x: source.position.x + 40,
|
||||
y: source.position.y + 40,
|
||||
},
|
||||
data: duplicateData,
|
||||
selected: true,
|
||||
},
|
||||
]);
|
||||
onEditingNodeIdChange(null);
|
||||
},
|
||||
[
|
||||
nodes,
|
||||
onEditingNodeIdChange,
|
||||
setNodes,
|
||||
specsByType,
|
||||
],
|
||||
);
|
||||
|
||||
const handleNodesChange = useCallback(
|
||||
(changes: NodeChange[]) => {
|
||||
const startIds = new Set(
|
||||
@@ -431,10 +475,12 @@ export function WorkflowCanvas({
|
||||
onEditingEdgeIdChange(null);
|
||||
onEditingNodeIdChange(id);
|
||||
},
|
||||
duplicate: duplicateNode,
|
||||
remove: deleteNode,
|
||||
}),
|
||||
[
|
||||
deleteNode,
|
||||
duplicateNode,
|
||||
onDebugOpenChange,
|
||||
onEditingEdgeIdChange,
|
||||
onEditingNodeIdChange,
|
||||
|
||||
Reference in New Issue
Block a user