@progress/kendo-angular-grid 16.11.0-develop.1 → 16.11.0-develop.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,6 +27,7 @@ export class CellSelectionService {
27
27
  this.mouseUpEvent = new EventEmitter();
28
28
  this.currentSelection = [];
29
29
  this.active = false;
30
+ this.nonSelectableRows = new Map();
30
31
  this.dragging = false;
31
32
  this.dragSelectDeselect = false;
32
33
  this.lastSelectionItem = { itemKey: 0, columnKey: 0 };
@@ -48,9 +49,13 @@ export class CellSelectionService {
48
49
  selectableSettings.drag;
49
50
  return this.active && dragAndMultiple;
50
51
  }
52
+ get hasNonSelectable() {
53
+ return this.nonSelectableRows.size > 0;
54
+ }
51
55
  init(settings) {
52
56
  this.settings = settings;
53
57
  this.currentSelection = [];
58
+ this.nonSelectableRows = new Map();
54
59
  if (settings.selectable && settings.selectable.enabled !== false) {
55
60
  const iterator = this.getIterator();
56
61
  let item = iterator.next();
@@ -65,6 +70,9 @@ export class CellSelectionService {
65
70
  if (selectedCellArgs.selected) {
66
71
  this.currentSelection.push(selectedCellArgs.item);
67
72
  }
73
+ if (!settings.isRowSelectable(rowArgs)) {
74
+ this.nonSelectableRows.set(rowArgs.index, rowArgs.dataItem);
75
+ }
68
76
  });
69
77
  }
70
78
  item = iterator.next();
@@ -74,7 +82,7 @@ export class CellSelectionService {
74
82
  isCellSelected(item, col) {
75
83
  if (this.settings && this.active) {
76
84
  const selectedCellArgs = this.settings.cellSelected({ dataItem: item.data, index: item.index }, col, col.leafIndex);
77
- return this.options.enabled && selectedCellArgs.selected;
85
+ return this.options.enabled && selectedCellArgs.selected && !this.nonSelectableRows.has(item.index);
78
86
  }
79
87
  return false;
80
88
  }
@@ -89,7 +97,7 @@ export class CellSelectionService {
89
97
  ev = this.toggle(item);
90
98
  }
91
99
  else if (this.options.mode === "multiple") {
92
- if (ctrlKey && !event.shiftKey) {
100
+ if ((ctrlKey || !this.options.metaKeyMultiSelect) && !event.shiftKey) {
93
101
  ev = this.toggle(item);
94
102
  }
95
103
  else if (event.shiftKey) {
@@ -130,7 +138,7 @@ export class CellSelectionService {
130
138
  if (this.isCellSelected(item, item.column)) {
131
139
  deselectedCells.push(this.lastSelectionItem);
132
140
  }
133
- else {
141
+ else if (!this.nonSelectableRows.has(item.index)) {
134
142
  selectedCells.push(this.lastSelectionItem);
135
143
  }
136
144
  return {
@@ -145,7 +153,7 @@ export class CellSelectionService {
145
153
  this.settings.cellSelected({ dataItem: item.data, index: item.index }, item.column, item.column.leafIndex).item;
146
154
  this.lastSelectionItemRowIndex = item.index;
147
155
  this.lastSelectionItemColIndex = item.column.leafIndex;
148
- if (!this.isCellSelected(item, item.column)) {
156
+ if (!this.isCellSelected(item, item.column) && !this.nonSelectableRows.has(item.index)) {
149
157
  selectedCells.push(this.lastSelectionItem);
150
158
  }
151
159
  this.currentSelection.forEach((selectedItem) => {
@@ -176,7 +184,7 @@ export class CellSelectionService {
176
184
  if (rowArgs) {
177
185
  const cellsToRemove = this.currentSelection.filter(selectedItem => {
178
186
  const contender = this.settings.cellSelected(rowArgs, null, null).item;
179
- return selectedItem.itemKey === contender.itemKey;
187
+ return selectedItem.itemKey === contender.itemKey || this.nonSelectableRows.has(rowArgs.index);
180
188
  });
181
189
  if (cellsToRemove.length) {
182
190
  const ev = {
@@ -214,7 +222,7 @@ export class CellSelectionService {
214
222
  if (!isInSelectionRect && selected) {
215
223
  deselectedCells.push(item);
216
224
  }
217
- if (isInSelectionRect && !selected) {
225
+ if (isInSelectionRect && !selected && !this.nonSelectableRows.has(idx)) {
218
226
  selectedCells.push(item);
219
227
  }
220
228
  });
@@ -236,7 +244,8 @@ export class CellSelectionService {
236
244
  cellAggregates: false,
237
245
  checkboxOnly: false,
238
246
  enabled: true,
239
- mode: "multiple"
247
+ mode: "multiple",
248
+ metaKeyMultiSelect: true
240
249
  };
241
250
  if (!isPresent(this.settings)) {
242
251
  return defaultOptions;
@@ -246,7 +255,8 @@ export class CellSelectionService {
246
255
  cellAggregates: false,
247
256
  checkboxOnly: false,
248
257
  enabled: this.settings.selectable,
249
- mode: "multiple"
258
+ mode: "multiple",
259
+ metaKeyMultiSelect: true
250
260
  };
251
261
  }
252
262
  else {
@@ -2,13 +2,14 @@
2
2
  * Copyright © 2024 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { detectIE } from './../utils';
6
5
  import { Directive, HostBinding, Renderer2, ElementRef, Input, Output, EventEmitter, NgZone } from '@angular/core';
7
6
  import { SelectionService } from './selection.service';
8
7
  import { isPresent } from '../utils';
9
8
  import { hasObservers } from '@progress/kendo-angular-common';
9
+ import { CellSelectionService } from './cell-selection.service';
10
10
  import * as i0 from "@angular/core";
11
11
  import * as i1 from "./selection.service";
12
+ import * as i2 from "./cell-selection.service";
12
13
  /**
13
14
  * Represents the select-all checkbox feature of the Grid ([see example](slug:grid_selection_persistence#toc-selecting-all-items)).
14
15
  *
@@ -24,8 +25,9 @@ import * as i1 from "./selection.service";
24
25
  * ```
25
26
  */
26
27
  export class SelectAllCheckboxDirective {
27
- constructor(selectionService, el, renderer, ngZone) {
28
+ constructor(selectionService, cellSelectionService, el, renderer, ngZone) {
28
29
  this.selectionService = selectionService;
30
+ this.cellSelectionService = cellSelectionService;
29
31
  this.el = el;
30
32
  this.renderer = renderer;
31
33
  this.ngZone = ngZone;
@@ -55,11 +57,11 @@ export class SelectAllCheckboxDirective {
55
57
  * @hidden
56
58
  */
57
59
  onClick() {
58
- // yields consistent cross-browser behavior when clicking an indeterminate checkbox
59
- const undefinedCheckedStateInIE = detectIE() && this.selectionService.selectAllState === undefined;
60
- const isChecked = undefinedCheckedStateInIE ? true : this.el.nativeElement.checked;
60
+ const uncheckedState = this.el.nativeElement.indeterminate ? 'indeterminate' : 'unchecked';
61
+ const checkboxState = this.el.nativeElement.checked ? 'checked' : uncheckedState;
62
+ const isChecked = this.selectionService.hasNonSelectable ? !this.selectionService.selectAllChecked : this.el.nativeElement.checked;
61
63
  const options = this.selectionService.options;
62
- const enabledAndMultiple = options.enabled && options.mode === 'multiple';
64
+ const enabledAndMultiple = options.enabled && options.mode === 'multiple' && !this.cellSelectionService.active;
63
65
  const shouldEmitSelectAll = hasObservers(this.selectAllChange);
64
66
  if (enabledAndMultiple || shouldEmitSelectAll) {
65
67
  this.ngZone.run(() => {
@@ -67,7 +69,7 @@ export class SelectAllCheckboxDirective {
67
69
  this.selectionService.updateAll(isChecked);
68
70
  }
69
71
  if (shouldEmitSelectAll) {
70
- this.selectAllChange.emit(isChecked ? 'checked' : 'unchecked');
72
+ this.selectAllChange.emit(checkboxState);
71
73
  }
72
74
  });
73
75
  }
@@ -95,7 +97,7 @@ export class SelectAllCheckboxDirective {
95
97
  }
96
98
  }
97
99
  }
98
- SelectAllCheckboxDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SelectAllCheckboxDirective, deps: [{ token: i1.SelectionService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
100
+ SelectAllCheckboxDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SelectAllCheckboxDirective, deps: [{ token: i1.SelectionService }, { token: i2.CellSelectionService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
99
101
  SelectAllCheckboxDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: SelectAllCheckboxDirective, isStandalone: true, selector: "[kendoGridSelectAllCheckbox]", inputs: { state: "state" }, outputs: { selectAllChange: "selectAllChange" }, host: { properties: { "attr.type": "this.type" } }, usesOnChanges: true, ngImport: i0 });
100
102
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SelectAllCheckboxDirective, decorators: [{
101
103
  type: Directive,
@@ -103,7 +105,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
103
105
  selector: '[kendoGridSelectAllCheckbox]',
104
106
  standalone: true
105
107
  }]
106
- }], ctorParameters: function () { return [{ type: i1.SelectionService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { state: [{
108
+ }], ctorParameters: function () { return [{ type: i1.SelectionService }, { type: i2.CellSelectionService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { state: [{
107
109
  type: Input
108
110
  }], selectAllChange: [{
109
111
  type: Output
@@ -6,9 +6,11 @@ import { Directive, HostBinding, ElementRef, Input, Renderer2, NgZone } from '@a
6
6
  import { SelectionService } from './selection.service';
7
7
  import { Keys } from '@progress/kendo-angular-common';
8
8
  import { CellSelectionAggregateService } from '../aggregates/selection-aggregate.service';
9
+ import { CellSelectionService } from './cell-selection.service';
9
10
  import * as i0 from "@angular/core";
10
11
  import * as i1 from "./selection.service";
11
- import * as i2 from "../aggregates/selection-aggregate.service";
12
+ import * as i2 from "./cell-selection.service";
13
+ import * as i3 from "../aggregates/selection-aggregate.service";
12
14
  /**
13
15
  * Represents the row-selection checkbox of the Grid. The directive expects the
14
16
  * index of the current row as an input parameter. Inside the [`CellTemplateDirective`](slug:api_grid_celltemplatedirective), apply the
@@ -28,8 +30,9 @@ import * as i2 from "../aggregates/selection-aggregate.service";
28
30
  * ```
29
31
  */
30
32
  export class SelectionCheckboxDirective {
31
- constructor(selectionService, aggregateService, el, renderer, ngZone) {
33
+ constructor(selectionService, cellSelectionService, aggregateService, el, renderer, ngZone) {
32
34
  this.selectionService = selectionService;
35
+ this.cellSelectionService = cellSelectionService;
33
36
  this.aggregateService = aggregateService;
34
37
  this.el = el;
35
38
  this.renderer = renderer;
@@ -51,12 +54,25 @@ export class SelectionCheckboxDirective {
51
54
  this.destroyKeyDown();
52
55
  }
53
56
  }
54
- onClick() {
57
+ onClick(event) {
58
+ const nonSelectableRow = this.selectionService.nonSelectableRows.has(this.itemIndex) || this.cellSelectionService.nonSelectableRows.has(this.itemIndex);
59
+ if (nonSelectableRow || this.cellSelectionService.options.cell) {
60
+ event.preventDefault();
61
+ return;
62
+ }
55
63
  if (this.selectionService.options.enabled) {
56
64
  this.ngZone.run(() => {
57
- const ev = this.selectionService.toggleByIndex(this.itemIndex);
58
- ev.ctrlKey = true;
59
- ev.shiftKey = false;
65
+ let ev;
66
+ const ctrlKey = event.ctrlKey || event.metaKey;
67
+ if (event.shiftKey) {
68
+ const item = { index: this.itemIndex };
69
+ ev = this.selectionService.addAllTo(item, ctrlKey);
70
+ }
71
+ else {
72
+ ev = this.selectionService.toggleByIndex(this.itemIndex);
73
+ }
74
+ ev.ctrlKey = event.ctrlKey;
75
+ ev.shiftKey = event.shiftKey;
60
76
  if (this.selectionService.options.cellAggregates) {
61
77
  ev.cellAggregates = this.aggregateService.onSelectionChange(ev);
62
78
  }
@@ -66,17 +82,18 @@ export class SelectionCheckboxDirective {
66
82
  }
67
83
  onKeyDown(e) {
68
84
  if (e.keyCode === Keys.Enter) {
69
- this.onClick();
85
+ this.onClick(e);
70
86
  }
71
87
  }
72
88
  /*
73
89
  * @hidden
74
90
  */
75
91
  setCheckedState() {
76
- this.renderer.setProperty(this.el.nativeElement, 'checked', this.selectionService.isSelected(this.itemIndex));
92
+ const isSelected = this.selectionService.nonSelectableRows.has(this.itemIndex) ? false : this.selectionService.isSelected(this.itemIndex);
93
+ this.renderer.setProperty(this.el.nativeElement, 'checked', isSelected);
77
94
  }
78
95
  }
79
- SelectionCheckboxDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SelectionCheckboxDirective, deps: [{ token: i1.SelectionService }, { token: i2.CellSelectionAggregateService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
96
+ SelectionCheckboxDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SelectionCheckboxDirective, deps: [{ token: i1.SelectionService }, { token: i2.CellSelectionService }, { token: i3.CellSelectionAggregateService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
80
97
  SelectionCheckboxDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: SelectionCheckboxDirective, isStandalone: true, selector: "[kendoGridSelectionCheckbox]", inputs: { itemIndex: ["kendoGridSelectionCheckbox", "itemIndex"] }, host: { properties: { "attr.type": "this.type" } }, ngImport: i0 });
81
98
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SelectionCheckboxDirective, decorators: [{
82
99
  type: Directive,
@@ -84,7 +101,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
84
101
  selector: '[kendoGridSelectionCheckbox]',
85
102
  standalone: true
86
103
  }]
87
- }], ctorParameters: function () { return [{ type: i1.SelectionService }, { type: i2.CellSelectionAggregateService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { itemIndex: [{
104
+ }], ctorParameters: function () { return [{ type: i1.SelectionService }, { type: i2.CellSelectionService }, { type: i3.CellSelectionAggregateService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { itemIndex: [{
88
105
  type: Input,
89
106
  args: ['kendoGridSelectionCheckbox']
90
107
  }], type: [{
@@ -50,6 +50,9 @@ export class Selection {
50
50
  if (!isPresent(this.ctx.grid.rowSelected)) {
51
51
  this.ctx.grid.rowSelected = (row) => this.rowSelectionState.has(this.getItemKey(row));
52
52
  }
53
+ if (!isPresent(this.ctx.grid.isRowSelectable)) {
54
+ this.ctx.grid.isRowSelectable = (_row) => Boolean(this.ctx.grid.selectable);
55
+ }
53
56
  if (!isPresent(this.ctx.grid.cellSelected)) {
54
57
  this.ctx.grid.cellSelected = (row, column, colIndex) => {
55
58
  const contender = this.getSelectionItem(row, column, colIndex);
@@ -28,6 +28,7 @@ export class SelectionService {
28
28
  this.ctxService = ctxService;
29
29
  this.changes = new EventEmitter();
30
30
  this.currentSelection = [];
31
+ this.nonSelectableRows = new Map();
31
32
  this.selectAllChecked = false;
32
33
  this.active = false;
33
34
  this.dragging = false;
@@ -48,6 +49,9 @@ export class SelectionService {
48
49
  selectableSettings.drag;
49
50
  return this.active && dragAndMultiple;
50
51
  }
52
+ get hasNonSelectable() {
53
+ return this.nonSelectableRows.size > 0;
54
+ }
51
55
  init(settings) {
52
56
  this.settings = settings;
53
57
  if (!isPresent(this.lastSelectionStartIndex)) {
@@ -55,6 +59,7 @@ export class SelectionService {
55
59
  this.lastSelectionData = this.ctxService?.grid.selectionDirective?.rangeSelectionStartRow?.dataItem || {};
56
60
  }
57
61
  this.currentSelection = [];
62
+ this.nonSelectableRows = new Map();
58
63
  if (settings.selectable && settings.selectable.enabled !== false) {
59
64
  const iterator = this.getIterator();
60
65
  this._selectAllState = true;
@@ -71,6 +76,10 @@ export class SelectionService {
71
76
  else {
72
77
  this._selectAllState = undefined;
73
78
  }
79
+ if (!settings.isRowSelectable(rowArgs)) {
80
+ this.nonSelectableRows.set(rowArgs.index, rowArgs.dataItem);
81
+ this._selectAllState = undefined;
82
+ }
74
83
  }
75
84
  item = iterator.next();
76
85
  }
@@ -81,7 +90,7 @@ export class SelectionService {
81
90
  }
82
91
  isSelected(index) {
83
92
  if (this.settings && this.active) {
84
- return this.options.enabled && isPresent(this.currentSelection[index]);
93
+ return this.options.enabled && isPresent(this.currentSelection[index]) && !this.nonSelectableRows.has(index);
85
94
  }
86
95
  }
87
96
  handleClick(item, event) {
@@ -95,7 +104,7 @@ export class SelectionService {
95
104
  ev = this.toggle(item);
96
105
  }
97
106
  else if (this.options.mode === "multiple") {
98
- if (ctrlKey && !event.shiftKey) {
107
+ if ((ctrlKey || !this.options.metaKeyMultiSelect) && !event.shiftKey) {
99
108
  ev = this.toggle(item);
100
109
  }
101
110
  else if (event.shiftKey) {
@@ -132,9 +141,13 @@ export class SelectionService {
132
141
  if (this.isSelected(item.index)) {
133
142
  deselectedRows.push(rowArgs);
134
143
  }
135
- else {
144
+ else if (!this.nonSelectableRows.has(item.index)) {
136
145
  selectedRows.push(rowArgs);
137
146
  }
147
+ if (this.hasNonSelectable) {
148
+ const nonSelectableRows = this.currentSelection.filter(i => this.nonSelectableRows.has(i.index));
149
+ deselectedRows.push(...nonSelectableRows);
150
+ }
138
151
  return {
139
152
  deselectedRows: deselectedRows,
140
153
  selectedRows: selectedRows
@@ -167,7 +180,7 @@ export class SelectionService {
167
180
  const selectedRows = [];
168
181
  this.lastSelectionStartIndex = item.index;
169
182
  this.lastSelectionData = item.data;
170
- if (!this.isSelected(item.index)) {
183
+ if (!this.isSelected(item.index) && !this.nonSelectableRows.has(item.index)) {
171
184
  selectedRows.push({ dataItem: item.data, index: item.index });
172
185
  }
173
186
  this.currentSelection.forEach((row) => {
@@ -190,7 +203,7 @@ export class SelectionService {
190
203
  dataItem: item.value.data,
191
204
  index: item.value.index
192
205
  };
193
- if (this.isSelected(rowArgs.index)) {
206
+ if (this.isSelected(rowArgs.index) || this.nonSelectableRows.has(rowArgs.index)) {
194
207
  const ev = {
195
208
  ctrlKey: false,
196
209
  deselectedRows: [rowArgs],
@@ -216,12 +229,16 @@ export class SelectionService {
216
229
  if ((idx < start || idx > end) && this.isSelected(idx) && !ctrlKey) {
217
230
  deselectedRows.push(rowArgs);
218
231
  }
219
- if ((idx >= start && idx <= end) && !this.isSelected(idx)) {
232
+ if ((idx >= start && idx <= end) && !this.isSelected(idx) && !this.nonSelectableRows.has(idx)) {
220
233
  selectedRows.push(rowArgs);
221
234
  }
222
235
  }
223
236
  next = iterator.next();
224
237
  }
238
+ if (this.hasNonSelectable) {
239
+ const nonSelectableRows = this.currentSelection.filter(i => this.nonSelectableRows.has(i.index));
240
+ deselectedRows.push(...nonSelectableRows);
241
+ }
225
242
  return {
226
243
  deselectedRows: deselectedRows,
227
244
  selectedRows: selectedRows
@@ -237,11 +254,13 @@ export class SelectionService {
237
254
  if (next.value && next.value.type === "data") {
238
255
  const idx = next.value.index;
239
256
  const rowArgs = { dataItem: next.value.data, index: idx };
240
- if (this.isSelected(idx) && !selectAllChecked) {
241
- deselectedRows.push(rowArgs);
242
- }
243
- if (!this.isSelected(idx) && selectAllChecked) {
244
- selectedRows.push(rowArgs);
257
+ if (!this.nonSelectableRows.has(idx)) {
258
+ if (this.isSelected(idx) && !selectAllChecked) {
259
+ deselectedRows.push(rowArgs);
260
+ }
261
+ if (!this.isSelected(idx) && selectAllChecked) {
262
+ selectedRows.push(rowArgs);
263
+ }
245
264
  }
246
265
  }
247
266
  next = iterator.next();
@@ -249,6 +268,10 @@ export class SelectionService {
249
268
  if (!selectedRows.length && !deselectedRows.length) {
250
269
  return;
251
270
  }
271
+ if (this.hasNonSelectable) {
272
+ const nonSelectableRows = this.currentSelection.filter(i => this.nonSelectableRows.has(i.index));
273
+ deselectedRows.push(...nonSelectableRows);
274
+ }
252
275
  const ev = {
253
276
  ctrlKey: true,
254
277
  deselectedRows: deselectedRows,
@@ -274,7 +297,7 @@ export class SelectionService {
274
297
  if ((idx < start || idx > end) && this.isSelected(idx)) {
275
298
  deselectedRows.push(rowArgs);
276
299
  }
277
- if ((idx >= start && idx <= end) && !this.isSelected(idx)) {
300
+ if ((idx >= start && idx <= end) && !this.isSelected(idx) && !this.nonSelectableRows.has(idx)) {
278
301
  selectedRows.push(rowArgs);
279
302
  }
280
303
  }
@@ -284,6 +307,10 @@ export class SelectionService {
284
307
  if (this.options.cellAggregates) {
285
308
  cellAggregates = this.aggregateService.onSelectionChange({ selectedRows, deselectedRows });
286
309
  }
310
+ if (this.hasNonSelectable) {
311
+ const nonSelectableRows = this.currentSelection.filter(i => this.nonSelectableRows.has(i.index));
312
+ deselectedRows.push(...nonSelectableRows);
313
+ }
287
314
  return {
288
315
  deselectedRows: deselectedRows,
289
316
  selectedRows: selectedRows,
@@ -303,7 +330,8 @@ export class SelectionService {
303
330
  cellAggregates: false,
304
331
  checkboxOnly: false,
305
332
  enabled: true,
306
- mode: "multiple"
333
+ mode: "multiple",
334
+ metaKeyMultiSelect: true
307
335
  };
308
336
  if (!isPresent(this.settings)) {
309
337
  return defaultOptions;
@@ -313,7 +341,8 @@ export class SelectionService {
313
341
  cellAggregates: false,
314
342
  checkboxOnly: false,
315
343
  enabled: this.settings.selectable,
316
- mode: "multiple"
344
+ mode: "multiple",
345
+ metaKeyMultiSelect: true
317
346
  };
318
347
  }
319
348
  else {