Skip to content

Commit acfce79

Browse files
committed
fix: not remove action when node removed
1 parent 84f8281 commit acfce79

File tree

3 files changed

+88
-17
lines changed

3 files changed

+88
-17
lines changed

client/src/components/pages/flow-detail/flow-inside.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export const FlowInside = () => {
3434
handleDoubleClickNode,
3535
handleDoubleClickEdge,
3636
flow,
37+
handleNodesDelete,
3738
} = useFlowCtx()
3839
const { t } = useTranslation('common')
3940

@@ -89,6 +90,7 @@ export const FlowInside = () => {
8990
onInit={handleInit}
9091
onNodeDoubleClick={handleDoubleClickNode}
9192
onEdgeDoubleClick={handleDoubleClickEdge}
93+
onNodesDelete={handleNodesDelete}
9294
>
9395
<Background
9496
gap={24}

client/src/components/pages/flow-detail/flow-provider.tsx

Lines changed: 85 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
NodeChange,
1919
NodeMouseHandler,
2020
OnConnect,
21+
OnNodesDelete,
2122
ReactFlowInstance,
2223
addEdge,
2324
useEdgesState,
@@ -59,6 +60,7 @@ type FlowCtx = {
5960
setNodes: React.Dispatch<React.SetStateAction<Node<any>[]>>
6061
setEdges: React.Dispatch<React.SetStateAction<Edge<any>[]>>
6162
handleDeleteEdgeById: (id: string) => void
63+
handleNodesDelete: OnNodesDelete
6264
}
6365

6466
const FlowContext = createContext<FlowCtx | undefined>(undefined)
@@ -135,6 +137,8 @@ export const FlowProvider = ({ children, flow }: Props) => {
135137
selectedEdge,
136138
selectedNode,
137139
flows: nodes.map((node) => node.data),
140+
nodes,
141+
edges,
138142
})
139143

140144
const [reactFlowInstance, setReactFlowInstance] = useState<ReactFlowInstance<
@@ -584,6 +588,33 @@ export const FlowProvider = ({ children, flow }: Props) => {
584588
})
585589
}, [])
586590

591+
/**
592+
* Finds a node in the given array of nodes that has the specified node as its next action.
593+
* @param nodes - The array of nodes to search in.
594+
* @param node - The node to find the next action for.
595+
* @returns The node that has the specified node as its next action, or undefined if not found.
596+
*/
597+
const findNodeIsNextAction = useCallback((nodes: Node[], node: Node<any>) => {
598+
return nodes.find((nd) => {
599+
return (
600+
nd.data?.nextAction === node.id ||
601+
nd.data?.nextActions?.some((na: any) => na.id === node.id)
602+
)
603+
})
604+
}, [])
605+
606+
const findNodeContainNextAction = useCallback(
607+
(nodes: Node[], node: Node<any>) => {
608+
return nodes.find((nd) => {
609+
return (
610+
nd.data?.nextAction === node.id ||
611+
nd.data?.nextActions?.some((na: any) => na.id === node.id)
612+
)
613+
})
614+
},
615+
[],
616+
)
617+
587618
/**
588619
* Retrieves the complete flows from the given nodes.
589620
* A complete flow is a sequence of nodes where each node has a next action or is a final node.
@@ -594,20 +625,6 @@ export const FlowProvider = ({ children, flow }: Props) => {
594625
const getCompleteFlows = useCallback(() => {
595626
let clonedNodes = _.cloneDeep(nodes)
596627

597-
/**
598-
* Checks if a given node is the next action of any of the cloned nodes.
599-
* @param node - The node to check.
600-
* @returns True if the node is the next action of any cloned node, false otherwise.
601-
*/
602-
const nodeIsNextAction = (node: Node<any>) => {
603-
return clonedNodes.some((nd) => {
604-
return (
605-
nd.data?.nextAction === node.id ||
606-
nd.data?.nextActions?.some((na: any) => na.id === node.id)
607-
)
608-
})
609-
}
610-
611628
/**
612629
* Checks if a node is to be removed.
613630
* @param node - The node to check.
@@ -622,7 +639,7 @@ export const FlowProvider = ({ children, flow }: Props) => {
622639
}
623640

624641
if (
625-
!nodeIsNextAction(node) &&
642+
!findNodeIsNextAction(clonedNodes, node) &&
626643
(!node.data?.nextAction || !node.data?.nextActions)
627644
) {
628645
return true
@@ -643,8 +660,59 @@ export const FlowProvider = ({ children, flow }: Props) => {
643660
}
644661

645662
return clonedNodes.map((node) => node.data)
646-
}, [nodes])
663+
}, [findNodeIsNextAction, nodes])
664+
665+
/**
666+
* Handles the deletion of nodes.
667+
* @param nodeDels - The nodes to be deleted.
668+
*/
669+
const handleNodesDelete: OnNodesDelete = useCallback(
670+
(nodeDels) => {
671+
const nodeToDelete = nodeDels[0]
672+
673+
// get node is have next action to remove this next action
674+
const nodeIsHaveNextAction = findNodeIsNextAction(nodes, nodeToDelete)
675+
676+
if (!nodeIsHaveNextAction) {
677+
return
678+
}
679+
680+
// remove next action from node is have next action
681+
if (nodeIsHaveNextAction?.data.nextAction) {
682+
delete nodeIsHaveNextAction.data.nextAction
683+
}
684+
685+
// remove next actions from node is have next action
686+
if (nodeIsHaveNextAction?.data.nextActions) {
687+
// remove next action from next actions
688+
nodeIsHaveNextAction.data.nextActions =
689+
nodeIsHaveNextAction.data.nextActions.filter(
690+
(na: any) => na.id !== nodeToDelete.id,
691+
)
647692

693+
// remove next actions if it empty
694+
if (nodeIsHaveNextAction.data.nextActions.length === 0) {
695+
delete nodeIsHaveNextAction.data.nextActions
696+
}
697+
}
698+
699+
setNodes((nodes) => {
700+
return nodes.map((node) => {
701+
if (node.id === nodeIsHaveNextAction.id) {
702+
return nodeIsHaveNextAction
703+
}
704+
705+
return node
706+
})
707+
})
708+
},
709+
[findNodeIsNextAction, nodes, setNodes],
710+
)
711+
712+
/**
713+
* Deletes an edge by its ID.
714+
* @param id - The ID of the edge to delete.
715+
*/
648716
const handleDeleteEdgeById = useCallback(
649717
(id: string) => {
650718
const edge = getEdge(id)
@@ -727,6 +795,7 @@ export const FlowProvider = ({ children, flow }: Props) => {
727795
setNodes,
728796
setEdges,
729797
handleDeleteEdgeById,
798+
handleNodesDelete,
730799
}}
731800
>
732801
{children}

client/src/components/pages/flow-detail/nodes.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export const NodeWrapper = (props?: {
8383
return (
8484
<div className={cn('bg-card shadow rounded-md p-2 border-card', className)}>
8585
{children}
86-
<HandleCustom type='target' position={Position.Top} isConnectable={1} />
86+
<HandleCustom type='target' position={Position.Top} />
8787
<HandleCustom type='source' position={Position.Bottom} />
8888
</div>
8989
)

0 commit comments

Comments
 (0)