refactor(desktop): draw the issue peek in the window's own side panel

Merged
DA
11d ago
+480-356

The developer's ask, following #3664: "it looks and behaves different from the side panel on a task/inbox. Can you make sure we are sharing components."

What was different

#3664 drew the peek as a pane of its own, modelled on the automation's Runs pane, with its own:

  • head, ground and identifier
  • Open as page and Close buttons
  • width bounds (360 to 720px) and kept width
  • slide (usePaneSlide)

Nothing about it matched the side panel beside a task, an agent's page, or the Inbox: no tab, no full screen, no title-bar toggle, no ⌥⌘B, a different width, and different motion.

What it shares now

  • PanelFrame, extracted from SidePanel (side-panel.tsx). It draws:

    • the .side-panel pane
    • its top row: tabs, the chosen tab's actions, and the full-screen button
    • the room it keeps while full screen
    • the resize edge
    • the exit motion (playExit)

    SidePanel now renders through it with no change in behaviour, and the peek renders through the same frame.

  • The tab row. The peek's one tab is the issue, drawn with the strip's own Tab (status glyph, identifier, title). Its × shuts the panel, as closing a panel's last tab does. The chosen tab's ⋯ is the issue's own IssueMenu, which now offers Open as page in place of the old button.

  • The window's side panel state. Whether the peek stands, its width (SIDE_PANEL_WIDTH and the kept width), and full screen all come from tasks.sidePanel, as the Inbox's panel does.

    • The title bar's panel toggle and ⌥⌘B show and hide the peek once an issue has been peeked. issuesView.peeked holds it, in the way inboxView.chosen holds the Inbox's item.
    • Expand panel fills the Issues page.
  • Motion. The arrival is the shared pane glide (.side-panel), and the exit is the side panel's own.

  • Content. The issue still scrolls in DocumentScroll, the column every document uses.

Behaviour kept from #3664

  • A press or Return opens the peek, and ⌘-press or ⌘Return opens the issue's page.
  • The peek follows the keyboard without reading the issue again.
  • If there's no room for the panel next to one column, a press opens the page instead.
  • An issue that is filtered out, archived, or belongs to another workspace closes the peek.
  • Escape now leaves full screen first, then closes the peek.

Tests

  • issues-page.test.ts's harness now uses the real useSidePanel. The peek tests assert on .side-panel, the tab's ×, and Open as page in ⋯. The narrow-window width moves from 600 to 500, since the panel's minimum is 280.
  • New: the peek stands in the side panel's frame, with the issue's tab, the panel's own 400px width, and Expand panel. Escape steps out of full screen first, then closes the peek.
  • New (desktop-shell.test.ts): the panel toggle appears over the Issues list once an issue has been peeked, and not before.
  • #testing/pane-motion's recording engine now answers getAnimations, which the shared exit calls.

The desktop renderer suite (2065 tests), typecheck, oxlint, biome, knip and repository-checks pass.

Screenshots

The peek in the side panel's frame: the well ground, the issue's tab with ×, ⋯ and Expand panel.

The peek beside the board in the side panel frame

Expand panel fills the Issues page, as it fills a task's window.

The peek full screen over the board

The harness renders IssuesPage alone, so the title bar's toggle is out of frame; it is covered by the shell test.

Made with Luke


Devin Review