From 5a568d72dbf50ad0201bfea07fdd14902f975a6a Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Mon, 16 Dec 2024 14:58:07 -0500 Subject: [PATCH] initial full port of the merge algorithm (#803) --- ui100/src/ApiConsole.tsx | 9 +++------ ui100/src/Visualizer.tsx | 12 ++++++------ ui100/src/model/visualizer.ts | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 12 deletions(-) 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 = [