@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.
- package/aggregates/selection-aggregate.service.d.ts +1 -3
- package/column-menu/column-menu-item.directive.d.ts +1 -1
- package/common/provider.service.d.ts +2 -1
- package/data/data-mapping.service.d.ts +46 -0
- package/databinding.directive.d.ts +2 -1
- package/esm2022/aggregates/selection-aggregate.service.mjs +4 -8
- package/esm2022/column-menu/column-menu-item.directive.mjs +1 -1
- package/esm2022/common/provider.service.mjs +1 -1
- package/esm2022/data/data-mapping.service.mjs +125 -0
- package/esm2022/databinding.directive.mjs +12 -3
- package/esm2022/grid.component.mjs +41 -34
- package/esm2022/grouping/group-scroll-binding.directive.mjs +2 -2
- package/esm2022/package-metadata.mjs +2 -2
- package/esm2022/rendering/list.component.mjs +76 -57
- package/esm2022/rendering/table-body.component.mjs +37 -128
- package/esm2022/selection/selection-checkbox.directive.mjs +1 -1
- package/esm2022/selection/selection.service.mjs +23 -4
- package/esm2022/state-management/undo-redo.directive.mjs +74 -16
- package/esm2022/state-management/undo-redo.service.mjs +0 -1
- package/esm2022/state-management/undo-redo.stack.mjs +6 -0
- package/esm2022/utils.mjs +19 -0
- package/fesm2022/progress-kendo-angular-grid.mjs +934 -785
- package/grid.component.d.ts +12 -6
- package/package.json +20 -20
- package/rendering/list.component.d.ts +9 -6
- package/rendering/table-body.component.d.ts +9 -27
- package/schematics/ngAdd/index.js +4 -4
- package/selection/selection.service.d.ts +1 -1
- package/state-management/undo-redo.directive.d.ts +12 -2
- package/state-management/undo-redo.service.d.ts +0 -2
- package/state-management/undo-redo.stack.d.ts +2 -0
- 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
|
|
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:
|
|
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:
|
|
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')
|
|
112
|
+
.pipe(filter((event) => event.action === 'save' || event.action === 'remove'))
|
|
100
113
|
.subscribe(event => {
|
|
101
114
|
this.stack.add({
|
|
102
|
-
originalEvent: event,
|
|
103
|
-
gridState:
|
|
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(() =>
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
171
|
-
|
|
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
|
+
};
|