import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; import VisibilityIcon from "@mui/icons-material/Visibility"; import { Button, IconButton, Paper, Table, TableBody, TableCell, TableContainer, TableFooter, TableHead, TableRow, Tooltip, } from "@mui/material"; import { filesize } from "filesize"; import React from "react"; import { useNavigate } from "react-router-dom"; import { GroupApi } from "../api/GroupApi"; import { VMApi, VMInfo, VMState } from "../api/VMApi"; import { AsyncWidget } from "../widgets/AsyncWidget"; import { RouterLink } from "../widgets/RouterLink"; import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer"; import { VMStatusWidget } from "../widgets/vms/VMStatusWidget"; export function VMListRoute(): React.ReactElement { const [groups, setGroups] = React.useState>(); const [list, setList] = React.useState(); const loadKey = React.useRef(1); const load = async () => { setGroups([undefined, ...(await GroupApi.GetList())]); setList(await VMApi.GetList()); }; const reload = () => { loadKey.current += 1; setList(undefined); }; return ( ( } > )} /> ); } function VMListWidget(p: { groups: Array; list: VMInfo[]; onReload: () => void; }): React.ReactElement { const navigate = useNavigate(); const [hiddenGroups, setHiddenGroups] = React.useState< Set >(new Set()); const [runningVMs, setRunningVMs] = React.useState>(new Set()); const toggleHiddenGroup = (g: string | undefined) => { if (hiddenGroups.has(g)) hiddenGroups.delete(g); else hiddenGroups.add(g); setHiddenGroups(new Set([...hiddenGroups])); }; const updateVMState = (v: VMInfo, s: VMState) => { const running = s !== "Shutoff"; if (runningVMs.has(v.name) === running) { return; } if (running) runningVMs.add(v.name); else runningVMs.delete(v.name); setRunningVMs(new Set([...runningVMs])); }; return ( Name Description Memory vCPU Status Actions {p.groups.map((g, num) => ( toggleHiddenGroup(g)}> {!hiddenGroups?.has(g) ? ( ) : ( )} {g ?? "default"} {!hiddenGroups.has(g) && p.list .filter((row) => row.group === g) .map((row) => ( navigate(row.ViewURL)} > {row.name} {row.description ?? ""} {vmMemoryToHuman(row.memory)} {row.number_vcpu} updateVMState(row, s)} /> ))} ))} {vmMemoryToHuman( p.list .filter((v) => runningVMs.has(v.name)) .reduce((s, v) => s + v.memory, 0) )} {" / "} {vmMemoryToHuman(p.list.reduce((s, v) => s + v.memory, 0))} {p.list .filter((v) => runningVMs.has(v.name)) .reduce((s, v) => s + v.number_vcpu, 0)} {" / "} {p.list.reduce((s, v) => s + v.number_vcpu, 0)}
); } function vmMemoryToHuman(size: number): string { return filesize(size * 1000 * 1000); }