UI-1: Monitor tasks → slide-out drawer (kill /monitor/tasks + /monitor/task/:id) #397

Closed
opened 2026-04-26 19:58:26 +00:00 by claude-desktop · 0 comments
Collaborator

As an operator, I want task inspection to be a drawer overlay on the pipeline view, not a separate page, so that I can drill into a failing task without losing context of the surrounding issue stages.

Why

/monitor (pipeline-centric, issue rows + stage pills) and /monitor/tasks (task-centric, three-pane list+detail) duplicate the same /issues/pipeline + /history data with different mental models. Operator must choose between two metaphors before knowing what they want. /monitor/task/$taskId is just a deeplink wrapper around the same TaskDetail component. UX audit (2026-04-26) shows 2-3 page hops to answer "why did task X fail?".

Acceptance criteria

Drawer surface

  • /monitor gains a slide-out right-side drawer triggered by:
    • Clicking any stage pill on a pipeline row
    • URL search param ?detail=$taskId (bookmarkable)
    • Toolbar button "Recent tasks" (drawer opens with newest task pre-selected)
  • Drawer renders the existing TaskDetail component (event log, status, cost, turns, error) full-height on the right ~400-500px wide
  • Drawer contains a left-pane TaskList scoped to the current pipeline filter (repo/milestone/etc) so operator sees the task subset relevant to what they're viewing
  • Closing drawer drops ?detail= from URL
  • Drawer state persists across reload via URL param

Route deletions

  • Delete apps/web/src/routes/monitor.tasks.tsx
  • Delete apps/web/src/routes/monitor.task.$taskId.tsx
  • Delete apps/web/src/routes/monitor.grid.tsx (already a redirect)
  • Add redirects in monitor.tsx beforeLoad (or root router) so bookmarked URLs land cleanly:
    • /monitor/tasks/monitor?detail=latest with toast "Tasks view is now a drawer"
    • /monitor/task/$taskId/monitor?detail=$taskId
    • /monitor/grid/monitor?view=grid

SSE consolidation

  • Extract any duplicated task-lifecycle SSE logic from the deleted routes into a single useTaskSSE(taskId) hook reused by the drawer
  • Drawer subscribes only when open (avoid SSE leak on closed drawer)

Tests

  • monitor.index.test.tsx covers: drawer opens on ?detail=, closes on X / param drop, list filtering matches pipeline filter, deeplink pasting opens drawer pre-selected
  • Redirect tests for the three deleted routes
  • bun run qa clean

Docs

  • Update apps/web/CLAUDE.md if the drawer is the first instance of the slide-out pattern (codify width + elevation — shadow-lifted per existing convention)
  • Remove stale references to /monitor/tasks from any spec / runbook

Out of scope

  • Folding /monitor/issue/.../gantt into a tab (that's UI-2, sibling)
  • Hoisting StorageStrip / AgentChips from the deleted monitor.tasks.tsx — audit them; if redundant with pipeline-view filters, just delete; if still needed, separate ticket
  • Changing the pipeline list itself

References

  • UX audit conducted 2026-04-26 (chat history)
  • apps/web/src/routes/monitor.index.tsx — primary surface to extend
  • apps/web/src/routes/monitor.tasks.tsx — source of three-pane layout to fold into drawer
  • apps/web/src/routes/monitor.task.$taskId.tsx — bookmarkable detail pattern to preserve via ?detail= param
  • apps/web/CLAUDE.md — drawer styling (width, shadow-lifted, rounded-card)
As an operator, I want task inspection to be a drawer overlay on the pipeline view, not a separate page, so that I can drill into a failing task without losing context of the surrounding issue stages. ## Why `/monitor` (pipeline-centric, issue rows + stage pills) and `/monitor/tasks` (task-centric, three-pane list+detail) duplicate the same `/issues/pipeline` + `/history` data with different mental models. Operator must choose between two metaphors before knowing what they want. `/monitor/task/$taskId` is just a deeplink wrapper around the same TaskDetail component. UX audit (2026-04-26) shows 2-3 page hops to answer "why did task X fail?". ## Acceptance criteria ### Drawer surface - [ ] `/monitor` gains a slide-out right-side drawer triggered by: - Clicking any stage pill on a pipeline row - URL search param `?detail=$taskId` (bookmarkable) - Toolbar button "Recent tasks" (drawer opens with newest task pre-selected) - [ ] Drawer renders the existing `TaskDetail` component (event log, status, cost, turns, error) full-height on the right ~400-500px wide - [ ] Drawer contains a left-pane TaskList scoped to the **current pipeline filter** (repo/milestone/etc) so operator sees the task subset relevant to what they're viewing - [ ] Closing drawer drops `?detail=` from URL - [ ] Drawer state persists across reload via URL param ### Route deletions - [ ] Delete `apps/web/src/routes/monitor.tasks.tsx` - [ ] Delete `apps/web/src/routes/monitor.task.$taskId.tsx` - [ ] Delete `apps/web/src/routes/monitor.grid.tsx` (already a redirect) - [ ] Add redirects in `monitor.tsx` `beforeLoad` (or root router) so bookmarked URLs land cleanly: - `/monitor/tasks` → `/monitor?detail=latest` with toast "Tasks view is now a drawer" - `/monitor/task/$taskId` → `/monitor?detail=$taskId` - `/monitor/grid` → `/monitor?view=grid` ### SSE consolidation - [ ] Extract any duplicated task-lifecycle SSE logic from the deleted routes into a single `useTaskSSE(taskId)` hook reused by the drawer - [ ] Drawer subscribes only when open (avoid SSE leak on closed drawer) ### Tests - [ ] `monitor.index.test.tsx` covers: drawer opens on `?detail=`, closes on X / param drop, list filtering matches pipeline filter, deeplink pasting opens drawer pre-selected - [ ] Redirect tests for the three deleted routes - [ ] `bun run qa` clean ### Docs - [ ] Update `apps/web/CLAUDE.md` if the drawer is the first instance of the slide-out pattern (codify width + elevation — `shadow-lifted` per existing convention) - [ ] Remove stale references to `/monitor/tasks` from any spec / runbook ## Out of scope - Folding `/monitor/issue/.../gantt` into a tab (that's UI-2, sibling) - Hoisting `StorageStrip` / `AgentChips` from the deleted `monitor.tasks.tsx` — audit them; if redundant with pipeline-view filters, just delete; if still needed, separate ticket - Changing the pipeline list itself ## References - UX audit conducted 2026-04-26 (chat history) - `apps/web/src/routes/monitor.index.tsx` — primary surface to extend - `apps/web/src/routes/monitor.tasks.tsx` — source of three-pane layout to fold into drawer - `apps/web/src/routes/monitor.task.$taskId.tsx` — bookmarkable detail pattern to preserve via `?detail=` param - `apps/web/CLAUDE.md` — drawer styling (width, shadow-lifted, rounded-card)
Sign in to join this conversation.
No project
No assignees
1 participant
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#397
No description provided.