fix(activity): an old audit/log link opens its tab, times read relative, one name for admin actions

Seen in the browser, not in the page's own tests: the navigation provider rewrites a retired page id
to `activity` before the page's chunk reads the URL, so `?page=audit` landed on the Runs tab. The
retired-page map now carries the params that open the successor's part (`at`), and the provider
writes them as it rewrites the page — on load and on Back alike.

A list time is relative with the exact second on hover (the DESIGN copy rule); a run moved over from
the audit log, whose start and end are one instant, shows no length instead of an invented "1 sec".
The audit log is called "admin actions" everywhere it is named (the clear button and its confirm, the
Configuration group, the cleanup job, which also prunes the run history its description left out).
This commit is contained in:
2026-10-18 04:00:38 +02:00
parent fe6308d844
commit c288ba147b
18 changed files with 133 additions and 92 deletions
+12 -7
View File
@@ -7,7 +7,7 @@ import { api, type AuditQuery, type AuditRow } from "../lib/api";
import { notifyActionError } from "../lib/actionErrors";
import { sinceOf } from "../lib/activityUrlState";
import { auditActionLabel, auditText } from "../lib/auditText";
import { formatDateTime, formatDateTimeSec } from "../lib/format";
import { formatDateTimeSec } from "../lib/format";
import { notify } from "../lib/notifications";
import { qk } from "../lib/queryKeys";
import { useHistoryList } from "../lib/useHistoryList";
@@ -15,6 +15,7 @@ import type { Shared } from "./ActivityRuns";
import { useConfirm } from "./confirmContext";
import HistoryList from "./HistoryList";
import HistoryRow from "./HistoryRow";
import { RelativeTime } from "./ui/RelativeTime";
import { Button } from "./ui/Button";
import FilterSelect from "./ui/FilterSelect";
@@ -134,17 +135,21 @@ export default function ActivityAudit({
cells={
<>
<span className="truncate font-medium">{auditActionLabel(t, row.action)}</span>
<span className="tabular-nums text-muted sm:hidden">
{formatDateTime(row.created_at, lang)}
</span>
<RelativeTime
at={row.created_at}
seconds
className="tabular-nums text-muted sm:hidden"
/>
<span
className={`hidden truncate sm:block ${who ? "text-muted" : "italic text-muted"}`}
>
{who ?? t("audit.system")}
</span>
<span className="hidden tabular-nums text-muted sm:block">
{formatDateTime(row.created_at, lang)}
</span>
<RelativeTime
at={row.created_at}
seconds
className="hidden tabular-nums text-muted sm:block"
/>
<span className="col-span-2 truncate text-muted sm:col-span-1">
{[head, sub].filter(Boolean).join(" · ")}
</span>