Skip to content

Commit fe8e316

Browse files
authored
Merge branch 'master' into ddincheva/calendarBugFixs
2 parents 2f06b05 + c6e22df commit fe8e316

File tree

7 files changed

+90
-23
lines changed

7 files changed

+90
-23
lines changed

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,14 @@ export class IgxExcelStyleConditionalFilterComponent implements OnDestroy {
5353
constructor(public esf: IgxGridExcelStyleFilteringComponent) {
5454
this.esf.columnChange.pipe(takeUntil(this.destroy$)).subscribe(() => {
5555
if (this.esf.grid) {
56-
this._subMenuOverlaySettings.outlet = (this.esf.grid as any).outlet;
56+
this._subMenuOverlaySettings.outlet = this.esf.grid.outlet;
5757
}
5858
});
59-
}
59+
60+
if (this.esf.grid) {
61+
this._subMenuOverlaySettings.outlet = this.esf.grid.outlet;
62+
}
63+
}
6064

6165
ngOnDestroy(): void {
6266
this.destroy$.next(true);
@@ -147,7 +151,7 @@ export class IgxExcelStyleConditionalFilterComponent implements OnDestroy {
147151
const exprTree = this.esf.column.filteringExpressionsTree;
148152
return exprTree && exprTree.filteringOperands && exprTree.filteringOperands.length &&
149153
!((exprTree.filteringOperands[0] as IFilteringExpression).condition &&
150-
(exprTree.filteringOperands[0] as IFilteringExpression).condition.name === 'in');
154+
(exprTree.filteringOperands[0] as IFilteringExpression).condition.name === 'in');
151155
}
152156

153157
/**

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,15 @@ export class IgxGridExcelStyleFilteringComponent implements OnDestroy {
500500
}
501501

502502
private generateUniqueValues(columnValues: any[]) {
503-
this.uniqueValues = Array.from(new Set(columnValues));
503+
if (this.column.dataType === DataType.String && this.column.filteringIgnoreCase) {
504+
const filteredUniqueValues = columnValues.map(s => s?.toLowerCase())
505+
.reduce((map, val, i) => map.get(val) ? map : map.set(val, columnValues[i]),
506+
new Map);
507+
508+
this.uniqueValues = Array.from(filteredUniqueValues.values());
509+
} else {
510+
this.uniqueValues = Array.from(new Set(columnValues));
511+
}
504512
}
505513

506514
private generateFilterValues(isDateColumn: boolean = false) {

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { FilteringExpressionsTree, IFilteringExpressionsTree } from '../../data-
33
import { IgxGridBaseDirective } from '../grid-base.directive';
44
import { IFilteringExpression, FilteringLogic } from '../../data-operations/filtering-expression.interface';
55
import { Subject } from 'rxjs';
6-
import { takeUntil, filter } from 'rxjs/operators';
6+
import { takeUntil, first } from 'rxjs/operators';
77
import { IForOfState } from '../../directives/for-of/for_of.directive';
88
import { IgxColumnComponent } from '../columns/column.component';
99
import { IFilteringOperation } from '../../data-operations/filtering-condition';
@@ -65,7 +65,8 @@ export class IgxFilteringService implements OnDestroy {
6565
}
6666

6767
public toggleFilterDropdown(element, column, classRef) {
68-
if (!this._componentOverlayId || (this.column && this.column.field !== column.field)) {
68+
if (!this._componentOverlayId || (this.column && this.column.field !== column.field)) {
69+
this.initFilteringSettings();
6970
this.column = column;
7071
const filterIcon = this.column.filteringExpressionsTree ? 'igx-excel-filter__icon--filtered' : 'igx-excel-filter__icon';
7172
const filterIconTarget = element.querySelector('.' + filterIcon);
@@ -97,8 +98,9 @@ export class IgxFilteringService implements OnDestroy {
9798
positionStrategy: new ExcelStylePositionStrategy(this._filterMenuPositionSettings),
9899
scrollStrategy: new AbsoluteScrollStrategy()
99100
};
101+
100102
this._overlayService.onOpening.pipe(
101-
filter((overlay) => overlay.id === this._componentOverlayId),
103+
first((overlay) => overlay.id === this._componentOverlayId),
102104
takeUntil(this.destroy$)).subscribe((eventArgs) => {
103105
const instance = this.grid.excelStyleFilteringComponent ?
104106
this.grid.excelStyleFilteringComponent :
@@ -111,7 +113,7 @@ export class IgxFilteringService implements OnDestroy {
111113
});
112114

113115
this._overlayService.onClosed.pipe(
114-
filter(overlay => overlay.id === this._componentOverlayId),
116+
first((overlay) => overlay.id === this._componentOverlayId),
115117
takeUntil(this.destroy$)).subscribe((eventArgs) => {
116118
const instance = this.grid.excelStyleFilteringComponent ?
117119
this.grid.excelStyleFilteringComponent :
@@ -354,7 +356,7 @@ export class IgxFilteringService implements OnDestroy {
354356
}
355357

356358
if ((currExpressionUI.beforeOperator === undefined || currExpressionUI.beforeOperator === null ||
357-
currExpressionUI.beforeOperator === FilteringLogic.Or) &&
359+
currExpressionUI.beforeOperator === FilteringLogic.Or) &&
358360
currExpressionUI.afterOperator === FilteringLogic.And) {
359361

360362
currAndBranch = new FilteringExpressionsTree(FilteringLogic.And, columnId);
@@ -481,8 +483,8 @@ export class IgxFilteringService implements OnDestroy {
481483
}
482484

483485
private generateExpressionsListRecursive(expressions: IFilteringExpressionsTree | IFilteringExpression,
484-
operator: FilteringLogic,
485-
expressionsUIs: ExpressionUI[]): void {
486+
operator: FilteringLogic,
487+
expressionsUIs: ExpressionUI[]): void {
486488
if (!expressions) {
487489
return;
488490
}

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

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4384,10 +4384,42 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => {
43844384
expect(listItems.length).toBe(0, 'incorrect rendered list items count');
43854385
}));
43864386

4387-
it('Should display "Add to current filter selection" button on typing in input', fakeAsync(() => {
4388-
// Open excel style filtering dialog.
4389-
GridFunctions.clickExcelFilterIconFromCode(fix, grid, 'Downloads');
4387+
it('Should ignore duplicate records when column\'\s filteringIgnoreCase is true', fakeAsync(() => {
4388+
const column = grid.getColumnByName('AnotherField');
4389+
expect(column.filteringIgnoreCase).toBeTrue();
4390+
4391+
GridFunctions.clickExcelFilterIconFromCode(fix, grid, 'AnotherField');
4392+
tick(100);
4393+
fix.detectChanges();
4394+
4395+
const searchComponent = GridFunctions.getExcelStyleSearchComponent(fix);
4396+
const listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix, searchComponent);
4397+
4398+
expect(listItems.length).toBe(3, 'incorrect rendered list items count');
4399+
expect(listItems[1].innerText).toBe('Custom', 'incorrect list item label');
4400+
}));
43904401

4402+
it('Should not ignore duplicate records when column\'\s filteringIgnoreCase is false', fakeAsync(() => {
4403+
const column = grid.getColumnByName('AnotherField');
4404+
column.filteringIgnoreCase = false;
4405+
expect(column.filteringIgnoreCase).toBeFalse();
4406+
4407+
GridFunctions.clickExcelFilterIconFromCode(fix, grid, 'AnotherField');
4408+
tick(100);
4409+
fix.detectChanges();
4410+
4411+
const searchComponent = GridFunctions.getExcelStyleSearchComponent(fix);
4412+
const listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix, searchComponent);
4413+
4414+
expect(listItems.length).toBe(5, 'incorrect rendered list items count');
4415+
expect(listItems[1].innerText).toBe('Custom', 'incorrect list item label');
4416+
expect(listItems[3].innerText).toBe('custoM', 'incorrect list item label');
4417+
expect(listItems[4].innerText).toBe('custom', 'incorrect list item label');
4418+
}));
4419+
4420+
it('Should display "Add to current filter selection" button on typing in input', fakeAsync(() => {
4421+
// Open excel style filtering dialog.
4422+
GridFunctions.clickExcelFilterIconFromCode(fix, grid, 'Downloads');
43914423
// Type string in search box.
43924424
const searchComponent = GridFunctions.getExcelStyleSearchComponent(fix);
43934425
const inputNativeElement = GridFunctions.getExcelStyleSearchComponentInput(fix, searchComponent);
@@ -4761,6 +4793,30 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => {
47614793
loadingIndicator = GridFunctions.getExcelFilteringLoadingIndicator(fix);
47624794
expect(loadingIndicator).toBeNull('esf loading indicator is visible');
47634795
}));
4796+
4797+
it('Done callback should be executed only once per column', fakeAsync(() => {
4798+
const compInstance = fix.componentInstance as IgxGridFilteringESFLoadOnDemandComponent;
4799+
// Open excel style custom filtering dialog and wait a bit.
4800+
GridFunctions.clickExcelFilterIcon(fix, 'ProductName');
4801+
tick(1000);
4802+
fix.detectChanges();
4803+
4804+
// Verify items in search have loaded and that the loading indicator is not visible.
4805+
expect(compInstance.doneCallbackCounter).toBe(1, 'Incorrect done callback execution count');
4806+
let listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix);
4807+
expect(listItems.length).toBe(6, 'incorrect rendered list items count');
4808+
let loadingIndicator = GridFunctions.getExcelFilteringLoadingIndicator(fix);
4809+
expect(loadingIndicator).toBeNull('esf loading indicator is visible');
4810+
4811+
GridFunctions.clickExcelFilterIcon(fix, 'Downloads');
4812+
tick(1000);
4813+
fix.detectChanges();
4814+
expect(compInstance.doneCallbackCounter).toBe(2, 'Incorrect done callback execution count');
4815+
listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix);
4816+
expect(listItems.length).toBe(9, 'incorrect rendered list items count');
4817+
loadingIndicator = GridFunctions.getExcelFilteringLoadingIndicator(fix);
4818+
expect(loadingIndicator).toBeNull('esf loading indicator is visible');
4819+
}));
47644820
});
47654821

47664822
describe(null, () => {

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
HostListener,
99
Input,
1010
NgZone,
11-
OnInit,
1211
OnDestroy
1312
} from '@angular/core';
1413
import { DataType } from '../../data-operations/data-util';
@@ -31,7 +30,7 @@ import { IgxGridExcelStyleFilteringComponent } from '../filtering/excel-style/gr
3130
selector: 'igx-grid-header',
3231
templateUrl: './grid-header.component.html'
3332
})
34-
export class IgxGridHeaderComponent implements DoCheck, OnInit, OnDestroy {
33+
export class IgxGridHeaderComponent implements DoCheck, OnDestroy {
3534

3635
private _destroy$ = new Subject<boolean>();
3736

@@ -143,10 +142,6 @@ export class IgxGridHeaderComponent implements DoCheck, OnInit, OnDestroy {
143142
public zone: NgZone
144143
) { }
145144

146-
public ngOnInit() {
147-
this.grid.filteringService.initFilteringSettings();
148-
}
149-
150145
public ngDoCheck() {
151146
this.getSortDirection();
152147
this.cdr.markForCheck();

projects/igniteui-angular/src/lib/test-utils/grid-samples.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,7 @@ export class CustomFilter extends IgxFilteringOperand {
998998
<igx-column width="100px" [field]="'ReleaseDate'" [header]="'ReleaseDate'" headerClasses="header-release-date"
999999
[filterable]="filterable" [resizable]="resizable" dataType="date">
10001000
</igx-column>
1001-
<igx-column width="100px" [field]="'AnotherField'" [header]="'Anogther Field'" [filterable]="filterable"
1001+
<igx-column width="100px" [field]="'AnotherField'" [header]="'Another Field'" [filterable]="filterable"
10021002
dataType="string" [filters]="customFilter">
10031003
</igx-column>
10041004
</igx-grid>`
@@ -1106,6 +1106,7 @@ export class CustomFilteringStrategyComponent extends BasicGridComponent {
11061106
export class IgxGridFilteringESFLoadOnDemandComponent extends BasicGridComponent {
11071107
private _filteringStrategy = new FilteringStrategy();
11081108
public data = SampleTestData.excelFilteringData();
1109+
public doneCallbackCounter = 0;
11091110

11101111
public columnValuesStrategy = (column: IgxColumnComponent,
11111112
columnExprTree: IFilteringExpressionsTree,
@@ -1114,6 +1115,7 @@ export class IgxGridFilteringESFLoadOnDemandComponent extends BasicGridComponent
11141115
const filteredData = this._filteringStrategy.filter(this.data, columnExprTree);
11151116
const columnValues = filteredData.map(record => record[column.field]);
11161117
done(columnValues);
1118+
this.doneCallbackCounter++;
11171119
}, 1000);
11181120
}
11191121
}

projects/igniteui-angular/src/lib/test-utils/sample-test-data.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,15 +1515,15 @@ export class SampleTestData {
15151515
ProductName: 'Some other item with Script',
15161516
ReleaseDate: SampleTestData.timeGenerator.timedelta(SampleTestData.today, 'day', 1),
15171517
Released: null,
1518-
AnotherField: 'a'
1518+
AnotherField: 'Custom'
15191519
},
15201520
{
15211521
Downloads: 0,
15221522
ID: 7,
15231523
ProductName: null,
15241524
ReleaseDate: SampleTestData.timeGenerator.timedelta(SampleTestData.today, 'month', 1),
15251525
Released: true,
1526-
AnotherField: 'a'
1526+
AnotherField: 'custoM'
15271527
},
15281528
{
15291529
Downloads: 1000,

0 commit comments

Comments
 (0)