Skip to content

Add sort + filter to dashboard runs table (BEN-47)#51

Closed
benSepanski wants to merge 1 commit intomainfrom
claude/nifty-bardeen-zxl3J
Closed

Add sort + filter to dashboard runs table (BEN-47)#51
benSepanski wants to merge 1 commit intomainfrom
claude/nifty-bardeen-zxl3J

Conversation

@benSepanski
Copy link
Copy Markdown
Owner

Context

BEN-47: the runs table in src/web/Dashboard.tsx was render-only — no sort headers, no status filter, no way to narrow by issue identifier. With more than ~50 runs the dashboard becomes a Ctrl-F dance.

TL;DR

Add sortable column headers, multi-select status pills, and a free-text identifier/title filter to the dashboard runs table. State persists in the URL hash so views are reload-stable and shareable.

Summary

  • New src/web/dashboardFilters.ts — pure parseFilters / serializeFilters / applyFilters / toggleStatus / toggleSort helpers, no React deps. Unit-tested in dashboardFilters.test.ts (15 cases).
  • src/web/Dashboard.tsx — adds FilterBar (status pills + text input) and SortableHeader, sorts on Started, Finished, Turns, Tokens, Cost; default remains "started desc".
  • URL hash carries status, q, sort, dir (e.g. #/?status=failed,running&q=BEN-30&sort=cost&dir=asc), so reloads and shared links keep the view.
  • src/web/App.tsxparseHash() extracts the dashboard query string and passes it to <Dashboard />.
  • docs/FRONTEND.md — documents the new query-string convention next to the route table.

Demo

n/a — automated cron run; web UI not exercised in headless environment. Manual smoke-test journey: pnpm dev WORKFLOW.md --mock, click status pills, sort headers, and the URL hash updates; reloading restores the view.

Alternatives

  • Server-side filtering via a new /api/runs?status=... query — rejected: the current API already returns the visible runs, and client-side filtering is instant and matches the ticket's "client-side filter is fine" guidance.
  • React context for filter state — rejected: a single prop from App.tsx matches existing patterns (route.search) and avoids ambient state.
  • Virtualization (@tanstack/react-virtual) — deferred per the ticket's "only if N > ~200" note.

Test Plan

  • pnpm all — typecheck + fmt:check + lint + test + eval (135 unit + 5 eval, all green)
  • pnpm build:web — not run in this cron environment
  • New dashboardFilters.test.ts covers parse/serialize round-trip, multi-status filter, identifier and title text filter (case-insensitive), each sort key, and null-finishedAt ordering.

Generated by Claude Code

The runs table was render-only: no way to sort, narrow by status, or
hone in on a specific issue identifier. Once the DB has more than ~50
runs the dashboard becomes a Ctrl-F dance.

Filter / sort state lives in the URL hash so views are reload-stable
and shareable (e.g. `#/?status=failed&q=BEN-30`). The pure parse /
serialize / apply helpers live in `dashboardFilters.ts` and are
unit-tested independently of React.
@benSepanski benSepanski closed this May 4, 2026
@benSepanski benSepanski deleted the claude/nifty-bardeen-zxl3J branch May 4, 2026 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants