|
|
|
|
@ -715,6 +715,108 @@ export const useNodesInteractions = () => {
|
|
|
|
|
handleSyncWorkflowDraft()
|
|
|
|
|
}, [store, handleSyncWorkflowDraft, getNodesReadOnly, t])
|
|
|
|
|
|
|
|
|
|
const handleNodeCopySelected = useCallback((): undefined | Node[] => {
|
|
|
|
|
if (getNodesReadOnly())
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
setClipboardElements,
|
|
|
|
|
} = workflowStore.getState()
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
getNodes,
|
|
|
|
|
} = store.getState()
|
|
|
|
|
|
|
|
|
|
const nodes = getNodes()
|
|
|
|
|
const nodesToCopy = nodes.filter(node => node.data.selected)
|
|
|
|
|
|
|
|
|
|
setClipboardElements(nodesToCopy)
|
|
|
|
|
|
|
|
|
|
return nodesToCopy
|
|
|
|
|
}, [getNodesReadOnly, store, workflowStore])
|
|
|
|
|
|
|
|
|
|
const handleNodePaste = useCallback((): undefined | Node[] => {
|
|
|
|
|
if (getNodesReadOnly())
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
clipboardElements,
|
|
|
|
|
} = workflowStore.getState()
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
getNodes,
|
|
|
|
|
setNodes,
|
|
|
|
|
} = store.getState()
|
|
|
|
|
|
|
|
|
|
const nodesToPaste: Node[] = []
|
|
|
|
|
const nodes = getNodes()
|
|
|
|
|
|
|
|
|
|
for (const nodeToPaste of clipboardElements) {
|
|
|
|
|
const nodeType = nodeToPaste.data.type
|
|
|
|
|
const nodesWithSameType = nodes.filter(node => node.data.type === nodeType)
|
|
|
|
|
|
|
|
|
|
const newNode = generateNewNode({
|
|
|
|
|
data: {
|
|
|
|
|
...NODES_INITIAL_DATA[nodeType],
|
|
|
|
|
...nodeToPaste.data,
|
|
|
|
|
_connectedSourceHandleIds: [],
|
|
|
|
|
_connectedTargetHandleIds: [],
|
|
|
|
|
title: nodesWithSameType.length > 0 ? `${t(`workflow.blocks.${nodeType}`)} ${nodesWithSameType.length + 1}` : t(`workflow.blocks.${nodeType}`),
|
|
|
|
|
selected: true,
|
|
|
|
|
},
|
|
|
|
|
position: {
|
|
|
|
|
x: nodeToPaste.position.x + 10,
|
|
|
|
|
y: nodeToPaste.position.y + 10,
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
nodesToPaste.push(newNode)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setNodes([...nodes.map((n: Node) => ({ ...n, selected: false, data: { ...n.data, selected: false } })), ...nodesToPaste])
|
|
|
|
|
|
|
|
|
|
handleSyncWorkflowDraft()
|
|
|
|
|
|
|
|
|
|
return nodesToPaste
|
|
|
|
|
}, [getNodesReadOnly, handleSyncWorkflowDraft, store, t, workflowStore])
|
|
|
|
|
|
|
|
|
|
const handleNodeDuplicateSelected = useCallback(() => {
|
|
|
|
|
if (getNodesReadOnly())
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
handleNodeCopySelected()
|
|
|
|
|
handleNodePaste()
|
|
|
|
|
}, [getNodesReadOnly, handleNodeCopySelected, handleNodePaste])
|
|
|
|
|
|
|
|
|
|
const handleNodeCut = useCallback(() => {
|
|
|
|
|
if (getNodesReadOnly())
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
const nodesToCut = handleNodeCopySelected()
|
|
|
|
|
if (!nodesToCut)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
for (const node of nodesToCut)
|
|
|
|
|
handleNodeDelete(node.id)
|
|
|
|
|
}, [getNodesReadOnly, handleNodeCopySelected, handleNodeDelete])
|
|
|
|
|
|
|
|
|
|
const handleNodeDeleteSelected = useCallback(() => {
|
|
|
|
|
if (getNodesReadOnly())
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
getNodes,
|
|
|
|
|
} = store.getState()
|
|
|
|
|
|
|
|
|
|
const nodes = getNodes()
|
|
|
|
|
const nodesToDelete = nodes.filter(node => node.data.selected)
|
|
|
|
|
|
|
|
|
|
if (!nodesToDelete)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
for (const node of nodesToDelete)
|
|
|
|
|
handleNodeDelete(node.id)
|
|
|
|
|
}, [getNodesReadOnly, handleNodeDelete, store])
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
handleNodeDragStart,
|
|
|
|
|
handleNodeDrag,
|
|
|
|
|
@ -729,5 +831,10 @@ export const useNodesInteractions = () => {
|
|
|
|
|
handleNodeDelete,
|
|
|
|
|
handleNodeChange,
|
|
|
|
|
handleNodeAdd,
|
|
|
|
|
handleNodeDuplicateSelected,
|
|
|
|
|
handleNodeCopySelected,
|
|
|
|
|
handleNodeCut,
|
|
|
|
|
handleNodeDeleteSelected,
|
|
|
|
|
handleNodePaste,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|