80 lines
2.3 KiB
TypeScript
80 lines
2.3 KiB
TypeScript
"use client";
|
|
import { Button } from "@/components/ui/button";
|
|
import type { useFurnitureJobs } from "./use-furniture-jobs";
|
|
export function FurnitureJobHistory({
|
|
state,
|
|
}: {
|
|
state: ReturnType<typeof useFurnitureJobs>;
|
|
}) {
|
|
return (
|
|
<details className="shrink-0 border-b border-[var(--admin-border)] bg-[var(--admin-surface)] px-4 py-2 text-sm">
|
|
<summary className="cursor-pointer">
|
|
Import history ·{" "}
|
|
{
|
|
state.jobs.filter(
|
|
(j) => j.state === "queued" || j.state === "running",
|
|
).length
|
|
}{" "}
|
|
active
|
|
</summary>
|
|
<div className="max-h-72 space-y-2 overflow-auto py-2">
|
|
{state.error && <p role="alert">{state.error}</p>}
|
|
{!state.jobs.length && <p>No background imports yet.</p>}
|
|
{state.jobs.map((job) => {
|
|
const done = job.items.filter((i) => i.state === "done"),
|
|
failed = job.items.filter((i) => i.state === "failed");
|
|
return (
|
|
<details
|
|
key={job.id}
|
|
className="rounded border border-[var(--admin-border)] p-2"
|
|
>
|
|
<summary className="cursor-pointer">
|
|
{new Date(job.createdAt).toLocaleString()} · {job.state} ·{" "}
|
|
{done.length}/{job.items.length} imported · {failed.length}{" "}
|
|
failed
|
|
</summary>
|
|
<ul className="space-y-1 py-2">
|
|
{job.items.map((item) => (
|
|
<li key={item.classname}>
|
|
<strong>{item.classname}</strong> · {item.state}
|
|
{item.itemId ? ` · ID ${item.itemId}` : ""}
|
|
{item.error && (
|
|
<p className="text-[var(--admin-warning)]">
|
|
{item.error}
|
|
</p>
|
|
)}
|
|
{[...new Set(item.warnings ?? [])].map((warning) => (
|
|
<p
|
|
key={warning}
|
|
className="text-xs text-[var(--admin-text-muted)]"
|
|
>
|
|
{warning}
|
|
</p>
|
|
))}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
{failed.length > 0 && job.state !== "running" && (
|
|
<Button
|
|
variant="outline"
|
|
disabled={state.busy}
|
|
onClick={() =>
|
|
void state.submit(failed, {
|
|
sourceId: job.sourceId,
|
|
mode: job.mode,
|
|
translate: job.translate,
|
|
langs: job.langs,
|
|
})
|
|
}
|
|
>
|
|
Retry failed items only
|
|
</Button>
|
|
)}
|
|
</details>
|
|
);
|
|
})}
|
|
</div>
|
|
</details>
|
|
);
|
|
}
|