@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
@@ -8,15 +8,20 @@ import { GridComponent } from '../grid.component';
8
8
  import { UndoRedoEvent } from './grid-state.models';
9
9
  import { Subscription } from 'rxjs';
10
10
  import { EditService } from '../editing/edit.service';
11
- import { filter, tap } from 'rxjs/operators';
11
+ import { filter } from 'rxjs/operators';
12
12
  import { UndoRedoService } from './undo-redo.service';
13
- import { hasObservers } from '@progress/kendo-angular-common';
13
+ import { hasObservers, isPresent } from '@progress/kendo-angular-common';
14
14
  import { ChangeNotificationService } from '../data/change-notification.service';
15
+ import { ContextService } from '../common/provider.service';
16
+ import { LocalDataChangesService } from '../editing/local-data-changes.service';
17
+ import { recursiveFlatMap } from '../utils';
15
18
  import * as i0 from "@angular/core";
16
19
  import * as i1 from "../grid.component";
17
20
  import * as i2 from "../editing/edit.service";
18
21
  import * as i3 from "./undo-redo.service";
19
22
  import * as i4 from "../data/change-notification.service";
23
+ import * as i5 from "../common/provider.service";
24
+ import * as i6 from "../editing/local-data-changes.service";
20
25
  /**
21
26
  * Represents the directive that manages undo-redo operations in the Grid.
22
27
  * Use this directive to enable undo and redo functionality for user actions in the Grid.
@@ -33,11 +38,17 @@ export class UndoRedoDirective {
33
38
  editService;
34
39
  undoRedoService;
35
40
  changeNotification;
41
+ ctx;
42
+ localDataChangesService;
36
43
  /**
37
44
  * Sets the maximum number of actions to keep in the undo-redo stack.
38
45
  * @default 10
39
46
  */
40
47
  maxStoredStates = 10;
48
+ /**
49
+ * Defines the property name of the data item unique key that will be used to identify the items when performing undo-redo actions.
50
+ */
51
+ itemIdKey;
41
52
  /**
42
53
  * Fires when you perform the undo action. Provides the Grid state to apply.
43
54
  */
@@ -55,11 +66,13 @@ export class UndoRedoDirective {
55
66
  stack;
56
67
  subs = new Subscription();
57
68
  addToState = true;
58
- constructor(host, editService, undoRedoService, changeNotification) {
69
+ constructor(host, editService, undoRedoService, changeNotification, ctx, localDataChangesService) {
59
70
  this.host = host;
60
71
  this.editService = editService;
61
72
  this.undoRedoService = undoRedoService;
62
73
  this.changeNotification = changeNotification;
74
+ this.ctx = ctx;
75
+ this.localDataChangesService = localDataChangesService;
63
76
  this.host.undoRedoService = this.undoRedoService;
64
77
  }
65
78
  ngOnInit() {
@@ -71,7 +84,7 @@ export class UndoRedoDirective {
71
84
  sort: this.host.sort,
72
85
  filter: this.host.filter,
73
86
  group: this.host.group
74
- }, gridState: structuredClone(this.host.currentState)
87
+ }, gridState: this.host.currentState
75
88
  });
76
89
  this.subs = this.host.gridStateChange.subscribe((state) => {
77
90
  if (this.addToState) {
@@ -83,7 +96,7 @@ export class UndoRedoDirective {
83
96
  filter: state.filter,
84
97
  group: state.group
85
98
  },
86
- gridState: structuredClone(state)
99
+ gridState: state
87
100
  });
88
101
  }
89
102
  let stackEndPointReached;
@@ -96,36 +109,72 @@ export class UndoRedoDirective {
96
109
  this.undoRedoService.stackEndReached.next(stackEndPointReached);
97
110
  });
98
111
  this.subs.add(this.editService.changes
99
- .pipe(filter(event => event.action === 'save' || event.action === 'remove'), tap(event => this.undoRedoService.originalEvent = event))
112
+ .pipe(filter((event) => event.action === 'save' || event.action === 'remove'))
100
113
  .subscribe(event => {
101
114
  this.stack.add({
102
- originalEvent: event,
103
- gridState: structuredClone(this.host.currentState)
115
+ originalEvent: { ...event, dataItem: structuredClone(event.dataItem) },
116
+ gridState: this.host.currentState
104
117
  });
105
118
  this.addToState = false;
106
119
  this.host.gridStateChange.emit(this.stack.current.gridState);
107
120
  this.addToState = true;
108
121
  this.updateUndoRedoDisabled();
109
122
  }));
110
- this.subs.add(this.changeNotification.changes.subscribe(() => this.stack.current.gridState = this.host.currentState));
123
+ this.subs.add(this.changeNotification.changes.subscribe(() => {
124
+ if (!this.ctx.dataBindingDirective) {
125
+ this.stack.current.gridState = this.host.currentState;
126
+ }
127
+ }));
111
128
  ['Undo', 'Redo'].forEach((action) => {
112
129
  this.subs.add(this.undoRedoService[`on${action}`].subscribe(() => {
113
130
  if (!this.stack[`can${action}`]) {
114
131
  return;
115
132
  }
116
- this.stack[`${action.toLowerCase()}`]();
133
+ let eventData;
134
+ if (action === 'Undo') {
135
+ const isSaveOrRemove = this.stack.current.originalEvent.action === 'save' || this.stack.current.originalEvent.action === 'remove';
136
+ eventData = isSaveOrRemove ? this.stack.current : this.stack.peekPrev();
137
+ }
138
+ else {
139
+ eventData = this.stack.peekNext();
140
+ }
141
+ const event = new UndoRedoEvent(eventData);
117
142
  if (hasObservers(this[`on${action}`])) {
118
- const event = new UndoRedoEvent(this.stack.current);
119
143
  this[`on${action}`].emit(event);
120
144
  if (event.isDefaultPrevented()) {
121
145
  return;
122
146
  }
123
147
  }
148
+ this.stack[`${action.toLowerCase()}`]();
124
149
  this.updateUndoRedoDisabled();
125
- this.host.loadState(this.stack.current.gridState);
150
+ const originalAction = event.originalEvent.action;
151
+ const isLocalData = isPresent(this.ctx?.dataBindingDirective);
152
+ if (!isLocalData) {
153
+ return;
154
+ }
155
+ const isSaveOrRemove = originalAction === 'save' || originalAction === 'remove';
156
+ if (isSaveOrRemove) {
157
+ if (originalAction === 'save') {
158
+ 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);
160
+ }
161
+ else if (action === 'Undo') {
162
+ this.localDataChangesService?.data.splice(event.originalEvent.rowIndex, 0, event.originalEvent.dataItem);
163
+ }
164
+ else {
165
+ this.localDataChangesService?.data.splice(event.originalEvent.rowIndex, 1);
166
+ }
167
+ this.localDataChangesService?.changes.emit();
168
+ }
169
+ else {
170
+ this.host.loadState({ ...this.stack.current.gridState, currentData: null });
171
+ if (this.isDataStateChangeEvent(event.originalEvent)) {
172
+ const { skip, take, sort, filter, group } = this.stack.current.gridState;
173
+ this.host.dataStateChange.emit({ skip, take, sort, filter, group });
174
+ }
175
+ }
126
176
  }));
127
177
  });
128
- this.subs.add(this.undoRedoService.setState.subscribe((state) => this.stack.add({ originalEvent: 'dataChange', gridState: state })));
129
178
  }
130
179
  ngOnDestroy() {
131
180
  this.stack.clear();
@@ -167,8 +216,15 @@ export class UndoRedoDirective {
167
216
  }
168
217
  this.undoRedoService.stackEndReached.next(false);
169
218
  }
170
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UndoRedoDirective, deps: [{ token: i1.GridComponent }, { token: i2.EditService }, { token: i3.UndoRedoService }, { token: i4.ChangeNotificationService }], target: i0.ɵɵFactoryTarget.Directive });
171
- 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 });
219
+ getGridDataItems(data) {
220
+ return Array.isArray(data) ? data.flatMap(recursiveFlatMap) :
221
+ data.data.flatMap(recursiveFlatMap);
222
+ }
223
+ isDataStateChangeEvent(event) {
224
+ return event && ['skip', 'take', 'sort', 'filter', 'group'].some(prop => prop in event);
225
+ }
226
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UndoRedoDirective, deps: [{ token: i1.GridComponent }, { token: i2.EditService }, { token: i3.UndoRedoService }, { token: i4.ChangeNotificationService }, { token: i5.ContextService }, { token: i6.LocalDataChangesService }], target: i0.ɵɵFactoryTarget.Directive });
227
+ 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 });
172
228
  }
173
229
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UndoRedoDirective, decorators: [{
174
230
  type: Directive,
@@ -178,7 +234,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
178
234
  exportAs: 'kendoGridUndoRedo',
179
235
  providers: [UndoRedoService]
180
236
  }]
181
- }], ctorParameters: function () { return [{ type: i1.GridComponent }, { type: i2.EditService }, { type: i3.UndoRedoService }, { type: i4.ChangeNotificationService }]; }, propDecorators: { maxStoredStates: [{
237
+ }], ctorParameters: function () { return [{ type: i1.GridComponent }, { type: i2.EditService }, { type: i3.UndoRedoService }, { type: i4.ChangeNotificationService }, { type: i5.ContextService }, { type: i6.LocalDataChangesService }]; }, propDecorators: { maxStoredStates: [{
238
+ type: Input
239
+ }], itemIdKey: [{
182
240
  type: Input
183
241
  }], onUndo: [{
184
242
  type: Output,
@@ -13,7 +13,6 @@ export class UndoRedoService {
13
13
  onUndo = new Subject();
14
14
  onRedo = new Subject();
15
15
  stackEndReached = new Subject();
16
- setState = new Subject();
17
16
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UndoRedoService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
18
17
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: UndoRedoService });
19
18
  }
@@ -139,6 +139,12 @@ export class UndoRedoStack {
139
139
  this.currentNode = this.currentNode.previous;
140
140
  return this.currentNode.state;
141
141
  }
142
+ peekNext() {
143
+ return this.currentNode.next?.state || null;
144
+ }
145
+ peekPrev() {
146
+ return this.currentNode.previous?.state || null;
147
+ }
142
148
  /**
143
149
  * Performs a redo operation, moving to the next state
144
150
  * @returns The next state or null if can't redo
package/esm2022/utils.mjs CHANGED
@@ -4,6 +4,7 @@
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { InjectionToken } from '@angular/core';
6
6
  import { merge, of } from 'rxjs';
7
+ import { isDocumentAvailable } from '@progress/kendo-angular-common';
7
8
  export { isChanged, anyChanged, hasObservers } from '@progress/kendo-angular-common';
8
9
  const EMPTY_REGEX = /^\s*$/;
9
10
  /**
@@ -199,3 +200,21 @@ export const isMultipleRangesEnabled = (selectableSettings) => {
199
200
  typeof selectableSettings === 'object' &&
200
201
  selectableSettings.selectable.multipleRanges;
201
202
  };
203
+ /**
204
+ * @hidden
205
+ * Calculates the height of a table row by inserting a temporary row into the table body when the `rowHeight` option is not set.
206
+ */
207
+ export const calcRowHeight = (tableBody) => {
208
+ let result = 0;
209
+ if (!isDocumentAvailable()) {
210
+ return result;
211
+ }
212
+ if (tableBody) {
213
+ const row = tableBody.insertRow(0);
214
+ const cell = row.insertCell(0);
215
+ cell.textContent = ' ';
216
+ result = row.getBoundingClientRect().height;
217
+ tableBody.deleteRow(0);
218
+ }
219
+ return result;
220
+ };