fix(webui): collapse automation run history by default

This commit is contained in:
chengyongru 2026-06-15 21:03:48 +08:00
parent 85a3ff1372
commit acf408ced2
11 changed files with 57 additions and 74 deletions

View File

@ -3965,67 +3965,64 @@ function AutomationRunHistory({
tx: (key: string, fallback: string, values?: Record<string, unknown>) => string; tx: (key: string, fallback: string, values?: Record<string, unknown>) => string;
}) { }) {
if (!history.length) return null; if (!history.length) return null;
const visible = expanded ? [...history].reverse() : history.slice(-4).reverse(); const visible = [...history].reverse();
const hiddenCount = history.length - visible.length;
return ( return (
<section className="rounded-[18px] bg-muted/32 px-3 py-3"> <section className="rounded-[18px] bg-muted/32 px-3 py-3">
<div className="mb-3 flex items-center justify-between gap-3"> <button
<h4 className="text-[12px] font-medium leading-none text-foreground"> type="button"
className="flex w-full items-center justify-between gap-3 text-left"
aria-expanded={expanded}
onClick={() => onExpandedChange(!expanded)}
>
<span className="text-[12px] font-medium leading-none text-foreground">
{tx("settings.automations.history.timeline", "Run history")} {tx("settings.automations.history.timeline", "Run history")}
</h4>
<span className="text-[11px] leading-none text-muted-foreground tabular-nums">
{history.length}
</span> </span>
</div> <span className="inline-flex items-center gap-2 text-[11px] leading-none text-muted-foreground">
<div className="space-y-2"> <span className="tabular-nums">{history.length}</span>
{visible.map((run) => { <ChevronDown
const status = automationRunStatusLabel(run.status, tx); className={cn("h-3.5 w-3.5 transition-transform", expanded && "rotate-180")}
const duration = run.duration_ms === undefined aria-hidden
? null />
: formatAutomationRunDuration(run.duration_ms, locale, tx); </span>
return ( </button>
<div {expanded ? (
key={`${run.run_at_ms}:${run.status}:${run.duration_ms ?? "none"}`} <div className="mt-3 space-y-2">
className="grid grid-cols-[auto_minmax(0,1fr)_auto] items-start gap-2 rounded-[14px] bg-background/62 px-3 py-2" {visible.map((run) => {
> const status = automationRunStatusLabel(run.status, tx);
<span const duration = run.duration_ms === undefined
className={cn("mt-1.5 h-1.5 w-1.5 rounded-full", automationRunDotClass(run.status))} ? null
aria-hidden : formatAutomationRunDuration(run.duration_ms, locale, tx);
/> return (
<span className="min-w-0"> <div
key={`${run.run_at_ms}:${run.status}:${run.duration_ms ?? "none"}`}
className="grid grid-cols-[auto_minmax(0,1fr)_auto] items-start gap-2 rounded-[14px] bg-background/62 px-3 py-2"
>
<span <span
className="block line-clamp-2 text-[12.5px] leading-5 text-foreground/82" className={cn("mt-1.5 h-1.5 w-1.5 rounded-full", automationRunDotClass(run.status))}
title={run.error ?? undefined} aria-hidden
> />
{status} <span className="min-w-0">
{run.error ? ` · ${run.error}` : ""} <span
className="block line-clamp-2 text-[12.5px] leading-5 text-foreground/82"
title={run.error ?? undefined}
>
{status}
{run.error ? ` · ${run.error}` : ""}
</span>
<span className="block truncate text-[11.5px] leading-4 text-muted-foreground">
{fmtDateTime(run.run_at_ms, locale)}
</span>
</span> </span>
<span className="block truncate text-[11.5px] leading-4 text-muted-foreground"> {duration ? (
{fmtDateTime(run.run_at_ms, locale)} <span className="rounded-full bg-muted px-2 py-0.5 text-[11px] leading-4 text-muted-foreground">
</span> {duration}
</span> </span>
{duration ? ( ) : null}
<span className="rounded-full bg-muted px-2 py-0.5 text-[11px] leading-4 text-muted-foreground"> </div>
{duration} );
</span> })}
) : null} </div>
</div>
);
})}
</div>
{history.length > 4 ? (
<button
type="button"
className="mt-3 inline-flex text-[12px] font-medium text-muted-foreground underline-offset-2 hover:text-foreground hover:underline"
onClick={() => onExpandedChange(!expanded)}
>
{expanded
? tx("settings.automations.history.showRecent", "Show recent runs")
: tx("settings.automations.history.showMore", "Show {{count}} more", {
count: hiddenCount,
})}
</button>
) : null} ) : null}
</section> </section>
); );

View File

@ -582,8 +582,6 @@
"skipped": "Skipped", "skipped": "Skipped",
"recent": "Last result", "recent": "Last result",
"timeline": "Run history", "timeline": "Run history",
"showMore": "Show {{count}} more",
"showRecent": "Show recent runs",
"statusWithDuration": "{{status}} · {{duration}}" "statusWithDuration": "{{status}} · {{duration}}"
}, },
"message": { "message": {

View File

@ -582,8 +582,6 @@
"skipped": "Omitida", "skipped": "Omitida",
"recent": "Último resultado", "recent": "Último resultado",
"timeline": "Historial de ejecuciones", "timeline": "Historial de ejecuciones",
"showMore": "Mostrar {{count}} más",
"showRecent": "Mostrar ejecuciones recientes",
"statusWithDuration": "{{status}} · {{duration}}" "statusWithDuration": "{{status}} · {{duration}}"
}, },
"message": { "message": {

View File

@ -582,8 +582,6 @@
"skipped": "Ignorée", "skipped": "Ignorée",
"recent": "Dernier résultat", "recent": "Dernier résultat",
"timeline": "Historique dexécution", "timeline": "Historique dexécution",
"showMore": "Afficher {{count}} de plus",
"showRecent": "Afficher les exécutions récentes",
"statusWithDuration": "{{status}} · {{duration}}" "statusWithDuration": "{{status}} · {{duration}}"
}, },
"message": { "message": {

View File

@ -582,8 +582,6 @@
"skipped": "Dilewati", "skipped": "Dilewati",
"recent": "Hasil terakhir", "recent": "Hasil terakhir",
"timeline": "Riwayat eksekusi", "timeline": "Riwayat eksekusi",
"showMore": "Tampilkan {{count}} lagi",
"showRecent": "Tampilkan eksekusi terbaru",
"statusWithDuration": "{{status}} · {{duration}}" "statusWithDuration": "{{status}} · {{duration}}"
}, },
"message": { "message": {

View File

@ -582,8 +582,6 @@
"skipped": "スキップ", "skipped": "スキップ",
"recent": "最新結果", "recent": "最新結果",
"timeline": "実行履歴", "timeline": "実行履歴",
"showMore": "さらに {{count}} 件表示",
"showRecent": "最近の実行のみ表示",
"statusWithDuration": "{{status}} · {{duration}}" "statusWithDuration": "{{status}} · {{duration}}"
}, },
"message": { "message": {

View File

@ -582,8 +582,6 @@
"skipped": "건너뜀", "skipped": "건너뜀",
"recent": "최근 결과", "recent": "최근 결과",
"timeline": "실행 기록", "timeline": "실행 기록",
"showMore": "{{count}}개 더 보기",
"showRecent": "최근 실행만 보기",
"statusWithDuration": "{{status}} · {{duration}}" "statusWithDuration": "{{status}} · {{duration}}"
}, },
"message": { "message": {

View File

@ -582,8 +582,6 @@
"skipped": "Đã bỏ qua", "skipped": "Đã bỏ qua",
"recent": "Kết quả gần nhất", "recent": "Kết quả gần nhất",
"timeline": "Lịch sử chạy", "timeline": "Lịch sử chạy",
"showMore": "Hiển thị thêm {{count}}",
"showRecent": "Chỉ hiển thị lần chạy gần đây",
"statusWithDuration": "{{status}} · {{duration}}" "statusWithDuration": "{{status}} · {{duration}}"
}, },
"message": { "message": {

View File

@ -582,8 +582,6 @@
"skipped": "已跳过", "skipped": "已跳过",
"recent": "最近结果", "recent": "最近结果",
"timeline": "运行记录", "timeline": "运行记录",
"showMore": "再显示 {{count}} 条",
"showRecent": "只看最近记录",
"statusWithDuration": "{{status}} · {{duration}}" "statusWithDuration": "{{status}} · {{duration}}"
}, },
"message": { "message": {

View File

@ -582,8 +582,6 @@
"skipped": "已略過", "skipped": "已略過",
"recent": "最近結果", "recent": "最近結果",
"timeline": "執行記錄", "timeline": "執行記錄",
"showMore": "再顯示 {{count}} 筆",
"showRecent": "只看最近記錄",
"statusWithDuration": "{{status}} · {{duration}}" "statusWithDuration": "{{status}} · {{duration}}"
}, },
"message": { "message": {

View File

@ -629,9 +629,13 @@ describe("App layout", () => {
expect(message!).not.toHaveClass("line-clamp-6"); expect(message!).not.toHaveClass("line-clamp-6");
expect(screen.queryByText(/oldest failure/)).not.toBeInTheDocument(); expect(screen.queryByText(/oldest failure/)).not.toBeInTheDocument();
fireEvent.click(within(detailPanel).getByRole("button", { name: "Show 2 more" })); const historyToggle = within(detailPanel).getByRole("button", { name: /Run history/ });
expect(historyToggle).toHaveAttribute("aria-expanded", "false");
fireEvent.click(historyToggle);
expect(historyToggle).toHaveAttribute("aria-expanded", "true");
expect(screen.getAllByText(/oldest failure/)).toHaveLength(2); expect(screen.getAllByText(/oldest failure/)).toHaveLength(2);
fireEvent.click(within(detailPanel).getByRole("button", { name: "Show recent runs" })); fireEvent.click(historyToggle);
expect(historyToggle).toHaveAttribute("aria-expanded", "false");
expect(screen.queryByText(/oldest failure/)).not.toBeInTheDocument(); expect(screen.queryByText(/oldest failure/)).not.toBeInTheDocument();
}); });