UNPKG

schyma

Version:

JSON Schemas Visualizer React component

181 lines 9.35 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const react_1 = tslib_1.__importStar(require("react")); const react_flow_smart_edge_1 = require("@tisoap/react-flow-smart-edge"); const reactflow_1 = require("reactflow"); const reusables_1 = require("../utils/reusables"); const dagreUtils_1 = require("../utils/dagreUtils"); const position = { x: 0, y: 0, zoom: 0.2 }; const initialEdges = [ { id: 'edges-e5-7', source: '0', target: '1', label: '+', labelBgPadding: [8, 4], labelBgBorderRadius: 4, animated: true, type: 'smart', markerEnd: { type: reactflow_1.MarkerType.ArrowClosed, }, }, ]; function Flow({ initialNode, nNodes, setnNodes, setCurrentNode, schema }) { const { nodes: layoutedNodes, edges: layoutedEdges } = (0, dagreUtils_1.getLayoutedElements)([initialNode], initialEdges); const [nodes, setNodes, onNodesChange] = (0, reactflow_1.useNodesState)(layoutedNodes); const [edges, setEdges, onEdgesChange] = (0, reactflow_1.useEdgesState)(layoutedEdges); const { setCenter } = (0, reactflow_1.useReactFlow)(); const onConnect = (0, react_1.useCallback)((connection) => setEdges((eds) => (0, reactflow_1.addEdge)(Object.assign(Object.assign({}, connection), { type: reactflow_1.ConnectionLineType.SmoothStep, animated: true }), eds)), // eslint-disable-next-line react-hooks/exhaustive-deps []); const extractChildren = (props, parent) => tslib_1.__awaiter(this, void 0, void 0, function* () { const children = []; for (const prop in props) { const id = String(Math.floor(Math.random() * 1000000)); if (props[prop].$ref) { const res = yield (0, reusables_1.resolveRef)(props[prop].$ref, schema); children.push({ id, type: 'input', data: Object.assign(Object.assign(Object.assign(Object.assign({}, props[prop]), { label: prop, parent: parent.id, relations: Object.assign(Object.assign({}, parent.relations), { [parent.id]: 'node' }) }), res), { children: [] }), position: position, sourcePosition: reactflow_1.Position.Right, targetPosition: reactflow_1.Position.Left, }); } else { children.push({ id, type: 'input', data: Object.assign(Object.assign({}, props[prop]), { label: prop, id, parent: parent.id, relations: Object.assign(Object.assign({}, parent.relations), { [parent.id]: 'node' }), children: [] }), position: position, sourcePosition: reactflow_1.Position.Right, targetPosition: reactflow_1.Position.Left, }); } } return children; }); (0, react_1.useEffect)(() => { const fetchInitialChildren = () => tslib_1.__awaiter(this, void 0, void 0, function* () { const newNodes = []; const properties = initialNode.data.properties; const children = yield extractChildren(properties, initialNode); newNodes.push({ id: initialNode.id, type: 'input', data: { children, label: initialNode.data.label, description: initialNode.data.description, properties: initialNode.data.properties, relations: initialNode.data.relations, }, position: { x: 0, y: 0 }, sourcePosition: reactflow_1.Position.Right, targetPosition: reactflow_1.Position.Left, }); setNodes(newNodes); }); fetchInitialChildren(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // Node focus when clicked const focusNode = (children, zoom) => { if (children.length === 0) return; let middleChild = children[Math.floor(children.length / 2)]; const middleChildWithLatestPosition = nodes.filter((a) => a.id == middleChild.id)[0]; if (middleChildWithLatestPosition) { middleChild = middleChildWithLatestPosition; } setCenter(middleChild.position.x, middleChild.position.y, { zoom, duration: 1000 }); }; // On Node Click const nodeClick = (_event, node) => tslib_1.__awaiter(this, void 0, void 0, function* () { const findChildren = nodes.filter((item) => { var _a; return ((_a = item === null || item === void 0 ? void 0 : item.data) === null || _a === void 0 ? void 0 : _a.parent) === node.id; }); if (!findChildren.length) { const itemChildren = node.data.children; const newEdges = [ ...edges, ...itemChildren.map((item) => { var _a; return { id: String(Math.floor(Math.random() * 1000000)), source: (_a = item === null || item === void 0 ? void 0 : item.data) === null || _a === void 0 ? void 0 : _a.parent, target: item === null || item === void 0 ? void 0 : item.id, markerEnd: { type: reactflow_1.MarkerType.ArrowClosed, }, }; }), ]; //TODO: Fix nodes type error const newNodes = nodes.concat(itemChildren); const { nodes: layoutedNodes, edges: layoutedEdges } = (0, dagreUtils_1.getLayoutedElements)(newNodes, newEdges, 'LR'); setNodes([...layoutedNodes]); setEdges([...layoutedEdges]); if (itemChildren.length > 0) { focusNode(itemChildren, 0.9); } } else { const newNodes = (0, reusables_1.removeElementsByParent)(nodes, node.id); const newEdges = (0, reusables_1.removeEdgesByParent)(edges, node.id); const { nodes: layoutedNodes, edges: layoutedEdges } = (0, dagreUtils_1.getLayoutedElements)(newNodes, newEdges, 'LR'); setNodes([...layoutedNodes]); setEdges([...layoutedEdges]); focusNode([node], 0.9); } }); //On Node Hover function handleMouseEnter(_e, node) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (!nNodes[node.id]) { const itemChildren = []; const nodeChildren = node.data.children; yield Promise.all(nodeChildren.map((item) => tslib_1.__awaiter(this, void 0, void 0, function* () { let children = []; const label = item.data.label; const extractProps = (0, reusables_1.propMerge)(item.data, label); if (Object.keys(extractProps).length > 0) { const res = yield extractChildren(extractProps, item); children = res; } const relations = Object.assign(Object.assign({}, node.data.relations), item.data.relations); itemChildren.push({ id: item.id, type: (children === null || children === void 0 ? void 0 : children.length) > 0 ? 'default' : 'output', data: { label: item.data.label, children: children, parent: item.data.parent, examples: item.data.examples, description: item.data.description, relations: relations, }, position: position, sourcePosition: reactflow_1.Position.Right, targetPosition: reactflow_1.Position.Left, }); }))); node.data.children = itemChildren; nNodes[node.id] = node; setnNodes(nNodes); } setCurrentNode(node); }); } const edgeTypes = { smart: react_flow_smart_edge_1.SmartBezierEdge, }; return (react_1.default.createElement(reactflow_1.ReactFlow, { nodes: nodes, edges: edges, edgeTypes: edgeTypes, onNodesChange: onNodesChange, connectionLineType: reactflow_1.ConnectionLineType.SmoothStep, onEdgesChange: onEdgesChange, onConnect: onConnect, onNodeMouseEnter: handleMouseEnter, onNodeClick: nodeClick, fitView: true, defaultViewport: { x: 1, y: 1, zoom: 0.9 } }, react_1.default.createElement(reactflow_1.MiniMap, null), react_1.default.createElement(reactflow_1.Controls, null), react_1.default.createElement(reactflow_1.Background, null))); } exports.default = ({ setCurrentNode, setnNodes, nNodes, initialNode, schema }) => (react_1.default.createElement(reactflow_1.ReactFlowProvider, null, react_1.default.createElement(Flow, { setnNodes: setnNodes, nNodes: nNodes, setCurrentNode: setCurrentNode, initialNode: initialNode, schema: schema }))); //# sourceMappingURL=Nodes.js.map