Skip to content

feat: add PDF export for dashboards#4

Merged
Orsso merged 3 commits into
mainfrom
feat/dashboard-pdf-export
Mar 19, 2026
Merged

feat: add PDF export for dashboards#4
Orsso merged 3 commits into
mainfrom
feat/dashboard-pdf-export

Conversation

@Orsso

@Orsso Orsso commented Mar 18, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add client-side PDF export using html2canvas-pro + jsPDF
  • "Export PDF" button in dashboard toolbar captures the grid as a multi-page landscape PDF
  • Interactive chrome (drag handles, resize handles, FAB) hidden during capture via .exporting CSS class
  • DashboardGrid wrapped with forwardRef to expose container element to parent

Files changed

File Change
frontend/lib/export-dashboard-pdf.ts New — async export utility
frontend/app/project/[id]/dashboard/page.tsx Export button + grid ref
frontend/components/dashboard/dashboard-grid.tsx forwardRef wrapper
frontend/app/globals.css .exporting hide rules
frontend/package.json html2canvas-pro, jspdf deps

Test plan

  • tsc --noEmit passes
  • ESLint passes
  • next build succeeds
  • 157 backend tests pass
  • Manual: open dashboard with cards → click Export PDF → verify downloaded PDF contains all cards without UI chrome

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.
@Orsso
Orsso force-pushed the feat/dashboard-pdf-export branch from 0825e54 to bed2f98 Compare March 18, 2026 17:01

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +145 to +146
<DashboardGrid
ref={gridRef}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines +15 to +20
const canvas = await html2canvas(gridElement, {
scale: 2,
useCORS: true,
backgroundColor: '#ffffff',
logging: false,
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Adrien Reibel added 2 commits March 18, 2026 18:09
- 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
@Orsso
Orsso merged commit 317ad94 into main Mar 19, 2026
6 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