import { Grid, gridClasses, typographyClasses } from '@mui/material'; import { dSizeStr } from 'format-data-size'; import { FC, ReactNode, useMemo } from 'react'; import { BLUE, GREY, PURPLE, RED } from '../../lib/consts/DEFAULT_THEME'; import { toAnvilDetail, toAnvilMemoryCalcable, toAnvilSharedStorageOverview, } from '../../lib/api_converters'; import FlexBox from '../FlexBox'; import Spinner from '../Spinner'; import StackBar from '../Bars/StackBar'; import { BodyText, InlineMonoText, MonoText } from '../Text'; import useFetch from '../../hooks/useFetch'; const N_100 = BigInt(100); const MAP_TO_ANVIL_STATE_COLOUR = { degraded: RED, not_ready: PURPLE, optimal: BLUE, }; const MAP_TO_HOST_STATE_COLOUR: Record = { offline: PURPLE, online: BLUE, }; const AnvilSummary: FC = (props) => { const { anvilUuid } = props; const { data: rAnvil, loading: loadingAnvil } = useFetch( `/anvil/${anvilUuid}`, ); const anvil = useMemo( () => rAnvil && toAnvilDetail(rAnvil), [rAnvil], ); const { data: cpu, loading: loadingCpu } = useFetch( `/anvil/${anvilUuid}/cpu`, ); const cpuSubnodes = useMemo( () => cpu && Object.values(cpu.hosts), [cpu], ); const { data: rMemory, loading: loadingMemory } = useFetch( `/anvil/${anvilUuid}/memory`, ); const memory = useMemo( () => rMemory && toAnvilMemoryCalcable(rMemory), [rMemory], ); const { data: rStorages, loading: loadingStorages } = useFetch(`/anvil/${anvilUuid}/store`); const storages = useMemo( () => rStorages && toAnvilSharedStorageOverview(rStorages), [rStorages], ); const loading = useMemo( () => [loadingAnvil, loadingCpu, loadingMemory, loadingStorages].some( (cond) => cond, ), [loadingAnvil, loadingCpu, loadingMemory, loadingStorages], ); const anvilSummary = useMemo( () => anvil && ( {anvil.state} ), [anvil], ); const hostsSummary = useMemo( () => anvil && ( .${typographyClasses.root}:first-child`]: { marginBottom: '-.6em', }, }} > {Object.values(anvil.hosts).map((host) => { const { name, state, stateProgress, uuid } = host; const stateColour: string = MAP_TO_HOST_STATE_COLOUR[state] ?? GREY; let stateValue: string = state; if (!['offline', 'online'].includes(state)) { stateValue = `${stateProgress}%`; } return ( {name}{' '} {stateValue} ); })} ), [anvil], ); const cpuSummary = useMemo( () => cpu && cpuSubnodes && ( {cpuSubnodes[0].name} {cpuSubnodes[0].vendor} .${gridClasses.item}:nth-child(-n + 2)`]: { marginBottom: '-.6em', }, }} width="calc(0% + 4em)" > CORES {cpu.cores} THREADS {cpu.threads} {cpuSubnodes[1].name} {cpuSubnodes[1].vendor} ), [cpu, cpuSubnodes], ); const memorySummary = useMemo( () => memory && ( FREE {dSizeStr(memory.total - (memory.reserved + memory.allocated), { toUnit: 'ibyte', })} / {dSizeStr(memory.total, { toUnit: 'ibyte' })} ), [memory], ); const storeSummary = useMemo( () => storages && ( FREE {dSizeStr(storages.totalFree, { toUnit: 'ibyte' })} / {dSizeStr(storages.totalSize, { toUnit: 'ibyte' })} ), [storages], ); return loading ? ( ) : ( .${gridClasses.item}:nth-child(odd)`]: { alignItems: 'center', display: 'flex', height: '2.5em', }, }} > Node {anvilSummary} Subnodes {hostsSummary} CPU {cpuSummary} Memory {memorySummary} Storage {storeSummary} ); }; export default AnvilSummary;