Selaa lähdekoodia

Update graph to use node tools

victorbrambati 2 vuotta sitten
vanhempi
commit
589936ade8
1 muutettua tiedostoa jossa 56 lisäystä ja 45 poistoa
  1. 56 45
      src/components/Graph/index.tsx

+ 56 - 45
src/components/Graph/index.tsx

@@ -4,18 +4,17 @@ import {
   TransformComponent,
   TransformComponent,
   TransformWrapper,
   TransformWrapper,
 } from "react-zoom-pan-pinch";
 } from "react-zoom-pan-pinch";
-import { Canvas, EdgeData, ElkRoot, NodeData, NodeProps } from "reaflow";
+import { Canvas, Edge, ElkRoot, useSelection } from "reaflow";
 import { CustomNode } from "src/components/CustomNode";
 import { CustomNode } from "src/components/CustomNode";
 import { NodeModal } from "src/containers/Modals/NodeModal";
 import { NodeModal } from "src/containers/Modals/NodeModal";
 import { getEdgeNodes } from "src/containers/Editor/LiveEditor/helpers";
 import { getEdgeNodes } from "src/containers/Editor/LiveEditor/helpers";
 import useConfig from "src/hooks/store/useConfig";
 import useConfig from "src/hooks/store/useConfig";
 import styled from "styled-components";
 import styled from "styled-components";
 import shallow from "zustand/shallow";
 import shallow from "zustand/shallow";
+import useNodeTools from "src/hooks/store/useNodeTools";
 
 
 interface LayoutProps {
 interface LayoutProps {
   isWidget: boolean;
   isWidget: boolean;
-  openModal: () => void;
-  setSelectedNode: (node: object) => void;
 }
 }
 
 
 const StyledEditorWrapper = styled.div<{ isWidget: boolean }>`
 const StyledEditorWrapper = styled.div<{ isWidget: boolean }>`
@@ -33,14 +32,21 @@ const StyledEditorWrapper = styled.div<{ isWidget: boolean }>`
   }
   }
 `;
 `;
 
 
-const MemoizedGraph = React.memo(function Layout({
-  isWidget,
-  openModal,
-  setSelectedNode,
-}: LayoutProps) {
+const MemoizedGraph = React.memo(function Layout({ isWidget }: LayoutProps) {
   const json = useConfig((state) => state.json);
   const json = useConfig((state) => state.json);
-  const [nodes, setNodes] = React.useState<NodeData[]>([]);
-  const [edges, setEdges] = React.useState<EdgeData[]>([]);
+
+  const [nodes, edges, newNodes, newEdges, selectedNode] = useNodeTools(
+    (state) => [
+      state.nodes,
+      state.edges,
+      state.newNodes,
+      state.newEdges,
+      state.selectedNode,
+    ],
+    shallow
+  );
+  const setNodeTools = useNodeTools((state) => state.setNodeTools);
+
   const [size, setSize] = React.useState({
   const [size, setSize] = React.useState({
     width: 2000,
     width: 2000,
     height: 2000,
     height: 2000,
@@ -55,38 +61,34 @@ const MemoizedGraph = React.memo(function Layout({
   React.useEffect(() => {
   React.useEffect(() => {
     const { nodes, edges } = getEdgeNodes(json, expand);
     const { nodes, edges } = getEdgeNodes(json, expand);
 
 
-    setNodes(nodes);
-    setEdges(edges);
+    setNodeTools("nodes", nodes);
+    setNodeTools("edges", edges);
+    setNodeTools("newNodes", nodes);
+    setNodeTools("newEdges", edges);
   }, [json, expand]);
   }, [json, expand]);
 
 
   const onInit = (ref: ReactZoomPanPinchRef) => {
   const onInit = (ref: ReactZoomPanPinchRef) => {
     setConfig("zoomPanPinch", ref);
     setConfig("zoomPanPinch", ref);
   };
   };
 
 
-  const onCanvasClick = () => {
-    const input = document.querySelector("input:focus") as HTMLInputElement;
-    if (input) input.blur();
-  };
-
   const onLayoutChange = (layout: ElkRoot) => {
   const onLayoutChange = (layout: ElkRoot) => {
     if (layout.width && layout.height)
     if (layout.width && layout.height)
       setSize({ width: layout.width, height: layout.height });
       setSize({ width: layout.width, height: layout.height });
   };
   };
 
 
-  const handleNodeClick = React.useCallback(
-    (e: React.MouseEvent<SVGElement>, props: NodeProps) => {
-      setSelectedNode(props.properties.text);
-      openModal();
+  const { selections, onClick, removeSelection } = useSelection({
+    nodes,
+    edges,
+    onSelection: (s) => {
+      if (!isWidget) {
+        if (s[0] === selectedNode) {
+          removeSelection(selectedNode);
+        } else {
+          setNodeTools("selectedNode", s[0]);
+        }
+      }
     },
     },
-    [openModal, setSelectedNode]
-  );
-
-  const node = React.useCallback(
-    (props) => (
-      <CustomNode onClick={(e) => handleNodeClick(e, props)} {...props} />
-    ),
-    [handleNodeClick]
-  );
+  });
 
 
   return (
   return (
     <StyledEditorWrapper isWidget={isWidget}>
     <StyledEditorWrapper isWidget={isWidget}>
@@ -114,8 +116,20 @@ const MemoizedGraph = React.memo(function Layout({
             direction={layout}
             direction={layout}
             key={layout}
             key={layout}
             onLayoutChange={onLayoutChange}
             onLayoutChange={onLayoutChange}
-            onCanvasClick={onCanvasClick}
-            node={node}
+            selections={selections}
+            node={(props) =>
+              newNodes.find((n) => n.id === props.id) ? (
+                <CustomNode
+                  onClick={(e) => onClick && onClick(e, props)}
+                  {...props}
+                />
+              ) : (
+                <></>
+              )
+            }
+            edge={(props) =>
+              newEdges.find((e) => e.id === props.id) ? <Edge /> : <></>
+            }
             zoomable={false}
             zoomable={false}
             readonly
             readonly
           />
           />
@@ -126,23 +140,20 @@ const MemoizedGraph = React.memo(function Layout({
 });
 });
 
 
 export const Graph = ({ isWidget = false }: { isWidget?: boolean }) => {
 export const Graph = ({ isWidget = false }: { isWidget?: boolean }) => {
-  const [isModalVisible, setModalVisible] = React.useState(false);
-  const [selectedNode, setSelectedNode] = React.useState<object>({});
-
-  const openModal = React.useCallback(() => setModalVisible(true), []);
-
+  const [newNodes, selectedNode, copySelectedNode] = useNodeTools(
+    (state) => [state.nodes, state.selectedNode, state.copySelectedNode],
+    shallow
+  );
+  const setNodeTools = useNodeTools((state) => state.setNodeTools);
+  const selectedNodeObject = newNodes.find((n) => n.id === selectedNode);
   return (
   return (
     <>
     <>
-      <MemoizedGraph
-        openModal={openModal}
-        setSelectedNode={setSelectedNode}
-        isWidget={isWidget}
-      />
+      <MemoizedGraph isWidget={isWidget} />
       {!isWidget && (
       {!isWidget && (
         <NodeModal
         <NodeModal
-          selectedNode={selectedNode}
-          visible={isModalVisible}
-          closeModal={() => setModalVisible(false)}
+          selectedNode={selectedNodeObject?.text}
+          visible={copySelectedNode}
+          closeModal={() => setNodeTools("copySelectedNode", false)}
         />
         />
       )}
       )}
     </>
     </>