Skip to content

Commit c4acb0d

Browse files
committed
feat(core): add flag to removeNodes to remove children of a node
1 parent bc2de72 commit c4acb0d

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

packages/core/src/store/actions.ts

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -506,13 +506,42 @@ export function useActions(
506506
}
507507
}
508508

509-
const removeNodes: Actions['removeNodes'] = (nodes, removeConnectedEdges = true) => {
509+
const removeNodes: Actions['removeNodes'] = (nodes, removeConnectedEdges = true, removeChildren = false) => {
510510
let nodesToRemove = nodes instanceof Function ? nodes(state.nodes) : nodes
511511
nodesToRemove = Array.isArray(nodesToRemove) ? nodesToRemove : [nodesToRemove]
512512

513513
const nodeChanges: NodeRemoveChange[] = []
514514
const edgeChanges: EdgeRemoveChange[] = []
515515

516+
function createEdgeRemovalChanges(nodes: Node[]) {
517+
const connections = getConnectedEdges(nodes, state.edges).filter((edge) => {
518+
if (isDef(edge.deletable)) {
519+
return edge.deletable
520+
}
521+
return true
522+
})
523+
524+
edgeChanges.push(...connections.map((connection) => createRemoveChange(connection.id)))
525+
}
526+
527+
// recursively get all children and if the child is a parent, get those children as well until all nodes have been removed that are children of the current node
528+
function createChildrenRemovalChanges(id: string) {
529+
const children = state.nodes.filter((n) => n.parentNode === id)
530+
531+
if (children.length) {
532+
const childIds = children.map((n) => n.id)
533+
nodeChanges.push(...childIds.map((id) => createRemoveChange(id)))
534+
535+
if (removeConnectedEdges) {
536+
createEdgeRemovalChanges(children)
537+
}
538+
539+
children.forEach((child) => {
540+
createChildrenRemovalChanges(child.id)
541+
})
542+
}
543+
}
544+
516545
nodesToRemove.forEach((item) => {
517546
const currNode = typeof item === 'string' ? findNode(item) : item
518547

@@ -527,14 +556,11 @@ export function useActions(
527556
nodeChanges.push(createRemoveChange(currNode.id))
528557

529558
if (removeConnectedEdges) {
530-
const connections = getConnectedEdges([currNode], state.edges).filter((edge) => {
531-
if (isDef(edge.deletable)) {
532-
return edge.deletable
533-
}
534-
return true
535-
})
559+
createEdgeRemovalChanges([currNode])
560+
}
536561

537-
edgeChanges.push(...connections.map((connection) => createRemoveChange(connection.id)))
562+
if (removeChildren) {
563+
createChildrenRemovalChanges(currNode.id)
538564
}
539565
})
540566

packages/core/src/types/store.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ export type AddNodes = (nodes: Node | Node[] | ((nodes: GraphNode[]) => Node | N
155155
export type RemoveNodes = (
156156
nodes: (string | Node) | (Node | string)[] | ((nodes: GraphNode[]) => (string | Node) | (Node | string)[]),
157157
removeConnectedEdges?: boolean,
158+
removeChildren?: boolean,
158159
) => void
159160

160161
export type RemoveEdges = (
@@ -209,7 +210,7 @@ export interface Actions extends ViewportFunctions {
209210
addNodes: AddNodes
210211
/** parses edges and adds to state */
211212
addEdges: AddEdges
212-
/** remove nodes (and possibly connected edges) from state */
213+
/** remove nodes (and possibly connected edges and children) from state */
213214
removeNodes: RemoveNodes
214215
/** remove edges from state */
215216
removeEdges: RemoveEdges

0 commit comments

Comments
 (0)