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.
129 lines
3.5 KiB
129 lines
3.5 KiB
1 year ago
|
import { Box } from '@mui/material';
|
||
|
import { FC, useMemo } from 'react';
|
||
|
|
||
|
import api from '../lib/api';
|
||
|
import ButtonWithMenu from './ButtonWithMenu';
|
||
|
import { MAP_TO_COLOUR } from './ContainedButton';
|
||
|
import handleAPIError from '../lib/handleAPIError';
|
||
|
import { BodyText } from './Text';
|
||
|
import useConfirmDialog from '../hooks/useConfirmDialog';
|
||
|
|
||
|
const ServerMenu: FC<ServerMenuProps> = (props) => {
|
||
|
const { serverName, serverState, serverUuid } = props;
|
||
|
|
||
|
const {
|
||
|
confirmDialog,
|
||
|
setConfirmDialogOpen,
|
||
|
setConfirmDialogProps,
|
||
|
finishConfirm,
|
||
|
} = useConfirmDialog();
|
||
|
|
||
|
const powerOptions = useMemo<MapToServerPowerOption>(
|
||
|
() => ({
|
||
|
'force-off': {
|
||
|
colour: 'red',
|
||
|
description: (
|
||
|
<>
|
||
|
This is equal to pulling the power cord, which may cause data loss
|
||
|
or system corruption.
|
||
|
</>
|
||
|
),
|
||
|
label: 'Force off',
|
||
|
path: `/command/stop-server/${serverUuid}?force=1`,
|
||
|
},
|
||
|
'power-off': {
|
||
|
description: (
|
||
|
<>
|
||
|
This is equal to pushing the power button. If the server
|
||
|
doesn't respond to the corresponding signals, you may have to
|
||
|
manually shut it down.
|
||
|
</>
|
||
|
),
|
||
|
label: 'Power off',
|
||
|
path: `/command/stop-server/${serverUuid}`,
|
||
|
},
|
||
|
'power-on': {
|
||
|
description: <>This is equal to pushing the power button.</>,
|
||
|
label: 'Power on',
|
||
|
path: `/command/start-server/${serverUuid}`,
|
||
|
},
|
||
|
}),
|
||
|
[serverUuid],
|
||
|
);
|
||
|
|
||
|
return (
|
||
|
<Box>
|
||
|
<ButtonWithMenu
|
||
|
getItemDisabled={(key) => {
|
||
|
const optionOn = key.includes('on');
|
||
|
const serverRunning = serverState === 'running';
|
||
|
|
||
|
return serverRunning === optionOn;
|
||
|
}}
|
||
|
items={powerOptions}
|
||
|
onItemClick={(key, value) => {
|
||
|
const { colour, description, label, path } = value;
|
||
|
|
||
|
const op = label.toLocaleLowerCase();
|
||
|
|
||
|
setConfirmDialogProps({
|
||
|
actionProceedText: label,
|
||
|
content: <BodyText>{description}</BodyText>,
|
||
|
onProceedAppend: () => {
|
||
|
setConfirmDialogProps((previous) => ({
|
||
|
...previous,
|
||
|
loading: true,
|
||
|
}));
|
||
|
|
||
|
api
|
||
|
.put(path)
|
||
|
.then(() => {
|
||
|
finishConfirm('Success', {
|
||
|
children: (
|
||
|
<>
|
||
|
Successfully registered {op} job on {serverName}.
|
||
|
</>
|
||
|
),
|
||
|
});
|
||
|
})
|
||
|
.catch((error) => {
|
||
|
const emsg = handleAPIError(error);
|
||
|
|
||
|
emsg.children = (
|
||
|
<>
|
||
|
Failed to register {op} job on {serverName}; CAUSE:{' '}
|
||
|
{emsg.children}.
|
||
|
</>
|
||
|
);
|
||
|
|
||
|
finishConfirm('Error', emsg);
|
||
|
});
|
||
|
},
|
||
|
proceedColour: colour,
|
||
|
titleText: `${label} server ${serverName}?`,
|
||
|
});
|
||
|
setConfirmDialogOpen(true);
|
||
|
}}
|
||
|
renderItem={(key, value) => {
|
||
|
const { colour, label } = value;
|
||
|
|
||
|
let ccode: string | undefined;
|
||
|
|
||
|
if (colour) {
|
||
|
ccode = MAP_TO_COLOUR[colour];
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
<BodyText inheritColour color={ccode}>
|
||
|
{label}
|
||
|
</BodyText>
|
||
|
);
|
||
|
}}
|
||
|
/>
|
||
|
{confirmDialog}
|
||
|
</Box>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
export default ServerMenu;
|