Files
EpicNext-Cms/src/components/admin/studio/furniture-jobs.tsx
T
Simo 3ae4f21217
CI / check (push) Successful in 1m40s
CI / deploy (push) Successful in 1m26s
CI / e2e (push) Successful in 24s
refactor(catalog): separate Studio data hooks and presentation
2026-09-05 18:15:29 +02:00

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>
);
}