Improve ISO list route UI
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		@@ -1,5 +1,4 @@
 | 
				
			|||||||
import {
 | 
					import {
 | 
				
			||||||
  Avatar,
 | 
					 | 
				
			||||||
  Button,
 | 
					  Button,
 | 
				
			||||||
  Dialog,
 | 
					  Dialog,
 | 
				
			||||||
  DialogActions,
 | 
					  DialogActions,
 | 
				
			||||||
@@ -27,7 +26,7 @@ export function IsoCatalogDialog(p: {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Dialog open={p.open} onClose={p.onClose}>
 | 
					    <Dialog open={p.open} onClose={p.onClose}>
 | 
				
			||||||
      <DialogTitle>Iso catalog</DialogTitle>
 | 
					      <DialogTitle>ISO catalog</DialogTitle>
 | 
				
			||||||
      <DialogContent>
 | 
					      <DialogContent>
 | 
				
			||||||
        <AsyncWidget
 | 
					        <AsyncWidget
 | 
				
			||||||
          loadKey={1}
 | 
					          loadKey={1}
 | 
				
			||||||
@@ -52,12 +51,13 @@ export function IsoCatalogDialogInner(p: {
 | 
				
			|||||||
    <List dense>
 | 
					    <List dense>
 | 
				
			||||||
      {p.catalog.map((entry) => (
 | 
					      {p.catalog.map((entry) => (
 | 
				
			||||||
        <a
 | 
					        <a
 | 
				
			||||||
 | 
					          key={entry.name}
 | 
				
			||||||
          href={entry.url}
 | 
					          href={entry.url}
 | 
				
			||||||
          target="_blank"
 | 
					          target="_blank"
 | 
				
			||||||
          rel="noopener"
 | 
					          rel="noopener"
 | 
				
			||||||
          style={{ color: "inherit", textDecoration: "none" }}
 | 
					          style={{ color: "inherit", textDecoration: "none" }}
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          <ListItem key={entry.name}>
 | 
					          <ListItem>
 | 
				
			||||||
            <ListItemButton>
 | 
					            <ListItemButton>
 | 
				
			||||||
              <ListItemAvatar>
 | 
					              <ListItemAvatar>
 | 
				
			||||||
                <img
 | 
					                <img
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
import DeleteIcon from "@mui/icons-material/Delete";
 | 
					import DeleteIcon from "@mui/icons-material/Delete";
 | 
				
			||||||
import DownloadIcon from "@mui/icons-material/Download";
 | 
					import DownloadIcon from "@mui/icons-material/Download";
 | 
				
			||||||
 | 
					import MenuBookIcon from "@mui/icons-material/MenuBook";
 | 
				
			||||||
 | 
					import RefreshIcon from "@mui/icons-material/Refresh";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  Alert,
 | 
					  Alert,
 | 
				
			||||||
  Button,
 | 
					  Button,
 | 
				
			||||||
@@ -15,6 +17,7 @@ import { filesize } from "filesize";
 | 
				
			|||||||
import React from "react";
 | 
					import React from "react";
 | 
				
			||||||
import { IsoFile, IsoFilesApi } from "../api/IsoFilesApi";
 | 
					import { IsoFile, IsoFilesApi } from "../api/IsoFilesApi";
 | 
				
			||||||
import { ServerApi } from "../api/ServerApi";
 | 
					import { ServerApi } from "../api/ServerApi";
 | 
				
			||||||
 | 
					import { IsoCatalogDialog } from "../dialogs/IsoCatalogDialog";
 | 
				
			||||||
import { useAlert } from "../hooks/providers/AlertDialogProvider";
 | 
					import { useAlert } from "../hooks/providers/AlertDialogProvider";
 | 
				
			||||||
import { useConfirm } from "../hooks/providers/ConfirmDialogProvider";
 | 
					import { useConfirm } from "../hooks/providers/ConfirmDialogProvider";
 | 
				
			||||||
import { useLoadingMessage } from "../hooks/providers/LoadingMessageProvider";
 | 
					import { useLoadingMessage } from "../hooks/providers/LoadingMessageProvider";
 | 
				
			||||||
@@ -24,8 +27,6 @@ import { AsyncWidget } from "../widgets/AsyncWidget";
 | 
				
			|||||||
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";
 | 
				
			||||||
import MenuBookIcon from "@mui/icons-material/MenuBook";
 | 
					 | 
				
			||||||
import { IsoCatalogDialog } from "../dialogs/IsoCatalogDialog";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function IsoFilesRoute(): React.ReactElement {
 | 
					export function IsoFilesRoute(): React.ReactElement {
 | 
				
			||||||
  const [list, setList] = React.useState<IsoFile[] | undefined>();
 | 
					  const [list, setList] = React.useState<IsoFile[] | undefined>();
 | 
				
			||||||
@@ -53,11 +54,18 @@ export function IsoFilesRoute(): React.ReactElement {
 | 
				
			|||||||
          <VirtWebRouteContainer
 | 
					          <VirtWebRouteContainer
 | 
				
			||||||
            label="ISO files management"
 | 
					            label="ISO files management"
 | 
				
			||||||
            actions={
 | 
					            actions={
 | 
				
			||||||
              <Tooltip title="Open the ISO catalog">
 | 
					              <span>
 | 
				
			||||||
                <IconButton onClick={() => setIsoCatalog(true)}>
 | 
					                <Tooltip title="Open the ISO catalog">
 | 
				
			||||||
                  <MenuBookIcon />
 | 
					                  <IconButton onClick={() => { setIsoCatalog(true); }}>
 | 
				
			||||||
                </IconButton>
 | 
					                    <MenuBookIcon />
 | 
				
			||||||
              </Tooltip>
 | 
					                  </IconButton>
 | 
				
			||||||
 | 
					                </Tooltip>
 | 
				
			||||||
 | 
					                <Tooltip title="Refresh ISO list">
 | 
				
			||||||
 | 
					                  <IconButton onClick={reload}>
 | 
				
			||||||
 | 
					                    <RefreshIcon />
 | 
				
			||||||
 | 
					                  </IconButton>
 | 
				
			||||||
 | 
					                </Tooltip>
 | 
				
			||||||
 | 
					              </span>
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            <UploadIsoFileCard onFileUploaded={reload} />
 | 
					            <UploadIsoFileCard onFileUploaded={reload} />
 | 
				
			||||||
@@ -68,7 +76,7 @@ export function IsoFilesRoute(): React.ReactElement {
 | 
				
			|||||||
      />
 | 
					      />
 | 
				
			||||||
      <IsoCatalogDialog
 | 
					      <IsoCatalogDialog
 | 
				
			||||||
        open={isoCatalog}
 | 
					        open={isoCatalog}
 | 
				
			||||||
        onClose={() => setIsoCatalog(false)}
 | 
					        onClose={() => { setIsoCatalog(false); }}
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
    </>
 | 
					    </>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
@@ -122,7 +130,7 @@ function UploadIsoFileCard(p: {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (uploadProgress !== null) {
 | 
					  if (uploadProgress !== null) {
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <VirtWebPaper label="File upload">
 | 
					      <VirtWebPaper label="File upload" noHorizontalMargin>
 | 
				
			||||||
        <Typography variant="body1">
 | 
					        <Typography variant="body1">
 | 
				
			||||||
          Upload in progress ({Math.floor(uploadProgress * 100)}%)...
 | 
					          Upload in progress ({Math.floor(uploadProgress * 100)}%)...
 | 
				
			||||||
        </Typography>
 | 
					        </Typography>
 | 
				
			||||||
@@ -132,7 +140,7 @@ function UploadIsoFileCard(p: {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <VirtWebPaper label="File upload">
 | 
					    <VirtWebPaper label="File upload" noHorizontalMargin>
 | 
				
			||||||
      <div style={{ display: "flex", alignItems: "center" }}>
 | 
					      <div style={{ display: "flex", alignItems: "center" }}>
 | 
				
			||||||
        <FileInput
 | 
					        <FileInput
 | 
				
			||||||
          value={value}
 | 
					          value={value}
 | 
				
			||||||
@@ -180,7 +188,7 @@ function UploadIsoFileFromUrlCard(p: {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <VirtWebPaper label="File upload from URL">
 | 
					    <VirtWebPaper label="File upload from URL" noHorizontalMargin>
 | 
				
			||||||
      <div style={{ display: "flex", alignItems: "center" }}>
 | 
					      <div style={{ display: "flex", alignItems: "center" }}>
 | 
				
			||||||
        <TextField
 | 
					        <TextField
 | 
				
			||||||
          label="URL"
 | 
					          label="URL"
 | 
				
			||||||
@@ -297,38 +305,31 @@ function IsoFilesList(p: {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <>
 | 
					    <>
 | 
				
			||||||
      <VirtWebPaper label="Files list">
 | 
					      {/* Download notification */}
 | 
				
			||||||
        {/* Download notification */}
 | 
					      {dlProgress !== undefined && (
 | 
				
			||||||
        {dlProgress !== undefined && (
 | 
					        <Alert severity="info">
 | 
				
			||||||
          <Alert severity="info">
 | 
					          <div
 | 
				
			||||||
            <div
 | 
					            style={{
 | 
				
			||||||
              style={{
 | 
					              display: "flex",
 | 
				
			||||||
                display: "flex",
 | 
					              flexDirection: "row",
 | 
				
			||||||
                flexDirection: "row",
 | 
					              alignItems: "center",
 | 
				
			||||||
                alignItems: "center",
 | 
					              overflow: "hidden",
 | 
				
			||||||
                overflow: "hidden",
 | 
					            }}
 | 
				
			||||||
              }}
 | 
					          >
 | 
				
			||||||
            >
 | 
					            <Typography variant="body1">
 | 
				
			||||||
              <Typography variant="body1">
 | 
					              Downloading... {dlProgress}%
 | 
				
			||||||
                Downloading... {dlProgress}%
 | 
					            </Typography>
 | 
				
			||||||
              </Typography>
 | 
					            <CircularProgress
 | 
				
			||||||
              <CircularProgress
 | 
					              variant="determinate"
 | 
				
			||||||
                variant="determinate"
 | 
					              size={"1.5rem"}
 | 
				
			||||||
                size={"1.5rem"}
 | 
					              style={{ marginLeft: "10px" }}
 | 
				
			||||||
                style={{ marginLeft: "10px" }}
 | 
					              value={dlProgress}
 | 
				
			||||||
                value={dlProgress}
 | 
					            />
 | 
				
			||||||
              />
 | 
					          </div>
 | 
				
			||||||
            </div>
 | 
					        </Alert>
 | 
				
			||||||
          </Alert>
 | 
					      )}
 | 
				
			||||||
        )}
 | 
					      {/* ISO files list table */}
 | 
				
			||||||
 | 
					      <DataGrid getRowId={(c) => c.filename} rows={p.list} columns={columns} />
 | 
				
			||||||
        {/* Files list table */}
 | 
					 | 
				
			||||||
        <DataGrid
 | 
					 | 
				
			||||||
          getRowId={(c) => c.filename}
 | 
					 | 
				
			||||||
          rows={p.list}
 | 
					 | 
				
			||||||
          columns={columns}
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      </VirtWebPaper>
 | 
					 | 
				
			||||||
    </>
 | 
					    </>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@ import {
 | 
				
			|||||||
  List,
 | 
					  List,
 | 
				
			||||||
  ListItemButton,
 | 
					  ListItemButton,
 | 
				
			||||||
  ListItemIcon,
 | 
					  ListItemIcon,
 | 
				
			||||||
  ListItemText
 | 
					  ListItemText,
 | 
				
			||||||
} from "@mui/material";
 | 
					} from "@mui/material";
 | 
				
			||||||
import { Outlet, useLocation } from "react-router-dom";
 | 
					import { Outlet, useLocation } from "react-router-dom";
 | 
				
			||||||
import { RouterLink } from "./RouterLink";
 | 
					import { RouterLink } from "./RouterLink";
 | 
				
			||||||
@@ -82,7 +82,15 @@ export function BaseAuthenticatedPage(): React.ReactElement {
 | 
				
			|||||||
            icon={<Icon path={mdiInformation} size={1} />}
 | 
					            icon={<Icon path={mdiInformation} size={1} />}
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
        </List>
 | 
					        </List>
 | 
				
			||||||
        <div style={{ flex: 1 }}>
 | 
					        <div
 | 
				
			||||||
 | 
					          style={{
 | 
				
			||||||
 | 
					            flexGrow: 1,
 | 
				
			||||||
 | 
					            flexShrink: 0,
 | 
				
			||||||
 | 
					            flexBasis: 0,
 | 
				
			||||||
 | 
					            minWidth: 0,
 | 
				
			||||||
 | 
					            display: "flex",
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
          <Outlet />
 | 
					          <Outlet />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </Box>
 | 
					      </Box>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,10 +2,19 @@ import { Paper, Typography } from "@mui/material";
 | 
				
			|||||||
import React, { PropsWithChildren } from "react";
 | 
					import React, { PropsWithChildren } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function VirtWebPaper(
 | 
					export function VirtWebPaper(
 | 
				
			||||||
  p: { label: string | React.ReactElement } & PropsWithChildren
 | 
					  p: {
 | 
				
			||||||
 | 
					    label: string | React.ReactElement;
 | 
				
			||||||
 | 
					    noHorizontalMargin?: boolean;
 | 
				
			||||||
 | 
					  } & PropsWithChildren
 | 
				
			||||||
): React.ReactElement {
 | 
					): React.ReactElement {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Paper elevation={2} style={{ padding: "10px", margin: "20px" }}>
 | 
					    <Paper
 | 
				
			||||||
 | 
					      elevation={2}
 | 
				
			||||||
 | 
					      style={{
 | 
				
			||||||
 | 
					        padding: "10px",
 | 
				
			||||||
 | 
					        margin: p.noHorizontalMargin ? "20px 0px" : "20px",
 | 
				
			||||||
 | 
					      }}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
      <Typography
 | 
					      <Typography
 | 
				
			||||||
        variant="subtitle1"
 | 
					        variant="subtitle1"
 | 
				
			||||||
        style={{ marginBottom: "10px", fontWeight: "bold" }}
 | 
					        style={{ marginBottom: "10px", fontWeight: "bold" }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,18 @@ export function VirtWebRouteContainer(
 | 
				
			|||||||
  } & PropsWithChildren
 | 
					  } & PropsWithChildren
 | 
				
			||||||
): React.ReactElement {
 | 
					): React.ReactElement {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div style={{ margin: "50px" }}>
 | 
					    <div
 | 
				
			||||||
 | 
					      style={{
 | 
				
			||||||
 | 
					        margin: "50px",
 | 
				
			||||||
 | 
					        flex: "1",
 | 
				
			||||||
 | 
					        flexGrow: 1,
 | 
				
			||||||
 | 
					        flexShrink: 0,
 | 
				
			||||||
 | 
					        flexBasis: 0,
 | 
				
			||||||
 | 
					        minWidth: 0,
 | 
				
			||||||
 | 
					        display: "flex",
 | 
				
			||||||
 | 
					        flexDirection: "column",
 | 
				
			||||||
 | 
					      }}
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
      <div
 | 
					      <div
 | 
				
			||||||
        style={{
 | 
					        style={{
 | 
				
			||||||
          display: "flex",
 | 
					          display: "flex",
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user