mirror of https://github.com/buster-so/buster.git
added additional styles
This commit is contained in:
parent
124997a1c0
commit
fb5abb8a75
|
@ -46,7 +46,7 @@ export const MetricTitle: React.FC<{
|
||||||
{`${name}`}
|
{`${name}`}
|
||||||
</Title>
|
</Title>
|
||||||
) : (
|
) : (
|
||||||
<div className="bg-item-active h-3.5 w-4/5 rounded-lg" />
|
<div className="bg-item-active/75 h-3.5 w-4/5 rounded-lg" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ export const MetricTitle: React.FC<{
|
||||||
{description}
|
{description}
|
||||||
</Text>
|
</Text>
|
||||||
) : (
|
) : (
|
||||||
<div className="bg-item-active mt-1 h-3.5 w-full rounded-lg" />
|
<div className="bg-item-active/75 mt-1 h-3.5 w-full rounded-lg" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,7 +12,10 @@ export const useExportReport = () => {
|
||||||
const getCanvas = async (editor: PlateEditor) => {
|
const getCanvas = async (editor: PlateEditor) => {
|
||||||
const { default: html2canvas } = await import('html2canvas-pro');
|
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');
|
const style = document.createElement('style');
|
||||||
|
style.setAttribute('data-report-export-style', 'true');
|
||||||
document.head.append(style);
|
document.head.append(style);
|
||||||
|
|
||||||
// Standard width for consistent PDF output (equivalent to A4 width with margins)
|
// 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)!;
|
const node = editor.api.toDOMNode(editor)!;
|
||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
|
// Ensure cleanup of style element if editor is missing
|
||||||
|
style.remove();
|
||||||
throw new Error('Editor not found');
|
throw new Error('Editor not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
const canvas = await html2canvas(node, {
|
try {
|
||||||
onclone: (document: Document) => {
|
const canvas = await html2canvas(node, {
|
||||||
const editorElement = document.querySelector('[contenteditable="true"]');
|
onclone: (document: Document) => {
|
||||||
if (editorElement) {
|
const editorElement = document.querySelector('[contenteditable="true"]');
|
||||||
// Force consistent width for the editor element
|
if (editorElement) {
|
||||||
const existingStyle = editorElement.getAttribute('style') || '';
|
// Force consistent width for the editor element
|
||||||
editorElement.setAttribute(
|
const existingStyle = editorElement.getAttribute('style') || '';
|
||||||
'style',
|
editorElement.setAttribute(
|
||||||
`${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(
|
|
||||||
'style',
|
'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) => {
|
const downloadFile = async (url: string, filename: string) => {
|
||||||
|
@ -89,6 +97,7 @@ export const useExportReport = () => {
|
||||||
await downloadFile(pdfBase64, 'plate.pdf');
|
await downloadFile(pdfBase64, 'plate.pdf');
|
||||||
openInfoMessage(NodeTypeLabels.pdfExportedSuccessfully.label);
|
openInfoMessage(NodeTypeLabels.pdfExportedSuccessfully.label);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
openErrorMessage(NodeTypeLabels.failedToExportPdf.label);
|
openErrorMessage(NodeTypeLabels.failedToExportPdf.label);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -99,6 +108,7 @@ export const useExportReport = () => {
|
||||||
await downloadFile(canvas.toDataURL('image/png'), 'plate.png');
|
await downloadFile(canvas.toDataURL('image/png'), 'plate.png');
|
||||||
openInfoMessage(NodeTypeLabels.imageExportedSuccessfully.label);
|
openInfoMessage(NodeTypeLabels.imageExportedSuccessfully.label);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
openErrorMessage(NodeTypeLabels.failedToExportImage.label);
|
openErrorMessage(NodeTypeLabels.failedToExportImage.label);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -154,6 +164,7 @@ export const useExportReport = () => {
|
||||||
await downloadFile(url, 'plate.html');
|
await downloadFile(url, 'plate.html');
|
||||||
openInfoMessage(NodeTypeLabels.htmlExportedSuccessfully.label);
|
openInfoMessage(NodeTypeLabels.htmlExportedSuccessfully.label);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
openErrorMessage(NodeTypeLabels.failedToExportHtml.label);
|
openErrorMessage(NodeTypeLabels.failedToExportHtml.label);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -165,6 +176,7 @@ export const useExportReport = () => {
|
||||||
await downloadFile(url, 'plate.md');
|
await downloadFile(url, 'plate.md');
|
||||||
openInfoMessage(NodeTypeLabels.markdownExportedSuccessfully.label);
|
openInfoMessage(NodeTypeLabels.markdownExportedSuccessfully.label);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
openErrorMessage(NodeTypeLabels.failedToExportMarkdown.label);
|
openErrorMessage(NodeTypeLabels.failedToExportMarkdown.label);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -314,19 +314,22 @@ const useDuplicateReportSelectMenu = (): DropdownItem => {
|
||||||
// Download as PDF
|
// Download as PDF
|
||||||
const useDownloadPdfSelectMenu = ({ reportId }: { reportId: string }): DropdownItem => {
|
const useDownloadPdfSelectMenu = ({ reportId }: { reportId: string }): DropdownItem => {
|
||||||
const { openErrorMessage } = useBusterNotifications();
|
const { openErrorMessage } = useBusterNotifications();
|
||||||
const editor = getReportEditor(reportId);
|
|
||||||
const { exportToPdf } = useExportReport();
|
const { exportToPdf } = useExportReport();
|
||||||
|
|
||||||
const onClick = async () => {
|
const onClick = async () => {
|
||||||
try {
|
try {
|
||||||
|
const editor = getReportEditor(reportId);
|
||||||
|
|
||||||
if (!editor) {
|
if (!editor) {
|
||||||
|
console.error('Editor not found');
|
||||||
openErrorMessage(NodeTypeLabels.failedToExportPdf.label);
|
openErrorMessage(NodeTypeLabels.failedToExportPdf.label);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await exportToPdf(editor);
|
await exportToPdf(editor);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
openErrorMessage('Failed to export PDF');
|
console.error(error);
|
||||||
|
openErrorMessage('Failed to export report as PDF');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue