Skip to content

Commit f94ce6d

Browse files
committed
fix(*): Export proper child data on inner levels
1 parent 24ab268 commit f94ce6d

File tree

1 file changed

+61
-52
lines changed

1 file changed

+61
-52
lines changed

projects/igniteui-angular/grids/core/src/services/pdf/pdf-exporter.ts

Lines changed: 61 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)