🏗️ Refactored Import socket events

This commit is contained in:
2023-12-06 21:56:58 -06:00
parent a068b82db3
commit 026d5832c5
3 changed files with 113 additions and 102 deletions

View File

@@ -53,25 +53,6 @@ export const Import = (props: IProps): ReactElement => {
}),
});
// 1a. Act on each comic issue successfully imported/failed, as indicated
// by the LS_COVER_EXTRACTED/LS_COVER_EXTRACTION_FAILED events
socketIOInstance.on("LS_COVER_EXTRACTED", (data) => {
const { completedJobCount, importResult } = data;
importJobQueue.setJobCount("successful", completedJobCount);
importJobQueue.setMostRecentImport(importResult.rawFileDetails.name);
});
socketIOInstance.on("LS_COVER_EXTRACTION_FAILED", (data) => {
const { failedJobCount } = data;
importJobQueue.setJobCount("failed", failedJobCount);
});
// 1b. Clear the localStorage sessionId upon receiving the
// LS_IMPORT_QUEUE_DRAINED event
socketIOInstance.on("LS_IMPORT_QUEUE_DRAINED", (data) => {
localStorage.removeItem("sessionId");
importJobQueue.setStatus("drained");
queryClient.invalidateQueries({ queryKey: ["allImportJobResults"] });
});
const toggleQueue = (queueAction: string, queueStatus: string) => {
socketIOInstance.emit(
"call",
@@ -94,29 +75,35 @@ export const Import = (props: IProps): ReactElement => {
switch (status) {
case "running":
return (
<div className="control">
<div>
<button
className="button is-warning is-light"
className="flex space-x-1 sm:mt-0 sm:flex-row sm:items-center rounded-lg border border-green-400 dark:border-green-200 bg-green-200 px-3 py-1 text-gray-500 hover:bg-transparent hover:text-green-600 focus:outline-none focus:ring active:text-indigo-500"
onClick={() => {
toggleQueue("pause", "paused");
importJobQueue.setStatus("paused");
}}
>
<i className="fa-solid fa-pause mr-2"></i> Pause
<span className="text-md">Pause</span>
<span className="w-5 h-5">
<i className="h-5 w-5 icon-[solar--pause-bold]"></i>
</span>
</button>
</div>
);
case "paused":
return (
<div className="control">
<div>
<button
className="button is-success is-light"
className="flex space-x-1 sm:mt-0 sm:flex-row sm:items-center rounded-lg border border-green-400 dark:border-green-200 bg-green-200 px-3 py-1 text-gray-500 hover:bg-transparent hover:text-green-600 focus:outline-none focus:ring active:text-indigo-500"
onClick={() => {
toggleQueue("resume", "running");
importJobQueue.setStatus("running");
}}
>
<i className="fa-solid fa-play mr-2"></i> Resume
<span className="text-md">Resume</span>
<span className="w-5 h-5">
<i className="h-5 w-5 icon-[solar--play-bold]"></i>
</span>
</button>
</div>
);
@@ -132,7 +119,7 @@ export const Import = (props: IProps): ReactElement => {
<div>
<section>
<header className="bg-slate-200 dark:bg-slate-500">
<div className="mx-auto max-w-screen-xl px-2 py-2 sm:px-6 sm:py-12 lg:px-8">
<div className="mx-auto max-w-screen-xl px-2 py-2 sm:px-6 sm:py-8 lg:px-8 lg:py-4">
<div className="sm:flex sm:items-center sm:justify-between">
<div className="text-center sm:text-left">
<h1 className="text-2xl font-bold text-gray-900 dark:text-white sm:text-3xl">
@@ -143,25 +130,16 @@ export const Import = (props: IProps): ReactElement => {
Import comics into the ThreeTwo library.
</p>
</div>
<div className="mt-4 flex flex-col gap-4 sm:mt-0 sm:flex-row sm:items-center">
<button
className="block rounded-lg bg-indigo-600 px-5 py-3 text-sm font-medium text-white transition hover:bg-indigo-700 focus:outline-none focus:ring"
type="button"
>
Create Post
</button>
</div>
</div>
</div>
</header>
<div className="mx-auto max-w-screen-xl px-4 py-4 sm:px-6 sm:py-12 lg:px-8">
<div className="mx-auto max-w-screen-xl px-4 py-4 sm:px-6 sm:py-8 lg:px-8">
<article
role="alert"
className="rounded-lg max-w-screen-md border-s-4 border-blue-500 bg-blue-50 p-4 dark:border-s-4 dark:border-blue-600 dark:bg-blue-300 dark:text-slate-600"
>
<div className="message-body">
<div>
<p>
Importing will add comics identified from the mapped folder into
ThreeTwo's database.
@@ -195,78 +173,73 @@ export const Import = (props: IProps): ReactElement => {
<span>Start Import</span>
</button>
</p> */}
<div className="mt-4">
<button
className="flex space-x-1 sm:mt-0 sm:flex-row sm:items-center rounded-lg border border-green-600 bg-green-300 px-5 py-3 text-gray-500 hover:bg-transparent hover:text-green-600 focus:outline-none focus:ring active:text-indigo-500"
onClick={() => {
initiateImport();
importJobQueue.setStatus("running");
}}
>
<span className="text-md">Start Import</span>
<span className="w-6 h-6">
<i className="h-6 w-6 icon-[solar--file-left-bold-duotone]"></i>
</span>
</button>
<div className="my-4">
{importJobQueue.status === "drained" ||
(importJobQueue.status === undefined && (
<button
className="flex space-x-1 sm:mt-0 sm:flex-row sm:items-center rounded-lg border border-green-400 dark:border-green-200 bg-green-200 px-5 py-3 text-gray-500 hover:bg-transparent hover:text-green-600 focus:outline-none focus:ring active:text-indigo-500"
onClick={() => {
initiateImport();
importJobQueue.setStatus("running");
}}
>
<span className="text-md">Start Import</span>
<span className="w-6 h-6">
<i className="h-6 w-6 icon-[solar--file-left-bold-duotone]"></i>
</span>
</button>
))}
</div>
{importJobQueue.status !== "drained" &&
!isUndefined(importJobQueue.status) && (
<div className="mt-4">
<table className="table">
<thead>
<tr>
<th>Completed Jobs</th>
<th>Failed Jobs</th>
<th>Queue Controls</th>
<th>Queue Status</th>
</tr>
</thead>
{/* Activity */}
{(importJobQueue.status === "running" ||
importJobQueue.status === "paused") && (
<>
<span className="flex items-center my-5 max-w-screen-lg">
<span className="text-xl text-slate-500 dark:text-slate-200 pr-5">
Import Activity
</span>
<span className="h-px flex-1 bg-slate-200 dark:bg-slate-400"></span>
</span>
<div className="mt-5 flex flex-col gap-4 sm:mt-0 sm:flex-row sm:items-center">
<dl className="grid grid-cols-2 gap-4 sm:grid-cols-2">
{/* Successful import counts */}
<div className="flex flex-col rounded-lg bg-green-100 dark:bg-green-200 px-4 py-6 text-center">
<dd className="text-3xl text-green-600 md:text-5xl">
{importJobQueue.successfulJobCount}
</dd>
<dt className="text-lg font-medium text-gray-500">
imported
</dt>
</div>
{/* Failed job counts */}
<div className="flex flex-col rounded-lg bg-red-100 dark:bg-red-200 px-4 py-6 text-center">
<dd className="text-3xl text-red-600 md:text-5xl">
{importJobQueue.failedJobCount}
</dd>
<dt className="text-lg font-medium text-gray-500">
failed
</dt>
</div>
<tbody>
<tr>
<th>
{importJobQueue.successfulJobCount > 0 && (
<div className="box has-background-success-light has-text-centered">
<span className="is-size-2 has-text-weight-bold">
{importJobQueue.successfulJobCount}
</span>
</div>
)}
</th>
<td>
{importJobQueue.failedJobCount > 0 && (
<div className="box has-background-danger has-text-centered">
<span className="is-size-2 has-text-weight-bold">
{importJobQueue.failedJobCount}
</span>
</div>
)}
</td>
<td>{renderQueueControls(importJobQueue.status)}</td>
<td>
{importJobQueue.status !== undefined ? (
<span className="tag is-warning">
{importJobQueue.status}
</span>
) : null}
</td>
</tr>
</tbody>
</table>
Imported{" "}
<span className="has-text-weight-bold">
{importJobQueue.mostRecentImport}
<div className="flex flex-col dark:text-slate-200 text-slate-400">
<dd>{renderQueueControls(importJobQueue.status)}</dd>
</div>
</dl>
</div>
<div className="flex">
<span className="mt-2 dark:text-slate-200 text-slate-400">
Imported: <span>{importJobQueue.mostRecentImport}</span>
</span>
</div>
)}
</>
)}
{/* Past imports */}
{!isLoading && !isEmpty(data?.data) && (
<div className="max-w-screen-lg">
<span className="flex items-center mt-6">
<span className="text-xl dark:text-slate-200 pr-5">
<span className="text-xl text-slate-500 dark:text-slate-200 pr-5">
Past Imports
</span>
<span className="h-px flex-1 bg-slate-200 dark:bg-slate-400"></span>

View File

@@ -76,15 +76,15 @@ export const Navbar2 = (): ReactElement => {
<ul className="flex items-center gap-6 text-md">
{/* Settings Icon and text */}
<li>
<a
href="#"
<Link
to="/settings"
className="flex items-center space-x-1 text-gray-500 transition hover:text-gray-500/75 dark:text-white dark:hover:text-white/75"
>
<span className="w-5 h-5">
<i className="icon-[solar--settings-outline] h-5 w-5"></i>
</span>
<span>Settings</span>
</a>
</Link>
</li>
<li>

View File

@@ -5,6 +5,7 @@ import { SOCKET_BASE_URI } from "../constants/endpoints";
import { produce } from "immer";
import AirDCPPSocket from "../services/DcppSearchService";
import axios from "axios";
import { QueryClient } from "@tanstack/react-query";
/* Broadly, this file sets up:
* 1. The zustand-based global client state
@@ -69,6 +70,7 @@ export const useStore = create((set, get) => ({
}));
const { getState, setState } = useStore;
const queryClient = new QueryClient();
/** Socket.IO initialization **/
// 1. Fetch sessionId from localStorage
@@ -115,6 +117,42 @@ socketIOInstance.on("RESTORE_JOB_COUNTS_AFTER_SESSION_RESTORATION", (data) => {
}));
});
// 1a. Act on each comic issue successfully imported/failed, as indicated
// by the LS_COVER_EXTRACTED/LS_COVER_EXTRACTION_FAILED events
socketIOInstance.on("LS_COVER_EXTRACTED", (data) => {
const { completedJobCount, importResult } = data;
setState((state) => ({
importJobQueue: {
...state.importJobQueue,
successfulJobCount: completedJobCount,
mostRecentImport: importResult.rawFileDetails.name,
},
}));
});
socketIOInstance.on("LS_COVER_EXTRACTION_FAILED", (data) => {
const { failedJobCount } = data;
setState((state) => ({
importJobQueue: {
...state.importJobQueue,
failedJobCount,
},
}));
});
// 1b. Clear the localStorage sessionId upon receiving the
// LS_IMPORT_QUEUE_DRAINED event
socketIOInstance.on("LS_IMPORT_QUEUE_DRAINED", (data) => {
localStorage.removeItem("sessionId");
setState((state) => ({
importJobQueue: {
...state.importJobQueue,
status: "drained",
},
}));
console.log("a", queryClient);
queryClient.invalidateQueries({ queryKey: ["allImportJobResults"] });
});
/**
* Method to init AirDC++ Socket with supplied settings
* @param configuration - credentials, and hostname details to init AirDC++ connection