diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a13501965..672f4847e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to - #1282 - ♻️(backend) fallback to email identifier when no name #1298 - 🐛(backend) allow ASCII characters in user sub field #1295 +- ⚡️(frontend) improve fallback width calculation #1333 ### Fixed diff --git a/src/frontend/apps/impress/src/features/docs/doc-export/__tests__/TablePDF.test.tsx b/src/frontend/apps/impress/src/features/docs/doc-export/__tests__/TablePDF.test.tsx new file mode 100644 index 0000000000..bc33b12ec5 --- /dev/null +++ b/src/frontend/apps/impress/src/features/docs/doc-export/__tests__/TablePDF.test.tsx @@ -0,0 +1,64 @@ +import { describe, expect, it } from 'vitest'; + +import { utilTable } from '../blocks-mapping/tablePDF'; + +/** + * Tests for utilTable utility. + * Scenarios covered: + * - All widths specified and below full width + * - Mix of known / unknown widths (fallback distribution) + * - All widths unknown + * - Widths exceeding full table width (clamping & scale=100) + * - Sum exceeding full width without unknowns (no division by zero side-effects) + */ + +describe('utilTable', () => { + it('returns unchanged widths and correct scale when all widths are known and below full width', () => { + const input = [165, 200]; + const { columnWidths, tableScale } = utilTable(730, input); + expect(columnWidths).toEqual(input); // unchanged + expect(tableScale).toBe(50); + }); + + it('distributes fallback width equally among unknown columns', () => { + const input: (number | undefined)[] = [100, undefined, 200, undefined]; + const { columnWidths, tableScale } = utilTable(730, input); + expect(columnWidths).toEqual([100, 215, 200, 215]); + expect(tableScale).toBe(100); // fills full width exactly + }); + + it('handles all columns unknown', () => { + const input: (number | undefined)[] = [undefined, undefined]; + const { columnWidths, tableScale } = utilTable(730, input); + expect(columnWidths).toEqual([365, 365]); + expect(tableScale).toBe(100); + }); + + it('clamps total width to full width when sum exceeds it (single large column)', () => { + const input = [800]; + const { columnWidths, tableScale } = utilTable(730, input); + expect(columnWidths).toEqual([800]); + expect(tableScale).toBe(100); + }); + + it('clamps total width to full width when multiple columns exceed it', () => { + const input = [500, 300]; // sum = 800 > 730 + const { columnWidths, tableScale } = utilTable(730, input); + expect(columnWidths).toEqual([500, 300]); + expect(tableScale).toBe(100); + }); + + it('does not assign fallback when there are no unknown widths (avoid division by zero impact)', () => { + const input = [400, 400]; + const { columnWidths, tableScale } = utilTable(730, input); + expect(columnWidths).toEqual([400, 400]); + expect(tableScale).toBe(100); + }); + + it('computes proportional scale with custom fullWidth', () => { + const input = [100, 200]; // total 300 + const { columnWidths, tableScale } = utilTable(1000, input); + expect(columnWidths).toEqual([100, 200]); + expect(tableScale).toBe(30); + }); +}); diff --git a/src/frontend/apps/impress/src/features/docs/doc-export/blocks-mapping/tablePDF.tsx b/src/frontend/apps/impress/src/features/docs/doc-export/blocks-mapping/tablePDF.tsx index 878c88ea5e..d33a29cd35 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-export/blocks-mapping/tablePDF.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-export/blocks-mapping/tablePDF.tsx @@ -13,6 +13,7 @@ import { StyleSheet, Text } from '@react-pdf/renderer'; import { DocsExporterPDF } from '../types'; const PIXELS_PER_POINT = 0.75; +const FULL_WIDTH = 730; const styles = StyleSheet.create({ tableContainer: { border: '1px solid #ddd', @@ -47,16 +48,10 @@ export const blockMappingTablePDF: DocsExporterPDF['mappings']['blockMapping'][' true, ) as boolean[]; - /** - * Calculate the table scale based on the column widths. - */ - const columnWidths = blockContent.columnWidths.map((w) => w || 120); - const fullWidth = 730; - const totalWidth = Math.min( - columnWidths.reduce((sum, w) => sum + w, 0), - fullWidth, + const { columnWidths, tableScale } = utilTable( + FULL_WIDTH, + blockContent.columnWidths, ); - const tableScale = (totalWidth * 100) / fullWidth; return (