Pierre HUBERT 7d7d9c5437
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Improve icon buttons
2024-12-06 18:39:25 +01:00

178 lines
4.4 KiB
TypeScript

import { Button, Spinner, Toolbar, Tooltip } from "@fluentui/react-components";
import {
ArrowResetRegular,
PauseRegular,
PlayCircleRegular,
PlayFilled,
PowerRegular,
StopRegular,
} from "@fluentui/react-icons";
import React from "react";
import { GroupApi, TreatmentResult } from "../api/GroupApi";
import { VMGroup } from "../api/ServerApi";
import { VMInfo, VMState } from "../api/VMApi";
import { useAlert } from "../hooks/providers/AlertDialogProvider";
import { useConfirm } from "../hooks/providers/ConfirmDialogProvider";
import { useToast } from "../hooks/providers/ToastProvider";
export function GroupVMAction(p: {
group: VMGroup;
state?: VMState;
vm?: VMInfo;
}): React.ReactElement {
return (
<Toolbar>
<GroupVMButton
enabled={p.group.can_start}
icon={<PlayFilled />}
tooltip="Start"
group={p.group}
vm={p.vm}
allowedStates={["Shutdown", "Shutoff", "Crashed"]}
currState={p.state}
needConfirm={false}
action={GroupApi.StartVM}
/>
<GroupVMButton
enabled={p.group.can_suspend}
icon={<PauseRegular />}
tooltip="Suspend"
group={p.group}
vm={p.vm}
allowedStates={["Running"]}
currState={p.state}
needConfirm={true}
action={GroupApi.SuspendVM}
/>
<GroupVMButton
enabled={p.group.can_resume}
icon={<PlayCircleRegular />}
tooltip="Resume"
group={p.group}
vm={p.vm}
allowedStates={["Paused", "PowerManagementSuspended"]}
currState={p.state}
needConfirm={false}
action={GroupApi.ResumeVM}
/>
<GroupVMButton
enabled={p.group.can_shutdown}
icon={<PowerRegular />}
tooltip="Shutdown"
group={p.group}
vm={p.vm}
allowedStates={["Running"]}
currState={p.state}
needConfirm={true}
action={GroupApi.ShutdownVM}
/>
<GroupVMButton
enabled={p.group.can_kill}
icon={<StopRegular />}
tooltip="Kill"
group={p.group}
vm={p.vm}
allowedStates={[
"Running",
"Paused",
"PowerManagementSuspended",
"Blocked",
]}
currState={p.state}
needConfirm={true}
action={GroupApi.KillVM}
/>
<GroupVMButton
enabled={p.group.can_reset}
icon={<ArrowResetRegular />}
tooltip="Reset"
group={p.group}
vm={p.vm}
allowedStates={[
"Running",
"Paused",
"PowerManagementSuspended",
"Blocked",
]}
currState={p.state}
needConfirm={true}
action={GroupApi.ResetVM}
/>
</Toolbar>
);
}
function GroupVMButton(p: {
enabled: boolean;
icon: React.ReactElement;
action: (group: VMGroup, vm?: VMInfo) => Promise<TreatmentResult>;
tooltip: string;
currState?: VMState;
allowedStates: VMState[];
group: VMGroup;
vm?: VMInfo;
needConfirm: boolean;
}): React.ReactElement {
const toast = useToast();
const confirm = useConfirm();
const alert = useAlert();
const [running, setRunning] = React.useState(false);
const target = p.vm
? `the VM ${p.vm.name}`
: `all the VM of the group ${p.group.id}`;
const allowed =
!p.vm || (p.currState && p.allowedStates.includes(p.currState));
const perform = async () => {
if (running || !allowed) return;
try {
if (
(!p.vm || p.needConfirm) &&
!(await confirm(
`Do you want to perform ${p.tooltip} action on ${target}?`,
`Confirmation`,
p.tooltip
))
) {
return;
}
setRunning(true);
const result = await p.action(p.group, p.vm);
toast(
p.tooltip,
`${p.tooltip} action on ${target}: ${result.ok} OK / ${result.failed} Failed`,
"success"
);
} catch (e) {
console.error("Failed to perform group action!", e);
alert(`Failed to perform ${p.tooltip} action on ${target}: ${e}`);
} finally {
setRunning(false);
}
};
if (!p.enabled) return <></>;
return (
<Tooltip
content={`${p.tooltip} ${target}`}
relationship="description"
withArrow
>
<Button
icon={running ? <Spinner size="tiny" /> : p.icon}
onClick={allowed ? perform : undefined}
disabled={!allowed}
appearance="subtle"
/>
</Tooltip>
);
}