|
|
|
@ -1,10 +1,11 @@ |
|
|
|
|
import { Grid, gridClasses } from '@mui/material'; |
|
|
|
|
import { Grid, gridClasses, typographyClasses } from '@mui/material'; |
|
|
|
|
import { dSizeStr } from 'format-data-size'; |
|
|
|
|
import { FC, useMemo } from 'react'; |
|
|
|
|
import { FC, ReactNode, useMemo } from 'react'; |
|
|
|
|
|
|
|
|
|
import { BLUE, PURPLE, RED } from '../../lib/consts/DEFAULT_THEME'; |
|
|
|
|
import { BLUE, GREY, PURPLE, RED } from '../../lib/consts/DEFAULT_THEME'; |
|
|
|
|
|
|
|
|
|
import { |
|
|
|
|
toAnvilDetail, |
|
|
|
|
toAnvilMemoryCalcable, |
|
|
|
|
toAnvilSharedStorageOverview, |
|
|
|
|
} from '../../lib/api_converters'; |
|
|
|
@ -14,11 +15,31 @@ import StackBar from '../Bars/StackBar'; |
|
|
|
|
import { BodyText, InlineMonoText, MonoText } from '../Text'; |
|
|
|
|
import useFetch from '../../hooks/useFetch'; |
|
|
|
|
|
|
|
|
|
const n100 = BigInt(100); |
|
|
|
|
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<string, string> = { |
|
|
|
|
offline: PURPLE, |
|
|
|
|
online: BLUE, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const AnvilSummary: FC<AnvilSummaryProps> = (props) => { |
|
|
|
|
const { anvilUuid } = props; |
|
|
|
|
|
|
|
|
|
const { data: rAnvil, loading: loadingAnvil } = useFetch<AnvilListItem>( |
|
|
|
|
`/anvil/${anvilUuid}`, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const anvil = useMemo<APIAnvilDetail | undefined>( |
|
|
|
|
() => rAnvil && toAnvilDetail(rAnvil), |
|
|
|
|
[rAnvil], |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const { data: cpu, loading: loadingCpu } = useFetch<AnvilCPU>( |
|
|
|
|
`/anvil/${anvilUuid}/cpu`, |
|
|
|
|
); |
|
|
|
@ -46,8 +67,57 @@ const AnvilSummary: FC<AnvilSummaryProps> = (props) => { |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const loading = useMemo<boolean>( |
|
|
|
|
() => loadingCpu || loadingMemory || loadingStorages, |
|
|
|
|
[loadingCpu, loadingMemory, loadingStorages], |
|
|
|
|
() => |
|
|
|
|
[loadingAnvil, loadingCpu, loadingMemory, loadingStorages].some( |
|
|
|
|
(cond) => cond, |
|
|
|
|
), |
|
|
|
|
[loadingAnvil, loadingCpu, loadingMemory, loadingStorages], |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const anvilSummary = useMemo( |
|
|
|
|
() => |
|
|
|
|
anvil && ( |
|
|
|
|
<MonoText inheritColour color={MAP_TO_ANVIL_STATE_COLOUR[anvil.state]}> |
|
|
|
|
{anvil.state} |
|
|
|
|
</MonoText> |
|
|
|
|
), |
|
|
|
|
[anvil], |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const hostsSummary = useMemo( |
|
|
|
|
() => |
|
|
|
|
anvil && ( |
|
|
|
|
<FlexBox |
|
|
|
|
spacing={0} |
|
|
|
|
sx={{ |
|
|
|
|
[`& > .${typographyClasses.root}:first-child`]: { |
|
|
|
|
marginBottom: '-.6em', |
|
|
|
|
}, |
|
|
|
|
}} |
|
|
|
|
> |
|
|
|
|
{Object.values(anvil.hosts).map<ReactNode>((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 ( |
|
|
|
|
<BodyText key={`anvil-summary-host-${uuid}`} whiteSpace="nowrap"> |
|
|
|
|
{name}{' '} |
|
|
|
|
<InlineMonoText inheritColour color={stateColour}> |
|
|
|
|
{stateValue} |
|
|
|
|
</InlineMonoText> |
|
|
|
|
</BodyText> |
|
|
|
|
); |
|
|
|
|
})} |
|
|
|
|
</FlexBox> |
|
|
|
|
), |
|
|
|
|
[anvil], |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const cpuSummary = useMemo( |
|
|
|
@ -114,11 +184,11 @@ const AnvilSummary: FC<AnvilSummaryProps> = (props) => { |
|
|
|
|
thin |
|
|
|
|
value={{ |
|
|
|
|
reserved: { |
|
|
|
|
value: Number((memory.reserved * n100) / memory.total), |
|
|
|
|
value: Number((memory.reserved * N_100) / memory.total), |
|
|
|
|
}, |
|
|
|
|
allocated: { |
|
|
|
|
value: Number( |
|
|
|
|
((memory.reserved + memory.allocated) * n100) / memory.total, |
|
|
|
|
((memory.reserved + memory.allocated) * N_100) / memory.total, |
|
|
|
|
), |
|
|
|
|
colour: { 0: BLUE, 70: PURPLE, 90: RED }, |
|
|
|
|
}, |
|
|
|
@ -150,7 +220,7 @@ const AnvilSummary: FC<AnvilSummaryProps> = (props) => { |
|
|
|
|
value={{ |
|
|
|
|
allocated: { |
|
|
|
|
value: Number( |
|
|
|
|
((storages.totalSize - storages.totalFree) * n100) / |
|
|
|
|
((storages.totalSize - storages.totalFree) * N_100) / |
|
|
|
|
storages.totalSize, |
|
|
|
|
), |
|
|
|
|
colour: { 0: BLUE, 70: PURPLE, 90: RED }, |
|
|
|
@ -177,6 +247,18 @@ const AnvilSummary: FC<AnvilSummaryProps> = (props) => { |
|
|
|
|
}, |
|
|
|
|
}} |
|
|
|
|
> |
|
|
|
|
<Grid item xs={1}> |
|
|
|
|
<BodyText>Node</BodyText> |
|
|
|
|
</Grid> |
|
|
|
|
<Grid item xs={2}> |
|
|
|
|
{anvilSummary} |
|
|
|
|
</Grid> |
|
|
|
|
<Grid item xs={1}> |
|
|
|
|
<BodyText>Subnodes</BodyText> |
|
|
|
|
</Grid> |
|
|
|
|
<Grid item xs={2}> |
|
|
|
|
{hostsSummary} |
|
|
|
|
</Grid> |
|
|
|
|
<Grid item xs={1}> |
|
|
|
|
<BodyText>CPU</BodyText> |
|
|
|
|
</Grid> |
|
|
|
|