Add groups support #146
| @@ -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<TreatmentResult> { | ||||
|     return ( | ||||
|       await APIClient.exec({ | ||||
|         method: "GET", | ||||
|         uri: `/group/${g.id}/vm/start` + (vm ? `?vm_id=${vm.uuid}` : ""), | ||||
|       }) | ||||
|     ).data; | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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} | ||||
|       /> | ||||
|     </Toolbar> | ||||
|   ); | ||||
| @@ -28,7 +33,7 @@ export function GroupVMAction(p: { | ||||
| function GroupVMButton(p: { | ||||
|   enabled: boolean; | ||||
|   icon: React.ReactElement; | ||||
|   action: (group: VMGroup, vm?: VMGroup) => Promise<void>; | ||||
|   action: (group: VMGroup, vm?: VMInfo) => Promise<TreatmentResult>; | ||||
|   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 ( | ||||
|     <Tooltip | ||||
|       content={`${p.tooltip} ${ | ||||
|         p.vm ? `the VM ${p.vm.name}` : `all the VM of the group ${p.group.id}` | ||||
|       }`} | ||||
|       content={`${p.tooltip} ${target}`} | ||||
|       relationship="description" | ||||
|       withArrow | ||||
|     > | ||||
|       <Button | ||||
|         icon={p.icon} | ||||
|         onClick={process} | ||||
|         icon={running ? <Spinner size="tiny" /> : p.icon} | ||||
|         onClick={allowed ? perform : undefined} | ||||
|         disabled={!allowed} | ||||
|         appearance="subtle" | ||||
|       /> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user