mirror of
https://github.com/openziti/zrok.git
synced 2025-02-22 05:01:01 +01:00
back to react flow (for now)
This commit is contained in:
parent
0eb2163a9c
commit
8e3dc00698
120
ui/package-lock.json
generated
120
ui/package-lock.json
generated
@ -13,9 +13,11 @@
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@testing-library/react": "^13.3.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"dagre": "^0.8.5",
|
||||
"react": "^18.2.0",
|
||||
"react-data-table-component": "^7.5.2",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-flow-renderer": "^10.3.12",
|
||||
"react-force-graph-2d": "^1.23.10",
|
||||
"react-scripts": "5.0.1",
|
||||
"styled-components": "^5.3.5",
|
||||
@ -5589,6 +5591,11 @@
|
||||
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
|
||||
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA=="
|
||||
},
|
||||
"node_modules/classcat": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.3.tgz",
|
||||
"integrity": "sha512-6dK2ke4VEJZOFx2ZfdDAl5OhEL8lvkl6EHF92IfRePfHxQTqir5NlcNVUv+2idjDqCX2NDc8m8YSAI5NI975ZQ=="
|
||||
},
|
||||
"node_modules/clean-css": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz",
|
||||
@ -6503,6 +6510,15 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/dagre": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz",
|
||||
"integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==",
|
||||
"dependencies": {
|
||||
"graphlib": "^2.1.8",
|
||||
"lodash": "^4.17.15"
|
||||
}
|
||||
},
|
||||
"node_modules/damerau-levenshtein": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
||||
@ -8770,6 +8786,14 @@
|
||||
"resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
|
||||
"integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ=="
|
||||
},
|
||||
"node_modules/graphlib": {
|
||||
"version": "2.1.8",
|
||||
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
|
||||
"integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.15"
|
||||
}
|
||||
},
|
||||
"node_modules/gzip-size": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz",
|
||||
@ -14629,6 +14653,26 @@
|
||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
|
||||
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
|
||||
},
|
||||
"node_modules/react-flow-renderer": {
|
||||
"version": "10.3.12",
|
||||
"resolved": "https://registry.npmjs.org/react-flow-renderer/-/react-flow-renderer-10.3.12.tgz",
|
||||
"integrity": "sha512-DTaz4HV0rA/qtvY80fjdb/QwIvtZEhqCQ2iAqfzFH08RjWCrLmESX4Nc400EB3CGcCK8/pDn/ta4cOS3udunTw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.18.9",
|
||||
"classcat": "^5.0.3",
|
||||
"d3-drag": "^3.0.0",
|
||||
"d3-selection": "^3.0.0",
|
||||
"d3-zoom": "^3.0.0",
|
||||
"zustand": "^3.7.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "16 || 17 || 18",
|
||||
"react-dom": "16 || 17 || 18"
|
||||
}
|
||||
},
|
||||
"node_modules/react-force-graph-2d": {
|
||||
"version": "1.23.10",
|
||||
"resolved": "https://registry.npmjs.org/react-force-graph-2d/-/react-force-graph-2d-1.23.10.tgz",
|
||||
@ -16424,6 +16468,19 @@
|
||||
"is-typedarray": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "4.7.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
|
||||
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unbox-primitive": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
||||
@ -17445,6 +17502,22 @@
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/zustand": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz",
|
||||
"integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==",
|
||||
"engines": {
|
||||
"node": ">=12.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
@ -21385,6 +21458,11 @@
|
||||
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
|
||||
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA=="
|
||||
},
|
||||
"classcat": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.3.tgz",
|
||||
"integrity": "sha512-6dK2ke4VEJZOFx2ZfdDAl5OhEL8lvkl6EHF92IfRePfHxQTqir5NlcNVUv+2idjDqCX2NDc8m8YSAI5NI975ZQ=="
|
||||
},
|
||||
"clean-css": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz",
|
||||
@ -22044,6 +22122,15 @@
|
||||
"d3-transition": "2 - 3"
|
||||
}
|
||||
},
|
||||
"dagre": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz",
|
||||
"integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==",
|
||||
"requires": {
|
||||
"graphlib": "^2.1.8",
|
||||
"lodash": "^4.17.15"
|
||||
}
|
||||
},
|
||||
"damerau-levenshtein": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
||||
@ -23708,6 +23795,14 @@
|
||||
"resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
|
||||
"integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ=="
|
||||
},
|
||||
"graphlib": {
|
||||
"version": "2.1.8",
|
||||
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
|
||||
"integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.15"
|
||||
}
|
||||
},
|
||||
"gzip-size": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz",
|
||||
@ -27775,6 +27870,19 @@
|
||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
|
||||
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
|
||||
},
|
||||
"react-flow-renderer": {
|
||||
"version": "10.3.12",
|
||||
"resolved": "https://registry.npmjs.org/react-flow-renderer/-/react-flow-renderer-10.3.12.tgz",
|
||||
"integrity": "sha512-DTaz4HV0rA/qtvY80fjdb/QwIvtZEhqCQ2iAqfzFH08RjWCrLmESX4Nc400EB3CGcCK8/pDn/ta4cOS3udunTw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.18.9",
|
||||
"classcat": "^5.0.3",
|
||||
"d3-drag": "^3.0.0",
|
||||
"d3-selection": "^3.0.0",
|
||||
"d3-zoom": "^3.0.0",
|
||||
"zustand": "^3.7.2"
|
||||
}
|
||||
},
|
||||
"react-force-graph-2d": {
|
||||
"version": "1.23.10",
|
||||
"resolved": "https://registry.npmjs.org/react-force-graph-2d/-/react-force-graph-2d-1.23.10.tgz",
|
||||
@ -29104,6 +29212,12 @@
|
||||
"is-typedarray": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.7.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
|
||||
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
|
||||
"peer": true
|
||||
},
|
||||
"unbox-primitive": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
||||
@ -29884,6 +29998,12 @@
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
|
||||
},
|
||||
"zustand": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz",
|
||||
"integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==",
|
||||
"requires": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,11 @@
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@testing-library/react": "^13.3.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"dagre": "^0.8.5",
|
||||
"react": "^18.2.0",
|
||||
"react-data-table-component": "^7.5.2",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-flow-renderer": "^10.3.12",
|
||||
"react-force-graph-2d": "^1.23.10",
|
||||
"react-scripts": "5.0.1",
|
||||
"styled-components": "^5.3.5",
|
||||
|
@ -1,23 +1,19 @@
|
||||
import * as metadata from './api/metadata';
|
||||
import {useEffect, useLayoutEffect, useRef, useState} from "react";
|
||||
import ForceGraph2D from 'react-force-graph-2d';
|
||||
|
||||
let g1 = {}
|
||||
import ReactFlow, {isNode, useNodesState} from "react-flow-renderer";
|
||||
import dagre from 'dagre';
|
||||
|
||||
const Network = (props) => {
|
||||
const ref = useRef();
|
||||
const [graph, setGraph] = useState({nodes: [], links: []})
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState([]);
|
||||
const [edges, setEdges] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
let mounted = true
|
||||
let g1 = graph
|
||||
let interval = setInterval(() => {
|
||||
metadata.overview().then(resp => {
|
||||
let g = buildGraph(resp.data)
|
||||
if(!compareGraphs(g, g1)) {
|
||||
setGraph(g)
|
||||
g1 = g
|
||||
}
|
||||
setNodes(getLayout(g))
|
||||
setEdges(g.edges)
|
||||
})
|
||||
}, 1000)
|
||||
return () => {
|
||||
@ -29,34 +25,10 @@ const Network = (props) => {
|
||||
return (
|
||||
<div className={"network"}>
|
||||
<h1>Network</h1>
|
||||
<ForceGraph2D
|
||||
ref={ref}
|
||||
width={1024}
|
||||
height={300}
|
||||
graphData={graph}
|
||||
nodeDefaultSize={[100, 50]}
|
||||
nodeCanvasObject={(node, ctx, globalScale) => {
|
||||
const label = node.name;
|
||||
const fontSize = 12/globalScale;
|
||||
ctx.font = `${fontSize}px JetBrains Mono`;
|
||||
const textWidth = ctx.measureText(label).width;
|
||||
const bckgDimensions = [textWidth, fontSize].map(n => n + fontSize * 2.2); // some padding
|
||||
|
||||
ctx.fillStyle = '#3b2693';
|
||||
ctx.strokeStyle = '#3b2693'
|
||||
ctx.lineWidth = 0.5
|
||||
ctx.fillRect(node.x - bckgDimensions[0] / 2, node.y - bckgDimensions[1] / 2, ...bckgDimensions);
|
||||
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillStyle = 'white';
|
||||
ctx.fillText(label, node.x, node.y);
|
||||
|
||||
node.__bckgDimensions = bckgDimensions; // to re-use in nodePointerAreaPaint
|
||||
}}
|
||||
onEngineStop={() => {
|
||||
ref.current.zoomToFit(200);
|
||||
}}
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
@ -65,24 +37,34 @@ const Network = (props) => {
|
||||
function buildGraph(overview) {
|
||||
let out = {
|
||||
nodes: [],
|
||||
links: []
|
||||
edges: []
|
||||
}
|
||||
let id = 1
|
||||
overview.forEach((item) => {
|
||||
let envId = id
|
||||
out.nodes.push({
|
||||
id: item.environment.zitiIdentityId,
|
||||
name: 'Environment: ' + item.environment.zitiIdentityId
|
||||
id: '' + envId,
|
||||
data: {label: 'Environment: ' + item.environment.zitiIdentityId},
|
||||
position: {x: (id * 25), y: 0},
|
||||
draggable: true
|
||||
});
|
||||
id++
|
||||
if(item.services != null) {
|
||||
item.services.forEach((svc) => {
|
||||
if(svc.active) {
|
||||
item.services.forEach((item) => {
|
||||
if(item.active) {
|
||||
out.nodes.push({
|
||||
id: svc.zitiServiceId,
|
||||
name: 'Service: ' + svc.zitiServiceId
|
||||
id: '' + id,
|
||||
data: {label: 'Service: ' + item.zitiServiceId},
|
||||
position: {x: (id * 25), y: 0},
|
||||
draggable: true
|
||||
})
|
||||
out.links.push({
|
||||
source: item.environment.zitiIdentityId,
|
||||
target: svc.zitiServiceId
|
||||
out.edges.push({
|
||||
id: 'e' + envId + '-' + id,
|
||||
source: '' + envId,
|
||||
target: '' + id,
|
||||
animated: true
|
||||
})
|
||||
id++
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -90,18 +72,33 @@ function buildGraph(overview) {
|
||||
return out
|
||||
}
|
||||
|
||||
function compareGraphs(g, g1) {
|
||||
if(g.nodes.length !== g1.nodes.length) return false;
|
||||
for(let i = 0; i < g.nodes.length; i++) {
|
||||
if(!compareNodes(g.nodes[i], g1.nodes[i])) return false;
|
||||
}
|
||||
return true
|
||||
const nodeWidth = 215;
|
||||
const nodeHeight = 75;
|
||||
|
||||
function getLayout(overview) {
|
||||
const dagreGraph = new dagre.graphlib.Graph();
|
||||
dagreGraph.setGraph({ rankdir: 'TB' });
|
||||
dagreGraph.setDefaultEdgeLabel(() => ({}));
|
||||
|
||||
overview.nodes.forEach((n) => {
|
||||
dagreGraph.setNode(n.id, { width: nodeWidth, height: nodeHeight });
|
||||
})
|
||||
overview.edges.forEach((e) => {
|
||||
dagreGraph.setEdge(e.source, e.target);
|
||||
})
|
||||
dagre.layout(dagreGraph);
|
||||
|
||||
return overview.nodes.map((n) => {
|
||||
const nodeWithPosition = dagreGraph.node(n.id);
|
||||
n.targetPosition = 'top';
|
||||
n.sourcePosition = 'bottom';
|
||||
n.position = {
|
||||
x: nodeWithPosition.x - (nodeWidth / 2) + (Math.random() / 1000) + 50,
|
||||
y: nodeWithPosition.y - (nodeHeight / 2) + 50,
|
||||
}
|
||||
return n;
|
||||
});
|
||||
}
|
||||
|
||||
function compareNodes(n, n1) {
|
||||
if(n.id !== n1.id) return false;
|
||||
if(n.name !== n1.name) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
export default Network;
|
@ -117,4 +117,8 @@ h1, h2, h3, h4, h5, h6 {
|
||||
|
||||
.network {
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.react-flow__attribution {
|
||||
display: none;
|
||||
}
|
Loading…
Reference in New Issue
Block a user