Skip to content

Commit

Permalink
feature: Edit JSON in Diagram View
Browse files Browse the repository at this point in the history
- add graphParser to parse graph Nodes into JSON
- add functionality to update JSON on node edit

References Issue #147
Changes to be committed:
	modified:   src/containers/Modals/NodeModal/index.tsx
	new file:   src/utils/graphParser.ts
  • Loading branch information
theogainey committed Oct 5, 2022
1 parent 62b2666 commit 0555858
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/containers/Modals/NodeModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import styled from "styled-components";
import { parser } from "src/utils/jsonParser";
import { isValidJson } from "src/utils/isValidJson";
import { ErrorContainer } from "src/components/ErrorContainer";
import useConfig from "src/hooks/store/useConfig";
import { graphParser } from "src/utils/graphParser";

interface NodeModalProps {
selectedNode: NodeData;
Expand All @@ -32,6 +34,8 @@ const StyledTextarea = styled.textarea`
export const NodeModal = ({ selectedNode, visible, closeModal }: NodeModalProps) => {
const setGraphValue = useGraph(state => state.setGraphValue);
const nodes = useGraph(state => state.nodes);
const edges = useGraph(state => state.edges);
const setJson = useConfig(state => state.setJson);
const nodeData = Array.isArray(selectedNode.text)
? Object.fromEntries(selectedNode.text)
: selectedNode.text;
Expand All @@ -51,9 +55,12 @@ export const NodeModal = ({ selectedNode, visible, closeModal }: NodeModalProps)
Array.isArray(parsedText)
? setText(Object.fromEntries(parsedText))
: setText(parsedText);
const updatedNode = {...selectedNode, text: parsedText} ;
setGraphValue("nodes", [...nodes.filter(({id}) => id !== selectedNode.id), updatedNode]);
hasError(false);
const updatedNode = {...selectedNode, text: parsedText};
const newNodes = nodes.map((node)=> node.id===selectedNode.id ? updatedNode : node);

setGraphValue("nodes", newNodes);
hasError(false);
setJson(JSON.stringify(graphParser(newNodes, edges)));
}
else {
hasError(true);
Expand Down
43 changes: 43 additions & 0 deletions src/utils/graphParser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

const nodeToValue = (node:NodeData) => Array.isArray(node.text) ? Object.fromEntries(node.text) : node.text;

const hasEdgeLeaving = (node:NodeData, edges:EdgeData[]) => edges.some((edge)=> node.id === edge.from);
const hasChild = (node:NodeData) => !!node.data.hasChild;

const getChildNode = (edge: EdgeData, nodes: NodeData[]) => nodes.find((node)=> node.id === edge.to) as NodeData;
const moveNodeToFront = (node: NodeData, nodes: NodeData[]) => [node, ...removeNode(node, nodes)];

const removeNode = (node: NodeData, nodes: NodeData[]) => nodes.filter((n)=> n.id !== node.id);
const removeEdge = (edge: EdgeData, edges: EdgeData[]) => edges.filter((e)=> e.id !== edge.id);

const getEdge = (node:NodeData, edges:EdgeData[]) => edges.find((edge)=> node.id === edge.from) as EdgeData;

export const graphParser = (nodes:NodeData[], edges:EdgeData[]) =>{
const currentNode = nodes[0];
if((!hasChild(currentNode) && !hasEdgeLeaving(currentNode, edges))){
return nodeToValue(currentNode);
}
if(hasChild(currentNode)) {
const childEdges = edges.filter((edge)=> edge.from === currentNode.id);
const remainingEdges = edges.filter((edge)=> edge.from !== currentNode.id);
const remainingNodes = removeNode(currentNode, nodes);
const key = nodeToValue(currentNode);
const obj = {};
obj[key] = childEdges.map((edge)=>{
const childNode = getChildNode(edge, remainingNodes);
const nextNodes = moveNodeToFront(childNode, remainingNodes);
return typeof nodeToValue(childNode) === 'string'
? nodeToValue(childNode)
: Object.assign({}, nodeToValue(childNode), graphParser(nextNodes, remainingEdges));
});
return obj;
}
const remainingNodes = removeNode(currentNode, nodes);
const nextEdge = getEdge(currentNode, edges);
const remainingEdges = removeEdge(nextEdge, edges);
const childNode = getChildNode(nextEdge, remainingNodes);
const nextNodes = moveNodeToFront(childNode, remainingNodes);

return Object.assign({}, nodeToValue(currentNode), graphParser(nextNodes, remainingEdges));
}

0 comments on commit 0555858

Please sign in to comment.