From 300a12a4ebfc63efeea7c29a732c11e74ff4b0f8 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sat, 28 Feb 2026 14:10:50 -0500 Subject: [PATCH] Refine workflow runs list: grid layout, search, CI dots, spacing Use CSS grid with subgrid for guaranteed column alignment. Remove repo name, add PR icon, move duration next to status, show CI as dot next to PR number, add typeahead search. Reverse sort (Merge first). Co-Authored-By: Claude Opus 4.6 --- apps/arc-web/app/data/runs.ts | 2 +- apps/arc-web/app/routes/workflow-runs.tsx | 103 +++++++++++++--------- 2 files changed, 62 insertions(+), 43 deletions(-) diff --git a/apps/arc-web/app/data/runs.ts b/apps/arc-web/app/data/runs.ts index 0348a812f..875c7cff9 100644 --- a/apps/arc-web/app/data/runs.ts +++ b/apps/arc-web/app/data/runs.ts @@ -157,7 +157,7 @@ export const columns: { ]; export function allRunsFlat(): RunWithStatus[] { - return columns.flatMap((col) => + return [...columns].reverse().flatMap((col) => col.items.map((item) => ({ ...item, status: col.id, diff --git a/apps/arc-web/app/routes/workflow-runs.tsx b/apps/arc-web/app/routes/workflow-runs.tsx index bca224957..9666310a0 100644 --- a/apps/arc-web/app/routes/workflow-runs.tsx +++ b/apps/arc-web/app/routes/workflow-runs.tsx @@ -1,71 +1,90 @@ +import { useState } from "react"; +import { MagnifyingGlassIcon } from "@heroicons/react/24/outline"; import { allRunsFlat, ciConfig, statusColors } from "../data/runs"; -import type { CiStatus, RunWithStatus } from "../data/runs"; +import type { RunWithStatus } from "../data/runs"; const runs = allRunsFlat(); -function CiBadge({ status }: { status: CiStatus }) { - const config = ciConfig[status]; +function GitPullRequestIcon({ className }: { className?: string }) { return ( - - - {config.label} - + ); } function RunRow({ run }: { run: RunWithStatus }) { const colors = statusColors[run.status]; return ( -
- +
+ {run.statusLabel} - - {run.repo} - {run.number != null && ( - #{run.number} + + {run.elapsed} + + + + {run.title} + {run.comments != null && run.comments > 0 && ( + + + {run.comments} + )} - {run.title} + + {run.additions != null && +{run.additions.toLocaleString()}} + {run.deletions != null && -{run.deletions.toLocaleString()}} + - {run.additions != null && run.deletions != null && ( - - +{run.additions.toLocaleString()} - -{run.deletions.toLocaleString()} - - )} - - {run.ci != null && ( - - - - )} - - {run.comments != null && run.comments > 0 && ( - - - {run.comments} - - )} - - - {run.elapsed} + + {run.number != null && ( + <> + + #{run.number} + {run.ci != null && } + + )}
); } export default function WorkflowRuns() { + const [query, setQuery] = useState(""); + const filtered = runs.filter( + (r) => + r.title.toLowerCase().includes(query.toLowerCase()) || + r.statusLabel.toLowerCase().includes(query.toLowerCase()) || + (r.number != null && `#${r.number}`.includes(query)), + ); + return ( -
- {runs.map((run) => ( - - ))} +
+
+ + setQuery(e.target.value)} + className="w-full rounded-lg border border-white/[0.06] bg-navy-800/80 py-2 pl-9 pr-3 text-sm text-ice-100 placeholder-navy-600 outline-none transition-colors focus:border-teal-500/40 focus:ring-0" + /> +
+
+ {filtered.map((run) => ( + + ))} + {filtered.length === 0 && ( +

No runs match "{query}"

+ )} +
); }