import { mdiHarddiskPlus } from "@mdi/js"; import Icon from "@mdi/react"; import CheckCircleIcon from "@mui/icons-material/CheckCircle"; import DeleteIcon from "@mui/icons-material/Delete"; import { Button, IconButton, Paper, Tooltip } from "@mui/material"; import React from "react"; import { DiskImage } from "../../api/DiskImageApi"; import { ServerApi } from "../../api/ServerApi"; import { VMFileDisk, VMInfo, VMState } from "../../api/VMApi"; import { ConvertDiskImageDialog } from "../../dialogs/ConvertDiskImageDialog"; import { useConfirm } from "../../hooks/providers/ConfirmDialogProvider"; import { VMDiskFileWidget } from "../vms/VMDiskFileWidget"; import { CheckboxInput } from "./CheckboxInput"; import { DiskBusSelect } from "./DiskBusSelect"; import { DiskImageSelect } from "./DiskImageSelect"; import { SelectInput } from "./SelectInput"; import { TextInput } from "./TextInput"; export function VMDisksList(p: { vm: VMInfo; state?: VMState; onChange?: () => void; editable: boolean; diskImagesList: DiskImage[]; }): React.ReactElement { const [currBackupRequest, setCurrBackupRequest] = React.useState< VMFileDisk | undefined >(); const addNewDisk = () => { p.vm.file_disks.push({ format: "QCow2", size: 10000 * 1000 * 1000, bus: "Virtio", delete: false, name: `disk${p.vm.file_disks.length}`, new: true, }); p.onChange?.(); }; const handleBackupRequest = (disk: VMFileDisk) => { setCurrBackupRequest(disk); }; const handleFinishBackup = () => { setCurrBackupRequest(undefined); }; return ( <> {/* disks list */} {p.vm.file_disks.map((d, num) => ( { p.vm.file_disks.splice(num, 1); p.onChange?.(); }} onRequestBackup={handleBackupRequest} diskImagesList={p.diskImagesList} /> ))} {p.editable && } {/* Disk backup */} {currBackupRequest && ( )} ); } function DiskInfo(p: { editable: boolean; canBackup: boolean; disk: VMFileDisk; onChange?: () => void; removeFromList: () => void; onRequestBackup: (disk: VMFileDisk) => void; diskImagesList: DiskImage[]; }): React.ReactElement { const confirm = useConfirm(); const deleteDisk = async () => { if (p.disk.deleteType) { p.disk.deleteType = undefined; p.onChange?.(); return; } const keepFile = await confirm( `You asked to delete the disk ${p.disk.name}. Do you want to keep the block file or not ? `, "Delete disk", "Keep the file", "Delete the file" ); if (!(await confirm("Do you really want to delete this disk?"))) return; p.disk.deleteType = keepFile ? "keepfile" : "deletefile"; p.onChange?.(); }; if (!p.editable || !p.disk.new) return ( {p.editable && ( {p.disk.deleteType ? ( ) : ( )} )} {p.canBackup && ( { p.onRequestBackup(p.disk); }} > )} } /> ); return (
/^[a-zA-Z0-9]+$/.test(v)} value={p.disk.name} onValueChange={(v) => { p.disk.name = v ?? ""; p.onChange?.(); }} />
{ p.disk.format = v as any; if (p.disk.format === "Raw") p.disk.is_sparse = true; p.onChange?.(); }} /> {/* Bus selection */} { p.disk.bus = v; p.onChange?.(); }} /> {/* Raw disk: choose sparse mode */} {p.disk.format === "Raw" && ( { if (p.disk.format === "Raw") p.disk.is_sparse = v; p.onChange?.(); }} /> )} { p.disk.size = Number(v ?? "0") * 1000 * 1000 * 1000; p.onChange?.(); }} type="number" disabled={!!p.disk.from_image} /> { p.disk.from_image = v; p.onChange?.(); }} />
); }