diff --git a/ui100/src/ApiConsole.tsx b/ui100/src/ApiConsole.tsx
index 3979af47..4a662267 100644
--- a/ui100/src/ApiConsole.tsx
+++ b/ui100/src/ApiConsole.tsx
@@ -1,6 +1,6 @@
import {useEffect, useState} from "react";
import {Configuration, MetadataApi} from "./api";
-import {buildVisualOverview, VisualOverview, visualOverviewsEqual} from "./model/visualizer.ts";
+import {buildVisualOverview, mergeVisualOverview, VisualOverview, visualOverviewsEqual} from "./model/visualizer.ts";
import {Box} from "@mui/material";
import NavBar from "./NavBar.tsx";
import {User} from "./model/user.ts";
@@ -36,10 +36,7 @@ const ApiConsole = ({ user, logout }: ApiConsoleProps) => {
let api = new MetadataApi(cfg);
api.overview()
.then(d => {
- let vo = buildVisualOverview(d);
- if(!visualOverviewsEqual(vo, overview)) {
- setOverview(vo);
- }
+ setOverview(mergeVisualOverview(overview, user, false, d));
})
.catch(e => {
console.log(e);
@@ -54,7 +51,7 @@ const ApiConsole = ({ user, logout }: ApiConsoleProps) => {
-
+
);
diff --git a/ui100/src/Visualizer.tsx b/ui100/src/Visualizer.tsx
index 28a51eba..e4f5333a 100644
--- a/ui100/src/Visualizer.tsx
+++ b/ui100/src/Visualizer.tsx
@@ -10,7 +10,7 @@ import AccountNode from "../AccountNode.tsx";
import AccessNode from "./AccessNode.tsx";
interface VisualizerProps {
- overview: VisualOverview;
+ vov: VisualOverview;
}
const nodeTypes = {
@@ -20,7 +20,7 @@ const nodeTypes = {
share: ShareNode
};
-const Visualizer = ({ overview }: VisualizerProps) => {
+const Visualizer = ({ vov }: VisualizerProps) => {
const [nodes, setNodes, onNodesChange] = useNodesState([]);
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
@@ -46,10 +46,10 @@ const Visualizer = ({ overview }: VisualizerProps) => {
}
useEffect(() => {
- let layouted = layout(overview.nodes, overview.edges);
+ let layouted = layout(vov.nodes, vov.edges);
setNodes(layouted.nodes);
setEdges(layouted.edges);
- }, [overview]);
+ }, [vov]);
return (
{
);
}
-export default ({ overview }: VisualizerProps) => {
+export default ({ vov }: VisualizerProps) => {
return (
-
+
);
diff --git a/ui100/src/model/visualizer.ts b/ui100/src/model/visualizer.ts
index de3693f5..6a4c3fb6 100644
--- a/ui100/src/model/visualizer.ts
+++ b/ui100/src/model/visualizer.ts
@@ -103,10 +103,42 @@ export const mergeVisualOverview = (oldVov: VisualOverview, u: User, limited: bo
}
});
}
+ newVov.nodes = sortNodes(newVov.nodes);
+ if(nodesEqual(oldVov.nodes, newVov.nodes)) {
+ // if the list of nodes is equal, the graph hasn't changed; we can just return the oldGraph and save the
+ // physics headaches in the visualizer.
+ return oldVov;
+ }
+
+ let outNodes = oldVov.nodes.filter(oldNode => newVov.nodes.find(newNode => newNode.id === oldNode.id && newNode.data.limited == oldNode.data.limited && newNode.data.label === oldNode.data.label));
+ let outEdges = oldVov.edges.filter(oldEdge => newVov.edges.find(newEdge => newEdge.target === oldEdge.target && newEdge.source === oldEdge.source));
+
+ outNodes.push(...newVov.nodes.filter(newNode => !outNodes.find(oldNode => oldNode.id === newNode.id && oldNode.data.limited === newNode.data.limited && oldNode.data.label === newNode.data.label)));
+ outEdges.push(...newVov.edges.filter(newEdge => !outEdges.find(oldEdge => oldEdge.target === newEdge.target && oldEdge.source === newEdge.source)));
+
+ newVov.nodes = outNodes;
+ newVov.edges = outEdges;
return newVov;
}
+const sortNodes = (nodes) => {
+ return nodes.sort((a, b) => {
+ if(a.id > b.id) {
+ return 1;
+ }
+ if(a.id < b.id) {
+ return -1;
+ }
+ return 0;
+ });
+}
+
+const nodesEqual = (a, b) => {
+ 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);
+}
+
export const buildVisualOverview = (overview: Overview): VisualOverview => {
let out = new VisualOverview();
out.nodes = [