@@ -347,28 +347,21 @@ export class IgxPdfExporterService extends IgxBaseExporter {
347347
348348 // For hierarchical grids, check if this record has child records
349349 if ( recordIsHierarchicalGrid ) {
350- const allDescendants = [ ] ;
350+ const allDescendants : Array < IExportRecord & { __index : number } > = [ ] ;
351351
352- // Collect all descendant records (children, grandchildren, etc.) that belong to this parent
353- // Child records have a different owner (island object) than the parent
354352 let j = i + 1 ;
355353 while ( j < data . length && data [ j ] . level > record . level ) {
356- // Include all descendants (any level deeper)
357354 if ( ! data [ j ] . hidden ) {
358- allDescendants . push ( data [ j ] ) ;
355+ // Attach the original index into data
356+ allDescendants . push ( { ...( data [ j ] as any ) , __index : j } ) ;
359357 }
360358 j ++ ;
361359 }
362360
363- // If there are descendant records, draw child table(s)
364361 if ( allDescendants . length > 0 ) {
365- // Group descendants by owner to separate different child grids
366- // Owner is the actual island object, not a string
367- // Only collect DIRECT children (one level deeper) for initial grouping
368- const directDescendantsByOwner = new Map < any , IExportRecord [ ] > ( ) ;
362+ const directDescendantsByOwner = new Map < any , Array < IExportRecord & { __index : number } > > ( ) ;
369363
370364 for ( const desc of allDescendants ) {
371- // Only include records that are exactly one level deeper (direct children)
372365 if ( desc . level === record . level + 1 ) {
373366 const owner = desc . owner ;
374367 if ( ! directDescendantsByOwner . has ( owner ) ) {
@@ -378,13 +371,12 @@ export class IgxPdfExporterService extends IgxBaseExporter {
378371 }
379372 }
380373
381- // Draw each child grid separately with its direct children only
382374 for ( const [ owner , directChildren ] of directDescendantsByOwner ) {
383375 yPosition = this . drawHierarchicalChildren (
384376 pdf ,
385377 data ,
386- allDescendants , // Pass all descendants so grandchildren can be found
387- directChildren ,
378+ allDescendants , // descendants WITH __index
379+ directChildren , // direct children WITH __index
388380 owner ,
389381 yPosition ,
390382 margin ,
@@ -397,7 +389,6 @@ export class IgxPdfExporterService extends IgxBaseExporter {
397389 ) ;
398390 }
399391
400- // Skip the descendant records we just processed
401392 i = j - 1 ;
402393 }
403394 }
@@ -644,7 +635,7 @@ export class IgxPdfExporterService extends IgxBaseExporter {
644635 private drawHierarchicalChildren (
645636 pdf : jsPDF ,
646637 allData : IExportRecord [ ] ,
647- allDescendants : IExportRecord [ ] , // All descendants to search for grandchildren
638+ allDescendants : any [ ] , // All descendants to search for grandchildren
648639 childRecords : IExportRecord [ ] , // Direct children to render at this level
649640 childOwner : any , // Owner is the island object, not a string
650641 yPosition : number ,
@@ -768,49 +759,67 @@ export class IgxPdfExporterService extends IgxBaseExporter {
768759 this . drawDataRow ( pdf , childRecord , childColumns , [ ] , childTableX , yPosition , childColumnWidth , rowHeight , 0 , options ) ;
769760 yPosition += rowHeight ;
770761
771- // Check if this child has grandchildren (deeper levels in different child grids)
772- // Look for grandchildren in allDescendants that are direct descendants of this childRecord
773- const grandchildrenForThisRecord = allDescendants . filter ( r =>
774- r . level === childRecord . level + 1 && r . type !== 'HeaderRecord'
775- ) ;
762+ // allDescendants here is an array of records with an extra __index property
763+ const childIndex = ( childRecord as any ) . __index as number | undefined ;
764+
765+ if ( childIndex !== undefined ) {
766+ // Find this child's position in allDescendants (by original index)
767+ const childPosInDesc = allDescendants . findIndex ( d => d . __index === childIndex ) ;
776768
777- if ( grandchildrenForThisRecord . length > 0 ) {
778- // Group grandchildren by their owner (different child islands under this record)
779- const grandchildrenByOwner = new Map < any , IExportRecord [ ] > ( ) ;
780-
781- for ( const gc of grandchildrenForThisRecord ) {
782- // Use the actual owner object
783- const gcOwner = gc . owner ;
784- // Only include grandchildren that have a different owner (separate child grid)
785- if ( gcOwner !== childOwner ) {
786- if ( ! grandchildrenByOwner . has ( gcOwner ) ) {
787- grandchildrenByOwner . set ( gcOwner , [ ] ) ;
769+ if ( childPosInDesc !== - 1 ) {
770+ const subtree : Array < IExportRecord & { __index : number } > = [ ] ;
771+ const childLevel = childRecord . level ;
772+
773+ // Collect all deeper records until we hit same-or-higher level
774+ for ( let k = childPosInDesc + 1 ; k < allDescendants . length ; k ++ ) {
775+ const rec = allDescendants [ k ] ;
776+ if ( rec . level <= childLevel ) {
777+ break ;
778+ }
779+ if ( rec . type !== 'HeaderRecord' ) {
780+ subtree . push ( rec ) ;
788781 }
789- grandchildrenByOwner . get ( gcOwner ) ! . push ( gc ) ;
790782 }
791- }
792783
793- // Recursively draw each grandchild owner's records with increased indentation
794- for ( const [ gcOwner , directGrandchildren ] of grandchildrenByOwner ) {
795- yPosition = this . drawHierarchicalChildren (
796- pdf ,
797- allData ,
798- allDescendants , // Pass all descendants so great-grandchildren can be found
799- directGrandchildren , // Direct grandchildren to render
800- gcOwner ,
801- yPosition ,
802- margin ,
803- indentPerLevel + 20 , // Increase indentation for next level
804- usableWidth ,
805- pageHeight ,
806- headerHeight ,
807- rowHeight ,
808- options
809- ) ;
784+ if ( subtree . length > 0 ) {
785+ // Direct grandchildren for this child: exactly one level deeper
786+ const grandchildrenForThisRecord = subtree . filter ( r =>
787+ r . level === childRecord . level + 1 && r . owner !== childOwner
788+ ) ;
789+
790+ if ( grandchildrenForThisRecord . length > 0 ) {
791+ const grandchildrenByOwner = new Map < any , Array < IExportRecord & { __index : number } > > ( ) ;
792+
793+ for ( const gc of grandchildrenForThisRecord ) {
794+ const gcOwner = gc . owner ;
795+ if ( ! grandchildrenByOwner . has ( gcOwner ) ) {
796+ grandchildrenByOwner . set ( gcOwner , [ ] ) ;
797+ }
798+ grandchildrenByOwner . get ( gcOwner ) ! . push ( gc ) ;
799+ }
800+
801+ for ( const [ gcOwner , directGrandchildren ] of grandchildrenByOwner ) {
802+ yPosition = this . drawHierarchicalChildren (
803+ pdf ,
804+ allData ,
805+ subtree , // only this child's subtree for deeper levels
806+ directGrandchildren ,
807+ gcOwner ,
808+ yPosition ,
809+ margin ,
810+ indentPerLevel + 20 ,
811+ usableWidth ,
812+ pageHeight ,
813+ headerHeight ,
814+ rowHeight ,
815+ options
816+ ) ;
817+ }
818+ }
819+ }
810820 }
811821 }
812822 }
813-
814823 // Add spacing after child table
815824 yPosition += 5 ;
816825
0 commit comments