Skip to content

feat(reports): render print preview from the same document as the PDF - #60

Merged
Morialkar merged 1 commit into
mainfrom
feat/reports-unified-print-pdf
Aug 1, 2026
Merged

feat(reports): render print preview from the same document as the PDF#60
Morialkar merged 1 commit into
mainfrom
feat/reports-unified-print-pdf

Conversation

@Morialkar

Copy link
Copy Markdown
Owner

Closes defect (f) from manual QA, and lifts the export memory ceiling.

The problem

The print tab re-implemented the report layout in JSX with its own @media print stylesheet, while the PDF export rendered a Blade template through Dompdf. Two independent implementations of the same document, so they disagreed on markup, on styling, and — least obviously — on content: the preview rendered previewData, which is paginated, while the export ran unpaginated. Printing gave you one page of records; exporting gave you all of them.

The change

renderReportHtml() is now the single rendering of a report document. The PDF export and a new POST /reports/preview/html both go through it. The print tab embeds that document in an iframe and prints the iframe, so what is previewed is what is printed is what is exported — by construction, not by keeping two implementations in step.

This removes ~156 lines of duplicated JSX and the 81-line print stylesheet.

Export limits

Raised, with numbers measured against the real dev report rather than picked round:

before after
memory_limit 256M 512M (measured peak 288M)
max_execution_time 30s 180s
nginx fastcgi_read_timeout 60s default 180s

All three were needed: raising memory alone still left the request dying on a timeout.

Verification

Driven against the running stack:

  • print tab renders the API document in the iframe: 470 rows, all records, with the PDF's own styling — the old preview showed 10
  • selecting a card view switches the preview to 247 cards, 0 table rows, matching what the PDF now produces
  • the card export that previously exhausted 256M returns HTTP 200, a 1.5 MB PDF, in 19s
  • fresh tab, zero console errors

Also: 185 API tests (2 new — the preview HTML is unpaginated, and it honours the selected card view), 76 client tests (3 new — the iframe carries the API document, print targets the iframe rather than the page, and a failed load reports instead of showing a blank frame), Pint, tsc -b, ESLint, Prettier.

Still open — needs your call

Card mode remains heavy at scale: 248 pages for 247 records, roughly one card per page. That is content, not CSS — the view stacks 16 fields with 12 in a single column and titles that wrap to three lines. I measured removing the column min-height, tightening field margins and card padding, and shrinking the @page margins; none crossed the threshold to two cards per page, so I shipped none of them. Options worth deciding on: cap records per export, offer landscape, or trim the fields in the card view.

The print tab re-implemented the report layout in JSX with its own @media
print stylesheet, while the PDF export rendered a Blade template through
Dompdf. Two independent implementations of the same document, so they
disagreed on markup, on styling, and on content: the preview showed only the
current preview page while the export contained every record.

Extract renderReportHtml() as the single rendering, used by the PDF export
and by a new POST /reports/preview/html. The print tab now embeds that
document in an iframe and prints the iframe, so what is previewed is what is
printed and what is exported. This removes ~156 lines of duplicated JSX and
the 81-line print stylesheet.

Also raise the export limits, measured against the real dev report: card
rendering of 247 records peaks at 288M, which the 256M limit killed outright,
and takes long enough to need a higher max_execution_time and a matching
nginx fastcgi_read_timeout.
@Morialkar
Morialkar merged commit 1fa22ff into main Aug 1, 2026
5 checks passed
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.

1 participant