Can upload disk images on the server
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2025-05-27 20:40:48 +02:00
parent 6a7af7e6c4
commit b55880b43c
13 changed files with 288 additions and 5 deletions

View File

@ -0,0 +1,151 @@
import RefreshIcon from "@mui/icons-material/Refresh";
import {
Button,
IconButton,
LinearProgress,
Tooltip,
Typography,
} from "@mui/material";
import { filesize } from "filesize";
import React from "react";
import { DiskImage, DiskImageApi } from "../api/DiskImageApi";
import { ServerApi } from "../api/ServerApi";
import { useAlert } from "../hooks/providers/AlertDialogProvider";
import { useSnackbar } from "../hooks/providers/SnackbarProvider";
import { AsyncWidget } from "../widgets/AsyncWidget";
import { FileInput } from "../widgets/forms/FileInput";
import { VirtWebPaper } from "../widgets/VirtWebPaper";
import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer";
export function DiskImagesRoute(): React.ReactElement {
const [list, setList] = React.useState<DiskImage[] | undefined>();
const loadKey = React.useRef(1);
const load = async () => {
setList(await DiskImageApi.GetList());
};
const reload = () => {
loadKey.current += 1;
setList(undefined);
};
return (
<VirtWebRouteContainer label="Disk images">
<AsyncWidget
loadKey={loadKey.current}
errMsg="Failed to load disk images list!"
load={load}
ready={list !== undefined}
build={() => (
<VirtWebRouteContainer
label="Disk images management"
actions={
<span>
<Tooltip title="Refresh Disk images list">
<IconButton onClick={reload}>
<RefreshIcon />
</IconButton>
</Tooltip>
</span>
}
>
<UploadDiskImageCard onFileUploaded={reload} />
<DiskImageList list={list!} onReload={reload} />
</VirtWebRouteContainer>
)}
/>
</VirtWebRouteContainer>
);
}
function UploadDiskImageCard(p: {
onFileUploaded: () => void;
}): React.ReactElement {
const alert = useAlert();
const snackbar = useSnackbar();
const [value, setValue] = React.useState<File | null>(null);
const [uploadProgress, setUploadProgress] = React.useState<number | null>(
null
);
const handleChange = (newValue: File | null) => {
if (
newValue &&
newValue.size > ServerApi.Config.constraints.disk_image_max_size
) {
alert(
`The file is too big (max size allowed: ${filesize(
ServerApi.Config.constraints.disk_image_max_size
)}`
);
return;
}
if (
newValue &&
!ServerApi.Config.disk_images_mimetypes.includes(newValue.type)
) {
alert(`Selected file mimetype is not allowed! (${newValue.type})`);
return;
}
setValue(newValue);
};
const upload = async () => {
try {
setUploadProgress(0);
await DiskImageApi.Upload(value!, setUploadProgress);
setValue(null);
snackbar("The file was successfully uploaded!");
p.onFileUploaded();
} catch (e) {
console.error(e);
await alert(`Failed to perform file upload! ${e}`);
}
setUploadProgress(null);
};
if (uploadProgress !== null) {
return (
<VirtWebPaper label="File upload" noHorizontalMargin>
<Typography variant="body1">
Upload in progress ({Math.floor(uploadProgress * 100)}%)...
</Typography>
<LinearProgress variant="determinate" value={uploadProgress * 100} />
</VirtWebPaper>
);
}
return (
<VirtWebPaper label="Disk image upload" noHorizontalMargin>
<div style={{ display: "flex", alignItems: "center" }}>
<FileInput
value={value}
onChange={handleChange}
style={{ flex: 1 }}
slotProps={{
htmlInput: {
accept: ServerApi.Config.disk_images_mimetypes.join(","),
},
}}
/>
{value && <Button onClick={upload}>Upload</Button>}
</div>
</VirtWebPaper>
);
}
function DiskImageList(p: {
list: DiskImage[];
onReload: () => void;
}): React.ReactElement {
return <>todo</>;
}