Bladeren bron

Add collapse nodes & node tools

victorbrambati 2 jaren geleden
bovenliggende
commit
ccf2240018
4 gewijzigde bestanden met toevoegingen van 173 en 0 verwijderingen
  1. 85 0
      src/containers/Editor/NodeTools.ts
  2. 39 0
      src/hooks/store/useNodeTools.tsx
  3. 15 0
      src/utils/findEdgeChildren.ts
  4. 34 0
      src/utils/findNodeChildren.ts

+ 85 - 0
src/containers/Editor/NodeTools.ts

@@ -0,0 +1,85 @@
+import { NodeData, EdgeData, removeAndUpsertNodes } from "reaflow";
+import { findNodeChildren } from "src/utils/findNodeChildren";
+import toast from "react-hot-toast";
+import { NodeTools } from "src/hooks/store/useNodeTools";
+import { findEdgeChildren } from "src/utils/findEdgeChildren";
+
+export const collapseNodes = (
+  selectedNode: string,
+  nodes: NodeData[],
+  edges: EdgeData[],
+  collapsedNodes: { [key: string]: NodeData[] },
+  collapsedEdges: { [key: string]: EdgeData[] },
+  setNodeTools: (key: keyof NodeTools, value: unknown) => void
+) => {
+  if (selectedNode) {
+    const childrenOfNode = findNodeChildren(selectedNode, nodes, edges);
+    const childrenOfEdge = findEdgeChildren(
+      selectedNode,
+      childrenOfNode,
+      edges
+    );
+
+    const newCollapsedEdges = {};
+    newCollapsedEdges[selectedNode] = childrenOfEdge;
+    setNodeTools("collapsedEdges", {
+      ...collapsedEdges,
+      ...newCollapsedEdges,
+    });
+
+    const newCollapsedNodes = {};
+    newCollapsedNodes[selectedNode] = childrenOfNode;
+    setNodeTools("collapsedNodes", {
+      ...collapsedNodes,
+      ...newCollapsedNodes,
+    });
+
+    const resultOfRemovedNodes = removeAndUpsertNodes(
+      nodes,
+      edges,
+      childrenOfNode
+    );
+
+    const edgesResult = resultOfRemovedNodes.edges.filter((e) =>
+      e.id.startsWith("e")
+    );
+    setNodeTools("newNodes", resultOfRemovedNodes.nodes);
+    setNodeTools("newEdges", edgesResult);
+    setTimeout(() => toast.dismiss("restartToast"), 230);
+  } else {
+    toast("Please select a node to collapse!");
+  }
+};
+
+export const expandNodes = (
+  selectedNode: string,
+  nodes: NodeData[],
+  edges: EdgeData[],
+  collapsedNodes: { [key: string]: NodeData[] },
+  collapsedEdges: { [key: string]: EdgeData[] },
+  setNodeTools: (nodeTools: keyof NodeTools, value: unknown) => void
+) => {
+  if (selectedNode) {
+    const concatEdges = edges.concat(collapsedEdges[selectedNode]);
+    const concatNodes = nodes.concat(collapsedNodes[selectedNode]);
+
+    setNodeTools("newNodes", concatNodes);
+    setNodeTools("newEdges", concatEdges);
+  } else {
+    toast("Please select a node to expand!");
+  }
+};
+
+export const restartNodes = (
+  initialNodes: NodeData[],
+  initialEdges: EdgeData[],
+  nodes: NodeData[],
+  setNodeTools: (nodeTools: keyof NodeTools, value: unknown) => void
+) => {
+  if (nodes !== initialNodes) {
+    setNodeTools("newNodes", initialNodes);
+    setNodeTools("newEdges", initialEdges);
+  } else {
+    toast("Collapse at last once the node to restart!", { id: "restartToast" });
+  }
+};

+ 39 - 0
src/hooks/store/useNodeTools.tsx

@@ -0,0 +1,39 @@
+import create from "zustand";
+import { EdgeData, NodeData } from "reaflow";
+
+export interface NodeTools {
+  selectedNode: string;
+  copySelectedNode: boolean;
+  nodes: NodeData[];
+  edges: EdgeData[];
+  newNodes: NodeData[];
+  newEdges: EdgeData[];
+  collapsedNodes: { [key: string]: NodeData[] };
+  collapsedEdges: { [key: string]: EdgeData[] };
+}
+
+export interface SettingsNodeTools {
+  setNodeTools: (key: keyof NodeTools, value: unknown) => void;
+}
+
+const initialStates: NodeTools = {
+  selectedNode: "",
+  copySelectedNode: false,
+  nodes: [],
+  edges: [],
+  newNodes: [],
+  newEdges: [],
+  collapsedNodes: {},
+  collapsedEdges: {},
+};
+
+const useNodeTools = create<NodeTools & SettingsNodeTools>((set) => ({
+  ...initialStates,
+  setNodeTools: (nodeTool: keyof NodeTools, value: unknown) =>
+    set((state) => ({
+      ...state,
+      [nodeTool]: value,
+    })),
+}));
+
+export default useNodeTools;

+ 15 - 0
src/utils/findEdgeChildren.ts

@@ -0,0 +1,15 @@
+import { NodeData, EdgeData } from "reaflow/dist/types";
+
+
+export const findEdgeChildren = (selectedNode: string, connections: NodeData[], edges: EdgeData[]) => {
+
+    const nodeIds = connections.map((n) => n.id);
+    nodeIds.push(selectedNode);
+    const newEdges = edges.filter(
+      (e) =>
+        nodeIds.includes(e.from as string) && nodeIds.includes(e.to as string)
+    );
+
+    return newEdges;
+
+  };

+ 34 - 0
src/utils/findNodeChildren.ts

@@ -0,0 +1,34 @@
+import { NodeData, EdgeData } from "reaflow/dist/types";
+
+
+export const findNodeChildren = (selectedNode: string, nodes: NodeData[], edges: EdgeData[]) => {
+
+const toByFrom = {};
+for (const edge of edges) {
+  if(edge.from){
+  toByFrom[edge.from] ??= [];
+  toByFrom[edge.from].push(edge.to);
+  }
+}
+
+const getNodes = (parent, allNodesIds:string[] = []) => {
+  const tos = toByFrom[parent];
+  if (tos) {
+    allNodesIds.push(...tos);
+    for (const to of tos) {
+      getNodes(to, allNodesIds);
+    }
+  }
+  return allNodesIds;
+};
+
+  
+ const myNodes = getNodes(selectedNode);
+
+    const findNodes = myNodes.map((id) => {
+      const node = nodes.find((n) => n.id === id);
+      return node as NodeData<any>;
+    });
+
+    return findNodes;
+  };