Skip to content

Commit 68211c7

Browse files
sstoyanovIGbkulov
authored andcommitted
Move filtering logic from grid to filteringService (#4358)
* chore(igx-grid): Move filtering logic from grid to filteringService, #4326 * chore(igx-grid): Adjust test, #4326 * test(igx-grid): Adjust tests to be fakeAsync, #4326
1 parent b27fe59 commit 68211c7

21 files changed

+177
-157
lines changed

projects/igniteui-angular/src/lib/grids/filtering/excel-style/excel-style-custom-dialog.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ export class IgxExcelStyleCustomDialogComponent implements AfterViewInit {
148148
this.expressionsList[this.expressionsList.length - 1].afterOperator = null;
149149
}
150150

151-
this.filteringService.filter(this.column.field, this.expressionsList);
151+
this.filteringService.filterInternal(this.column.field, this.expressionsList);
152152
this.closeDialog();
153153
}
154154

projects/igniteui-angular/src/lib/grids/filtering/excel-style/grid.excel-style-filtering.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ export class IgxGridExcelStyleFilteringComponent implements OnDestroy, AfterView
530530
});
531531
});
532532
this.expressionsList = new Array<ExpressionUI>();
533-
this.filteringService.filter(this.column.field, filterTree);
533+
this.filteringService.filterInternal(this.column.field, filterTree);
534534
} else {
535535
this.filteringService.clearFilter(this.column.field);
536536
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoC
253253
this.filteringService.removeExpression(this.column.field, indexToRemove);
254254

255255
this.updateVisibleFilters();
256-
this.filteringService.filter(this.column.field);
256+
this.filteringService.filterInternal(this.column.field);
257257
}
258258

259259
private isMoreIconHidden(): boolean {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,6 @@ export class IgxGridFilteringRowComponent implements AfterViewInit {
708708
}
709709

710710
private filter() {
711-
this.filteringService.filter(this.column.field);
711+
this.filteringService.filterInternal(this.column.field);
712712
}
713713
}

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

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { DataUtil } from '../../data-operations/data-util';
1515
import { IgxGridSortingPipe } from '../grid/grid.pipes';
1616
import { IgxDatePipeComponent } from '../grid.common';
1717
import { IgxColumnComponent, IgxColumnGroupComponent } from '../column.component';
18+
import { IFilteringOperation } from '../../data-operations/filtering-condition';
1819

1920
const FILTERING_ICONS_FONT_SET = 'filtering-icons';
2021

@@ -124,9 +125,9 @@ export class IgxFilteringService implements OnDestroy {
124125
}
125126

126127
/**
127-
* Execute filtering on the grid.
128+
* Internal method to create expressionsTree and filter grid used in both filter modes.
128129
*/
129-
public filter(field: string, expressions: FilteringExpressionsTree | Array<ExpressionUI> = null): void {
130+
public filterInternal(field: string, expressions: FilteringExpressionsTree | Array<ExpressionUI> = null): void {
130131
this.isFiltering = true;
131132

132133
let expressionsTree;
@@ -137,36 +138,74 @@ export class IgxFilteringService implements OnDestroy {
137138
}
138139

139140
if (expressionsTree.filteringOperands.length === 0) {
140-
this.grid.clearFilter(field);
141+
this.clearFilter(field);
141142
} else {
142-
this.grid.filter(field, null, expressionsTree);
143+
this.filter(field, null, expressionsTree);
143144
}
144145

145-
// Wait for the change detection to update filtered data through the pipes and then emit the event.
146-
requestAnimationFrame(() => this.grid.onFilteringDone.emit(expressionsTree));
147-
148146
this.isFiltering = false;
149147
}
150148

149+
/**
150+
* Execute filtering on the grid.
151+
*/
152+
public filter(field: string, value: any, conditionOrExpressionTree?: IFilteringOperation | IFilteringExpressionsTree,
153+
ignoreCase?: boolean) {
154+
const col = this.gridAPI.get_column_by_name(this.gridId, field);
155+
const filteringIgnoreCase = ignoreCase || (col ? col.filteringIgnoreCase : false);
156+
157+
if (conditionOrExpressionTree) {
158+
this.gridAPI.filter(this.gridId, field, value, conditionOrExpressionTree, filteringIgnoreCase);
159+
} else {
160+
const expressionsTreeForColumn = this.grid.filteringExpressionsTree.find(field);
161+
if (expressionsTreeForColumn instanceof FilteringExpressionsTree) {
162+
this.gridAPI.filter(this.gridId, field, value, expressionsTreeForColumn, filteringIgnoreCase);
163+
} else {
164+
const expressionForColumn = expressionsTreeForColumn as IFilteringExpression;
165+
this.gridAPI.filter(this.gridId, field, value, expressionForColumn.condition, filteringIgnoreCase);
166+
}
167+
}
168+
169+
// Wait for the change detection to update filtered data through the pipes and then emit the event.
170+
requestAnimationFrame(() => this.grid.onFilteringDone.emit(col.filteringExpressionsTree));
171+
}
172+
151173
/**
152174
* Clear the filter of a given column.
153175
*/
154176
public clearFilter(field: string): void {
155-
this.isFiltering = true;
177+
if (field) {
178+
const column = this.gridAPI.get_column_by_name(this.gridId, field);
179+
if (!column) {
180+
return;
181+
}
182+
}
156183

157-
this.grid.clearFilter(field);
184+
this.isFiltering = true;
158185

159-
const expr = this.grid.filteringExpressionsTree.find(field);
186+
this.gridAPI.clear_filter(this.gridId, field);
160187

161188
// Wait for the change detection to update filtered data through the pipes and then emit the event.
162-
requestAnimationFrame(() => this.grid.onFilteringDone.emit(expr as FilteringExpressionsTree));
189+
requestAnimationFrame(() => this.grid.onFilteringDone.emit(null));
163190

164-
const expressions = this.getExpressions(field);
165-
expressions.length = 0;
191+
if (field) {
192+
const expressions = this.getExpressions(field);
193+
expressions.length = 0;
194+
}
166195

167196
this.isFiltering = false;
168197
}
169198

199+
/**
200+
* Filters all the `IgxColumnComponent` in the `IgxGridComponent` with the same condition.
201+
*/
202+
public filterGlobal(value: any, condition?, ignoreCase?) {
203+
this.gridAPI.filter_global(this.gridId, value, condition, ignoreCase);
204+
205+
// Wait for the change detection to update filtered data through the pipes and then emit the event.
206+
requestAnimationFrame(() => this.grid.onFilteringDone.emit(this.grid.filteringExpressionsTree));
207+
}
208+
170209
/**
171210
* Register filtering SVG icons in the icon service.
172211
*/

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

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3343,20 +3343,7 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
33433343
*/
33443344
public filter(name: string, value: any, conditionOrExpressionTree?: IFilteringOperation | IFilteringExpressionsTree,
33453345
ignoreCase?: boolean) {
3346-
const col = this.gridAPI.get_column_by_name(this.id, name);
3347-
const filteringIgnoreCase = ignoreCase || (col ? col.filteringIgnoreCase : false);
3348-
3349-
if (conditionOrExpressionTree) {
3350-
this.gridAPI.filter(this.id, name, value, conditionOrExpressionTree, filteringIgnoreCase);
3351-
} else {
3352-
const expressionsTreeForColumn = this._filteringExpressionsTree.find(name);
3353-
if (expressionsTreeForColumn instanceof FilteringExpressionsTree) {
3354-
this.gridAPI.filter(this.id, name, value, expressionsTreeForColumn, filteringIgnoreCase);
3355-
} else {
3356-
const expressionForColumn = expressionsTreeForColumn as IFilteringExpression;
3357-
this.gridAPI.filter(this.id, name, value, expressionForColumn.condition, filteringIgnoreCase);
3358-
}
3359-
}
3346+
this.filteringService.filter(name, value, conditionOrExpressionTree, ignoreCase);
33603347
}
33613348

33623349
/**
@@ -3370,7 +3357,7 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
33703357
* @memberof IgxGridBaseComponent
33713358
*/
33723359
public filterGlobal(value: any, condition?, ignoreCase?) {
3373-
this.gridAPI.filter_global(this.id, value, condition, ignoreCase);
3360+
this.filteringService.filterGlobal(value, condition, ignoreCase);
33743361
}
33753362

33763363
/**
@@ -3426,14 +3413,7 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
34263413
* @memberof IgxGridBaseComponent
34273414
*/
34283415
public clearFilter(name?: string) {
3429-
if (name) {
3430-
const column = this.gridAPI.get_column_by_name(this.id, name);
3431-
if (!column) {
3432-
return;
3433-
}
3434-
}
3435-
3436-
this.gridAPI.clear_filter(this.id, name);
3416+
this.filteringService.clearFilter(name);
34373417
}
34383418

34393419
/**

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { SortingDirection } from '../../data-operations/sorting-expression.inter
88
import { UIInteractions, wait } from '../../test-utils/ui-interactions.spec';
99
import { HelperUtils} from '../../test-utils/helper-utils.spec';
1010
import { configureTestSuite } from '../../test-utils/configure-suite';
11-
import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition';
11+
import { IgxStringFilteringOperand, IgxNumberFilteringOperand } from '../../data-operations/filtering-condition';
1212
import { SampleTestData } from '../../test-utils/sample-test-data.spec';
1313

1414
const DEBOUNCETIME = 30;
@@ -383,19 +383,19 @@ describe('IgxGrid - Cell component', () => {
383383
expect(cell.value.getTime()).toBe(selectedDate.getTime());
384384
}));
385385

386-
it('should exit edit mode on filtering', (async () => {
386+
it('should exit edit mode on filtering', (fakeAsync(() => {
387387
const cell = grid.getCellByColumn(0, 'fullName');
388388
const cellDom = fixture.debugElement.queryAll(By.css(CELL_CSS_CLASS))[0];
389389
const cellValue = cell.value;
390390

391391
cellDom.triggerEventHandler('dblclick', {});
392-
await wait();
392+
tick();
393393

394394
const editTemplate = cellDom.query(By.css('input'));
395395
expect(cell.inEditMode).toBe(true);
396396

397397
UIInteractions.sendInput(editTemplate, 'Rick Gilmore');
398-
await wait();
398+
tick();
399399

400400
grid.filter('fullName', 'Al', IgxStringFilteringOperand.instance().condition('equals'));
401401
fixture.detectChanges();
@@ -404,26 +404,26 @@ describe('IgxGrid - Cell component', () => {
404404

405405
expect(cell.inEditMode).toBe(false);
406406
expect(cell.value).toBe(cellValue);
407-
}));
407+
})));
408408

409-
it('should not throw errors when update cell to value, which does not match filter criteria', (async () => {
410-
grid.filter('personNumber', 1, IgxStringFilteringOperand.instance().condition('equals'));
409+
it('should not throw errors when update cell to value, which does not match filter criteria', (fakeAsync(() => {
410+
grid.filter('personNumber', 1, IgxNumberFilteringOperand.instance().condition('equals'));
411411
fixture.detectChanges();
412412

413413
const cell = grid.getCellByColumn(0, 'personNumber');
414414
const cellDomPK = fixture.debugElement.queryAll(By.css(CELL_CSS_CLASS))[4];
415415
const previousCell = grid.getCellByColumn(0, 'birthday');
416416

417417
cellDomPK.triggerEventHandler('dblclick', {});
418-
await wait();
418+
tick();
419419
expect(cell.inEditMode).toBe(true);
420420

421421
const editTemplate = cellDomPK.query(By.css('input[type=\'number\']'));
422422
UIInteractions.sendInput(editTemplate, 9);
423-
await wait();
423+
tick();
424424

425425
expect (() => previousCell.onClick({})).not.toThrow();
426-
}));
426+
})));
427427

428428
it('should exit edit mode on sorting', (async () => {
429429
const cell = grid.getCellByColumn(0, 'fullName');

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

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ describe('IgxGrid - Filtering actions', () => {
3030
.compileComponents();
3131
}));
3232

33-
it('should correctly filter by \'string\' filtering conditions', () => {
33+
it('should correctly filter by \'string\' filtering conditions', fakeAsync(() => {
3434
const fix = TestBed.createComponent(IgxGridFilteringComponent);
3535
fix.detectChanges();
3636

@@ -123,9 +123,9 @@ describe('IgxGrid - Filtering actions', () => {
123123
grid.filter('AnotherField', '', CustomFilter.instance().condition('custom'), false);
124124
fix.detectChanges();
125125
expect(grid.rowList.length).toEqual(1);
126-
});
126+
}));
127127

128-
it('should correctly filter by \'number\' filtering conditions', () => {
128+
it('should correctly filter by \'number\' filtering conditions', fakeAsync(() => {
129129
const fix = TestBed.createComponent(IgxGridFilteringComponent);
130130
fix.detectChanges();
131131

@@ -199,9 +199,9 @@ describe('IgxGrid - Filtering actions', () => {
199199
grid.filter('Downloads', null, IgxNumberFilteringOperand.instance().condition('notEmpty'), true);
200200
fix.detectChanges();
201201
expect(grid.rowList.length).toEqual(7);
202-
});
202+
}));
203203

204-
it('should correctly filter by \'boolean\' filtering conditions', () => {
204+
it('should correctly filter by \'boolean\' filtering conditions', fakeAsync(() => {
205205
const fix = TestBed.createComponent(IgxGridFilteringComponent);
206206
fix.detectChanges();
207207

@@ -247,9 +247,9 @@ describe('IgxGrid - Filtering actions', () => {
247247
grid.filter('Released', null, IgxBooleanFilteringOperand.instance().condition('null'));
248248
fix.detectChanges();
249249
expect(grid.rowList.length).toEqual(2);
250-
});
250+
}));
251251

252-
it('should correctly filter by \'date\' filtering conditions', () => {
252+
it('should correctly filter by \'date\' filtering conditions', fakeAsync(() => {
253253
const fix = TestBed.createComponent(IgxGridFilteringComponent);
254254
fix.detectChanges();
255255

@@ -367,9 +367,9 @@ describe('IgxGrid - Filtering actions', () => {
367367
grid.filter('ReleaseDate', null, IgxDateFilteringOperand.instance().condition('yesterday'));
368368
fix.detectChanges();
369369
expect(grid.rowList.length).toEqual(1);
370-
});
370+
}));
371371

372-
it('should correctly apply multiple filtering through API', () => {
372+
it('should correctly apply multiple filtering through API', fakeAsync(() => {
373373
const fix = TestBed.createComponent(IgxGridFilteringComponent);
374374
fix.detectChanges();
375375

@@ -395,9 +395,9 @@ describe('IgxGrid - Filtering actions', () => {
395395

396396
expect(grid.rowList.length).toEqual(8);
397397
expect(grid.filteringExpressionsTree.filteringOperands.length).toEqual(0);
398-
});
398+
}));
399399

400-
it('should correctly apply global filtering', () => {
400+
it('should correctly apply global filtering', fakeAsync(() => {
401401
const fix = TestBed.createComponent(IgxGridFilteringComponent);
402402
fix.detectChanges();
403403

@@ -409,9 +409,9 @@ describe('IgxGrid - Filtering actions', () => {
409409

410410
expect(grid.filteringExpressionsTree.filteringOperands.length).toEqual(grid.columns.length);
411411
expect(grid.rowList.length).toEqual(1);
412-
});
412+
}));
413413

414-
it('Should render chip when filtering using the API.', () => {
414+
it('Should render chip when filtering using the API.', fakeAsync(() => {
415415
const fixture = TestBed.createComponent(IgxGridFilteringComponent);
416416
fixture.detectChanges();
417417

@@ -436,9 +436,9 @@ describe('IgxGrid - Filtering actions', () => {
436436
expect(filteringChips.length).toEqual(1);
437437
chipContent = filteringChips[0].query(By.css('.igx-chip__content')).nativeElement.innerText;
438438
expect(chipContent).toEqual('Filter');
439-
});
439+
}));
440440

441-
it('Should correctly apply two conditions to two columns at once.', () => {
441+
it('Should correctly apply two conditions to two columns at once.', fakeAsync(() => {
442442
const fix = TestBed.createComponent(IgxGridFilteringComponent);
443443
fix.detectChanges();
444444

@@ -470,9 +470,9 @@ describe('IgxGrid - Filtering actions', () => {
470470

471471
expect(grid.rowList.length).toEqual(8);
472472
expect(grid.filteringExpressionsTree.filteringOperands.length).toEqual(0);
473-
});
473+
}));
474474

475-
it('Should correctly apply two conditions to number column.', () => {
475+
it('Should correctly apply two conditions to number column.', fakeAsync(() => {
476476
const fix = TestBed.createComponent(IgxGridFilteringComponent);
477477
fix.detectChanges();
478478

@@ -497,9 +497,9 @@ describe('IgxGrid - Filtering actions', () => {
497497

498498
expect(grid.rowList.length).toEqual(3);
499499
expect((grid.filteringExpressionsTree.filteringOperands[0] as FilteringExpressionsTree).filteringOperands.length).toEqual(2);
500-
});
500+
}));
501501

502-
it('Should correctly apply two conditions to string column.', () => {
502+
it('Should correctly apply two conditions to string column.', fakeAsync(() => {
503503
const fix = TestBed.createComponent(IgxGridFilteringComponent);
504504
fix.detectChanges();
505505

@@ -524,9 +524,9 @@ describe('IgxGrid - Filtering actions', () => {
524524

525525
expect(grid.rowList.length).toEqual(1);
526526
expect((grid.filteringExpressionsTree.filteringOperands[0] as FilteringExpressionsTree).filteringOperands.length).toEqual(2);
527-
});
527+
}));
528528

529-
it('Should correctly apply two conditions to date column.', () => {
529+
it('Should correctly apply two conditions to date column.', fakeAsync(() => {
530530
const fix = TestBed.createComponent(IgxGridFilteringComponent);
531531
fix.detectChanges();
532532

@@ -552,7 +552,7 @@ describe('IgxGrid - Filtering actions', () => {
552552

553553
expect(grid.rowList.length).toEqual(4);
554554
expect((grid.filteringExpressionsTree.filteringOperands[0] as FilteringExpressionsTree).filteringOperands.length).toEqual(2);
555-
});
555+
}));
556556

557557
it('Should correctly update summary.', fakeAsync(() => {
558558
const fix = TestBed.createComponent(IgxGridFilteringComponent);

0 commit comments

Comments
 (0)