mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
## Context Another take on [this PR](https://github.com/supabase/supabase/pull/50733), decided that it's better UX + DX to use a PDF library (`@react-pdf/renderer`) instead for handling exporting Notebooks to PDF. The previous method using `print` involved a lot of sparse patching in various places + had a lot of limitations, not to mention its awkward UX to "Print". There's a lot of code changes in this PR but it's because we're constructing the PDF document based on the notebook's contents using primitives from `@react-pdf/renderer` which gives us a lot more control over the PDF's output. PDF output will differ slightly from the Notebook UI in the browser - Added a custom header in the report which covers the notebook name + project name, and when its exported - Empty markdown cells are skipped - Query cells will show both SQL content + results (either table or chart) - Opting to skip syntax highlighting for SQL content (Can consider separately) - Results will only be included in the PDF if the notebook's been run (Aligns with Copy as Markdown CTA) - For table results, _all_ rows will be rendered (Aligns with Copy as Markdown CTA) Feel free to give it a spin! 🙂 🙏 <img width="248" height="207" alt="image" src="https://github.com/user-attachments/assets/e38c14ba-7ee8-40ce-99b1-fa126453bf0f" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added an “Export as PDF” option for notebooks. - PDFs include notebook details, Markdown content, SQL queries, query results, tables, and charts. - Query exports show errors, empty results, row counts, and applicable row limits. - Export progress is displayed while the PDF is generated, and failures are reported via notifications. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
40 lines
1.3 KiB
TypeScript
40 lines
1.3 KiB
TypeScript
import { pdf } from '@react-pdf/renderer'
|
|
import saveAs from 'file-saver'
|
|
import type { Snapshot } from 'valtio'
|
|
|
|
import { type QueryResult } from '../types'
|
|
import { NotebookPdfDocument } from './NotebookPdfDocument'
|
|
import { isQueryCell, type Cell } from '@/data/content/notebooks/notebook-schema'
|
|
|
|
export interface ExportNotebookToPdfParams {
|
|
name: string
|
|
projectName?: string
|
|
cells: readonly Snapshot<Cell>[]
|
|
getResult: (cellId: string) => QueryResult | undefined
|
|
}
|
|
|
|
/**
|
|
* Gathers a notebook's cells and each query cell's last in-session result — results aren't
|
|
* persisted with the notebook, so they're read off the same `queryCellRefs` imperative
|
|
* handles `notebookToMarkdown` (ExplorerNotebookTab.utils.ts) already uses — then renders
|
|
* and downloads a PDF report.
|
|
*/
|
|
export async function exportNotebookToPdf({
|
|
name,
|
|
projectName,
|
|
cells,
|
|
getResult,
|
|
}: ExportNotebookToPdfParams): Promise<void> {
|
|
const results = new Map<string, QueryResult>()
|
|
cells.filter(isQueryCell).forEach((cell) => {
|
|
const result = getResult(cell._id)
|
|
if (result) results.set(cell._id, result)
|
|
})
|
|
|
|
const blob = await pdf(
|
|
<NotebookPdfDocument name={name} projectName={projectName} cells={cells} results={results} />
|
|
).toBlob()
|
|
|
|
saveAs(blob, `${name}.pdf`)
|
|
}
|