@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
@@ -526,6 +526,24 @@ const isMultipleRangesEnabled = (selectableSettings) => {
526
526
  typeof selectableSettings === 'object' &&
527
527
  selectableSettings.selectable.multipleRanges;
528
528
  };
529
+ /**
530
+ * @hidden
531
+ * Calculates the height of a table row by inserting a temporary row into the table body when the `rowHeight` option is not set.
532
+ */
533
+ const calcRowHeight = (tableBody) => {
534
+ let result = 0;
535
+ if (!isDocumentAvailable()) {
536
+ return result;
537
+ }
538
+ if (tableBody) {
539
+ const row = tableBody.insertRow(0);
540
+ const cell = row.insertCell(0);
541
+ cell.textContent = ' ';
542
+ result = row.getBoundingClientRect().height;
543
+ tableBody.deleteRow(0);
544
+ }
545
+ return result;
546
+ };
529
547
 
530
548
  /**
531
549
  * @hidden
@@ -850,7 +868,7 @@ class ContextService {
850
868
  topToolbarNavigation;
851
869
  bottomToolbarNavigation;
852
870
  navigable;
853
- groupBindingDirective;
871
+ dataBindingDirective;
854
872
  constructor(renderer, localization) {
855
873
  this.renderer = renderer;
856
874
  this.localization = localization;
@@ -14121,7 +14139,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
14121
14139
  }] } });
14122
14140
 
14123
14141
  /**
14124
- * Represents a directive that manages keyboard navigation for a column menu item. [See example](slug:columnmenu_grid#customizing-the-content).
14142
+ * Represents a directive that manages keyboard navigation for a column menu item ([see example](slug:columnmenu_grid#customizing-the-content)).
14125
14143
  *
14126
14144
  * @example
14127
14145
  * ```html
@@ -16657,7 +16675,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
16657
16675
  */
16658
16676
  class CellSelectionAggregateService {
16659
16677
  ctx;
16660
- dataChanges;
16661
16678
  columnInfoService;
16662
16679
  selectedItems = [];
16663
16680
  groupedAggregates = { dates: [], numbers: [], booleans: [] };
@@ -16673,9 +16690,8 @@ class CellSelectionAggregateService {
16673
16690
  latest: null
16674
16691
  };
16675
16692
  sub = new Subscription();
16676
- constructor(ctx, dataChanges, columnInfoService) {
16693
+ constructor(ctx, columnInfoService) {
16677
16694
  this.ctx = ctx;
16678
- this.dataChanges = dataChanges;
16679
16695
  this.columnInfoService = columnInfoService;
16680
16696
  }
16681
16697
  ngOnDestroy() {
@@ -16836,12 +16852,12 @@ class CellSelectionAggregateService {
16836
16852
  this.aggregates['isFalse'] = this.aggregates['isTrue'] = null;
16837
16853
  this.aggregates['earliest'] = this.aggregates['latest'] = null;
16838
16854
  }
16839
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellSelectionAggregateService, deps: [{ token: ContextService }, { token: LocalDataChangesService }, { token: ColumnInfoService }], target: i0.ɵɵFactoryTarget.Injectable });
16855
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellSelectionAggregateService, deps: [{ token: ContextService }, { token: ColumnInfoService }], target: i0.ɵɵFactoryTarget.Injectable });
16840
16856
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellSelectionAggregateService });
16841
16857
  }
16842
16858
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellSelectionAggregateService, decorators: [{
16843
16859
  type: Injectable
16844
- }], ctorParameters: function () { return [{ type: ContextService }, { type: LocalDataChangesService }, { type: ColumnInfoService }]; } });
16860
+ }], ctorParameters: function () { return [{ type: ContextService }, { type: ColumnInfoService }]; } });
16845
16861
 
16846
16862
  /**
16847
16863
  * @hidden
@@ -16970,6 +16986,8 @@ class SelectionService {
16970
16986
  if (ev.shiftKey) {
16971
16987
  ev.rangeStartRow = { dataItem: this.lastSelectionData, index: this.lastSelectionStartIndex };
16972
16988
  ev.rangeEndRow = { dataItem: item.data, index: item.index };
16989
+ this.lastSelectionData = item.data;
16990
+ this.lastSelectionStartIndex = item.index;
16973
16991
  }
16974
16992
  this.syncCurrentSelection(ev);
16975
16993
  this.changes.emit(ev);
@@ -17058,13 +17076,14 @@ class SelectionService {
17058
17076
  item = iterator.next();
17059
17077
  }
17060
17078
  }
17061
- addAllTo(item, ctrlKey, preserveSelection = false) {
17079
+ addAllTo(item, ctrlKey, preserveSelection = false, shiftKey = false) {
17062
17080
  const selectedRows = [];
17063
17081
  const deselectedRows = [];
17064
17082
  const start = Math.min(this.lastSelectionStartIndex, item.index);
17065
17083
  const end = Math.max(this.lastSelectionStartIndex, item.index);
17066
17084
  const iterator = this.getIterator();
17067
17085
  let next = iterator.next();
17086
+ let selectedItem;
17068
17087
  while (!next.done) {
17069
17088
  if (next.value && next.value.type === "data") {
17070
17089
  const idx = next.value.index;
@@ -17075,6 +17094,9 @@ class SelectionService {
17075
17094
  if ((idx >= start && idx <= end) && !this.isSelected(idx) && !this.nonSelectableRows.has(idx)) {
17076
17095
  selectedRows.push(rowArgs);
17077
17096
  }
17097
+ if (idx === item.index && !this.nonSelectableRows.has(idx)) {
17098
+ selectedItem = rowArgs;
17099
+ }
17078
17100
  }
17079
17101
  next = iterator.next();
17080
17102
  }
@@ -17082,10 +17104,23 @@ class SelectionService {
17082
17104
  const nonSelectableRows = this.currentSelection.filter(i => this.nonSelectableRows.has(i.index));
17083
17105
  deselectedRows.push(...nonSelectableRows);
17084
17106
  }
17085
- return {
17086
- deselectedRows: deselectedRows,
17087
- selectedRows: selectedRows
17107
+ const selectionEvent = {
17108
+ deselectedRows,
17109
+ selectedRows
17088
17110
  };
17111
+ if (shiftKey && selectedItem) {
17112
+ selectionEvent.rangeStartRow = {
17113
+ dataItem: this.lastSelectionData,
17114
+ index: this.lastSelectionStartIndex
17115
+ };
17116
+ selectionEvent.rangeEndRow = {
17117
+ dataItem: selectedItem.dataItem,
17118
+ index: selectedItem.index
17119
+ };
17120
+ this.lastSelectionData = selectedItem.dataItem;
17121
+ this.lastSelectionStartIndex = selectedItem.index;
17122
+ }
17123
+ return selectionEvent;
17089
17124
  }
17090
17125
  updateAll(selectAllChecked) {
17091
17126
  this.selectAllChecked = selectAllChecked;
@@ -19074,7 +19109,7 @@ class SelectionCheckboxDirective {
19074
19109
  const ctrlKey = event.ctrlKey || event.metaKey;
19075
19110
  if (event.shiftKey && this.selectionService.options.mode === 'multiple') {
19076
19111
  const item = { index: this.itemIndex };
19077
- ev = this.selectionService.addAllTo(item, ctrlKey);
19112
+ ev = this.selectionService.addAllTo(item, ctrlKey, false, event.shiftKey);
19078
19113
  }
19079
19114
  else {
19080
19115
  ev = this.selectionService.toggleByIndex(this.itemIndex);
@@ -19573,27 +19608,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
19573
19608
  type: Input
19574
19609
  }] } });
19575
19610
 
19576
- /**
19577
- * @hidden
19578
- */
19579
- class RowspanService {
19580
- skipCells = [];
19581
- addCells(rowIndex, colIndex, rowspan) {
19582
- for (let i = 1; i < rowspan; i++) {
19583
- if (!this.skipCells.some(this.cellExists(rowIndex + i, colIndex))) {
19584
- this.skipCells.push({ rowIndex: rowIndex + i, colIndex });
19585
- }
19586
- }
19587
- }
19588
- reset() {
19589
- this.skipCells = [];
19590
- }
19591
- shouldSkip(rowIndex, colIndex) {
19592
- return !!this.skipCells.find(this.cellExists(rowIndex, colIndex));
19593
- }
19594
- cellExists = (rowIndex, colIndex) => cell => cell.rowIndex === rowIndex && cell.colIndex === colIndex;
19595
- }
19596
-
19597
19611
  const columnCellIndex = (cell, cells) => {
19598
19612
  let cellIndex = 0;
19599
19613
  for (let idx = 0; idx < cells.length; idx++) {
@@ -19622,13 +19636,12 @@ class TableBodyComponent {
19622
19636
  cellSelectionService;
19623
19637
  columnInfoService;
19624
19638
  navigationService;
19625
- rowspanService;
19626
19639
  columns = [];
19627
19640
  allColumns;
19628
19641
  groups = [];
19629
19642
  detailTemplate;
19630
19643
  noRecordsTemplate;
19631
- data;
19644
+ rowsToRender;
19632
19645
  skip = 0;
19633
19646
  selectable;
19634
19647
  filterable;
@@ -19638,7 +19651,6 @@ class TableBodyComponent {
19638
19651
  isVirtual;
19639
19652
  cellLoadingTemplate;
19640
19653
  skipGroupDecoration = false;
19641
- showGroupFooters = false;
19642
19654
  lockedColumnsCount = 0;
19643
19655
  totalColumnsCount = 0;
19644
19656
  virtualColumns;
@@ -19656,9 +19668,7 @@ class TableBodyComponent {
19656
19668
  clickTimeout;
19657
19669
  minusIcon = minusIcon;
19658
19670
  plusIcon = plusIcon;
19659
- dataArray;
19660
- rerender = false;
19661
- constructor(detailsService, groupsService, changeNotification, editService, ctx, ngZone, renderer, element, domEvents, selectionService, cellSelectionService, columnInfoService, navigationService, rowspanService) {
19671
+ constructor(detailsService, groupsService, changeNotification, editService, ctx, ngZone, renderer, element, domEvents, selectionService, cellSelectionService, columnInfoService, navigationService) {
19662
19672
  this.detailsService = detailsService;
19663
19673
  this.groupsService = groupsService;
19664
19674
  this.changeNotification = changeNotification;
@@ -19672,7 +19682,6 @@ class TableBodyComponent {
19672
19682
  this.cellSelectionService = cellSelectionService;
19673
19683
  this.columnInfoService = columnInfoService;
19674
19684
  this.navigationService = navigationService;
19675
- this.rowspanService = rowspanService;
19676
19685
  this.noRecordsText = this.ctx.localization.get('noRecords');
19677
19686
  this.cellKeydownSubscription = this.navigationService.cellKeydown.subscribe((args) => this.cellKeydownHandler(args));
19678
19687
  this.trackByWrapper = this.trackByWrapper.bind(this);
@@ -19681,12 +19690,6 @@ class TableBodyComponent {
19681
19690
  get newDataItem() {
19682
19691
  return this.editService.newDataItem;
19683
19692
  }
19684
- get cachedDataArray() {
19685
- if (!this.dataArray) {
19686
- this.dataArray = this.data.map(item => item);
19687
- }
19688
- return this.dataArray;
19689
- }
19690
19693
  // Number of unlocked columns in the next table, if any
19691
19694
  unlockedColumnsCount(item) {
19692
19695
  const allColumns = this.allColumns || this.columns;
@@ -19698,25 +19701,7 @@ class TableBodyComponent {
19698
19701
  });
19699
19702
  const contentColumnsCount = this.totalColumnsCount - this.lockedColumnsCount - allColumnsCount;
19700
19703
  const headerFooterColumnsCount = this.totalColumnsCount - this.lockedColumnsCount - allColumns.length;
19701
- return item && this.isDataItem(item) ? contentColumnsCount : headerFooterColumnsCount;
19702
- }
19703
- shouldSkipCell(rowIndex, colIndex) {
19704
- return this.rowspanService.shouldSkip(rowIndex, colIndex);
19705
- }
19706
- getRowspan(row, column, colIndex) {
19707
- if (this.rerender) {
19708
- this.dataArray = null;
19709
- this.rerender = false;
19710
- }
19711
- const rowspan = column.cellRowspan(row, column, this.cachedDataArray);
19712
- if (rowspan > 1) {
19713
- this.rowspanService.addCells(row.index, colIndex, rowspan);
19714
- }
19715
- this.ngZone.runOutsideAngular(() => setTimeout(() => {
19716
- this.rerender = true;
19717
- this.rowspanService.reset();
19718
- }));
19719
- return rowspan;
19704
+ return item && item.type === 'data' ? contentColumnsCount : headerFooterColumnsCount;
19720
19705
  }
19721
19706
  isAriaSelected(item, column) {
19722
19707
  return this.cellSelectionService.isCellSelected(item, column) ||
@@ -19726,44 +19711,16 @@ class TableBodyComponent {
19726
19711
  this.detailsService.toggleRow(index, dataItem);
19727
19712
  return false;
19728
19713
  }
19729
- isExpanded(viewItem) {
19730
- return this.detailsService.isExpanded(viewItem.index, viewItem.data);
19731
- }
19732
19714
  detailButtonIconName(viewItem) {
19733
- const expanded = this.isExpanded(viewItem);
19734
- return expanded ? 'minus' : 'plus';
19715
+ return viewItem.isExpanded ? 'minus' : 'plus';
19735
19716
  }
19736
19717
  detailButtonSvgIcon(viewItem) {
19737
- const expanded = this.isExpanded(viewItem);
19738
- return expanded ? this.minusIcon : this.plusIcon;
19718
+ return viewItem.isExpanded ? this.minusIcon : this.plusIcon;
19739
19719
  }
19740
19720
  detailButtonTitle(viewItem) {
19741
- const messageKey = this.isExpanded(viewItem) ? 'detailCollapse' : 'detailExpand';
19721
+ const messageKey = viewItem.isExpanded ? 'detailCollapse' : 'detailExpand';
19742
19722
  return this.ctx.localization.get(messageKey);
19743
19723
  }
19744
- isGroup(item) {
19745
- return item.type === 'group';
19746
- }
19747
- isDataItem(item) {
19748
- return !this.isGroup(item) && !this.isFooter(item);
19749
- }
19750
- isFooter(item) {
19751
- return item.type === 'footer';
19752
- }
19753
- isFooterItemInExpandedGroup(item) {
19754
- const footerItem = { data: item.data, index: item.groupIndex, parentGroup: item.group.parentGroup };
19755
- return this.isInExpandedGroup(footerItem);
19756
- }
19757
- isDataItemInExpandedGroup(item) {
19758
- const dataItem = { data: item.group.data, index: item.groupIndex, parentGroup: item.group.parentGroup };
19759
- return this.isInExpandedGroup(dataItem);
19760
- }
19761
- isInExpandedGroup(item) {
19762
- return this.groupsService.isInExpandedGroup(item);
19763
- }
19764
- isParentGroupExpanded(item) {
19765
- return this.groupsService.isInExpandedGroup(item.parentGroup);
19766
- }
19767
19724
  isOdd(item) {
19768
19725
  return item.index % 2 !== 0;
19769
19726
  }
@@ -19986,7 +19943,7 @@ class TableBodyComponent {
19986
19943
  const columnIndex = this.lockedColumnsCount + index;
19987
19944
  let rowIndex = row.getAttribute('data-kendo-grid-item-index');
19988
19945
  rowIndex = rowIndex ? parseInt(rowIndex, 10) : -1;
19989
- const dataItem = rowIndex === -1 ? this.editService.newDataItem : this.data.at(rowIndex - this.skip);
19946
+ const dataItem = rowIndex === -1 ? this.editService.newDataItem : this.rowsToRender.find(item => +item.index === rowIndex && item.type === 'data')?.data;
19990
19947
  const isEditedColumn = this.editService.isEditedColumn(rowIndex, column);
19991
19948
  const isEditedRow = this.editService.isEdited(rowIndex);
19992
19949
  const type = eventArg.type === 'keydown' ? 'click' : eventArg.type;
@@ -20031,8 +19988,8 @@ class TableBodyComponent {
20031
19988
  });
20032
19989
  }
20033
19990
  }
20034
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableBodyComponent, deps: [{ token: DetailsService }, { token: GroupsService }, { token: ChangeNotificationService }, { token: EditService }, { token: ContextService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: DomEventsService }, { token: SelectionService }, { token: CellSelectionService }, { token: ColumnInfoService }, { token: NavigationService }, { token: RowspanService }], target: i0.ɵɵFactoryTarget.Component });
20035
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TableBodyComponent, isStandalone: true, selector: "[kendoGridTableBody]", inputs: { columns: "columns", allColumns: "allColumns", groups: "groups", detailTemplate: "detailTemplate", noRecordsTemplate: "noRecordsTemplate", data: "data", skip: "skip", selectable: "selectable", filterable: "filterable", noRecordsText: "noRecordsText", isLocked: "isLocked", isLoading: "isLoading", isVirtual: "isVirtual", cellLoadingTemplate: "cellLoadingTemplate", skipGroupDecoration: "skipGroupDecoration", showGroupFooters: "showGroupFooters", lockedColumnsCount: "lockedColumnsCount", totalColumnsCount: "totalColumnsCount", virtualColumns: "virtualColumns", trackBy: "trackBy", rowSticky: "rowSticky", totalColumns: "totalColumns", rowClass: "rowClass" }, host: { properties: { "class.k-table-tbody": "this.hostClass" } }, usesOnChanges: true, ngImport: i0, template: `
19991
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TableBodyComponent, deps: [{ token: DetailsService }, { token: GroupsService }, { token: ChangeNotificationService }, { token: EditService }, { token: ContextService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: DomEventsService }, { token: SelectionService }, { token: CellSelectionService }, { token: ColumnInfoService }, { token: NavigationService }], target: i0.ɵɵFactoryTarget.Component });
19992
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TableBodyComponent, isStandalone: true, selector: "[kendoGridTableBody]", inputs: { columns: "columns", allColumns: "allColumns", groups: "groups", detailTemplate: "detailTemplate", noRecordsTemplate: "noRecordsTemplate", rowsToRender: "rowsToRender", skip: "skip", selectable: "selectable", filterable: "filterable", noRecordsText: "noRecordsText", isLocked: "isLocked", isLoading: "isLoading", isVirtual: "isVirtual", cellLoadingTemplate: "cellLoadingTemplate", skipGroupDecoration: "skipGroupDecoration", lockedColumnsCount: "lockedColumnsCount", totalColumnsCount: "totalColumnsCount", virtualColumns: "virtualColumns", trackBy: "trackBy", rowSticky: "rowSticky", totalColumns: "totalColumns", rowClass: "rowClass" }, host: { properties: { "class.k-table-tbody": "this.hostClass" } }, usesOnChanges: true, ngImport: i0, template: `
20036
19993
  <ng-container *ngIf="editService.hasNewItem">
20037
19994
  <tr class="k-grid-add-row k-grid-edit-row k-master-row"
20038
19995
  kendoGridLogicalRow
@@ -20073,7 +20030,7 @@ class TableBodyComponent {
20073
20030
  </td>
20074
20031
  </tr>
20075
20032
  </ng-container>
20076
- <tr *ngIf="data?.length === 0 || data === null" class="k-grid-norecords" role="row">
20033
+ <tr *ngIf="!rowsToRender?.length" class="k-grid-norecords" role="row">
20077
20034
  <td [attr.colspan]="colSpan" class="k-table-td">
20078
20035
  <ng-template
20079
20036
  *ngIf="noRecordsTemplate?.templateRef"
@@ -20086,8 +20043,8 @@ class TableBodyComponent {
20086
20043
  </ng-container>
20087
20044
  </td>
20088
20045
  </tr>
20089
- <ng-container *ngFor="let item of data; trackBy: trackByWrapper; let rowIndex = index;">
20090
- <tr *ngIf="isGroup(item) && isParentGroupExpanded($any(item)) && showGroupHeader(item)"
20046
+ <ng-container *ngFor="let item of rowsToRender; trackBy: trackByWrapper; let rowIndex = index;">
20047
+ <tr *ngIf="item.type === 'group'"
20091
20048
  kendoGridGroupHeader
20092
20049
  [columns]="columns"
20093
20050
  [groups]="groups"
@@ -20105,8 +20062,7 @@ class TableBodyComponent {
20105
20062
  [logicalCellsCount]="columns.length"
20106
20063
  [logicalSlaveCellsCount]="groupHeaderSlaveCellsCount">
20107
20064
  </tr>
20108
- <tr
20109
- *ngIf="isDataItem(item) && (!$any(item).group || isDataItemInExpandedGroup($any(item)))"
20065
+ <tr *ngIf="item.showDataItem"
20110
20066
  kendoGridLogicalRow
20111
20067
  [dataRowIndex]="$any(item).index"
20112
20068
  [dataItem]="item.data"
@@ -20119,7 +20075,7 @@ class TableBodyComponent {
20119
20075
  [class.k-grid-row-sticky]="rowSticky ? rowSticky({ dataItem: item.data, index: $any(item).index }) : false"
20120
20076
  [ngClass]="rowClass({ dataItem: item.data, index: $any(item).index })"
20121
20077
  [class.k-master-row]="true"
20122
- [class.k-expanded]="isDataItem(item) && isExpanded(item)"
20078
+ [class.k-expanded]="item.isExpanded"
20123
20079
  [class.k-grid-edit-row]="isEditingRow($any(item).index)"
20124
20080
  [attr.aria-selected]="lockedColumnsCount < 1 ? isSelectable({ dataItem: item.data, index: $any(item).index }) && isRowSelected(item) : undefined"
20125
20081
  [attr.data-kendo-grid-item-index]="$any(item).index"
@@ -20148,7 +20104,7 @@ class TableBodyComponent {
20148
20104
  </a>
20149
20105
  </td>
20150
20106
  <ng-container *ngFor="let column of columns; let columnIndex = index; trackBy: trackByColumns;">
20151
- <td *ngIf="column.cellRowspan ? !shouldSkipCell(rowIndex, lockedColumnsCount + columnIndex) : true"
20107
+ <td *ngIf="!item.cells?.[lockedColumnsCount + columnIndex]?.skip"
20152
20108
  kendoGridCell
20153
20109
  [rowIndex]="$any(item).index"
20154
20110
  [columnIndex]="lockedColumnsCount + columnIndex"
@@ -20165,10 +20121,7 @@ class TableBodyComponent {
20165
20121
  [dataItem]="item.data"
20166
20122
  [colIndex]="columnIndex"
20167
20123
  [colSpan]="column.colspan"
20168
- [rowSpan]="column.cellRowspan ? getRowspan({
20169
- index: rowIndex,
20170
- dataItem: item
20171
- }, column, lockedColumnsCount + columnIndex) : 1"
20124
+ [rowSpan]="item.cells[lockedColumnsCount + columnIndex]?.rowspan"
20172
20125
  [attr.role]="column.tableCellsRole"
20173
20126
  class="k-table-td"
20174
20127
  [attr.aria-selected]="lockedColumnsCount < 1 && isSelectable({ dataItem: item.data, index: $any(item).index }) ? isAriaSelected(item, column) : undefined"
@@ -20178,24 +20131,18 @@ class TableBodyComponent {
20178
20131
  [class.k-grid-edit-cell]="isEditingCell($any(item).index, column)"
20179
20132
  [ngStyle]="column.sticky ? addStickyColumnStyles(column) : column.style"
20180
20133
  [attr.colspan]="column.colspan"
20181
- [class.k-selected]="isSelectable && cellSelectionService.isCellSelected(item, column)"
20182
- >
20134
+ [class.k-selected]="isSelectable && cellSelectionService.isCellSelected(item, column)">
20183
20135
  </td>
20184
20136
  </ng-container>
20185
20137
  </tr>
20186
- <tr *ngIf="isDataItem(item) &&
20187
- (!$any(item).group || isDataItemInExpandedGroup($any(item))) &&
20188
- detailTemplate?.templateRef &&
20189
- detailTemplate.showIf(item.data, $any(item).index) &&
20190
- isExpanded(item)"
20138
+ <tr *ngIf="item.showDetailRow"
20191
20139
  class="k-detail-row"
20192
20140
  kendoGridLogicalRow
20193
20141
  [dataRowIndex]="$any(item).index"
20194
20142
  [dataItem]="item.data"
20195
20143
  [logicalRowIndex]="logicalRowIndex(rowIndex) + 1"
20196
20144
  [logicalSlaveRow]="false"
20197
- [logicalCellsCount]="1"
20198
- >
20145
+ [logicalCellsCount]="1">
20199
20146
  <td class="k-group-cell k-table-td k-table-group-td" *ngFor="let g of groups"></td>
20200
20147
  <td class="k-hierarchy-cell k-table-td"></td>
20201
20148
  <td class="k-detail-cell k-table-td"
@@ -20207,8 +20154,7 @@ class TableBodyComponent {
20207
20154
  [dataItem]="item.data"
20208
20155
  [colIndex]="0"
20209
20156
  [colSpan]="allColumnsSpan + 1"
20210
- role="gridcell" aria-selected="false"
20211
- >
20157
+ role="gridcell" aria-selected="false">
20212
20158
  <ng-template
20213
20159
  [ngTemplateOutlet]="detailTemplate.templateRef"
20214
20160
  [ngTemplateOutletContext]="{
@@ -20219,10 +20165,7 @@ class TableBodyComponent {
20219
20165
  </ng-template>
20220
20166
  </td>
20221
20167
  </tr>
20222
- <tr *ngIf="isFooter(item) &&
20223
- $any(item).group &&
20224
- (isFooterItemInExpandedGroup($any(item)) || (showGroupFooters && isParentGroupExpanded($any(item).group))) &&
20225
- !$any(item.data).hideFooter"
20168
+ <tr *ngIf="item.type === 'footer'"
20226
20169
  class="k-group-footer"
20227
20170
  kendoGridLogicalRow
20228
20171
  [logicalRowIndex]="logicalRowIndex(rowIndex)"
@@ -20238,8 +20181,7 @@ class TableBodyComponent {
20238
20181
  kendoGridLogicalCell
20239
20182
  [logicalRowIndex]="logicalRowIndex(rowIndex)"
20240
20183
  [logicalColIndex]="0"
20241
- aria-selected="false"
20242
- >
20184
+ aria-selected="false">
20243
20185
  </td>
20244
20186
  <td kendoGridLogicalCell
20245
20187
  [logicalRowIndex]="logicalRowIndex(rowIndex)"
@@ -20308,7 +20250,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20308
20250
  </td>
20309
20251
  </tr>
20310
20252
  </ng-container>
20311
- <tr *ngIf="data?.length === 0 || data === null" class="k-grid-norecords" role="row">
20253
+ <tr *ngIf="!rowsToRender?.length" class="k-grid-norecords" role="row">
20312
20254
  <td [attr.colspan]="colSpan" class="k-table-td">
20313
20255
  <ng-template
20314
20256
  *ngIf="noRecordsTemplate?.templateRef"
@@ -20321,8 +20263,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20321
20263
  </ng-container>
20322
20264
  </td>
20323
20265
  </tr>
20324
- <ng-container *ngFor="let item of data; trackBy: trackByWrapper; let rowIndex = index;">
20325
- <tr *ngIf="isGroup(item) && isParentGroupExpanded($any(item)) && showGroupHeader(item)"
20266
+ <ng-container *ngFor="let item of rowsToRender; trackBy: trackByWrapper; let rowIndex = index;">
20267
+ <tr *ngIf="item.type === 'group'"
20326
20268
  kendoGridGroupHeader
20327
20269
  [columns]="columns"
20328
20270
  [groups]="groups"
@@ -20340,8 +20282,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20340
20282
  [logicalCellsCount]="columns.length"
20341
20283
  [logicalSlaveCellsCount]="groupHeaderSlaveCellsCount">
20342
20284
  </tr>
20343
- <tr
20344
- *ngIf="isDataItem(item) && (!$any(item).group || isDataItemInExpandedGroup($any(item)))"
20285
+ <tr *ngIf="item.showDataItem"
20345
20286
  kendoGridLogicalRow
20346
20287
  [dataRowIndex]="$any(item).index"
20347
20288
  [dataItem]="item.data"
@@ -20354,7 +20295,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20354
20295
  [class.k-grid-row-sticky]="rowSticky ? rowSticky({ dataItem: item.data, index: $any(item).index }) : false"
20355
20296
  [ngClass]="rowClass({ dataItem: item.data, index: $any(item).index })"
20356
20297
  [class.k-master-row]="true"
20357
- [class.k-expanded]="isDataItem(item) && isExpanded(item)"
20298
+ [class.k-expanded]="item.isExpanded"
20358
20299
  [class.k-grid-edit-row]="isEditingRow($any(item).index)"
20359
20300
  [attr.aria-selected]="lockedColumnsCount < 1 ? isSelectable({ dataItem: item.data, index: $any(item).index }) && isRowSelected(item) : undefined"
20360
20301
  [attr.data-kendo-grid-item-index]="$any(item).index"
@@ -20383,7 +20324,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20383
20324
  </a>
20384
20325
  </td>
20385
20326
  <ng-container *ngFor="let column of columns; let columnIndex = index; trackBy: trackByColumns;">
20386
- <td *ngIf="column.cellRowspan ? !shouldSkipCell(rowIndex, lockedColumnsCount + columnIndex) : true"
20327
+ <td *ngIf="!item.cells?.[lockedColumnsCount + columnIndex]?.skip"
20387
20328
  kendoGridCell
20388
20329
  [rowIndex]="$any(item).index"
20389
20330
  [columnIndex]="lockedColumnsCount + columnIndex"
@@ -20400,10 +20341,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20400
20341
  [dataItem]="item.data"
20401
20342
  [colIndex]="columnIndex"
20402
20343
  [colSpan]="column.colspan"
20403
- [rowSpan]="column.cellRowspan ? getRowspan({
20404
- index: rowIndex,
20405
- dataItem: item
20406
- }, column, lockedColumnsCount + columnIndex) : 1"
20344
+ [rowSpan]="item.cells[lockedColumnsCount + columnIndex]?.rowspan"
20407
20345
  [attr.role]="column.tableCellsRole"
20408
20346
  class="k-table-td"
20409
20347
  [attr.aria-selected]="lockedColumnsCount < 1 && isSelectable({ dataItem: item.data, index: $any(item).index }) ? isAriaSelected(item, column) : undefined"
@@ -20413,24 +20351,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20413
20351
  [class.k-grid-edit-cell]="isEditingCell($any(item).index, column)"
20414
20352
  [ngStyle]="column.sticky ? addStickyColumnStyles(column) : column.style"
20415
20353
  [attr.colspan]="column.colspan"
20416
- [class.k-selected]="isSelectable && cellSelectionService.isCellSelected(item, column)"
20417
- >
20354
+ [class.k-selected]="isSelectable && cellSelectionService.isCellSelected(item, column)">
20418
20355
  </td>
20419
20356
  </ng-container>
20420
20357
  </tr>
20421
- <tr *ngIf="isDataItem(item) &&
20422
- (!$any(item).group || isDataItemInExpandedGroup($any(item))) &&
20423
- detailTemplate?.templateRef &&
20424
- detailTemplate.showIf(item.data, $any(item).index) &&
20425
- isExpanded(item)"
20358
+ <tr *ngIf="item.showDetailRow"
20426
20359
  class="k-detail-row"
20427
20360
  kendoGridLogicalRow
20428
20361
  [dataRowIndex]="$any(item).index"
20429
20362
  [dataItem]="item.data"
20430
20363
  [logicalRowIndex]="logicalRowIndex(rowIndex) + 1"
20431
20364
  [logicalSlaveRow]="false"
20432
- [logicalCellsCount]="1"
20433
- >
20365
+ [logicalCellsCount]="1">
20434
20366
  <td class="k-group-cell k-table-td k-table-group-td" *ngFor="let g of groups"></td>
20435
20367
  <td class="k-hierarchy-cell k-table-td"></td>
20436
20368
  <td class="k-detail-cell k-table-td"
@@ -20442,8 +20374,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20442
20374
  [dataItem]="item.data"
20443
20375
  [colIndex]="0"
20444
20376
  [colSpan]="allColumnsSpan + 1"
20445
- role="gridcell" aria-selected="false"
20446
- >
20377
+ role="gridcell" aria-selected="false">
20447
20378
  <ng-template
20448
20379
  [ngTemplateOutlet]="detailTemplate.templateRef"
20449
20380
  [ngTemplateOutletContext]="{
@@ -20454,10 +20385,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20454
20385
  </ng-template>
20455
20386
  </td>
20456
20387
  </tr>
20457
- <tr *ngIf="isFooter(item) &&
20458
- $any(item).group &&
20459
- (isFooterItemInExpandedGroup($any(item)) || (showGroupFooters && isParentGroupExpanded($any(item).group))) &&
20460
- !$any(item.data).hideFooter"
20388
+ <tr *ngIf="item.type === 'footer'"
20461
20389
  class="k-group-footer"
20462
20390
  kendoGridLogicalRow
20463
20391
  [logicalRowIndex]="logicalRowIndex(rowIndex)"
@@ -20473,8 +20401,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20473
20401
  kendoGridLogicalCell
20474
20402
  [logicalRowIndex]="logicalRowIndex(rowIndex)"
20475
20403
  [logicalColIndex]="0"
20476
- aria-selected="false"
20477
- >
20404
+ aria-selected="false">
20478
20405
  </td>
20479
20406
  <td kendoGridLogicalCell
20480
20407
  [logicalRowIndex]="logicalRowIndex(rowIndex)"
@@ -20503,7 +20430,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20503
20430
  GroupHeaderComponent, IconWrapperComponent, NgTemplateOutlet, ResizeSensorComponent
20504
20431
  ]
20505
20432
  }]
20506
- }], ctorParameters: function () { return [{ type: DetailsService }, { type: GroupsService }, { type: ChangeNotificationService }, { type: EditService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: DomEventsService }, { type: SelectionService }, { type: CellSelectionService }, { type: ColumnInfoService }, { type: NavigationService }, { type: RowspanService }]; }, propDecorators: { columns: [{
20433
+ }], ctorParameters: function () { return [{ type: DetailsService }, { type: GroupsService }, { type: ChangeNotificationService }, { type: EditService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: DomEventsService }, { type: SelectionService }, { type: CellSelectionService }, { type: ColumnInfoService }, { type: NavigationService }]; }, propDecorators: { columns: [{
20507
20434
  type: Input
20508
20435
  }], allColumns: [{
20509
20436
  type: Input
@@ -20513,7 +20440,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20513
20440
  type: Input
20514
20441
  }], noRecordsTemplate: [{
20515
20442
  type: Input
20516
- }], data: [{
20443
+ }], rowsToRender: [{
20517
20444
  type: Input
20518
20445
  }], skip: [{
20519
20446
  type: Input
@@ -20533,8 +20460,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20533
20460
  type: Input
20534
20461
  }], skipGroupDecoration: [{
20535
20462
  type: Input
20536
- }], showGroupFooters: [{
20537
- type: Input
20538
20463
  }], lockedColumnsCount: [{
20539
20464
  type: Input
20540
20465
  }], totalColumnsCount: [{
@@ -21289,8 +21214,8 @@ const packageMetadata = {
21289
21214
  productName: 'Kendo UI for Angular',
21290
21215
  productCode: 'KENDOUIANGULAR',
21291
21216
  productCodes: ['KENDOUIANGULAR'],
21292
- publishDate: 1750771045,
21293
- version: '19.1.2',
21217
+ publishDate: 1751281289,
21218
+ version: '19.2.0-develop.10',
21294
21219
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
21295
21220
  };
21296
21221
 
@@ -23323,6 +23248,141 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
23323
23248
  args: ['style.min-width']
23324
23249
  }] } });
23325
23250
 
23251
+ /**
23252
+ * @hidden
23253
+ */
23254
+ class RowspanService {
23255
+ skipCells = [];
23256
+ addCells(rowIndex, colIndex, rowspan) {
23257
+ for (let i = 1; i < rowspan; i++) {
23258
+ if (!this.skipCells.some(this.cellExists(rowIndex + i, colIndex))) {
23259
+ this.skipCells.push({ rowIndex: rowIndex + i, colIndex });
23260
+ }
23261
+ }
23262
+ }
23263
+ reset() {
23264
+ this.skipCells = [];
23265
+ }
23266
+ shouldSkip(rowIndex, colIndex) {
23267
+ return !!this.skipCells.find(this.cellExists(rowIndex, colIndex));
23268
+ }
23269
+ cellExists = (rowIndex, colIndex) => cell => cell.rowIndex === rowIndex && cell.colIndex === colIndex;
23270
+ }
23271
+
23272
+ /**
23273
+ * @hidden
23274
+ */
23275
+ class DataMappingService {
23276
+ rowspanService;
23277
+ groupsService;
23278
+ detailsService;
23279
+ recalculateRowspan = true;
23280
+ dataArray = null;
23281
+ constructor(rowspanService, groupsService, detailsService) {
23282
+ this.rowspanService = rowspanService;
23283
+ this.groupsService = groupsService;
23284
+ this.detailsService = detailsService;
23285
+ }
23286
+ isGroup(item) {
23287
+ return item.type === 'group';
23288
+ }
23289
+ /**
23290
+ * Maps the data to the Grid row items, applying rowspan and detail row logic.
23291
+ */
23292
+ dataMapper(data, nonLockedColumnsToRender, lockedLeafColumns, detailTemplate, showFooter) {
23293
+ const result = [];
23294
+ if (!data || !nonLockedColumnsToRender && !lockedLeafColumns) {
23295
+ return [];
23296
+ }
23297
+ let dataIndex = 0;
23298
+ for (const item of data) {
23299
+ if (this.shouldRenderItem(item, detailTemplate, showFooter)) {
23300
+ if (item.type === 'data') {
23301
+ item.cells = [];
23302
+ for (let i = 0; i < (lockedLeafColumns.length + nonLockedColumnsToRender.length); i++) {
23303
+ const column = i < lockedLeafColumns.length ? lockedLeafColumns.get(i) : nonLockedColumnsToRender.get(i - lockedLeafColumns.length);
23304
+ const cell = {};
23305
+ if (column.cellRowspan && this.shouldSkipCell(dataIndex, i)) {
23306
+ cell.skip = true;
23307
+ }
23308
+ else {
23309
+ cell.rowspan = column.cellRowspan ? this.getRowspan({
23310
+ index: dataIndex,
23311
+ dataItem: item
23312
+ }, column, i, data) : 1;
23313
+ }
23314
+ item.cells.push(cell);
23315
+ }
23316
+ }
23317
+ result.push(item);
23318
+ }
23319
+ dataIndex++;
23320
+ }
23321
+ this.recalculateRowspan = true;
23322
+ this.rowspanService.reset();
23323
+ return result;
23324
+ }
23325
+ isDataItem(item) {
23326
+ return !this.isGroup(item) && !this.isFooter(item);
23327
+ }
23328
+ isFooter(item) {
23329
+ return item.type === 'footer';
23330
+ }
23331
+ isFooterItemInExpandedGroup(item) {
23332
+ const footerItem = { data: item.data, index: item.groupIndex, parentGroup: item.group.parentGroup };
23333
+ return this.isInExpandedGroup(footerItem);
23334
+ }
23335
+ isDataItemInExpandedGroup(item) {
23336
+ const dataItem = { data: item.group.data, index: item.groupIndex, parentGroup: item.group.parentGroup };
23337
+ return this.isInExpandedGroup(dataItem);
23338
+ }
23339
+ isInExpandedGroup(item) {
23340
+ return this.groupsService.isInExpandedGroup(item);
23341
+ }
23342
+ isParentGroupExpanded(item) {
23343
+ return this.groupsService.isInExpandedGroup(item.parentGroup);
23344
+ }
23345
+ isExpanded(viewItem) {
23346
+ return this.detailsService.isExpanded(viewItem.index, viewItem.data);
23347
+ }
23348
+ shouldRenderItem(item, detailTemplate, showFooter) {
23349
+ const renderGroupHeader = this.isGroup(item) && this.isParentGroupExpanded(item);
23350
+ const renderDataItem = this.isDataItem(item) && (!item.group || this.isDataItemInExpandedGroup(item));
23351
+ const renderDetailTemplate = renderDataItem && detailTemplate?.templateRef && detailTemplate.showIf(item.data, item.index) && this.isExpanded(item);
23352
+ const isVisibleFooter = this.isFooter(item) && item.group && (this.isFooterItemInExpandedGroup(item) || (showFooter && this.isParentGroupExpanded(item.group)));
23353
+ const renderFooter = isVisibleFooter && !item.data.hideFooter;
23354
+ item.showDataItem = renderDataItem;
23355
+ item.showDetailRow = renderDataItem && renderDetailTemplate;
23356
+ item.isExpanded = this.isExpanded(item);
23357
+ return renderGroupHeader || renderDataItem || renderDetailTemplate || renderFooter;
23358
+ }
23359
+ shouldSkipCell(rowIndex, colIndex) {
23360
+ return this.rowspanService.shouldSkip(rowIndex, colIndex);
23361
+ }
23362
+ cachedDataArray(data) {
23363
+ if (!this.dataArray) {
23364
+ this.dataArray = data.map(item => item);
23365
+ }
23366
+ return this.dataArray;
23367
+ }
23368
+ getRowspan(row, column, colIndex, data) {
23369
+ if (this.recalculateRowspan) {
23370
+ this.dataArray = null;
23371
+ this.recalculateRowspan = false;
23372
+ }
23373
+ const rowspan = column.cellRowspan(row, column, this.cachedDataArray(data));
23374
+ if (rowspan > 1) {
23375
+ this.rowspanService.addCells(row.index, colIndex, rowspan);
23376
+ }
23377
+ return rowspan;
23378
+ }
23379
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataMappingService, deps: [{ token: RowspanService }, { token: GroupsService }, { token: DetailsService }], target: i0.ɵɵFactoryTarget.Injectable });
23380
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataMappingService });
23381
+ }
23382
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataMappingService, decorators: [{
23383
+ type: Injectable
23384
+ }], ctorParameters: function () { return [{ type: RowspanService }, { type: GroupsService }, { type: DetailsService }]; } });
23385
+
23326
23386
  const elementAt = (index, elements, elementOffset) => {
23327
23387
  for (let idx = 0, elementIdx = 0; idx < elements.length; idx++) {
23328
23388
  const offset = elementOffset(elements[idx]);
@@ -23387,14 +23447,13 @@ class ListComponent {
23387
23447
  changeDetector;
23388
23448
  pdfService;
23389
23449
  columnInfo;
23390
- rowspanService;
23450
+ dataMappingService;
23391
23451
  hostClass = true;
23392
23452
  hostRole = 'presentation';
23393
23453
  data;
23394
23454
  groups = [];
23395
23455
  total;
23396
23456
  rowHeight;
23397
- stickyRowHeight;
23398
23457
  detailRowHeight;
23399
23458
  take;
23400
23459
  skip = 0;
@@ -23419,6 +23478,7 @@ class ListComponent {
23419
23478
  scrollBottom = new EventEmitter();
23420
23479
  totalHeight;
23421
23480
  columnsStartIdx = 0;
23481
+ allItems = [];
23422
23482
  get showFooter() {
23423
23483
  return this.groupable && this.groupable.showFooter;
23424
23484
  }
@@ -23444,6 +23504,7 @@ class ListComponent {
23444
23504
  columnsEndIdx;
23445
23505
  viewportColumnsWidth;
23446
23506
  scrollLeft = 0;
23507
+ recalculateRowspan = true;
23447
23508
  observer;
23448
23509
  get lockedLeafColumns() {
23449
23510
  return this.columns.lockedLeafColumns;
@@ -23476,7 +23537,8 @@ class ListComponent {
23476
23537
  rtl = false;
23477
23538
  columnUpdateFrame;
23478
23539
  hasLockedContainer;
23479
- constructor(scrollerFactory, detailsService, changeNotification, suspendService, groupsService, ngZone, renderer, scrollSyncService, resizeService, editService, supportService, navigationService, scrollRequestService, ctx, columnResizingService, changeDetector, pdfService, columnInfo, rowspanService) {
23540
+ minRowHeight;
23541
+ constructor(scrollerFactory, detailsService, changeNotification, suspendService, groupsService, ngZone, renderer, scrollSyncService, resizeService, editService, supportService, navigationService, scrollRequestService, ctx, columnResizingService, changeDetector, pdfService, columnInfo, dataMappingService) {
23480
23542
  this.changeNotification = changeNotification;
23481
23543
  this.suspendService = suspendService;
23482
23544
  this.groupsService = groupsService;
@@ -23492,12 +23554,13 @@ class ListComponent {
23492
23554
  this.changeDetector = changeDetector;
23493
23555
  this.pdfService = pdfService;
23494
23556
  this.columnInfo = columnInfo;
23495
- this.rowspanService = rowspanService;
23557
+ this.dataMappingService = dataMappingService;
23496
23558
  this.scroller = scrollerFactory(this.dispatcher);
23497
23559
  this.subscriptions = detailsService.changes.subscribe(x => this.detailExpand(x));
23498
23560
  this.subscriptions.add(scrollRequestService.requests.subscribe(req => isPresent(req.adjustIndex) ? this.scrollTo(req.request, req.adjustIndex) : this.scrollToItem(req.request)));
23499
23561
  }
23500
23562
  ngOnInit() {
23563
+ this.minRowHeight = this.isVirtual ? this.rowHeight || calcRowHeight(this.table.nativeElement) : this.rowHeight;
23501
23564
  this.init();
23502
23565
  this.subscriptions.add(this.ngZone.runOutsideAngular(this.handleRowSync.bind(this)));
23503
23566
  this.subscriptions.add(this.ngZone.runOutsideAngular(this.handleRowNavigationLocked.bind(this)));
@@ -23533,6 +23596,22 @@ class ListComponent {
23533
23596
  if (this.virtualColumns && (!this.viewportColumns || this.viewportWidthChange())) {
23534
23597
  this.updateViewportColumns();
23535
23598
  }
23599
+ const shouldCalculatePageSize = isDocumentAvailable() && this.isVirtual && this.ctx.grid && !this.ctx.grid.pageSize;
23600
+ if (shouldCalculatePageSize) {
23601
+ const calculatedPageSize = this.calcVirtualPageSize();
23602
+ if (calculatedPageSize > 0) {
23603
+ this.ngZone.onMicrotaskEmpty.pipe(take(1)).subscribe(() => {
23604
+ this.ctx.grid.pageSize = calculatedPageSize;
23605
+ this.ngZone.run(() => {
23606
+ this.pageChange.emit({
23607
+ skip: this.skip || 0,
23608
+ take: calculatedPageSize
23609
+ });
23610
+ });
23611
+ });
23612
+ }
23613
+ }
23614
+ this.allItems = this.dataMappingService.dataMapper(this.data, this.nonLockedColumnsToRender, this.lockedLeafColumns, this.detailTemplate, this.showFooter);
23536
23615
  }
23537
23616
  ngAfterViewInit() {
23538
23617
  if (!isDocumentAvailable()) {
@@ -23571,7 +23650,7 @@ class ListComponent {
23571
23650
  if (this.suspendService.scroll) {
23572
23651
  return;
23573
23652
  }
23574
- this.rowHeightService = new RowHeightService(this.total, this.rowHeight, this.detailRowHeight);
23653
+ this.rowHeightService = new RowHeightService(this.total, this.rowHeight || this.minRowHeight, this.detailRowHeight);
23575
23654
  this.totalHeight = this.rowHeightService.totalHeight();
23576
23655
  if (!isUniversal()) {
23577
23656
  this.ngZone.runOutsideAngular(this.createScroller.bind(this));
@@ -23600,6 +23679,36 @@ class ListComponent {
23600
23679
  args.preventDefault();
23601
23680
  }
23602
23681
  }
23682
+ updateViewportColumns(range) {
23683
+ const columns = this.columns.nonLockedLeafColumns.toArray();
23684
+ // eslint-disable-next-line prefer-const
23685
+ let { startIdx, endIdx, offset } = range || this.calculateViewportColumns();
23686
+ const start = Math.max(0, startIdx - bufferSize);
23687
+ const end = Math.min(endIdx + bufferSize, columns.length - 1);
23688
+ if (start < startIdx) {
23689
+ for (let idx = startIdx - 1; idx >= start; idx--) {
23690
+ offset -= columns[idx].width;
23691
+ }
23692
+ }
23693
+ let currentColumns = columns.slice(start, end + 1);
23694
+ this.viewportColumnsWidth = currentColumns.reduce((total, column) => total + column.width, 0);
23695
+ const stickyBeforeStart = columns.slice(0, start).filter(c => c.sticky && !currentColumns.some(col => col === c));
23696
+ const stickyAfterEnd = columns.slice(end, columns.length).filter(c => c.sticky && !currentColumns.some(col => col === c));
23697
+ currentColumns = [...stickyBeforeStart, ...currentColumns, ...stickyAfterEnd];
23698
+ if (start > 0) {
23699
+ const offsetColumn = new ColumnBase();
23700
+ offsetColumn.width = offset;
23701
+ currentColumns.unshift(offsetColumn);
23702
+ }
23703
+ this.viewportColumns = new QueryList();
23704
+ this.viewportColumns.reset(currentColumns);
23705
+ this.columnsStartIdx = start;
23706
+ this.columnsEndIdx = end;
23707
+ this.columnInfo.columnRangeChange.emit({ start, end, offset });
23708
+ if (!range) {
23709
+ this.updateColumnViewport(startIdx, endIdx);
23710
+ }
23711
+ }
23603
23712
  detailExpand({ index, expand }) {
23604
23713
  if (expand) {
23605
23714
  this.rowHeightService.expandDetail(index);
@@ -23640,10 +23749,10 @@ class ListComponent {
23640
23749
  const observable = this.scroller
23641
23750
  .create(this.rowHeightService, this.skip, this.take, this.total);
23642
23751
  this.skipScroll = false;
23643
- this.scrollerSubscription = observable.pipe(filter((x) => x instanceof PageAction), filter(() => {
23752
+ this.scrollerSubscription = observable.pipe(filter((x) => x instanceof PageAction), filter((x) => {
23644
23753
  const temp = this.skipScroll;
23645
23754
  this.skipScroll = false;
23646
- return !temp;
23755
+ return !temp && x.skip !== this.skip;
23647
23756
  }), tap(() => this.rebind = true))
23648
23757
  .subscribe((x) => this.ngZone.run(() => this.pageChange.emit(x)));
23649
23758
  this.scrollerSubscription.add(observable.pipe(filter((x) => x instanceof ScrollAction))
@@ -23682,7 +23791,6 @@ class ListComponent {
23682
23791
  .pipe(filter(isLocked), switchMapTo(onStable())), this.editService.changed, this.resizeService.changes, this.columnResizingService.changes
23683
23792
  .pipe(filter(change => change.type === 'end')), this.supportService.changes)
23684
23793
  .pipe(tap(() => {
23685
- this.ngZone.run(() => this.rowspanService.reset());
23686
23794
  this.resetNavigationViewport();
23687
23795
  }), filter(isLocked))
23688
23796
  .subscribe(() => {
@@ -23826,36 +23934,6 @@ class ListComponent {
23826
23934
  })
23827
23935
  .forEach(setHeight(this.renderer));
23828
23936
  }
23829
- updateViewportColumns(range) {
23830
- const columns = this.columns.nonLockedLeafColumns.toArray();
23831
- // eslint-disable-next-line prefer-const
23832
- let { startIdx, endIdx, offset } = range || this.calculateViewportColumns();
23833
- const start = Math.max(0, startIdx - bufferSize);
23834
- const end = Math.min(endIdx + bufferSize, columns.length - 1);
23835
- if (start < startIdx) {
23836
- for (let idx = startIdx - 1; idx >= start; idx--) {
23837
- offset -= columns[idx].width;
23838
- }
23839
- }
23840
- let currentColumns = columns.slice(start, end + 1);
23841
- this.viewportColumnsWidth = currentColumns.reduce((total, column) => total + column.width, 0);
23842
- const stickyBeforeStart = columns.slice(0, start).filter(c => c.sticky && !currentColumns.some(col => col === c));
23843
- const stickyAfterEnd = columns.slice(end, columns.length).filter(c => c.sticky && !currentColumns.some(col => col === c));
23844
- currentColumns = [...stickyBeforeStart, ...currentColumns, ...stickyAfterEnd];
23845
- if (start > 0) {
23846
- const offsetColumn = new ColumnBase();
23847
- offsetColumn.width = offset;
23848
- currentColumns.unshift(offsetColumn);
23849
- }
23850
- this.viewportColumns = new QueryList();
23851
- this.viewportColumns.reset(currentColumns);
23852
- this.columnsStartIdx = start;
23853
- this.columnsEndIdx = end;
23854
- this.columnInfo.columnRangeChange.emit({ start, end, offset });
23855
- if (!range) {
23856
- this.updateColumnViewport(startIdx, endIdx);
23857
- }
23858
- }
23859
23937
  handleColumnScroll() {
23860
23938
  const container = this.container.nativeElement;
23861
23939
  const scrollLeft = container.scrollLeft;
@@ -23927,8 +24005,15 @@ class ListComponent {
23927
24005
  }
23928
24006
  return element.offsetLeft;
23929
24007
  }
23930
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListComponent, deps: [{ token: SCROLLER_FACTORY_TOKEN }, { token: DetailsService }, { token: ChangeNotificationService }, { token: SuspendService }, { token: GroupsService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: ScrollSyncService }, { token: ResizeService }, { token: EditService }, { token: BrowserSupportService }, { token: NavigationService }, { token: ScrollRequestService }, { token: ContextService }, { token: ColumnResizingService }, { token: i0.ChangeDetectorRef }, { token: PDFService }, { token: ColumnInfoService }, { token: RowspanService }], target: i0.ɵɵFactoryTarget.Component });
23931
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ListComponent, isStandalone: true, selector: "kendo-grid-list", inputs: { data: "data", groups: "groups", total: "total", rowHeight: "rowHeight", stickyRowHeight: "stickyRowHeight", detailRowHeight: "detailRowHeight", take: "take", skip: "skip", columns: "columns", detailTemplate: "detailTemplate", noRecordsTemplate: "noRecordsTemplate", selectable: "selectable", groupable: "groupable", filterable: "filterable", rowClass: "rowClass", rowSticky: "rowSticky", loading: "loading", trackBy: "trackBy", virtualColumns: "virtualColumns", isVirtual: "isVirtual", cellLoadingTemplate: "cellLoadingTemplate", loadingTemplate: "loadingTemplate", sort: "sort", size: "size" }, outputs: { contentScroll: "contentScroll", pageChange: "pageChange", scrollBottom: "scrollBottom" }, host: { properties: { "class.k-grid-container": "this.hostClass", "attr.role": "this.hostRole" } }, providers: [
24008
+ calcVirtualPageSize = () => {
24009
+ const containerHeight = this.container.nativeElement.offsetHeight;
24010
+ if (containerHeight && (this.rowHeight ?? this.minRowHeight)) {
24011
+ return Math.ceil((containerHeight / (this.rowHeight ?? this.minRowHeight)) * 1.5);
24012
+ }
24013
+ return 0;
24014
+ };
24015
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListComponent, deps: [{ token: SCROLLER_FACTORY_TOKEN }, { token: DetailsService }, { token: ChangeNotificationService }, { token: SuspendService }, { token: GroupsService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: ScrollSyncService }, { token: ResizeService }, { token: EditService }, { token: BrowserSupportService }, { token: NavigationService }, { token: ScrollRequestService }, { token: ContextService }, { token: ColumnResizingService }, { token: i0.ChangeDetectorRef }, { token: PDFService }, { token: ColumnInfoService }, { token: DataMappingService }], target: i0.ɵɵFactoryTarget.Component });
24016
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ListComponent, isStandalone: true, selector: "kendo-grid-list", inputs: { data: "data", groups: "groups", total: "total", rowHeight: "rowHeight", detailRowHeight: "detailRowHeight", take: "take", skip: "skip", columns: "columns", detailTemplate: "detailTemplate", noRecordsTemplate: "noRecordsTemplate", selectable: "selectable", groupable: "groupable", filterable: "filterable", rowClass: "rowClass", rowSticky: "rowSticky", loading: "loading", trackBy: "trackBy", virtualColumns: "virtualColumns", isVirtual: "isVirtual", cellLoadingTemplate: "cellLoadingTemplate", loadingTemplate: "loadingTemplate", sort: "sort", size: "size" }, outputs: { contentScroll: "contentScroll", pageChange: "pageChange", scrollBottom: "scrollBottom" }, host: { properties: { "class.k-grid-container": "this.hostClass", "attr.role": "this.hostRole" } }, providers: [
23932
24017
  {
23933
24018
  provide: SCROLLER_FACTORY_TOKEN,
23934
24019
  useValue: DEFAULT_SCROLLER_FACTORY
@@ -23964,13 +24049,12 @@ class ListComponent {
23964
24049
  role="presentation"
23965
24050
  [groups]="groups"
23966
24051
  [isLocked]="true"
23967
- [data]="data"
24052
+ [rowsToRender]="allItems"
23968
24053
  [noRecordsText]="''"
23969
24054
  [columns]="$any(lockedLeafColumns)"
23970
24055
  [totalColumnsCount]="leafColumns.length"
23971
24056
  [totalColumns]="columns"
23972
24057
  [detailTemplate]="detailTemplate"
23973
- [showGroupFooters]="showFooter"
23974
24058
  [skip]="skip"
23975
24059
  [selectable]="selectable"
23976
24060
  [trackBy]="trackBy"
@@ -24012,9 +24096,8 @@ class ListComponent {
24012
24096
  <tbody kendoGridTableBody
24013
24097
  role="rowgroup"
24014
24098
  [skipGroupDecoration]="isLocked"
24015
- [data]="data"
24099
+ [rowsToRender]="allItems"
24016
24100
  [groups]="groups"
24017
- [showGroupFooters]="showFooter"
24018
24101
  [columns]="$any(nonLockedColumnsToRender)"
24019
24102
  [allColumns]="$any(nonLockedLeafColumns)"
24020
24103
  [detailTemplate]="detailTemplate"
@@ -24044,7 +24127,7 @@ class ListComponent {
24044
24127
  <div [style.width.px]="totalWidth"></div>
24045
24128
  </div>
24046
24129
  </div>
24047
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { kind: "directive", type: TableDirective, selector: "[kendoGridResizableTable]", inputs: ["locked", "virtualColumns"] }, { kind: "directive", type: GridTableDirective, selector: "[kendoGridTable]", inputs: ["size"] }, { kind: "component", type: ColGroupComponent, selector: "[kendoGridColGroup]", inputs: ["columns", "groups", "detailTemplate", "sort"] }, { kind: "component", type: TableBodyComponent, selector: "[kendoGridTableBody]", inputs: ["columns", "allColumns", "groups", "detailTemplate", "noRecordsTemplate", "data", "skip", "selectable", "filterable", "noRecordsText", "isLocked", "isLoading", "isVirtual", "cellLoadingTemplate", "skipGroupDecoration", "showGroupFooters", "lockedColumnsCount", "totalColumnsCount", "virtualColumns", "trackBy", "rowSticky", "totalColumns", "rowClass"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }, { kind: "directive", type: ResizableContainerDirective, selector: "[kendoGridResizableContainer]", inputs: ["lockedWidth", "kendoGridResizableContainer"] }] });
24130
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { kind: "directive", type: TableDirective, selector: "[kendoGridResizableTable]", inputs: ["locked", "virtualColumns"] }, { kind: "directive", type: GridTableDirective, selector: "[kendoGridTable]", inputs: ["size"] }, { kind: "component", type: ColGroupComponent, selector: "[kendoGridColGroup]", inputs: ["columns", "groups", "detailTemplate", "sort"] }, { kind: "component", type: TableBodyComponent, selector: "[kendoGridTableBody]", inputs: ["columns", "allColumns", "groups", "detailTemplate", "noRecordsTemplate", "rowsToRender", "skip", "selectable", "filterable", "noRecordsText", "isLocked", "isLoading", "isVirtual", "cellLoadingTemplate", "skipGroupDecoration", "lockedColumnsCount", "totalColumnsCount", "virtualColumns", "trackBy", "rowSticky", "totalColumns", "rowClass"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }, { kind: "directive", type: ResizableContainerDirective, selector: "[kendoGridResizableContainer]", inputs: ["lockedWidth", "kendoGridResizableContainer"] }] });
24048
24131
  }
24049
24132
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListComponent, decorators: [{
24050
24133
  type: Component,
@@ -24087,13 +24170,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
24087
24170
  role="presentation"
24088
24171
  [groups]="groups"
24089
24172
  [isLocked]="true"
24090
- [data]="data"
24173
+ [rowsToRender]="allItems"
24091
24174
  [noRecordsText]="''"
24092
24175
  [columns]="$any(lockedLeafColumns)"
24093
24176
  [totalColumnsCount]="leafColumns.length"
24094
24177
  [totalColumns]="columns"
24095
24178
  [detailTemplate]="detailTemplate"
24096
- [showGroupFooters]="showFooter"
24097
24179
  [skip]="skip"
24098
24180
  [selectable]="selectable"
24099
24181
  [trackBy]="trackBy"
@@ -24135,9 +24217,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
24135
24217
  <tbody kendoGridTableBody
24136
24218
  role="rowgroup"
24137
24219
  [skipGroupDecoration]="isLocked"
24138
- [data]="data"
24220
+ [rowsToRender]="allItems"
24139
24221
  [groups]="groups"
24140
- [showGroupFooters]="showFooter"
24141
24222
  [columns]="$any(nonLockedColumnsToRender)"
24142
24223
  [allColumns]="$any(nonLockedLeafColumns)"
24143
24224
  [detailTemplate]="detailTemplate"
@@ -24174,7 +24255,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
24174
24255
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
24175
24256
  type: Inject,
24176
24257
  args: [SCROLLER_FACTORY_TOKEN]
24177
- }] }, { type: DetailsService }, { type: ChangeNotificationService }, { type: SuspendService }, { type: GroupsService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: ScrollSyncService }, { type: ResizeService }, { type: EditService }, { type: BrowserSupportService }, { type: NavigationService }, { type: ScrollRequestService }, { type: ContextService }, { type: ColumnResizingService }, { type: i0.ChangeDetectorRef }, { type: PDFService }, { type: ColumnInfoService }, { type: RowspanService }]; }, propDecorators: { hostClass: [{
24258
+ }] }, { type: DetailsService }, { type: ChangeNotificationService }, { type: SuspendService }, { type: GroupsService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: ScrollSyncService }, { type: ResizeService }, { type: EditService }, { type: BrowserSupportService }, { type: NavigationService }, { type: ScrollRequestService }, { type: ContextService }, { type: ColumnResizingService }, { type: i0.ChangeDetectorRef }, { type: PDFService }, { type: ColumnInfoService }, { type: DataMappingService }]; }, propDecorators: { hostClass: [{
24178
24259
  type: HostBinding,
24179
24260
  args: ['class.k-grid-container']
24180
24261
  }], hostRole: [{
@@ -24188,8 +24269,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
24188
24269
  type: Input
24189
24270
  }], rowHeight: [{
24190
24271
  type: Input
24191
- }], stickyRowHeight: [{
24192
- type: Input
24193
24272
  }], detailRowHeight: [{
24194
24273
  type: Input
24195
24274
  }], take: [{
@@ -24239,10 +24318,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
24239
24318
  args: ['container', { static: true }]
24240
24319
  }], lockedContainer: [{
24241
24320
  type: ViewChild,
24242
- args: ['lockedContainer', { static: false }]
24321
+ args: ['lockedContainer']
24243
24322
  }], lockedTable: [{
24244
24323
  type: ViewChild,
24245
- args: ['lockedTable', { static: false }]
24324
+ args: ['lockedTable']
24246
24325
  }], table: [{
24247
24326
  type: ViewChild,
24248
24327
  args: ['table', { static: true }]
@@ -27566,6 +27645,538 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
27566
27645
  args: [GroupToolbarToolComponent]
27567
27646
  }] } });
27568
27647
 
27648
+ /**
27649
+ * A directive that handles in-memory data operations like [paging]({% slug paging_grid %}),
27650
+ * [sorting]({% slug sorting_grid %}), and [grouping]({% slug grouping_grid %}).
27651
+ *
27652
+ * Use this directive with local data and enable the Grid data operations with minimal configuration.
27653
+ * ([More information and examples]({% slug local_data_grid %}#toc-using-the-data-binding-directive)).
27654
+ *
27655
+ * @example
27656
+ * ```html
27657
+ * <kendo-grid [kendoGridBinding]="gridData"></kendo-grid>
27658
+ * ```
27659
+ * @remarks
27660
+ * Applied to: {@link GridComponent}.
27661
+ */
27662
+ class DataBindingDirective {
27663
+ grid;
27664
+ changeDetector;
27665
+ localDataChangesService;
27666
+ rowReorderService;
27667
+ /**
27668
+ * Sets the number of records to skip in the Grid.
27669
+ *
27670
+ * @default 0
27671
+ */
27672
+ set skip(value) {
27673
+ if (!isPresent(value)) {
27674
+ value = 0;
27675
+ }
27676
+ this.grid.skip = this.state.skip = value;
27677
+ if (this.rowReorderService) {
27678
+ this.rowReorderService.skip = value;
27679
+ }
27680
+ }
27681
+ /**
27682
+ * Sets the sort descriptors for the Grid data.
27683
+ *
27684
+ */
27685
+ set sort(value) {
27686
+ this.grid.sort = this.state.sort = value;
27687
+ }
27688
+ /**
27689
+ * Sets the filter descriptor for the Grid data.
27690
+ *
27691
+ */
27692
+ set filter(value) {
27693
+ this.grid.filter = this.state.filter = value;
27694
+ }
27695
+ /**
27696
+ * Sets the page size for the Grid pager.
27697
+ *
27698
+ */
27699
+ set pageSize(value) {
27700
+ this.grid.pageSize = this.state.take = value;
27701
+ }
27702
+ /**
27703
+ * Sets the group descriptors for the Grid data.
27704
+ *
27705
+ */
27706
+ set group(value) {
27707
+ this.grid.group = this.state.group = value;
27708
+ }
27709
+ /**
27710
+ * Sets the data array for the Grid.
27711
+ *
27712
+ */
27713
+ set data(value) {
27714
+ this.originalData = value || [];
27715
+ if (this.localDataChangesService) {
27716
+ this.localDataChangesService.data = value;
27717
+ }
27718
+ this.dataChanged = true;
27719
+ }
27720
+ state = {
27721
+ skip: 0
27722
+ };
27723
+ originalData = [];
27724
+ dataChanged;
27725
+ stateChangeSubscription;
27726
+ dataChangedSubscription;
27727
+ rowReorderSubscription;
27728
+ constructor(grid, changeDetector, localDataChangesService, rowReorderService, ctx) {
27729
+ this.grid = grid;
27730
+ this.changeDetector = changeDetector;
27731
+ this.localDataChangesService = localDataChangesService;
27732
+ this.rowReorderService = rowReorderService;
27733
+ if (localDataChangesService) {
27734
+ this.dataChangedSubscription = this.localDataChangesService.changes.subscribe(this.rebind.bind(this));
27735
+ }
27736
+ ctx && (ctx.dataBindingDirective = this);
27737
+ }
27738
+ /**
27739
+ * @hidden
27740
+ */
27741
+ ngOnInit() {
27742
+ this.applyState(this.state);
27743
+ this.stateChangeSubscription = this.grid
27744
+ .dataStateChange
27745
+ .subscribe(this.onStateChange.bind(this));
27746
+ if (this.rowReorderService) {
27747
+ this.rowReorderSubscription = this.grid
27748
+ .rowReorder
27749
+ .subscribe(this.onRowReorder.bind(this));
27750
+ }
27751
+ }
27752
+ /**
27753
+ * @hidden
27754
+ */
27755
+ ngOnDestroy() {
27756
+ if (this.stateChangeSubscription) {
27757
+ this.stateChangeSubscription.unsubscribe();
27758
+ }
27759
+ if (this.dataChangedSubscription) {
27760
+ this.dataChangedSubscription.unsubscribe();
27761
+ }
27762
+ if (this.rowReorderSubscription) {
27763
+ this.rowReorderSubscription.unsubscribe();
27764
+ }
27765
+ }
27766
+ /**
27767
+ * @hidden
27768
+ */
27769
+ ngOnChanges(changes) {
27770
+ if (anyChanged(["pageSize", "skip", "sort", "group", "filter"], changes)) {
27771
+ this.rebind();
27772
+ }
27773
+ }
27774
+ ngDoCheck() {
27775
+ if (this.dataChanged) {
27776
+ this.updateGridData();
27777
+ }
27778
+ }
27779
+ /**
27780
+ * @hidden
27781
+ */
27782
+ onStateChange(state) {
27783
+ this.applyState(state);
27784
+ this.rebind();
27785
+ }
27786
+ /**
27787
+ * @hidden
27788
+ */
27789
+ onRowReorder(ev) {
27790
+ this.rowReorderService.reorderRows(ev, this.originalData);
27791
+ this.rebind();
27792
+ }
27793
+ /**
27794
+ * @hidden
27795
+ */
27796
+ rebind() {
27797
+ this.data = this.originalData;
27798
+ this.updateGridData();
27799
+ this.notifyDataChange();
27800
+ }
27801
+ /**
27802
+ * Notifies the Grid that its data has changed.
27803
+ */
27804
+ notifyDataChange() {
27805
+ this.grid.onDataChange();
27806
+ if (this.changeDetector) {
27807
+ this.changeDetector.markForCheck();
27808
+ }
27809
+ }
27810
+ process(state) {
27811
+ if (this.grid.isVirtual && (!isPresent(state.take) || state.take === 0)) {
27812
+ return {
27813
+ data: [],
27814
+ total: this.originalData?.length || 0
27815
+ };
27816
+ }
27817
+ return process(this.originalData, state);
27818
+ }
27819
+ applyState({ skip, take, sort, group, filter }) {
27820
+ this.skip = skip;
27821
+ this.pageSize = take;
27822
+ this.sort = sort;
27823
+ this.group = group;
27824
+ this.filter = filter;
27825
+ }
27826
+ updateGridData() {
27827
+ this.grid.data = this.process(this.state);
27828
+ this.grid.updateNavigationMetadata();
27829
+ this.dataChanged = false;
27830
+ }
27831
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataBindingDirective, deps: [{ token: GridComponent }, { token: i0.ChangeDetectorRef }, { token: LocalDataChangesService }, { token: RowReorderService }, { token: ContextService }], target: i0.ɵɵFactoryTarget.Directive });
27832
+ 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 });
27833
+ }
27834
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataBindingDirective, decorators: [{
27835
+ type: Directive,
27836
+ args: [{
27837
+ selector: '[kendoGridBinding]',
27838
+ exportAs: 'kendoGridBinding',
27839
+ standalone: true
27840
+ }]
27841
+ }], ctorParameters: function () { return [{ type: GridComponent }, { type: i0.ChangeDetectorRef }, { type: LocalDataChangesService }, { type: RowReorderService }, { type: ContextService }]; }, propDecorators: { skip: [{
27842
+ type: Input
27843
+ }], sort: [{
27844
+ type: Input
27845
+ }], filter: [{
27846
+ type: Input
27847
+ }], pageSize: [{
27848
+ type: Input
27849
+ }], group: [{
27850
+ type: Input
27851
+ }], data: [{
27852
+ type: Input,
27853
+ args: ["kendoGridBinding"]
27854
+ }] } });
27855
+
27856
+ const hasGroups = (items) => items && items.length && items[0].field && items[0].items;
27857
+ const groupDescriptorsPresent = (descriptors) => isPresent(descriptors) && descriptors.length > 0;
27858
+ const processGroups = (data, state) => process(data, state).data;
27859
+ const removeParentDescriptors = (parents, owner) => g => g.field !== owner.field && !parents.some(y => y.field === g.field);
27860
+ const findGroup = (groupIndex, groups) => {
27861
+ const parents = [];
27862
+ return {
27863
+ group: groupIndex.split("_").reduce((acc, x) => {
27864
+ const idx = parseInt(x, 10);
27865
+ if (acc.items) {
27866
+ parents.push(acc);
27867
+ return acc.items[idx];
27868
+ }
27869
+ return isArray(acc) ? acc[idx] : acc;
27870
+ }, groups),
27871
+ parents
27872
+ };
27873
+ };
27874
+ const findChildren = (data, parents) => {
27875
+ const filters = parents.map(p => ({ field: p.field, operator: "eq", value: p.value }));
27876
+ return filterBy(data, {
27877
+ filters: filters,
27878
+ logic: "and"
27879
+ });
27880
+ };
27881
+ /**
27882
+ * @hidden
27883
+ */
27884
+ const count = (groups, includeFooters = false) => (groups.reduce((acc, group) => {
27885
+ if (!group.skipHeader) {
27886
+ acc++;
27887
+ }
27888
+ if (group.items) {
27889
+ const children = count(group.items, includeFooters);
27890
+ if (includeFooters && children && !group.hideFooter) {
27891
+ acc++;
27892
+ }
27893
+ acc += children;
27894
+ }
27895
+ return acc;
27896
+ }, 0));
27897
+ /**
27898
+ * @hidden
27899
+ */
27900
+ const noDescriptors = (descriptors) => !isPresent(descriptors) || !descriptors.length;
27901
+ /**
27902
+ * @hidden
27903
+ */
27904
+ const slice = (groups, skip, take, includeFooters = false) => {
27905
+ if (!isPresent(take)) {
27906
+ return groups;
27907
+ }
27908
+ const result = [];
27909
+ for (let idx = 0, length = groups.length; idx < length; idx++) {
27910
+ if (take <= 0) {
27911
+ break;
27912
+ }
27913
+ const group = groups[idx];
27914
+ const groupItems = group.items;
27915
+ let itemCount = count(groupItems, includeFooters);
27916
+ if (includeFooters && groupItems.length) {
27917
+ itemCount++;
27918
+ }
27919
+ const skipHeader = skip > 0;
27920
+ if (skip) {
27921
+ skip--;
27922
+ if (itemCount && skip >= itemCount) {
27923
+ skip -= itemCount;
27924
+ continue;
27925
+ }
27926
+ }
27927
+ if (!skipHeader || itemCount) {
27928
+ const items = [];
27929
+ let hideFooter = true;
27930
+ if (!skipHeader) {
27931
+ take--;
27932
+ }
27933
+ if (take) {
27934
+ if (hasGroups(groupItems)) {
27935
+ const children = slice(groupItems, skip, take, includeFooters);
27936
+ items.push(...children);
27937
+ take -= count(children, includeFooters);
27938
+ }
27939
+ else {
27940
+ items.push(...groupItems.slice(skip, Math.min(skip + take, groupItems.length)));
27941
+ take -= items.length;
27942
+ }
27943
+ if (take && includeFooters) {
27944
+ hideFooter = false;
27945
+ take--;
27946
+ }
27947
+ skip = 0;
27948
+ }
27949
+ result.push({
27950
+ aggregates: group.aggregates,
27951
+ field: group.field,
27952
+ hideFooter,
27953
+ items,
27954
+ offset: idx,
27955
+ skipHeader,
27956
+ value: group.value
27957
+ });
27958
+ }
27959
+ }
27960
+ return result;
27961
+ };
27962
+ const skippedHeaders = (groupItem) => {
27963
+ let total = 0;
27964
+ while (groupItem) {
27965
+ if (groupItem.skipHeader) {
27966
+ total++;
27967
+ }
27968
+ groupItem = groupItem.items && groupItem.items[0] || null;
27969
+ }
27970
+ return total;
27971
+ };
27972
+ /**
27973
+ * A directive which encapsulates the in-memory handling of grouping with virtual scrolling.
27974
+ * @remarks
27975
+ * Applied to: {@link GridComponent}.
27976
+ */
27977
+ class GroupBindingDirective extends DataBindingDirective {
27978
+ groupsService;
27979
+ /**
27980
+ * The array of data which will be used to populate the Grid.
27981
+ */
27982
+ set kendoGridGroupBinding(value) {
27983
+ this.groups = null;
27984
+ this.grid.resetGroupsState();
27985
+ this.data = value;
27986
+ }
27987
+ /**
27988
+ * @hidden
27989
+ */
27990
+ set data(value) {
27991
+ this.originalData = value || [];
27992
+ this.dataChanged = true;
27993
+ }
27994
+ /**
27995
+ * Defines the descriptors by which the data will be sorted.
27996
+ */
27997
+ set sort(value) {
27998
+ const noCurrentDescriptors = noDescriptors(this.state.sort);
27999
+ const noIncomingDescriptors = noDescriptors(value);
28000
+ const clear = this.state.sort !== value && !(noCurrentDescriptors && noIncomingDescriptors);
28001
+ this.grid.sort = this.state.sort = value;
28002
+ if (clear) {
28003
+ this.groups = null;
28004
+ this.grid.resetGroupsState();
28005
+ }
28006
+ }
28007
+ /**
28008
+ * Defines the descriptor by which the data will be filtered.
28009
+ */
28010
+ set filter(value) {
28011
+ const clear = diffFilters(this.state.filter, value);
28012
+ if (clear) {
28013
+ this.state.filter = value;
28014
+ this.grid.filter = cloneFilters(value);
28015
+ this.groups = null;
28016
+ this.grid.resetGroupsState();
28017
+ }
28018
+ }
28019
+ /**
28020
+ * Defines the descriptors by which the data will be grouped.
28021
+ */
28022
+ set group(value) {
28023
+ // don't clear if no groups are present in previous and current value
28024
+ const groupsPresent = groupDescriptorsPresent(this.state.group) || groupDescriptorsPresent(value);
28025
+ const clear = this.state.group !== value && groupsPresent;
28026
+ this.grid.group = this.state.group = value;
28027
+ if (clear) {
28028
+ this.groups = null;
28029
+ this.grid.resetGroupsState();
28030
+ this.skip = 0;
28031
+ }
28032
+ }
28033
+ groups;
28034
+ gridSubs = new Subscription();
28035
+ constructor(changeDetector, localDataChangesService, ctxService, groupsService) {
28036
+ super(ctxService.grid, changeDetector, localDataChangesService, null, ctxService);
28037
+ this.groupsService = groupsService;
28038
+ ctxService.dataBindingDirective = this;
28039
+ }
28040
+ ngOnInit() {
28041
+ super.ngOnInit();
28042
+ this.gridSubs.add(this.grid.groupExpand.subscribe(this.groupExpand.bind(this)));
28043
+ this.gridSubs.add(this.grid.groupCollapse.subscribe(this.groupCollapse.bind(this)));
28044
+ }
28045
+ ngAfterContentInit() {
28046
+ if (isDevMode() && this.grid.isGroupExpanded) {
28047
+ throw new Error(GridConfigurationErrorMessages.groupBindingDirectives);
28048
+ }
28049
+ }
28050
+ ngOnDestroy() {
28051
+ this.gridSubs.unsubscribe();
28052
+ }
28053
+ /**
28054
+ * @hidden
28055
+ */
28056
+ toggleAll(expand) {
28057
+ this.skip = 0;
28058
+ this.grid.scrollTo({ row: 0, column: 0 });
28059
+ this.groups.forEach((gr, idx) => {
28060
+ const expanded = this.groupsService.isExpanded({
28061
+ group: gr,
28062
+ groupIndex: idx.toString(),
28063
+ parentGroup: undefined
28064
+ });
28065
+ const performToggle = (expand && !expanded) || (!expand && expanded);
28066
+ if (performToggle) {
28067
+ this.grid.groupsService.toggleRow({
28068
+ type: 'group',
28069
+ data: gr,
28070
+ index: idx.toString(),
28071
+ level: 0,
28072
+ parentGroup: undefined
28073
+ });
28074
+ this[expand ? 'groupExpand' : 'groupCollapse']({ groupIndex: idx.toString() });
28075
+ }
28076
+ });
28077
+ }
28078
+ /**
28079
+ * Collapses all expanded root level groups.
28080
+ */
28081
+ collapseAll() {
28082
+ this.toggleAll(false);
28083
+ }
28084
+ /**
28085
+ * Expands all expanded root level groups.
28086
+ */
28087
+ expandAll() {
28088
+ this.toggleAll(true);
28089
+ }
28090
+ /**
28091
+ * @hidden
28092
+ */
28093
+ groupExpand({ groupIndex }) {
28094
+ const { group, parents } = findGroup(groupIndex, this.groups);
28095
+ if (!group) {
28096
+ return;
28097
+ }
28098
+ this.groupsService.expandChildren(groupIndex);
28099
+ if (!group.items.length) {
28100
+ const descriptors = this.state.group.filter(removeParentDescriptors(parents, group));
28101
+ const children = findChildren(this.originalData, parents.concat(group));
28102
+ group.items = processGroups(children, {
28103
+ filter: this.state.filter,
28104
+ group: descriptors,
28105
+ sort: this.state.sort
28106
+ });
28107
+ }
28108
+ this.grid.data = this.dataResult(this.state.skip, this.state.take);
28109
+ }
28110
+ /**
28111
+ * @hidden
28112
+ */
28113
+ groupCollapse({ groupIndex }) {
28114
+ const { group } = findGroup(groupIndex, this.groups);
28115
+ if (group) {
28116
+ group.items = [];
28117
+ }
28118
+ else {
28119
+ return;
28120
+ }
28121
+ this.grid.data = this.dataResult(this.state.skip, this.state.take);
28122
+ }
28123
+ process(state) {
28124
+ if (state.group && state.group.length) {
28125
+ const groups = this.processGroups(state);
28126
+ this.grid.skip -= skippedHeaders(groups.data[0]);
28127
+ return groups;
28128
+ }
28129
+ else {
28130
+ this.groups = null;
28131
+ }
28132
+ return super.process(state);
28133
+ }
28134
+ processGroups(state) {
28135
+ if (!this.groups || !this.groups.length) {
28136
+ this.groups = processGroups(this.originalData, {
28137
+ filter: state.filter,
28138
+ group: state.group,
28139
+ sort: state.sort
28140
+ });
28141
+ }
28142
+ return this.dataResult(state.skip, state.take);
28143
+ }
28144
+ dataResult(skip, take) {
28145
+ const includeFooters = this.grid.showGroupFooters;
28146
+ return {
28147
+ data: slice(this.groups, skip, take, includeFooters),
28148
+ total: count(this.groups, includeFooters)
28149
+ };
28150
+ }
28151
+ applyState({ skip, take, sort, group, filter }) {
28152
+ this.skip = skip;
28153
+ this.state.take = take;
28154
+ // this.pageSize = take; // do need to update take as the process with slice correctly
28155
+ this.sort = sort;
28156
+ this.group = group;
28157
+ this.filter = filter;
28158
+ }
28159
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupBindingDirective, deps: [{ token: i0.ChangeDetectorRef }, { token: LocalDataChangesService }, { token: ContextService }, { token: GroupsService }], target: i0.ɵɵFactoryTarget.Directive });
28160
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupBindingDirective, isStandalone: true, selector: "[kendoGridGroupBinding]", inputs: { kendoGridGroupBinding: "kendoGridGroupBinding", sort: "sort", filter: "filter", group: "group" }, exportAs: ["kendoGridGroupBinding"], usesInheritance: true, ngImport: i0 });
28161
+ }
28162
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupBindingDirective, decorators: [{
28163
+ type: Directive,
28164
+ args: [{
28165
+ selector: '[kendoGridGroupBinding]',
28166
+ exportAs: 'kendoGridGroupBinding',
28167
+ standalone: true
28168
+ }]
28169
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: LocalDataChangesService }, { type: ContextService }, { type: GroupsService }]; }, propDecorators: { kendoGridGroupBinding: [{
28170
+ type: Input,
28171
+ args: ["kendoGridGroupBinding"]
28172
+ }], sort: [{
28173
+ type: Input
28174
+ }], filter: [{
28175
+ type: Input
28176
+ }], group: [{
28177
+ type: Input
28178
+ }] } });
28179
+
27569
28180
  const createControl = (source) => (acc, key) => {
27570
28181
  acc[key] = new FormControl(source[key]);
27571
28182
  return acc;
@@ -27644,9 +28255,9 @@ class GridComponent {
27644
28255
  localization;
27645
28256
  ctx;
27646
28257
  sizingService;
27647
- adaptiveService;
27648
28258
  adaptiveGridService;
27649
28259
  rowReorderService;
28260
+ dataMappingService;
27650
28261
  /**
27651
28262
  * Sets the data of the Grid. If you provide an array, the Grid gets the total count automatically.
27652
28263
  * ([more information and example]({% slug binding_grid %})).
@@ -28358,10 +28969,8 @@ class GridComponent {
28358
28969
  dragTargetContainer;
28359
28970
  dropTargetContainer;
28360
28971
  dialogContainer;
28361
- /**
28362
- * @hidden
28363
- */
28364
28972
  adaptiveRenderer;
28973
+ listComponent;
28365
28974
  get scrollbarWidth() {
28366
28975
  return this.supportService.scrollbarWidth;
28367
28976
  }
@@ -28557,6 +29166,7 @@ class GridComponent {
28557
29166
  */
28558
29167
  blockArrowSelection = false;
28559
29168
  undoRedoService;
29169
+ rowsToRender;
28560
29170
  selectionSubscription;
28561
29171
  stateChangeSubscription;
28562
29172
  groupExpandCollapseSubscription;
@@ -28582,7 +29192,7 @@ class GridComponent {
28582
29192
  rowReorderSubscription;
28583
29193
  rtl = false;
28584
29194
  _rowSticky;
28585
- constructor(supportService, selectionService, cellSelectionService, wrapper, groupInfoService, groupsService, changeNotification, detailsService, editService, filterService, pdfService, responsiveService, renderer, excelService, ngZone, scrollSyncService, domEvents, columnResizingService, changeDetectorRef, columnReorderService, columnInfoService, navigationService, sortService, scrollRequestService, localization, ctx, sizingService, adaptiveService, adaptiveGridService, rowReorderService) {
29195
+ constructor(supportService, selectionService, cellSelectionService, wrapper, groupInfoService, groupsService, changeNotification, detailsService, editService, filterService, pdfService, responsiveService, renderer, excelService, ngZone, scrollSyncService, domEvents, columnResizingService, changeDetectorRef, columnReorderService, columnInfoService, navigationService, sortService, scrollRequestService, localization, ctx, sizingService, adaptiveGridService, rowReorderService, dataMappingService) {
28586
29196
  this.supportService = supportService;
28587
29197
  this.selectionService = selectionService;
28588
29198
  this.cellSelectionService = cellSelectionService;
@@ -28610,9 +29220,9 @@ class GridComponent {
28610
29220
  this.localization = localization;
28611
29221
  this.ctx = ctx;
28612
29222
  this.sizingService = sizingService;
28613
- this.adaptiveService = adaptiveService;
28614
29223
  this.adaptiveGridService = adaptiveGridService;
28615
29224
  this.rowReorderService = rowReorderService;
29225
+ this.dataMappingService = dataMappingService;
28616
29226
  const isValid = validatePackage(packageMetadata);
28617
29227
  this.showLicenseWatermark = shouldShowValidationUI(isValid);
28618
29228
  this.ctx.grid = this;
@@ -28719,6 +29329,11 @@ class GridComponent {
28719
29329
  this.initSelectionService();
28720
29330
  this.updateNavigationMetadata();
28721
29331
  }
29332
+ ngDoCheck() {
29333
+ if (!this.isScrollable) {
29334
+ this.rowsToRender = this.dataMappingService.dataMapper(this.view, this.nonLockedLeafColumns, this.lockedLeafColumns, this.detailTemplate, this.showGroupFooters);
29335
+ }
29336
+ }
28722
29337
  ngOnChanges(changes) {
28723
29338
  if (isChanged$1("data", changes)) {
28724
29339
  this.onDataChange();
@@ -29040,12 +29655,12 @@ class GridComponent {
29040
29655
  this.sort = state.sort;
29041
29656
  this.group = state.group;
29042
29657
  this.filter = state.filter;
29043
- this.group = state.group;
29044
29658
  this.skip = state.skip;
29045
29659
  this.pageSize = state.take;
29046
- this.data = state.currentData;
29047
- this.changeNotification.notify();
29048
- this.changeDetectorRef.detectChanges();
29660
+ if (state.currentData) {
29661
+ this.data = state.currentData;
29662
+ }
29663
+ this.changeDetectorRef.markForCheck();
29049
29664
  }
29050
29665
  traverseColumns(columns, callback) {
29051
29666
  columns.forEach((column) => {
@@ -29256,6 +29871,9 @@ class GridComponent {
29256
29871
  source.locked = target.locked;
29257
29872
  }
29258
29873
  this.columnsContainer.refresh();
29874
+ if (this.virtualColumns) {
29875
+ this.listComponent.updateViewportColumns();
29876
+ }
29259
29877
  this.changeDetectorRef.markForCheck();
29260
29878
  });
29261
29879
  }
@@ -29414,10 +30032,7 @@ class GridComponent {
29414
30032
  if (this.columnList.filter(x => x.locked && x.parent && !x.parent.isLocked).length) {
29415
30033
  throw new Error(ColumnConfigurationErrorMessages.lockedParent);
29416
30034
  }
29417
- if ((this.rowHeight || this.detailRowHeight) && !this.isVirtual) {
29418
- console.warn(GridConfigurationErrorMessages.rowHeightVirtual);
29419
- }
29420
- if (!this.rowHeight && this.isVirtual) {
30035
+ if (this.detailRowHeight && !this.isVirtual) {
29421
30036
  console.warn(GridConfigurationErrorMessages.rowHeightVirtual);
29422
30037
  }
29423
30038
  if (!this.detailRowHeight && this.isVirtual && this.detailTemplate) {
@@ -29464,9 +30079,6 @@ class GridComponent {
29464
30079
  }
29465
30080
  this.dataStateChange.emit(x);
29466
30081
  hasObservers(this.gridStateChange) && this.gridStateChange.emit({ ...this.currentState, ...x });
29467
- if (this.undoRedoService) {
29468
- this.undoRedoService.originalEvent = x;
29469
- }
29470
30082
  });
29471
30083
  this.stateChangeSubscription.add(merge(this.columnReorder, this.columnResize, this.columnVisibilityChange, this.columnLockedChange, this.columnStickyChange).pipe(flatMap(() => this.ngZone.onStable.pipe(take(1))))
29472
30084
  .subscribe(() => this.ngZone.run(() => hasObservers(this.gridStateChange) && this.gridStateChange.emit(this.currentState))));
@@ -29684,7 +30296,8 @@ class GridComponent {
29684
30296
  column = toAdd.shift();
29685
30297
  viewportColumns.push(column);
29686
30298
  if (column.isColumnGroup) {
29687
- toAdd.unshift(...column.childrenArray);
30299
+ const children = columnsArray.filter(c => c.parent && c.parent.id === column.id);
30300
+ toAdd.unshift(...children);
29688
30301
  }
29689
30302
  }
29690
30303
  const lastFromGroup = viewportColumns[viewportColumns.length - 1];
@@ -29740,8 +30353,8 @@ class GridComponent {
29740
30353
  }
29741
30354
  if (this.groupsService.isExpanded({ groupIndex: index }) !== expand) {
29742
30355
  this.groupsService.toggleRow({ index }, false);
29743
- if (this.ctx.groupBindingDirective) {
29744
- this.ctx.groupBindingDirective[`group${expand ? 'Expand' : 'Collapse'}`]({ groupIndex: index });
30356
+ if (this.ctx.dataBindingDirective && this.ctx.dataBindingDirective instanceof GroupBindingDirective) {
30357
+ this.ctx.dataBindingDirective[`group${expand ? 'Expand' : 'Collapse'}`]({ groupIndex: index });
29745
30358
  }
29746
30359
  }
29747
30360
  }
@@ -29762,7 +30375,7 @@ class GridComponent {
29762
30375
  this.dragTargetContainer?.notify();
29763
30376
  this.dropTargetContainer?.notify();
29764
30377
  }
29765
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GridComponent, deps: [{ token: BrowserSupportService }, { token: SelectionService }, { token: CellSelectionService }, { token: i0.ElementRef }, { token: GroupInfoService }, { token: GroupsService }, { token: ChangeNotificationService }, { token: DetailsService }, { token: EditService }, { token: FilterService }, { token: PDFService }, { token: ResponsiveService }, { token: i0.Renderer2 }, { token: ExcelService }, { token: i0.NgZone }, { token: ScrollSyncService }, { token: DomEventsService }, { token: ColumnResizingService }, { token: i0.ChangeDetectorRef }, { token: ColumnReorderService }, { token: ColumnInfoService }, { token: NavigationService }, { token: SortService }, { token: ScrollRequestService }, { token: i1$2.LocalizationService }, { token: ContextService }, { token: SizingOptionsService }, { token: i2$1.AdaptiveService }, { token: AdaptiveGridService }, { token: RowReorderService }], target: i0.ɵɵFactoryTarget.Component });
30378
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GridComponent, deps: [{ token: BrowserSupportService }, { token: SelectionService }, { token: CellSelectionService }, { token: i0.ElementRef }, { token: GroupInfoService }, { token: GroupsService }, { token: ChangeNotificationService }, { token: DetailsService }, { token: EditService }, { token: FilterService }, { token: PDFService }, { token: ResponsiveService }, { token: i0.Renderer2 }, { token: ExcelService }, { token: i0.NgZone }, { token: ScrollSyncService }, { token: DomEventsService }, { token: ColumnResizingService }, { token: i0.ChangeDetectorRef }, { token: ColumnReorderService }, { token: ColumnInfoService }, { token: NavigationService }, { token: SortService }, { token: ScrollRequestService }, { token: i1$2.LocalizationService }, { token: ContextService }, { token: SizingOptionsService }, { token: AdaptiveGridService }, { token: RowReorderService }, { token: DataMappingService }], target: i0.ɵɵFactoryTarget.Component });
29766
30379
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: GridComponent, isStandalone: true, selector: "kendo-grid", inputs: { data: "data", pageSize: "pageSize", height: "height", rowHeight: "rowHeight", adaptiveMode: "adaptiveMode", detailRowHeight: "detailRowHeight", skip: "skip", scrollable: "scrollable", selectable: "selectable", sort: "sort", size: "size", trackBy: "trackBy", filter: "filter", group: "group", virtualColumns: "virtualColumns", filterable: "filterable", sortable: "sortable", pageable: "pageable", groupable: "groupable", gridResizable: "gridResizable", rowReorderable: "rowReorderable", navigable: "navigable", autoSize: "autoSize", rowClass: "rowClass", rowSticky: "rowSticky", rowSelected: "rowSelected", isRowSelectable: "isRowSelectable", cellSelected: "cellSelected", resizable: "resizable", reorderable: "reorderable", loading: "loading", columnMenu: "columnMenu", hideHeader: "hideHeader", showInactiveTools: "showInactiveTools", isDetailExpanded: "isDetailExpanded", isGroupExpanded: "isGroupExpanded" }, outputs: { filterChange: "filterChange", pageChange: "pageChange", groupChange: "groupChange", sortChange: "sortChange", selectionChange: "selectionChange", rowReorder: "rowReorder", dataStateChange: "dataStateChange", gridStateChange: "gridStateChange", groupExpand: "groupExpand", groupCollapse: "groupCollapse", detailExpand: "detailExpand", detailCollapse: "detailCollapse", edit: "edit", cancel: "cancel", save: "save", remove: "remove", add: "add", cellClose: "cellClose", cellClick: "cellClick", pdfExport: "pdfExport", excelExport: "excelExport", columnResize: "columnResize", columnReorder: "columnReorder", columnVisibilityChange: "columnVisibilityChange", columnLockedChange: "columnLockedChange", columnStickyChange: "columnStickyChange", scrollBottom: "scrollBottom", contentScroll: "contentScroll" }, host: { properties: { "attr.dir": "this.dir", "class.k-grid": "this.hostClass", "class.k-grid-sm": "this.sizeSmallClass", "class.k-grid-md": "this.sizeMediumClass", "class.k-grid-lockedcolumns": "this.lockedClasses", "class.k-grid-virtual": "this.virtualClasses", "class.k-grid-no-scrollbar": "this.noScrollbarClass", "class.k-grid-resizable": "this.isResizable", "style.minWidth": "this.minWidth", "style.maxWidth": "this.maxWidth", "style.minHeight": "this.minHeight", "style.maxHeight": "this.maxHeight" } }, providers: [
29767
30380
  BrowserSupportService,
29768
30381
  LocalizationService,
@@ -29812,8 +30425,9 @@ class GridComponent {
29812
30425
  RowspanService,
29813
30426
  AdaptiveGridService,
29814
30427
  ColumnMenuService,
29815
- MenuTabbingService
29816
- ], queries: [{ propertyName: "columns", predicate: ColumnBase }, { propertyName: "detailTemplateChildren", predicate: DetailTemplateDirective }, { propertyName: "cellLoadingTemplateChildren", predicate: CellLoadingTemplateDirective }, { propertyName: "loadingTemplateChildren", predicate: LoadingTemplateDirective }, { propertyName: "statusBarTemplateChildren", predicate: StatusBarTemplateDirective }, { propertyName: "noRecordsTemplateChildren", predicate: NoRecordsTemplateDirective }, { propertyName: "pagerTemplateChildren", predicate: PagerTemplateDirective }, { propertyName: "toolbarTemplateChildren", predicate: ToolbarTemplateDirective }, { propertyName: "columnMenuTemplates", predicate: ColumnMenuTemplateDirective }], viewQueries: [{ propertyName: "lockedHeader", first: true, predicate: ["lockedHeader"], descendants: true }, { propertyName: "header", first: true, predicate: ["header"], descendants: true }, { propertyName: "ariaRoot", first: true, predicate: ["ariaRoot"], descendants: true, static: true }, { propertyName: "dragTargetContainer", first: true, predicate: DragTargetContainerDirective, descendants: true }, { propertyName: "dropTargetContainer", first: true, predicate: DropTargetContainerDirective, descendants: true }, { propertyName: "dialogContainer", first: true, predicate: ["dialogContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "adaptiveRenderer", first: true, predicate: AdaptiveRendererComponent, descendants: true }, { propertyName: "footer", predicate: ["footer"], descendants: true }], exportAs: ["kendoGrid"], usesOnChanges: true, ngImport: i0, template: `
30428
+ MenuTabbingService,
30429
+ DataMappingService
30430
+ ], queries: [{ propertyName: "columns", predicate: ColumnBase }, { propertyName: "detailTemplateChildren", predicate: DetailTemplateDirective }, { propertyName: "cellLoadingTemplateChildren", predicate: CellLoadingTemplateDirective }, { propertyName: "loadingTemplateChildren", predicate: LoadingTemplateDirective }, { propertyName: "statusBarTemplateChildren", predicate: StatusBarTemplateDirective }, { propertyName: "noRecordsTemplateChildren", predicate: NoRecordsTemplateDirective }, { propertyName: "pagerTemplateChildren", predicate: PagerTemplateDirective }, { propertyName: "toolbarTemplateChildren", predicate: ToolbarTemplateDirective }, { propertyName: "columnMenuTemplates", predicate: ColumnMenuTemplateDirective }], viewQueries: [{ propertyName: "lockedHeader", first: true, predicate: ["lockedHeader"], descendants: true }, { propertyName: "header", first: true, predicate: ["header"], descendants: true }, { propertyName: "ariaRoot", first: true, predicate: ["ariaRoot"], descendants: true, static: true }, { propertyName: "dragTargetContainer", first: true, predicate: DragTargetContainerDirective, descendants: true }, { propertyName: "dropTargetContainer", first: true, predicate: DropTargetContainerDirective, descendants: true }, { propertyName: "dialogContainer", first: true, predicate: ["dialogContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "adaptiveRenderer", first: true, predicate: AdaptiveRendererComponent, descendants: true }, { propertyName: "listComponent", first: true, predicate: ListComponent, descendants: true }, { propertyName: "footer", predicate: ["footer"], descendants: true }], exportAs: ["kendoGrid"], usesOnChanges: true, ngImport: i0, template: `
29817
30431
  <ng-container kendoGridLocalizedMessages
29818
30432
  i18n-groupPanelEmpty="kendo.grid.groupPanelEmpty|The label visible in the Grid group panel when it is empty"
29819
30433
  groupPanelEmpty="Drag a column header and drop it here to group by that column"
@@ -30464,7 +31078,7 @@ class GridComponent {
30464
31078
  <tbody kendoGridTableBody
30465
31079
  [isLoading]="loading"
30466
31080
  [groups]="group"
30467
- [data]="$any(view)"
31081
+ [rowsToRender]="rowsToRender"
30468
31082
  [skip]="skip"
30469
31083
  [columns]="$any(leafColumns)"
30470
31084
  [totalColumnsCount]="leafColumns.length"
@@ -30473,7 +31087,6 @@ class GridComponent {
30473
31087
  [filterable]="filterable"
30474
31088
  [noRecordsTemplate]="noRecordsTemplate"
30475
31089
  [detailTemplate]="detailTemplate"
30476
- [showGroupFooters]="showGroupFooters"
30477
31090
  [trackBy]="trackBy"
30478
31091
  [rowClass]="rowClass"
30479
31092
  kendoDraggable
@@ -30580,7 +31193,7 @@ class GridComponent {
30580
31193
  <kendo-grid-adaptive-renderer *ngIf="isAdaptiveModeEnabled"></kendo-grid-adaptive-renderer>
30581
31194
 
30582
31195
  <div kendoWatermarkOverlay *ngIf="showLicenseWatermark"></div>
30583
- `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoGridLocalizedMessages]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ToolbarComponent, selector: "kendo-grid-toolbar", inputs: ["position", "size", "navigable"] }, { kind: "component", type: GroupPanelComponent, selector: "kendo-grid-group-panel", inputs: ["text", "navigable", "groups"], outputs: ["change"] }, { kind: "directive", type: TableDirective, selector: "[kendoGridResizableTable]", inputs: ["locked", "virtualColumns"] }, { kind: "directive", type: GridTableDirective, selector: "[kendoGridTable]", inputs: ["size"] }, { kind: "component", type: ColGroupComponent, selector: "[kendoGridColGroup]", inputs: ["columns", "groups", "detailTemplate", "sort"] }, { kind: "component", type: HeaderComponent, selector: "[kendoGridHeader]", inputs: ["totalColumnLevels", "columns", "groups", "detailTemplate", "scrollable", "filterable", "sort", "filter", "sortable", "groupable", "lockedColumnsCount", "resizable", "reorderable", "columnMenu", "columnMenuTemplate", "totalColumnsCount", "totalColumns", "tabIndex", "size"] }, { kind: "directive", type: ResizableContainerDirective, selector: "[kendoGridResizableContainer]", inputs: ["lockedWidth", "kendoGridResizableContainer"] }, { kind: "component", type: ListComponent, selector: "kendo-grid-list", inputs: ["data", "groups", "total", "rowHeight", "stickyRowHeight", "detailRowHeight", "take", "skip", "columns", "detailTemplate", "noRecordsTemplate", "selectable", "groupable", "filterable", "rowClass", "rowSticky", "loading", "trackBy", "virtualColumns", "isVirtual", "cellLoadingTemplate", "loadingTemplate", "sort", "size"], outputs: ["contentScroll", "pageChange", "scrollBottom"] }, { kind: "directive", type: DragTargetContainerDirective, selector: "[kendoDragTargetContainer]", inputs: ["hint", "dragTargetFilter", "dragHandle", "dragDelay", "threshold", "dragTargetId", "dragData", "dragDisabled", "mode", "cursorStyle", "hintContext"], outputs: ["onDragReady", "onPress", "onDragStart", "onDrag", "onRelease", "onDragEnd"], exportAs: ["kendoDragTargetContainer"] }, { kind: "directive", type: DropTargetContainerDirective, selector: "[kendoDropTargetContainer]", inputs: ["dropTargetFilter", "dropDisabled"], outputs: ["onDragEnter", "onDragOver", "onDragLeave", "onDrop"], exportAs: ["kendoDropTargetContainer"] }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["enableDrag"], outputs: ["kendoPress", "kendoDrag", "kendoRelease"] }, { kind: "directive", type: GridMarqueeDirective, selector: "[kendoGridSelectionMarquee]" }, { kind: "component", type: FooterComponent, selector: "[kendoGridFooter]", inputs: ["columns", "groups", "detailTemplate", "scrollable", "lockedColumnsCount", "logicalRowIndex", "totalColumns", "totalColumnsCount"] }, { kind: "component", type: TableBodyComponent, selector: "[kendoGridTableBody]", inputs: ["columns", "allColumns", "groups", "detailTemplate", "noRecordsTemplate", "data", "skip", "selectable", "filterable", "noRecordsText", "isLocked", "isLoading", "isVirtual", "cellLoadingTemplate", "skipGroupDecoration", "showGroupFooters", "lockedColumnsCount", "totalColumnsCount", "virtualColumns", "trackBy", "rowSticky", "totalColumns", "rowClass"] }, { kind: "component", type: LoadingComponent, selector: "[kendoGridLoading]", inputs: ["loadingTemplate"] }, { kind: "component", type: StatusBarComponent, selector: "kendo-grid-status-bar", inputs: ["statusBarTemplate"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: WatermarkOverlayComponent, selector: "div[kendoWatermarkOverlay]" }, { kind: "component", type: i51.CustomMessagesComponent, selector: "kendo-datapager-messages, kendo-pager-messages" }, { kind: "component", type: i51.PagerInfoComponent, selector: "kendo-datapager-info, kendo-pager-info" }, { kind: "component", type: i51.PagerInputComponent, selector: "kendo-datapager-input, kendo-pager-input", inputs: ["showPageText", "size"] }, { kind: "component", type: i51.PagerNextButtonsComponent, selector: "kendo-datapager-next-buttons, kendo-pager-next-buttons", inputs: ["size"] }, { kind: "component", type: i51.PagerNumericButtonsComponent, selector: "kendo-datapager-numeric-buttons, kendo-pager-numeric-buttons", inputs: ["buttonCount", "size"] }, { kind: "component", type: i51.PagerPageSizesComponent, selector: "kendo-datapager-page-sizes, kendo-pager-page-sizes", inputs: ["showItemsText", "pageSizes", "size", "adaptiveMode"] }, { kind: "component", type: i51.PagerPrevButtonsComponent, selector: "kendo-datapager-prev-buttons, kendo-pager-prev-buttons", inputs: ["size"] }, { kind: "directive", type: i51.PagerTemplateDirective, selector: "[kendoDataPagerTemplate], [kendoPagerTemplate]" }, { kind: "component", type: i51.PagerComponent, selector: "kendo-datapager, kendo-pager", inputs: ["externalTemplate", "total", "skip", "pageSize", "buttonCount", "info", "type", "pageSizeValues", "previousNext", "navigable", "size", "responsive", "adaptiveMode"], outputs: ["pageChange", "pageSizeChange", "pagerInputVisibilityChange", "pageTextVisibilityChange", "itemsTextVisibilityChange"], exportAs: ["kendoDataPager", "kendoPager"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AdaptiveRendererComponent, selector: "kendo-grid-adaptive-renderer" }], encapsulation: i0.ViewEncapsulation.None });
31196
+ `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoGridLocalizedMessages]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ToolbarComponent, selector: "kendo-grid-toolbar", inputs: ["position", "size", "navigable"] }, { kind: "component", type: GroupPanelComponent, selector: "kendo-grid-group-panel", inputs: ["text", "navigable", "groups"], outputs: ["change"] }, { kind: "directive", type: TableDirective, selector: "[kendoGridResizableTable]", inputs: ["locked", "virtualColumns"] }, { kind: "directive", type: GridTableDirective, selector: "[kendoGridTable]", inputs: ["size"] }, { kind: "component", type: ColGroupComponent, selector: "[kendoGridColGroup]", inputs: ["columns", "groups", "detailTemplate", "sort"] }, { kind: "component", type: HeaderComponent, selector: "[kendoGridHeader]", inputs: ["totalColumnLevels", "columns", "groups", "detailTemplate", "scrollable", "filterable", "sort", "filter", "sortable", "groupable", "lockedColumnsCount", "resizable", "reorderable", "columnMenu", "columnMenuTemplate", "totalColumnsCount", "totalColumns", "tabIndex", "size"] }, { kind: "directive", type: ResizableContainerDirective, selector: "[kendoGridResizableContainer]", inputs: ["lockedWidth", "kendoGridResizableContainer"] }, { kind: "component", type: ListComponent, selector: "kendo-grid-list", inputs: ["data", "groups", "total", "rowHeight", "detailRowHeight", "take", "skip", "columns", "detailTemplate", "noRecordsTemplate", "selectable", "groupable", "filterable", "rowClass", "rowSticky", "loading", "trackBy", "virtualColumns", "isVirtual", "cellLoadingTemplate", "loadingTemplate", "sort", "size"], outputs: ["contentScroll", "pageChange", "scrollBottom"] }, { kind: "directive", type: DragTargetContainerDirective, selector: "[kendoDragTargetContainer]", inputs: ["hint", "dragTargetFilter", "dragHandle", "dragDelay", "threshold", "dragTargetId", "dragData", "dragDisabled", "mode", "cursorStyle", "hintContext"], outputs: ["onDragReady", "onPress", "onDragStart", "onDrag", "onRelease", "onDragEnd"], exportAs: ["kendoDragTargetContainer"] }, { kind: "directive", type: DropTargetContainerDirective, selector: "[kendoDropTargetContainer]", inputs: ["dropTargetFilter", "dropDisabled"], outputs: ["onDragEnter", "onDragOver", "onDragLeave", "onDrop"], exportAs: ["kendoDropTargetContainer"] }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["enableDrag"], outputs: ["kendoPress", "kendoDrag", "kendoRelease"] }, { kind: "directive", type: GridMarqueeDirective, selector: "[kendoGridSelectionMarquee]" }, { kind: "component", type: FooterComponent, selector: "[kendoGridFooter]", inputs: ["columns", "groups", "detailTemplate", "scrollable", "lockedColumnsCount", "logicalRowIndex", "totalColumns", "totalColumnsCount"] }, { kind: "component", type: TableBodyComponent, selector: "[kendoGridTableBody]", inputs: ["columns", "allColumns", "groups", "detailTemplate", "noRecordsTemplate", "rowsToRender", "skip", "selectable", "filterable", "noRecordsText", "isLocked", "isLoading", "isVirtual", "cellLoadingTemplate", "skipGroupDecoration", "lockedColumnsCount", "totalColumnsCount", "virtualColumns", "trackBy", "rowSticky", "totalColumns", "rowClass"] }, { kind: "component", type: LoadingComponent, selector: "[kendoGridLoading]", inputs: ["loadingTemplate"] }, { kind: "component", type: StatusBarComponent, selector: "kendo-grid-status-bar", inputs: ["statusBarTemplate"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: WatermarkOverlayComponent, selector: "div[kendoWatermarkOverlay]" }, { kind: "component", type: i51.CustomMessagesComponent, selector: "kendo-datapager-messages, kendo-pager-messages" }, { kind: "component", type: i51.PagerInfoComponent, selector: "kendo-datapager-info, kendo-pager-info" }, { kind: "component", type: i51.PagerInputComponent, selector: "kendo-datapager-input, kendo-pager-input", inputs: ["showPageText", "size"] }, { kind: "component", type: i51.PagerNextButtonsComponent, selector: "kendo-datapager-next-buttons, kendo-pager-next-buttons", inputs: ["size"] }, { kind: "component", type: i51.PagerNumericButtonsComponent, selector: "kendo-datapager-numeric-buttons, kendo-pager-numeric-buttons", inputs: ["buttonCount", "size"] }, { kind: "component", type: i51.PagerPageSizesComponent, selector: "kendo-datapager-page-sizes, kendo-pager-page-sizes", inputs: ["showItemsText", "pageSizes", "size", "adaptiveMode"] }, { kind: "component", type: i51.PagerPrevButtonsComponent, selector: "kendo-datapager-prev-buttons, kendo-pager-prev-buttons", inputs: ["size"] }, { kind: "directive", type: i51.PagerTemplateDirective, selector: "[kendoDataPagerTemplate], [kendoPagerTemplate]" }, { kind: "component", type: i51.PagerComponent, selector: "kendo-datapager, kendo-pager", inputs: ["externalTemplate", "total", "skip", "pageSize", "buttonCount", "info", "type", "pageSizeValues", "previousNext", "navigable", "size", "responsive", "adaptiveMode"], outputs: ["pageChange", "pageSizeChange", "pagerInputVisibilityChange", "pageTextVisibilityChange", "itemsTextVisibilityChange"], exportAs: ["kendoDataPager", "kendoPager"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AdaptiveRendererComponent, selector: "kendo-grid-adaptive-renderer" }], encapsulation: i0.ViewEncapsulation.None });
30584
31197
  }
30585
31198
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GridComponent, decorators: [{
30586
31199
  type: Component,
@@ -30636,7 +31249,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
30636
31249
  RowspanService,
30637
31250
  AdaptiveGridService,
30638
31251
  ColumnMenuService,
30639
- MenuTabbingService
31252
+ MenuTabbingService,
31253
+ DataMappingService
30640
31254
  ],
30641
31255
  selector: 'kendo-grid',
30642
31256
  template: `
@@ -31290,7 +31904,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
31290
31904
  <tbody kendoGridTableBody
31291
31905
  [isLoading]="loading"
31292
31906
  [groups]="group"
31293
- [data]="$any(view)"
31907
+ [rowsToRender]="rowsToRender"
31294
31908
  [skip]="skip"
31295
31909
  [columns]="$any(leafColumns)"
31296
31910
  [totalColumnsCount]="leafColumns.length"
@@ -31299,7 +31913,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
31299
31913
  [filterable]="filterable"
31300
31914
  [noRecordsTemplate]="noRecordsTemplate"
31301
31915
  [detailTemplate]="detailTemplate"
31302
- [showGroupFooters]="showGroupFooters"
31303
31916
  [trackBy]="trackBy"
31304
31917
  [rowClass]="rowClass"
31305
31918
  kendoDraggable
@@ -31416,7 +32029,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
31416
32029
  IconWrapperComponent, WatermarkOverlayComponent, ...KENDO_PAGER, NgTemplateOutlet, AdaptiveRendererComponent
31417
32030
  ]
31418
32031
  }]
31419
- }], ctorParameters: function () { return [{ type: BrowserSupportService }, { type: SelectionService }, { type: CellSelectionService }, { type: i0.ElementRef }, { type: GroupInfoService }, { type: GroupsService }, { type: ChangeNotificationService }, { type: DetailsService }, { type: EditService }, { type: FilterService }, { type: PDFService }, { type: ResponsiveService }, { type: i0.Renderer2 }, { type: ExcelService }, { type: i0.NgZone }, { type: ScrollSyncService }, { type: DomEventsService }, { type: ColumnResizingService }, { type: i0.ChangeDetectorRef }, { type: ColumnReorderService }, { type: ColumnInfoService }, { type: NavigationService }, { type: SortService }, { type: ScrollRequestService }, { type: i1$2.LocalizationService }, { type: ContextService }, { type: SizingOptionsService }, { type: i2$1.AdaptiveService }, { type: AdaptiveGridService }, { type: RowReorderService }]; }, propDecorators: { data: [{
32032
+ }], ctorParameters: function () { return [{ type: BrowserSupportService }, { type: SelectionService }, { type: CellSelectionService }, { type: i0.ElementRef }, { type: GroupInfoService }, { type: GroupsService }, { type: ChangeNotificationService }, { type: DetailsService }, { type: EditService }, { type: FilterService }, { type: PDFService }, { type: ResponsiveService }, { type: i0.Renderer2 }, { type: ExcelService }, { type: i0.NgZone }, { type: ScrollSyncService }, { type: DomEventsService }, { type: ColumnResizingService }, { type: i0.ChangeDetectorRef }, { type: ColumnReorderService }, { type: ColumnInfoService }, { type: NavigationService }, { type: SortService }, { type: ScrollRequestService }, { type: i1$2.LocalizationService }, { type: ContextService }, { type: SizingOptionsService }, { type: AdaptiveGridService }, { type: RowReorderService }, { type: DataMappingService }]; }, propDecorators: { data: [{
31420
32033
  type: Input
31421
32034
  }], pageSize: [{
31422
32035
  type: Input
@@ -31631,6 +32244,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
31631
32244
  }], adaptiveRenderer: [{
31632
32245
  type: ViewChild,
31633
32246
  args: [AdaptiveRendererComponent]
32247
+ }], listComponent: [{
32248
+ type: ViewChild,
32249
+ args: [ListComponent]
31634
32250
  }] } });
31635
32251
 
31636
32252
  /**
@@ -31679,207 +32295,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
31679
32295
  }]
31680
32296
  }], ctorParameters: function () { return [{ type: i1$2.LocalizationService }]; } });
31681
32297
 
31682
- /**
31683
- * A directive that handles in-memory data operations like [paging]({% slug paging_grid %}),
31684
- * [sorting]({% slug sorting_grid %}), and [grouping]({% slug grouping_grid %}).
31685
- *
31686
- * Use this directive with local data and enable the Grid data operations with minimal configuration.
31687
- * ([More information and examples]({% slug local_data_grid %}#toc-using-the-data-binding-directive)).
31688
- *
31689
- * @example
31690
- * ```html
31691
- * <kendo-grid [kendoGridBinding]="gridData"></kendo-grid>
31692
- * ```
31693
- * @remarks
31694
- * Applied to: {@link GridComponent}.
31695
- */
31696
- class DataBindingDirective {
31697
- grid;
31698
- changeDetector;
31699
- localDataChangesService;
31700
- rowReorderService;
31701
- /**
31702
- * Sets the number of records to skip in the Grid.
31703
- *
31704
- * @default 0
31705
- */
31706
- set skip(value) {
31707
- if (!isPresent(value)) {
31708
- value = 0;
31709
- }
31710
- this.grid.skip = this.state.skip = value;
31711
- if (this.rowReorderService) {
31712
- this.rowReorderService.skip = value;
31713
- }
31714
- }
31715
- /**
31716
- * Sets the sort descriptors for the Grid data.
31717
- *
31718
- */
31719
- set sort(value) {
31720
- this.grid.sort = this.state.sort = value;
31721
- }
31722
- /**
31723
- * Sets the filter descriptor for the Grid data.
31724
- *
31725
- */
31726
- set filter(value) {
31727
- this.grid.filter = this.state.filter = value;
31728
- }
31729
- /**
31730
- * Sets the page size for the Grid pager.
31731
- *
31732
- */
31733
- set pageSize(value) {
31734
- this.grid.pageSize = this.state.take = value;
31735
- }
31736
- /**
31737
- * Sets the group descriptors for the Grid data.
31738
- *
31739
- */
31740
- set group(value) {
31741
- this.grid.group = this.state.group = value;
31742
- }
31743
- /**
31744
- * Sets the data array for the Grid.
31745
- *
31746
- */
31747
- set data(value) {
31748
- this.originalData = value || [];
31749
- if (this.localDataChangesService) {
31750
- this.localDataChangesService.data = value;
31751
- }
31752
- this.dataChanged = true;
31753
- }
31754
- state = {
31755
- skip: 0
31756
- };
31757
- originalData = [];
31758
- dataChanged;
31759
- stateChangeSubscription;
31760
- dataChangedSubscription;
31761
- rowReorderSubscription;
31762
- constructor(grid, changeDetector, localDataChangesService, rowReorderService) {
31763
- this.grid = grid;
31764
- this.changeDetector = changeDetector;
31765
- this.localDataChangesService = localDataChangesService;
31766
- this.rowReorderService = rowReorderService;
31767
- if (localDataChangesService) {
31768
- this.dataChangedSubscription = this.localDataChangesService.changes.subscribe(this.rebind.bind(this));
31769
- }
31770
- }
31771
- /**
31772
- * @hidden
31773
- */
31774
- ngOnInit() {
31775
- this.applyState(this.state);
31776
- this.stateChangeSubscription = this.grid
31777
- .dataStateChange
31778
- .subscribe(this.onStateChange.bind(this));
31779
- if (this.rowReorderService) {
31780
- this.rowReorderSubscription = this.grid
31781
- .rowReorder
31782
- .subscribe(this.onRowReorder.bind(this));
31783
- }
31784
- }
31785
- /**
31786
- * @hidden
31787
- */
31788
- ngOnDestroy() {
31789
- if (this.stateChangeSubscription) {
31790
- this.stateChangeSubscription.unsubscribe();
31791
- }
31792
- if (this.dataChangedSubscription) {
31793
- this.dataChangedSubscription.unsubscribe();
31794
- }
31795
- if (this.rowReorderSubscription) {
31796
- this.rowReorderSubscription.unsubscribe();
31797
- }
31798
- }
31799
- /**
31800
- * @hidden
31801
- */
31802
- ngOnChanges(changes) {
31803
- if (anyChanged(["pageSize", "skip", "sort", "group", "filter"], changes)) {
31804
- this.rebind();
31805
- }
31806
- }
31807
- ngDoCheck() {
31808
- if (this.dataChanged) {
31809
- this.updateGridData();
31810
- }
31811
- }
31812
- /**
31813
- * @hidden
31814
- */
31815
- onStateChange(state) {
31816
- this.applyState(state);
31817
- this.rebind();
31818
- }
31819
- /**
31820
- * @hidden
31821
- */
31822
- onRowReorder(ev) {
31823
- this.rowReorderService.reorderRows(ev, this.originalData);
31824
- this.rebind();
31825
- }
31826
- /**
31827
- * @hidden
31828
- */
31829
- rebind() {
31830
- this.data = this.originalData;
31831
- this.updateGridData();
31832
- this.notifyDataChange();
31833
- }
31834
- /**
31835
- * Notifies the Grid that its data has changed.
31836
- */
31837
- notifyDataChange() {
31838
- this.grid.onDataChange();
31839
- if (this.changeDetector) {
31840
- this.changeDetector.markForCheck();
31841
- }
31842
- }
31843
- process(state) {
31844
- return process(this.originalData, state);
31845
- }
31846
- applyState({ skip, take, sort, group, filter }) {
31847
- this.skip = skip;
31848
- this.pageSize = take;
31849
- this.sort = sort;
31850
- this.group = group;
31851
- this.filter = filter;
31852
- }
31853
- updateGridData() {
31854
- this.grid.data = this.process(this.state);
31855
- this.grid.updateNavigationMetadata();
31856
- this.dataChanged = false;
31857
- }
31858
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataBindingDirective, deps: [{ token: GridComponent }, { token: i0.ChangeDetectorRef }, { token: LocalDataChangesService }, { token: RowReorderService }], target: i0.ɵɵFactoryTarget.Directive });
31859
- 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 });
31860
- }
31861
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataBindingDirective, decorators: [{
31862
- type: Directive,
31863
- args: [{
31864
- selector: '[kendoGridBinding]',
31865
- exportAs: 'kendoGridBinding',
31866
- standalone: true
31867
- }]
31868
- }], ctorParameters: function () { return [{ type: GridComponent }, { type: i0.ChangeDetectorRef }, { type: LocalDataChangesService }, { type: RowReorderService }]; }, propDecorators: { skip: [{
31869
- type: Input
31870
- }], sort: [{
31871
- type: Input
31872
- }], filter: [{
31873
- type: Input
31874
- }], pageSize: [{
31875
- type: Input
31876
- }], group: [{
31877
- type: Input
31878
- }], data: [{
31879
- type: Input,
31880
- args: ["kendoGridBinding"]
31881
- }] } });
31882
-
31883
32298
  /**
31884
32299
  * Stores the row selection state of the Grid in memory
31885
32300
  * ([see example]({% slug selection_grid %}#toc-toggling-the-selection-functionality)).
@@ -32782,330 +33197,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
32782
33197
  type: Input
32783
33198
  }] } });
32784
33199
 
32785
- const hasGroups = (items) => items && items.length && items[0].field && items[0].items;
32786
- const groupDescriptorsPresent = (descriptors) => isPresent(descriptors) && descriptors.length > 0;
32787
- const processGroups = (data, state) => process(data, state).data;
32788
- const removeParentDescriptors = (parents, owner) => g => g.field !== owner.field && !parents.some(y => y.field === g.field);
32789
- const findGroup = (groupIndex, groups) => {
32790
- const parents = [];
32791
- return {
32792
- group: groupIndex.split("_").reduce((acc, x) => {
32793
- const idx = parseInt(x, 10);
32794
- if (acc.items) {
32795
- parents.push(acc);
32796
- return acc.items[idx];
32797
- }
32798
- return isArray(acc) ? acc[idx] : acc;
32799
- }, groups),
32800
- parents
32801
- };
32802
- };
32803
- const findChildren = (data, parents) => {
32804
- const filters = parents.map(p => ({ field: p.field, operator: "eq", value: p.value }));
32805
- return filterBy(data, {
32806
- filters: filters,
32807
- logic: "and"
32808
- });
32809
- };
32810
- /**
32811
- * @hidden
32812
- */
32813
- const count = (groups, includeFooters = false) => (groups.reduce((acc, group) => {
32814
- if (!group.skipHeader) {
32815
- acc++;
32816
- }
32817
- if (group.items) {
32818
- const children = count(group.items, includeFooters);
32819
- if (includeFooters && children && !group.hideFooter) {
32820
- acc++;
32821
- }
32822
- acc += children;
32823
- }
32824
- return acc;
32825
- }, 0));
32826
- /**
32827
- * @hidden
32828
- */
32829
- const noDescriptors = (descriptors) => !isPresent(descriptors) || !descriptors.length;
32830
- /**
32831
- * @hidden
32832
- */
32833
- const slice = (groups, skip, take, includeFooters = false) => {
32834
- if (!isPresent(take)) {
32835
- return groups;
32836
- }
32837
- const result = [];
32838
- for (let idx = 0, length = groups.length; idx < length; idx++) {
32839
- if (take <= 0) {
32840
- break;
32841
- }
32842
- const group = groups[idx];
32843
- const groupItems = group.items;
32844
- let itemCount = count(groupItems, includeFooters);
32845
- if (includeFooters && groupItems.length) {
32846
- itemCount++;
32847
- }
32848
- const skipHeader = skip > 0;
32849
- if (skip) {
32850
- skip--;
32851
- if (itemCount && skip >= itemCount) {
32852
- skip -= itemCount;
32853
- continue;
32854
- }
32855
- }
32856
- if (!skipHeader || itemCount) {
32857
- const items = [];
32858
- let hideFooter = true;
32859
- if (!skipHeader) {
32860
- take--;
32861
- }
32862
- if (take) {
32863
- if (hasGroups(groupItems)) {
32864
- const children = slice(groupItems, skip, take, includeFooters);
32865
- items.push(...children);
32866
- take -= count(children, includeFooters);
32867
- }
32868
- else {
32869
- items.push(...groupItems.slice(skip, Math.min(skip + take, groupItems.length)));
32870
- take -= items.length;
32871
- }
32872
- if (take && includeFooters) {
32873
- hideFooter = false;
32874
- take--;
32875
- }
32876
- skip = 0;
32877
- }
32878
- result.push({
32879
- aggregates: group.aggregates,
32880
- field: group.field,
32881
- hideFooter,
32882
- items,
32883
- offset: idx,
32884
- skipHeader,
32885
- value: group.value
32886
- });
32887
- }
32888
- }
32889
- return result;
32890
- };
32891
- const skippedHeaders = (groupItem) => {
32892
- let total = 0;
32893
- while (groupItem) {
32894
- if (groupItem.skipHeader) {
32895
- total++;
32896
- }
32897
- groupItem = groupItem.items && groupItem.items[0] || null;
32898
- }
32899
- return total;
32900
- };
32901
- /**
32902
- * A directive which encapsulates the in-memory handling of grouping with virtual scrolling.
32903
- * @remarks
32904
- * Applied to: {@link GridComponent}.
32905
- */
32906
- class GroupBindingDirective extends DataBindingDirective {
32907
- groupsService;
32908
- /**
32909
- * The array of data which will be used to populate the Grid.
32910
- */
32911
- set kendoGridGroupBinding(value) {
32912
- this.groups = null;
32913
- this.grid.resetGroupsState();
32914
- this.data = value;
32915
- }
32916
- /**
32917
- * @hidden
32918
- */
32919
- set data(value) {
32920
- this.originalData = value || [];
32921
- this.dataChanged = true;
32922
- }
32923
- /**
32924
- * Defines the descriptors by which the data will be sorted.
32925
- */
32926
- set sort(value) {
32927
- const noCurrentDescriptors = noDescriptors(this.state.sort);
32928
- const noIncomingDescriptors = noDescriptors(value);
32929
- const clear = this.state.sort !== value && !(noCurrentDescriptors && noIncomingDescriptors);
32930
- this.grid.sort = this.state.sort = value;
32931
- if (clear) {
32932
- this.groups = null;
32933
- this.grid.resetGroupsState();
32934
- }
32935
- }
32936
- /**
32937
- * Defines the descriptor by which the data will be filtered.
32938
- */
32939
- set filter(value) {
32940
- const clear = diffFilters(this.state.filter, value);
32941
- if (clear) {
32942
- this.state.filter = value;
32943
- this.grid.filter = cloneFilters(value);
32944
- this.groups = null;
32945
- this.grid.resetGroupsState();
32946
- }
32947
- }
32948
- /**
32949
- * Defines the descriptors by which the data will be grouped.
32950
- */
32951
- set group(value) {
32952
- // don't clear if no groups are present in previous and current value
32953
- const groupsPresent = groupDescriptorsPresent(this.state.group) || groupDescriptorsPresent(value);
32954
- const clear = this.state.group !== value && groupsPresent;
32955
- this.grid.group = this.state.group = value;
32956
- if (clear) {
32957
- this.groups = null;
32958
- this.grid.resetGroupsState();
32959
- this.skip = 0;
32960
- }
32961
- }
32962
- groups;
32963
- gridSubs = new Subscription();
32964
- constructor(changeDetector, localDataChangesService, ctxService, groupsService) {
32965
- super(ctxService.grid, changeDetector, localDataChangesService);
32966
- this.groupsService = groupsService;
32967
- ctxService.groupBindingDirective = this;
32968
- }
32969
- ngOnInit() {
32970
- super.ngOnInit();
32971
- this.gridSubs.add(this.grid.groupExpand.subscribe(this.groupExpand.bind(this)));
32972
- this.gridSubs.add(this.grid.groupCollapse.subscribe(this.groupCollapse.bind(this)));
32973
- }
32974
- ngAfterContentInit() {
32975
- if (isDevMode() && this.grid.isGroupExpanded) {
32976
- throw new Error(GridConfigurationErrorMessages.groupBindingDirectives);
32977
- }
32978
- }
32979
- ngOnDestroy() {
32980
- this.gridSubs.unsubscribe();
32981
- }
32982
- /**
32983
- * @hidden
32984
- */
32985
- toggleAll(expand) {
32986
- this.skip = 0;
32987
- this.grid.scrollTo({ row: 0, column: 0 });
32988
- this.groups.forEach((gr, idx) => {
32989
- const expanded = this.groupsService.isExpanded({
32990
- group: gr,
32991
- groupIndex: idx.toString(),
32992
- parentGroup: undefined
32993
- });
32994
- const performToggle = (expand && !expanded) || (!expand && expanded);
32995
- if (performToggle) {
32996
- this.grid.groupsService.toggleRow({
32997
- type: 'group',
32998
- data: gr,
32999
- index: idx.toString(),
33000
- level: 0,
33001
- parentGroup: undefined
33002
- });
33003
- this[expand ? 'groupExpand' : 'groupCollapse']({ groupIndex: idx.toString() });
33004
- }
33005
- });
33006
- }
33007
- /**
33008
- * Collapses all expanded root level groups.
33009
- */
33010
- collapseAll() {
33011
- this.toggleAll(false);
33012
- }
33013
- /**
33014
- * Expands all expanded root level groups.
33015
- */
33016
- expandAll() {
33017
- this.toggleAll(true);
33018
- }
33019
- /**
33020
- * @hidden
33021
- */
33022
- groupExpand({ groupIndex }) {
33023
- const { group, parents } = findGroup(groupIndex, this.groups);
33024
- if (!group) {
33025
- return;
33026
- }
33027
- this.groupsService.expandChildren(groupIndex);
33028
- if (!group.items.length) {
33029
- const descriptors = this.state.group.filter(removeParentDescriptors(parents, group));
33030
- const children = findChildren(this.originalData, parents.concat(group));
33031
- group.items = processGroups(children, {
33032
- filter: this.state.filter,
33033
- group: descriptors,
33034
- sort: this.state.sort
33035
- });
33036
- }
33037
- this.grid.data = this.dataResult(this.state.skip, this.state.take);
33038
- }
33039
- /**
33040
- * @hidden
33041
- */
33042
- groupCollapse({ groupIndex }) {
33043
- const { group } = findGroup(groupIndex, this.groups);
33044
- if (group) {
33045
- group.items = [];
33046
- }
33047
- else {
33048
- return;
33049
- }
33050
- this.grid.data = this.dataResult(this.state.skip, this.state.take);
33051
- }
33052
- process(state) {
33053
- if (state.group && state.group.length) {
33054
- const groups = this.processGroups(state);
33055
- this.grid.skip -= skippedHeaders(groups.data[0]);
33056
- return groups;
33057
- }
33058
- else {
33059
- this.groups = null;
33060
- }
33061
- return super.process(state);
33062
- }
33063
- processGroups(state) {
33064
- if (!this.groups || !this.groups.length) {
33065
- this.groups = processGroups(this.originalData, {
33066
- filter: state.filter,
33067
- group: state.group,
33068
- sort: state.sort
33069
- });
33070
- }
33071
- return this.dataResult(state.skip, state.take);
33072
- }
33073
- dataResult(skip, take) {
33074
- const includeFooters = this.grid.showGroupFooters;
33075
- return {
33076
- data: slice(this.groups, skip, take, includeFooters),
33077
- total: count(this.groups, includeFooters)
33078
- };
33079
- }
33080
- applyState({ skip, take, sort, group, filter }) {
33081
- this.skip = skip;
33082
- this.state.take = take;
33083
- // this.pageSize = take; // do need to update take as the process with slice correctly
33084
- this.sort = sort;
33085
- this.group = group;
33086
- this.filter = filter;
33087
- }
33088
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupBindingDirective, deps: [{ token: i0.ChangeDetectorRef }, { token: LocalDataChangesService }, { token: ContextService }, { token: GroupsService }], target: i0.ɵɵFactoryTarget.Directive });
33089
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupBindingDirective, isStandalone: true, selector: "[kendoGridGroupBinding]", inputs: { kendoGridGroupBinding: "kendoGridGroupBinding", sort: "sort", filter: "filter", group: "group" }, exportAs: ["kendoGridGroupBinding"], usesInheritance: true, ngImport: i0 });
33090
- }
33091
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupBindingDirective, decorators: [{
33092
- type: Directive,
33093
- args: [{
33094
- selector: '[kendoGridGroupBinding]',
33095
- exportAs: 'kendoGridGroupBinding',
33096
- standalone: true
33097
- }]
33098
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: LocalDataChangesService }, { type: ContextService }, { type: GroupsService }]; }, propDecorators: { kendoGridGroupBinding: [{
33099
- type: Input,
33100
- args: ["kendoGridGroupBinding"]
33101
- }], sort: [{
33102
- type: Input
33103
- }], filter: [{
33104
- type: Input
33105
- }], group: [{
33106
- type: Input
33107
- }] } });
33108
-
33109
33200
  /**
33110
33201
  * Represents the Kendo UI GridSpacer component for Angular.
33111
33202
  * Used to give additional white space between the Pager inner elements,
@@ -33758,6 +33849,12 @@ class UndoRedoStack {
33758
33849
  this.currentNode = this.currentNode.previous;
33759
33850
  return this.currentNode.state;
33760
33851
  }
33852
+ peekNext() {
33853
+ return this.currentNode.next?.state || null;
33854
+ }
33855
+ peekPrev() {
33856
+ return this.currentNode.previous?.state || null;
33857
+ }
33761
33858
  /**
33762
33859
  * Performs a redo operation, moving to the next state
33763
33860
  * @returns The next state or null if can't redo
@@ -33880,7 +33977,6 @@ class UndoRedoService {
33880
33977
  onUndo = new Subject();
33881
33978
  onRedo = new Subject();
33882
33979
  stackEndReached = new Subject();
33883
- setState = new Subject();
33884
33980
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UndoRedoService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
33885
33981
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UndoRedoService });
33886
33982
  }
@@ -33904,11 +34000,17 @@ class UndoRedoDirective {
33904
34000
  editService;
33905
34001
  undoRedoService;
33906
34002
  changeNotification;
34003
+ ctx;
34004
+ localDataChangesService;
33907
34005
  /**
33908
34006
  * Sets the maximum number of actions to keep in the undo-redo stack.
33909
34007
  * @default 10
33910
34008
  */
33911
34009
  maxStoredStates = 10;
34010
+ /**
34011
+ * Defines the property name of the data item unique key that will be used to identify the items when performing undo-redo actions.
34012
+ */
34013
+ itemIdKey;
33912
34014
  /**
33913
34015
  * Fires when you perform the undo action. Provides the Grid state to apply.
33914
34016
  */
@@ -33926,11 +34028,13 @@ class UndoRedoDirective {
33926
34028
  stack;
33927
34029
  subs = new Subscription();
33928
34030
  addToState = true;
33929
- constructor(host, editService, undoRedoService, changeNotification) {
34031
+ constructor(host, editService, undoRedoService, changeNotification, ctx, localDataChangesService) {
33930
34032
  this.host = host;
33931
34033
  this.editService = editService;
33932
34034
  this.undoRedoService = undoRedoService;
33933
34035
  this.changeNotification = changeNotification;
34036
+ this.ctx = ctx;
34037
+ this.localDataChangesService = localDataChangesService;
33934
34038
  this.host.undoRedoService = this.undoRedoService;
33935
34039
  }
33936
34040
  ngOnInit() {
@@ -33942,7 +34046,7 @@ class UndoRedoDirective {
33942
34046
  sort: this.host.sort,
33943
34047
  filter: this.host.filter,
33944
34048
  group: this.host.group
33945
- }, gridState: structuredClone(this.host.currentState)
34049
+ }, gridState: this.host.currentState
33946
34050
  });
33947
34051
  this.subs = this.host.gridStateChange.subscribe((state) => {
33948
34052
  if (this.addToState) {
@@ -33954,7 +34058,7 @@ class UndoRedoDirective {
33954
34058
  filter: state.filter,
33955
34059
  group: state.group
33956
34060
  },
33957
- gridState: structuredClone(state)
34061
+ gridState: state
33958
34062
  });
33959
34063
  }
33960
34064
  let stackEndPointReached;
@@ -33967,36 +34071,72 @@ class UndoRedoDirective {
33967
34071
  this.undoRedoService.stackEndReached.next(stackEndPointReached);
33968
34072
  });
33969
34073
  this.subs.add(this.editService.changes
33970
- .pipe(filter(event => event.action === 'save' || event.action === 'remove'), tap(event => this.undoRedoService.originalEvent = event))
34074
+ .pipe(filter((event) => event.action === 'save' || event.action === 'remove'))
33971
34075
  .subscribe(event => {
33972
34076
  this.stack.add({
33973
- originalEvent: event,
33974
- gridState: structuredClone(this.host.currentState)
34077
+ originalEvent: { ...event, dataItem: structuredClone(event.dataItem) },
34078
+ gridState: this.host.currentState
33975
34079
  });
33976
34080
  this.addToState = false;
33977
34081
  this.host.gridStateChange.emit(this.stack.current.gridState);
33978
34082
  this.addToState = true;
33979
34083
  this.updateUndoRedoDisabled();
33980
34084
  }));
33981
- this.subs.add(this.changeNotification.changes.subscribe(() => this.stack.current.gridState = this.host.currentState));
34085
+ this.subs.add(this.changeNotification.changes.subscribe(() => {
34086
+ if (!this.ctx.dataBindingDirective) {
34087
+ this.stack.current.gridState = this.host.currentState;
34088
+ }
34089
+ }));
33982
34090
  ['Undo', 'Redo'].forEach((action) => {
33983
34091
  this.subs.add(this.undoRedoService[`on${action}`].subscribe(() => {
33984
34092
  if (!this.stack[`can${action}`]) {
33985
34093
  return;
33986
34094
  }
33987
- this.stack[`${action.toLowerCase()}`]();
34095
+ let eventData;
34096
+ if (action === 'Undo') {
34097
+ const isSaveOrRemove = this.stack.current.originalEvent.action === 'save' || this.stack.current.originalEvent.action === 'remove';
34098
+ eventData = isSaveOrRemove ? this.stack.current : this.stack.peekPrev();
34099
+ }
34100
+ else {
34101
+ eventData = this.stack.peekNext();
34102
+ }
34103
+ const event = new UndoRedoEvent(eventData);
33988
34104
  if (hasObservers(this[`on${action}`])) {
33989
- const event = new UndoRedoEvent(this.stack.current);
33990
34105
  this[`on${action}`].emit(event);
33991
34106
  if (event.isDefaultPrevented()) {
33992
34107
  return;
33993
34108
  }
33994
34109
  }
34110
+ this.stack[`${action.toLowerCase()}`]();
33995
34111
  this.updateUndoRedoDisabled();
33996
- this.host.loadState(this.stack.current.gridState);
34112
+ const originalAction = event.originalEvent.action;
34113
+ const isLocalData = isPresent$1(this.ctx?.dataBindingDirective);
34114
+ if (!isLocalData) {
34115
+ return;
34116
+ }
34117
+ const isSaveOrRemove = originalAction === 'save' || originalAction === 'remove';
34118
+ if (isSaveOrRemove) {
34119
+ if (originalAction === 'save') {
34120
+ const stateItem = this.getGridDataItems(this.stack.current.gridState.currentData).find(item => item[this.itemIdKey] === event.originalEvent.dataItem[this.itemIdKey]);
34121
+ Object.assign(event.originalEvent.originalDataItem, stateItem);
34122
+ }
34123
+ else if (action === 'Undo') {
34124
+ this.localDataChangesService?.data.splice(event.originalEvent.rowIndex, 0, event.originalEvent.dataItem);
34125
+ }
34126
+ else {
34127
+ this.localDataChangesService?.data.splice(event.originalEvent.rowIndex, 1);
34128
+ }
34129
+ this.localDataChangesService?.changes.emit();
34130
+ }
34131
+ else {
34132
+ this.host.loadState({ ...this.stack.current.gridState, currentData: null });
34133
+ if (this.isDataStateChangeEvent(event.originalEvent)) {
34134
+ const { skip, take, sort, filter, group } = this.stack.current.gridState;
34135
+ this.host.dataStateChange.emit({ skip, take, sort, filter, group });
34136
+ }
34137
+ }
33997
34138
  }));
33998
34139
  });
33999
- this.subs.add(this.undoRedoService.setState.subscribe((state) => this.stack.add({ originalEvent: 'dataChange', gridState: state })));
34000
34140
  }
34001
34141
  ngOnDestroy() {
34002
34142
  this.stack.clear();
@@ -34038,8 +34178,15 @@ class UndoRedoDirective {
34038
34178
  }
34039
34179
  this.undoRedoService.stackEndReached.next(false);
34040
34180
  }
34041
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UndoRedoDirective, deps: [{ token: GridComponent }, { token: EditService }, { token: UndoRedoService }, { token: ChangeNotificationService }], target: i0.ɵɵFactoryTarget.Directive });
34042
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: UndoRedoDirective, isStandalone: true, selector: "[kendoGridUndoRedo]", inputs: { maxStoredStates: "maxStoredStates" }, outputs: { onUndo: "undo", onRedo: "redo" }, providers: [UndoRedoService], exportAs: ["kendoGridUndoRedo"], ngImport: i0 });
34181
+ getGridDataItems(data) {
34182
+ return Array.isArray(data) ? data.flatMap(recursiveFlatMap) :
34183
+ data.data.flatMap(recursiveFlatMap);
34184
+ }
34185
+ isDataStateChangeEvent(event) {
34186
+ return event && ['skip', 'take', 'sort', 'filter', 'group'].some(prop => prop in event);
34187
+ }
34188
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UndoRedoDirective, deps: [{ token: GridComponent }, { token: EditService }, { token: UndoRedoService }, { token: ChangeNotificationService }, { token: ContextService }, { token: LocalDataChangesService }], target: i0.ɵɵFactoryTarget.Directive });
34189
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: UndoRedoDirective, isStandalone: true, selector: "[kendoGridUndoRedo]", inputs: { maxStoredStates: "maxStoredStates", itemIdKey: "itemIdKey" }, outputs: { onUndo: "undo", onRedo: "redo" }, providers: [UndoRedoService], exportAs: ["kendoGridUndoRedo"], ngImport: i0 });
34043
34190
  }
34044
34191
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UndoRedoDirective, decorators: [{
34045
34192
  type: Directive,
@@ -34049,7 +34196,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
34049
34196
  exportAs: 'kendoGridUndoRedo',
34050
34197
  providers: [UndoRedoService]
34051
34198
  }]
34052
- }], ctorParameters: function () { return [{ type: GridComponent }, { type: EditService }, { type: UndoRedoService }, { type: ChangeNotificationService }]; }, propDecorators: { maxStoredStates: [{
34199
+ }], ctorParameters: function () { return [{ type: GridComponent }, { type: EditService }, { type: UndoRedoService }, { type: ChangeNotificationService }, { type: ContextService }, { type: LocalDataChangesService }]; }, propDecorators: { maxStoredStates: [{
34200
+ type: Input
34201
+ }], itemIdKey: [{
34053
34202
  type: Input
34054
34203
  }], onUndo: [{
34055
34204
  type: Output,