Skip to content

Commit 39e5d20

Browse files
authored
Merge branch 'master' into pbozhinov/fixes-chips-not-being-reordered-ivy
2 parents 343bb99 + 3f45101 commit 39e5d20

File tree

17 files changed

+229
-22
lines changed

17 files changed

+229
-22
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ All notable changes for each version of this project will be documented in this
1717
- **Behavioral Change** - Pinning columns is no longer automatically prevented when the pinning area would exceed the size of the grid.
1818

1919
### New Features
20+
- `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid`:
21+
- `sortStrategy` input is added, which can be used to set a global sorting strategy for the entire grid.
22+
(**NOTE**: The grid's `sortStrategy` is of different type compared to the column's `sortStrategy`.)
23+
- `NoopSortingStrategy` is added, which can be used to disable the default sorting of the grid by assigning its instance to the grid's `sortStrategy` input. (Useful for remote sorting.)
24+
- `NoopFilteringStrategy` is added, which can be used to disable the default filtering of the grid by assigning its instance to the grid's `filterStrategy` input. (Useful for remote filtering.)
25+
- `sortingExpressionsChange` event emitter is added, which is fired whenever a change to the sorting expressions has occurred (prior to performing the actual sorting).
26+
- `filteringExpressionsTreeChange` event emitter is added, which is fired whenever a change to the filtering expressions has occurred (prior to performing the actual filtering).
2027
- `IgxOverlayService`:
2128
- `setOffset` method added. It offsets the content along the corresponding axis by the provided amount.
2229
- `IgxToggleDirective`:

projects/igniteui-angular/migrations/update-8_2_6/index.spec.ts

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import * as path from 'path';
2-
32
// tslint:disable:no-implicit-dependencies
43
import { virtualFs } from '@angular-devkit/core';
54
import { EmptyTree } from '@angular-devkit/schematics';
@@ -64,4 +63,27 @@ describe('Update 8.2.6', () => {
6463
);
6564
done();
6665
});
66+
67+
it('should update igx-grid-paginator-theme', done => {
68+
appTree.create(
69+
'/testSrc/appPrefix/component/test.component.scss',
70+
`$dark-grid-paginator: igx-grid-paginator-theme($color: black);
71+
@include igx-grid-paginator($dark-grid-paginator);
72+
.igx-grid-paginator__pager {
73+
@include igx-button($dark-button);
74+
}
75+
$dark-grid-paginator-schema: extend($_dark-grid-pagination,());`
76+
);
77+
const tree = schematicRunner.runSchematic('migration-12', {}, appTree);
78+
expect(tree.readContent('/testSrc/appPrefix/component/test.component.scss'))
79+
.toEqual(
80+
`$dark-grid-paginator: igx-paginator-theme($color: black);
81+
@include igx-paginator($dark-grid-paginator);
82+
.igx-grid-paginator__pager {
83+
@include igx-button($dark-button);
84+
}
85+
$dark-grid-paginator-schema: extend($_dark-pagination,());`
86+
);
87+
done();
88+
});
6789
});

projects/igniteui-angular/migrations/update-8_2_6/index.ts

+50
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,64 @@ import {
33
SchematicContext,
44
Tree
55
} from '@angular-devkit/schematics';
6+
import { getProjects, getWorkspace } from '../common/util';
67
import { UpdateChanges } from '../common/UpdateChanges';
78

89
const version = '8.2.6';
910

1011
export default function(): Rule {
1112
return (host: Tree, context: SchematicContext) => {
13+
const themes = ['$_base-dark-grid-pagination',
14+
'$_dark-grid-pagination',
15+
'$_dark-fluent-grid-pagination',
16+
'$_light-grid-pagination',
17+
'$_fluent-grid-pagination',
18+
'$_round-shape-grid-pagination',
19+
'$_default-shape-grid-pagination',
20+
'$_square-shape-grid-pagination'];
21+
22+
const newThemes = ['$_base-dark-pagination',
23+
'$_dark-pagination',
24+
'$_dark-fluent-pagination',
25+
'$_light-pagination',
26+
'$_fluent-pagination',
27+
'$_round-shape-pagination',
28+
'$_default-shape-pagination',
29+
'$_square-shape-pagination'];
30+
31+
let globalStyleExt: string;
32+
const config = getWorkspace(host);
33+
const projects = getProjects(config);
34+
1235
context.logger.info(`Applying migration for Ignite UI for Angular to version ${version}`);
1336

37+
if (config.schematics && config.schematics['@schematics/angular:component']) {
38+
// updated projects have global prefix rather than per-project:
39+
globalStyleExt = config.schematics['@schematics/angular:component'].styleext;
40+
}
41+
42+
for (const proj of projects) {
43+
const dir = host.getDir(proj.sourceRoot);
44+
let ext = globalStyleExt || 'scss';
45+
if (proj.schematics && proj.schematics['@schematics/angular:component']) {
46+
ext = proj.schematics['@schematics/angular:component'].styleext || ext;
47+
}
48+
dir.visit((path, entry) => {
49+
if (path.endsWith('.' + ext)) {
50+
let content = entry.content.toString();
51+
if (content.match(/\bigx-grid-paginator\b/g)) {
52+
content = content.replace(/\bigx-grid-paginator\b/g, 'igx-paginator');
53+
}
54+
themes.forEach((n, i) => {
55+
if (content.indexOf(n) !== -1) {
56+
content = content.split(n).join(newThemes[i]);
57+
}
58+
});
59+
host.overwrite(path, content);
60+
}
61+
});
62+
}
63+
1464
const update = new UpdateChanges(__dirname, host, context);
1565
update.applyChanges();
1666
};

projects/igniteui-angular/src/lib/data-operations/data-util.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { IFilteringState } from './filtering-state.interface';
22

3-
import { IgxSorting, IgxDataRecordSorting } from './sorting-strategy';
3+
import { IgxSorting, IgxDataRecordSorting, IGridSortingStrategy } from './sorting-strategy';
44
import { IgxGrouping } from './grouping-strategy';
55
import { IGroupByResult } from './grouping-result.interface';
66

@@ -30,24 +30,25 @@ export enum DataType {
3030
* @hidden
3131
*/
3232
export class DataUtil {
33-
public static sort<T>(data: T[], expressions: ISortingExpression[], sorting: IgxSorting = new IgxSorting()): T[] {
33+
public static sort<T>(data: T[], expressions: ISortingExpression[], sorting: IGridSortingStrategy = new IgxSorting()): T[] {
3434
return sorting.sort(data, expressions);
3535
}
3636

3737
public static treeGridSort(hierarchicalData: ITreeGridRecord[],
3838
expressions: ISortingExpression[],
39+
sorting: IGridSortingStrategy = new IgxDataRecordSorting(),
3940
parent?: ITreeGridRecord): ITreeGridRecord[] {
4041
let res: ITreeGridRecord[] = [];
4142
hierarchicalData.forEach((hr: ITreeGridRecord) => {
4243
const rec: ITreeGridRecord = DataUtil.cloneTreeGridRecord(hr);
4344
rec.parent = parent;
4445
if (rec.children) {
45-
rec.children = DataUtil.treeGridSort(rec.children, expressions, rec);
46+
rec.children = DataUtil.treeGridSort(rec.children, expressions, sorting, rec);
4647
}
4748
res.push(rec);
4849
});
4950

50-
res = DataUtil.sort(res, expressions, new IgxDataRecordSorting());
51+
res = DataUtil.sort(res, expressions, sorting);
5152

5253
return res;
5354
}

projects/igniteui-angular/src/lib/data-operations/filtering-strategy.ts

+14
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@ export interface IFilteringStrategy {
55
filter(data: any[], expressionsTree: IFilteringExpressionsTree, advancedExpressionsTree?: IFilteringExpressionsTree): any[];
66
}
77

8+
export class NoopFilteringStrategy implements IFilteringStrategy {
9+
private static _instance: NoopFilteringStrategy = null;
10+
11+
private constructor() { }
12+
13+
public static instance() {
14+
return this._instance || (this._instance = new NoopFilteringStrategy());
15+
}
16+
17+
public filter(data: any[], expressionsTree: IFilteringExpressionsTree, advancedExpressionsTree?: IFilteringExpressionsTree): any[] {
18+
return data;
19+
}
20+
}
21+
822
export abstract class BaseFilteringStrategy implements IFilteringStrategy {
923
public abstract filter(data: any[], expressionsTree: IFilteringExpressionsTree,
1024
advancedExpressionsTree?: IFilteringExpressionsTree): any[];

projects/igniteui-angular/src/lib/data-operations/sorting-strategy.ts

+19-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,25 @@ export class DefaultSortingStrategy implements ISortingStrategy {
7171
}
7272
}
7373

74-
export class IgxSorting {
74+
export interface IGridSortingStrategy {
75+
sort(data: any[], expressions: ISortingExpression[]): any[];
76+
}
77+
78+
export class NoopSortingStrategy implements IGridSortingStrategy {
79+
private static _instance: NoopSortingStrategy = null;
80+
81+
private constructor() { }
82+
83+
public static instance() {
84+
return this._instance || (this._instance = new NoopSortingStrategy());
85+
}
86+
87+
public sort(data: any[], expressions: ISortingExpression[]): any[] {
88+
return data;
89+
}
90+
}
91+
92+
export class IgxSorting implements IGridSortingStrategy {
7593
public sort(data: any[], expressions: ISortingExpression[]): any[] {
7694
return this.sortDataRecursive(data, expressions);
7795
}

projects/igniteui-angular/src/lib/directives/autocomplete/autocomplete.directive.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective
201201
}
202202

203203
/** @hidden @internal */
204-
@HostListener('input', ['$event'])
204+
@HostListener('input')
205205
onInput() {
206206
this.open();
207207
}
@@ -217,8 +217,8 @@ export class IgxAutocompleteDirective extends IgxDropDownItemNavigationDirective
217217
}
218218

219219
/** @hidden @internal */
220-
@HostListener('keydown.Tab', ['$event'])
221-
@HostListener('keydown.Shift.Tab', [`$event`])
220+
@HostListener('keydown.Tab')
221+
@HostListener('keydown.Shift.Tab')
222222
onTab() {
223223
this.close();
224224
}

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

+45-2
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ import { IgxHeadSelectorDirective, IgxRowSelectorDirective } from './selection/r
131131
import { IgxGridToolbarCustomContentDirective } from './toolbar/toolbar.directive';
132132
import { IgxColumnComponent } from './columns/column.component';
133133
import { IgxColumnGroupComponent } from './columns/column-group.component';
134+
import { IGridSortingStrategy } from '../data-operations/sorting-strategy';
134135

135136
const MINIMUM_COLUMN_WIDTH = 136;
136137
const FILTER_ROW_HEIGHT = 50;
@@ -168,6 +169,7 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
168169
public _destroyed = false;
169170
private overlayIDs = [];
170171
private _filteringStrategy: IFilteringStrategy;
172+
private _sortingStrategy: IGridSortingStrategy;
171173

172174
private _hostWidth;
173175
private _advancedFilteringOverlayId: string;
@@ -327,7 +329,18 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
327329
}
328330

329331
/**
330-
*@hidden
332+
* Emitted before filtering is performed.
333+
* Returns the filtering expressions tree of the column for which filtering was performed.
334+
* ```typescript
335+
* filteringExprTreeChange(event: IFilteringExpressionsTree){
336+
* const filteringTree = event;
337+
* }
338+
* ```
339+
* ```html
340+
* <igx-grid #grid [data]="localData" [height]="'305px'" [autoGenerate]="true"
341+
* (filteringExpressionsTreeChange)="filteringExprTreeChange($event)"></igx-grid>
342+
* ```
343+
* @memberof IgxGridBaseDirective
331344
*/
332345
@Output()
333346
public filteringExpressionsTreeChange = new EventEmitter<IFilteringExpressionsTree>();
@@ -1078,6 +1091,27 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
10781091
this._filteringStrategy = classRef;
10791092
}
10801093

1094+
/**
1095+
* Gets the sorting strategy of the grid.
1096+
* ```typescript
1097+
* let sortStrategy = this.grid.sortStrategy
1098+
* ```
1099+
*/
1100+
@Input()
1101+
get sortStrategy(): IGridSortingStrategy {
1102+
return this._sortingStrategy;
1103+
}
1104+
1105+
/**
1106+
* Sets the sorting strategy of the grid.
1107+
* ```html
1108+
* <igx-grid #grid [data]="localData" [sortStrategy]="sortStrategy"></igx-grid>
1109+
* ```
1110+
*/
1111+
set sortStrategy(value: IGridSortingStrategy) {
1112+
this._sortingStrategy = value;
1113+
}
1114+
10811115
/**
10821116
* An @Input property that provides a callback for loading unique column values on demand.
10831117
* If this property is provided, the unique values it generates will be used by the Excel Style Filtering.
@@ -2155,7 +2189,16 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
21552189
}
21562190

21572191
/**
2158-
*@hidden
2192+
* Emitted before sorting is performed. Returns the sorting expressions.
2193+
* ```html
2194+
* <igx-grid #grid [data]="localData" [autoGenerate]="true" (sortingExpressionsChange)="sortingExprChange($event)"></igx-grid>
2195+
* ```
2196+
* ```typescript
2197+
* sortingExprChange(event: ISortingExpression[]){
2198+
* const sortingExpressions = event;
2199+
* }
2200+
* ```
2201+
* @memberof IgxGridBaseDirective
21592202
*/
21602203
@Output()
21612204
public sortingExpressionsChange = new EventEmitter<ISortingExpression[]>();

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

+21
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
} from '../../test-utils/grid-samples.spec';
4646
import { HelperUtils } from '../../test-utils/helper-utils.spec';
4747
import { GridSelectionMode, FilterMode } from '../common/enums';
48+
import { NoopFilteringStrategy } from '../../data-operations/filtering-strategy';
4849

4950
const FILTER_UI_ROW = 'igx-grid-filtering-row';
5051
const FILTER_UI_CELL = 'igx-grid-filtering-cell';
@@ -3422,6 +3423,26 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => {
34223423
expect(chip.componentInstance.selected).toBeTruthy();
34233424
}));
34243425

3426+
it('Should disable filtering feature when using NoopFilteringStrategy.', (async () => {
3427+
// Use the NoopFilteringStrategy.
3428+
grid.filterStrategy = NoopFilteringStrategy.instance();
3429+
fix.detectChanges();
3430+
3431+
GridFunctions.clickFilterCellChip(fix, 'ProductName');
3432+
fix.detectChanges();
3433+
3434+
// Add first chip.
3435+
GridFunctions.typeValueInFilterRowInput('some value', fix);
3436+
await wait(16);
3437+
GridFunctions.submitFilterRowInput(fix);
3438+
await wait(100);
3439+
3440+
// Verify the grid is not filtered, because of the noop filter strategy.
3441+
expect(grid.rowList.length).toBe(8);
3442+
expect(GridFunctions.getCurrentCellFromGrid(grid, 0, 1).value).toBe('Ignite UI for JavaScript');
3443+
expect(GridFunctions.getCurrentCellFromGrid(grid, 1, 1).value).toBe('NetAdvantage');
3444+
}));
3445+
34253446
it('Should close filterRow when changing filterMode from \'quickFilter\' to \'excelStyleFilter\'', (async () => {
34263447
GridFunctions.clickFilterCellChip(fix, 'ProductName');
34273448
fix.detectChanges();

projects/igniteui-angular/src/lib/grids/grid/grid.component.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@
107107
| gridTransaction:id:pipeTrigger
108108
| visibleColumns:hasVisibleColumns
109109
| gridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger
110-
| gridSort:sortingExpressions:id:pipeTrigger
110+
| gridSort:sortingExpressions:sortStrategy:id:pipeTrigger
111111
| gridGroupBy:groupingExpressions:groupingExpansionState:groupsExpanded:id:groupsRecords:pipeTrigger
112112
| gridPaging:page:perPage:id:pipeTrigger
113113
| gridSummary:hasSummarizedColumns:summaryCalculationMode:summaryPosition:id:pipeTrigger:summaryPipeTrigger"

projects/igniteui-angular/src/lib/grids/grid/grid.pipes.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { GridBaseAPIService } from '../api.service';
1212
import { IgxGridBaseDirective } from '../grid-base.directive';
1313
import { GridType } from '../common/grid.interface';
1414
import { IFilteringStrategy } from '../../data-operations/filtering-strategy';
15+
import { IGridSortingStrategy } from '../../data-operations/sorting-strategy';
1516

1617
/**
1718
*@hidden
@@ -27,14 +28,15 @@ export class IgxGridSortingPipe implements PipeTransform {
2728
this.gridAPI = <IgxGridAPIService>gridAPI;
2829
}
2930

30-
public transform(collection: any[], expressions: ISortingExpression[], id: string, pipeTrigger: number): any[] {
31+
public transform(collection: any[], expressions: ISortingExpression[], sorting: IGridSortingStrategy,
32+
id: string, pipeTrigger: number): any[] {
3133
const grid = this.gridAPI.grid;
3234
let result: any[];
3335

3436
if (!expressions.length) {
3537
result = collection;
3638
} else {
37-
result = DataUtil.sort(cloneArray(collection), expressions);
39+
result = DataUtil.sort(cloneArray(collection), expressions, sorting);
3840
}
3941
grid.filteredSortedData = result;
4042

0 commit comments

Comments
 (0)