Display the list of uploaded disk images
This commit is contained in:
		@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					import DeleteIcon from "@mui/icons-material/Delete";
 | 
				
			||||||
 | 
					import DownloadIcon from "@mui/icons-material/Download";
 | 
				
			||||||
import RefreshIcon from "@mui/icons-material/Refresh";
 | 
					import RefreshIcon from "@mui/icons-material/Refresh";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  Button,
 | 
					  Button,
 | 
				
			||||||
@@ -6,6 +8,7 @@ import {
 | 
				
			|||||||
  Tooltip,
 | 
					  Tooltip,
 | 
				
			||||||
  Typography,
 | 
					  Typography,
 | 
				
			||||||
} from "@mui/material";
 | 
					} from "@mui/material";
 | 
				
			||||||
 | 
					import { DataGrid, GridColDef } from "@mui/x-data-grid";
 | 
				
			||||||
import { filesize } from "filesize";
 | 
					import { filesize } from "filesize";
 | 
				
			||||||
import React from "react";
 | 
					import React from "react";
 | 
				
			||||||
import { DiskImage, DiskImageApi } from "../api/DiskImageApi";
 | 
					import { DiskImage, DiskImageApi } from "../api/DiskImageApi";
 | 
				
			||||||
@@ -13,6 +16,7 @@ import { ServerApi } from "../api/ServerApi";
 | 
				
			|||||||
import { useAlert } from "../hooks/providers/AlertDialogProvider";
 | 
					import { useAlert } from "../hooks/providers/AlertDialogProvider";
 | 
				
			||||||
import { useSnackbar } from "../hooks/providers/SnackbarProvider";
 | 
					import { useSnackbar } from "../hooks/providers/SnackbarProvider";
 | 
				
			||||||
import { AsyncWidget } from "../widgets/AsyncWidget";
 | 
					import { AsyncWidget } from "../widgets/AsyncWidget";
 | 
				
			||||||
 | 
					import { DateWidget } from "../widgets/DateWidget";
 | 
				
			||||||
import { FileInput } from "../widgets/forms/FileInput";
 | 
					import { FileInput } from "../widgets/forms/FileInput";
 | 
				
			||||||
import { VirtWebPaper } from "../widgets/VirtWebPaper";
 | 
					import { VirtWebPaper } from "../widgets/VirtWebPaper";
 | 
				
			||||||
import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer";
 | 
					import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer";
 | 
				
			||||||
@@ -32,28 +36,28 @@ export function DiskImagesRoute(): React.ReactElement {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <VirtWebRouteContainer label="Disk images">
 | 
					    <VirtWebRouteContainer
 | 
				
			||||||
 | 
					      label="Disk images management"
 | 
				
			||||||
 | 
					      actions={
 | 
				
			||||||
 | 
					        <span>
 | 
				
			||||||
 | 
					          <Tooltip title="Refresh Disk images list">
 | 
				
			||||||
 | 
					            <IconButton onClick={reload}>
 | 
				
			||||||
 | 
					              <RefreshIcon />
 | 
				
			||||||
 | 
					            </IconButton>
 | 
				
			||||||
 | 
					          </Tooltip>
 | 
				
			||||||
 | 
					        </span>
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
      <AsyncWidget
 | 
					      <AsyncWidget
 | 
				
			||||||
        loadKey={loadKey.current}
 | 
					        loadKey={loadKey.current}
 | 
				
			||||||
        errMsg="Failed to load disk images list!"
 | 
					        errMsg="Failed to load disk images list!"
 | 
				
			||||||
        load={load}
 | 
					        load={load}
 | 
				
			||||||
        ready={list !== undefined}
 | 
					        ready={list !== undefined}
 | 
				
			||||||
        build={() => (
 | 
					        build={() => (
 | 
				
			||||||
          <VirtWebRouteContainer
 | 
					          <>
 | 
				
			||||||
            label="Disk images management"
 | 
					 | 
				
			||||||
            actions={
 | 
					 | 
				
			||||||
              <span>
 | 
					 | 
				
			||||||
                <Tooltip title="Refresh Disk images list">
 | 
					 | 
				
			||||||
                  <IconButton onClick={reload}>
 | 
					 | 
				
			||||||
                    <RefreshIcon />
 | 
					 | 
				
			||||||
                  </IconButton>
 | 
					 | 
				
			||||||
                </Tooltip>
 | 
					 | 
				
			||||||
              </span>
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          >
 | 
					 | 
				
			||||||
            <UploadDiskImageCard onFileUploaded={reload} />
 | 
					            <UploadDiskImageCard onFileUploaded={reload} />
 | 
				
			||||||
            <DiskImageList list={list!} onReload={reload} />
 | 
					            <DiskImageList list={list!} onReload={reload} />
 | 
				
			||||||
          </VirtWebRouteContainer>
 | 
					          </>
 | 
				
			||||||
        )}
 | 
					        )}
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
    </VirtWebRouteContainer>
 | 
					    </VirtWebRouteContainer>
 | 
				
			||||||
@@ -148,5 +152,53 @@ function DiskImageList(p: {
 | 
				
			|||||||
  list: DiskImage[];
 | 
					  list: DiskImage[];
 | 
				
			||||||
  onReload: () => void;
 | 
					  onReload: () => void;
 | 
				
			||||||
}): React.ReactElement {
 | 
					}): React.ReactElement {
 | 
				
			||||||
  return <>todo</>;
 | 
					  const columns: GridColDef<(typeof p.list)[number]>[] = [
 | 
				
			||||||
 | 
					    { field: "file_name", headerName: "File name", flex: 3 },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      field: "format",
 | 
				
			||||||
 | 
					      headerName: "Format",
 | 
				
			||||||
 | 
					      flex: 1,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      field: "file_size",
 | 
				
			||||||
 | 
					      headerName: "File size",
 | 
				
			||||||
 | 
					      flex: 1,
 | 
				
			||||||
 | 
					      renderCell(params) {
 | 
				
			||||||
 | 
					        return filesize(params.row.file_size);
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      field: "created",
 | 
				
			||||||
 | 
					      headerName: "Created",
 | 
				
			||||||
 | 
					      flex: 1,
 | 
				
			||||||
 | 
					      renderCell(params) {
 | 
				
			||||||
 | 
					        return <DateWidget time={params.row.created} />;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      field: "actions",
 | 
				
			||||||
 | 
					      headerName: "",
 | 
				
			||||||
 | 
					      width: 120,
 | 
				
			||||||
 | 
					      renderCell(params) {
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					          <>
 | 
				
			||||||
 | 
					            <Tooltip title="Download image">
 | 
				
			||||||
 | 
					              <IconButton onClick={() => downloadIso(params.row)}>
 | 
				
			||||||
 | 
					                <DownloadIcon />
 | 
				
			||||||
 | 
					              </IconButton>
 | 
				
			||||||
 | 
					            </Tooltip>
 | 
				
			||||||
 | 
					            <Tooltip title="Delete file">
 | 
				
			||||||
 | 
					              <IconButton onClick={() => deleteIso(params.row)}>
 | 
				
			||||||
 | 
					                <DeleteIcon />
 | 
				
			||||||
 | 
					              </IconButton>
 | 
				
			||||||
 | 
					            </Tooltip>
 | 
				
			||||||
 | 
					          </>
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <DataGrid getRowId={(c) => c.file_name} rows={p.list} columns={columns} />
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								virtweb_frontend/src/widgets/DateWidget.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								virtweb_frontend/src/widgets/DateWidget.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					export function DateWidget(p: { time: number }): React.ReactElement {
 | 
				
			||||||
 | 
					  const date = new Date(p.time * 1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <>
 | 
				
			||||||
 | 
					      {pad(date.getDate())}/{pad(date.getMonth() + 1)}/{date.getFullYear()}
 | 
				
			||||||
 | 
					    </>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function pad(num: number): string {
 | 
				
			||||||
 | 
					  return num.toString().padStart(2, "0");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user