Skip to content

Commit 28eec6b

Browse files
committed
feat(h-grid): update adv filtering schema on row expand
1 parent d0361ce commit 28eec6b

File tree

2 files changed

+103
-85
lines changed

2 files changed

+103
-85
lines changed

projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts

Lines changed: 56 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { QueryBuilderFunctions } from '../../query-builder/query-builder-functio
2727
import { By } from '@angular/platform-browser';
2828
import { IgxDateTimeEditorDirective } from '../../directives/date-time-editor/date-time-editor.directive';
2929
import { QueryBuilderSelectors } from '../../query-builder/query-builder.common';
30-
import { IgxHGridRemoteOnDemandComponent } from '../hierarchical-grid/hierarchical-grid.spec';
30+
import { IgxHGridRemoteOnDemandComponent, IgxHierarchicalGridToggleRIComponent } from '../hierarchical-grid/hierarchical-grid.spec';
3131
import { IGridResourceStrings } from '../../core/i18n/grid-resources';
3232

3333
describe('IgxGrid - Advanced Filtering #grid - ', () => {
@@ -1750,76 +1750,69 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => {
17501750
expect(hgrid.filteredData.length).toBe(5);
17511751
}));
17521752

1753-
it('Should have proper fields in UI when schema is defined with load on demand.', fakeAsync(() => {
1754-
const fixture = TestBed.createComponent(IgxHGridRemoteOnDemandComponent);
1755-
const hierarchicalGrid = fixture.componentInstance.instance;
1753+
it('Should update root grid schema when row island is expanded.', fakeAsync(() => {
1754+
const fixture = TestBed.createComponent(IgxHierarchicalGridToggleRIComponent);
1755+
const hierarchicalGrid = fixture.componentInstance.hgrid;
17561756
hierarchicalGrid.allowAdvancedFiltering = true;
1757-
hierarchicalGrid.schema = [
1758-
{
1759-
name: 'rootLevel',
1760-
fields: [
1761-
{ field: 'ID', dataType: 'string' },
1762-
{ field: 'ChildLevels', dataType: 'number' },
1763-
{ field: 'ProductName', dataType: 'string' },
1764-
{ field: 'Col1', dataType: 'number' },
1765-
{ field: 'Col2', dataType: 'number' },
1766-
{ field: 'Col3', dataType: 'number' }
1767-
],
1768-
childEntities: [
1769-
{
1770-
name: 'childData',
1771-
fields: [
1772-
{ field: 'ID', dataType: 'string' },
1773-
{ field: 'ProductName', dataType: 'string' }
1774-
],
1775-
childEntities: [
1776-
{
1777-
name: 'childData2',
1778-
fields: [
1779-
{ field: 'ID', dataType: 'string' },
1780-
{ field: 'ProductName', dataType: 'string' }
1781-
]
1782-
}
1783-
]
1784-
}
1785-
]
1786-
}
1787-
]
1788-
fixture.detectChanges();
1789-
1790-
hierarchicalGrid.openAdvancedFilteringDialog();
17911757
fixture.detectChanges();
17921758

1793-
// Click the initial 'Add Condition' button.
1794-
QueryBuilderFunctions.clickQueryBuilderInitialAddConditionBtn(fixture, 0);
1795-
tick(100);
1796-
fixture.detectChanges();
1797-
// Populate edit inputs.
1798-
QueryBuilderFunctions.selectColumnInEditModeExpression(fixture, 0); // Select 'ID' column.
1799-
QueryBuilderFunctions.selectOperatorInEditModeExpression(fixture, 10); // Select 'In' operator.
1800-
tick(100);
1801-
fixture.detectChanges();
1802-
1803-
const entityInputGroup = QueryBuilderFunctions.getQueryBuilderEntitySelect(fixture, 1).querySelector('input');
1804-
expect(entityInputGroup.value).toBe('childData');
1759+
// Open advanced filtering dialog and create an 'In' condition.
1760+
const createInConditionAndGetReturnFields = () => {
1761+
// Open Advanced Filtering dialog.
1762+
hierarchicalGrid.openAdvancedFilteringDialog();
1763+
fixture.detectChanges();
1764+
1765+
// Click the initial 'Add Condition' button.
1766+
QueryBuilderFunctions.clickQueryBuilderInitialAddConditionBtn(fixture, 0);
1767+
tick(100);
1768+
fixture.detectChanges();
1769+
// Populate edit inputs.
1770+
QueryBuilderFunctions.selectColumnInEditModeExpression(fixture, 0); // Select 'ID' column.
1771+
QueryBuilderFunctions.selectOperatorInEditModeExpression(fixture, 10); // Select 'In' operator.
1772+
tick(100);
1773+
fixture.detectChanges();
1774+
1775+
// Verify entities
1776+
QueryBuilderFunctions.clickQueryBuilderEntitySelect(fixture, 1);
1777+
fixture.detectChanges();
1778+
const queryBuilderElement: HTMLElement = fixture.debugElement.queryAll(By.css(`.${QueryBuilderSelectors.QUERY_BUILDER_TREE}`))[1].nativeElement;
1779+
let dropdownValues: string[] = QueryBuilderFunctions.getQueryBuilderSelectDropdownItems(queryBuilderElement).map((x: any) => x.innerText);
1780+
let expectedValues = ['childData'];
1781+
expect(dropdownValues).toEqual(expectedValues);
1782+
1783+
// Verify return fields
1784+
QueryBuilderFunctions.clickQueryBuilderFieldsCombo(fixture, 1);
1785+
fixture.detectChanges();
1786+
const innerQueryReturnFields = QueryBuilderFunctions.getQueryBuilderSelectDropdown(queryBuilderElement, 1);
1787+
1788+
return innerQueryReturnFields;
1789+
};
18051790

1806-
const fieldInputGroup = QueryBuilderFunctions.getQueryBuilderFieldsCombo(fixture, 1).querySelector('input');
1807-
expect(fieldInputGroup.value).toBe('ID');
1791+
let innerQueryReturnFields = createInConditionAndGetReturnFields();
1792+
expect(innerQueryReturnFields).toBeNull();
18081793

1809-
// Verify entities
1810-
QueryBuilderFunctions.clickQueryBuilderEntitySelect(fixture, 1);
1794+
// Close Advanced Filtering dialog.
1795+
hierarchicalGrid.closeAdvancedFilteringDialog(false);
1796+
tick(200);
18111797
fixture.detectChanges();
1812-
const queryBuilderElement: HTMLElement = fixture.debugElement.queryAll(By.css(`.${QueryBuilderSelectors.QUERY_BUILDER_TREE}`))[1].nativeElement;
1813-
let dropdownValues: string[] = QueryBuilderFunctions.getQueryBuilderSelectDropdownItems(queryBuilderElement).map((x: any) => x.innerText);
1814-
let expectedValues = ['childData'];
1815-
expect(dropdownValues).toEqual(expectedValues);
18161798

1817-
// Verify return fileds
1818-
QueryBuilderFunctions.clickQueryBuilderFieldsCombo(fixture, 1);
1799+
// Expand row island
1800+
const row = hierarchicalGrid.gridAPI.get_row_by_index(0) as any;
1801+
UIInteractions.simulateClickAndSelectEvent(row.expander);
18191802
fixture.detectChanges();
1820-
dropdownValues = QueryBuilderFunctions.getQueryBuilderSelectDropdownItems(queryBuilderElement, 1).map((x: any) => x.innerText);
1821-
expectedValues = ['ID', 'ProductName'];
1822-
expect(dropdownValues).toEqual(expectedValues);
1803+
1804+
// Open advanced filtering dialog and verify that schema is updated.
1805+
innerQueryReturnFields = createInConditionAndGetReturnFields();
1806+
expect(innerQueryReturnFields).not.toBeNull();
1807+
const items = Array.from(innerQueryReturnFields.querySelectorAll('.igx-drop-down__item'));
1808+
expect(items.length).toBe(7);
1809+
expect((items[0] as HTMLElement).innerText).toBe('ID');
1810+
expect((items[1] as HTMLElement).innerText).toBe('ChildLevels');
1811+
expect((items[2] as HTMLElement).innerText).toBe('ProductName');
1812+
expect((items[3] as HTMLElement).innerText).toBe('Col1');
1813+
expect((items[4] as HTMLElement).innerText).toBe('Col2');
1814+
expect((items[5] as HTMLElement).innerText).toBe('Col3');
1815+
expect((items[6] as HTMLElement).innerText).toBe('childData2');
18231816
}));
18241817

18251818
it('Should correctly change resource strings for hierarchical Advanced Filtering dialog.', fakeAsync(() => {

projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -587,11 +587,10 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
587587
* const schema = this.grid.schema;
588588
* this.grid.schema = [{ name: 'Products', fields: [...], childEntities: [...] }];
589589
* ```
590+
* @deprecated in version 20.1.0.
590591
*/
591592
@Input()
592-
public set schema(entities: EntityType[]) {
593-
this._hGridSchema = entities;
594-
}
593+
public set schema(entities: EntityType[]) {}
595594

596595
/* blazorSuppress */
597596
public get schema() {
@@ -683,6 +682,10 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
683682
this.batchEditing = val;
684683
});
685684
}
685+
this.columnsAutogenerated.subscribe((e) => {
686+
this.updateRootGridSchema(e);
687+
});
688+
686689
super.ngOnInit();
687690
}
688691

@@ -1256,40 +1259,62 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
12561259
];
12571260

12581261
entities[0].childEntities = this.childLayoutList.reduce((acc, rowIsland) => {
1259-
return acc.concat(this.generateChildEntity(rowIsland, this.data[0][rowIsland.key][0]));
1262+
return acc.concat(this.generateChildEntity(rowIsland));
12601263
}
12611264
, []);
12621265
}
12631266

12641267
return entities;
12651268
}
12661269

1267-
private generateChildEntity(rowIsland: IgxRowIslandComponent, firstRowData: any[]): EntityType {
1270+
private updateRootGridSchema(event: any) {
1271+
const schema = (this.rootGrid as IgxHierarchicalGridComponent).schema;
1272+
if (!schema || schema.length === 0) {
1273+
return;
1274+
}
1275+
1276+
let path = [];
1277+
let parentIsland = this.parentIsland;
1278+
while (parentIsland) {
1279+
path.push(parentIsland.key);
1280+
parentIsland = parentIsland.parentIsland;
1281+
}
1282+
1283+
path.reverse();
1284+
if (path.length > 0) {
1285+
let childLevel = path[0];
1286+
let childEntity;
1287+
while (childLevel) {
1288+
childEntity = schema[0].childEntities.find(e => e.name === childLevel);
1289+
childLevel = path.shift();
1290+
}
1291+
1292+
childEntity.fields = event.columns.filter((column) => !column.columnGroup && column.filterable)
1293+
.map(f => ({
1294+
field: f.field,
1295+
dataType: f.dataType,
1296+
label: f.label,
1297+
header: f.header,
1298+
editorOptions: f.editorOptions,
1299+
filters: f.filters,
1300+
pipeArgs: f.pipeArgs,
1301+
defaultTimeFormat: f.defaultTimeFormat,
1302+
defaultDateTimeFormat: f.defaultDateTimeFormat
1303+
})) as FieldType[];
1304+
}
1305+
}
1306+
1307+
private generateChildEntity(rowIsland: IgxRowIslandComponent): EntityType {
12681308
const entityName = rowIsland.key;
12691309
let fields = [];
12701310
let childEntities;
1271-
if (!rowIsland.autoGenerate) {
1311+
if (rowIsland.childColumns?.length > 0) {
12721312
fields = flatten(rowIsland.childColumns.toArray()).filter(col => col.field)
12731313
.map(f => ({ field: f.field, dataType: f.dataType })) as FieldType[];
1274-
} else if (firstRowData) {
1275-
const rowIslandFields = Object.keys(firstRowData).map(key => {
1276-
if (firstRowData[key] instanceof Array) {
1277-
return null;
1278-
}
1279-
1280-
return {
1281-
field: key,
1282-
dataType: this.resolveDataTypes(firstRowData[key])
1283-
}
1284-
});
1285-
fields = rowIslandFields.filter(f => f !== null) as FieldType[];
12861314
}
12871315

12881316
const rowIslandChildEntities = rowIsland.childLayoutList.reduce((acc, childRowIsland) => {
1289-
if (!firstRowData) {
1290-
return null;
1291-
}
1292-
return acc.concat(this.generateChildEntity(childRowIsland, firstRowData[childRowIsland.key][0]));
1317+
return acc.concat(this.generateChildEntity(childRowIsland));
12931318
}, []);
12941319

12951320
if (rowIslandChildEntities?.length > 0) {

0 commit comments

Comments
 (0)