diff --git a/remote_frontend/src/api/GroupApi.ts b/remote_frontend/src/api/GroupApi.ts index ef692b8..0fd84e9 100644 --- a/remote_frontend/src/api/GroupApi.ts +++ b/remote_frontend/src/api/GroupApi.ts @@ -32,4 +32,76 @@ export class GroupApi { }) ).data; } + + /** + * Request to suspend the VM of a group + */ + static async SuspendVM(g: VMGroup, vm?: VMInfo): Promise { + return ( + await APIClient.exec({ + method: "GET", + uri: `/group/${g.id}/vm/suspend` + (vm ? `?vm_id=${vm.uuid}` : ""), + }) + ).data; + } + + /** + * Request to resume the VM of a group + */ + static async ResumeVM(g: VMGroup, vm?: VMInfo): Promise { + return ( + await APIClient.exec({ + method: "GET", + uri: `/group/${g.id}/vm/resume` + (vm ? `?vm_id=${vm.uuid}` : ""), + }) + ).data; + } + + /** + * Request to shutdown the VM of a group + */ + static async ShutdownVM(g: VMGroup, vm?: VMInfo): Promise { + return ( + await APIClient.exec({ + method: "GET", + uri: `/group/${g.id}/vm/shutdown` + (vm ? `?vm_id=${vm.uuid}` : ""), + }) + ).data; + } + + /** + * Request to kill the VM of a group + */ + static async KillVM(g: VMGroup, vm?: VMInfo): Promise { + return ( + await APIClient.exec({ + method: "GET", + uri: `/group/${g.id}/vm/kill` + (vm ? `?vm_id=${vm.uuid}` : ""), + }) + ).data; + } + + /** + * Request to reset the VM of a group + */ + static async ResetVM(g: VMGroup, vm?: VMInfo): Promise { + return ( + await APIClient.exec({ + method: "GET", + uri: `/group/${g.id}/vm/reset` + (vm ? `?vm_id=${vm.uuid}` : ""), + }) + ).data; + } + + /** + * Request a screenshot of the VM of group + */ + static async ScreenshotVM(g: VMGroup, vm?: VMInfo): Promise { + return ( + await APIClient.exec({ + method: "GET", + uri: `/group/${g.id}/vm/screenshot` + (vm ? `?vm_id=${vm.uuid}` : ""), + }) + ).data; + } } diff --git a/remote_frontend/src/widgets/GroupVMAction.tsx b/remote_frontend/src/widgets/GroupVMAction.tsx index 6a86b72..eb508a9 100644 --- a/remote_frontend/src/widgets/GroupVMAction.tsx +++ b/remote_frontend/src/widgets/GroupVMAction.tsx @@ -1,12 +1,18 @@ import { Button, Spinner, Toolbar, Tooltip } from "@fluentui/react-components"; -import { PlayRegular } from "@fluentui/react-icons"; +import { + ArrowResetRegular, + PauseRegular, + PlayRegular, + 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 { GroupApi, TreatmentResult } from "../api/GroupApi"; -import React from "react"; -import { useToast } from "../hooks/providers/ToastProvider"; -import { useConfirm } from "../hooks/providers/ConfirmDialogProvider"; import { useAlert } from "../hooks/providers/AlertDialogProvider"; +import { useConfirm } from "../hooks/providers/ConfirmDialogProvider"; +import { useToast } from "../hooks/providers/ToastProvider"; export function GroupVMAction(p: { group: VMGroup; @@ -26,6 +32,71 @@ export function GroupVMAction(p: { needConfirm={false} action={GroupApi.StartVM} /> + } + tooltip="Resume" + group={p.group} + vm={p.vm} + allowedStates={["Paused", "PowerManagementSuspended"]} + currState={p.state} + needConfirm={false} + action={GroupApi.ResumeVM} + /> + } + tooltip="Suspend" + group={p.group} + vm={p.vm} + allowedStates={["Running"]} + currState={p.state} + needConfirm={true} + action={GroupApi.SuspendVM} + /> + } + tooltip="Shutdown" + group={p.group} + vm={p.vm} + allowedStates={["Running"]} + currState={p.state} + needConfirm={true} + action={GroupApi.ShutdownVM} + /> + } + tooltip="Kill" + group={p.group} + vm={p.vm} + allowedStates={[ + "Running", + "Paused", + "PowerManagementSuspended", + "Blocked", + ]} + currState={p.state} + needConfirm={true} + action={GroupApi.KillVM} + /> + } + tooltip="Reset" + group={p.group} + vm={p.vm} + allowedStates={[ + "Running", + "Paused", + "PowerManagementSuspended", + "Blocked", + ]} + currState={p.state} + needConfirm={true} + action={GroupApi.ResetVM} + /> ); }