From b17da38e529a4bf4e31c4e578de6aefd98cc4485 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Fri, 6 Dec 2024 18:12:42 +0100 Subject: [PATCH] Can start group VM --- remote_frontend/src/api/GroupApi.ts | 19 +++++- remote_frontend/src/widgets/GroupVMAction.tsx | 61 ++++++++++++++++--- 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/remote_frontend/src/api/GroupApi.ts b/remote_frontend/src/api/GroupApi.ts index ec740d1..ef692b8 100644 --- a/remote_frontend/src/api/GroupApi.ts +++ b/remote_frontend/src/api/GroupApi.ts @@ -1,11 +1,16 @@ import { APIClient } from "./ApiClient"; import { VMGroup } from "./ServerApi"; -import { VMState } from "./VMApi"; +import { VMInfo, VMState } from "./VMApi"; export interface GroupVMState { [key: string]: VMState; } +export interface TreatmentResult { + ok: number; + failed: number; +} + export class GroupApi { /** * Get the state of the VMs of a group @@ -15,4 +20,16 @@ export class GroupApi { await APIClient.exec({ method: "GET", uri: `/group/${g.id}/vm/state` }) ).data; } + + /** + * Request to start the VM of a group + */ + static async StartVM(g: VMGroup, vm?: VMInfo): Promise { + return ( + await APIClient.exec({ + method: "GET", + uri: `/group/${g.id}/vm/start` + (vm ? `?vm_id=${vm.uuid}` : ""), + }) + ).data; + } } diff --git a/remote_frontend/src/widgets/GroupVMAction.tsx b/remote_frontend/src/widgets/GroupVMAction.tsx index 7761421..6a86b72 100644 --- a/remote_frontend/src/widgets/GroupVMAction.tsx +++ b/remote_frontend/src/widgets/GroupVMAction.tsx @@ -1,7 +1,12 @@ -import { Button, Toolbar, Tooltip } from "@fluentui/react-components"; +import { Button, Spinner, Toolbar, Tooltip } from "@fluentui/react-components"; import { PlayRegular } from "@fluentui/react-icons"; 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"; export function GroupVMAction(p: { group: VMGroup; @@ -19,7 +24,7 @@ export function GroupVMAction(p: { allowedStates={["Shutdown", "Shutoff", "Crashed"]} currState={p.state} needConfirm={false} - action={async () => {}} + action={GroupApi.StartVM} /> ); @@ -28,7 +33,7 @@ export function GroupVMAction(p: { function GroupVMButton(p: { enabled: boolean; icon: React.ReactElement; - action: (group: VMGroup, vm?: VMGroup) => Promise; + action: (group: VMGroup, vm?: VMInfo) => Promise; tooltip: string; currState?: VMState; allowedStates: VMState[]; @@ -36,24 +41,62 @@ function GroupVMButton(p: { vm?: VMInfo; needConfirm: boolean; }): React.ReactElement { - const process = () => {}; + 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 (