@@ -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
6466const 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 <
@@ -499,6 +503,8 @@ export const FlowProvider = ({ children, flow }: Props) => {
499503 ( edge ) => edge . target === connection . target ,
500504 ) . length
501505
506+ const targetNode = nodes . find ( ( node ) => node . id === connection . target )
507+
502508 if ( connection . source === connection . target ) return false
503509
504510 if (
@@ -526,6 +532,14 @@ export const FlowProvider = ({ children, flow }: Props) => {
526532 } )
527533 }
528534
535+ if (
536+ ( targetNode ?. data . action === EActionTypes . CHECK_VARIABLES ||
537+ targetNode ?. data . action === EActionTypes . PROMPT_AND_COLLECT ) &&
538+ sourcesFromHandleInState < 1
539+ ) {
540+ return true
541+ }
542+
529543 if ( targetFromHandleInState === 1 ) return false
530544 if ( sourcesFromHandleInState < 1 ) return true
531545
@@ -584,6 +598,33 @@ export const FlowProvider = ({ children, flow }: Props) => {
584598 } )
585599 } , [ ] )
586600
601+ /**
602+ * Finds a node in the given array of nodes that has the specified node as its next action.
603+ * @param nodes - The array of nodes to search in.
604+ * @param node - The node to find the next action for.
605+ * @returns The node that has the specified node as its next action, or undefined if not found.
606+ */
607+ const findNodeIsNextAction = useCallback ( ( 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+ const findNodeContainNextAction = useCallback (
617+ ( nodes : Node [ ] , node : Node < any > ) => {
618+ return nodes . find ( ( nd ) => {
619+ return (
620+ nd . data ?. nextAction === node . id ||
621+ nd . data ?. nextActions ?. some ( ( na : any ) => na . id === node . id )
622+ )
623+ } )
624+ } ,
625+ [ ] ,
626+ )
627+
587628 /**
588629 * Retrieves the complete flows from the given nodes.
589630 * A complete flow is a sequence of nodes where each node has a next action or is a final node.
@@ -594,20 +635,6 @@ export const FlowProvider = ({ children, flow }: Props) => {
594635 const getCompleteFlows = useCallback ( ( ) => {
595636 let clonedNodes = _ . cloneDeep ( nodes )
596637
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-
611638 /**
612639 * Checks if a node is to be removed.
613640 * @param node - The node to check.
@@ -622,7 +649,7 @@ export const FlowProvider = ({ children, flow }: Props) => {
622649 }
623650
624651 if (
625- ! nodeIsNextAction ( node ) &&
652+ ! findNodeIsNextAction ( clonedNodes , node ) &&
626653 ( ! node . data ?. nextAction || ! node . data ?. nextActions )
627654 ) {
628655 return true
@@ -643,8 +670,59 @@ export const FlowProvider = ({ children, flow }: Props) => {
643670 }
644671
645672 return clonedNodes . map ( ( node ) => node . data )
646- } , [ nodes ] )
673+ } , [ findNodeIsNextAction , nodes ] )
674+
675+ /**
676+ * Handles the deletion of nodes.
677+ * @param nodeDels - The nodes to be deleted.
678+ */
679+ const handleNodesDelete : OnNodesDelete = useCallback (
680+ ( nodeDels ) => {
681+ const nodeToDelete = nodeDels [ 0 ]
647682
683+ // get node is have next action to remove this next action
684+ const nodeIsHaveNextAction = findNodeIsNextAction ( nodes , nodeToDelete )
685+
686+ if ( ! nodeIsHaveNextAction ) {
687+ return
688+ }
689+
690+ // remove next action from node is have next action
691+ if ( nodeIsHaveNextAction ?. data . nextAction ) {
692+ delete nodeIsHaveNextAction . data . nextAction
693+ }
694+
695+ // remove next actions from node is have next action
696+ if ( nodeIsHaveNextAction ?. data . nextActions ) {
697+ // remove next action from next actions
698+ nodeIsHaveNextAction . data . nextActions =
699+ nodeIsHaveNextAction . data . nextActions . filter (
700+ ( na : any ) => na . id !== nodeToDelete . id ,
701+ )
702+
703+ // remove next actions if it empty
704+ if ( nodeIsHaveNextAction . data . nextActions . length === 0 ) {
705+ delete nodeIsHaveNextAction . data . nextActions
706+ }
707+ }
708+
709+ setNodes ( ( nodes ) => {
710+ return nodes . map ( ( node ) => {
711+ if ( node . id === nodeIsHaveNextAction . id ) {
712+ return nodeIsHaveNextAction
713+ }
714+
715+ return node
716+ } )
717+ } )
718+ } ,
719+ [ findNodeIsNextAction , nodes , setNodes ] ,
720+ )
721+
722+ /**
723+ * Deletes an edge by its ID.
724+ * @param id - The ID of the edge to delete.
725+ */
648726 const handleDeleteEdgeById = useCallback (
649727 ( id : string ) => {
650728 const edge = getEdge ( id )
@@ -727,6 +805,7 @@ export const FlowProvider = ({ children, flow }: Props) => {
727805 setNodes,
728806 setEdges,
729807 handleDeleteEdgeById,
808+ handleNodesDelete,
730809 } }
731810 >
732811 { children }
0 commit comments