Proposal H, item 2: inline PDF export runs the real pipeline on /display - #109
Merged
WilfordGrimley merged 2 commits intoJul 19, 2026
Merged
Conversation
…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
…b-inline-export-04bam2
This was referenced Jul 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Item 2 of the owner's revised hands-on-review work order for Proposal H
(
docs/proposals/proposal-h-unified-display-page.md, behindNEXT_PUBLIC_UNIFIED_DISPLAY_ENABLED) - pulled to the front of the sequenceper the owner's "inline export pulled to the front" decision: the classic
Print tab is condemned, and
/displayabsorbs export entirely. Independentof 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
/displaynowruns the exact same export pipeline the classic PDF tab uses -
useDownloadPDF,useSaveToDrivePDF, andImageFailureConfirmModalare exported fromPDFGenerator.tsx(not forked) and consumed directly, fed by this page's owntoolbar settings (paper size, bleed edge, guides) via a
PDFPropsobjectbuilt in
DisplayPage.tsx.pageSize: "CUSTOM"with explicitpageWidth/pageHeight(this page's own landscape-swapped dimensions) iswhat 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
#81paced 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/rendereris still building the file - inferred fromcompleted >= totalon the sameonImageProgresssignal the classic tabalready 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
ImageFailureConfirmModalmounts on
/display, naming failed cards and blocking (cancellable) downloaduntil confirmed, exactly as the classic tab's own coverage in
PDFGenerator.spec.tsproves for that surface.Checklist
pre-commitand installed the hooks withpre-commit installbefore creating any commits.tests/DisplayPageExport.spec.ts(4 tests): exports with non-defaultsettings (custom bleed edge, Guides off) and downloads
cards.pdfwithoutnavigating off
/display, verified via a captured full-resolution imagerequest; a real determinate progress bar appears mid-fetch (captured via
a
MutationObserverin-page, robust against the "fetching" phase's ownnarrow 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.tsfull regression (14/14) - zero behaviorchange to Step 1/PR 2a/PR 2b's own surfaces.
tests/PDFGenerator.spec.tsfull regression (8/8) - zero behaviorchange to the classic tab's own export pipeline, confirming the
exported functions are genuinely shared, not diverged copies.
npx tsc --noEmitclean.npx jest- 391 tests passing.NEXT_PUBLIC_UNIFIED_DISPLAY_ENABLED=true npx next build- cleanproduction build with the flag on (the standing verification bar).
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