Skip to content

feat(igx-hierarchical-grid): export hierarchical grid #9206

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Apr 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ac06346
feat(igx-hierarchical-grid): export hierarchical grid
onlyexeption Mar 25, 2021
42b0ec5
feat(hierarchical-grid): excel export major refactoring
onlyexeption Mar 30, 2021
cbf04af
feat(hierarchical-grid): major refactoring
onlyexeption Apr 1, 2021
a2f69d1
feat(hierarchical-grid): major base-export refactoring
onlyexeption Apr 6, 2021
0858599
feat(hierarchical-grid): address PR comments
onlyexeption Apr 13, 2021
404743b
chore(*): add type to owner property
onlyexeption Apr 13, 2021
e2a1543
Merge branch 'master' into ibarakov/feat-5848-master
DiyanDimitrov Apr 15, 2021
7b3bba5
feat(hierarchical-grid): add tests for hGrid export + address PR comm…
onlyexeption Apr 15, 2021
68d7c09
Merge branch 'ibarakov/feat-5848-master' of https://github.com/Ignite…
onlyexeption Apr 15, 2021
cb4f0a0
Merge branch 'master' into ibarakov/feat-5848-master
gedinakova Apr 16, 2021
c72e9be
chore(*): minor changes regarding PR comments
onlyexeption Apr 16, 2021
41d6866
Merge branch 'ibarakov/feat-5848-master' of https://github.com/Ignite…
onlyexeption Apr 16, 2021
2e75f40
chore(*): fix expected data for styles.xml
onlyexeption Apr 16, 2021
8ada2ee
test(Excel): Fixed styles.xml template
gedinakova Apr 16, 2021
e903ac1
test(Excel): Fixed failing col visibility tests.
gedinakova Apr 16, 2021
4912115
Merge branch 'master' into ibarakov/feat-5848-master
gedinakova Apr 16, 2021
2edaef0
Merge branch 'ibarakov/feat-5848-master' of https://github.com/Ignite…
gedinakova Apr 16, 2021
519f9cf
Merge branch 'master' into ibarakov/feat-5848-master
gedinakova Apr 17, 2021
81e2043
Merge branch 'master' into ibarakov/feat-5848-master
gedinakova Apr 19, 2021
04e6b45
chore(*): fix tests + address PR comments
onlyexeption Apr 19, 2021
56a6dd5
Merge branch 'ibarakov/feat-5848-master' of https://github.com/Ignite…
onlyexeption Apr 19, 2021
c822ee2
chore(*): replace property
onlyexeption Apr 19, 2021
5467f57
chore(*): edit changelog.md
onlyexeption Apr 19, 2021
626dea1
chore(*): remove leftover comment
onlyexeption Apr 19, 2021
be9fd72
Merge branch 'master' into ibarakov/feat-5848-master
gedinakova Apr 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ All notable changes for each version of this project will be documented in this
- `onDataPreLoad` -> `dataPreLoad`

### New Features
- `IgxHierarchicalGrid`
- Added support for exporting hierarchical data.
- `IgxForOf`, `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid`
- **Behavioral Change** - Virtual containers now scroll smoothly when using the mouse wheel(s) to scroll them horizontally or vertically. This behavior more closely resembles the scrolling behavior of non-virtualized containers in most modern browsers.
- `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class CharSeparatedValueData {
return '';
}

this._isSpecialData = ExportUtilities.isSpecialData(this._data);
this._isSpecialData = ExportUtilities.isSpecialData(this._data[0]);
this._escapeCharacters.push(this._delimiter);

this._headerRecord = this.processHeaderRecord(keys);
Expand All @@ -52,7 +52,7 @@ export class CharSeparatedValueData {
done('');
}

this._isSpecialData = ExportUtilities.isSpecialData(this._data);
this._isSpecialData = ExportUtilities.isSpecialData(this._data[0]);
this._escapeCharacters.push(this._delimiter);

this._headerRecord = this.processHeaderRecord(keys);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,15 @@ import { configureTestSuite } from '../../test-utils/configure-suite';
import { IgxTreeGridPrimaryForeignKeyComponent } from '../../test-utils/tree-grid-components.spec';
import { IgxTreeGridModule, IgxTreeGridComponent } from '../../grids/tree-grid/public_api';
import { IgxNumberFilteringOperand } from '../../data-operations/filtering-condition';
import { wait } from '../../test-utils/ui-interactions.spec';
import { UIInteractions, wait } from '../../test-utils/ui-interactions.spec';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { FilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree';
import { FilteringLogic } from '../../data-operations/filtering-expression.interface';
import { IgxHierarchicalGridExportComponent } from '../../test-utils/hierarchical-grid-components.spec';
import { IgxHierarchicalGridModule,
IgxHierarchicalGridComponent,
} from '../../grids/hierarchical-grid/public_api';
import { IgxHierarchicalRowComponent } from '../../grids/hierarchical-grid/hierarchical-row.component';

describe('Excel Exporter', () => {
configureTestSuite();
Expand All @@ -47,9 +52,10 @@ describe('Excel Exporter', () => {
GridWithEmptyColumnsComponent,
GridIDNameJobTitleHireDataPerformanceComponent,
GridHireDateComponent,
GridExportGroupedDataComponent
GridExportGroupedDataComponent,
IgxHierarchicalGridExportComponent
],
imports: [IgxGridModule, IgxTreeGridModule, NoopAnimationsModule]
imports: [IgxGridModule, IgxTreeGridModule, IgxHierarchicalGridModule, NoopAnimationsModule]
}).compileComponents();
}));

Expand Down Expand Up @@ -140,7 +146,6 @@ describe('Excel Exporter', () => {
await wait();

const grid = fix.componentInstance.grid;
options.ignoreColumnsOrder = true;
options.ignoreColumnsVisibility = false;

expect(grid.visibleColumns.length).toEqual(3, 'Invalid number of visible columns!');
Expand Down Expand Up @@ -632,6 +637,101 @@ describe('Excel Exporter', () => {
});
});

describe('', () => {
let fix;
let hGrid: IgxHierarchicalGridComponent;

beforeEach(waitForAsync(() => {
options = createExportOptions('HierarchicalGridExcelExport');
fix = TestBed.createComponent(IgxHierarchicalGridExportComponent);
fix.detectChanges();

hGrid = fix.componentInstance.hGrid;
}));

it('should export hierarchical grid', async () => {
await exportAndVerify(hGrid, options, actualData.exportHierarchicalData);
});

it('should export hierarchical grid respecting options width.', async () => {
options = createExportOptions('HierarchicalGridExcelExport', 50);
await exportAndVerify(hGrid, options, actualData.exportHierarchicalDataWithColumnWidth);
});

it('should export sorted hierarchical grid data', async () => {
hGrid.sort({fieldName: 'GrammyNominations', dir: SortingDirection.Desc});

fix.detectChanges();

await exportAndVerify(hGrid, options, actualData.exportSortedHierarchicalData);
});

it('should export hierarchical grid data with ignored sorting', async () => {
hGrid.sort({fieldName: 'GrammyNominations', dir: SortingDirection.Desc});

options.ignoreSorting = true;
fix.detectChanges();

await exportAndVerify(hGrid, options, actualData.exportHierarchicalData);
});

it('should export filtered hierarchical grid data', async () => {
hGrid.filter('Debut', '2009', IgxStringFilteringOperand.instance().condition('contains'), true);
fix.detectChanges();

await exportAndVerify(hGrid, options, actualData.exportFilteredHierarchicalData);
});

it('should export hierarchical grid data with ignored filtering', async () => {
hGrid.filter('Debut', '2009', IgxStringFilteringOperand.instance().condition('contains'), true);
fix.detectChanges();

options.ignoreFiltering = true;

await exportAndVerify(hGrid, options, actualData.exportHierarchicalData);
});

it('should export hierarchical grid with expanded rows.', async () => {
const firstRow = hGrid.hgridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent;
const secondRow = hGrid.hgridAPI.get_row_by_index(1) as IgxHierarchicalRowComponent;

UIInteractions.simulateClickAndSelectEvent(firstRow.expander);
fix.detectChanges();
expect(firstRow.expanded).toBe(true);

let childGrids = hGrid.hgridAPI.getChildGrids(false);

const firstChildGrid = childGrids[0];
const firstChildRow = firstChildGrid.hgridAPI.get_row_by_index(2) as IgxHierarchicalRowComponent;

UIInteractions.simulateClickAndSelectEvent(firstChildRow.expander);
fix.detectChanges();
expect(firstChildRow.expanded).toBe(true);

const secondChildGrid = childGrids[1];
const secondChildRow = secondChildGrid.hgridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent;

UIInteractions.simulateClickAndSelectEvent(secondChildRow.expander);
fix.detectChanges();
expect(secondChildRow.expanded).toBe(true);

UIInteractions.simulateClickAndSelectEvent(secondRow.expander);
fix.detectChanges();
expect(secondRow.expanded).toBe(true);

childGrids = hGrid.hgridAPI.getChildGrids(false);

const thirdChildGrid = childGrids[3];
const thirdChildRow = thirdChildGrid.hgridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent;

UIInteractions.simulateClickAndSelectEvent(thirdChildRow.expander);
fix.detectChanges();
expect(thirdChildRow.expanded).toBe(true);

await exportAndVerify(hGrid, options, actualData.exportHierarchicalDataWithExpandedRows);
});
});

describe('', () => {
let fix;
let treeGrid: IgxTreeGridComponent;
Expand Down Expand Up @@ -855,9 +955,10 @@ describe('Excel Exporter', () => {
};

const exportAndVerify = async (component, exportOptions, expectedData) => {
const isHGrid = component instanceof IgxHierarchicalGridComponent;
const wrapper = await getExportedData(component, exportOptions);
await wrapper.verifyStructure();
await wrapper.verifyDataFilesContent(expectedData);
await wrapper.verifyStructure(isHGrid);
await wrapper.verifyDataFilesContent(expectedData, '', isHGrid);
};
});

Expand Down
28 changes: 24 additions & 4 deletions projects/igniteui-angular/src/lib/services/excel/excel-exporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ExcelElementsFactory } from './excel-elements-factory';
import { ExcelFolderTypes } from './excel-enums';
import { IgxExcelExporterOptions } from './excel-exporter-options';
import { IExcelFolder } from './excel-interfaces';
import { IExportRecord, IgxBaseExporter } from '../exporter-common/base-export-service';
import { ExportRecordType, IExportRecord, IgxBaseExporter, DEFAULT_OWNER } from '../exporter-common/base-export-service';
import { ExportUtilities } from '../exporter-common/export-utilities';
import { WorksheetData } from './worksheet-data';
import { IBaseEventArgs } from '../../core/utils';
Expand Down Expand Up @@ -72,9 +72,13 @@ export class IgxExcelExporterService extends IgxBaseExporter {
}

protected exportDataImplementation(data: IExportRecord[], options: IgxExcelExporterOptions): void {
const level = data[0]?.level;
const firstDataElement = data[0];
let rootKeys;
let columnCount;
let columnWidths;
let indexOfLastPinnedColumn;

if (typeof level !== 'undefined') {
if (typeof firstDataElement !== 'undefined') {
let maxLevel = 0;

data.forEach((r) => {
Expand All @@ -84,9 +88,25 @@ export class IgxExcelExporterService extends IgxBaseExporter {
if (maxLevel > 7) {
throw Error('Can create an outline of up to eight levels!');
}

if (firstDataElement.type === ExportRecordType.HierarchicalGridRecord) {
columnCount = data
.map(a => this._ownersMap.get(a.owner).columns.length + a.level)
.sort((a,b) => b - a)[0];

rootKeys = this._ownersMap.get(firstDataElement.owner).columns.map(c => c.header);
} else {
const defaultOwner = this._ownersMap.get(DEFAULT_OWNER);
const columns = defaultOwner.columns.filter(col => !col.skip);
columnWidths = defaultOwner.columnWidths;
indexOfLastPinnedColumn = defaultOwner.indexOfLastPinnedColumn;
columnCount = columns.length;
rootKeys = columns.map(c => c.header);
}
}

const worksheetData = new WorksheetData(data, this.columnWidthList, options, this._indexOfLastPinnedColumn, this._sort);
const worksheetData =
new WorksheetData(data, options, this._sort, columnCount, rootKeys, indexOfLastPinnedColumn, columnWidths);

this._xlsx = new (JSZip as any).default();

Expand Down
Loading