@@ -5,6 +5,22 @@ import autoTable from "jspdf-autotable";
55import { getCippFormatting } from "../utils/get-cipp-formatting" ;
66import { useSettings } from "../hooks/use-settings" ;
77
8+ // Flatten nested objects so deeply nested properties export properly.
9+ // This function only restructures data without formatting - formatting happens later in one pass.
10+ const flattenObject = ( obj , parentKey = "" ) => {
11+ const flattened = { } ;
12+ Object . keys ( obj ) . forEach ( ( key ) => {
13+ const fullKey = parentKey ? `${ parentKey } .${ key } ` : key ;
14+ if ( typeof obj [ key ] === "object" && obj [ key ] !== null && ! Array . isArray ( obj [ key ] ) ) {
15+ Object . assign ( flattened , flattenObject ( obj [ key ] , fullKey ) ) ;
16+ } else {
17+ // Store the raw value - formatting will happen in a single pass later
18+ flattened [ fullKey ] = obj [ key ] ;
19+ }
20+ } ) ;
21+ return flattened ;
22+ } ;
23+
824// Shared helper so the toolbar buttons and bulk export path share the same PDF logic.
925export const exportRowsToPdf = ( {
1026 rows = [ ] ,
@@ -21,7 +37,7 @@ export const exportRowsToPdf = ({
2137 const size = "A3" ;
2238 const orientation = "landscape" ;
2339 const doc = new jsPDF ( orientation , unit , size ) ;
24- const tableData = rows . map ( ( row ) => row . original ?? row ) ;
40+ const tableData = rows . map ( ( row ) => flattenObject ( row . original ?? row ) ) ;
2541
2642 const exportColumns = columns
2743 . filter ( ( c ) => columnVisibility [ c . id ] )
@@ -30,8 +46,11 @@ export const exportRowsToPdf = ({
3046 // Use the existing formatting helper so PDF output mirrors table formatting.
3147 const formattedData = tableData . map ( ( row ) => {
3248 const formattedRow = { } ;
33- Object . keys ( row ) . forEach ( ( key ) => {
34- formattedRow [ key ] = getCippFormatting ( row [ key ] , key , "text" , false ) ;
49+ exportColumns . forEach ( ( col ) => {
50+ const key = col . dataKey ;
51+ if ( key in row ) {
52+ formattedRow [ key ] = getCippFormatting ( row [ key ] , key , "text" , false ) ;
53+ }
3554 } ) ;
3655 return formattedRow ;
3756 } ) ;
@@ -58,15 +77,15 @@ export const exportRowsToPdf = ({
5877 const columnWidths = exportColumns . map ( ( col ) => {
5978 const headerLength = col . header . length ;
6079 const maxContentLength = Math . max (
61- ...formattedData . map ( ( row ) => String ( row [ col . dataKey ] || "" ) . length )
80+ ...formattedData . map ( ( row ) => String ( row [ col . dataKey ] || "" ) . length ) ,
6281 ) ;
6382 const estimatedWidth = Math . max ( headerLength , maxContentLength ) * 6 ;
6483 return Math . min ( estimatedWidth , ( availableWidth / columnCount ) * 1.5 ) ;
6584 } ) ;
6685
6786 const totalEstimatedWidth = columnWidths . reduce ( ( sum , width ) => sum + width , 0 ) ;
6887 const normalizedWidths = columnWidths . map (
69- ( width ) => ( width / totalEstimatedWidth ) * availableWidth
88+ ( width ) => ( width / totalEstimatedWidth ) * availableWidth ,
7089 ) ;
7190
7291 // Honor tenant branding colors when present so exports stay on-brand.
0 commit comments