Feature/newnew workflow loop node (#14863)
Co-authored-by: arkunzz <4873204@qq.com>
This commit is contained in:
@@ -29,6 +29,8 @@ import {
|
||||
CUSTOM_EDGE,
|
||||
ITERATION_CHILDREN_Z_INDEX,
|
||||
ITERATION_PADDING,
|
||||
LOOP_CHILDREN_Z_INDEX,
|
||||
LOOP_PADDING,
|
||||
NODES_INITIAL_DATA,
|
||||
NODE_WIDTH_X_OFFSET,
|
||||
X_OFFSET,
|
||||
@@ -42,9 +44,12 @@ import {
|
||||
} from '../utils'
|
||||
import { CUSTOM_NOTE_NODE } from '../note-node/constants'
|
||||
import type { IterationNodeType } from '../nodes/iteration/types'
|
||||
import type { LoopNodeType } from '../nodes/loop/types'
|
||||
import { CUSTOM_ITERATION_START_NODE } from '../nodes/iteration-start/constants'
|
||||
import { CUSTOM_LOOP_START_NODE } from '../nodes/loop-start/constants'
|
||||
import type { VariableAssignerNodeType } from '../nodes/variable-assigner/types'
|
||||
import { useNodeIterationInteractions } from '../nodes/iteration/use-interactions'
|
||||
import { useNodeLoopInteractions } from '../nodes/loop/use-interactions'
|
||||
import { useWorkflowHistoryStore } from '../workflow-history-store'
|
||||
import { useNodesSyncDraft } from './use-nodes-sync-draft'
|
||||
import { useHelpline } from './use-helpline'
|
||||
@@ -73,6 +78,10 @@ export const useNodesInteractions = () => {
|
||||
handleNodeIterationChildDrag,
|
||||
handleNodeIterationChildrenCopy,
|
||||
} = useNodeIterationInteractions()
|
||||
const {
|
||||
handleNodeLoopChildDrag,
|
||||
handleNodeLoopChildrenCopy,
|
||||
} = useNodeLoopInteractions()
|
||||
const dragNodeStartPosition = useRef({ x: 0, y: 0 } as { x: number; y: number })
|
||||
|
||||
const { saveStateToHistory, undo, redo } = useWorkflowHistory()
|
||||
@@ -86,6 +95,9 @@ export const useNodesInteractions = () => {
|
||||
if (node.type === CUSTOM_ITERATION_START_NODE || node.type === CUSTOM_NOTE_NODE)
|
||||
return
|
||||
|
||||
if (node.type === CUSTOM_LOOP_START_NODE || node.type === CUSTOM_NOTE_NODE)
|
||||
return
|
||||
|
||||
dragNodeStartPosition.current = { x: node.position.x, y: node.position.y }
|
||||
}, [workflowStore, getNodesReadOnly])
|
||||
|
||||
@@ -96,6 +108,9 @@ export const useNodesInteractions = () => {
|
||||
if (node.type === CUSTOM_ITERATION_START_NODE)
|
||||
return
|
||||
|
||||
if (node.type === CUSTOM_LOOP_START_NODE)
|
||||
return
|
||||
|
||||
const {
|
||||
getNodes,
|
||||
setNodes,
|
||||
@@ -105,6 +120,7 @@ export const useNodesInteractions = () => {
|
||||
const nodes = getNodes()
|
||||
|
||||
const { restrictPosition } = handleNodeIterationChildDrag(node)
|
||||
const { restrictPosition: restrictLoopPosition } = handleNodeLoopChildDrag(node)
|
||||
|
||||
const {
|
||||
showHorizontalHelpLineNodes,
|
||||
@@ -120,6 +136,8 @@ export const useNodesInteractions = () => {
|
||||
currentNode.position.x = showVerticalHelpLineNodes[0].position.x
|
||||
else if (restrictPosition.x !== undefined)
|
||||
currentNode.position.x = restrictPosition.x
|
||||
else if (restrictLoopPosition.x !== undefined)
|
||||
currentNode.position.x = restrictLoopPosition.x
|
||||
else
|
||||
currentNode.position.x = node.position.x
|
||||
|
||||
@@ -127,12 +145,13 @@ export const useNodesInteractions = () => {
|
||||
currentNode.position.y = showHorizontalHelpLineNodes[0].position.y
|
||||
else if (restrictPosition.y !== undefined)
|
||||
currentNode.position.y = restrictPosition.y
|
||||
else if (restrictLoopPosition.y !== undefined)
|
||||
currentNode.position.y = restrictLoopPosition.y
|
||||
else
|
||||
currentNode.position.y = node.position.y
|
||||
})
|
||||
|
||||
setNodes(newNodes)
|
||||
}, [store, getNodesReadOnly, handleSetHelpline, handleNodeIterationChildDrag])
|
||||
}, [getNodesReadOnly, store, handleNodeIterationChildDrag, handleNodeLoopChildDrag, handleSetHelpline])
|
||||
|
||||
const handleNodeDragStop = useCallback<NodeDragHandler>((_, node) => {
|
||||
const {
|
||||
@@ -163,6 +182,9 @@ export const useNodesInteractions = () => {
|
||||
if (node.type === CUSTOM_NOTE_NODE || node.type === CUSTOM_ITERATION_START_NODE)
|
||||
return
|
||||
|
||||
if (node.type === CUSTOM_LOOP_START_NODE || node.type === CUSTOM_NOTE_NODE)
|
||||
return
|
||||
|
||||
const {
|
||||
getNodes,
|
||||
setNodes,
|
||||
@@ -237,6 +259,9 @@ export const useNodesInteractions = () => {
|
||||
if (node.type === CUSTOM_NOTE_NODE || node.type === CUSTOM_ITERATION_START_NODE)
|
||||
return
|
||||
|
||||
if (node.type === CUSTOM_NOTE_NODE || node.type === CUSTOM_LOOP_START_NODE)
|
||||
return
|
||||
|
||||
const {
|
||||
setEnteringNodePayload,
|
||||
} = workflowStore.getState()
|
||||
@@ -311,6 +336,8 @@ export const useNodesInteractions = () => {
|
||||
const handleNodeClick = useCallback<NodeMouseHandler>((_, node) => {
|
||||
if (node.type === CUSTOM_ITERATION_START_NODE)
|
||||
return
|
||||
if (node.type === CUSTOM_LOOP_START_NODE)
|
||||
return
|
||||
handleNodeSelect(node.id)
|
||||
}, [handleNodeSelect])
|
||||
|
||||
@@ -344,6 +371,10 @@ export const useNodesInteractions = () => {
|
||||
if (edges.find(edge => edge.source === source && edge.sourceHandle === sourceHandle && edge.target === target && edge.targetHandle === targetHandle))
|
||||
return
|
||||
|
||||
const parendNode = nodes.find(node => node.id === targetNode?.parentId)
|
||||
const isInIteration = parendNode && parendNode.data.type === BlockEnum.Iteration
|
||||
const isInLoop = !!parendNode && parendNode.data.type === BlockEnum.Loop
|
||||
|
||||
const newEdge = {
|
||||
id: `${source}-${sourceHandle}-${target}-${targetHandle}`,
|
||||
type: CUSTOM_EDGE,
|
||||
@@ -354,10 +385,12 @@ export const useNodesInteractions = () => {
|
||||
data: {
|
||||
sourceType: nodes.find(node => node.id === source)!.data.type,
|
||||
targetType: nodes.find(node => node.id === target)!.data.type,
|
||||
isInIteration: !!targetNode?.parentId,
|
||||
iteration_id: targetNode?.parentId,
|
||||
isInIteration,
|
||||
iteration_id: isInIteration ? targetNode?.parentId : undefined,
|
||||
isInLoop,
|
||||
loop_id: isInLoop ? targetNode?.parentId : undefined,
|
||||
},
|
||||
zIndex: targetNode?.parentId ? ITERATION_CHILDREN_Z_INDEX : 0,
|
||||
zIndex: targetNode?.parentId ? (isInIteration ? ITERATION_CHILDREN_Z_INDEX : LOOP_CHILDREN_Z_INDEX) : 0,
|
||||
}
|
||||
const nodesConnectedSourceOrTargetHandleIdsMap = getNodesConnectedSourceOrTargetHandleIdsMap(
|
||||
[
|
||||
@@ -554,6 +587,45 @@ export const useNodesInteractions = () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentNode.data.type === BlockEnum.Loop) {
|
||||
const loopChildren = nodes.filter(node => node.parentId === currentNode.id)
|
||||
|
||||
if (loopChildren.length) {
|
||||
if (currentNode.data._isBundled) {
|
||||
loopChildren.forEach((child) => {
|
||||
handleNodeDelete(child.id)
|
||||
})
|
||||
return handleNodeDelete(nodeId)
|
||||
}
|
||||
else {
|
||||
if (loopChildren.length === 1) {
|
||||
handleNodeDelete(loopChildren[0].id)
|
||||
handleNodeDelete(nodeId)
|
||||
|
||||
return
|
||||
}
|
||||
const { setShowConfirm, showConfirm } = workflowStore.getState()
|
||||
|
||||
if (!showConfirm) {
|
||||
setShowConfirm({
|
||||
title: t('workflow.nodes.loop.deleteTitle'),
|
||||
desc: t('workflow.nodes.loop.deleteDesc') || '',
|
||||
onConfirm: () => {
|
||||
loopChildren.forEach((child) => {
|
||||
handleNodeDelete(child.id)
|
||||
})
|
||||
handleNodeDelete(nodeId)
|
||||
handleSyncWorkflowDraft()
|
||||
setShowConfirm(undefined)
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const connectedEdges = getConnectedEdges([{ id: nodeId } as Node], edges)
|
||||
const nodesConnectedSourceOrTargetHandleIdsMap = getNodesConnectedSourceOrTargetHandleIdsMap(connectedEdges.map(edge => ({ type: 'remove', edge })), nodes)
|
||||
const newNodes = produce(nodes, (draft: Node[]) => {
|
||||
@@ -612,6 +684,7 @@ export const useNodesInteractions = () => {
|
||||
const {
|
||||
newNode,
|
||||
newIterationStartNode,
|
||||
newLoopStartNode,
|
||||
} = generateNewNode({
|
||||
data: {
|
||||
...NODES_INITIAL_DATA[nodeType],
|
||||
@@ -640,13 +713,28 @@ export const useNodesInteractions = () => {
|
||||
}
|
||||
newNode.parentId = prevNode.parentId
|
||||
newNode.extent = prevNode.extent
|
||||
|
||||
const parentNode = nodes.find(node => node.id === prevNode.parentId) || null
|
||||
const isInIteration = !!parentNode && parentNode.data.type === BlockEnum.Iteration
|
||||
const isInLoop = !!parentNode && parentNode.data.type === BlockEnum.Loop
|
||||
|
||||
if (prevNode.parentId) {
|
||||
newNode.data.isInIteration = true
|
||||
newNode.data.iteration_id = prevNode.parentId
|
||||
newNode.zIndex = ITERATION_CHILDREN_Z_INDEX
|
||||
if (newNode.data.type === BlockEnum.Answer || newNode.data.type === BlockEnum.Tool || newNode.data.type === BlockEnum.Assigner) {
|
||||
const parentIterNodeIndex = nodes.findIndex(node => node.id === prevNode.parentId)
|
||||
const iterNodeData: IterationNodeType = nodes[parentIterNodeIndex].data
|
||||
newNode.data.isInIteration = isInIteration
|
||||
newNode.data.isInLoop = isInLoop
|
||||
if (isInIteration) {
|
||||
newNode.data.iteration_id = parentNode.id
|
||||
newNode.zIndex = ITERATION_CHILDREN_Z_INDEX
|
||||
}
|
||||
if (isInLoop) {
|
||||
newNode.data.loop_id = parentNode.id
|
||||
newNode.zIndex = LOOP_CHILDREN_Z_INDEX
|
||||
}
|
||||
if (isInIteration && (newNode.data.type === BlockEnum.Answer || newNode.data.type === BlockEnum.Tool || newNode.data.type === BlockEnum.Assigner)) {
|
||||
const iterNodeData: IterationNodeType = parentNode.data
|
||||
iterNodeData._isShowTips = true
|
||||
}
|
||||
if (isInLoop && (newNode.data.type === BlockEnum.Answer || newNode.data.type === BlockEnum.Tool || newNode.data.type === BlockEnum.Assigner)) {
|
||||
const iterNodeData: IterationNodeType = parentNode.data
|
||||
iterNodeData._isShowTips = true
|
||||
}
|
||||
}
|
||||
@@ -661,11 +749,13 @@ export const useNodesInteractions = () => {
|
||||
data: {
|
||||
sourceType: prevNode.data.type,
|
||||
targetType: newNode.data.type,
|
||||
isInIteration: !!prevNode.parentId,
|
||||
iteration_id: prevNode.parentId,
|
||||
isInIteration,
|
||||
isInLoop,
|
||||
iteration_id: isInIteration ? prevNode.parentId : undefined,
|
||||
loop_id: isInLoop ? prevNode.parentId : undefined,
|
||||
_connectedNodeIsSelected: true,
|
||||
},
|
||||
zIndex: prevNode.parentId ? ITERATION_CHILDREN_Z_INDEX : 0,
|
||||
zIndex: prevNode.parentId ? (isInIteration ? ITERATION_CHILDREN_Z_INDEX : LOOP_CHILDREN_Z_INDEX) : 0,
|
||||
}
|
||||
const nodesConnectedSourceOrTargetHandleIdsMap = getNodesConnectedSourceOrTargetHandleIdsMap(
|
||||
[
|
||||
@@ -686,10 +776,17 @@ export const useNodesInteractions = () => {
|
||||
|
||||
if (node.data.type === BlockEnum.Iteration && prevNode.parentId === node.id)
|
||||
node.data._children?.push(newNode.id)
|
||||
|
||||
if (node.data.type === BlockEnum.Loop && prevNode.parentId === node.id)
|
||||
node.data._children?.push(newNode.id)
|
||||
})
|
||||
draft.push(newNode)
|
||||
|
||||
if (newIterationStartNode)
|
||||
draft.push(newIterationStartNode)
|
||||
|
||||
if (newLoopStartNode)
|
||||
draft.push(newLoopStartNode)
|
||||
})
|
||||
|
||||
if (newNode.data.type === BlockEnum.VariableAssigner || newNode.data.type === BlockEnum.VariableAggregator) {
|
||||
@@ -736,10 +833,22 @@ export const useNodesInteractions = () => {
|
||||
}
|
||||
newNode.parentId = nextNode.parentId
|
||||
newNode.extent = nextNode.extent
|
||||
if (nextNode.parentId) {
|
||||
newNode.data.isInIteration = true
|
||||
newNode.data.iteration_id = nextNode.parentId
|
||||
newNode.zIndex = ITERATION_CHILDREN_Z_INDEX
|
||||
|
||||
const parentNode = nodes.find(node => node.id === nextNode.parentId) || null
|
||||
const isInIteration = !!parentNode && parentNode.data.type === BlockEnum.Iteration
|
||||
const isInLoop = !!parentNode && parentNode.data.type === BlockEnum.Loop
|
||||
|
||||
if (parentNode && nextNode.parentId) {
|
||||
newNode.data.isInIteration = isInIteration
|
||||
newNode.data.isInLoop = isInLoop
|
||||
if (isInIteration) {
|
||||
newNode.data.iteration_id = parentNode.id
|
||||
newNode.zIndex = ITERATION_CHILDREN_Z_INDEX
|
||||
}
|
||||
if (isInLoop) {
|
||||
newNode.data.loop_id = parentNode.id
|
||||
newNode.zIndex = LOOP_CHILDREN_Z_INDEX
|
||||
}
|
||||
}
|
||||
|
||||
let newEdge
|
||||
@@ -755,11 +864,13 @@ export const useNodesInteractions = () => {
|
||||
data: {
|
||||
sourceType: newNode.data.type,
|
||||
targetType: nextNode.data.type,
|
||||
isInIteration: !!nextNode.parentId,
|
||||
iteration_id: nextNode.parentId,
|
||||
isInIteration,
|
||||
isInLoop,
|
||||
iteration_id: isInIteration ? nextNode.parentId : undefined,
|
||||
loop_id: isInLoop ? nextNode.parentId : undefined,
|
||||
_connectedNodeIsSelected: true,
|
||||
},
|
||||
zIndex: nextNode.parentId ? ITERATION_CHILDREN_Z_INDEX : 0,
|
||||
zIndex: nextNode.parentId ? (isInIteration ? ITERATION_CHILDREN_Z_INDEX : LOOP_CHILDREN_Z_INDEX) : 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -796,10 +907,20 @@ export const useNodesInteractions = () => {
|
||||
node.data.start_node_id = newNode.id
|
||||
node.data.startNodeType = newNode.data.type
|
||||
}
|
||||
|
||||
if (node.data.type === BlockEnum.Loop && nextNode.parentId === node.id)
|
||||
node.data._children?.push(newNode.id)
|
||||
|
||||
if (node.data.type === BlockEnum.Loop && node.data.start_node_id === nextNodeId) {
|
||||
node.data.start_node_id = newNode.id
|
||||
node.data.startNodeType = newNode.data.type
|
||||
}
|
||||
})
|
||||
draft.push(newNode)
|
||||
if (newIterationStartNode)
|
||||
draft.push(newIterationStartNode)
|
||||
if (newLoopStartNode)
|
||||
draft.push(newLoopStartNode)
|
||||
})
|
||||
if (newEdge) {
|
||||
const newEdges = produce(edges, (draft) => {
|
||||
@@ -840,10 +961,22 @@ export const useNodesInteractions = () => {
|
||||
}
|
||||
newNode.parentId = prevNode.parentId
|
||||
newNode.extent = prevNode.extent
|
||||
if (prevNode.parentId) {
|
||||
newNode.data.isInIteration = true
|
||||
newNode.data.iteration_id = prevNode.parentId
|
||||
newNode.zIndex = ITERATION_CHILDREN_Z_INDEX
|
||||
|
||||
const parentNode = nodes.find(node => node.id === prevNode.parentId) || null
|
||||
const isInIteration = !!parentNode && parentNode.data.type === BlockEnum.Iteration
|
||||
const isInLoop = !!parentNode && parentNode.data.type === BlockEnum.Loop
|
||||
|
||||
if (parentNode && prevNode.parentId) {
|
||||
newNode.data.isInIteration = isInIteration
|
||||
newNode.data.isInLoop = isInLoop
|
||||
if (isInIteration) {
|
||||
newNode.data.iteration_id = parentNode.id
|
||||
newNode.zIndex = ITERATION_CHILDREN_Z_INDEX
|
||||
}
|
||||
if (isInLoop) {
|
||||
newNode.data.loop_id = parentNode.id
|
||||
newNode.zIndex = LOOP_CHILDREN_Z_INDEX
|
||||
}
|
||||
}
|
||||
|
||||
const currentEdgeIndex = edges.findIndex(edge => edge.source === prevNodeId && edge.target === nextNodeId)
|
||||
@@ -857,13 +990,20 @@ export const useNodesInteractions = () => {
|
||||
data: {
|
||||
sourceType: prevNode.data.type,
|
||||
targetType: newNode.data.type,
|
||||
isInIteration: !!prevNode.parentId,
|
||||
iteration_id: prevNode.parentId,
|
||||
isInIteration,
|
||||
isInLoop,
|
||||
iteration_id: isInIteration ? prevNode.parentId : undefined,
|
||||
loop_id: isInLoop ? prevNode.parentId : undefined,
|
||||
_connectedNodeIsSelected: true,
|
||||
},
|
||||
zIndex: prevNode.parentId ? ITERATION_CHILDREN_Z_INDEX : 0,
|
||||
zIndex: prevNode.parentId ? (isInIteration ? ITERATION_CHILDREN_Z_INDEX : LOOP_CHILDREN_Z_INDEX) : 0,
|
||||
}
|
||||
let newNextEdge: Edge | null = null
|
||||
|
||||
const nextNodeParentNode = nodes.find(node => node.id === nextNode.parentId) || null
|
||||
const isNextNodeInIteration = !!nextNodeParentNode && nextNodeParentNode.data.type === BlockEnum.Iteration
|
||||
const isNextNodeInLoop = !!nextNodeParentNode && nextNodeParentNode.data.type === BlockEnum.Loop
|
||||
|
||||
if (nodeType !== BlockEnum.IfElse && nodeType !== BlockEnum.QuestionClassifier) {
|
||||
newNextEdge = {
|
||||
id: `${newNode.id}-${sourceHandle}-${nextNodeId}-${nextNodeTargetHandle}`,
|
||||
@@ -875,11 +1015,13 @@ export const useNodesInteractions = () => {
|
||||
data: {
|
||||
sourceType: newNode.data.type,
|
||||
targetType: nextNode.data.type,
|
||||
isInIteration: !!nextNode.parentId,
|
||||
iteration_id: nextNode.parentId,
|
||||
isInIteration: isNextNodeInIteration,
|
||||
isInLoop: isNextNodeInLoop,
|
||||
iteration_id: isNextNodeInIteration ? nextNode.parentId : undefined,
|
||||
loop_id: isNextNodeInLoop ? nextNode.parentId : undefined,
|
||||
_connectedNodeIsSelected: true,
|
||||
},
|
||||
zIndex: nextNode.parentId ? ITERATION_CHILDREN_Z_INDEX : 0,
|
||||
zIndex: nextNode.parentId ? (isNextNodeInIteration ? ITERATION_CHILDREN_Z_INDEX : LOOP_CHILDREN_Z_INDEX) : 0,
|
||||
}
|
||||
}
|
||||
const nodesConnectedSourceOrTargetHandleIdsMap = getNodesConnectedSourceOrTargetHandleIdsMap(
|
||||
@@ -908,10 +1050,14 @@ export const useNodesInteractions = () => {
|
||||
|
||||
if (node.data.type === BlockEnum.Iteration && prevNode.parentId === node.id)
|
||||
node.data._children?.push(newNode.id)
|
||||
if (node.data.type === BlockEnum.Loop && prevNode.parentId === node.id)
|
||||
node.data._children?.push(newNode.id)
|
||||
})
|
||||
draft.push(newNode)
|
||||
if (newIterationStartNode)
|
||||
draft.push(newIterationStartNode)
|
||||
if (newLoopStartNode)
|
||||
draft.push(newLoopStartNode)
|
||||
})
|
||||
setNodes(newNodes)
|
||||
if (newNode.data.type === BlockEnum.VariableAssigner || newNode.data.type === BlockEnum.VariableAggregator) {
|
||||
@@ -969,6 +1115,7 @@ export const useNodesInteractions = () => {
|
||||
const {
|
||||
newNode: newCurrentNode,
|
||||
newIterationStartNode,
|
||||
newLoopStartNode,
|
||||
} = generateNewNode({
|
||||
data: {
|
||||
...NODES_INITIAL_DATA[nodeType],
|
||||
@@ -978,7 +1125,9 @@ export const useNodesInteractions = () => {
|
||||
_connectedTargetHandleIds: [],
|
||||
selected: currentNode.data.selected,
|
||||
isInIteration: currentNode.data.isInIteration,
|
||||
isInLoop: currentNode.data.isInLoop,
|
||||
iteration_id: currentNode.data.iteration_id,
|
||||
loop_id: currentNode.data.loop_id,
|
||||
},
|
||||
position: {
|
||||
x: currentNode.position.x,
|
||||
@@ -1010,6 +1159,8 @@ export const useNodesInteractions = () => {
|
||||
draft.splice(index, 1, newCurrentNode)
|
||||
if (newIterationStartNode)
|
||||
draft.push(newIterationStartNode)
|
||||
if (newLoopStartNode)
|
||||
draft.push(newLoopStartNode)
|
||||
})
|
||||
setNodes(newNodes)
|
||||
const newEdges = produce(edges, (draft) => {
|
||||
@@ -1058,6 +1209,9 @@ export const useNodesInteractions = () => {
|
||||
if (node.type === CUSTOM_NOTE_NODE || node.type === CUSTOM_ITERATION_START_NODE)
|
||||
return
|
||||
|
||||
if (node.type === CUSTOM_NOTE_NODE || node.type === CUSTOM_LOOP_START_NODE)
|
||||
return
|
||||
|
||||
e.preventDefault()
|
||||
const container = document.querySelector('#workflow-container')
|
||||
const { x, y } = container!.getBoundingClientRect()
|
||||
@@ -1085,13 +1239,15 @@ export const useNodesInteractions = () => {
|
||||
|
||||
if (nodeId) {
|
||||
// If nodeId is provided, copy that specific node
|
||||
const nodeToCopy = nodes.find(node => node.id === nodeId && node.data.type !== BlockEnum.Start && node.type !== CUSTOM_ITERATION_START_NODE)
|
||||
const nodeToCopy = nodes.find(node => node.id === nodeId && node.data.type !== BlockEnum.Start
|
||||
&& node.type !== CUSTOM_ITERATION_START_NODE && node.type !== CUSTOM_LOOP_START_NODE)
|
||||
if (nodeToCopy)
|
||||
setClipboardElements([nodeToCopy])
|
||||
}
|
||||
else {
|
||||
// If no nodeId is provided, fall back to the current behavior
|
||||
const bundledNodes = nodes.filter(node => node.data._isBundled && node.data.type !== BlockEnum.Start && !node.data.isInIteration)
|
||||
const bundledNodes = nodes.filter(node => node.data._isBundled && node.data.type !== BlockEnum.Start
|
||||
&& !node.data.isInIteration && !node.data.isInLoop)
|
||||
|
||||
if (bundledNodes.length) {
|
||||
setClipboardElements(bundledNodes)
|
||||
@@ -1138,6 +1294,7 @@ export const useNodesInteractions = () => {
|
||||
const {
|
||||
newNode,
|
||||
newIterationStartNode,
|
||||
newLoopStartNode,
|
||||
} = generateNewNode({
|
||||
type: nodeToPaste.type,
|
||||
data: {
|
||||
@@ -1176,6 +1333,17 @@ export const useNodesInteractions = () => {
|
||||
newChildren.push(newIterationStartNode!)
|
||||
}
|
||||
|
||||
if (nodeToPaste.data.type === BlockEnum.Loop) {
|
||||
newLoopStartNode!.parentId = newNode.id;
|
||||
(newNode.data as LoopNodeType).start_node_id = newLoopStartNode!.id
|
||||
|
||||
newChildren = handleNodeLoopChildrenCopy(nodeToPaste.id, newNode.id)
|
||||
newChildren.forEach((child) => {
|
||||
newNode.data._children?.push(child.id)
|
||||
})
|
||||
newChildren.push(newLoopStartNode!)
|
||||
}
|
||||
|
||||
nodesToPaste.push(newNode)
|
||||
|
||||
if (newChildren.length)
|
||||
@@ -1206,7 +1374,7 @@ export const useNodesInteractions = () => {
|
||||
saveStateToHistory(WorkflowHistoryEvent.NodePaste)
|
||||
handleSyncWorkflowDraft()
|
||||
}
|
||||
}, [getNodesReadOnly, workflowStore, store, reactflow, saveStateToHistory, handleSyncWorkflowDraft, handleNodeIterationChildrenCopy])
|
||||
}, [getNodesReadOnly, workflowStore, store, reactflow, saveStateToHistory, handleSyncWorkflowDraft, handleNodeIterationChildrenCopy, handleNodeLoopChildrenCopy])
|
||||
|
||||
const handleNodesDuplicate = useCallback((nodeId?: string) => {
|
||||
if (getNodesReadOnly())
|
||||
@@ -1278,9 +1446,12 @@ export const useNodesInteractions = () => {
|
||||
})
|
||||
|
||||
if (rightNode! && bottomNode!) {
|
||||
if (width < rightNode!.position.x + rightNode.width! + ITERATION_PADDING.right)
|
||||
const parentNode = nodes.find(n => n.id === rightNode.parentId)
|
||||
const paddingMap = parentNode?.data.type === BlockEnum.Iteration ? ITERATION_PADDING : LOOP_PADDING
|
||||
|
||||
if (width < rightNode!.position.x + rightNode.width! + paddingMap.right)
|
||||
return
|
||||
if (height < bottomNode.position.y + bottomNode.height! + ITERATION_PADDING.bottom)
|
||||
if (height < bottomNode.position.y + bottomNode.height! + paddingMap.bottom)
|
||||
return
|
||||
}
|
||||
const newNodes = produce(nodes, (draft) => {
|
||||
|
Reference in New Issue
Block a user