Files
PaperClipAI/ui
Michael NguyenandClaude Fable 5 2a5aa5e213 feat(ui): viewer=full document deep link opens the maximized side pane (#12812)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents ask humans for decisions through approval cards, and a chat
gateway plugin can forward those cards to Slack with an "Open task"
button
> - The button opens the bare task page; to read the document under
approval, the reviewer must click four more times (open the side pane,
open the Artifacts tab, open the artifact, maximize the pane)
> - Approvals are the highest-frequency human touchpoint, so each
removed click matters
> - This pull request adds a `viewer=full` option to the existing
`#document-<key>` deep link; the link now opens the target document and
maximizes the side pane
> - The benefit is one-click access from an external notification to a
full-size reading surface for the document under approval

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The issue page already supports `#document-<key>` deep links. They open
the document in the side pane, but at the pane's default width.

**Current behavior**

An external link cannot request the maximized (full-size) document view.
A reviewer who follows an approval notification must maximize the pane
by hand each time.

**Proposed behavior**

`#document-<key>&viewer=full` opens the document and maximizes the side
pane. Plan documents open in the Plan tab, maximized. Mobile keeps the
full-screen sheet. Unknown `viewer` values are ignored, so old links and
new links stay compatible in both directions.

**Reason and benefit**

Chat notifications about approvals can now land the reviewer directly on
a full-size view of the document they must read. This removes four
clicks from every approval review.

**Breaking changes**

None. The parameter is optional and additive. Links without it keep
today's behavior.

## What Changed

- `ui/src/lib/document-annotation-hash.ts`: parse and build an optional
`viewer=full` parameter in document hashes.
- `ui/src/lib/issue-document-deep-link.ts`: thread a `maximize` flag on
properties-pane routes; the continuation-summary route is unchanged.
- `ui/src/context/PanelContext.tsx`: add a one-shot panel maximize
request (`requestPanelMaximize` / `clearPanelMaximizeRequest`).
- `ui/src/components/PropertiesPanel.tsx`: the resizable panel host
consumes a pending request once it is visible and laid out, then clears
it.
- `ui/src/pages/IssueDetail.tsx`: request the maximize on the desktop
deep-link path only; mobile keeps the sheet.
- Tests for all of the above.

## Verification

- `cd ui && pnpm typecheck` — clean.
- `cd ui && pnpm vitest run src/lib/document-annotation-hash.test.ts
src/lib/issue-document-deep-link.test.ts
src/components/PropertiesPanel.test.tsx` — 31/31 green.
- New cases cover: `viewer` parse/build round trip, unknown values
ignored, maximize routing for document and plan tabs, a pending request
consumed on mount, and a request held while the panel is hidden.
- Manual check: open an issue with `#document-<key>&viewer=full` in the
URL; the pane opens on that document, maximized. Remove the parameter;
the pane opens at its normal width.

## Risks

- Low risk. The parameter is optional; no data, schema, or API changes.
- The maximize request lives in React context as a one-shot flag. It is
cleared on first consumption, so a stale request cannot re-maximize the
pane on later navigations.
- If a link carries `viewer=full` on a web build older than this change,
the parameter is ignored and the document still opens.

## Model Used

- Claude Fable 5 (`claude-fable-5`), Anthropic. Agentic coding session
with extended thinking and tool use (file edits, shell, test runs).

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-09-03 20:27:25 -10:00
..
…

@paperclipai/ui

Published static assets for the Paperclip board UI.

What gets published

The npm package contains the production build under dist/. It does not ship the UI source tree or workspace-only dependencies.

Storybook

Storybook config, stories, and fixtures live under ui/storybook/.

pnpm --filter @paperclipai/ui storybook
pnpm --filter @paperclipai/ui build-storybook

Typical use

Install the package, then serve or copy the built files from node_modules/@paperclipai/ui/dist.