feat(cms): improve catalog, editorial recovery and operations
This commit is contained in:
1 parent
2fead134e6
commit
c389c3893d
122 files changed
+8137
-703
No files matched your search
@@ -1,5 +1,7 @@
|
||||
"use client";
|
||||
import Link from "next/link";
|
||||
import { useFormatter, useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { retryableJobItems } from "@/lib/furni/import-job-retry";
|
||||
import type { useFurnitureJobs } from "./use-furniture-jobs";
|
||||
@@ -10,6 +12,7 @@ export function FurnitureJobHistory({
|
||||
}) {
|
||||
const t = useTranslations("pages.admin.importHistory");
|
||||
const format = useFormatter();
|
||||
const [limits, setLimits] = useState<Record<string, number>>({});
|
||||
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">
|
||||
@@ -21,6 +24,12 @@ export function FurnitureJobHistory({
|
||||
</summary>
|
||||
<div className="max-h-72 space-y-2 overflow-auto py-2">
|
||||
{state.error && <p role="alert">{state.error}</p>}
|
||||
<p className="text-xs text-[var(--admin-text-muted)]">
|
||||
{t("historyLimit")}
|
||||
</p>
|
||||
<Button variant="outline" onClick={() => void state.refresh()}>
|
||||
{t("refreshHistory")}
|
||||
</Button>
|
||||
{!state.jobs.length && <p>{t("empty")}</p>}
|
||||
{state.jobs.map((job) => {
|
||||
const retryItems = retryableJobItems(job);
|
||||
@@ -50,7 +59,7 @@ export function FurnitureJobHistory({
|
||||
aria-label={t("progress")}
|
||||
/>
|
||||
<ul className="space-y-1 py-2">
|
||||
{job.items.map((item) => (
|
||||
{job.items.slice(0, limits[job.id] ?? 50).map((item) => (
|
||||
<li key={item.classname}>
|
||||
<strong>{item.classname}</strong> · {t(item.state)}
|
||||
{item.itemId ? ` · ID ${item.itemId}` : ""}
|
||||
@@ -70,6 +79,46 @@ export function FurnitureJobHistory({
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{job.items.length > (limits[job.id] ?? 50) && (
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() =>
|
||||
setLimits((current) => ({
|
||||
...current,
|
||||
[job.id]: (current[job.id] ?? 50) + 50,
|
||||
}))
|
||||
}
|
||||
>
|
||||
{t("showMoreItems")}
|
||||
</Button>
|
||||
)}
|
||||
{(job.state === "queued" || job.state === "running") && (
|
||||
<div className="space-y-2 py-2">
|
||||
<p className="text-xs text-[var(--admin-text-muted)]">
|
||||
{t(job.cancelRequested ? "cancelRequested" : "cancelHint")}
|
||||
</p>
|
||||
<Button
|
||||
variant="outline"
|
||||
disabled={state.cancelling !== null || job.cancelRequested}
|
||||
onClick={() => void state.cancel(job.id)}
|
||||
>
|
||||
{t("cancelRemaining")}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{job.items.some(
|
||||
(item) =>
|
||||
item.state === "interrupted" ||
|
||||
item.error?.startsWith("Server restarted during import.") ||
|
||||
(item.state === "running" && job.state === "interrupted"),
|
||||
) && (
|
||||
<p role="alert" className="py-2 text-[var(--admin-warning)]">
|
||||
{t("uncertainOutcome")}{" "}
|
||||
<Link href="/admin/studio/audit" className="underline">
|
||||
{t("reviewLocalData")}
|
||||
</Link>
|
||||
</p>
|
||||
)}
|
||||
{retryItems.length > 0 && (
|
||||
<Button
|
||||
variant="outline"
|
||||
@@ -84,7 +133,7 @@ export function FurnitureJobHistory({
|
||||
}
|
||||
>
|
||||
{t(
|
||||
job.state === "interrupted"
|
||||
job.state === "interrupted" || job.state === "cancelled"
|
||||
? "retryUnfinished"
|
||||
: "retryFailed",
|
||||
)}
|
||||
|
||||
Reference in new issue
Block a user