refactor(export): move PDF table template to shared package

This commit is contained in:
Ahmed Bouhuolia
2025-12-29 23:54:43 +02:00
parent 350d229e98
commit 339289be9f
4 changed files with 143 additions and 12 deletions

View File

@@ -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<string, any>,
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 },

View File

@@ -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 (
<Box fontSize="12px" lineHeight="1.4" fontFamily='system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"'>
<Box p="20px">
{(sheetTitle || sheetDescription) && (
<Box mb="18px" className="sheet__title">
{sheetTitle && (
<x.h2 m={0} mb="10px" fontSize="16px" lineHeight="1" className="sheetTitle">
{sheetTitle}
</x.h2>
)}
{sheetDescription && (
<x.p m={0} className="sheetDesc">
{sheetDescription}
</x.p>
)}
</Box>
)}
<x.table
className="sheet__table"
fontSize="inherit"
lineHeight="inherit"
w="100%"
tableLayout="auto"
borderCollapse="collapse"
>
<x.thead>
<x.tr>
{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 (
<x.th
key={column.accessor}
borderTop="1px solid #000"
borderBottom="1px solid #000"
bg="#fff"
p="4px"
lineHeight="1.2"
className={`column--${column.accessor}`}
style={styleObj}
>
{column.name || column.accessor}
</x.th>
);
})}
</x.tr>
</x.thead>
<x.tbody>
{table.rows.map((row, rowIndex) => (
<x.tr key={rowIndex} className={row.classNames}>
{row.cells.map((cell) => (
<x.td
key={cell.key}
p="4px 8px"
borderBottom="1px solid #CCC"
className={`cell--${cell.key}`}
>
<span dangerouslySetInnerHTML={{ __html: cell.value }} />
</x.td>
))}
</x.tr>
))}
</x.tbody>
</x.table>
{customCSS && (
<x.style dangerouslySetInnerHTML={{ __html: customCSS }} />
)}
</Box>
</Box>
);
}

View File

@@ -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';

View File

@@ -0,0 +1,14 @@
import {
ExportResourceTableTemplate,
ExportResourceTableTemplateProps,
} from '../components/ExportResourceTableTemplate';
import { renderSSR } from './render-ssr';
export const renderExportResourceTableTemplateHtml = (
props: ExportResourceTableTemplateProps
) => {
return renderSSR(
<ExportResourceTableTemplate {...props} />
);
};