Add ISO catalog
This commit is contained in:
@ -5,6 +5,15 @@ export interface IsoFile {
|
||||
size: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* ISO catalog entries
|
||||
*/
|
||||
export interface ISOCatalogEntry {
|
||||
name: string;
|
||||
url: string;
|
||||
image: string;
|
||||
}
|
||||
|
||||
export class IsoFilesApi {
|
||||
/**
|
||||
* Upload a new ISO file to the server
|
||||
@ -74,4 +83,23 @@ export class IsoFilesApi {
|
||||
uri: `/iso/${file.filename}`,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get iso catalog
|
||||
*/
|
||||
static async Catalog(): Promise<ISOCatalogEntry[]> {
|
||||
return (
|
||||
await APIClient.exec({
|
||||
method: "GET",
|
||||
uri: "/assets/iso_catalog.json",
|
||||
})
|
||||
).data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get catalog image URL
|
||||
*/
|
||||
static CatalogImageURL(entry: ISOCatalogEntry): string {
|
||||
return APIClient.backendURL() + entry.image;
|
||||
}
|
||||
}
|
||||
|
75
virtweb_frontend/src/dialogs/IsoCatalogDialog.tsx
Normal file
75
virtweb_frontend/src/dialogs/IsoCatalogDialog.tsx
Normal file
@ -0,0 +1,75 @@
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemButton,
|
||||
ListItemText,
|
||||
} from "@mui/material";
|
||||
import React from "react";
|
||||
import { ISOCatalogEntry, IsoFilesApi } from "../api/IsoFilesApi";
|
||||
import { AsyncWidget } from "../widgets/AsyncWidget";
|
||||
|
||||
export function IsoCatalogDialog(p: {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}): React.ReactElement {
|
||||
const [catalog, setCatalog] = React.useState<ISOCatalogEntry[] | undefined>();
|
||||
|
||||
const load = async () => {
|
||||
setCatalog(await IsoFilesApi.Catalog());
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={p.open} onClose={p.onClose}>
|
||||
<DialogTitle>Iso catalog</DialogTitle>
|
||||
<DialogContent>
|
||||
<AsyncWidget
|
||||
loadKey={1}
|
||||
load={load}
|
||||
errMsg="Failed to load catalog"
|
||||
build={() => <IsoCatalogDialogInner catalog={catalog!} />}
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button autoFocus onClick={p.onClose}>
|
||||
Close
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
export function IsoCatalogDialogInner(p: {
|
||||
catalog: ISOCatalogEntry[];
|
||||
}): React.ReactElement {
|
||||
return (
|
||||
<List dense>
|
||||
{p.catalog.map((entry) => (
|
||||
<a
|
||||
href={entry.url}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
style={{ color: "inherit", textDecoration: "none" }}
|
||||
>
|
||||
<ListItem key={entry.name}>
|
||||
<ListItemButton>
|
||||
<ListItemAvatar>
|
||||
<img
|
||||
src={IsoFilesApi.CatalogImageURL(entry)}
|
||||
style={{ width: "2em" }}
|
||||
/>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary={entry.name} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
</a>
|
||||
))}
|
||||
</List>
|
||||
);
|
||||
}
|
@ -24,9 +24,12 @@ import { AsyncWidget } from "../widgets/AsyncWidget";
|
||||
import { FileInput } from "../widgets/forms/FileInput";
|
||||
import { VirtWebPaper } from "../widgets/VirtWebPaper";
|
||||
import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer";
|
||||
import MenuBookIcon from "@mui/icons-material/MenuBook";
|
||||
import { IsoCatalogDialog } from "../dialogs/IsoCatalogDialog";
|
||||
|
||||
export function IsoFilesRoute(): React.ReactElement {
|
||||
const [list, setList] = React.useState<IsoFile[] | undefined>();
|
||||
const [isoCatalog, setIsoCatalog] = React.useState(false);
|
||||
|
||||
const loadKey = React.useRef(1);
|
||||
|
||||
@ -40,19 +43,34 @@ export function IsoFilesRoute(): React.ReactElement {
|
||||
};
|
||||
|
||||
return (
|
||||
<AsyncWidget
|
||||
loadKey={loadKey.current}
|
||||
errMsg="Failed to load ISO files list!"
|
||||
load={load}
|
||||
ready={list !== undefined}
|
||||
build={() => (
|
||||
<VirtWebRouteContainer label="ISO files management">
|
||||
<UploadIsoFileCard onFileUploaded={reload} />
|
||||
<UploadIsoFileFromUrlCard onFileUploaded={reload} />
|
||||
<IsoFilesList list={list!} onReload={reload} />
|
||||
</VirtWebRouteContainer>
|
||||
)}
|
||||
/>
|
||||
<>
|
||||
<AsyncWidget
|
||||
loadKey={loadKey.current}
|
||||
errMsg="Failed to load ISO files list!"
|
||||
load={load}
|
||||
ready={list !== undefined}
|
||||
build={() => (
|
||||
<VirtWebRouteContainer
|
||||
label="ISO files management"
|
||||
actions={
|
||||
<Tooltip title="Open the ISO catalog">
|
||||
<IconButton onClick={() => setIsoCatalog(true)}>
|
||||
<MenuBookIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
}
|
||||
>
|
||||
<UploadIsoFileCard onFileUploaded={reload} />
|
||||
<UploadIsoFileFromUrlCard onFileUploaded={reload} />
|
||||
<IsoFilesList list={list!} onReload={reload} />
|
||||
</VirtWebRouteContainer>
|
||||
)}
|
||||
/>
|
||||
<IsoCatalogDialog
|
||||
open={isoCatalog}
|
||||
onClose={() => setIsoCatalog(false)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user