|
@@ -4,13 +4,14 @@ 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, NodeData } 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 useGraph from "src/hooks/store/useGraph";
|
|
|
|
|
|
interface LayoutProps {
|
|
interface LayoutProps {
|
|
isWidget: boolean;
|
|
isWidget: boolean;
|
|
@@ -39,8 +40,10 @@ const MemoizedGraph = React.memo(function Layout({
|
|
setSelectedNode,
|
|
setSelectedNode,
|
|
}: LayoutProps) {
|
|
}: 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 = useGraph((state) => state.nodes);
|
|
|
|
+ const edges = useGraph((state) => state.edges);
|
|
|
|
+ const setGraphValue = useGraph((state) => state.setGraphValue);
|
|
|
|
+
|
|
const [size, setSize] = React.useState({
|
|
const [size, setSize] = React.useState({
|
|
width: 2000,
|
|
width: 2000,
|
|
height: 2000,
|
|
height: 2000,
|
|
@@ -52,41 +55,29 @@ const MemoizedGraph = React.memo(function Layout({
|
|
shallow
|
|
shallow
|
|
);
|
|
);
|
|
|
|
|
|
- React.useEffect(() => {
|
|
|
|
- const { nodes, edges } = getEdgeNodes(json, expand);
|
|
|
|
-
|
|
|
|
- setNodes(nodes);
|
|
|
|
- setEdges(edges);
|
|
|
|
- }, [json, expand]);
|
|
|
|
|
|
+ const handleNodeClick = React.useCallback(
|
|
|
|
+ (e: React.MouseEvent<SVGElement>, data: NodeData) => {
|
|
|
|
+ setSelectedNode(data.text);
|
|
|
|
+ openModal();
|
|
|
|
+ },
|
|
|
|
+ [openModal, setSelectedNode]
|
|
|
|
+ );
|
|
|
|
|
|
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();
|
|
|
|
- },
|
|
|
|
- [openModal, setSelectedNode]
|
|
|
|
- );
|
|
|
|
|
|
+ React.useEffect(() => {
|
|
|
|
+ const { nodes, edges } = getEdgeNodes(json, expand);
|
|
|
|
|
|
- const node = React.useCallback(
|
|
|
|
- (props) => (
|
|
|
|
- <CustomNode onClick={(e) => handleNodeClick(e, props)} {...props} />
|
|
|
|
- ),
|
|
|
|
- [handleNodeClick]
|
|
|
|
- );
|
|
|
|
|
|
+ setGraphValue("nodes", nodes);
|
|
|
|
+ setGraphValue("edges", edges);
|
|
|
|
+ }, [expand, json, setGraphValue]);
|
|
|
|
|
|
return (
|
|
return (
|
|
<StyledEditorWrapper isWidget={isWidget}>
|
|
<StyledEditorWrapper isWidget={isWidget}>
|
|
@@ -98,6 +89,9 @@ const MemoizedGraph = React.memo(function Layout({
|
|
wheel={{
|
|
wheel={{
|
|
step: 0.05,
|
|
step: 0.05,
|
|
}}
|
|
}}
|
|
|
|
+ doubleClick={{
|
|
|
|
+ disabled: true,
|
|
|
|
+ }}
|
|
>
|
|
>
|
|
<TransformComponent
|
|
<TransformComponent
|
|
wrapperStyle={{
|
|
wrapperStyle={{
|
|
@@ -114,8 +108,12 @@ const MemoizedGraph = React.memo(function Layout({
|
|
direction={layout}
|
|
direction={layout}
|
|
key={layout}
|
|
key={layout}
|
|
onLayoutChange={onLayoutChange}
|
|
onLayoutChange={onLayoutChange}
|
|
- onCanvasClick={onCanvasClick}
|
|
|
|
- node={node}
|
|
|
|
|
|
+ node={(props) => (
|
|
|
|
+ <CustomNode {...props} onClick={handleNodeClick} />
|
|
|
|
+ )}
|
|
|
|
+ edge={(props) => (
|
|
|
|
+ <Edge {...props} containerClassName={`edge-${props.id}`} />
|
|
|
|
+ )}
|
|
zoomable={false}
|
|
zoomable={false}
|
|
readonly
|
|
readonly
|
|
/>
|
|
/>
|
|
@@ -131,6 +129,28 @@ export const Graph = ({ isWidget = false }: { isWidget?: boolean }) => {
|
|
|
|
|
|
const openModal = React.useCallback(() => setModalVisible(true), []);
|
|
const openModal = React.useCallback(() => setModalVisible(true), []);
|
|
|
|
|
|
|
|
+ const collapsedNodes = useGraph((state) => state.collapsedNodes);
|
|
|
|
+ const collapsedEdges = useGraph((state) => state.collapsedEdges);
|
|
|
|
+
|
|
|
|
+ React.useEffect(() => {
|
|
|
|
+ const nodeList = collapsedNodes.map((id) => `[id*="node-${id}"]`);
|
|
|
|
+ const edgeList = collapsedEdges.map((id) => `[class*="edge-${id}"]`);
|
|
|
|
+
|
|
|
|
+ const nodes = document.querySelectorAll('[id*="node-"]');
|
|
|
|
+ const edges = document.querySelectorAll('[class*="edge-"]');
|
|
|
|
+
|
|
|
|
+ nodes.forEach((node) => node.classList.remove("hide"));
|
|
|
|
+ edges.forEach((edges) => edges.classList.remove("hide"));
|
|
|
|
+
|
|
|
|
+ if (nodeList.length) {
|
|
|
|
+ const selectedNodes = document.querySelectorAll(nodeList.join(","));
|
|
|
|
+ const selectedEdges = document.querySelectorAll(edgeList.join(","));
|
|
|
|
+
|
|
|
|
+ selectedNodes.forEach((node) => node.classList.add("hide"));
|
|
|
|
+ selectedEdges.forEach((edge) => edge.classList.add("hide"));
|
|
|
|
+ }
|
|
|
|
+ }, [collapsedNodes, collapsedEdges]);
|
|
|
|
+
|
|
return (
|
|
return (
|
|
<>
|
|
<>
|
|
<MemoizedGraph
|
|
<MemoizedGraph
|