feat(board): stall highlight + Sort: stall + Stalled filter chip (B8) #424

Merged
code-lead merged 1 commit from dev/416 into main 2026-04-27 01:21:12 +00:00
Collaborator

Adds stall-awareness to the planner board so operators spot rotting cards before they're missed.

stalled_for_ms added to BoardCard (type + server). Card borders turn border-warning at per-stage threshold and border-error + clock icon at 2×; transition-colors prevents flicker. Per-column Sort: age | stall toggle (localStorage-persisted). Toolbar Stalled (N) chip filters to only stalled cards, combines AND with existing chips, persists as ?stalled=true; dimmed + inert when N = 0.

Test plan

  • board-card.test.tsx — no ring below threshold; border-warning at threshold; border-error + clock icon at 2× threshold (idle_assigned, running, in_review).
  • board-column.test.tsx — Sort: stall reorders within each status bucket by stalled_for_ms desc; Sort: age restores server order.
  • board.test.tsxStalled (N) chip shows count; disabled/no-op at 0; click toggles only_stalled; filter hides non-stalled cards; count respects repo filter.
  • filter-logic.test.tsisCardStalled, countStalledCards, only_stalled AND-combine with repo filter.
  • All 475 web + 2010 server tests green.

Closes #416

Adds stall-awareness to the planner board so operators spot rotting cards before they're missed. `stalled_for_ms` added to `BoardCard` (type + server). Card borders turn `border-warning` at per-stage threshold and `border-error` + clock icon at 2×; `transition-colors` prevents flicker. Per-column `Sort: age | stall` toggle (localStorage-persisted). Toolbar `Stalled (N)` chip filters to only stalled cards, combines AND with existing chips, persists as `?stalled=true`; dimmed + inert when N = 0. ## Test plan - `board-card.test.tsx` — no ring below threshold; `border-warning` at threshold; `border-error` + clock icon at 2× threshold (idle_assigned, running, in_review). - `board-column.test.tsx` — Sort: stall reorders within each status bucket by `stalled_for_ms` desc; Sort: age restores server order. - `board.test.tsx` — `Stalled (N)` chip shows count; disabled/no-op at 0; click toggles `only_stalled`; filter hides non-stalled cards; count respects repo filter. - `filter-logic.test.ts` — `isCardStalled`, `countStalledCards`, `only_stalled` AND-combine with repo filter. - All 475 web + 2010 server tests green. Closes #416
feat(board): stall highlight (warning/error) + Sort: stall + Stalled filter chip (B8)
All checks were successful
qa / qa (pull_request) Successful in 7m5s
qa / dockerfile (pull_request) Successful in 8s
ba47b14382
Adds stall-awareness to the planner board:

- `stalled_for_ms` field added to `BoardCard` (shared type + server)
- Card border turns `border-warning` at per-stage threshold, `border-error`
  + clock icon at 2× threshold; transitions via existing `transition-colors`
- Per-column `Sort: age | stall` toggle sorts cards by `stalled_for_ms` desc
  within each status group; persists in `localStorage` per column
- Toolbar `Stalled (N)` chip filters to only stalled cards; combines AND
  with repo/milestone/label/unassigned; URL-persisted as `?stalled=true`;
  dimmed + inert when N === 0

Thresholds mirror docs/label-routing.md: running/queued = 30 min,
in_review/idle_assigned/unassigned = 10 min.

Tests: board-card.test.tsx (stall rings + clock icon), board-column.test.tsx
(stall sort), board.test.tsx (Stalled chip), filter-logic.test.ts (stall filter helpers).

Closes #416

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dev requested review from reviewer 2026-04-27 01:17:18 +00:00
reviewer approved these changes 2026-04-27 01:20:34 +00:00
reviewer left a comment

All AC from #416 verified. CI green.

  • stallBorderClass() correctly gates border-warning at threshold and border-error at 2×; ClockIcon renders when isDoubleStalled; transition-colors prevents flicker ✓
  • Sort toggle persists per-column via board.sort.<type> localStorage key; stall sort applies b.stalled_for_ms - a.stalled_for_ms within each status bucket, not across buckets ✓
  • Stalled chip count computed against { ...filters, only_stalled: false } so it reflects the current repo/milestone/label scope (not the already-filtered view); disabled + opacity-40 at N=0; ?stalled=true URL persistence wired correctly in handleFilterChange
  • stalled_for_ms added to shared type with JSDoc and all four card construction sites on the server ✓
  • Test coverage complete across all three required files plus filter-logic.test.ts

Nit: STALL_THRESHOLD_BY_STATUS.queued (30 min) is dead — the server hardcodes stalled_for_ms: 0 for queued cards (no queue-entry timestamp available). Fine to leave as self-documenting intent for a future follow-up.

All AC from #416 verified. CI green. - `stallBorderClass()` correctly gates `border-warning` at threshold and `border-error` at 2×; `ClockIcon` renders when `isDoubleStalled`; `transition-colors` prevents flicker ✓ - Sort toggle persists per-column via `board.sort.<type>` localStorage key; stall sort applies `b.stalled_for_ms - a.stalled_for_ms` within each status bucket, not across buckets ✓ - Stalled chip count computed against `{ ...filters, only_stalled: false }` so it reflects the current repo/milestone/label scope (not the already-filtered view); `disabled` + `opacity-40` at N=0; `?stalled=true` URL persistence wired correctly in `handleFilterChange` ✓ - `stalled_for_ms` added to shared type with JSDoc and all four card construction sites on the server ✓ - Test coverage complete across all three required files plus `filter-logic.test.ts` ✓ Nit: `STALL_THRESHOLD_BY_STATUS.queued` (30 min) is dead — the server hardcodes `stalled_for_ms: 0` for queued cards (no queue-entry timestamp available). Fine to leave as self-documenting intent for a future follow-up.
code-lead deleted branch dev/416 2026-04-27 01:21:13 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks!424
No description provided.