finally, deltas (#803)

This commit is contained in:
Michael Quigley 2024-12-17 12:49:33 -05:00
parent 5a568d72db
commit e17b4bdd65
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
2 changed files with 53 additions and 19 deletions

View File

@ -1,6 +1,12 @@
import {useEffect, useState} from "react"; import {useEffect, useRef, useState} from "react";
import {Configuration, MetadataApi} from "./api"; import {Configuration, MetadataApi, Overview} from "./api";
import {buildVisualOverview, mergeVisualOverview, VisualOverview, visualOverviewsEqual} from "./model/visualizer.ts"; import {
buildVisualOverview,
mergeVisualOverview,
nodesEqual,
VisualOverview,
visualOverviewsEqual
} from "./model/visualizer.ts";
import {Box} from "@mui/material"; import {Box} from "@mui/material";
import NavBar from "./NavBar.tsx"; import NavBar from "./NavBar.tsx";
import {User} from "./model/user.ts"; import {User} from "./model/user.ts";
@ -14,6 +20,7 @@ interface ApiConsoleProps {
const ApiConsole = ({ user, logout }: ApiConsoleProps) => { const ApiConsole = ({ user, logout }: ApiConsoleProps) => {
const [version, setVersion] = useState("no version set"); const [version, setVersion] = useState("no version set");
const [overview, setOverview] = useState(new VisualOverview()); const [overview, setOverview] = useState(new VisualOverview());
const oldVov = useRef<VisualOverview>(overview);
useEffect(() => { useEffect(() => {
let api = new MetadataApi(); let api = new MetadataApi();
@ -26,8 +33,7 @@ const ApiConsole = ({ user, logout }: ApiConsoleProps) => {
}); });
}, []); }, []);
useEffect(() => { const update = () => {
let interval = setInterval(() => {
let cfg = new Configuration({ let cfg = new Configuration({
headers: { headers: {
"X-TOKEN": user.token "X-TOKEN": user.token
@ -36,13 +42,28 @@ const ApiConsole = ({ user, logout }: ApiConsoleProps) => {
let api = new MetadataApi(cfg); let api = new MetadataApi(cfg);
api.overview() api.overview()
.then(d => { .then(d => {
setOverview(mergeVisualOverview(overview, user, false, d)); let newVov = mergeVisualOverview(oldVov.current, user, d.accountLimited!, d);
if(!nodesEqual(oldVov.current.nodes, newVov.nodes)) {
console.log("refreshed vov", oldVov.current.nodes, newVov.nodes);
setOverview(newVov);
oldVov.current = newVov;
}
}) })
.catch(e => { .catch(e => {
console.log(e); console.log(e);
}); });
}
useEffect(() => {
update();
let mounted = true;
let interval = setInterval(() => {
if(mounted) {
update();
}
}, 1000); }, 1000);
return () => { return () => {
mounted = false;
clearInterval(interval); clearInterval(interval);
} }
}, []); }, []);

View File

@ -44,6 +44,7 @@ export const mergeVisualOverview = (oldVov: VisualOverview, u: User, limited: bo
target: envNode.id! target: envNode.id!
}); });
if(env.shares) { if(env.shares) {
envNode.data.empty = false;
env.shares.forEach(shr => { env.shares.forEach(shr => {
let shrLabel = shr.token!; let shrLabel = shr.token!;
if(shr.backendProxyEndpoint !== "") { if(shr.backendProxyEndpoint !== "") {
@ -71,6 +72,7 @@ export const mergeVisualOverview = (oldVov: VisualOverview, u: User, limited: bo
}); });
} }
if(env.frontends) { if(env.frontends) {
envNode.data.empty = false;
env.frontends.forEach(fe => { env.frontends.forEach(fe => {
let feNode = { let feNode = {
id: fe.token!, id: fe.token!,
@ -111,9 +113,17 @@ export const mergeVisualOverview = (oldVov: VisualOverview, u: User, limited: bo
return oldVov; 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)); // preserve nodes that exist in the new overview and remove those that do not.
let outEdges = oldVov.edges.filter(oldEdge => newVov.edges.find(newEdge => newEdge.target === oldEdge.target && newEdge.source === oldEdge.source)); let outNodes = [];
if(oldVov.nodes) {
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 = [];
if(oldVov.edges) {
outEdges = oldVov.edges.filter(oldEdge => newVov.edges.find(newEdge => newEdge.target === oldEdge.target && newEdge.source === oldEdge.source));
}
// and then do the opposite; add any nodes that are in the new overview, but missing from the old overview.
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))); 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))); outEdges.push(...newVov.edges.filter(newEdge => !outEdges.find(oldEdge => oldEdge.target === newEdge.target && oldEdge.source === newEdge.source)));
@ -134,7 +144,10 @@ const sortNodes = (nodes) => {
}); });
} }
const nodesEqual = (a, b) => { export const nodesEqual = (a: Node[], b: Node[]) => {
if(!a && !b) return true;
if(a && !b) return false;
if(b && !a) return false;
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);
} }