@@ -352,28 +352,21 @@ export class IgxPdfExporterService extends IgxBaseExporter {
352352
353353 // For hierarchical grids, check if this record has child records
354354 if ( recordIsHierarchicalGrid ) {
355- const allDescendants = [ ] ;
355+ const allDescendants : Array < IExportRecord & { __index : number } > = [ ] ;
356356
357- // Collect all descendant records (children, grandchildren, etc.) that belong to this parent
358- // Child records have a different owner (island object) than the parent
359357 let j = i + 1 ;
360358 while ( j < data . length && data [ j ] . level > record . level ) {
361- // Include all descendants (any level deeper)
362359 if ( ! data [ j ] . hidden ) {
363- allDescendants . push ( data [ j ] ) ;
360+ // Attach the original index into data
361+ allDescendants . push ( { ...( data [ j ] as any ) , __index : j } ) ;
364362 }
365363 j ++ ;
366364 }
367365
368- // If there are descendant records, draw child table(s)
369366 if ( allDescendants . length > 0 ) {
370- // Group descendants by owner to separate different child grids
371- // Owner is the actual island object, not a string
372- // Only collect DIRECT children (one level deeper) for initial grouping
373- const directDescendantsByOwner = new Map < any , IExportRecord [ ] > ( ) ;
367+ const directDescendantsByOwner = new Map < any , Array < IExportRecord & { __index : number } > > ( ) ;
374368
375369 for ( const desc of allDescendants ) {
376- // Only include records that are exactly one level deeper (direct children)
377370 if ( desc . level === record . level + 1 ) {
378371 const owner = desc . owner ;
379372 if ( ! directDescendantsByOwner . has ( owner ) ) {
@@ -383,13 +376,12 @@ export class IgxPdfExporterService extends IgxBaseExporter {
383376 }
384377 }
385378
386- // Draw each child grid separately with its direct children only
387379 for ( const [ owner , directChildren ] of directDescendantsByOwner ) {
388380 yPosition = this . drawHierarchicalChildren (
389381 pdf ,
390382 data ,
391- allDescendants , // Pass all descendants so grandchildren can be found
392- directChildren ,
383+ allDescendants , // descendants WITH __index
384+ directChildren , // direct children WITH __index
393385 owner ,
394386 yPosition ,
395387 margin ,
@@ -402,7 +394,6 @@ export class IgxPdfExporterService extends IgxBaseExporter {
402394 ) ;
403395 }
404396
405- // Skip the descendant records we just processed
406397 i = j - 1 ;
407398 }
408399 }
@@ -649,7 +640,7 @@ export class IgxPdfExporterService extends IgxBaseExporter {
649640 private drawHierarchicalChildren (
650641 pdf : jsPDF ,
651642 allData : IExportRecord [ ] ,
652- allDescendants : IExportRecord [ ] , // All descendants to search for grandchildren
643+ allDescendants : any [ ] , // All descendants to search for grandchildren
653644 childRecords : IExportRecord [ ] , // Direct children to render at this level
654645 childOwner : any , // Owner is the island object, not a string
655646 yPosition : number ,
@@ -773,49 +764,67 @@ export class IgxPdfExporterService extends IgxBaseExporter {
773764 this . drawDataRow ( pdf , childRecord , childColumns , [ ] , childTableX , yPosition , childColumnWidth , rowHeight , 0 , options ) ;
774765 yPosition += rowHeight ;
775766
776- // Check if this child has grandchildren (deeper levels in different child grids)
777- // Look for grandchildren in allDescendants that are direct descendants of this childRecord
778- const grandchildrenForThisRecord = allDescendants . filter ( r =>
779- r . level === childRecord . level + 1 && r . type !== 'HeaderRecord'
780- ) ;
767+ // allDescendants here is an array of records with an extra __index property
768+ const childIndex = ( childRecord as any ) . __index as number | undefined ;
769+
770+ if ( childIndex !== undefined ) {
771+ // Find this child's position in allDescendants (by original index)
772+ const childPosInDesc = allDescendants . findIndex ( d => d . __index === childIndex ) ;
781773
782- if ( grandchildrenForThisRecord . length > 0 ) {
783- // Group grandchildren by their owner (different child islands under this record)
784- const grandchildrenByOwner = new Map < any , IExportRecord [ ] > ( ) ;
785-
786- for ( const gc of grandchildrenForThisRecord ) {
787- // Use the actual owner object
788- const gcOwner = gc . owner ;
789- // Only include grandchildren that have a different owner (separate child grid)
790- if ( gcOwner !== childOwner ) {
791- if ( ! grandchildrenByOwner . has ( gcOwner ) ) {
792- grandchildrenByOwner . set ( gcOwner , [ ] ) ;
774+ if ( childPosInDesc !== - 1 ) {
775+ const subtree : Array < IExportRecord & { __index : number } > = [ ] ;
776+ const childLevel = childRecord . level ;
777+
778+ // Collect all deeper records until we hit same-or-higher level
779+ for ( let k = childPosInDesc + 1 ; k < allDescendants . length ; k ++ ) {
780+ const rec = allDescendants [ k ] ;
781+ if ( rec . level <= childLevel ) {
782+ break ;
783+ }
784+ if ( rec . type !== 'HeaderRecord' ) {
785+ subtree . push ( rec ) ;
793786 }
794- grandchildrenByOwner . get ( gcOwner ) ! . push ( gc ) ;
795787 }
796- }
797788
798- // Recursively draw each grandchild owner's records with increased indentation
799- for ( const [ gcOwner , directGrandchildren ] of grandchildrenByOwner ) {
800- yPosition = this . drawHierarchicalChildren (
801- pdf ,
802- allData ,
803- allDescendants , // Pass all descendants so great-grandchildren can be found
804- directGrandchildren , // Direct grandchildren to render
805- gcOwner ,
806- yPosition ,
807- margin ,
808- indentPerLevel + 20 , // Increase indentation for next level
809- usableWidth ,
810- pageHeight ,
811- headerHeight ,
812- rowHeight ,
813- options
814- ) ;
789+ if ( subtree . length > 0 ) {
790+ // Direct grandchildren for this child: exactly one level deeper
791+ const grandchildrenForThisRecord = subtree . filter ( r =>
792+ r . level === childRecord . level + 1 && r . owner !== childOwner
793+ ) ;
794+
795+ if ( grandchildrenForThisRecord . length > 0 ) {
796+ const grandchildrenByOwner = new Map < any , Array < IExportRecord & { __index : number } > > ( ) ;
797+
798+ for ( const gc of grandchildrenForThisRecord ) {
799+ const gcOwner = gc . owner ;
800+ if ( ! grandchildrenByOwner . has ( gcOwner ) ) {
801+ grandchildrenByOwner . set ( gcOwner , [ ] ) ;
802+ }
803+ grandchildrenByOwner . get ( gcOwner ) ! . push ( gc ) ;
804+ }
805+
806+ for ( const [ gcOwner , directGrandchildren ] of grandchildrenByOwner ) {
807+ yPosition = this . drawHierarchicalChildren (
808+ pdf ,
809+ allData ,
810+ subtree , // only this child's subtree for deeper levels
811+ directGrandchildren ,
812+ gcOwner ,
813+ yPosition ,
814+ margin ,
815+ indentPerLevel + 20 ,
816+ usableWidth ,
817+ pageHeight ,
818+ headerHeight ,
819+ rowHeight ,
820+ options
821+ ) ;
822+ }
823+ }
824+ }
815825 }
816826 }
817827 }
818-
819828 // Add spacing after child table
820829 yPosition += 5 ;
821830
0 commit comments