Skip to content

Commit 8562713

Browse files
authored
Merge branch '13.0.x' into simeonoff/fix-10665
2 parents 5996dba + 1f2b02d commit 8562713

File tree

11 files changed

+124
-28
lines changed

11 files changed

+124
-28
lines changed

projects/igniteui-angular/src/lib/carousel/carousel-base.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { AnimationBuilder, AnimationPlayer, AnimationReferenceMetadata, useAnimation } from '@angular/animations';
2-
import { EventEmitter } from '@angular/core';
2+
import { ChangeDetectorRef, EventEmitter } from '@angular/core';
33
import { fadeIn } from '../animations/fade';
44
import { slideInLeft } from '../animations/slide';
55
import { mkenum } from '../core/utils';
@@ -49,7 +49,7 @@ export abstract class IgxCarouselComponentBase {
4949
/** @hidden */
5050
protected newDuration = 0;
5151

52-
constructor(private builder: AnimationBuilder) {
52+
constructor(private builder: AnimationBuilder, private cdr: ChangeDetectorRef) {
5353
}
5454

5555
/** @hidden */
@@ -86,6 +86,7 @@ export abstract class IgxCarouselComponentBase {
8686
if (this.animationStarted(this.enterAnimationPlayer)) {
8787
this.enterAnimationPlayer.reset();
8888
this.enterAnimationDone.emit();
89+
this.cdr.markForCheck();
8990
}
9091
}
9192

@@ -155,6 +156,7 @@ export abstract class IgxCarouselComponentBase {
155156
this.newDuration = 0;
156157
this.previousItem.previous = false;
157158
this.enterAnimationDone.emit();
159+
this.cdr.markForCheck();
158160
});
159161
this.previousItem.previous = true;
160162
this.enterAnimationPlayer.play();

projects/igniteui-angular/src/lib/carousel/carousel.component.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import {
1818
TemplateRef,
1919
ViewChild,
2020
ContentChild,
21-
Injectable
21+
Injectable,
22+
ChangeDetectorRef
2223
} from '@angular/core';
2324
import { IgxIconModule } from '../icon/public_api';
2425
import { IBaseEventArgs, mkenum, PlatformUtil } from '../core/utils';
@@ -534,9 +535,9 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On
534535
this.restartInterval();
535536
}
536537

537-
constructor(private element: ElementRef, private iterableDiffers: IterableDiffers,
538+
constructor(cdr: ChangeDetectorRef, private element: ElementRef, private iterableDiffers: IterableDiffers,
538539
builder: AnimationBuilder, private platformUtil: PlatformUtil) {
539-
super(builder);
540+
super(builder, cdr);
540541
this.differ = this.iterableDiffers.find([]).create(null);
541542
}
542543

projects/igniteui-angular/src/lib/expansion-panel/expansion-panel.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,8 @@ export class IgxExpansionPanelComponent extends ToggleAnimationPlayer implements
225225
* ```
226226
*/
227227
public collapse(evt?: Event) {
228-
if (this.collapsed) { // If expansion panel is already collapsed, do nothing
228+
// If expansion panel is already collapsed or is collapsing, do nothing
229+
if (this.collapsed || this.closeAnimationPlayer) {
229230
return;
230231
}
231232
const args = { event: evt, panel: this, owner: this, cancel: false };

projects/igniteui-angular/src/lib/expansion-panel/expansion-panel.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,16 @@ describe('igxExpansionPanel', () => {
196196
expect(panel.collapsed).toBeFalsy();
197197
expect(header.interaction.emit).toHaveBeenCalledTimes(4);
198198
expect(panel.contentCollapsed.emit).toHaveBeenCalledTimes(1);
199+
200+
// collapse when the panel has already started collapsing
201+
header.onAction(mockEvent);
202+
header.onAction(mockEvent);
203+
tick();
204+
fixture.detectChanges();
205+
206+
expect(panel.collapsed).toBeTruthy();
207+
expect(header.interaction.emit).toHaveBeenCalledTimes(6);
208+
expect(panel.contentCollapsing.emit).toHaveBeenCalledTimes(2);
199209
}));
200210

201211
it('Should expand/collapse without animation when animationSettings === null', fakeAsync(() => {

projects/igniteui-angular/src/lib/grids/common/strategy.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { GridType } from './grid.interface';
1111
const DATE_TYPE = 'date';
1212
const TIME_TYPE = 'time';
1313
const DATE_TIME_TYPE = 'dateTime';
14+
const STRING_TYPE = 'string';
1415

1516
export interface IGridSortingStrategy {
1617
sort(data: any[], expressions: ISortingExpression[], grid?: GridType): any[];
@@ -43,7 +44,8 @@ export class IgxSorting implements IGridSortingStrategy {
4344
const column = grid ? grid.getColumnByName(expressions[level].fieldName) : null;
4445
const isDate = column?.dataType === DATE_TYPE || column?.dataType === DATE_TIME_TYPE;
4546
const isTime = column?.dataType === TIME_TYPE;
46-
const group = this.groupedRecordsByExpression(data, i, expressions[level], isDate);
47+
const isString = column?.dataType === STRING_TYPE;
48+
const group = this.groupedRecordsByExpression(data, i, expressions[level], isDate, isString);
4749
const groupRow: IGroupByRecord = {
4850
expression: expressions[level],
4951
level,
@@ -104,17 +106,24 @@ export class IgxSorting implements IGridSortingStrategy {
104106
data: T[],
105107
index: number,
106108
expression: IGroupingExpression,
107-
isDate: boolean = false
109+
isDate: boolean = false,
110+
isString: boolean
108111
): T[] {
109112
const res = [];
110113
const key = expression.fieldName;
111114
const len = data.length;
112-
const groupval = this.getFieldValue(data[index], key, isDate);
115+
let groupval = this.getFieldValue(data[index], key, isDate);
113116
res.push(data[index]);
114117
index++;
115118
const comparer = expression.groupingComparer || DefaultSortingStrategy.instance().compareValues;
116119
for (let i = index; i < len; i++) {
117-
if (comparer(this.getFieldValue(data[i], key, isDate), groupval) === 0) {
120+
let fieldValue = this.getFieldValue(data[i], key, isDate);
121+
if (expression.ignoreCase && isString) {
122+
// when column's dataType is string but the value is number
123+
fieldValue = fieldValue?.toString().toLowerCase();
124+
groupval = groupval?.toString().toLowerCase();
125+
}
126+
if (comparer(fieldValue, groupval) === 0) {
118127
res.push(data[i]);
119128
} else {
120129
break;
@@ -147,13 +156,14 @@ export class IgxSorting implements IGridSortingStrategy {
147156
const column = grid?.getColumnByName(expr.fieldName);
148157
const isDate = column?.dataType === DATE_TYPE || column?.dataType === DATE_TIME_TYPE;
149158
const isTime = column?.dataType === TIME_TYPE;
159+
const isString = column?.dataType === STRING_TYPE;
150160
data = expr.strategy.sort(data, expr.fieldName, expr.dir, expr.ignoreCase, this.getFieldValue, isDate, isTime);
151161
if (expressionIndex === exprsLen - 1) {
152162
return data;
153163
}
154164
// in case of multiple sorting
155165
for (i = 0; i < dataLen; i++) {
156-
gbData = this.groupedRecordsByExpression(data, i, expr, isDate);
166+
gbData = this.groupedRecordsByExpression(data, i, expr, isDate, isString);
157167
gbDataLen = gbData.length;
158168
if (gbDataLen > 1) {
159169
gbData = this.sortDataRecursive(gbData, expressions, expressionIndex + 1, grid);

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

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ describe('IgxGrid - GroupBy #grid', () => {
3939
GroupByDataMoreColumnsComponent,
4040
GroupByEmptyColumnFieldComponent,
4141
MultiColumnHeadersWithGroupingComponent,
42-
GridGroupByRowCustomSelectorsComponent
42+
GridGroupByRowCustomSelectorsComponent,
43+
GridGroupByCaseSensitiveComponent
4344
],
4445
imports: [NoopAnimationsModule, IgxGridModule]
4546
});
@@ -63,7 +64,11 @@ describe('IgxGrid - GroupBy #grid', () => {
6364
if (level === maxLevel) {
6465
count++;
6566
}
66-
expect(rec[field]).toEqual(val);
67+
if (groupRow.groupRow.expression.ignoreCase) {
68+
expect(rec[field]?.toString().toLowerCase()).toEqual(val?.toString().toLowerCase());
69+
} else {
70+
expect(rec[field]).toEqual(val);
71+
}
6772
}
6873
}
6974
};
@@ -376,6 +381,30 @@ describe('IgxGrid - GroupBy #grid', () => {
376381
grid.groupingExpressions);
377382
}));
378383

384+
it('should group records correctly when ignoreCase is set to true.', fakeAsync(() => {
385+
const fix = TestBed.createComponent(GridGroupByCaseSensitiveComponent);
386+
fix.detectChanges();
387+
388+
// set groupingExpressions
389+
const grid = fix.componentInstance.instance;
390+
const exprs: ISortingExpression[] = [
391+
{ fieldName: 'ContactTitle', dir: SortingDirection.Asc, ignoreCase: true }
392+
];
393+
grid.groupingExpressions = exprs;
394+
tick();
395+
fix.detectChanges();
396+
397+
let groupRows = grid.groupsRowList.toArray();
398+
let dataRows = grid.dataRowList.toArray();
399+
400+
expect(groupRows.length).toEqual(2);
401+
expect(dataRows.length).toEqual(5);
402+
// verify groups
403+
checkGroups(groupRows,
404+
['Order Administrator', 'Owner'],
405+
grid.groupingExpressions);
406+
}));
407+
379408
it('should allow setting expand/collapse state', fakeAsync(() => {
380409
const fix = TestBed.createComponent(DefaultGridComponent);
381410
const grid = fix.componentInstance.instance;
@@ -3701,3 +3730,45 @@ export class GridGroupByRowCustomSelectorsComponent extends DataParent {
37013730
this.groupByRowClick = _event;
37023731
}
37033732
}
3733+
3734+
@Component({
3735+
template: `
3736+
<igx-grid
3737+
[width]='width'
3738+
[height]='height'
3739+
[data]="testData">
3740+
<igx-column [field]="'ID'" [header]="'ID'" [width]="200" [groupable]="true" [hasSummary]="false"></igx-column>
3741+
<igx-column [field]="'ContactTitle'" [header]="'ContactTitle'" [width]="200" [groupable]="true" [hasSummary]="false"
3742+
dataType="string"></igx-column>
3743+
</igx-grid>
3744+
`
3745+
})
3746+
export class GridGroupByCaseSensitiveComponent extends DataParent {
3747+
@ViewChild(IgxGridComponent, { read: IgxGridComponent, static: true })
3748+
public instance: IgxGridComponent;
3749+
3750+
public width = '800px';
3751+
public height = null;
3752+
public testData = [
3753+
{
3754+
ID: 1,
3755+
ContactTitle: "Owner"
3756+
},
3757+
{
3758+
ID: 2,
3759+
ContactTitle: 'Order Administrator'
3760+
},
3761+
{
3762+
ID: 3,
3763+
ContactTitle: "owner"
3764+
},
3765+
{
3766+
ID: 4,
3767+
ContactTitle: "Owner"
3768+
},
3769+
{
3770+
ID: 5,
3771+
ContactTitle: 'Order Administrator'
3772+
}
3773+
];
3774+
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,9 +284,9 @@ describe('IgxGrid - Grid Sorting #grid', () => {
284284
grid.sortingExpressions = exprs;
285285

286286
fixture.detectChanges();
287-
expect(grid.getCellByColumn(0, secondColumn).value).toEqual('ALex');
288-
expect(grid.getCellByColumn(0, thirdColumn).value).toEqual('Smith');
289-
expect(grid.getCellByColumn(0, firstColumn).value).toEqual(5);
287+
expect(grid.getCellByColumn(0, secondColumn).value).toEqual('Alex');
288+
expect(grid.getCellByColumn(0, thirdColumn).value).toEqual('Wilson');
289+
expect(grid.getCellByColumn(0, firstColumn).value).toEqual(4);
290290
expect(grid.getCellByColumn(grid.data.length - 1, secondColumn).value).toEqual('Rick');
291291
expect(grid.getCellByColumn(grid.data.length - 1, thirdColumn).value).toEqual('BRown');
292292
expect(grid.getCellByColumn(grid.data.length - 1, firstColumn).value).toEqual(7);
@@ -299,9 +299,9 @@ describe('IgxGrid - Grid Sorting #grid', () => {
299299
grid.sort(exprs);
300300
fixture.detectChanges();
301301

302-
expect(grid.getCellByColumn(0, secondColumn).value).toEqual('ALex');
303-
expect(grid.getCellByColumn(0, thirdColumn).value).toEqual('Smith');
304-
expect(grid.getCellByColumn(0, firstColumn).value).toEqual(5);
302+
expect(grid.getCellByColumn(0, secondColumn).value).toEqual('Alex');
303+
expect(grid.getCellByColumn(0, thirdColumn).value).toEqual('Wilson');
304+
expect(grid.getCellByColumn(0, firstColumn).value).toEqual(4);
305305
expect(grid.getCellByColumn(grid.data.length - 1, secondColumn).value).toEqual('Rick');
306306
expect(grid.getCellByColumn(grid.data.length - 1, thirdColumn).value).toEqual('BRown');
307307
expect(grid.getCellByColumn(grid.data.length - 1, firstColumn).value).toEqual(7);

projects/igniteui-angular/src/lib/stepper/stepper.component.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ describe('Stepper service unit tests', () => {
980980
};
981981

982982
stepperService = new IgxStepperService();
983-
stepper = new IgxStepperComponent(mockAnimationBuilder, stepperService, mockElementRef);
983+
stepper = new IgxStepperComponent(mockCdr, mockAnimationBuilder, stepperService, mockElementRef);
984984
steps = [];
985985
for (let index = 0; index < 4; index++) {
986986
const newStep = new IgxStepComponent(stepper, mockCdr, null,

projects/igniteui-angular/src/lib/stepper/stepper.component.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common';
33
import {
44
Component, HostBinding, OnDestroy, OnInit,
55
Input, Output, EventEmitter, ContentChildren, QueryList, ElementRef,
6-
NgModule, OnChanges, SimpleChanges, TemplateRef, ContentChild, AfterContentInit
6+
NgModule, OnChanges, SimpleChanges, TemplateRef, ContentChild, AfterContentInit, ChangeDetectorRef
77
} from '@angular/core';
88
import { Subject } from 'rxjs';
99
import { takeUntil } from 'rxjs/operators';
@@ -331,10 +331,11 @@ export class IgxStepperComponent extends IgxCarouselComponentBase implements Igx
331331
private readonly _defaultAnimationDuration = 350;
332332

333333
constructor(
334+
cdr: ChangeDetectorRef,
334335
private animBuilder: AnimationBuilder,
335336
private stepperService: IgxStepperService,
336337
private element: ElementRef<HTMLElement>) {
337-
super(animBuilder);
338+
super(animBuilder, cdr);
338339
this.stepperService.stepper = this;
339340
}
340341

projects/igniteui-angular/src/lib/tabs/tabs.directive.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { AnimationBuilder } from '@angular/animations';
22
import {
3-
AfterViewInit, ContentChildren, Directive, EventEmitter,
3+
AfterViewInit, ChangeDetectorRef, ContentChildren, Directive, EventEmitter,
44
Input, OnDestroy, Output, QueryList
55
} from '@angular/core';
66
import { Subscription } from 'rxjs';
@@ -119,8 +119,8 @@ export abstract class IgxTabsDirective extends IgxCarouselComponentBase implemen
119119
private _itemChanges$: Subscription;
120120

121121
/** @hidden */
122-
constructor(builder: AnimationBuilder) {
123-
super(builder);
122+
constructor(builder: AnimationBuilder, cdr: ChangeDetectorRef) {
123+
super(builder, cdr);
124124
}
125125

126126
/** @hidden */

0 commit comments

Comments
 (0)