From a90038f7a7a6e893b01b651fc2073afb3a63a338 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Wed, 15 Apr 2026 09:22:17 -0400 Subject: [PATCH] =?UTF-8?q?refactor(web):=20rename=20board=20column=20pend?= =?UTF-8?q?ing=20=E2=86=92=20initializing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clarifies that Submitted/Starting runs are initializing, not just pending. Also refactors run-detail to display the actual run status via runStatusDisplay instead of mapping to board columns. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/fabro-web/app/data/runs.ts | 33 +++++++++++++++++-- apps/fabro-web/app/routes/run-detail.tsx | 25 +++++++------- apps/fabro-web/app/routes/runs.tsx | 2 +- docs/api-reference/fabro-api.yaml | 2 +- lib/crates/fabro-server/src/server.rs | 12 +++---- .../src/models/board-column.ts | 2 +- 6 files changed, 50 insertions(+), 26 deletions(-) diff --git a/apps/fabro-web/app/data/runs.ts b/apps/fabro-web/app/data/runs.ts index 3356205b0..b6629cbf2 100644 --- a/apps/fabro-web/app/data/runs.ts +++ b/apps/fabro-web/app/data/runs.ts @@ -29,11 +29,11 @@ export interface RunItem { sandboxId?: string; } -export type ColumnStatus = "working" | "pending" | "review" | "merge" | "running" | "waiting" | "succeeded" | "failed"; +export type ColumnStatus = "working" | "initializing" | "review" | "merge" | "running" | "waiting" | "succeeded" | "failed"; export const columnNames: Record = { working: "Working", - pending: "Pending", + initializing: "Initializing", review: "Verify", merge: "Merge", running: "Running", @@ -108,7 +108,7 @@ export function deriveCiStatus(checks: CheckRun[]): CiStatus { export const statusColors: Record = { working: { dot: "bg-teal-500", text: "text-teal-500" }, - pending: { dot: "bg-amber", text: "text-amber" }, + initializing: { dot: "bg-amber", text: "text-amber" }, review: { dot: "bg-mint", text: "text-mint" }, merge: { dot: "bg-teal-300", text: "text-teal-300" }, running: { dot: "bg-teal-500", text: "text-teal-500" }, @@ -117,6 +117,33 @@ export const statusColors: Record = failed: { dot: "bg-coral", text: "text-coral" }, }; +export type RunStatus = + | "submitted" + | "starting" + | "running" + | "paused" + | "removing" + | "succeeded" + | "failed" + | "dead"; + +export const runStatusDisplay: Record = { + submitted: { label: "Submitted", dot: "bg-fg-muted", text: "text-fg-muted" }, + starting: { label: "Starting", dot: "bg-amber", text: "text-amber" }, + running: { label: "Running", dot: "bg-teal-500", text: "text-teal-500" }, + paused: { label: "Paused", dot: "bg-amber", text: "text-amber" }, + removing: { label: "Removing", dot: "bg-fg-muted", text: "text-fg-muted" }, + succeeded: { label: "Succeeded", dot: "bg-mint", text: "text-mint" }, + failed: { label: "Failed", dot: "bg-coral", text: "text-coral" }, + dead: { label: "Dead", dot: "bg-coral", text: "text-coral" }, +}; + +const knownRunStatuses = new Set(Object.keys(runStatusDisplay)); + +export function isRunStatus(s: string): s is RunStatus { + return knownRunStatuses.has(s); +} + export const ciConfig: Record = { passing: { label: "Passing", dot: "bg-mint", text: "text-mint" }, failing: { label: "Changes needed", dot: "bg-coral", text: "text-coral" }, diff --git a/apps/fabro-web/app/routes/run-detail.tsx b/apps/fabro-web/app/routes/run-detail.tsx index 5b4f6c163..d6ad109e5 100644 --- a/apps/fabro-web/app/routes/run-detail.tsx +++ b/apps/fabro-web/app/routes/run-detail.tsx @@ -2,8 +2,8 @@ import { useEffect } from "react"; import { ChevronDownIcon, ChevronRightIcon } from "@heroicons/react/20/solid"; import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react"; import { Link, Outlet, useFetcher, useLocation } from "react-router"; -import { columnNames, mapRunSummaryToRunItem, statusColors } from "../data/runs"; -import type { ColumnStatus, RunSummaryResponse } from "../data/runs"; +import { mapRunSummaryToRunItem, runStatusDisplay, isRunStatus } from "../data/runs"; +import type { RunSummaryResponse } from "../data/runs"; import { apiJson } from "../api"; import { useDemoMode } from "../lib/demo-mode"; import type { PreviewUrlResponse } from "@qltysh/fabro-api-client"; @@ -25,17 +25,16 @@ export async function loader({ request, params }: any) { if (!response.ok) return { run: null }; const summary: RunSummaryResponse = await response.json(); const item = mapRunSummaryToRunItem(summary); - const statusMap: Record = { - running: "working", - paused: "pending", - completed: "merge", - }; - const status = statusMap[summary.status ?? ""] ?? "working"; + const rawStatus = summary.status ?? "submitted"; + const display = isRunStatus(rawStatus) + ? runStatusDisplay[rawStatus] + : { label: rawStatus, dot: "bg-fg-muted", text: "text-fg-muted" }; return { run: { ...item, - status, - statusLabel: columnNames[status] ?? summary.status ?? "Unknown", + statusLabel: display.label, + statusDot: display.dot, + statusText: display.text, }, }; } @@ -78,8 +77,6 @@ export default function RunDetail({ loaderData, params }: any) { return

Run not found.

; } - const colors = statusColors[run.status]; - return (