@progress/kendo-angular-grid 19.2.0-develop.8 → 19.2.0

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.
package/README.md CHANGED
@@ -4,9 +4,14 @@
4
4
 
5
5
  ## Kendo UI for Angular Data Grid Component
6
6
 
7
- > * This package is part of the [Kendo UI for Angular](https://www.telerik.com/kendo-angular-ui/)—a commercial UI library.
8
- > * You must [install a license key](https://www.telerik.com/kendo-angular-ui/my-license) when adding the package to your project. To receive a license key, either [purchase a license](https://www.telerik.com/purchase/kendo-ui) or register for a [free trial](https://www.telerik.com/download-login-v2-kendo-angular-ui).
9
- > * The 30-day free trial gives you access to all the Kendo UI for Angular components and their full functionality. Additionally, for the period of your license, you get access to our legendary technical support provided directly by the Kendo UI for Angular team!
7
+ > * This package is part of [Kendo UI for Angular](https://www.telerik.com/kendo-angular-ui/)—a commercial UI library.
8
+ > * To use this package, you must install a license key file, whether you are on a paid license or a 30-day free trial. To receive a license key, either [purchase a license](https://www.telerik.com/purchase/kendo-ui) or start a [free trial](https://www.telerik.com/download-login-v2-kendo-angular-ui).
9
+ > * Adding a valid license key file ensures a seamless experience during the trial period—no watermarks, no warnings, and full access to all components and features.
10
+ > * Trial users can register for a free license key file. Without it, your trial may be interrupted by visual indicators or functionality limitations.
11
+ > * Additionally, for the period of your license, you get access to our legendary technical support provided directly by the Kendo UI for Angular team!
12
+ > * Learn more: https://www.telerik.com/kendo-angular-ui/components/licensing
13
+ >
14
+ > [Start using Kendo UI for Angular](https://www.telerik.com/download-login-v2-kendo-angular-ui) and speed up your development process!
10
15
 
11
16
  The [Kendo UI for Angular Data Grid](https://www.telerik.com/kendo-angular-ui/components/grid) includes a comprehensive set of ready-to-use features covering everything from paging, sorting, filtering, editing, and grouping to row and column virtualization, exporting to PDF and Excel, and accessibility support. This Data Grid Component (sometimes called a Data Table) is built on Angular from the ground up, by a company with a long history of making enterprise-ready Grids. This results in an Angular data grid that delivers lighting fast performance and is highly customizable.
12
17
 
@@ -6,7 +6,7 @@ import { ChangeDetectorRef, ElementRef, NgZone, Renderer2 } from '@angular/core'
6
6
  import { ContextService } from '../common/provider.service';
7
7
  import * as i0 from "@angular/core";
8
8
  /**
9
- * Represents a directive that manages keyboard navigation for a column menu item. [See example](slug:columnmenu_grid#customizing-the-content).
9
+ * Represents a directive that manages keyboard navigation for a column menu item ([see example](slug:columnmenu_grid#customizing-the-content)).
10
10
  *
11
11
  * @example
12
12
  * ```html
@@ -7,7 +7,7 @@ import { LocalizationService } from '@progress/kendo-angular-l10n';
7
7
  import type { GridComponent } from '../grid.component';
8
8
  import { GridToolbarNavigationService } from '../rendering/toolbar/toolbar-navigation.service';
9
9
  import type { GroupBindingDirective } from '../grouping/group-scroll-binding.directive';
10
- import { DataBindingDirective } from '../databinding.directive';
10
+ import type { DataBindingDirective } from '../databinding.directive';
11
11
  import * as i0 from "@angular/core";
12
12
  /**
13
13
  * @hidden
@@ -12,7 +12,7 @@ import { ContextService } from '../common/provider.service';
12
12
  import * as i0 from "@angular/core";
13
13
  import * as i1 from "../common/provider.service";
14
14
  /**
15
- * Represents a directive that manages keyboard navigation for a column menu item. [See example](slug:columnmenu_grid#customizing-the-content).
15
+ * Represents a directive that manages keyboard navigation for a column menu item ([see example](slug:columnmenu_grid#customizing-the-content)).
16
16
  *
17
17
  * @example
18
18
  * ```html
@@ -94,12 +94,10 @@ export class TableDirective {
94
94
  if (isConstrainedMode && !this.service.autoFitResize) {
95
95
  this.renderer.setStyle(this.element.nativeElement, 'width', this.service.originalWidth + 'px');
96
96
  }
97
- else {
98
- if (!this.virtualColumns || this.locked) {
99
- const delta = deltas.reduce((sum, item) => sum + item, 0);
100
- const width = this.service.originalWidth + delta;
101
- this.renderer.setStyle(this.element.nativeElement, 'width', width + 'px');
102
- }
97
+ else if (!this.virtualColumns || this.locked) {
98
+ const delta = deltas.reduce((sum, item) => sum + item, 0);
99
+ const width = this.service.originalWidth + delta;
100
+ this.renderer.setStyle(this.element.nativeElement, 'width', width + 'px');
103
101
  }
104
102
  this.cdr.detectChanges();
105
103
  }
@@ -100,7 +100,6 @@ import { AdaptiveGridService } from './common/adaptiveness.service';
100
100
  import { AdaptiveRendererComponent } from './adaptiveness/adaptive-renderer.component';
101
101
  import { ColumnMenuService } from './column-menu/column-menu.service';
102
102
  import { MenuTabbingService } from './filtering/menu/menu-tabbing.service';
103
- import { GroupBindingDirective } from './grouping/group-scroll-binding.directive';
104
103
  import { DataMappingService } from './data/data-mapping.service';
105
104
  import * as i0 from "@angular/core";
106
105
  import * as i1 from "./layout/browser-support.service";
@@ -922,10 +921,8 @@ export class GridComponent {
922
921
  dragTargetContainer;
923
922
  dropTargetContainer;
924
923
  dialogContainer;
925
- /**
926
- * @hidden
927
- */
928
924
  adaptiveRenderer;
925
+ listComponent;
929
926
  get scrollbarWidth() {
930
927
  return this.supportService.scrollbarWidth;
931
928
  }
@@ -1826,6 +1823,9 @@ export class GridComponent {
1826
1823
  source.locked = target.locked;
1827
1824
  }
1828
1825
  this.columnsContainer.refresh();
1826
+ if (this.virtualColumns) {
1827
+ this.listComponent.updateViewportColumns();
1828
+ }
1829
1829
  this.changeDetectorRef.markForCheck();
1830
1830
  });
1831
1831
  }
@@ -2248,7 +2248,8 @@ export class GridComponent {
2248
2248
  column = toAdd.shift();
2249
2249
  viewportColumns.push(column);
2250
2250
  if (column.isColumnGroup) {
2251
- toAdd.unshift(...column.childrenArray);
2251
+ const children = columnsArray.filter(c => c.parent && c.parent.id === column.id);
2252
+ toAdd.unshift(...children);
2252
2253
  }
2253
2254
  }
2254
2255
  const lastFromGroup = viewportColumns[viewportColumns.length - 1];
@@ -2304,7 +2305,7 @@ export class GridComponent {
2304
2305
  }
2305
2306
  if (this.groupsService.isExpanded({ groupIndex: index }) !== expand) {
2306
2307
  this.groupsService.toggleRow({ index }, false);
2307
- if (this.ctx.dataBindingDirective && this.ctx.dataBindingDirective instanceof GroupBindingDirective) {
2308
+ if (this.ctx.dataBindingDirective && isPresent(this.ctx.dataBindingDirective.groupExpand)) {
2308
2309
  this.ctx.dataBindingDirective[`group${expand ? 'Expand' : 'Collapse'}`]({ groupIndex: index });
2309
2310
  }
2310
2311
  }
@@ -2378,7 +2379,7 @@ export class GridComponent {
2378
2379
  ColumnMenuService,
2379
2380
  MenuTabbingService,
2380
2381
  DataMappingService
2381
- ], 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: `
2382
+ ], 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: `
2382
2383
  <ng-container kendoGridLocalizedMessages
2383
2384
  i18n-groupPanelEmpty="kendo.grid.groupPanelEmpty|The label visible in the Grid group panel when it is empty"
2384
2385
  groupPanelEmpty="Drag a column header and drop it here to group by that column"
@@ -4195,4 +4196,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
4195
4196
  }], adaptiveRenderer: [{
4196
4197
  type: ViewChild,
4197
4198
  args: [AdaptiveRendererComponent]
4199
+ }], listComponent: [{
4200
+ type: ViewChild,
4201
+ args: [ListComponent]
4198
4202
  }] } });
@@ -284,6 +284,12 @@ export class GroupBindingDirective extends DataBindingDirective {
284
284
  this.grid.data = this.dataResult(this.state.skip, this.state.take);
285
285
  }
286
286
  process(state) {
287
+ if (this.grid.isVirtual && (!isPresent(state.take) || state.take === 0)) {
288
+ return {
289
+ data: [],
290
+ total: this.originalData?.length || 0
291
+ };
292
+ }
287
293
  if (state.group && state.group.length) {
288
294
  const groups = this.processGroups(state);
289
295
  this.grid.skip -= skippedHeaders(groups.data[0]);
@@ -10,7 +10,7 @@ export const packageMetadata = {
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCode: 'KENDOUIANGULAR',
12
12
  productCodes: ['KENDOUIANGULAR'],
13
- publishDate: 1751032619,
14
- version: '19.2.0-develop.8',
13
+ publishDate: 1751463227,
14
+ version: '19.2.0',
15
15
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
16
16
  };
@@ -274,7 +274,7 @@ export class ListComponent {
274
274
  if (shouldCalculatePageSize) {
275
275
  const calculatedPageSize = this.calcVirtualPageSize();
276
276
  if (calculatedPageSize > 0) {
277
- this.ngZone.onMicrotaskEmpty.pipe(take(1)).subscribe(() => {
277
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => {
278
278
  this.ctx.grid.pageSize = calculatedPageSize;
279
279
  this.ngZone.run(() => {
280
280
  this.pageChange.emit({
@@ -353,6 +353,36 @@ export class ListComponent {
353
353
  args.preventDefault();
354
354
  }
355
355
  }
356
+ updateViewportColumns(range) {
357
+ const columns = this.columns.nonLockedLeafColumns.toArray();
358
+ // eslint-disable-next-line prefer-const
359
+ let { startIdx, endIdx, offset } = range || this.calculateViewportColumns();
360
+ const start = Math.max(0, startIdx - bufferSize);
361
+ const end = Math.min(endIdx + bufferSize, columns.length - 1);
362
+ if (start < startIdx) {
363
+ for (let idx = startIdx - 1; idx >= start; idx--) {
364
+ offset -= columns[idx].width;
365
+ }
366
+ }
367
+ let currentColumns = columns.slice(start, end + 1);
368
+ this.viewportColumnsWidth = currentColumns.reduce((total, column) => total + column.width, 0);
369
+ const stickyBeforeStart = columns.slice(0, start).filter(c => c.sticky && !currentColumns.some(col => col === c));
370
+ const stickyAfterEnd = columns.slice(end, columns.length).filter(c => c.sticky && !currentColumns.some(col => col === c));
371
+ currentColumns = [...stickyBeforeStart, ...currentColumns, ...stickyAfterEnd];
372
+ if (start > 0) {
373
+ const offsetColumn = new ColumnBase();
374
+ offsetColumn.width = offset;
375
+ currentColumns.unshift(offsetColumn);
376
+ }
377
+ this.viewportColumns = new QueryList();
378
+ this.viewportColumns.reset(currentColumns);
379
+ this.columnsStartIdx = start;
380
+ this.columnsEndIdx = end;
381
+ this.columnInfo.columnRangeChange.emit({ start, end, offset });
382
+ if (!range) {
383
+ this.updateColumnViewport(startIdx, endIdx);
384
+ }
385
+ }
356
386
  detailExpand({ index, expand }) {
357
387
  if (expand) {
358
388
  this.rowHeightService.expandDetail(index);
@@ -578,36 +608,6 @@ export class ListComponent {
578
608
  })
579
609
  .forEach(setHeight(this.renderer));
580
610
  }
581
- updateViewportColumns(range) {
582
- const columns = this.columns.nonLockedLeafColumns.toArray();
583
- // eslint-disable-next-line prefer-const
584
- let { startIdx, endIdx, offset } = range || this.calculateViewportColumns();
585
- const start = Math.max(0, startIdx - bufferSize);
586
- const end = Math.min(endIdx + bufferSize, columns.length - 1);
587
- if (start < startIdx) {
588
- for (let idx = startIdx - 1; idx >= start; idx--) {
589
- offset -= columns[idx].width;
590
- }
591
- }
592
- let currentColumns = columns.slice(start, end + 1);
593
- this.viewportColumnsWidth = currentColumns.reduce((total, column) => total + column.width, 0);
594
- const stickyBeforeStart = columns.slice(0, start).filter(c => c.sticky && !currentColumns.some(col => col === c));
595
- const stickyAfterEnd = columns.slice(end, columns.length).filter(c => c.sticky && !currentColumns.some(col => col === c));
596
- currentColumns = [...stickyBeforeStart, ...currentColumns, ...stickyAfterEnd];
597
- if (start > 0) {
598
- const offsetColumn = new ColumnBase();
599
- offsetColumn.width = offset;
600
- currentColumns.unshift(offsetColumn);
601
- }
602
- this.viewportColumns = new QueryList();
603
- this.viewportColumns.reset(currentColumns);
604
- this.columnsStartIdx = start;
605
- this.columnsEndIdx = end;
606
- this.columnInfo.columnRangeChange.emit({ start, end, offset });
607
- if (!range) {
608
- this.updateColumnViewport(startIdx, endIdx);
609
- }
610
- }
611
611
  handleColumnScroll() {
612
612
  const container = this.container.nativeElement;
613
613
  const scrollLeft = container.scrollLeft;
@@ -77,15 +77,6 @@ export class UndoRedoDirective {
77
77
  }
78
78
  ngOnInit() {
79
79
  this.stack = new UndoRedoStack(this.maxStoredStates);
80
- this.stack.add({
81
- originalEvent: {
82
- skip: this.host.skip,
83
- take: this.host.pageSize,
84
- sort: this.host.sort,
85
- filter: this.host.filter,
86
- group: this.host.group
87
- }, gridState: this.host.currentState
88
- });
89
80
  this.subs = this.host.gridStateChange.subscribe((state) => {
90
81
  if (this.addToState) {
91
82
  this.stack.add({
@@ -156,7 +147,7 @@ export class UndoRedoDirective {
156
147
  if (isSaveOrRemove) {
157
148
  if (originalAction === 'save') {
158
149
  const stateItem = this.getGridDataItems(this.stack.current.gridState.currentData).find(item => item[this.itemIdKey] === event.originalEvent.dataItem[this.itemIdKey]);
159
- Object.assign(event.originalEvent.originalDataItem, stateItem);
150
+ this.localDataChangesService?.data.splice(event.originalEvent.rowIndex, 1, stateItem);
160
151
  }
161
152
  else if (action === 'Undo') {
162
153
  this.localDataChangesService?.data.splice(event.originalEvent.rowIndex, 0, event.originalEvent.dataItem);
@@ -169,13 +160,24 @@ export class UndoRedoDirective {
169
160
  else {
170
161
  this.host.loadState({ ...this.stack.current.gridState, currentData: null });
171
162
  if (this.isDataStateChangeEvent(event.originalEvent)) {
172
- const { skip, take, sort, filter, group } = this.stack.current.gridState;
163
+ const { skip, take, sort, filter, group } = event.gridState;
173
164
  this.host.dataStateChange.emit({ skip, take, sort, filter, group });
174
165
  }
175
166
  }
176
167
  }));
177
168
  });
178
169
  }
170
+ ngAfterViewInit() {
171
+ this.stack.add({
172
+ originalEvent: {
173
+ skip: this.host.skip,
174
+ take: this.host.pageSize,
175
+ sort: this.host.sort,
176
+ filter: this.host.filter,
177
+ group: this.host.group
178
+ }, gridState: this.host.currentState
179
+ });
180
+ }
179
181
  ngOnDestroy() {
180
182
  this.stack.clear();
181
183
  this.stack = null;