mirror of
https://github.com/langgenius/dify.git
synced 2026-04-26 10:16:40 +08:00
feat: when copy/paste multi nodes not require reconnect them (#32631)
This commit is contained in:
parent
654e41d47f
commit
4a2ba058bb
@ -1735,6 +1735,7 @@ export const useNodesInteractions = () => {
|
|||||||
const offsetX = currentPosition.x - x
|
const offsetX = currentPosition.x - x
|
||||||
const offsetY = currentPosition.y - y
|
const offsetY = currentPosition.y - y
|
||||||
let idMapping: Record<string, string> = {}
|
let idMapping: Record<string, string> = {}
|
||||||
|
const pastedNodesMap: Record<string, Node> = {}
|
||||||
const parentChildrenToAppend: { parentId: string, childId: string, childType: BlockEnum }[] = []
|
const parentChildrenToAppend: { parentId: string, childId: string, childType: BlockEnum }[] = []
|
||||||
clipboardElements.forEach((nodeToPaste, index) => {
|
clipboardElements.forEach((nodeToPaste, index) => {
|
||||||
const nodeType = nodeToPaste.data.type
|
const nodeType = nodeToPaste.data.type
|
||||||
@ -1794,7 +1795,21 @@ export const useNodesInteractions = () => {
|
|||||||
newLoopStartNode!.parentId = newNode.id;
|
newLoopStartNode!.parentId = newNode.id;
|
||||||
(newNode.data as LoopNodeType).start_node_id = newLoopStartNode!.id
|
(newNode.data as LoopNodeType).start_node_id = newLoopStartNode!.id
|
||||||
|
|
||||||
newChildren = handleNodeLoopChildrenCopy(nodeToPaste.id, newNode.id)
|
const oldLoopStartNode = nodes.find(
|
||||||
|
n =>
|
||||||
|
n.parentId === nodeToPaste.id
|
||||||
|
&& n.type === CUSTOM_LOOP_START_NODE,
|
||||||
|
)
|
||||||
|
idMapping[oldLoopStartNode!.id] = newLoopStartNode!.id
|
||||||
|
|
||||||
|
const { copyChildren, newIdMapping }
|
||||||
|
= handleNodeLoopChildrenCopy(
|
||||||
|
nodeToPaste.id,
|
||||||
|
newNode.id,
|
||||||
|
idMapping,
|
||||||
|
)
|
||||||
|
newChildren = copyChildren
|
||||||
|
idMapping = newIdMapping
|
||||||
newChildren.forEach((child) => {
|
newChildren.forEach((child) => {
|
||||||
newNode.data._children?.push({
|
newNode.data._children?.push({
|
||||||
nodeId: child.id,
|
nodeId: child.id,
|
||||||
@ -1839,18 +1854,31 @@ export const useNodesInteractions = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
idMapping[nodeToPaste.id] = newNode.id
|
||||||
nodesToPaste.push(newNode)
|
nodesToPaste.push(newNode)
|
||||||
|
pastedNodesMap[newNode.id] = newNode
|
||||||
|
|
||||||
if (newChildren.length)
|
if (newChildren.length) {
|
||||||
|
newChildren.forEach((child) => {
|
||||||
|
pastedNodesMap[child.id] = child
|
||||||
|
})
|
||||||
nodesToPaste.push(...newChildren)
|
nodesToPaste.push(...newChildren)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// only handle edge when paste nested block
|
// Rebuild edges where both endpoints are part of the pasted set.
|
||||||
edges.forEach((edge) => {
|
edges.forEach((edge) => {
|
||||||
const sourceId = idMapping[edge.source]
|
const sourceId = idMapping[edge.source]
|
||||||
const targetId = idMapping[edge.target]
|
const targetId = idMapping[edge.target]
|
||||||
|
|
||||||
if (sourceId && targetId) {
|
if (sourceId && targetId) {
|
||||||
|
const sourceNode = pastedNodesMap[sourceId]
|
||||||
|
const targetNode = pastedNodesMap[targetId]
|
||||||
|
const parentNode = sourceNode?.parentId && sourceNode.parentId === targetNode?.parentId
|
||||||
|
? pastedNodesMap[sourceNode.parentId] ?? nodes.find(n => n.id === sourceNode.parentId)
|
||||||
|
: null
|
||||||
|
const isInIteration = parentNode?.data.type === BlockEnum.Iteration
|
||||||
|
const isInLoop = parentNode?.data.type === BlockEnum.Loop
|
||||||
const newEdge: Edge = {
|
const newEdge: Edge = {
|
||||||
...edge,
|
...edge,
|
||||||
id: `${sourceId}-${edge.sourceHandle}-${targetId}-${edge.targetHandle}`,
|
id: `${sourceId}-${edge.sourceHandle}-${targetId}-${edge.targetHandle}`,
|
||||||
@ -1858,8 +1886,19 @@ export const useNodesInteractions = () => {
|
|||||||
target: targetId,
|
target: targetId,
|
||||||
data: {
|
data: {
|
||||||
...edge.data,
|
...edge.data,
|
||||||
|
isInIteration,
|
||||||
|
iteration_id: isInIteration ? parentNode?.id : undefined,
|
||||||
|
isInLoop,
|
||||||
|
loop_id: isInLoop ? parentNode?.id : undefined,
|
||||||
_connectedNodeIsSelected: false,
|
_connectedNodeIsSelected: false,
|
||||||
},
|
},
|
||||||
|
zIndex: parentNode
|
||||||
|
? isInIteration
|
||||||
|
? ITERATION_CHILDREN_Z_INDEX
|
||||||
|
: isInLoop
|
||||||
|
? LOOP_CHILDREN_Z_INDEX
|
||||||
|
: 0
|
||||||
|
: 0,
|
||||||
}
|
}
|
||||||
edgesToPaste.push(newEdge)
|
edgesToPaste.push(newEdge)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -108,12 +108,13 @@ export const useNodeLoopInteractions = () => {
|
|||||||
handleNodeLoopRerender(parentId)
|
handleNodeLoopRerender(parentId)
|
||||||
}, [store, handleNodeLoopRerender])
|
}, [store, handleNodeLoopRerender])
|
||||||
|
|
||||||
const handleNodeLoopChildrenCopy = useCallback((nodeId: string, newNodeId: string) => {
|
const handleNodeLoopChildrenCopy = useCallback((nodeId: string, newNodeId: string, idMapping: Record<string, string>) => {
|
||||||
const { getNodes } = store.getState()
|
const { getNodes } = store.getState()
|
||||||
const nodes = getNodes()
|
const nodes = getNodes()
|
||||||
const childrenNodes = nodes.filter(n => n.parentId === nodeId && n.type !== CUSTOM_LOOP_START_NODE)
|
const childrenNodes = nodes.filter(n => n.parentId === nodeId && n.type !== CUSTOM_LOOP_START_NODE)
|
||||||
|
const newIdMapping = { ...idMapping }
|
||||||
|
|
||||||
return childrenNodes.map((child, index) => {
|
const copyChildren = childrenNodes.map((child, index) => {
|
||||||
const childNodeType = child.data.type as BlockEnum
|
const childNodeType = child.data.type as BlockEnum
|
||||||
const { defaultValue } = nodesMetaDataMap![childNodeType]
|
const { defaultValue } = nodesMetaDataMap![childNodeType]
|
||||||
const nodesWithSameType = nodes.filter(node => node.data.type === childNodeType)
|
const nodesWithSameType = nodes.filter(node => node.data.type === childNodeType)
|
||||||
@ -139,8 +140,14 @@ export const useNodeLoopInteractions = () => {
|
|||||||
zIndex: LOOP_CHILDREN_Z_INDEX,
|
zIndex: LOOP_CHILDREN_Z_INDEX,
|
||||||
})
|
})
|
||||||
newNode.id = `${newNodeId}${newNode.id + index}`
|
newNode.id = `${newNodeId}${newNode.id + index}`
|
||||||
|
newIdMapping[child.id] = newNode.id
|
||||||
return newNode
|
return newNode
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
copyChildren,
|
||||||
|
newIdMapping,
|
||||||
|
}
|
||||||
}, [store, nodesMetaDataMap])
|
}, [store, nodesMetaDataMap])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user