@progress/kendo-angular-grid 19.1.2 → 19.2.0-develop.10

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.
Files changed (32) hide show
  1. package/aggregates/selection-aggregate.service.d.ts +1 -3
  2. package/column-menu/column-menu-item.directive.d.ts +1 -1
  3. package/common/provider.service.d.ts +2 -1
  4. package/data/data-mapping.service.d.ts +46 -0
  5. package/databinding.directive.d.ts +2 -1
  6. package/esm2022/aggregates/selection-aggregate.service.mjs +4 -8
  7. package/esm2022/column-menu/column-menu-item.directive.mjs +1 -1
  8. package/esm2022/common/provider.service.mjs +1 -1
  9. package/esm2022/data/data-mapping.service.mjs +125 -0
  10. package/esm2022/databinding.directive.mjs +12 -3
  11. package/esm2022/grid.component.mjs +41 -34
  12. package/esm2022/grouping/group-scroll-binding.directive.mjs +2 -2
  13. package/esm2022/package-metadata.mjs +2 -2
  14. package/esm2022/rendering/list.component.mjs +76 -57
  15. package/esm2022/rendering/table-body.component.mjs +37 -128
  16. package/esm2022/selection/selection-checkbox.directive.mjs +1 -1
  17. package/esm2022/selection/selection.service.mjs +23 -4
  18. package/esm2022/state-management/undo-redo.directive.mjs +74 -16
  19. package/esm2022/state-management/undo-redo.service.mjs +0 -1
  20. package/esm2022/state-management/undo-redo.stack.mjs +6 -0
  21. package/esm2022/utils.mjs +19 -0
  22. package/fesm2022/progress-kendo-angular-grid.mjs +934 -785
  23. package/grid.component.d.ts +12 -6
  24. package/package.json +20 -20
  25. package/rendering/list.component.d.ts +9 -6
  26. package/rendering/table-body.component.d.ts +9 -27
  27. package/schematics/ngAdd/index.js +4 -4
  28. package/selection/selection.service.d.ts +1 -1
  29. package/state-management/undo-redo.directive.d.ts +12 -2
  30. package/state-management/undo-redo.service.d.ts +0 -2
  31. package/state-management/undo-redo.stack.d.ts +2 -0
  32. package/utils.d.ts +5 -0
@@ -7,7 +7,6 @@ import { CellSelectionItem, SelectionEvent } from '../selection/types';
7
7
  import { RowArgs } from '../rendering/common/row-args';
8
8
  import { ContextService } from '../common/provider.service';
9
9
  import { ColumnInfoService } from '../common/column-info.service';
10
- import { LocalDataChangesService } from '../editing/local-data-changes.service';
11
10
  import * as i0 from "@angular/core";
12
11
  /**
13
12
  * @hidden
@@ -22,13 +21,12 @@ interface GroupedAggregates {
22
21
  */
23
22
  export declare class CellSelectionAggregateService {
24
23
  private ctx;
25
- private dataChanges;
26
24
  private columnInfoService;
27
25
  selectedItems: Array<CellSelectionItem | RowArgs>;
28
26
  groupedAggregates: GroupedAggregates;
29
27
  aggregates: SelectionAggregates;
30
28
  private sub;
31
- constructor(ctx: ContextService, dataChanges: LocalDataChangesService, columnInfoService: ColumnInfoService);
29
+ constructor(ctx: ContextService, columnInfoService: ColumnInfoService);
32
30
  ngOnDestroy(): void;
33
31
  isAggregateIncluded(aggregate: SelectionAggregate): boolean;
34
32
  init(): void;
@@ -6,7 +6,7 @@ import { ChangeDetectorRef, ElementRef, NgZone, Renderer2 } from '@angular/core'
6
6
  import { ContextService } from '../common/provider.service';
7
7
  import * as i0 from "@angular/core";
8
8
  /**
9
- * Represents a directive that manages keyboard navigation for a column menu item. [See example](slug:columnmenu_grid#customizing-the-content).
9
+ * Represents a directive that manages keyboard navigation for a column menu item ([see example](slug:columnmenu_grid#customizing-the-content)).
10
10
  *
11
11
  * @example
12
12
  * ```html
@@ -7,6 +7,7 @@ import { LocalizationService } from '@progress/kendo-angular-l10n';
7
7
  import type { GridComponent } from '../grid.component';
8
8
  import { GridToolbarNavigationService } from '../rendering/toolbar/toolbar-navigation.service';
9
9
  import type { GroupBindingDirective } from '../grouping/group-scroll-binding.directive';
10
+ import { DataBindingDirective } from '../databinding.directive';
10
11
  import * as i0 from "@angular/core";
11
12
  /**
12
13
  * @hidden
@@ -24,7 +25,7 @@ export declare class ContextService {
24
25
  topToolbarNavigation: GridToolbarNavigationService;
25
26
  bottomToolbarNavigation: GridToolbarNavigationService;
26
27
  navigable: boolean;
27
- groupBindingDirective: GroupBindingDirective;
28
+ dataBindingDirective: DataBindingDirective | GroupBindingDirective;
28
29
  constructor(renderer: Renderer2, localization: LocalizationService);
29
30
  static ɵfac: i0.ɵɵFactoryDeclaration<ContextService, never>;
30
31
  static ɵprov: i0.ɵɵInjectableDeclaration<ContextService>;
@@ -0,0 +1,46 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ import { QueryList } from '@angular/core';
6
+ import { RowspanService } from '../rendering/rowspan.service';
7
+ import { GroupsService } from '../grouping/groups.service';
8
+ import { GridItem } from './grid-item.interface';
9
+ import { DetailsService } from '../rendering/details/details.service';
10
+ import { ColumnBase } from '../columns/column-base';
11
+ import { DetailTemplateDirective } from '../rendering/details/detail-template.directive';
12
+ import * as i0 from "@angular/core";
13
+ /**
14
+ * @hidden
15
+ */
16
+ export declare class DataMappingService {
17
+ private rowspanService;
18
+ private groupsService;
19
+ private detailsService;
20
+ private recalculateRowspan;
21
+ private dataArray;
22
+ constructor(rowspanService: RowspanService, groupsService: GroupsService, detailsService: DetailsService);
23
+ private isGroup;
24
+ /**
25
+ * Maps the data to the Grid row items, applying rowspan and detail row logic.
26
+ */
27
+ dataMapper(data: any, nonLockedColumnsToRender: QueryList<ColumnBase>, lockedLeafColumns: QueryList<ColumnBase>, detailTemplate: DetailTemplateDirective, showFooter: boolean): Array<GridItem & {
28
+ showDataItem?: boolean;
29
+ showDetailRow?: boolean;
30
+ cells?: any[];
31
+ isExpanded?: boolean;
32
+ }>;
33
+ private isDataItem;
34
+ private isFooter;
35
+ private isFooterItemInExpandedGroup;
36
+ private isDataItemInExpandedGroup;
37
+ private isInExpandedGroup;
38
+ private isParentGroupExpanded;
39
+ private isExpanded;
40
+ private shouldRenderItem;
41
+ private shouldSkipCell;
42
+ private cachedDataArray;
43
+ private getRowspan;
44
+ static ɵfac: i0.ɵɵFactoryDeclaration<DataMappingService, never>;
45
+ static ɵprov: i0.ɵɵInjectableDeclaration<DataMappingService>;
46
+ }
@@ -10,6 +10,7 @@ import { GridDataResult } from './data/data.collection';
10
10
  import { LocalDataChangesService } from './editing/local-data-changes.service';
11
11
  import { RowReorderEvent } from './row-reordering/types';
12
12
  import { RowReorderService } from './row-reordering/row-reorder.service';
13
+ import { ContextService } from './common/provider.service';
13
14
  import * as i0 from "@angular/core";
14
15
  /**
15
16
  * A directive that handles in-memory data operations like [paging]({% slug paging_grid %}),
@@ -67,7 +68,7 @@ export declare class DataBindingDirective implements OnInit, OnDestroy, DoCheck,
67
68
  private stateChangeSubscription;
68
69
  private dataChangedSubscription;
69
70
  private rowReorderSubscription;
70
- constructor(grid: GridComponent, changeDetector?: ChangeDetectorRef, localDataChangesService?: LocalDataChangesService, rowReorderService?: RowReorderService);
71
+ constructor(grid: GridComponent, changeDetector?: ChangeDetectorRef, localDataChangesService?: LocalDataChangesService, rowReorderService?: RowReorderService, ctx?: ContextService);
71
72
  /**
72
73
  * @hidden
73
74
  */
@@ -5,19 +5,16 @@
5
5
  import { Injectable } from '@angular/core';
6
6
  import { ContextService } from '../common/provider.service';
7
7
  import { ColumnInfoService } from '../common/column-info.service';
8
- import { LocalDataChangesService } from '../editing/local-data-changes.service';
9
8
  import { recursiveFlatMap } from '../utils';
10
9
  import { Subscription } from 'rxjs';
11
10
  import * as i0 from "@angular/core";
12
11
  import * as i1 from "../common/provider.service";
13
- import * as i2 from "../editing/local-data-changes.service";
14
- import * as i3 from "../common/column-info.service";
12
+ import * as i2 from "../common/column-info.service";
15
13
  /**
16
14
  * @hidden
17
15
  */
18
16
  export class CellSelectionAggregateService {
19
17
  ctx;
20
- dataChanges;
21
18
  columnInfoService;
22
19
  selectedItems = [];
23
20
  groupedAggregates = { dates: [], numbers: [], booleans: [] };
@@ -33,9 +30,8 @@ export class CellSelectionAggregateService {
33
30
  latest: null
34
31
  };
35
32
  sub = new Subscription();
36
- constructor(ctx, dataChanges, columnInfoService) {
33
+ constructor(ctx, columnInfoService) {
37
34
  this.ctx = ctx;
38
- this.dataChanges = dataChanges;
39
35
  this.columnInfoService = columnInfoService;
40
36
  }
41
37
  ngOnDestroy() {
@@ -196,9 +192,9 @@ export class CellSelectionAggregateService {
196
192
  this.aggregates['isFalse'] = this.aggregates['isTrue'] = null;
197
193
  this.aggregates['earliest'] = this.aggregates['latest'] = null;
198
194
  }
199
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellSelectionAggregateService, deps: [{ token: i1.ContextService }, { token: i2.LocalDataChangesService }, { token: i3.ColumnInfoService }], target: i0.ɵɵFactoryTarget.Injectable });
195
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellSelectionAggregateService, deps: [{ token: i1.ContextService }, { token: i2.ColumnInfoService }], target: i0.ɵɵFactoryTarget.Injectable });
200
196
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellSelectionAggregateService });
201
197
  }
202
198
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellSelectionAggregateService, decorators: [{
203
199
  type: Injectable
204
- }], ctorParameters: function () { return [{ type: i1.ContextService }, { type: i2.LocalDataChangesService }, { type: i3.ColumnInfoService }]; } });
200
+ }], ctorParameters: function () { return [{ type: i1.ContextService }, { type: i2.ColumnInfoService }]; } });
@@ -12,7 +12,7 @@ import { ContextService } from '../common/provider.service';
12
12
  import * as i0 from "@angular/core";
13
13
  import * as i1 from "../common/provider.service";
14
14
  /**
15
- * Represents a directive that manages keyboard navigation for a column menu item. [See example](slug:columnmenu_grid#customizing-the-content).
15
+ * Represents a directive that manages keyboard navigation for a column menu item ([see example](slug:columnmenu_grid#customizing-the-content)).
16
16
  *
17
17
  * @example
18
18
  * ```html
@@ -23,7 +23,7 @@ export class ContextService {
23
23
  topToolbarNavigation;
24
24
  bottomToolbarNavigation;
25
25
  navigable;
26
- groupBindingDirective;
26
+ dataBindingDirective;
27
27
  constructor(renderer, localization) {
28
28
  this.renderer = renderer;
29
29
  this.localization = localization;
@@ -0,0 +1,125 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ import { Injectable } from '@angular/core';
6
+ import { RowspanService } from '../rendering/rowspan.service';
7
+ import { GroupsService } from '../grouping/groups.service';
8
+ import { DetailsService } from '../rendering/details/details.service';
9
+ import * as i0 from "@angular/core";
10
+ import * as i1 from "../rendering/rowspan.service";
11
+ import * as i2 from "../grouping/groups.service";
12
+ import * as i3 from "../rendering/details/details.service";
13
+ /**
14
+ * @hidden
15
+ */
16
+ export class DataMappingService {
17
+ rowspanService;
18
+ groupsService;
19
+ detailsService;
20
+ recalculateRowspan = true;
21
+ dataArray = null;
22
+ constructor(rowspanService, groupsService, detailsService) {
23
+ this.rowspanService = rowspanService;
24
+ this.groupsService = groupsService;
25
+ this.detailsService = detailsService;
26
+ }
27
+ isGroup(item) {
28
+ return item.type === 'group';
29
+ }
30
+ /**
31
+ * Maps the data to the Grid row items, applying rowspan and detail row logic.
32
+ */
33
+ dataMapper(data, nonLockedColumnsToRender, lockedLeafColumns, detailTemplate, showFooter) {
34
+ const result = [];
35
+ if (!data || !nonLockedColumnsToRender && !lockedLeafColumns) {
36
+ return [];
37
+ }
38
+ let dataIndex = 0;
39
+ for (const item of data) {
40
+ if (this.shouldRenderItem(item, detailTemplate, showFooter)) {
41
+ if (item.type === 'data') {
42
+ item.cells = [];
43
+ for (let i = 0; i < (lockedLeafColumns.length + nonLockedColumnsToRender.length); i++) {
44
+ const column = i < lockedLeafColumns.length ? lockedLeafColumns.get(i) : nonLockedColumnsToRender.get(i - lockedLeafColumns.length);
45
+ const cell = {};
46
+ if (column.cellRowspan && this.shouldSkipCell(dataIndex, i)) {
47
+ cell.skip = true;
48
+ }
49
+ else {
50
+ cell.rowspan = column.cellRowspan ? this.getRowspan({
51
+ index: dataIndex,
52
+ dataItem: item
53
+ }, column, i, data) : 1;
54
+ }
55
+ item.cells.push(cell);
56
+ }
57
+ }
58
+ result.push(item);
59
+ }
60
+ dataIndex++;
61
+ }
62
+ this.recalculateRowspan = true;
63
+ this.rowspanService.reset();
64
+ return result;
65
+ }
66
+ isDataItem(item) {
67
+ return !this.isGroup(item) && !this.isFooter(item);
68
+ }
69
+ isFooter(item) {
70
+ return item.type === 'footer';
71
+ }
72
+ isFooterItemInExpandedGroup(item) {
73
+ const footerItem = { data: item.data, index: item.groupIndex, parentGroup: item.group.parentGroup };
74
+ return this.isInExpandedGroup(footerItem);
75
+ }
76
+ isDataItemInExpandedGroup(item) {
77
+ const dataItem = { data: item.group.data, index: item.groupIndex, parentGroup: item.group.parentGroup };
78
+ return this.isInExpandedGroup(dataItem);
79
+ }
80
+ isInExpandedGroup(item) {
81
+ return this.groupsService.isInExpandedGroup(item);
82
+ }
83
+ isParentGroupExpanded(item) {
84
+ return this.groupsService.isInExpandedGroup(item.parentGroup);
85
+ }
86
+ isExpanded(viewItem) {
87
+ return this.detailsService.isExpanded(viewItem.index, viewItem.data);
88
+ }
89
+ shouldRenderItem(item, detailTemplate, showFooter) {
90
+ const renderGroupHeader = this.isGroup(item) && this.isParentGroupExpanded(item);
91
+ const renderDataItem = this.isDataItem(item) && (!item.group || this.isDataItemInExpandedGroup(item));
92
+ const renderDetailTemplate = renderDataItem && detailTemplate?.templateRef && detailTemplate.showIf(item.data, item.index) && this.isExpanded(item);
93
+ const isVisibleFooter = this.isFooter(item) && item.group && (this.isFooterItemInExpandedGroup(item) || (showFooter && this.isParentGroupExpanded(item.group)));
94
+ const renderFooter = isVisibleFooter && !item.data.hideFooter;
95
+ item.showDataItem = renderDataItem;
96
+ item.showDetailRow = renderDataItem && renderDetailTemplate;
97
+ item.isExpanded = this.isExpanded(item);
98
+ return renderGroupHeader || renderDataItem || renderDetailTemplate || renderFooter;
99
+ }
100
+ shouldSkipCell(rowIndex, colIndex) {
101
+ return this.rowspanService.shouldSkip(rowIndex, colIndex);
102
+ }
103
+ cachedDataArray(data) {
104
+ if (!this.dataArray) {
105
+ this.dataArray = data.map(item => item);
106
+ }
107
+ return this.dataArray;
108
+ }
109
+ getRowspan(row, column, colIndex, data) {
110
+ if (this.recalculateRowspan) {
111
+ this.dataArray = null;
112
+ this.recalculateRowspan = false;
113
+ }
114
+ const rowspan = column.cellRowspan(row, column, this.cachedDataArray(data));
115
+ if (rowspan > 1) {
116
+ this.rowspanService.addCells(row.index, colIndex, rowspan);
117
+ }
118
+ return rowspan;
119
+ }
120
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataMappingService, deps: [{ token: i1.RowspanService }, { token: i2.GroupsService }, { token: i3.DetailsService }], target: i0.ɵɵFactoryTarget.Injectable });
121
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataMappingService });
122
+ }
123
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataMappingService, decorators: [{
124
+ type: Injectable
125
+ }], ctorParameters: function () { return [{ type: i1.RowspanService }, { type: i2.GroupsService }, { type: i3.DetailsService }]; } });
@@ -8,10 +8,12 @@ import { GridComponent } from './grid.component';
8
8
  import { anyChanged, isPresent } from './utils';
9
9
  import { LocalDataChangesService } from './editing/local-data-changes.service';
10
10
  import { RowReorderService } from './row-reordering/row-reorder.service';
11
+ import { ContextService } from './common/provider.service';
11
12
  import * as i0 from "@angular/core";
12
13
  import * as i1 from "./grid.component";
13
14
  import * as i2 from "./editing/local-data-changes.service";
14
15
  import * as i3 from "./row-reordering/row-reorder.service";
16
+ import * as i4 from "./common/provider.service";
15
17
  /**
16
18
  * A directive that handles in-memory data operations like [paging]({% slug paging_grid %}),
17
19
  * [sorting]({% slug sorting_grid %}), and [grouping]({% slug grouping_grid %}).
@@ -92,7 +94,7 @@ export class DataBindingDirective {
92
94
  stateChangeSubscription;
93
95
  dataChangedSubscription;
94
96
  rowReorderSubscription;
95
- constructor(grid, changeDetector, localDataChangesService, rowReorderService) {
97
+ constructor(grid, changeDetector, localDataChangesService, rowReorderService, ctx) {
96
98
  this.grid = grid;
97
99
  this.changeDetector = changeDetector;
98
100
  this.localDataChangesService = localDataChangesService;
@@ -100,6 +102,7 @@ export class DataBindingDirective {
100
102
  if (localDataChangesService) {
101
103
  this.dataChangedSubscription = this.localDataChangesService.changes.subscribe(this.rebind.bind(this));
102
104
  }
105
+ ctx && (ctx.dataBindingDirective = this);
103
106
  }
104
107
  /**
105
108
  * @hidden
@@ -174,6 +177,12 @@ export class DataBindingDirective {
174
177
  }
175
178
  }
176
179
  process(state) {
180
+ if (this.grid.isVirtual && (!isPresent(state.take) || state.take === 0)) {
181
+ return {
182
+ data: [],
183
+ total: this.originalData?.length || 0
184
+ };
185
+ }
177
186
  return process(this.originalData, state);
178
187
  }
179
188
  applyState({ skip, take, sort, group, filter }) {
@@ -188,7 +197,7 @@ export class DataBindingDirective {
188
197
  this.grid.updateNavigationMetadata();
189
198
  this.dataChanged = false;
190
199
  }
191
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataBindingDirective, deps: [{ token: i1.GridComponent }, { token: i0.ChangeDetectorRef }, { token: i2.LocalDataChangesService }, { token: i3.RowReorderService }], target: i0.ɵɵFactoryTarget.Directive });
200
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataBindingDirective, deps: [{ token: i1.GridComponent }, { token: i0.ChangeDetectorRef }, { token: i2.LocalDataChangesService }, { token: i3.RowReorderService }, { token: i4.ContextService }], target: i0.ɵɵFactoryTarget.Directive });
192
201
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DataBindingDirective, isStandalone: true, selector: "[kendoGridBinding]", inputs: { skip: "skip", sort: "sort", filter: "filter", pageSize: "pageSize", group: "group", data: ["kendoGridBinding", "data"] }, exportAs: ["kendoGridBinding"], usesOnChanges: true, ngImport: i0 });
193
202
  }
194
203
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataBindingDirective, decorators: [{
@@ -198,7 +207,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
198
207
  exportAs: 'kendoGridBinding',
199
208
  standalone: true
200
209
  }]
201
- }], ctorParameters: function () { return [{ type: i1.GridComponent }, { type: i0.ChangeDetectorRef }, { type: i2.LocalDataChangesService }, { type: i3.RowReorderService }]; }, propDecorators: { skip: [{
210
+ }], ctorParameters: function () { return [{ type: i1.GridComponent }, { type: i0.ChangeDetectorRef }, { type: i2.LocalDataChangesService }, { type: i3.RowReorderService }, { type: i4.ContextService }]; }, propDecorators: { skip: [{
202
211
  type: Input
203
212
  }], sort: [{
204
213
  type: Input