Skip to content

Proposal H, item 2: inline PDF export runs the real pipeline on /display - #109

Merged
WilfordGrimley merged 2 commits into
masterfrom
claude/proposal-h-3b-inline-export-04bam2
Jul 19, 2026
Merged

Proposal H, item 2: inline PDF export runs the real pipeline on /display#109
WilfordGrimley merged 2 commits into
masterfrom
claude/proposal-h-3b-inline-export-04bam2

Conversation

@WilfordGrimley

Copy link
Copy Markdown

Description

Item 2 of the owner's revised hands-on-review work order for Proposal H
(docs/proposals/proposal-h-unified-display-page.md, behind
NEXT_PUBLIC_UNIFIED_DISPLAY_ENABLED) - pulled to the front of the sequence
per the owner's "inline export pulled to the front" decision: the classic
Print tab is condemned, and /display absorbs export entirely. Independent
of item 1 (PR #104, still open) - based directly off master, not stacked on
that PR, per the stacked-PR lesson in docs/lessons.md.

Real pipeline, in-page, no navigation. "Generate PDF" on /display now
runs the exact same export pipeline the classic PDF tab uses - useDownloadPDF,
useSaveToDrivePDF, and ImageFailureConfirmModal are exported from
PDFGenerator.tsx (not forked) and consumed directly, fed by this page's own
toolbar settings (paper size, bleed edge, guides) via a PDFProps object
built in DisplayPage.tsx. pageSize: "CUSTOM" with explicit
pageWidth/pageHeight (this page's own landscape-swapped dimensions) is
what makes the exported file match the live sheet rather than silently
reverting to the named size's portrait dimensions. Every setting this page
doesn't expose (card selection mode, cut-line geometry, quality/DPI,
spacing/margins, SCM mode) takes PDFGenerator.tsx's own documented default.

Real progress, not a spinner. A determinate <ProgressBar> shows
"Fetching images: N of ~M" while the existing #81 paced fetcher
(Semaphore(3), retry/backoff, immediate-fail on dead links - pdfImage.ts,
unchanged) works through full-resolution image fetches, then switches to an
indeterminate "Assembling PDF…" bar once every image has resolved but
@react-pdf/renderer is still building the file - inferred from
completed >= total on the same onImageProgress signal the classic tab
already uses, since the underlying pipeline has no separate "now assembling"
signal of its own.

Save to Google Drive rides along - same useSaveToDrivePDF/pipeline,
gated by the same isGoogleDriveAppConfigured() check the classic tab uses.
Cheap to wire since it needed no new machinery beyond what Download already
required, so this isn't a deep link - it's real.

Failure handling is byte-identical - the same ImageFailureConfirmModal
mounts on /display, naming failed cards and blocking (cancellable) download
until confirmed, exactly as the classic tab's own coverage in
PDFGenerator.spec.ts proves for that surface.

Checklist

  • I have installed pre-commit and installed the hooks with pre-commit install before creating any commits.
  • I have updated any related tests for code I modified or added new tests where appropriate.
  • I have manually tested my changes as follows:
    • New tests/DisplayPageExport.spec.ts (4 tests): exports with non-default
      settings (custom bleed edge, Guides off) and downloads cards.pdf without
      navigating off /display, verified via a captured full-resolution image
      request; a real determinate progress bar appears mid-fetch (captured via
      a MutationObserver in-page, robust against the "fetching" phase's own
      narrow timing window) and clears after; the failure-confirm modal blocks
      and (on cancel) actually prevents the download; confirming despite
      failures still downloads.
    • tests/DisplayPage.spec.ts full regression (14/14) - zero behavior
      change to Step 1/PR 2a/PR 2b's own surfaces.
    • tests/PDFGenerator.spec.ts full regression (8/8) - zero behavior
      change to the classic tab's own export pipeline, confirming the
      exported functions are genuinely shared, not diverged copies.
    • npx tsc --noEmit clean.
    • npx jest - 391 tests passing.
    • NEXT_PUBLIC_UNIFIED_DISPLAY_ENABLED=true npx next build - clean
      production build with the flag on (the standing verification bar).
  • I have updated any relevant documentation or created new documentation where appropriate.

Per the owner's staged-retirement instruction: this PR does NOT touch the
classic Print tab's navbar/route exposure - that's a separate, later PR once
the owner has verified inline export on a real deck.


Generated by Claude Code

…erate PDF runs the real pipeline in-page

"Generate PDF" on /display now runs the exact same export pipeline PDFGenerator.tsx
uses for the classic tab - useDownloadPDF/useSaveToDrivePDF/ImageFailureConfirmModal
exported from PDFGenerator.tsx (not forked) - fed by this page's own toolbar settings
(paper size, bleed edge, guides) instead of navigating to a separate tab. A real
determinate ProgressBar shows "Fetching images: N of ~M" while the #81 paced fetcher
works, switching to an indeterminate "Assembling PDF..." once every image has
resolved but the file itself is still being built.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHapYojTkT5wenrQwGbGYk
@WilfordGrimley
WilfordGrimley merged commit 92d9fc2 into master Jul 19, 2026
6 checks passed
@WilfordGrimley
WilfordGrimley deleted the claude/proposal-h-3b-inline-export-04bam2 branch July 19, 2026 01:28
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.

2 participants