@sankhyalabs/core 1.0.70 → 1.0.71-beta.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/.eslintrc.cjs +2 -1
- package/.releaserc +1 -1
- package/dist/dataunit/DataUnit.d.ts +33 -18
- package/dist/dataunit/DataUnit.js +220 -93
- package/dist/dataunit/DataUnit.js.map +1 -1
- package/dist/dataunit/loading/LoadDataRequest.d.ts +9 -0
- package/dist/dataunit/loading/LoadDataRequest.js +2 -0
- package/dist/dataunit/loading/LoadDataRequest.js.map +1 -0
- package/dist/dataunit/loading/LoadDataResponse.d.ts +6 -0
- package/dist/dataunit/loading/LoadDataResponse.js +2 -0
- package/dist/dataunit/loading/LoadDataResponse.js.map +1 -0
- package/dist/dataunit/loading/PaginationInfo.d.ts +7 -0
- package/dist/dataunit/loading/PaginationInfo.js +2 -0
- package/dist/dataunit/loading/PaginationInfo.js.map +1 -0
- package/dist/dataunit/state/action/DataUnitAction.d.ts +4 -0
- package/dist/dataunit/state/action/DataUnitAction.js.map +1 -1
- package/dist/dataunit/state/slice/ChangesSlice.d.ts +1 -0
- package/dist/dataunit/state/slice/ChangesSlice.js +3 -0
- package/dist/dataunit/state/slice/ChangesSlice.js.map +1 -1
- package/dist/dataunit/state/slice/LoadingControlSlice.d.ts +19 -0
- package/dist/dataunit/state/slice/LoadingControlSlice.js +45 -0
- package/dist/dataunit/state/slice/LoadingControlSlice.js.map +1 -0
- package/dist/dataunit/state/slice/RecordsSlice.js +2 -2
- package/dist/dataunit/state/slice/RecordsSlice.js.map +1 -1
- package/dist/dataunit/state/slice/SelectionSlice.js +0 -4
- package/dist/dataunit/state/slice/SelectionSlice.js.map +1 -1
- package/dist/dataunit/state/slice/WaitingChangesSlice.js.map +1 -1
- package/dist/exceptions/ErrorException.d.ts +2 -1
- package/dist/exceptions/ErrorException.js +2 -1
- package/dist/exceptions/ErrorException.js.map +1 -1
- package/dist/exceptions/WarningException.d.ts +2 -1
- package/dist/exceptions/WarningException.js +2 -1
- package/dist/exceptions/WarningException.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/ui/FloatingManager.d.ts +1 -0
- package/dist/ui/FloatingManager.js +1 -1
- package/dist/ui/FloatingManager.js.map +1 -1
- package/dist/utils/ArrayUtils.d.ts +13 -0
- package/dist/utils/ArrayUtils.js +27 -0
- package/dist/utils/ArrayUtils.js.map +1 -0
- package/dist/utils/NumberUtils.d.ts +8 -0
- package/dist/utils/NumberUtils.js +10 -0
- package/dist/utils/NumberUtils.js.map +1 -1
- package/dist/utils/StringUtils.d.ts +16 -2
- package/dist/utils/StringUtils.js +45 -3
- package/dist/utils/StringUtils.js.map +1 -1
- package/jest.config.ts +5 -5
- package/package.json +1 -1
- package/src/dataunit/DataUnit.ts +240 -102
- package/src/dataunit/loading/LoadDataRequest.ts +10 -0
- package/src/dataunit/loading/LoadDataResponse.ts +7 -0
- package/src/dataunit/loading/PaginationInfo.ts +8 -0
- package/src/dataunit/state/action/DataUnitAction.ts +4 -0
- package/src/dataunit/state/slice/ChangesSlice.ts +4 -0
- package/src/dataunit/state/slice/LoadingControlSlice.ts +60 -0
- package/src/dataunit/state/slice/RecordsSlice.ts +3 -5
- package/src/dataunit/state/slice/SelectionSlice.ts +0 -5
- package/src/dataunit/state/slice/WaitingChangesSlice.ts +0 -1
- package/src/exceptions/ErrorException.ts +3 -1
- package/src/exceptions/WarningException.ts +4 -1
- package/src/index.ts +15 -3
- package/src/ui/FloatingManager.ts +2 -1
- package/src/utils/ArrayUtils.ts +28 -0
- package/src/utils/NumberUtils.ts +10 -0
- package/src/utils/StringUtils.ts +53 -3
package/src/dataunit/DataUnit.ts
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
import { UnitMetadata, FieldDescriptor, SortingProvider, FilterProvider, Sort, Filter } from "./metadata/UnitMetadata.js";
|
|
2
1
|
import { convertType, toString } from "./metadata/DataType.js";
|
|
2
|
+
import { FieldDescriptor, Filter, FilterProvider, Sort, SortingProvider, UnitMetadata } from "./metadata/UnitMetadata.js";
|
|
3
3
|
|
|
4
|
-
import { DataUnitAction,
|
|
4
|
+
import { Action, DataUnitAction, ExecutionContext } from "./state/action/DataUnitAction.js";
|
|
5
5
|
import StateManager from "./state/StateManager.js";
|
|
6
6
|
|
|
7
|
-
import { HistReducer, canRedo, canUndo } from "./state/HistReducer.js";
|
|
8
|
-
import { UnitMetadataReducer, getField, getMetadata } from "./state/slice/UnitMetadataSlice.js";
|
|
9
|
-
import { RecordsReducer } from "./state/slice/RecordsSlice.js";
|
|
10
|
-
import { SelectionReducer, getSelection, hasNext, hasPrevious } from "./state/slice/SelectionSlice.js";
|
|
11
|
-
import { ChangesReducer, isDirty, getChangesToSave } from "./state/slice/ChangesSlice.js";
|
|
12
|
-
import { RemovedRecordsReducer } from "./state/slice/RemovedRecordsSlice.js";
|
|
13
|
-
import { AddedRecordsReducer, prepareAddedRecordId, prepareCopiedRecord } from "./state/slice/AddedRecordsSlice.js";
|
|
14
|
-
import { CurrentRecordsReducer, getCurrentRecords, getFieldValue, getModifiedRecords } from "./state/slice/CurrentRecordsSlice.js";
|
|
15
|
-
import { getBlockingWaitingChanges, getWaitingChangePromisses, getWaitingChanges, isWaiting, WaitingChangesReducer } from "./state/slice/WaitingChangesSlice.js";
|
|
16
|
-
import WaitingChangeException from "../exceptions/WaitingChangeException.js";
|
|
17
7
|
import ErrorException from "../exceptions/ErrorException.js";
|
|
8
|
+
import WaitingChangeException from "../exceptions/WaitingChangeException.js";
|
|
18
9
|
import { StringUtils } from "../utils/StringUtils.js";
|
|
10
|
+
import { LoadDataRequest } from "./loading/LoadDataRequest.js";
|
|
11
|
+
import { LoadDataResponse } from "./loading/LoadDataResponse.js";
|
|
12
|
+
import { PaginationInfo } from "./loading/PaginationInfo.js";
|
|
13
|
+
import { AddedRecordsReducer, prepareAddedRecordId, prepareCopiedRecord } from "./state/slice/AddedRecordsSlice.js";
|
|
14
|
+
import { ChangesReducer, getChangesToSave, isDirty, hasDirtyRecords } from "./state/slice/ChangesSlice.js";
|
|
15
|
+
import { CurrentRecordsReducer, getCurrentRecords, getFieldValue, getModifiedRecords } from "./state/slice/CurrentRecordsSlice.js";
|
|
16
|
+
import { getCurrentPage, getLastPage, getPaginationInfo, getCurrentRequest, LoadingControlReducer, hasMorePages, hasPreviousPages } from "./state/slice/LoadingControlSlice.js";
|
|
17
|
+
import { RecordsReducer } from "./state/slice/RecordsSlice.js";
|
|
18
|
+
import { RemovedRecordsReducer } from "./state/slice/RemovedRecordsSlice.js";
|
|
19
|
+
import { getSelection, hasNext, hasPrevious, SelectionReducer } from "./state/slice/SelectionSlice.js";
|
|
20
|
+
import { getField, getMetadata, UnitMetadataReducer } from "./state/slice/UnitMetadataSlice.js";
|
|
21
|
+
import { getBlockingWaitingChanges, getWaitingChangePromisses, isWaiting, WaitingChangesReducer } from "./state/slice/WaitingChangesSlice.js";
|
|
22
|
+
import { canRedo, canUndo, HistReducer } from "./state/HistReducer.js";
|
|
19
23
|
|
|
20
24
|
export default class DataUnit {
|
|
21
25
|
|
|
@@ -25,18 +29,21 @@ export default class DataUnit {
|
|
|
25
29
|
private _filterProviders: Map<string, FilterProvider>;
|
|
26
30
|
private _stateManager: StateManager;
|
|
27
31
|
private _interceptors: Array<DUActionInterceptor>;
|
|
32
|
+
private _pageSize: number;
|
|
28
33
|
|
|
29
34
|
public metadataLoader?: (dataUnit: DataUnit) => Promise<UnitMetadata>;
|
|
30
|
-
public dataLoader?: (dataUnit: DataUnit,
|
|
35
|
+
public dataLoader?: (dataUnit: DataUnit, request: LoadDataRequest) => Promise<LoadDataResponse>;
|
|
31
36
|
public saveLoader?: (dataUnit: DataUnit, changes: Array<Change>) => Promise<Array<SavedRecord>>;
|
|
32
37
|
public removeLoader?: (dataUnit: DataUnit, recordIds: Array<string>) => Promise<Array<string>>;
|
|
33
38
|
|
|
34
39
|
constructor(name: string) {
|
|
35
40
|
this._name = name;
|
|
41
|
+
this._pageSize = 0;
|
|
36
42
|
this._stateManager = new StateManager(
|
|
37
43
|
[
|
|
38
44
|
HistReducer,
|
|
39
45
|
UnitMetadataReducer,
|
|
46
|
+
LoadingControlReducer,
|
|
40
47
|
RecordsReducer,
|
|
41
48
|
RemovedRecordsReducer,
|
|
42
49
|
AddedRecordsReducer,
|
|
@@ -58,7 +65,6 @@ export default class DataUnit {
|
|
|
58
65
|
|
|
59
66
|
// Métodos privados
|
|
60
67
|
private validateAndTypeValue(fieldName: string, newValue: any): any {
|
|
61
|
-
//FIXME: Validações devem ser feitas aqui
|
|
62
68
|
const descriptor: FieldDescriptor | undefined = this.getField(fieldName);
|
|
63
69
|
return descriptor ? convertType(descriptor.dataType, newValue) : newValue;
|
|
64
70
|
}
|
|
@@ -78,16 +84,34 @@ export default class DataUnit {
|
|
|
78
84
|
return this._sortingProvider ? this._sortingProvider.getSort(this._name) : undefined;
|
|
79
85
|
}
|
|
80
86
|
|
|
81
|
-
private getFielterProviderKey(provider:FilterProvider):string{
|
|
82
|
-
if(provider.getKey){
|
|
87
|
+
private getFielterProviderKey(provider: FilterProvider): string {
|
|
88
|
+
if (provider.getKey) {
|
|
83
89
|
return provider.getKey();
|
|
84
90
|
}
|
|
85
91
|
return StringUtils.hashCode(provider.getFilter.toString());
|
|
86
92
|
}
|
|
87
93
|
|
|
94
|
+
private executeLoadData(request: LoadDataRequest, executionCtx?: ExecutionContext): Promise<LoadDataResponse> {
|
|
95
|
+
return new Promise(async (resolve, fail) => {
|
|
96
|
+
if (await this.dispatchAction(Action.LOADING_DATA, request, executionCtx)) {
|
|
97
|
+
if (this.dataLoader) {
|
|
98
|
+
this.dataLoader(this, request).then(
|
|
99
|
+
response => {
|
|
100
|
+
this.dispatchAction(Action.DATA_LOADED, response, executionCtx);
|
|
101
|
+
resolve(response);
|
|
102
|
+
}
|
|
103
|
+
).catch(error => {
|
|
104
|
+
const {errorCode} = error;
|
|
105
|
+
fail(new ErrorException("Problema carregando registros", error, errorCode))
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
88
112
|
// Loaders
|
|
89
|
-
public async loadMetadata(): Promise<UnitMetadata|void> {
|
|
90
|
-
if(this.dispatchAction(Action.LOADING_METADATA)){
|
|
113
|
+
public async loadMetadata(executionCtx?: ExecutionContext): Promise<UnitMetadata | void> {
|
|
114
|
+
if (await this.dispatchAction(Action.LOADING_METADATA, undefined, executionCtx)) {
|
|
91
115
|
return new Promise((resolve, fail) => {
|
|
92
116
|
if (this.metadataLoader) {
|
|
93
117
|
this.metadataLoader(this).then(
|
|
@@ -95,30 +119,60 @@ export default class DataUnit {
|
|
|
95
119
|
this.metadata = metadata
|
|
96
120
|
resolve(this.metadata);
|
|
97
121
|
}
|
|
98
|
-
).catch(error =>
|
|
122
|
+
).catch(error => {
|
|
123
|
+
const {errorCode} = error;
|
|
124
|
+
fail(new ErrorException("Problema carregando metadados", error, errorCode))
|
|
125
|
+
});
|
|
99
126
|
}
|
|
100
127
|
});
|
|
101
128
|
}
|
|
102
129
|
}
|
|
103
130
|
|
|
104
|
-
public async loadData(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
).catch(error => fail(new ErrorException("Problema carregando registros", error)));
|
|
116
|
-
}
|
|
117
|
-
});
|
|
131
|
+
public async loadData(quickFilter?: QuickFilter, executionCtx?: ExecutionContext): Promise<LoadDataResponse> {
|
|
132
|
+
|
|
133
|
+
const loadDataRequest: LoadDataRequest = {
|
|
134
|
+
quickFilter,
|
|
135
|
+
filters: this.getFilters(),
|
|
136
|
+
sort: this.getSort()
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
if (this._pageSize > 0) {
|
|
140
|
+
loadDataRequest.limit = this._pageSize
|
|
141
|
+
loadDataRequest.offset = 0;
|
|
118
142
|
}
|
|
143
|
+
|
|
144
|
+
return this.executeLoadData(loadDataRequest, executionCtx);
|
|
119
145
|
}
|
|
120
146
|
|
|
121
|
-
public async
|
|
147
|
+
public async gotoPage(page: number, executionCtx?: ExecutionContext): Promise<LoadDataResponse | void> {
|
|
148
|
+
|
|
149
|
+
let request = getCurrentRequest(this._stateManager);
|
|
150
|
+
|
|
151
|
+
if (!request) {
|
|
152
|
+
request = {
|
|
153
|
+
filters: this.getFilters(),
|
|
154
|
+
sort: this.getSort()
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (page >= 0 && page <= getLastPage(this._stateManager, this._pageSize)) {
|
|
159
|
+
return this.executeLoadData({
|
|
160
|
+
...request,
|
|
161
|
+
limit: this._pageSize,
|
|
162
|
+
offset: page * this._pageSize
|
|
163
|
+
}, executionCtx);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
public async nextPage(executionCtx?: ExecutionContext): Promise<LoadDataResponse | void> {
|
|
168
|
+
return this.gotoPage(getCurrentPage(this._stateManager) + 1, executionCtx);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
public async previousPage(executionCtx?: ExecutionContext): Promise<LoadDataResponse | void> {
|
|
172
|
+
return this.gotoPage(getCurrentPage(this._stateManager) - 1, executionCtx);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
public async saveData(executionCtx?: ExecutionContext): Promise<void> {
|
|
122
176
|
const blockingWaitingChanges = getBlockingWaitingChanges(this._stateManager);
|
|
123
177
|
|
|
124
178
|
if (blockingWaitingChanges && blockingWaitingChanges.size > 0) {
|
|
@@ -126,8 +180,8 @@ export default class DataUnit {
|
|
|
126
180
|
return Promise.reject(new WaitingChangeException("Aguardando alteração de campo", (waitingChange as WaitingChange).waitmessage));
|
|
127
181
|
} else {
|
|
128
182
|
if (isDirty(this._stateManager)) {
|
|
129
|
-
|
|
130
|
-
if (this.dispatchAction(Action.SAVING_DATA)) {
|
|
183
|
+
|
|
184
|
+
if (await this.dispatchAction(Action.SAVING_DATA, undefined, executionCtx)) {
|
|
131
185
|
const promisses = getWaitingChangePromisses(this._stateManager);
|
|
132
186
|
return new Promise((resolve, fail) => {
|
|
133
187
|
Promise.all(promisses || []).then(() => {
|
|
@@ -135,10 +189,13 @@ export default class DataUnit {
|
|
|
135
189
|
const changes: Array<Change> = getChangesToSave(this._name, this._stateManager);
|
|
136
190
|
this.saveLoader(this, changes).then(
|
|
137
191
|
records => {
|
|
138
|
-
this.dispatchAction(Action.DATA_SAVED, { changes, records });
|
|
192
|
+
this.dispatchAction(Action.DATA_SAVED, { changes, records }, executionCtx);
|
|
139
193
|
resolve();
|
|
140
194
|
}
|
|
141
|
-
).catch(cause =>
|
|
195
|
+
).catch(cause => {
|
|
196
|
+
const {errorCode} = cause;
|
|
197
|
+
fail(new ErrorException("Erro salvando alterações", cause, errorCode));
|
|
198
|
+
});
|
|
142
199
|
} else {
|
|
143
200
|
resolve();
|
|
144
201
|
}
|
|
@@ -154,44 +211,48 @@ export default class DataUnit {
|
|
|
154
211
|
public async removeSelectedRecords(buffered: boolean = false): Promise<Array<string>> {
|
|
155
212
|
const selection = getSelection(this._stateManager);
|
|
156
213
|
if (selection) {
|
|
157
|
-
|
|
214
|
+
const records = this.getSelectedRecords() || [];
|
|
215
|
+
return this.removeRecords(selection, records, buffered);
|
|
158
216
|
}
|
|
159
217
|
return Promise.resolve(selection);
|
|
160
218
|
}
|
|
161
219
|
|
|
162
|
-
public async removeRecords(
|
|
163
|
-
if (
|
|
220
|
+
public async removeRecords(recordIds: Array<string>, cachedRecords: Array<Record>, buffered: boolean = false, executionCtx?: ExecutionContext): Promise<Array<string>> {
|
|
221
|
+
if (recordIds) {
|
|
164
222
|
if (buffered || !this.removeLoader) {
|
|
165
|
-
this.dispatchAction(Action.RECORDS_REMOVED, { records, buffered: true });
|
|
223
|
+
this.dispatchAction(Action.RECORDS_REMOVED, { records: recordIds, cachedRecords, buffered: true }, executionCtx);
|
|
166
224
|
} else {
|
|
167
|
-
if (this.dispatchAction(Action.REMOVING_RECORDS)) {
|
|
225
|
+
if (await this.dispatchAction(Action.REMOVING_RECORDS, undefined, executionCtx)) {
|
|
168
226
|
|
|
169
227
|
return new Promise((resolve, fail) => {
|
|
170
228
|
if (this.removeLoader) {
|
|
171
|
-
this.removeLoader(this,
|
|
172
|
-
|
|
229
|
+
this.removeLoader(this, recordIds).then(
|
|
230
|
+
removedIds => {
|
|
173
231
|
let currentIndex = 0;
|
|
174
232
|
const removedIndex: Array<number> = [];
|
|
175
233
|
const currentRecords = getCurrentRecords(this._stateManager);
|
|
176
234
|
|
|
177
235
|
currentRecords.forEach((value, key) => {
|
|
178
|
-
if (
|
|
236
|
+
if (removedIds.includes(key)) {
|
|
179
237
|
removedIndex.push(currentIndex);
|
|
180
238
|
}
|
|
181
239
|
|
|
182
240
|
currentIndex++
|
|
183
241
|
});
|
|
184
242
|
|
|
185
|
-
this.dispatchAction(Action.RECORDS_REMOVED, { records, removedIndex, buffered: false });
|
|
186
|
-
resolve(
|
|
243
|
+
this.dispatchAction(Action.RECORDS_REMOVED, { records: removedIds, cachedRecords, removedIndex, buffered: false }, executionCtx);
|
|
244
|
+
resolve(removedIds);
|
|
187
245
|
}
|
|
188
|
-
).catch(error =>
|
|
246
|
+
).catch(error => {
|
|
247
|
+
const {errorCode} = error;
|
|
248
|
+
fail(new ErrorException("Problema removendo registros", error, errorCode))
|
|
249
|
+
});
|
|
189
250
|
}
|
|
190
251
|
});
|
|
191
252
|
}
|
|
192
253
|
}
|
|
193
254
|
}
|
|
194
|
-
return Promise.resolve(
|
|
255
|
+
return Promise.resolve(recordIds);
|
|
195
256
|
}
|
|
196
257
|
|
|
197
258
|
// API
|
|
@@ -217,12 +278,16 @@ export default class DataUnit {
|
|
|
217
278
|
this._filterProviders.set(this.getFielterProviderKey(provider), provider);
|
|
218
279
|
}
|
|
219
280
|
|
|
281
|
+
public getPaginationInfo(): PaginationInfo | void {
|
|
282
|
+
return getPaginationInfo(this._stateManager);
|
|
283
|
+
}
|
|
284
|
+
|
|
220
285
|
public set sortingProvider(provider: SortingProvider) {
|
|
221
286
|
this._sortingProvider = provider;
|
|
222
287
|
}
|
|
223
288
|
|
|
224
289
|
public set metadata(md: UnitMetadata) {
|
|
225
|
-
this.dispatchAction(Action.METADATA_LOADED, md);
|
|
290
|
+
this.dispatchAction(Action.METADATA_LOADED, md, undefined);
|
|
226
291
|
}
|
|
227
292
|
|
|
228
293
|
public get metadata(): UnitMetadata {
|
|
@@ -230,7 +295,7 @@ export default class DataUnit {
|
|
|
230
295
|
}
|
|
231
296
|
|
|
232
297
|
public set records(r: Array<Record>) {
|
|
233
|
-
this.dispatchAction(Action.DATA_LOADED,
|
|
298
|
+
this.dispatchAction(Action.DATA_LOADED, { records: this.records }, undefined);
|
|
234
299
|
}
|
|
235
300
|
|
|
236
301
|
public get records(): Array<Record> {
|
|
@@ -238,6 +303,14 @@ export default class DataUnit {
|
|
|
238
303
|
return records ? Array.from(records.values()) : [];
|
|
239
304
|
}
|
|
240
305
|
|
|
306
|
+
public set pageSize(size: number) {
|
|
307
|
+
this._pageSize = size;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
public get pageSize(): number {
|
|
311
|
+
return this._pageSize;
|
|
312
|
+
}
|
|
313
|
+
|
|
241
314
|
public getModifiedRecords(): Array<Record> {
|
|
242
315
|
const modified = getModifiedRecords(this._stateManager);
|
|
243
316
|
return modified || [];
|
|
@@ -247,14 +320,14 @@ export default class DataUnit {
|
|
|
247
320
|
return getField(this._stateManager, fieldName);
|
|
248
321
|
}
|
|
249
322
|
|
|
250
|
-
public addRecord(): void {
|
|
251
|
-
this.dispatchAction(Action.RECORDS_ADDED, prepareAddedRecordId(this._stateManager, [{}]));
|
|
323
|
+
public addRecord(executionCtx?: ExecutionContext): void {
|
|
324
|
+
this.dispatchAction(Action.RECORDS_ADDED, prepareAddedRecordId(this._stateManager, [{}]), executionCtx);
|
|
252
325
|
}
|
|
253
326
|
|
|
254
|
-
public copySelected(): void {
|
|
327
|
+
public copySelected(executionCtx?: ExecutionContext): void {
|
|
255
328
|
const selectedRecords = this.getSelectedRecords();
|
|
256
329
|
if (selectedRecords) {
|
|
257
|
-
this.dispatchAction(Action.RECORDS_COPIED, prepareCopiedRecord(this._stateManager, selectedRecords));
|
|
330
|
+
this.dispatchAction(Action.RECORDS_COPIED, prepareCopiedRecord(this._stateManager, selectedRecords), executionCtx);
|
|
258
331
|
}
|
|
259
332
|
}
|
|
260
333
|
|
|
@@ -272,38 +345,42 @@ export default class DataUnit {
|
|
|
272
345
|
const currentValue = this.getFieldValue(fieldName);
|
|
273
346
|
|
|
274
347
|
if (currentValue !== typedValue) {
|
|
275
|
-
this.dispatchAction(Action.DATA_CHANGED, { [fieldName]: typedValue, records });
|
|
348
|
+
this.dispatchAction(Action.DATA_CHANGED, { [fieldName]: typedValue, records }, undefined);
|
|
276
349
|
}
|
|
277
350
|
}
|
|
278
351
|
|
|
279
352
|
public startChange(fieldName: string, waitingChange: WaitingChange): void {
|
|
280
|
-
this.dispatchAction(Action.CHANGING_DATA, { [fieldName]: waitingChange });
|
|
353
|
+
this.dispatchAction(Action.CHANGING_DATA, { [fieldName]: waitingChange }, undefined);
|
|
281
354
|
}
|
|
282
355
|
|
|
283
356
|
public cancelWaitingChange(fieldName: string): void {
|
|
284
|
-
this.dispatchAction(Action.WAITING_CHANGE_CANCELED, { fieldName });
|
|
357
|
+
this.dispatchAction(Action.WAITING_CHANGE_CANCELED, { fieldName }, undefined);
|
|
285
358
|
}
|
|
286
359
|
|
|
287
360
|
public getSelection(): Array<string> {
|
|
288
361
|
return getSelection(this._stateManager);
|
|
289
362
|
}
|
|
290
363
|
|
|
291
|
-
public setSelection(selection: Array<string
|
|
292
|
-
this.dispatchAction(Action.SELECTION_CHANGED, { type: "id", selection });
|
|
364
|
+
public setSelection(selection: Array<string>, executionCtx?: ExecutionContext): void {
|
|
365
|
+
this.dispatchAction(Action.SELECTION_CHANGED, { type: "id", selection }, executionCtx);
|
|
293
366
|
}
|
|
294
367
|
|
|
295
|
-
public selectFirst(): void {
|
|
296
|
-
if(this.records.length > 0){
|
|
297
|
-
this.
|
|
368
|
+
public selectFirst(executionCtx?: ExecutionContext): void {
|
|
369
|
+
if (this.records.length > 0) {
|
|
370
|
+
this.setSelectionByIndex([0], executionCtx);
|
|
298
371
|
}
|
|
299
372
|
}
|
|
300
373
|
|
|
301
|
-
public selectLast(): void {
|
|
302
|
-
if(this.records.length > 0){
|
|
303
|
-
this.
|
|
374
|
+
public selectLast(executionCtx?: ExecutionContext): void {
|
|
375
|
+
if (this.records.length > 0) {
|
|
376
|
+
this.setSelectionByIndex([this.records.length - 1], executionCtx);
|
|
304
377
|
}
|
|
305
378
|
}
|
|
306
379
|
|
|
380
|
+
public setSelectionByIndex(selection: Array<number>, executionCtx?: ExecutionContext): void {
|
|
381
|
+
this.dispatchAction(Action.SELECTION_CHANGED, { type: "index", selection }, executionCtx);
|
|
382
|
+
}
|
|
383
|
+
|
|
307
384
|
public getSelectedRecords(): Array<Record> | undefined {
|
|
308
385
|
const selection: Array<string> = this.getSelection();
|
|
309
386
|
if (selection) {
|
|
@@ -312,28 +389,72 @@ export default class DataUnit {
|
|
|
312
389
|
}
|
|
313
390
|
}
|
|
314
391
|
|
|
315
|
-
public nextRecord(): void {
|
|
316
|
-
this.
|
|
392
|
+
public nextRecord(executionCtx?: ExecutionContext): void {
|
|
393
|
+
if(!hasNext(this._stateManager)){
|
|
394
|
+
if(hasMorePages(this._stateManager)){
|
|
395
|
+
this.nextPage({
|
|
396
|
+
before: act =>{
|
|
397
|
+
if(executionCtx && executionCtx.before){
|
|
398
|
+
act = executionCtx.before(act);
|
|
399
|
+
}
|
|
400
|
+
return act;
|
|
401
|
+
},
|
|
402
|
+
after: act => {
|
|
403
|
+
this.selectFirst(executionCtx);
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
} else {
|
|
408
|
+
this.dispatchAction(Action.NEXT_SELECTED, undefined, executionCtx);
|
|
409
|
+
}
|
|
317
410
|
}
|
|
318
411
|
|
|
319
|
-
public previousRecord(): void {
|
|
320
|
-
this.
|
|
412
|
+
public previousRecord(executionCtx?: ExecutionContext): void {
|
|
413
|
+
if(!hasPrevious(this._stateManager)){
|
|
414
|
+
if(hasPreviousPages(this._stateManager)){
|
|
415
|
+
this.previousPage({
|
|
416
|
+
before: act =>{
|
|
417
|
+
if(executionCtx && executionCtx.before){
|
|
418
|
+
act = executionCtx.before(act);
|
|
419
|
+
}
|
|
420
|
+
return act;
|
|
421
|
+
},
|
|
422
|
+
after: act => {
|
|
423
|
+
this.selectLast(executionCtx);
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
} else {
|
|
428
|
+
this.dispatchAction(Action.PREVIOUS_SELECTED, undefined, executionCtx);
|
|
429
|
+
}
|
|
321
430
|
}
|
|
322
431
|
|
|
323
|
-
public cancelEdition(): void {
|
|
324
|
-
this.dispatchAction(Action.EDITION_CANCELED);
|
|
432
|
+
public cancelEdition(executionCtx?: ExecutionContext): void {
|
|
433
|
+
this.dispatchAction(Action.EDITION_CANCELED, undefined, executionCtx);
|
|
325
434
|
}
|
|
326
435
|
|
|
327
436
|
public isDirty(): boolean {
|
|
328
437
|
return isDirty(this._stateManager);
|
|
329
438
|
}
|
|
330
439
|
|
|
440
|
+
public hasDirtyRecords(): boolean {
|
|
441
|
+
return hasDirtyRecords(this._stateManager);
|
|
442
|
+
}
|
|
443
|
+
|
|
331
444
|
public hasNext(): boolean {
|
|
332
|
-
|
|
445
|
+
let result = hasNext(this._stateManager);
|
|
446
|
+
if(!result){
|
|
447
|
+
result = hasMorePages(this._stateManager);
|
|
448
|
+
}
|
|
449
|
+
return result;
|
|
333
450
|
}
|
|
334
451
|
|
|
335
452
|
public hasPrevious(): boolean {
|
|
336
|
-
|
|
453
|
+
let result = hasPrevious(this._stateManager);
|
|
454
|
+
if(!result){
|
|
455
|
+
result = hasPreviousPages(this._stateManager);
|
|
456
|
+
}
|
|
457
|
+
return result;
|
|
337
458
|
}
|
|
338
459
|
|
|
339
460
|
public canUndo(): boolean {
|
|
@@ -344,12 +465,12 @@ export default class DataUnit {
|
|
|
344
465
|
return canRedo(this._stateManager);
|
|
345
466
|
}
|
|
346
467
|
|
|
347
|
-
public undo() {
|
|
348
|
-
this.dispatchAction(Action.CHANGE_UNDONE);
|
|
468
|
+
public undo(executionCtx?: ExecutionContext) {
|
|
469
|
+
this.dispatchAction(Action.CHANGE_UNDONE, undefined, executionCtx);
|
|
349
470
|
}
|
|
350
471
|
|
|
351
|
-
public redo() {
|
|
352
|
-
this.dispatchAction(Action.CHANGE_REDONE);
|
|
472
|
+
public redo(executionCtx?: ExecutionContext) {
|
|
473
|
+
this.dispatchAction(Action.CHANGE_REDONE, undefined, executionCtx);
|
|
353
474
|
}
|
|
354
475
|
|
|
355
476
|
public toString() {
|
|
@@ -357,33 +478,50 @@ export default class DataUnit {
|
|
|
357
478
|
}
|
|
358
479
|
|
|
359
480
|
// Actions / State manager
|
|
360
|
-
private dispatchAction(actionType: Action, payload?: any): boolean {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
481
|
+
private async dispatchAction(actionType: Action, payload?: any, executionCtx?: ExecutionContext): Promise<boolean> {
|
|
482
|
+
return new Promise(async resolve => {
|
|
483
|
+
let action = new DataUnitAction(actionType, payload);
|
|
484
|
+
if (executionCtx && executionCtx.before) {
|
|
485
|
+
action = executionCtx.before(action);
|
|
486
|
+
}
|
|
487
|
+
if (action && this._interceptors && this._interceptors.length > 0) {
|
|
488
|
+
action = await this.intercept(action, this._interceptors.values());
|
|
489
|
+
}
|
|
364
490
|
if (action) {
|
|
365
|
-
|
|
491
|
+
this.doDispatchAction(action);
|
|
492
|
+
if (executionCtx && executionCtx.after) {
|
|
493
|
+
executionCtx.after(action)
|
|
494
|
+
}
|
|
495
|
+
resolve(true);
|
|
496
|
+
} else {
|
|
497
|
+
resolve(false);
|
|
366
498
|
}
|
|
367
499
|
});
|
|
500
|
+
}
|
|
368
501
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
502
|
+
private async intercept(action: DataUnitAction, interceptors: IterableIterator<DUActionInterceptor>): Promise<DataUnitAction> {
|
|
503
|
+
return new Promise(async resolve => {
|
|
504
|
+
let ite;
|
|
505
|
+
while (action && !(ite = interceptors.next()).done) {
|
|
506
|
+
action = await ite.value.interceptAction(action);
|
|
507
|
+
}
|
|
508
|
+
resolve(action);
|
|
509
|
+
});
|
|
510
|
+
}
|
|
372
511
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
return true;
|
|
512
|
+
private doDispatchAction(action: DataUnitAction) {
|
|
513
|
+
this._stateManager.process(action);
|
|
514
|
+
this._observers.forEach(f => {
|
|
515
|
+
/*
|
|
516
|
+
if some observer throws exceptions,
|
|
517
|
+
should be continued
|
|
518
|
+
*/
|
|
519
|
+
try {
|
|
520
|
+
f(action);
|
|
521
|
+
} catch (e) {
|
|
522
|
+
console.warn("[DataUnit] error while call observer", e);
|
|
523
|
+
}
|
|
524
|
+
});
|
|
387
525
|
}
|
|
388
526
|
|
|
389
527
|
public subscribe(observer: (action: DataUnitAction) => void) {
|
|
@@ -396,7 +534,7 @@ export default class DataUnit {
|
|
|
396
534
|
}
|
|
397
535
|
|
|
398
536
|
export interface DUActionInterceptor {
|
|
399
|
-
interceptAction(action: DataUnitAction): DataUnitAction
|
|
537
|
+
interceptAction(action: DataUnitAction): DataUnitAction | Promise<DataUnitAction>;
|
|
400
538
|
}
|
|
401
539
|
|
|
402
540
|
export interface Record {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { QuickFilter } from "../DataUnit.js";
|
|
2
|
+
import { Filter, Sort } from "../metadata/UnitMetadata.js";
|
|
3
|
+
|
|
4
|
+
export interface LoadDataRequest {
|
|
5
|
+
offset?: number;
|
|
6
|
+
limit?: number;
|
|
7
|
+
quickFilter?: QuickFilter;
|
|
8
|
+
filters?: Array<Filter>;
|
|
9
|
+
sort?: Array<Sort>;
|
|
10
|
+
}
|
|
@@ -19,6 +19,10 @@ export class DataUnitAction implements StateAction{
|
|
|
19
19
|
return this._payload;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
+
export interface ExecutionContext{
|
|
23
|
+
before?: (action: DataUnitAction) => DataUnitAction;
|
|
24
|
+
after?: (action: DataUnitAction) => void;
|
|
25
|
+
}
|
|
22
26
|
|
|
23
27
|
export enum Action{
|
|
24
28
|
|
|
@@ -68,6 +68,10 @@ export const isDirty = (stateManager: StateManager): boolean => {
|
|
|
68
68
|
return true;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
return hasDirtyRecords(stateManager);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const hasDirtyRecords = (stateManager: StateManager): boolean => {
|
|
71
75
|
if(getWaitingChanges(stateManager) !== undefined){
|
|
72
76
|
return true;
|
|
73
77
|
}
|