feat: add PDF export for dashboards#4
Conversation
Client-side capture using html2canvas-pro + jsPDF. Adds an "Export PDF" button in the dashboard toolbar that renders the grid to a multi-page landscape PDF. Interactive chrome (drag handles, resize handles, FAB) is hidden during capture via a CSS class.
0825e54 to
bed2f98
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0825e54b8e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| <DashboardGrid | ||
| ref={gridRef} |
There was a problem hiding this comment.
Avoid attaching the export ref to
next/dynamic
Because DashboardGrid is loaded with next/dynamic, the ref assigned here resolves to Next's loadable wrapper rather than the DashboardGridHandle exposed in dashboard-grid.tsx. In practice handleExport() reads gridRef.current?.container as undefined and returns early, so clicking Export PDF never produces a file.
Useful? React with 👍 / 👎.
| const canvas = await html2canvas(gridElement, { | ||
| scale: 2, | ||
| useCORS: true, | ||
| backgroundColor: '#ffffff', | ||
| logging: false, | ||
| }) |
There was a problem hiding this comment.
Capture the full dashboard height before rasterizing
exportDashboardPdf() snapshots gridElement directly with html2canvas, but the referenced wrapper is the h-full container from dashboard-grid.tsx, not a full-height render target. For dashboards taller than the viewport, the canvas only contains the visible first screen, so the pagination loop just slices that partial capture and the lower cards never appear in the exported PDF.
Useful? React with 👍 / 👎.
- Replace forwardRef/useImperativeHandle with a stable DOM id, fixing the ref not forwarding through next/dynamic - Temporarily set scroll parent to overflow:visible + height:auto before capture so dashboards taller than the viewport are fully rasterized
Summary
html2canvas-pro+jsPDF.exportingCSS classDashboardGridwrapped withforwardRefto expose container element to parentFiles changed
frontend/lib/export-dashboard-pdf.tsfrontend/app/project/[id]/dashboard/page.tsxfrontend/components/dashboard/dashboard-grid.tsxforwardRefwrapperfrontend/app/globals.css.exportinghide rulesfrontend/package.jsonhtml2canvas-pro,jspdfdepsTest plan
tsc --noEmitpassesnext buildsucceeds