Files
zrok/ui100/src/ApiConsole.tsx
2024-12-19 13:51:00 -05:00

128 lines
3.9 KiB
TypeScript

import {useEffect, useRef, useState} from "react";
import {Configuration, MetadataApi} from "./api";
import {mergeVisualOverview, nodesEqual, VisualOverview} from "./model/visualizer.ts";
import {Grid2} from "@mui/material";
import NavBar from "./NavBar.tsx";
import {User} from "./model/user.ts";
import Visualizer from "./Visualizer.tsx";
import {Node} from "@xyflow/react";
import AccountPanel from "./AccountPanel.tsx";
import EnvironmentPanel from "./EnvironmentPanel.tsx";
import SharePanel from "./SharePanel.tsx";
import AccessPanel from "./AccessPanel.tsx";
import useStore from "./model/store.ts";
interface ApiConsoleProps {
user: User;
logout: () => void;
}
const ApiConsole = ({ user, logout }: ApiConsoleProps) => {
const overview = useStore((state) => state.overview);
const updateOverview = useStore((state) => state.updateOverview);
const oldVov = useRef<VisualOverview>(overview);
const [selectedNode, setSelectedNode] = useState(null as Node);
const [sidePanel, setSidePanel] = useState(<></>);
const updateEnvironments = useStore((state) => state.updateEnvironments);
const retrieveOverview = () => {
let cfg = new Configuration({
headers: {
"X-TOKEN": user.token
}
});
let api = new MetadataApi(cfg);
api.overview()
.then(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);
updateOverview(newVov);
oldVov.current = newVov;
}
})
.catch(e => {
console.log(e);
});
}
useEffect(() => {
retrieveOverview();
let mounted = true;
let interval = setInterval(() => {
if(mounted) {
retrieveOverview();
}
}, 1000);
return () => {
mounted = false;
clearInterval(interval);
}
}, []);
const retrieveEnvironmentDetail = () => {
let cfg = new Configuration({
headers: {
"X-TOKEN": user.token
}
});
let metadata = new MetadataApi(cfg);
metadata.getAccountDetail()
.then(d => {
updateEnvironments(d);
})
.catch(e => {
console.log("environmentDetail", e);
});
}
useEffect(() => {
retrieveEnvironmentDetail();
let interval = setInterval(() => {
retrieveEnvironmentDetail();
}, 5000);
return () => {
clearInterval(interval);
}
}, []);
useEffect(() => {
if(selectedNode) {
switch(selectedNode.type) {
case "account":
setSidePanel(<AccountPanel account={selectedNode} user={user} />);
break;
case "environment":
setSidePanel(<EnvironmentPanel environment={selectedNode} />);
break;
case "share":
setSidePanel(<SharePanel share={selectedNode} />);
break;
case "access":
setSidePanel(<AccessPanel access={selectedNode} />);
break;
}
} else {
setSidePanel(<></>);
}
}, [selectedNode]);
return (
<div>
<NavBar logout={logout} />
<Grid2 container spacing={2} columns={{ xs: 4, sm: 10, md: 12 }}>
<Grid2 size="grow">
<Visualizer vov={overview} onSelectionChanged={setSelectedNode} />
</Grid2>
<Grid2 size={4}>
{sidePanel}
</Grid2>
</Grid2>
</div>
);
}
export default ApiConsole;