Skip to content

Commit 514f3f8

Browse files
authored
fix(tree-grid): correctly process esf when tree grid grouping is enabled (#17338)
* test(esf): add a tree grid test with grouping * test(esf): add tree grid test checking esf items * fix(search): enhance filtering logic for tree grid with group by support * chore: address review comments * chore: resolve comments again
1 parent 70c2bd4 commit 514f3f8

3 files changed

Lines changed: 71 additions & 15 deletions

File tree

projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-search.component.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export class IgxExcelStyleLoadingValuesTemplateDirective {
3030
}
3131

3232
let NEXT_ID = 0;
33+
const TREE_GRID_GROUPING_HIDDEN_FIELD = '_Igx_Hidden_Data_';
3334
/**
3435
* A component used for presenting Excel style search UI.
3536
*/
@@ -612,7 +613,7 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy {
612613
searchVal = new Set(selectedItems.map(e => e.value.toLocaleTimeString()));
613614
break;
614615
case GridColumnDataType.String:
615-
if (this.esf.column.filteringIgnoreCase && !this.isHierarchical() && !this.isRemote()) {
616+
if (this.esf.column.filteringIgnoreCase && !this.isHierarchical() && !this.isTreeGridWithGroupBy() && !this.isRemote()) {
616617
const selectedValues = new Set(selectedItems.map(item => item.value.toLowerCase()));
617618
searchVal = new Set();
618619

@@ -899,6 +900,15 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy {
899900
return subRequired;
900901
}
901902

903+
private isTreeGridWithGroupBy(): boolean {
904+
if (this.esf.grid.type !== 'tree') {
905+
return false;
906+
}
907+
const data = this.esf.grid.data;
908+
const firstRecord = Array.isArray(data) && data.length > 0 ? data[0] : null;
909+
return !!firstRecord && typeof firstRecord === 'object' && Object.prototype.hasOwnProperty.call(firstRecord, TREE_GRID_GROUPING_HIDDEN_FIELD);
910+
}
911+
902912
private isRemote(): boolean {
903913
return this.esf.grid.verticalScrollContainer.isRemote || this.esf.grid.pagingMode === GridPagingMode.Remote;
904914
}

projects/igniteui-angular/grids/tree-grid/src/tree-grid-grouping.spec.ts

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { IgxTreeGridGroupByAreaComponent } from 'igniteui-angular/grids/tree-gri
66
import { TreeGridFunctions } from '../../../test-utils/tree-grid-functions.spec';
77
import { IgxTreeGridComponent } from './tree-grid.component';
88
import { DefaultSortingStrategy } from 'igniteui-angular/core';
9+
import { GridFunctions } from '../../../test-utils/grid-functions.spec';
910

1011
describe('IgxTreeGrid', () => {
1112

@@ -24,7 +25,7 @@ describe('IgxTreeGrid', () => {
2425
let groupByArea: IgxTreeGridGroupByAreaComponent;
2526

2627
const DROP_AREA_MSG = 'Drag a column header and drop it here to group by that column.';
27-
describe(' GroupByArea Standalone', ()=> {
28+
describe(' GroupByArea Standalone', () => {
2829

2930
beforeEach(() => {
3031
fix = TestBed.createComponent(IgxTreeGridGroupByAreaTestComponent);
@@ -53,7 +54,7 @@ describe('IgxTreeGrid', () => {
5354
expect(spanElement.innerText).toEqual(DROP_AREA_MSG);
5455
}));
5556

56-
it ('has the expected default properties\' values', fakeAsync(() => {
57+
it('has the expected default properties\' values', fakeAsync(() => {
5758
expect(groupByArea).toBeDefined();
5859
expect(groupByArea.grid).toEqual(treeGrid);
5960
expect(groupByArea.expressions).toEqual([]);
@@ -97,7 +98,7 @@ describe('IgxTreeGrid', () => {
9798
clearGridSubs();
9899
});
99100

100-
it ('GroupByArea has the expected properties\' values set', fakeAsync(() => {
101+
it('GroupByArea has the expected properties\' values set', fakeAsync(() => {
101102
expect(groupByArea).toBeDefined();
102103
expect(groupByArea.expressions.length).toEqual(2);
103104
expect(groupByArea.grid).toEqual(treeGrid);
@@ -132,7 +133,7 @@ describe('IgxTreeGrid', () => {
132133
expect(chips[0].id).toEqual('OnPTO');
133134
expect(chips[1].id).toEqual('HireDate');
134135

135-
groupingExpressions.push({ fieldName: 'JobTitle', dir: 2, ignoreCase: true, strategy: DefaultSortingStrategy.instance()});
136+
groupingExpressions.push({ fieldName: 'JobTitle', dir: 2, ignoreCase: true, strategy: DefaultSortingStrategy.instance() });
136137
fix.detectChanges();
137138
tick();
138139

@@ -180,7 +181,7 @@ describe('IgxTreeGrid', () => {
180181

181182
expect(treeGrid.getColumnByName('HireDate').hidden).toBeFalse();
182183

183-
groupingExpressions.push({ fieldName: 'JobTitle', dir: 2, ignoreCase: true, strategy: DefaultSortingStrategy.instance()});
184+
groupingExpressions.push({ fieldName: 'JobTitle', dir: 2, ignoreCase: true, strategy: DefaultSortingStrategy.instance() });
184185
groupByArea.expressions = [...groupingExpressions];
185186
fix.detectChanges();
186187
tick();
@@ -195,7 +196,7 @@ describe('IgxTreeGrid', () => {
195196
const aggregations = [{
196197
field: 'HireDate',
197198
aggregate: (_parent: any, children: any[]) => children.map((c) => c.HireDate)
198-
.reduce((min, c) => min < c ? min : c, new Date())
199+
.reduce((min, c) => min < c ? min : c, new Date())
199200
}];
200201

201202
fix.componentInstance.aggregations = aggregations;
@@ -296,6 +297,51 @@ describe('IgxTreeGrid', () => {
296297
expect(treeGrid.getColumnByName('OnPTO').hidden).toBeTrue();
297298
expect(treeGrid.getColumnByName('HireDate').hidden).toBeTrue();
298299
}));
300+
301+
it('should handle excel style filtering when grouping is applied and 3 or more items are selected', fakeAsync(() => {
302+
treeGrid.filterMode = 'excelStyleFilter';
303+
treeGrid.allowFiltering = true;
304+
treeGrid.expansionDepth = Infinity;
305+
fix.detectChanges();
306+
GridFunctions.clickExcelFilterIconFromCode(fix, treeGrid, 'Name');
307+
const checkboxes = GridFunctions.getExcelStyleFilteringCheckboxes(fix, null, 'igx-tree-grid');
308+
// unselect all
309+
checkboxes[0].click();
310+
fix.detectChanges();
311+
312+
checkboxes[2].click();
313+
checkboxes[3].click();
314+
checkboxes[4].click();
315+
fix.detectChanges();
316+
317+
GridFunctions.clickApplyExcelStyleFiltering(fix, null, 'igx-tree-grid');
318+
fix.detectChanges();
319+
320+
321+
expect(treeGrid.filteredData.length).toEqual(8);
322+
}));
323+
324+
it('should handle excel style filtering when grouping is applied and preserve all checked esf items', fakeAsync(() => {
325+
treeGrid.filterMode = 'excelStyleFilter';
326+
treeGrid.allowFiltering = true;
327+
treeGrid.expansionDepth = Infinity;
328+
fix.detectChanges();
329+
GridFunctions.clickExcelFilterIconFromCode(fix, treeGrid, 'Name');
330+
let checkboxes: HTMLInputElement[] = Array.from(GridFunctions.getExcelStyleFilteringCheckboxes(fix, null, 'igx-tree-grid') as HTMLInputElement[]);
331+
// unselect just one
332+
checkboxes[2].click();
333+
fix.detectChanges();
334+
335+
GridFunctions.clickApplyExcelStyleFiltering(fix, null, 'igx-tree-grid');
336+
fix.detectChanges();
337+
338+
GridFunctions.clickExcelFilterIconFromCode(fix, treeGrid, 'Name');
339+
checkboxes = Array.from(GridFunctions.getExcelStyleFilteringCheckboxes(fix, null, 'igx-tree-grid') as HTMLInputElement[]);
340+
341+
const uncheckedItem = checkboxes.splice(2, 1)[0];
342+
expect(uncheckedItem.checked).toBeFalse();
343+
checkboxes.forEach(c => expect(c.checked).toBeTrue());
344+
}));
299345
});
300346

301347
const getChips = (fixture) => {

projects/igniteui-angular/test-utils/tree-grid-components.spec.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,19 +1074,19 @@ export class IgxTreeGridCascadingSelectionTransactionComponent {
10741074
@Component({
10751075
template: `
10761076
<igx-tree-grid #treeGrid [data]="data | treeGridGrouping:groupingExpressions:groupKey:childDataKey:treeGrid:aggregations"
1077-
[childDataKey]="childDataKey" [expansionDepth]="0" width="900px" height="1000px">
1077+
[childDataKey]="childDataKey" [expansionDepth]="0" width="900px" height="1000px" >
10781078
<igx-tree-grid-group-by-area
10791079
[grid]="treeGrid"
10801080
[expressions]="groupingExpressions"
10811081
[hideGroupedColumns]="false">
10821082
</igx-tree-grid-group-by-area>
1083-
<igx-column [field]="groupKey" [resizable]="true" [width]="'250px'" [hidden]="groupingExpressions.length === 0"></igx-column>
1084-
<igx-column [field]="'ID'" dataType="number"></igx-column>
1085-
<igx-column [field]="'Name'" dataType="string"></igx-column>
1086-
<igx-column [field]="'JobTitle'" dataType="string"></igx-column>
1087-
<igx-column [field]="'HireDate'" dataType="date"></igx-column>
1088-
<igx-column [field]="'Age'" dataType="number"></igx-column>
1089-
<igx-column [field]="'OnPTO'" dataType="boolean"></igx-column>
1083+
<igx-column [field]="groupKey" [resizable]="true" [width]="'250px'" [hidden]="groupingExpressions.length === 0" [filterable]="true"></igx-column>
1084+
<igx-column [field]="'ID'" dataType="number" [filterable]="true"></igx-column>
1085+
<igx-column [field]="'Name'" dataType="string" [filterable]="true"></igx-column>
1086+
<igx-column [field]="'JobTitle'" dataType="string" [filterable]="true"></igx-column>
1087+
<igx-column [field]="'HireDate'" dataType="date" [filterable]="true"></igx-column>
1088+
<igx-column [field]="'Age'" dataType="number" [filterable]="true"></igx-column>
1089+
<igx-column [field]="'OnPTO'" dataType="boolean" [filterable]="true"></igx-column>
10901090
</igx-tree-grid>
10911091
`,
10921092
changeDetection: ChangeDetectionStrategy.Eager,

0 commit comments

Comments
 (0)