Local modifications to ClusterLabs/Anvil by Alteeve
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
5.1 KiB

import { Box, styled, Switch } from '@mui/material';
import API_BASE_URL from '../../lib/consts/API_BASE_URL';
import { LARGE_MOBILE_BREAKPOINT } from '../../lib/consts/DEFAULT_THEME';
import HOST_STATUS from '../../lib/consts/NODES';
import { ProgressBar } from '../Bars';
import Decorator, { Colours } from '../Decorator';
import { InnerPanel, InnerPanelHeader } from '../Panels';
import putFetch from '../../lib/fetchers/putFetch';
import { BodyText } from '../Text';
const PREFIX = 'AnvilHost';
const classes = {
state: `${PREFIX}-state`,
bar: `${PREFIX}-bar`,
label: `${PREFIX}-label`,
decoratorBox: `${PREFIX}-decoratorBox`,
};
const StyledBox = styled(Box)(({ theme }) => ({
overflow: 'auto',
height: '28vh',
paddingLeft: '.3em',
paddingRight: '.3em',
[theme.breakpoints.down(LARGE_MOBILE_BREAKPOINT)]: {
height: '100%',
overflow: 'hidden',
},
[`& .${classes.state}`]: {
paddingLeft: '.7em',
paddingRight: '.7em',
},
[`& .${classes.bar}`]: {
paddingLeft: '.7em',
paddingRight: '.7em',
},
[`& .${classes.label}`]: {
paddingTop: '.3em',
},
[`& .${classes.decoratorBox}`]: {
alignSelf: 'stretch',
paddingRight: '.3em',
},
}));
const selectStateMessage = (regex: RegExp, message: string): string => {
const msg = regex.exec(message);
if (msg) {
return HOST_STATUS.get(msg[0]) || 'Error code not recognized';
}
return 'Error code not found';
};
const selectDecorator = (state: string): Colours => {
switch (state) {
case 'online':
return 'ok';
case 'offline':
return 'off';
default:
return 'warning';
}
};
const AnvilHost = ({
hosts,
}: {
hosts: Array<AnvilStatusHost>;
}): JSX.Element => {
const stateRegex = /^[a-zA-Z]/;
const messageRegex = /^(message_[0-9]+)/;
return (
<StyledBox>
{hosts &&
hosts.map(
(host): JSX.Element =>
// Temporary fix: avoid crash when encounter undefined host entry by returning a blank element.
// TODO: figure out why there are undefined host entries.
host ? (
<InnerPanel key={host.host_uuid}>
<InnerPanelHeader>
<Box flexGrow={1}>
<BodyText text={host.host_name} />
</Box>
<Box className={classes.decoratorBox}>
<Decorator colour={selectDecorator(host.state)} />
</Box>
<Box>
<BodyText
text={
host?.state?.replace(stateRegex, (c) =>
c.toUpperCase(),
) || 'Not Available'
}
/>
</Box>
</InnerPanelHeader>
<Box display="flex" className={classes.state}>
<Box className={classes.label}>
<BodyText text="Power: " />
</Box>
<Box flexGrow={1}>
<Switch
checked={host.state === 'online'}
onChange={() =>
putFetch(
`${API_BASE_URL}/command/${
host.state === 'online'
? 'stop-subnode'
: 'start-subnode'
}/${host.host_uuid}`,
{},
)
}
/>
</Box>
<Box className={classes.label}>
<BodyText text="Member: " />
</Box>
<Box>
<Switch
checked={host.state === 'online'}
disabled={!(host.state === 'online')}
onChange={() =>
putFetch(
`${API_BASE_URL}/command/${
host.state === 'online' ? 'leave-an' : 'join-an'
}/${host.host_uuid}`,
{},
)
}
/>
</Box>
</Box>
{host.state !== 'online' && host.state !== 'offline' && (
<>
<Box display="flex" width="100%" className={classes.state}>
<Box>
<BodyText
text={selectStateMessage(
messageRegex,
host.state_message,
)}
/>
</Box>
</Box>
<Box display="flex" width="100%" className={classes.bar}>
<Box flexGrow={1}>
<ProgressBar progressPercentage={host.state_percent} />
</Box>
</Box>
</>
)}
</InnerPanel>
) : (
<></>
),
)}
</StyledBox>
);
};
export default AnvilHost;