From 339289be9f4a366fbde59ee00e57f5c3bae1e2aa Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Mon, 29 Dec 2025 23:54:43 +0200 Subject: [PATCH] refactor(export): move PDF table template to shared package --- .../server/src/modules/Export/ExportPdf.ts | 20 ++- .../ExportResourceTableTemplate.tsx | 119 ++++++++++++++++++ shared/pdf-templates/src/index.ts | 2 + .../render-export-resource-table-template.tsx | 14 +++ 4 files changed, 143 insertions(+), 12 deletions(-) create mode 100644 shared/pdf-templates/src/components/ExportResourceTableTemplate.tsx create mode 100644 shared/pdf-templates/src/renders/render-export-resource-table-template.tsx diff --git a/packages/server/src/modules/Export/ExportPdf.ts b/packages/server/src/modules/Export/ExportPdf.ts index 88fc2923a..99f55dbb7 100644 --- a/packages/server/src/modules/Export/ExportPdf.ts +++ b/packages/server/src/modules/Export/ExportPdf.ts @@ -1,14 +1,13 @@ import { Injectable } from '@nestjs/common'; import { ChromiumlyTenancy } from '../ChromiumlyTenancy/ChromiumlyTenancy.service'; -import { TemplateInjectable } from '../TemplateInjectable/TemplateInjectable.service'; +import { renderExportResourceTableTemplateHtml } from '@bigcapital/pdf-templates'; import { mapPdfRows } from './utils'; @Injectable() export class ExportPdf { constructor( - private readonly templateInjectable: TemplateInjectable, private readonly chromiumlyTenancy: ChromiumlyTenancy, - ) {} + ) { } /** * Generates the pdf table sheet for the given data and columns. @@ -19,21 +18,18 @@ export class ExportPdf { * @returns */ public async pdf( - columns: { accessor: string }, + columns: { accessor: string; name?: string; style?: string; group?: string }[], data: Record, sheetTitle: string = '', sheetDescription: string = '' ) { const rows = mapPdfRows(columns, data); - const htmlContent = await this.templateInjectable.render( - 'modules/export-resource-table', - { - table: { rows, columns }, - sheetTitle, - sheetDescription, - } - ); + const htmlContent = renderExportResourceTableTemplateHtml({ + table: { rows, columns }, + sheetTitle, + sheetDescription, + }); // Convert the HTML content to PDF return this.chromiumlyTenancy.convertHtmlContent(htmlContent, { margins: { top: 0.2, bottom: 0.2, left: 0.2, right: 0.2 }, diff --git a/shared/pdf-templates/src/components/ExportResourceTableTemplate.tsx b/shared/pdf-templates/src/components/ExportResourceTableTemplate.tsx new file mode 100644 index 000000000..42ac3c7f2 --- /dev/null +++ b/shared/pdf-templates/src/components/ExportResourceTableTemplate.tsx @@ -0,0 +1,119 @@ +import React from 'react'; +import { x } from '@xstyled/emotion'; +import { Box } from '../lib/layout/Box'; + +export interface ExportResourceTableColumn { + accessor: string; + name?: string; + style?: string; + group?: string; +} + +export interface ExportResourceTableCell { + key: string; + value: string; +} + +export interface ExportResourceTableRow { + cells: ExportResourceTableCell[]; + classNames?: string; +} + +export interface ExportResourceTableTemplateProps { + sheetTitle?: string; + sheetDescription?: string; + table: { + columns: ExportResourceTableColumn[]; + rows: ExportResourceTableRow[]; + }; + customCSS?: string; +} + +export function ExportResourceTableTemplate({ + sheetTitle, + sheetDescription, + table, + customCSS, +}: ExportResourceTableTemplateProps) { + return ( + + + {(sheetTitle || sheetDescription) && ( + + {sheetTitle && ( + + {sheetTitle} + + )} + {sheetDescription && ( + + {sheetDescription} + + )} + + )} + + + + + {table.columns.map((column) => { + let styleObj: React.CSSProperties | undefined; + if (column.style) { + try { + // Handle style as JSON string + styleObj = JSON.parse(column.style); + } catch { + // If parsing fails, ignore the style + styleObj = undefined; + } + } + return ( + + {column.name || column.accessor} + + ); + })} + + + + {table.rows.map((row, rowIndex) => ( + + {row.cells.map((cell) => ( + + + + ))} + + ))} + + + + {customCSS && ( + + )} + + + ); +} + diff --git a/shared/pdf-templates/src/index.ts b/shared/pdf-templates/src/index.ts index 51bae775e..5f9a7aee8 100644 --- a/shared/pdf-templates/src/index.ts +++ b/shared/pdf-templates/src/index.ts @@ -4,9 +4,11 @@ export * from './components/EstimatePaperTemplate'; export * from './components/ReceiptPaperTemplate'; export * from './components/PaymentReceivedPaperTemplate'; export * from './components/FinancialSheetTemplate'; +export * from './components/ExportResourceTableTemplate'; export * from './renders/render-invoice-paper-template'; export * from './renders/render-estimate-paper-template'; export * from './renders/render-receipt-paper-template'; export * from './renders/render-payment-received-paper-template'; export * from './renders/render-financial-sheet-template'; +export * from './renders/render-export-resource-table-template'; diff --git a/shared/pdf-templates/src/renders/render-export-resource-table-template.tsx b/shared/pdf-templates/src/renders/render-export-resource-table-template.tsx new file mode 100644 index 000000000..e4a1e6bf7 --- /dev/null +++ b/shared/pdf-templates/src/renders/render-export-resource-table-template.tsx @@ -0,0 +1,14 @@ +import { + ExportResourceTableTemplate, + ExportResourceTableTemplateProps, +} from '../components/ExportResourceTableTemplate'; +import { renderSSR } from './render-ssr'; + +export const renderExportResourceTableTemplateHtml = ( + props: ExportResourceTableTemplateProps +) => { + return renderSSR( + + ); +}; +