mirror of
https://github.com/openziti/zrok.git
synced 2025-06-25 20:22:45 +02:00
This commit is contained in:
parent
deb0d8ca22
commit
4b6613abd0
@ -1,6 +1,6 @@
|
|||||||
import {useCallback, useEffect, useRef, useState} from "react";
|
import {useCallback, useEffect, useRef, useState} from "react";
|
||||||
import {Configuration, MetadataApi} from "./api";
|
import {Configuration, MetadataApi} from "./api";
|
||||||
import {mergeVisualOverview, nodesEqual, VisualOverview} from "./model/visualizer.ts";
|
import {layout, mergeVisualOverview, nodesEqual, VisualOverview} from "./model/visualizer.ts";
|
||||||
import {Grid2} from "@mui/material";
|
import {Grid2} from "@mui/material";
|
||||||
import NavBar from "./NavBar.tsx";
|
import NavBar from "./NavBar.tsx";
|
||||||
import Visualizer from "./Visualizer.tsx";
|
import Visualizer from "./Visualizer.tsx";
|
||||||
@ -20,6 +20,8 @@ const ApiConsole = ({ logout }: ApiConsoleProps) => {
|
|||||||
const overview = useStore((state) => state.overview);
|
const overview = useStore((state) => state.overview);
|
||||||
const updateOverview = useStore((state) => state.updateOverview);
|
const updateOverview = useStore((state) => state.updateOverview);
|
||||||
const oldVov = useRef<VisualOverview>(overview);
|
const oldVov = useRef<VisualOverview>(overview);
|
||||||
|
const updateNodes = useStore((state) => state.updateNodes);
|
||||||
|
const updateEdges = useStore((state) => state.updateEdges);
|
||||||
const selectedNode = useStore((state) => state.selectedNode);
|
const selectedNode = useStore((state) => state.selectedNode);
|
||||||
const updateEnvironments = useStore((state) => state.updateEnvironments);
|
const updateEnvironments = useStore((state) => state.updateEnvironments);
|
||||||
const [mainPanel, setMainPanel] = useState(<Visualizer />);
|
const [mainPanel, setMainPanel] = useState(<Visualizer />);
|
||||||
@ -58,6 +60,14 @@ const ApiConsole = ({ logout }: ApiConsoleProps) => {
|
|||||||
console.log("refreshed vov", oldVov.current.nodes, newVov.nodes);
|
console.log("refreshed vov", oldVov.current.nodes, newVov.nodes);
|
||||||
updateOverview(newVov);
|
updateOverview(newVov);
|
||||||
oldVov.current = newVov;
|
oldVov.current = newVov;
|
||||||
|
|
||||||
|
let laidOut = layout(newVov.nodes, newVov.edges);
|
||||||
|
let selected = laidOut.nodes.map((n) => ({
|
||||||
|
...n,
|
||||||
|
selected: selectedNode ? selectedNode.id === n.id : false,
|
||||||
|
}));
|
||||||
|
updateNodes(selected);
|
||||||
|
updateEdges(laidOut.edges);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import {Box, Paper} from "@mui/material";
|
import {Box, Paper} from "@mui/material";
|
||||||
import useStore from "./model/store.ts";
|
import useStore from "./model/store.ts";
|
||||||
import {
|
import {
|
||||||
getMRT_RowSelectionHandler,
|
|
||||||
MaterialReactTable,
|
MaterialReactTable,
|
||||||
type MRT_ColumnDef,
|
type MRT_ColumnDef,
|
||||||
MRT_RowSelectionState,
|
MRT_RowSelectionState,
|
||||||
@ -60,6 +59,12 @@ const TabularView = () => {
|
|||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
muiToolbarAlertBannerProps: {
|
||||||
|
sx: {
|
||||||
|
color: "#241775",
|
||||||
|
backgroundColor: "#f5fde7",
|
||||||
|
}
|
||||||
|
},
|
||||||
positionToolbarAlertBanner: "bottom",
|
positionToolbarAlertBanner: "bottom",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -11,9 +11,6 @@ import {
|
|||||||
useOnViewportChange,
|
useOnViewportChange,
|
||||||
Viewport
|
Viewport
|
||||||
} from "@xyflow/react";
|
} from "@xyflow/react";
|
||||||
import {VisualOverview} from "./model/visualizer.ts";
|
|
||||||
import {useEffect} from "react";
|
|
||||||
import {stratify, tree} from "d3-hierarchy";
|
|
||||||
import ShareNode from "./ShareNode.tsx";
|
import ShareNode from "./ShareNode.tsx";
|
||||||
import EnvironmentNode from "./EnvironmentNode.tsx";
|
import EnvironmentNode from "./EnvironmentNode.tsx";
|
||||||
import AccountNode from "./AccountNode.tsx";
|
import AccountNode from "./AccountNode.tsx";
|
||||||
@ -29,15 +26,12 @@ const nodeTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const Visualizer = () => {
|
const Visualizer = () => {
|
||||||
const overview = useStore((state) => state.overview);
|
|
||||||
const selectedNode = useStore((state) => state.selectedNode);
|
|
||||||
const updateSelectedNode = useStore((state) => state.updateSelectedNode);
|
const updateSelectedNode = useStore((state) => state.updateSelectedNode);
|
||||||
const viewport = useStore((state) => state.viewport);
|
const viewport = useStore((state) => state.viewport);
|
||||||
const updateViewport = useStore((state) => state.updateViewport);
|
const updateViewport = useStore((state) => state.updateViewport);
|
||||||
const nodes = useStore((state) => state.nodes);
|
const nodes = useStore((state) => state.nodes);
|
||||||
const updateNodes = useStore((state) => state.updateNodes);
|
const updateNodes = useStore((state) => state.updateNodes);
|
||||||
const edges = useStore((state) => state.edges);
|
const edges = useStore((state) => state.edges);
|
||||||
const updateEdges = useStore((state) => state.updateEdges);
|
|
||||||
|
|
||||||
const onNodesChange = (changes) => {
|
const onNodesChange = (changes) => {
|
||||||
updateNodes(applyNodeChanges(changes, nodes));
|
updateNodes(applyNodeChanges(changes, nodes));
|
||||||
@ -57,27 +51,6 @@ const Visualizer = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const layout = (nodes, edges): VisualOverview => {
|
|
||||||
if(!nodes) {
|
|
||||||
return { nodes: [], edges: [] };
|
|
||||||
}
|
|
||||||
let g = tree();
|
|
||||||
if(nodes.length === 0) return { nodes, edges };
|
|
||||||
const width = 100;
|
|
||||||
const height = 75;
|
|
||||||
const hierarchy = stratify()
|
|
||||||
.id((node) => node.id)
|
|
||||||
.parentId((node) => edges.find((edge) => edge.target === node.id)?.source);
|
|
||||||
const root = hierarchy(nodes);
|
|
||||||
const layout = g.nodeSize([width * 2, height * 2])(root);
|
|
||||||
return {
|
|
||||||
nodes: layout
|
|
||||||
.descendants()
|
|
||||||
.map((node) => ({...node.data, position: {x: node.x, y: node.y}})),
|
|
||||||
edges,
|
|
||||||
} as VisualOverview
|
|
||||||
}
|
|
||||||
|
|
||||||
const nodeColor = (node) => {
|
const nodeColor = (node) => {
|
||||||
if(node.selected) {
|
if(node.selected) {
|
||||||
return "#9bf316";
|
return "#9bf316";
|
||||||
@ -85,18 +58,6 @@ const Visualizer = () => {
|
|||||||
return "#241775";
|
return "#241775";
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if(overview) {
|
|
||||||
let laidOut = layout(overview.nodes, overview.edges);
|
|
||||||
let selected = laidOut.nodes.map((n) => ({
|
|
||||||
...n,
|
|
||||||
selected: selectedNode ? selectedNode.id === n.id : false,
|
|
||||||
}));
|
|
||||||
updateNodes(selected);
|
|
||||||
updateEdges(laidOut.edges);
|
|
||||||
}
|
|
||||||
}, [overview]);
|
|
||||||
|
|
||||||
let fitView = false;
|
let fitView = false;
|
||||||
if(viewport.x === 0 && viewport.y === 0 && viewport.zoom === 1) {
|
if(viewport.x === 0 && viewport.y === 0 && viewport.zoom === 1) {
|
||||||
fitView = true;
|
fitView = true;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {Overview} from "../api";
|
import {Overview} from "../api";
|
||||||
import {Edge, Node} from "@xyflow/react";
|
import {Edge, Node} from "@xyflow/react";
|
||||||
import {User} from "./user.ts";
|
import {User} from "./user.ts";
|
||||||
|
import {stratify, tree} from "d3-hierarchy";
|
||||||
|
|
||||||
export class VisualOverview {
|
export class VisualOverview {
|
||||||
nodes: Node[];
|
nodes: Node[];
|
||||||
@ -150,3 +151,24 @@ export const nodesEqual = (a: Node[], b: Node[]) => {
|
|||||||
if(a.length !== b.length) return false;
|
if(a.length !== b.length) return false;
|
||||||
return a.every((e, i) => e.id === b[i].id && e.data.limited === b[i].data.limited && e.data.label === b[i].data.label);
|
return a.every((e, i) => e.id === b[i].id && e.data.limited === b[i].data.limited && e.data.label === b[i].data.label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const layout = (nodes, edges): VisualOverview => {
|
||||||
|
if(!nodes) {
|
||||||
|
return { nodes: [], edges: [] };
|
||||||
|
}
|
||||||
|
let g = tree();
|
||||||
|
if(nodes.length === 0) return { nodes, edges };
|
||||||
|
const width = 100;
|
||||||
|
const height = 75;
|
||||||
|
const hierarchy = stratify()
|
||||||
|
.id((node) => node.id)
|
||||||
|
.parentId((node) => edges.find((edge) => edge.target === node.id)?.source);
|
||||||
|
const root = hierarchy(nodes);
|
||||||
|
const layout = g.nodeSize([width * 2, height * 2])(root);
|
||||||
|
return {
|
||||||
|
nodes: layout
|
||||||
|
.descendants()
|
||||||
|
.map((node) => ({...node.data, position: {x: node.x, y: node.y}})),
|
||||||
|
edges,
|
||||||
|
} as VisualOverview
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user