This commit is contained in:
		@@ -36,6 +36,7 @@ export interface BaseFileVMDisk {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // application attributes
 | 
					  // application attributes
 | 
				
			||||||
  new?: boolean;
 | 
					  new?: boolean;
 | 
				
			||||||
 | 
					  originalSize?: number;
 | 
				
			||||||
  deleteType?: "keepfile" | "deletefile";
 | 
					  deleteType?: "keepfile" | "deletefile";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								virtweb_frontend/src/widgets/forms/DiskSizeInput.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								virtweb_frontend/src/widgets/forms/DiskSizeInput.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					import { ServerApi } from "../../api/ServerApi";
 | 
				
			||||||
 | 
					import { TextInput } from "./TextInput";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function DiskSizeInput(p: {
 | 
				
			||||||
 | 
					  label?: string;
 | 
				
			||||||
 | 
					  value: number;
 | 
				
			||||||
 | 
					  onChange: (size: number) => void;
 | 
				
			||||||
 | 
					}): React.ReactElement {
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <TextInput
 | 
				
			||||||
 | 
					      editable={true}
 | 
				
			||||||
 | 
					      label={p.label ?? "Disk size (GB)"}
 | 
				
			||||||
 | 
					      size={{
 | 
				
			||||||
 | 
					        min: ServerApi.Config.constraints.disk_size.min / (1000 * 1000 * 1000),
 | 
				
			||||||
 | 
					        max: ServerApi.Config.constraints.disk_size.max / (1000 * 1000 * 1000),
 | 
				
			||||||
 | 
					      }}
 | 
				
			||||||
 | 
					      value={(p.value / (1000 * 1000 * 1000)).toString()}
 | 
				
			||||||
 | 
					      onValueChange={(v) => {
 | 
				
			||||||
 | 
					        p.onChange?.(Number(v ?? "0") * 1000 * 1000 * 1000);
 | 
				
			||||||
 | 
					      }}
 | 
				
			||||||
 | 
					      type="number"
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
import { mdiHarddiskPlus } from "@mdi/js";
 | 
					import { mdiHarddiskPlus } from "@mdi/js";
 | 
				
			||||||
import Icon from "@mdi/react";
 | 
					import Icon from "@mdi/react";
 | 
				
			||||||
 | 
					import ExpandIcon from "@mui/icons-material/Expand";
 | 
				
			||||||
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
 | 
					import CheckCircleIcon from "@mui/icons-material/CheckCircle";
 | 
				
			||||||
import DeleteIcon from "@mui/icons-material/Delete";
 | 
					import DeleteIcon from "@mui/icons-material/Delete";
 | 
				
			||||||
import { Button, IconButton, Paper, Tooltip, Typography } from "@mui/material";
 | 
					import { Button, IconButton, Paper, Tooltip, Typography } from "@mui/material";
 | 
				
			||||||
@@ -15,6 +16,7 @@ import { DiskBusSelect } from "./DiskBusSelect";
 | 
				
			|||||||
import { DiskImageSelect } from "./DiskImageSelect";
 | 
					import { DiskImageSelect } from "./DiskImageSelect";
 | 
				
			||||||
import { SelectInput } from "./SelectInput";
 | 
					import { SelectInput } from "./SelectInput";
 | 
				
			||||||
import { TextInput } from "./TextInput";
 | 
					import { TextInput } from "./TextInput";
 | 
				
			||||||
 | 
					import { DiskSizeInput } from "./DiskSizeInput";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function VMDisksList(p: {
 | 
					export function VMDisksList(p: {
 | 
				
			||||||
  vm: VMInfo;
 | 
					  vm: VMInfo;
 | 
				
			||||||
@@ -99,6 +101,19 @@ function DiskInfo(p: {
 | 
				
			|||||||
  diskImagesList: DiskImage[];
 | 
					  diskImagesList: DiskImage[];
 | 
				
			||||||
}): React.ReactElement {
 | 
					}): React.ReactElement {
 | 
				
			||||||
  const confirm = useConfirm();
 | 
					  const confirm = useConfirm();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const expandDisk = () => {
 | 
				
			||||||
 | 
					    if (p.disk.resize === true) {
 | 
				
			||||||
 | 
					      p.disk.resize = false;
 | 
				
			||||||
 | 
					      p.disk.size = p.disk.originalSize!;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      p.disk.resize = true;
 | 
				
			||||||
 | 
					      p.disk.originalSize = p.disk.size!;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    p.onChange?.();
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const deleteDisk = async () => {
 | 
					  const deleteDisk = async () => {
 | 
				
			||||||
    if (p.disk.deleteType) {
 | 
					    if (p.disk.deleteType) {
 | 
				
			||||||
      p.disk.deleteType = undefined;
 | 
					      p.disk.deleteType = undefined;
 | 
				
			||||||
@@ -121,10 +136,29 @@ function DiskInfo(p: {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (!p.editable || !p.disk.new)
 | 
					  if (!p.editable || !p.disk.new)
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
 | 
					      <>
 | 
				
			||||||
        <VMDiskFileWidget
 | 
					        <VMDiskFileWidget
 | 
				
			||||||
          {...p}
 | 
					          {...p}
 | 
				
			||||||
          secondaryAction={
 | 
					          secondaryAction={
 | 
				
			||||||
            <>
 | 
					            <>
 | 
				
			||||||
 | 
					              {p.editable && (
 | 
				
			||||||
 | 
					                <IconButton
 | 
				
			||||||
 | 
					                  edge="end"
 | 
				
			||||||
 | 
					                  aria-label="expand disk"
 | 
				
			||||||
 | 
					                  onClick={expandDisk}
 | 
				
			||||||
 | 
					                >
 | 
				
			||||||
 | 
					                  {p.disk.resize === true ? (
 | 
				
			||||||
 | 
					                    <Tooltip title="Cancel disk expansion">
 | 
				
			||||||
 | 
					                      <ExpandIcon color="error" />
 | 
				
			||||||
 | 
					                    </Tooltip>
 | 
				
			||||||
 | 
					                  ) : (
 | 
				
			||||||
 | 
					                    <Tooltip title="Increase disk size">
 | 
				
			||||||
 | 
					                      <ExpandIcon />
 | 
				
			||||||
 | 
					                    </Tooltip>
 | 
				
			||||||
 | 
					                  )}
 | 
				
			||||||
 | 
					                </IconButton>
 | 
				
			||||||
 | 
					              )}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              {p.editable && (
 | 
					              {p.editable && (
 | 
				
			||||||
                <IconButton
 | 
					                <IconButton
 | 
				
			||||||
                  edge="end"
 | 
					                  edge="end"
 | 
				
			||||||
@@ -157,6 +191,19 @@ function DiskInfo(p: {
 | 
				
			|||||||
            </>
 | 
					            </>
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {/* New disk size*/}
 | 
				
			||||||
 | 
					        {p.disk.resize && (
 | 
				
			||||||
 | 
					          <DiskSizeInput
 | 
				
			||||||
 | 
					            label="New disk size (GB)"
 | 
				
			||||||
 | 
					            value={p.disk.size}
 | 
				
			||||||
 | 
					            onChange={(v) => {
 | 
				
			||||||
 | 
					              p.disk.size = v;
 | 
				
			||||||
 | 
					              p.onChange?.();
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        )}
 | 
				
			||||||
 | 
					      </>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@@ -233,21 +280,12 @@ function DiskInfo(p: {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      {/* Disk size */}
 | 
					      {/* Disk size */}
 | 
				
			||||||
      {(!p.disk.from_image || p.disk.resize === true) && (
 | 
					      {(!p.disk.from_image || p.disk.resize === true) && (
 | 
				
			||||||
        <TextInput
 | 
					        <DiskSizeInput
 | 
				
			||||||
          editable={true}
 | 
					          value={p.disk.size}
 | 
				
			||||||
          label="Disk size (GB)"
 | 
					          onChange={(v) => {
 | 
				
			||||||
          size={{
 | 
					            p.disk.size = v;
 | 
				
			||||||
            min:
 | 
					 | 
				
			||||||
              ServerApi.Config.constraints.disk_size.min / (1000 * 1000 * 1000),
 | 
					 | 
				
			||||||
            max:
 | 
					 | 
				
			||||||
              ServerApi.Config.constraints.disk_size.max / (1000 * 1000 * 1000),
 | 
					 | 
				
			||||||
          }}
 | 
					 | 
				
			||||||
          value={(p.disk.size / (1000 * 1000 * 1000)).toString()}
 | 
					 | 
				
			||||||
          onValueChange={(v) => {
 | 
					 | 
				
			||||||
            p.disk.size = Number(v ?? "0") * 1000 * 1000 * 1000;
 | 
					 | 
				
			||||||
            p.onChange?.();
 | 
					            p.onChange?.();
 | 
				
			||||||
          }}
 | 
					          }}
 | 
				
			||||||
          type="number"
 | 
					 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user