Add Workers Drawer

This commit is contained in:
2025-09-01 21:50:38 +02:00
parent 2019a11e93
commit 7c1d9125ba
4 changed files with 166 additions and 43 deletions

View File

@@ -13,6 +13,7 @@ import {
} from "./apiClient/data-contracts.ts";
import Search from "./Components/Search.tsx";
import { Typography } from "@mui/joy";
import Workers from "./Components/WorkerModal/Workers.tsx";
export const MangaConnectorContext = createContext<MangaConnector[]>([]);
export const MangaContext = createContext<Manga[]>([]);
@@ -43,7 +44,7 @@ export default function App() {
if (response.ok) setFileLibraries(response.data);
});
Api.queryMangaDownloadingList().then((response) => {
Api.mangaDownloadingList().then((response) => {
if (response.ok) setManga(response.data);
});
}, []);
@@ -67,6 +68,7 @@ export default function App() {
<Sheet className={"app"}>
<Header>
<Settings setApiUri={setApiUri} />
<Workers />
</Header>
<Sheet className={"app-content"}>
<MangaList mangas={manga}>

View File

@@ -0,0 +1,72 @@
import { Dispatch, ReactNode, useContext, useState } from "react";
import Drawer from "@mui/joy/Drawer";
import { Button, Option, Select, Table } from "@mui/joy";
import { BaseWorker } from "../../apiClient/data-contracts.ts";
import ModalClose from "@mui/joy/ModalClose";
import { ApiContext } from "../../apiClient/ApiContext.tsx";
export default function (): ReactNode {
const [open, setOpen] = useState(false);
const [workers, setWorkers] = useState<BaseWorker[]>([]);
const Api = useContext(ApiContext);
Api.workerList().then((response) => {
if (response.ok) {
setWorkers(response.data);
}
});
return (
<>
<Button onClick={() => setOpen(true)}>Workers</Button>
<WorkerDrawer open={open} setOpen={setOpen} workers={workers} />
</>
);
}
function WorkerDrawer({
open,
setOpen,
workers,
}: {
open: boolean;
setOpen: Dispatch<boolean>;
workers: BaseWorker[];
}): ReactNode {
return (
<Drawer open={open} onClose={() => setOpen(false)} size={"lg"}>
<ModalClose />
<Table
borderAxis="bothBetween"
size="md"
stickyFooter={false}
stickyHeader
>
<thead>
<tr>
<th>Key</th>
<th>Can run</th>
<th>Missing dependencies</th>
</tr>
</thead>
<tbody>
{workers.map((worker) => {
return (
<tr>
<td>{worker.key}</td>
<td>{worker.allDependenciesFulfilled ? "yes" : "no"}</td>
<td>
<Select placeholder={"Missing dependencies"}>
{worker.missingDependencies?.map((worker) => {
return <Option value={worker.key}>{worker.key}</Option>;
})}
</Select>
</td>
</tr>
);
})}
</tbody>
</Table>
</Drawer>
);
}

View File

@@ -227,12 +227,42 @@ export class V2<
* @request GET:/v2/Manga
*/
mangaList = (params: RequestParams = {}) =>
this.request<string[], any>({
this.request<Manga[], any>({
path: `/v2/Manga`,
method: "GET",
format: "json",
...params,
});
/**
* No description
*
* @tags Manga
* @name MangaKeysList
* @summary Returns all cached API.Schema.MangaContext.Manga.Keys
* @request GET:/v2/Manga/Keys
*/
mangaKeysList = (params: RequestParams = {}) =>
this.request<string[], any>({
path: `/v2/Manga/Keys`,
method: "GET",
format: "json",
...params,
});
/**
* No description
*
* @tags Manga
* @name MangaDownloadingList
* @summary Returns all API.Schema.MangaContext.Manga that are being downloaded from at least one API.MangaConnectors.MangaConnector
* @request GET:/v2/Manga/Downloading
*/
mangaDownloadingList = (params: RequestParams = {}) =>
this.request<Manga[], any>({
path: `/v2/Manga/Downloading`,
method: "GET",
format: "json",
...params,
});
/**
* No description
*
@@ -863,27 +893,12 @@ export class V2<
format: "json",
...params,
});
/**
* No description
*
* @tags Query
* @name QueryMangaDownloadingList
* @summary Returns all API.Schema.MangaContext.Manga that are being downloaded from at least one API.MangaConnectors.MangaConnector
* @request GET:/v2/Query/Manga/Downloading
*/
queryMangaDownloadingList = (params: RequestParams = {}) =>
this.request<Manga[], any>({
path: `/v2/Query/Manga/Downloading`,
method: "GET",
format: "json",
...params,
});
/**
* No description
*
* @tags Query
* @name QueryMangaSimilarNameList
* @summary Returns API.Schema.MangaContext.Manga with names similar to API.Schema.MangaContext.Manga (identified by MangaId
* @summary Returns API.Schema.MangaContext.Manga with names similar to API.Schema.MangaContext.Manga (identified by MangaId)
* @request GET:/v2/Query/Manga/{MangaId}/SimilarName
*/
queryMangaSimilarNameList = (mangaId: string, params: RequestParams = {}) =>
@@ -1283,11 +1298,11 @@ export class V2<
*
* @tags Worker
* @name WorkerList
* @summary Returns all API.Workers.BaseWorker.Keys
* @summary Returns all API.Workers.BaseWorker
* @request GET:/v2/Worker
*/
workerList = (params: RequestParams = {}) =>
this.request<string[], any>({
this.request<BaseWorker[], any>({
path: `/v2/Worker`,
method: "GET",
format: "json",
@@ -1297,16 +1312,14 @@ export class V2<
* No description
*
* @tags Worker
* @name WorkerWithIDsCreate
* @summary Returns API.Workers.BaseWorker with requested WorkerIds
* @request POST:/v2/Worker/WithIDs
* @name WorkerKeysList
* @summary Returns all API.Workers.BaseWorker.Keys
* @request GET:/v2/Worker/Keys
*/
workerWithIDsCreate = (data: string[], params: RequestParams = {}) =>
this.request<BaseWorker[], any>({
path: `/v2/Worker/WithIDs`,
method: "POST",
body: data,
type: ContentType.Json,
workerKeysList = (params: RequestParams = {}) =>
this.request<string[], any>({
path: `/v2/Worker/Keys`,
method: "GET",
format: "json",
...params,
});

View File

@@ -52,7 +52,11 @@ export interface AltTitle {
* @maxLength 256
*/
title: string;
key?: string | null;
/**
* @minLength 16
* @maxLength 64
*/
key: string;
}
export interface Author {
@@ -61,20 +65,24 @@ export interface Author {
* @maxLength 128
*/
authorName: string;
key?: string | null;
/**
* @minLength 16
* @maxLength 64
*/
key: string;
}
export interface BaseWorker {
/** Workers this Worker depends on being completed before running. */
dependsOn?: BaseWorker[] | null;
/** Dependencies and dependencies of dependencies. See also API.Workers.BaseWorker.DependsOn. */
allDependencies?: BaseWorker[] | null;
/** API.Workers.BaseWorker.AllDependencies and Self. */
dependenciesAndSelf?: BaseWorker[] | null;
/** API.Workers.BaseWorker.DependsOn where API.Workers.WorkerExecutionState is less than Completed. */
missingDependencies?: BaseWorker[] | null;
allDependenciesFulfilled?: boolean;
key?: string | null;
/**
* @minLength 16
* @maxLength 64
*/
key: string;
}
export interface Chapter {
@@ -103,7 +111,11 @@ export interface Chapter {
fileName: string;
downloaded: boolean;
fullArchiveFilePath?: string | null;
key?: string | null;
/**
* @minLength 16
* @maxLength 64
*/
key: string;
}
export interface ChapterMangaConnectorId {
@@ -129,7 +141,11 @@ export interface ChapterMangaConnectorId {
*/
websiteUrl?: string | null;
useForDownload?: boolean;
key?: string | null;
/**
* @minLength 16
* @maxLength 64
*/
key: string;
}
export interface FileLibrary {
@@ -143,7 +159,11 @@ export interface FileLibrary {
* @maxLength 512
*/
libraryName: string;
key?: string | null;
/**
* @minLength 16
* @maxLength 64
*/
key: string;
}
export interface GotifyRecord {
@@ -167,7 +187,11 @@ export interface LibraryConnector {
* @maxLength 256
*/
auth: string;
key?: string | null;
/**
* @minLength 16
* @maxLength 64
*/
key: string;
}
export interface Link {
@@ -182,7 +206,11 @@ export interface Link {
* @maxLength 2048
*/
linkUrl: string;
key?: string | null;
/**
* @minLength 16
* @maxLength 64
*/
key: string;
}
export interface Manga {
@@ -220,7 +248,11 @@ export interface Manga {
chapterIds?: string[] | null;
idsOnMangaConnectors?: Record<string, string>;
mangaConnectorIdsIds?: string[] | null;
key?: string | null;
/**
* @minLength 16
* @maxLength 64
*/
key: string;
}
export interface MangaConnector {
@@ -270,7 +302,11 @@ export interface MangaMangaConnectorId {
*/
websiteUrl?: string | null;
useForDownload?: boolean;
key?: string | null;
/**
* @minLength 16
* @maxLength 64
*/
key: string;
}
export interface MangaTag {