Skip to content

feat(dashboard): review queue as its own destination - #868

Open
kmonsoe wants to merge 2 commits into
feat/console-shellfrom
feat/review-queue
Open

feat(dashboard): review queue as its own destination#868
kmonsoe wants to merge 2 commits into
feat/console-shellfrom
feat/review-queue

Conversation

@kmonsoe

@kmonsoe kmonsoe commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Stacked on #867 (→ #866#865). The substance of the Oversight console: the design's "Review queue" screen.

What's here

  • pages/conversations.tsx — desktop two-pane (1.05fr/1.4fr inside the console shell): sectioned list + full-height pane; URL-driven selection (/dashboard/conversations/[id]), which gives mobile list→detail for free (list hides when a conversation is open, pane shows a "← Queue" back link, actions stack at 44px).
  • conversation-queue.ts — controller hook over GET /v1/conversations/queue (feat(conv): review-queue read model, internal notes, draft reject stamps #865): open + finished pages, per-selection detail, realtime refetch on conversation.* (org + selected-conversation channels), reconnect catch-up, 30s failure retry, and the pending → api → reload → inline error action shape shared with inbox-data. Pure helpers (partitionQueue, matchesQueueSearch, messageDraftKind) are unit-tested.
  • SectionsNeeds your attention = attention rows unclaimed or claimed by you; In progress = everything else open (incl. teammates' claims); Finished = closed. Client-side search over customer/subject/preview/topic.
  • Rows — channel tag, customer — subject, snippet, topic nudge line, "No draft — you write it" / "The agent is drafting…" badges, age, claim-holder face (cobalt = you, ink = teammate, dashed = unclaimed), note count.
  • Pane — thread via the existing MessageBubble (orientation untouched, per the handover; internal notes render as the amber card, interleaved chronologically); why-block reading rationale + toolNames off the pending draft's metadata (feat(agent-runtime): draft rationale from the audit pass + on-demand drafting #866), hidden when absent; claim-gated composer with Reply / Internal note · n tabs — draft-seeded textarea (⌘↵ send, fromDraftId approve-vs-edited stamping), Reject → POST :id/clear-draft (now writes draft_reply_rejected), Restore draft when dirty, Release, Ask for a draft (request-draft round trip with a local drafting state cleared when the draft lands), Close-no-reply. Unclaimed/held → "Claim to reply" / "Take over to reply" gate; closed → read-only. Plain composer fallback for draftless handovers.
  • Nav & landing — Oversight group with Conversations (live badge); Overview flips adminOnly; support agents at /dashboard are redirected to the queue.
  • i18n — full dashboard.console.queue.* namespace in en + nb (transcreated), plus errors.claim_held_by_other and errors.conv_draft_pending so a take-over collision no longer surfaces a raw UUID string.

Tests

dashboard-pages: 96 passed (new: section partitioning by claim/attention, search matching, draft-kind classification incl. draft_reply_rejected). Typecheck clean (dashboard-pages + apps/web). A full visual walkthrough of the stack (desktop + 390px, two-browser claim collision, approve/edit/reject stamps) follows after the overview rework lands on this stack.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CPwvC1MqF1uhpNqC8BmvQN

Two-pane /dashboard/conversations over the enriched queue DTO:
sectioned list (needs-you / in-progress / finished by claim+attention),
claim faces, topic nudges and no-draft badges; conversation pane with
interleaved internal notes, the agent why-block (rationale + tool
chips), and a claim-gated composer (approve/edit seeded draft, reject
via clear-draft, restore, release, ask-for-a-draft, close-no-reply,
note tab). Mobile is list-then-detail with stacked actions. Agents land
here; Oversight nav group added; claim_held_by_other and
conv_draft_pending translated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPwvC1MqF1uhpNqC8BmvQN
End-user bubbles switch from paper-deep fill to paper with a hairline
rule border per the mockup — paper-deep vanished against the pane's
paper-deep body. Opening /dashboard/conversations without an id now
selects the first queue row (route id still drives the mobile
list/detail split).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPwvC1MqF1uhpNqC8BmvQN
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.

1 participant