Files
VirtWeb/virtweb_frontend/src/widgets/vms/VMStatusWidget.tsx

133 lines
4.0 KiB
TypeScript

import PauseIcon from "@mui/icons-material/Pause";
import PersonalVideoIcon from "@mui/icons-material/PersonalVideo";
import PlayArrowIcon from "@mui/icons-material/PlayArrow";
import PowerSettingsNewIcon from "@mui/icons-material/PowerSettingsNew";
import ReplayIcon from "@mui/icons-material/Replay";
import StopIcon from "@mui/icons-material/Stop";
import { CircularProgress, Typography } from "@mui/material";
import React from "react";
import { useNavigate } from "react-router-dom";
import { VMApi, VMInfo, VMState } from "../../api/VMApi";
import { useSnackbar } from "../../hooks/providers/SnackbarProvider";
import { StateActionButton } from "../StateActionButton";
export function VMStatusWidget(p: {
vm: VMInfo;
onChange?: (s: VMState) => void;
}): React.ReactElement {
const snackbar = useSnackbar();
const navigate = useNavigate();
const [state, setState] = React.useState<undefined | VMState>(undefined);
const refresh = async () => {
try {
const s = await VMApi.GetState(p.vm);
if (s !== state) p.onChange?.(s);
setState(s);
} catch (e) {
console.error(e);
snackbar("Failed to refresh VM status!");
}
};
const changedAction = () => setState(undefined);
React.useEffect(() => {
refresh();
const i = setInterval(() => refresh(), 3000);
return () => clearInterval(i);
});
if (state === undefined)
return (
<>
<CircularProgress size={"1rem"} />
</>
);
return (
<div style={{ display: "inline-flex" }}>
<Typography>{state}</Typography>
{
/* VNC console */ p.vm.vnc_access && (
<StateActionButton
currState={state}
cond={["Running"]}
icon={<PersonalVideoIcon />}
tooltip="Graphical remote control over the VM"
performAction={async () => navigate(p.vm.VNCURL)}
onExecuted={() => {}}
/>
)
}
{/* Start VM */}
<StateActionButton
currState={state}
cond={["Shutdown", "Shutoff", "Crashed"]}
icon={<PlayArrowIcon />}
tooltip="Start the Virtual Machine"
performAction={() => VMApi.StartVM(p.vm)}
onExecuted={changedAction}
/>
{/* Resume VM */}
<StateActionButton
currState={state}
cond={["Paused", "PowerManagementSuspended"]}
icon={<PlayArrowIcon />}
tooltip="Resume the Virtual Machine"
performAction={() => VMApi.ResumeVM(p.vm)}
onExecuted={changedAction}
/>
{/* Suspend VM */}
<StateActionButton
currState={state}
cond={["Running"]}
icon={<PauseIcon />}
tooltip="Suspend the Virtual Machine"
confirmMessage="Do you really want to supsend this VM?"
performAction={() => VMApi.SuspendVM(p.vm)}
onExecuted={changedAction}
/>
{/* Shutdown VM */}
<StateActionButton
currState={state}
cond={["Running"]}
icon={<PowerSettingsNewIcon />}
tooltip="Shutdown the Virtual Machine"
confirmMessage="Do you really want to shutdown this VM?"
performAction={() => VMApi.ShutdownVM(p.vm)}
onExecuted={changedAction}
/>
{/* Kill VM */}
<StateActionButton
currState={state}
cond={["Running", "Paused", "PowerManagementSuspended", "Blocked"]}
icon={<StopIcon />}
tooltip="Kill the Virtual Machine"
confirmMessage="Do you really want to kill this VM? This could lead to data loss / corruption!"
performAction={() => VMApi.KillVM(p.vm)}
onExecuted={changedAction}
/>
{/* Reset VM */}
<StateActionButton
currState={state}
cond={["Running", "Paused", "PowerManagementSuspended", "Blocked"]}
icon={<ReplayIcon />}
tooltip="Reset the Virtual Machine"
confirmMessage="Do you really want to reset this VM?"
performAction={() => VMApi.ResetVM(p.vm)}
onExecuted={changedAction}
/>
</div>
);
}