import { Button, Grid, Paper, Typography } from "@mui/material"; import React, { PropsWithChildren } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { validate as validateUUID } from "uuid"; import { ServerApi } from "../api/ServerApi"; import { VMApi, VMInfo } from "../api/VMApi"; import { useAlert } from "../hooks/providers/AlertDialogProvider"; import { useSnackbar } from "../hooks/providers/SnackbarProvider"; import { AsyncWidget } from "../widgets/AsyncWidget"; import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer"; import { CheckboxInput } from "../widgets/forms/CheckboxInput"; import { SelectInput } from "../widgets/forms/SelectInput"; import { TextInput } from "../widgets/forms/TextInput"; export function CreateVMRoute(): React.ReactElement { const snackbar = useSnackbar(); const navigate = useNavigate(); const [vm] = React.useState(VMInfo.NewEmpty); const create = async (v: VMInfo) => { try { const res = await VMApi.Create(v); snackbar("The virtual machine was successfully created!"); v.uuid = res.uuid; navigate(v.ViewURL); } catch (e) { console.error(e); alert("Failed to create VM!"); } }; return ( navigate("/vms")} /> ); } export function EditVMRoute(): React.ReactElement { const navigate = useNavigate(); const alert = useAlert(); const snackbar = useSnackbar(); const { uuid } = useParams(); const [vm, setVM] = React.useState(undefined); const load = async () => { const vm = await VMApi.GetSingle(uuid!); setVM(vm); const state = await VMApi.GetState(vm); if (state !== "Shutdown" && state !== "Shutoff") { await alert("The Virtual machine is running, you cannot edit it!"); navigate(vm.ViewURL); } }; const save = async (v: VMInfo) => { try { await VMApi.UpdateSingle(v); snackbar("The virtual machine was successfully updated!"); navigate(v.ViewURL); } catch (e) { console.error(e); alert("Failed to update VM info!"); } }; return ( ( { navigate(vm!.ViewURL); }} onSave={save} /> )} /> ); } function EditVMInner(p: { vm: VMInfo; isCreating: boolean; onCancel: () => void; onSave: (vm: VMInfo) => Promise; }): React.ReactElement { const [changed, setChanged] = React.useState(false); const [, updateState] = React.useState(); const forceUpdate = React.useCallback(() => updateState({}), []); const valueChanged = () => { setChanged(true); forceUpdate(); }; return ( {changed && ( )} } > {/* Metadata section */} { p.vm.name = v ?? ""; valueChanged(); }} size={ServerApi.Config.constraints.name_size} /> { p.vm.genid = v; valueChanged(); }} checkValue={(v) => validateUUID(v)} /> { p.vm.title = v; valueChanged(); }} size={ServerApi.Config.constraints.title_size} /> { p.vm.description = v; valueChanged(); }} multiline={true} /> {/* General section */} { p.vm.architecture = v! as any; valueChanged(); }} value={p.vm.architecture} options={[ { label: "i686", value: "i686" }, { label: "x86_64", value: "x86_64" }, ]} /> { p.vm.boot_type = v! as any; valueChanged(); }} value={p.vm.boot_type} options={[ { label: "UEFI with Secure Boot", value: "UEFISecureBoot" }, { label: "UEFI", value: "UEFI" }, ]} /> { p.vm.memory = Number(v ?? "0"); valueChanged(); }} checkValue={(v) => Number(v) > ServerApi.Config.constraints.memory_size.min && Number(v) < ServerApi.Config.constraints.memory_size.max } /> { p.vm.vnc_access = v; valueChanged(); }} /> ); } function EditSection( p: { title: string } & PropsWithChildren ): React.ReactElement { return ( {p.title} {p.children} ); }