|
@@ -1,22 +1,16 @@
|
|
import React from "react";
|
|
import React from "react";
|
|
-import styled, { css } from "styled-components";
|
|
|
|
|
|
+import styled from "styled-components";
|
|
import ReactFlow, {
|
|
import ReactFlow, {
|
|
ControlButton,
|
|
ControlButton,
|
|
Controls,
|
|
Controls,
|
|
Elements,
|
|
Elements,
|
|
- isNode,
|
|
|
|
NodeExtent,
|
|
NodeExtent,
|
|
- Position,
|
|
|
|
- ReactFlowProvider,
|
|
|
|
} from "react-flow-renderer";
|
|
} from "react-flow-renderer";
|
|
import { defaultValue } from "../JsonEditor";
|
|
import { defaultValue } from "../JsonEditor";
|
|
import { parser } from "src/utils/json-editor-parser";
|
|
import { parser } from "src/utils/json-editor-parser";
|
|
import { useLocalStorage } from "usehooks-ts";
|
|
import { useLocalStorage } from "usehooks-ts";
|
|
-import dagre from "dagre";
|
|
|
|
import { CustomNodeComponent } from "./Node";
|
|
import { CustomNodeComponent } from "./Node";
|
|
-
|
|
|
|
-const dagreGraph = new dagre.graphlib.Graph();
|
|
|
|
-dagreGraph.setDefaultEdgeLabel(() => ({}));
|
|
|
|
|
|
+import { onLayout } from "./helpers";
|
|
|
|
|
|
const nodeExtent: NodeExtent = [
|
|
const nodeExtent: NodeExtent = [
|
|
[0, 0],
|
|
[0, 0],
|
|
@@ -49,57 +43,22 @@ const StyledLiveEditor = styled.div`
|
|
}
|
|
}
|
|
`;
|
|
`;
|
|
|
|
|
|
-const onLayout = (
|
|
|
|
- direction: string,
|
|
|
|
- elements: Elements,
|
|
|
|
- setElements: React.Dispatch<Elements>
|
|
|
|
-) => {
|
|
|
|
- const isHorizontal = direction === "LR";
|
|
|
|
- dagreGraph.setGraph({ rankdir: direction });
|
|
|
|
-
|
|
|
|
- elements.forEach((el) => {
|
|
|
|
- if (isNode(el)) {
|
|
|
|
- dagreGraph.setNode(el.id, { width: 175, height: 50 });
|
|
|
|
- } else {
|
|
|
|
- dagreGraph.setEdge(el.source, el.target);
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- dagre.layout(dagreGraph);
|
|
|
|
-
|
|
|
|
- const layoutedElements = elements.map((el) => {
|
|
|
|
- if (isNode(el)) {
|
|
|
|
- const nodeWithPosition = dagreGraph.node(el.id);
|
|
|
|
- el.targetPosition = isHorizontal ? Position.Left : Position.Top;
|
|
|
|
- el.sourcePosition = isHorizontal ? Position.Right : Position.Bottom;
|
|
|
|
- el.position = {
|
|
|
|
- x: nodeWithPosition.x + Math.random() / 1000,
|
|
|
|
- y: nodeWithPosition.y,
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return el;
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- setElements(layoutedElements);
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
const nodeTypes = {
|
|
const nodeTypes = {
|
|
special: CustomNodeComponent,
|
|
special: CustomNodeComponent,
|
|
};
|
|
};
|
|
|
|
|
|
-const LiveEditor: React.FC = () => {
|
|
|
|
|
|
+export const LiveEditor: React.FC = () => {
|
|
const [json] = useLocalStorage("json", JSON.stringify(defaultValue));
|
|
const [json] = useLocalStorage("json", JSON.stringify(defaultValue));
|
|
const [rfInstance, setRfInstance] = React.useState<any>(null);
|
|
const [rfInstance, setRfInstance] = React.useState<any>(null);
|
|
const [valid, setValid] = React.useState(true);
|
|
const [valid, setValid] = React.useState(true);
|
|
const [elements, setElements] = React.useState<Elements>(
|
|
const [elements, setElements] = React.useState<Elements>(
|
|
- parser(JSON.parse(json))
|
|
|
|
|
|
+ parser(json)
|
|
);
|
|
);
|
|
|
|
|
|
React.useEffect(() => {
|
|
React.useEffect(() => {
|
|
try {
|
|
try {
|
|
JSON.parse(json);
|
|
JSON.parse(json);
|
|
- setElements(parser(JSON.parse(json)));
|
|
|
|
|
|
+ onLayout("RL", parser(json), setElements);
|
|
setValid(true);
|
|
setValid(true);
|
|
} catch (error) {
|
|
} catch (error) {
|
|
setValid(false);
|
|
setValid(false);
|
|
@@ -116,27 +75,21 @@ const LiveEditor: React.FC = () => {
|
|
|
|
|
|
return (
|
|
return (
|
|
<StyledLiveEditor>
|
|
<StyledLiveEditor>
|
|
- <ReactFlowProvider>
|
|
|
|
- <ReactFlow
|
|
|
|
- nodeExtent={nodeExtent}
|
|
|
|
- elements={elements}
|
|
|
|
- nodeTypes={nodeTypes}
|
|
|
|
- onLoad={(rf: any) => {
|
|
|
|
- setRfInstance(rf);
|
|
|
|
- onLayout("RL", elements, setElements);
|
|
|
|
- }}
|
|
|
|
- >
|
|
|
|
- <Controls>
|
|
|
|
- <ControlButton
|
|
|
|
- onClick={() => onLayout("RL", elements, setElements)}
|
|
|
|
- >
|
|
|
|
- Style
|
|
|
|
- </ControlButton>
|
|
|
|
- </Controls>
|
|
|
|
- </ReactFlow>
|
|
|
|
- </ReactFlowProvider>
|
|
|
|
|
|
+ <ReactFlow
|
|
|
|
+ nodeExtent={nodeExtent}
|
|
|
|
+ elements={elements}
|
|
|
|
+ nodeTypes={nodeTypes}
|
|
|
|
+ onLoad={(rf: any) => {
|
|
|
|
+ setRfInstance(rf);
|
|
|
|
+ onLayout("RL", elements, setElements);
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ <Controls>
|
|
|
|
+ <ControlButton onClick={() => onLayout("RL", elements, setElements)}>
|
|
|
|
+ Style
|
|
|
|
+ </ControlButton>
|
|
|
|
+ </Controls>
|
|
|
|
+ </ReactFlow>
|
|
</StyledLiveEditor>
|
|
</StyledLiveEditor>
|
|
);
|
|
);
|
|
};
|
|
};
|
|
-
|
|
|
|
-export default LiveEditor;
|
|
|