From fb5abb8a75e2738cb1eab041b96a66a0f201e9d0 Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Fri, 8 Aug 2025 11:05:55 -0600 Subject: [PATCH] added additional styles --- .../src/components/ui/metric/MetricTitle.tsx | 4 +- .../ui/report/hooks/useExportReport.ts | 60 +++++++++++-------- .../ReportThreeDotMenu.tsx | 7 ++- 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/apps/web/src/components/ui/metric/MetricTitle.tsx b/apps/web/src/components/ui/metric/MetricTitle.tsx index 045beba14..892a5ff5e 100644 --- a/apps/web/src/components/ui/metric/MetricTitle.tsx +++ b/apps/web/src/components/ui/metric/MetricTitle.tsx @@ -46,7 +46,7 @@ export const MetricTitle: React.FC<{ {`${name}`} ) : ( -
+
)}
@@ -64,7 +64,7 @@ export const MetricTitle: React.FC<{ {description} ) : ( -
+
)}
diff --git a/apps/web/src/components/ui/report/hooks/useExportReport.ts b/apps/web/src/components/ui/report/hooks/useExportReport.ts index b4f2bd1ea..22df3a923 100644 --- a/apps/web/src/components/ui/report/hooks/useExportReport.ts +++ b/apps/web/src/components/ui/report/hooks/useExportReport.ts @@ -12,7 +12,10 @@ export const useExportReport = () => { const getCanvas = async (editor: PlateEditor) => { const { default: html2canvas } = await import('html2canvas-pro'); + // Create a temporary style element to isolate any styles needed during export. + // Ensure it is always cleaned up, even if an error occurs during rendering. const style = document.createElement('style'); + style.setAttribute('data-report-export-style', 'true'); document.head.append(style); // Standard width for consistent PDF output (equivalent to A4 width with margins) @@ -21,36 +24,41 @@ export const useExportReport = () => { const node = editor.api.toDOMNode(editor)!; if (!node) { + // Ensure cleanup of style element if editor is missing + style.remove(); throw new Error('Editor not found'); } - const canvas = await html2canvas(node, { - onclone: (document: Document) => { - const editorElement = document.querySelector('[contenteditable="true"]'); - if (editorElement) { - // Force consistent width for the editor element - const existingStyle = editorElement.getAttribute('style') || ''; - editorElement.setAttribute( - 'style', - `${existingStyle}; width: ${standardWidth} !important; max-width: ${standardWidth} !important; min-width: ${standardWidth} !important;` - ); - - // Apply consistent font family to all elements - Array.from(editorElement.querySelectorAll('*')).forEach((element) => { - const elementStyle = element.getAttribute('style') || ''; - element.setAttribute( + try { + const canvas = await html2canvas(node, { + onclone: (document: Document) => { + const editorElement = document.querySelector('[contenteditable="true"]'); + if (editorElement) { + // Force consistent width for the editor element + const existingStyle = editorElement.getAttribute('style') || ''; + editorElement.setAttribute( 'style', - `${elementStyle}; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif !important` + `${existingStyle}; width: ${standardWidth} !important; max-width: ${standardWidth} !important; min-width: ${standardWidth} !important;` ); - }); - } else { - throw new Error('Editor element not found'); - } - } - }); - style.remove(); - return canvas; + // Apply consistent font family to all elements + Array.from(editorElement.querySelectorAll('*')).forEach((element) => { + const elementStyle = element.getAttribute('style') || ''; + element.setAttribute( + 'style', + `${elementStyle}; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif !important` + ); + }); + } else { + throw new Error('Editor element not found'); + } + } + }); + return canvas; + } finally { + // Always remove temporary style tag + style.remove(); + } }; const downloadFile = async (url: string, filename: string) => { @@ -89,6 +97,7 @@ export const useExportReport = () => { await downloadFile(pdfBase64, 'plate.pdf'); openInfoMessage(NodeTypeLabels.pdfExportedSuccessfully.label); } catch (error) { + console.error(error); openErrorMessage(NodeTypeLabels.failedToExportPdf.label); } }; @@ -99,6 +108,7 @@ export const useExportReport = () => { await downloadFile(canvas.toDataURL('image/png'), 'plate.png'); openInfoMessage(NodeTypeLabels.imageExportedSuccessfully.label); } catch (error) { + console.error(error); openErrorMessage(NodeTypeLabels.failedToExportImage.label); } }; @@ -154,6 +164,7 @@ export const useExportReport = () => { await downloadFile(url, 'plate.html'); openInfoMessage(NodeTypeLabels.htmlExportedSuccessfully.label); } catch (error) { + console.error(error); openErrorMessage(NodeTypeLabels.failedToExportHtml.label); } }; @@ -165,6 +176,7 @@ export const useExportReport = () => { await downloadFile(url, 'plate.md'); openInfoMessage(NodeTypeLabels.markdownExportedSuccessfully.label); } catch (error) { + console.error(error); openErrorMessage(NodeTypeLabels.failedToExportMarkdown.label); } }; diff --git a/apps/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/ReportContainerHeaderButtons/ReportThreeDotMenu.tsx b/apps/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/ReportContainerHeaderButtons/ReportThreeDotMenu.tsx index 51d297dce..f21f2e8b0 100644 --- a/apps/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/ReportContainerHeaderButtons/ReportThreeDotMenu.tsx +++ b/apps/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/ReportContainerHeaderButtons/ReportThreeDotMenu.tsx @@ -314,19 +314,22 @@ const useDuplicateReportSelectMenu = (): DropdownItem => { // Download as PDF const useDownloadPdfSelectMenu = ({ reportId }: { reportId: string }): DropdownItem => { const { openErrorMessage } = useBusterNotifications(); - const editor = getReportEditor(reportId); const { exportToPdf } = useExportReport(); const onClick = async () => { try { + const editor = getReportEditor(reportId); + if (!editor) { + console.error('Editor not found'); openErrorMessage(NodeTypeLabels.failedToExportPdf.label); return; } await exportToPdf(editor); } catch (error) { - openErrorMessage('Failed to export PDF'); + console.error(error); + openErrorMessage('Failed to export report as PDF'); } };