CE-WP-0006/0007: Capture view polish, workplans, and UX refinements

- Blob URL stability, scroll centre, strip-only visual guide
- Focus-gated linking, unlink clears overlay, field badge tooltips
- Capture layout (viewer centre), grey guide lines, Add field button
- Workplans CE-WP-0006 (done) and CE-WP-0007 (T01-T09 done, T10-T12 todo)
- Integration tests and viewer-url helpers
This commit is contained in:
2026-06-08 00:37:34 +02:00
parent d25b01f6d5
commit 2fd085b65e
26 changed files with 1767 additions and 356 deletions

View File

@@ -0,0 +1,305 @@
---
id: CE-WP-0006
type: workplan
title: "Forms & review UX refinements — blob stability, scroll-center, linking, visual guide"
domain: citation_evidence
repo: citation-evidence
repo_id: a677c189-b4e2-4f2a-9e48-faa482c277e6
topic_slug: citation_evidence_mvp
topic_id: 96fa8e80-9f74-40f2-84cd-644e9747b9ec
status: done
owner: Bernd
created: 2026-06-07
updated: 2026-06-07
depends_on_workplan: CE-WP-0005
planning_order: 6
planning_priority: high
spec_refs:
- wiki/ProductRequirementsDocument.md
- wiki/ArchitectureOverview.md
- wiki/SharedContracts.md
- history/2026-06-07-ecosystem-state-assessment.md
state_hub_workstream_id: "97493fdb-a793-4e79-bc7c-6a56b6085873"
---
# CE-WP-0006 — Forms & Review UX Refinements
User-facing polish before architectural expansion (Markdown/HTML, citation
recovery, subsystem extraction). Addresses six issues observed during manual
demo use on `http://localhost:5173/`.
## User requirements (locked)
1. **PDF blob load failure on evidence capture** — saving a new evidence item
with commentary triggers
`Unexpected server response (0) while retrieving PDF "blob:http://…"`.
2. **Center cited region on evidence select** — clicking an evidence item must
scroll the document viewport so the marked passage is centred, not merely
brought into view at an edge.
3. **Visual guide from footer strip only** — in Forms mode, connection lines
must originate from the bottom evidence strip cards, not duplicate cards
below the form. The field end of each line should attach to the **bottom
edge of the form pane** to reduce overlap with field inputs.
4. **Evidence strip visibility filter** — the bottom row supports an optional
filter (`all` | `attached`). Focusing a form field switches the filter to
`attached` (evidence linked to that field only).
5. **Bidirectional linking** — linking must work both ways:
- evidence → field (existing staged flow), and
- field → evidence (select/focus field, then click evidence card to link).
6. **Link indicators on evidence cards** — connected cards show one or more link
symbols in the upper-right. Hover shows a tooltip listing connected form
field titles. Clicking a symbol removes that specific link.
## Scoping decisions
- **No architecture extraction** in this workplan — all changes stay in the
umbrella repo under existing `src/{work,binder,app,anchor,source}/` folders.
- **Review mode and Forms mode** both benefit from T01 (blob stability) and T02
(scroll centre); T03T06 are Forms-mode focused.
- **ActiveEvidenceChips** (`src/app/forms/ActiveEvidenceChips.tsx`) is removed
from the form pane layout; its rect-registration responsibility moves to the
footer `EvidenceStrip`. The module may remain as a thin helper or be inlined
— but it must not render duplicate cards below the form.
- **Unlink** uses `bindings.unlinkEvidence(linkId)` (hard delete per current
MVP semantics in `src/binder/services/bindings.ts`).
## Dependency order
```
T01 (blob URL stability)
└─ T02 (viewport centre on evidence select)
T03 (strip-only visual guide + remove duplicate chips)
├─ T04 (strip filter: all | attached)
├─ T05 (bidirectional linking)
└─ T06 (link badges + tooltip + unlink)
└─ T07 (integration tests)
T08 (update workplans/README.md) — parallel once file exists
```
---
## T01 — Fix PDF blob URL failure during evidence capture
```task
id: CE-WP-0006-T01
priority: critical
status: done
state_hub_task_id: "3cc6a93a-e506-4477-8ef7-8c6dee405bc8"
```
**Problem:** uploaded PDFs are served via ephemeral `blob:` URLs minted by
`PdfByteStore` and stamped onto `document.uri`. A full viewer remount (e.g.
`ViewerShell` re-keyed on `scrollVersion`) or persistence round-trip can leave
PDF.js fetching a revoked or stale blob URL.
**Investigate and fix:**
- `ViewerShell` should resolve the viewer URL from the live `PdfByteStore`
entry for `document.id` when bytes are present; treat persisted `document.uri`
blob URLs as hints only, never as the sole source after reload.
- Avoid unnecessary full `PdfSpikeViewer` remounts when only scroll-target
changes (split scroll trigger from component `key` if that is the root cause).
- Ensure `captureSnapshot` / restore does not persist blob URLs that cannot be
rehydrated, or re-mint blob URLs from stored bytes on session/engine restore
when ZIP import or upload repopulates the byte store.
- Add a regression test reproducing capture-after-upload without blob error
(`src/work/` or `tests/integration/`).
**Acceptance:** upload a PDF, select text, add commentary, save evidence — no
PDF.js blob fetch error; viewer remains usable.
---
## T02 — Centre viewport on marked region when selecting evidence
```task
id: CE-WP-0006-T02
priority: high
status: done
depends_on: [T01]
state_hub_task_id: "e09d8fa1-862e-4c83-b1c4-19c6826e4610"
```
**Problem:** `scrollToHighlight` brings the passage into view but does not
centre it. Users lose context when the highlight lands at the viewport edge.
**Implement:**
- Extend the viewer adapter scroll contract (`PdfSpikeViewer` /
`react-pdf-highlighter-plus` utils) so scroll-to-annotation centres the
highlight rect vertically (and horizontally when wider than viewport).
- Wire through `useScrollToAnnotation` callers:
`EvidenceSidebar`, `ViewerShell` highlight click, `ScrollBridge` in Forms
mode.
- Unit test for scroll math helper if extracted; DOM integration test asserting
scroll request includes centre intent (mock utils acceptable per ADR-0004).
**Acceptance:** click any evidence item in Review or Forms — the cited passage
appears centred in the document pane.
---
## T03 — Visual guide from footer evidence strip; remove duplicate form cards
```task
id: CE-WP-0006-T03
priority: high
status: done
depends_on: [T02]
state_hub_task_id: "f30df6ee-a1c4-4a1b-80e0-d44e54f7b9b6"
```
**Problem:** `FormPane` renders `ActiveEvidenceChips` below the form while
`EvidenceStrip` already shows the same cards at the bottom. The SVG overlay
(`Overlay.tsx`) draws field→card→highlight using rects registered by the
duplicate chips.
**Implement:**
- Remove `ActiveEvidenceChips` from `FormPane` in `FormsApp.tsx`.
- Register `kind="evidence-card"` rects from `EvidenceStrip` buttons instead
(one registration per visible card).
- Update `Overlay` path geometry:
- field end → **bottom-centre** of the active field row (or bottom of form
pane when no specific field is active),
- card end → top-centre of the strip card,
- highlight end → unchanged.
- Adjust `forms-overlay-e2e.dom.test.tsx` expectations for the new anchor
points and single card location.
**Acceptance:** only one evidence card row (footer strip); visual guide connects
form bottom → strip card → PDF highlight with no duplicate cards under the form.
---
## T04 — Evidence strip filter (all vs attached-to-active-field)
```task
id: CE-WP-0006-T04
priority: medium
status: done
depends_on: [T03]
state_hub_task_id: "1dafa73d-1d8c-43b6-8934-2fbf038fc3be"
```
**Implement in `EvidenceStrip`:**
- Filter state: `all` (default) | `attached`.
- UI toggle in the strip header (e.g. "All" / "Linked to field").
- When a form field receives focus (`FormFieldActivated` or
`useActiveState().activeTarget`), set filter to `attached` and show only
evidence items with an `EvidenceLink` to that target.
- When no field is active, `attached` filter shows evidence linked to any field
in the demo schema, or falls back to `all` — pick the less surprising option
and document it in the task commit message.
- Clearing field focus returns filter to users last explicit choice (not forced
back to `all`).
**Acceptance:** focus "Summary" field → strip shows only evidence linked to
`summary`; toggle restores full list.
---
## T05 — Bidirectional evidence ↔ field linking
```task
id: CE-WP-0006-T05
priority: high
status: done
depends_on: [T03]
state_hub_task_id: "2d7c9278-1ecc-4b59-ae3b-1a5d1e513885"
```
**Current:** evidence-first only — stage card in strip, then click field.
**Add field-first:**
- Click/focus a form field → enter "field staged for linking" state (banner
parallel to existing evidence-staged banner).
- Click an evidence card in the strip → `bindings.linkEvidenceToTarget` with
the staged field as target; clear staging.
- Evidence-first path remains unchanged.
- Mutual exclusion: staging evidence clears field staging and vice versa.
- Emit existing `EvidenceLinkCreated` event; link count chips on fields update.
**Acceptance:** link works via evidence→field and field→evidence; cancel clears
staging; duplicate link to same target is prevented or noop with user feedback.
---
## T06 — Link badges on evidence cards (tooltip + unlink)
```task
id: CE-WP-0006-T06
priority: high
status: done
depends_on: [T05]
state_hub_task_id: "064f6e48-e791-4cf5-9d04-df3fb7a11e48"
```
**On each evidence card in `EvidenceStrip`:**
- Query `bindings.listTargetsForEvidence(item.id)`.
- Render one link icon per connected form field in the cards upper-right
(stack or count badge when >3).
- `title` / `aria-label` on hover: field label from `DEMO_SCHEMA` (fallback to
`targetId`).
- Click icon → `bindings.unlinkEvidence(linkId)` for that target; refresh strip
and field link counts.
- Do not trigger link-staging when clicking the unlink control (stop
propagation).
**Acceptance:** linked cards show indicators; tooltip names fields; click removes
link without staging a new one.
---
## T07 — Integration tests for refined Forms UX
```task
id: CE-WP-0006-T07
priority: high
status: done
depends_on: [T04, T05, T06]
state_hub_task_id: "c50f9700-9902-4520-b8e2-6a010431b7ef"
```
Extend or add happy-dom integration tests:
- `tests/integration/forms-link-flow.dom.test.tsx` — bidirectional linking.
- `tests/integration/forms-overlay-e2e.dom.test.tsx` — strip-only rects, bottom
anchor geometry (path count / data attributes).
- `tests/integration/app-prd-scenario.dom.test.tsx` — capture-after-upload no
blob error (if not covered in T01 unit test).
- New or extended test for strip `attached` filter behaviour.
**Acceptance:** `pnpm test` green; tests document the six user requirements.
---
## T08 — Update workplans README index
```task
id: CE-WP-0006-T08
priority: low
status: done
state_hub_task_id: "715edb39-9b97-4d7f-b89b-71a0130326e8"
```
Update `workplans/README.md` to list CE-WP-0001..0006 with correct statuses
(00010005 `done`, 0006 `active`).
**Acceptance:** README table matches workplan frontmatter.
---
## Acceptance for the workplan
After CE-WP-0006:
1. Evidence capture on uploaded PDFs does not break the viewer.
2. Selecting evidence centres the cited passage in the document viewport.
3. Forms visual guide uses footer strip cards only; lines attach to form bottom.
4. Evidence strip supports all/attached filter; field focus narrows to attached.
5. Linking works evidence→field and field→evidence.
6. Linked evidence cards show unlinkable field indicators with tooltips.