Make Duration sortable on the runs page

It was left out because duration isn't a stored column, just
started_at/ended_at math - now expressed as a SQL case expression so it
can be sorted the same way as the other columns. Still-running rows
sort by elapsed-so-far; never-started (queued) rows sort as NULL, which
puts them out of the way at whichever end matches the current
direction.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-16 00:20:06 +02:00
co-authored by Claude Sonnet 5
parent 3131d8ce5b
commit 3f656baad1
+8 -1
View File
@@ -23,11 +23,18 @@ export const metadata: Metadata = { title: "Run History" };
const PAGE_SIZE = 25;
// Duration isn't a stored column - it's derived from started_at/ended_at (both unix seconds), so
// it needs a SQL expression rather than a plain column reference to be sortable. Still-running
// rows (ended_at IS NULL) count as elapsed-so-far; never-started (queued) rows sort as NULL,
// which SQLite puts first in ASC / last in DESC - keeping them out of the way either direction.
const durationExpr = sql`case when ${runs.startedAt} is null then null else coalesce(${runs.endedAt}, unixepoch()) - ${runs.startedAt} end`;
const SORT_COLUMNS = {
script: runs.scriptName,
status: runs.status,
triggeredBy: runs.triggeredBy,
started: runs.startedAt,
duration: durationExpr,
} as const;
type SortKey = keyof typeof SORT_COLUMNS;
const DEFAULT_SORT: SortKey = "started";
@@ -172,7 +179,7 @@ export default async function RunsPage({ searchParams }: RunsPageProps) {
<TableHead>{sortHeader("status", "Status")}</TableHead>
<TableHead>{sortHeader("triggeredBy", "Triggered by")}</TableHead>
<TableHead>{sortHeader("started", "Started")}</TableHead>
<TableHead>Duration</TableHead>
<TableHead>{sortHeader("duration", "Duration")}</TableHead>
</TableRow>
</TableHeader>
<TableBody>