@sankhyalabs/core 1.0.71-beta.2 → 1.0.71-beta.3
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/dist/dataunit/DataUnit.d.ts +32 -18
- package/dist/dataunit/DataUnit.js +195 -84
- 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/LoadControlSlice.d.ts +18 -0
- package/dist/dataunit/state/slice/LoadControlSlice.js +41 -0
- package/dist/dataunit/state/slice/LoadControlSlice.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/WaitingChangesSlice.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/dataunit/DataUnit.ts +213 -92
- 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/LoadControlSlice.ts +55 -0
- package/src/dataunit/state/slice/RecordsSlice.ts +3 -5
- package/src/dataunit/state/slice/WaitingChangesSlice.ts +0 -1
- package/src/index.ts +13 -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 } from "./state/slice/ChangesSlice.js";
|
|
15
|
+
import { CurrentRecordsReducer, getCurrentRecords, getFieldValue, getModifiedRecords } from "./state/slice/CurrentRecordsSlice.js";
|
|
16
|
+
import { getCurrentPage, getLastPage, getPaginationInfo, getCurrentRequest, LoadControlReducer, hasMorePages } from "./state/slice/LoadControlSlice.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
|
+
LoadControlReducer,
|
|
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,31 @@ 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 => fail(new ErrorException("Problema carregando registros", error)));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
88
109
|
// Loaders
|
|
89
|
-
public async loadMetadata(): Promise<UnitMetadata|void> {
|
|
90
|
-
if(this.dispatchAction(Action.LOADING_METADATA)){
|
|
110
|
+
public async loadMetadata(executionCtx?: ExecutionContext): Promise<UnitMetadata | void> {
|
|
111
|
+
if (await this.dispatchAction(Action.LOADING_METADATA, undefined, executionCtx)) {
|
|
91
112
|
return new Promise((resolve, fail) => {
|
|
92
113
|
if (this.metadataLoader) {
|
|
93
114
|
this.metadataLoader(this).then(
|
|
@@ -101,24 +122,51 @@ export default class DataUnit {
|
|
|
101
122
|
}
|
|
102
123
|
}
|
|
103
124
|
|
|
104
|
-
public async loadData(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
125
|
+
public async loadData(quickFilter?: QuickFilter, executionCtx?: ExecutionContext): Promise<LoadDataResponse> {
|
|
126
|
+
|
|
127
|
+
const loadDataRequest: LoadDataRequest = {
|
|
128
|
+
quickFilter,
|
|
129
|
+
filters: this.getFilters(),
|
|
130
|
+
sort: this.getSort()
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
if (this._pageSize > 0) {
|
|
134
|
+
loadDataRequest.limit = this._pageSize
|
|
135
|
+
loadDataRequest.offset = 0;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return this.executeLoadData(loadDataRequest, executionCtx);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public async gotoPage(page: number, executionCtx?: ExecutionContext): Promise<LoadDataResponse | void> {
|
|
142
|
+
|
|
143
|
+
let request = getCurrentRequest(this._stateManager);
|
|
144
|
+
|
|
145
|
+
if (!request) {
|
|
146
|
+
request = {
|
|
147
|
+
filters: this.getFilters(),
|
|
148
|
+
sort: this.getSort()
|
|
149
|
+
}
|
|
118
150
|
}
|
|
151
|
+
|
|
152
|
+
if (page >= 0 && page <= getLastPage(this._stateManager, this._pageSize)) {
|
|
153
|
+
return this.executeLoadData({
|
|
154
|
+
...request,
|
|
155
|
+
limit: this._pageSize,
|
|
156
|
+
offset: page * this._pageSize
|
|
157
|
+
}, executionCtx);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
public async nextPage(executionCtx?: ExecutionContext): Promise<LoadDataResponse | void> {
|
|
162
|
+
return this.gotoPage(getCurrentPage(this._stateManager) + 1, executionCtx);
|
|
119
163
|
}
|
|
120
164
|
|
|
121
|
-
public async
|
|
165
|
+
public async previousPage(executionCtx?: ExecutionContext): Promise<LoadDataResponse | void> {
|
|
166
|
+
return this.gotoPage(getCurrentPage(this._stateManager) - 1, executionCtx);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public async saveData(executionCtx?: ExecutionContext): Promise<void> {
|
|
122
170
|
const blockingWaitingChanges = getBlockingWaitingChanges(this._stateManager);
|
|
123
171
|
|
|
124
172
|
if (blockingWaitingChanges && blockingWaitingChanges.size > 0) {
|
|
@@ -126,8 +174,8 @@ export default class DataUnit {
|
|
|
126
174
|
return Promise.reject(new WaitingChangeException("Aguardando alteração de campo", (waitingChange as WaitingChange).waitmessage));
|
|
127
175
|
} else {
|
|
128
176
|
if (isDirty(this._stateManager)) {
|
|
129
|
-
|
|
130
|
-
if (this.dispatchAction(Action.SAVING_DATA)) {
|
|
177
|
+
|
|
178
|
+
if (await this.dispatchAction(Action.SAVING_DATA, undefined, executionCtx)) {
|
|
131
179
|
const promisses = getWaitingChangePromisses(this._stateManager);
|
|
132
180
|
return new Promise((resolve, fail) => {
|
|
133
181
|
Promise.all(promisses || []).then(() => {
|
|
@@ -135,7 +183,7 @@ export default class DataUnit {
|
|
|
135
183
|
const changes: Array<Change> = getChangesToSave(this._name, this._stateManager);
|
|
136
184
|
this.saveLoader(this, changes).then(
|
|
137
185
|
records => {
|
|
138
|
-
this.dispatchAction(Action.DATA_SAVED, { changes, records });
|
|
186
|
+
this.dispatchAction(Action.DATA_SAVED, { changes, records }, executionCtx);
|
|
139
187
|
resolve();
|
|
140
188
|
}
|
|
141
189
|
).catch(cause => fail(new ErrorException("Erro salvando alterações", cause)));
|
|
@@ -159,12 +207,12 @@ export default class DataUnit {
|
|
|
159
207
|
return Promise.resolve(selection);
|
|
160
208
|
}
|
|
161
209
|
|
|
162
|
-
public async removeRecords(records: Array<string>, buffered: boolean = false): Promise<Array<string>> {
|
|
210
|
+
public async removeRecords(records: Array<string>, buffered: boolean = false, executionCtx?: ExecutionContext): Promise<Array<string>> {
|
|
163
211
|
if (records) {
|
|
164
212
|
if (buffered || !this.removeLoader) {
|
|
165
|
-
this.dispatchAction(Action.RECORDS_REMOVED, { records, buffered: true });
|
|
213
|
+
this.dispatchAction(Action.RECORDS_REMOVED, { records, buffered: true }, executionCtx);
|
|
166
214
|
} else {
|
|
167
|
-
if (this.dispatchAction(Action.REMOVING_RECORDS)) {
|
|
215
|
+
if (await this.dispatchAction(Action.REMOVING_RECORDS, undefined, executionCtx)) {
|
|
168
216
|
|
|
169
217
|
return new Promise((resolve, fail) => {
|
|
170
218
|
if (this.removeLoader) {
|
|
@@ -182,7 +230,7 @@ export default class DataUnit {
|
|
|
182
230
|
currentIndex++
|
|
183
231
|
});
|
|
184
232
|
|
|
185
|
-
this.dispatchAction(Action.RECORDS_REMOVED, { records, removedIndex, buffered: false });
|
|
233
|
+
this.dispatchAction(Action.RECORDS_REMOVED, { records, removedIndex, buffered: false }, executionCtx);
|
|
186
234
|
resolve(records);
|
|
187
235
|
}
|
|
188
236
|
).catch(error => fail(new ErrorException("Problema removendo registros", error)));
|
|
@@ -217,12 +265,16 @@ export default class DataUnit {
|
|
|
217
265
|
this._filterProviders.set(this.getFielterProviderKey(provider), provider);
|
|
218
266
|
}
|
|
219
267
|
|
|
268
|
+
public getPaginationInfo(): PaginationInfo | void {
|
|
269
|
+
return getPaginationInfo(this._stateManager);
|
|
270
|
+
}
|
|
271
|
+
|
|
220
272
|
public set sortingProvider(provider: SortingProvider) {
|
|
221
273
|
this._sortingProvider = provider;
|
|
222
274
|
}
|
|
223
275
|
|
|
224
276
|
public set metadata(md: UnitMetadata) {
|
|
225
|
-
this.dispatchAction(Action.METADATA_LOADED, md);
|
|
277
|
+
this.dispatchAction(Action.METADATA_LOADED, md, undefined);
|
|
226
278
|
}
|
|
227
279
|
|
|
228
280
|
public get metadata(): UnitMetadata {
|
|
@@ -230,7 +282,7 @@ export default class DataUnit {
|
|
|
230
282
|
}
|
|
231
283
|
|
|
232
284
|
public set records(r: Array<Record>) {
|
|
233
|
-
this.dispatchAction(Action.DATA_LOADED,
|
|
285
|
+
this.dispatchAction(Action.DATA_LOADED, { records: this.records }, undefined);
|
|
234
286
|
}
|
|
235
287
|
|
|
236
288
|
public get records(): Array<Record> {
|
|
@@ -238,6 +290,14 @@ export default class DataUnit {
|
|
|
238
290
|
return records ? Array.from(records.values()) : [];
|
|
239
291
|
}
|
|
240
292
|
|
|
293
|
+
public set pageSize(size: number) {
|
|
294
|
+
this._pageSize = size;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
public get pageSize(): number {
|
|
298
|
+
return this._pageSize;
|
|
299
|
+
}
|
|
300
|
+
|
|
241
301
|
public getModifiedRecords(): Array<Record> {
|
|
242
302
|
const modified = getModifiedRecords(this._stateManager);
|
|
243
303
|
return modified || [];
|
|
@@ -247,14 +307,14 @@ export default class DataUnit {
|
|
|
247
307
|
return getField(this._stateManager, fieldName);
|
|
248
308
|
}
|
|
249
309
|
|
|
250
|
-
public addRecord(): void {
|
|
251
|
-
this.dispatchAction(Action.RECORDS_ADDED, prepareAddedRecordId(this._stateManager, [{}]));
|
|
310
|
+
public addRecord(executionCtx?: ExecutionContext): void {
|
|
311
|
+
this.dispatchAction(Action.RECORDS_ADDED, prepareAddedRecordId(this._stateManager, [{}]), executionCtx);
|
|
252
312
|
}
|
|
253
313
|
|
|
254
|
-
public copySelected(): void {
|
|
314
|
+
public copySelected(executionCtx?: ExecutionContext): void {
|
|
255
315
|
const selectedRecords = this.getSelectedRecords();
|
|
256
316
|
if (selectedRecords) {
|
|
257
|
-
this.dispatchAction(Action.RECORDS_COPIED, prepareCopiedRecord(this._stateManager, selectedRecords));
|
|
317
|
+
this.dispatchAction(Action.RECORDS_COPIED, prepareCopiedRecord(this._stateManager, selectedRecords), executionCtx);
|
|
258
318
|
}
|
|
259
319
|
}
|
|
260
320
|
|
|
@@ -272,38 +332,42 @@ export default class DataUnit {
|
|
|
272
332
|
const currentValue = this.getFieldValue(fieldName);
|
|
273
333
|
|
|
274
334
|
if (currentValue !== typedValue) {
|
|
275
|
-
this.dispatchAction(Action.DATA_CHANGED, { [fieldName]: typedValue, records });
|
|
335
|
+
this.dispatchAction(Action.DATA_CHANGED, { [fieldName]: typedValue, records }, undefined);
|
|
276
336
|
}
|
|
277
337
|
}
|
|
278
338
|
|
|
279
339
|
public startChange(fieldName: string, waitingChange: WaitingChange): void {
|
|
280
|
-
this.dispatchAction(Action.CHANGING_DATA, { [fieldName]: waitingChange });
|
|
340
|
+
this.dispatchAction(Action.CHANGING_DATA, { [fieldName]: waitingChange }, undefined);
|
|
281
341
|
}
|
|
282
342
|
|
|
283
343
|
public cancelWaitingChange(fieldName: string): void {
|
|
284
|
-
this.dispatchAction(Action.WAITING_CHANGE_CANCELED, { fieldName });
|
|
344
|
+
this.dispatchAction(Action.WAITING_CHANGE_CANCELED, { fieldName }, undefined);
|
|
285
345
|
}
|
|
286
346
|
|
|
287
347
|
public getSelection(): Array<string> {
|
|
288
348
|
return getSelection(this._stateManager);
|
|
289
349
|
}
|
|
290
350
|
|
|
291
|
-
public setSelection(selection: Array<string
|
|
292
|
-
this.dispatchAction(Action.SELECTION_CHANGED, { type: "id", selection });
|
|
351
|
+
public setSelection(selection: Array<string>, executionCtx?: ExecutionContext): void {
|
|
352
|
+
this.dispatchAction(Action.SELECTION_CHANGED, { type: "id", selection }, executionCtx);
|
|
293
353
|
}
|
|
294
354
|
|
|
295
|
-
public selectFirst(): void {
|
|
296
|
-
if(this.records.length > 0){
|
|
297
|
-
this.
|
|
355
|
+
public selectFirst(executionCtx?: ExecutionContext): void {
|
|
356
|
+
if (this.records.length > 0) {
|
|
357
|
+
this.setSelectionByIndex([0], executionCtx);
|
|
298
358
|
}
|
|
299
359
|
}
|
|
300
360
|
|
|
301
|
-
public selectLast(): void {
|
|
302
|
-
if(this.records.length > 0){
|
|
303
|
-
this.
|
|
361
|
+
public selectLast(executionCtx?: ExecutionContext): void {
|
|
362
|
+
if (this.records.length > 0) {
|
|
363
|
+
this.setSelectionByIndex([this.records.length - 1], executionCtx);
|
|
304
364
|
}
|
|
305
365
|
}
|
|
306
366
|
|
|
367
|
+
public setSelectionByIndex(selection: Array<number>, executionCtx?: ExecutionContext): void {
|
|
368
|
+
this.dispatchAction(Action.SELECTION_CHANGED, { type: "index", selection }, executionCtx);
|
|
369
|
+
}
|
|
370
|
+
|
|
307
371
|
public getSelectedRecords(): Array<Record> | undefined {
|
|
308
372
|
const selection: Array<string> = this.getSelection();
|
|
309
373
|
if (selection) {
|
|
@@ -312,16 +376,48 @@ export default class DataUnit {
|
|
|
312
376
|
}
|
|
313
377
|
}
|
|
314
378
|
|
|
315
|
-
public nextRecord(): void {
|
|
316
|
-
this.
|
|
379
|
+
public nextRecord(executionCtx?: ExecutionContext): void {
|
|
380
|
+
if(!hasNext(this._stateManager)){
|
|
381
|
+
if(hasMorePages(this._stateManager)){
|
|
382
|
+
this.nextPage({
|
|
383
|
+
before: act =>{
|
|
384
|
+
if(executionCtx && executionCtx.before){
|
|
385
|
+
act = executionCtx.before(act);
|
|
386
|
+
}
|
|
387
|
+
return act;
|
|
388
|
+
},
|
|
389
|
+
after: act => {
|
|
390
|
+
this.selectFirst(executionCtx);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
} else {
|
|
395
|
+
this.dispatchAction(Action.NEXT_SELECTED, undefined, executionCtx);
|
|
396
|
+
}
|
|
317
397
|
}
|
|
318
398
|
|
|
319
|
-
public previousRecord(): void {
|
|
320
|
-
this.
|
|
399
|
+
public previousRecord(executionCtx?: ExecutionContext): void {
|
|
400
|
+
if(!hasPrevious(this._stateManager)){
|
|
401
|
+
if(getCurrentPage(this._stateManager) > 0){
|
|
402
|
+
this.previousPage({
|
|
403
|
+
before: act =>{
|
|
404
|
+
if(executionCtx && executionCtx.before){
|
|
405
|
+
act = executionCtx.before(act);
|
|
406
|
+
}
|
|
407
|
+
return act;
|
|
408
|
+
},
|
|
409
|
+
after: act => {
|
|
410
|
+
this.selectLast(executionCtx);
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
} else {
|
|
415
|
+
this.dispatchAction(Action.PREVIOUS_SELECTED, undefined, executionCtx);
|
|
416
|
+
}
|
|
321
417
|
}
|
|
322
418
|
|
|
323
|
-
public cancelEdition(): void {
|
|
324
|
-
this.dispatchAction(Action.EDITION_CANCELED);
|
|
419
|
+
public cancelEdition(executionCtx?: ExecutionContext): void {
|
|
420
|
+
this.dispatchAction(Action.EDITION_CANCELED, undefined, executionCtx);
|
|
325
421
|
}
|
|
326
422
|
|
|
327
423
|
public isDirty(): boolean {
|
|
@@ -329,11 +425,19 @@ export default class DataUnit {
|
|
|
329
425
|
}
|
|
330
426
|
|
|
331
427
|
public hasNext(): boolean {
|
|
332
|
-
|
|
428
|
+
let result = hasNext(this._stateManager);
|
|
429
|
+
if(!result){
|
|
430
|
+
result = hasMorePages(this._stateManager);
|
|
431
|
+
}
|
|
432
|
+
return result;
|
|
333
433
|
}
|
|
334
434
|
|
|
335
435
|
public hasPrevious(): boolean {
|
|
336
|
-
|
|
436
|
+
let result = hasPrevious(this._stateManager);
|
|
437
|
+
if(!result){
|
|
438
|
+
result = getCurrentPage(this._stateManager) > 0;
|
|
439
|
+
}
|
|
440
|
+
return result;
|
|
337
441
|
}
|
|
338
442
|
|
|
339
443
|
public canUndo(): boolean {
|
|
@@ -344,12 +448,12 @@ export default class DataUnit {
|
|
|
344
448
|
return canRedo(this._stateManager);
|
|
345
449
|
}
|
|
346
450
|
|
|
347
|
-
public undo() {
|
|
348
|
-
this.dispatchAction(Action.CHANGE_UNDONE);
|
|
451
|
+
public undo(executionCtx?: ExecutionContext) {
|
|
452
|
+
this.dispatchAction(Action.CHANGE_UNDONE, undefined, executionCtx);
|
|
349
453
|
}
|
|
350
454
|
|
|
351
|
-
public redo() {
|
|
352
|
-
this.dispatchAction(Action.CHANGE_REDONE);
|
|
455
|
+
public redo(executionCtx?: ExecutionContext) {
|
|
456
|
+
this.dispatchAction(Action.CHANGE_REDONE, undefined, executionCtx);
|
|
353
457
|
}
|
|
354
458
|
|
|
355
459
|
public toString() {
|
|
@@ -357,33 +461,50 @@ export default class DataUnit {
|
|
|
357
461
|
}
|
|
358
462
|
|
|
359
463
|
// Actions / State manager
|
|
360
|
-
private dispatchAction(actionType: Action, payload?: any): boolean {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
464
|
+
private async dispatchAction(actionType: Action, payload?: any, executionCtx?: ExecutionContext): Promise<boolean> {
|
|
465
|
+
return new Promise(async resolve => {
|
|
466
|
+
let action = new DataUnitAction(actionType, payload);
|
|
467
|
+
if (executionCtx && executionCtx.before) {
|
|
468
|
+
action = executionCtx.before(action);
|
|
469
|
+
}
|
|
470
|
+
if (action && this._interceptors && this._interceptors.length > 0) {
|
|
471
|
+
action = await this.intercept(action, this._interceptors.values());
|
|
472
|
+
}
|
|
364
473
|
if (action) {
|
|
365
|
-
|
|
474
|
+
this.doDispatchAction(action);
|
|
475
|
+
if (executionCtx && executionCtx.after) {
|
|
476
|
+
executionCtx.after(action)
|
|
477
|
+
}
|
|
478
|
+
resolve(true);
|
|
479
|
+
} else {
|
|
480
|
+
resolve(false);
|
|
366
481
|
}
|
|
367
482
|
});
|
|
483
|
+
}
|
|
368
484
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
485
|
+
private async intercept(action: DataUnitAction, interceptors: IterableIterator<DUActionInterceptor>): Promise<DataUnitAction> {
|
|
486
|
+
return new Promise(async resolve => {
|
|
487
|
+
let ite;
|
|
488
|
+
while (action && !(ite = interceptors.next()).done) {
|
|
489
|
+
action = await ite.value.interceptAction(action);
|
|
490
|
+
}
|
|
491
|
+
resolve(action);
|
|
492
|
+
});
|
|
493
|
+
}
|
|
372
494
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
return true;
|
|
495
|
+
private doDispatchAction(action: DataUnitAction) {
|
|
496
|
+
this._stateManager.process(action);
|
|
497
|
+
this._observers.forEach(f => {
|
|
498
|
+
/*
|
|
499
|
+
if some observer throws exceptions,
|
|
500
|
+
should be continued
|
|
501
|
+
*/
|
|
502
|
+
try {
|
|
503
|
+
f(action);
|
|
504
|
+
} catch (e) {
|
|
505
|
+
console.warn("[DataUnit] error while call observer", e);
|
|
506
|
+
}
|
|
507
|
+
});
|
|
387
508
|
}
|
|
388
509
|
|
|
389
510
|
public subscribe(observer: (action: DataUnitAction) => void) {
|
|
@@ -396,7 +517,7 @@ export default class DataUnit {
|
|
|
396
517
|
}
|
|
397
518
|
|
|
398
519
|
export interface DUActionInterceptor {
|
|
399
|
-
interceptAction(action: DataUnitAction): DataUnitAction
|
|
520
|
+
interceptAction(action: DataUnitAction): DataUnitAction | Promise<DataUnitAction>;
|
|
400
521
|
}
|
|
401
522
|
|
|
402
523
|
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
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
|
|
2
|
+
import { LoadDataRequest } from "../../loading/LoadDataRequest.js";
|
|
3
|
+
import { PaginationInfo } from "../../loading/PaginationInfo.js";
|
|
4
|
+
import { Action } from "../action/DataUnitAction.js";
|
|
5
|
+
import StateManager, { ActionReducer, StateAction } from "../StateManager.js";
|
|
6
|
+
|
|
7
|
+
class LoadControlReducerImpl implements ActionReducer {
|
|
8
|
+
|
|
9
|
+
public sliceName: string = "pagination";
|
|
10
|
+
|
|
11
|
+
public reduce(stateManager: StateManager, currentState: LoadControlState, action: StateAction): LoadControlState {
|
|
12
|
+
switch (action.type) {
|
|
13
|
+
case Action.LOADING_DATA :
|
|
14
|
+
return {...currentState, lastRequest: action.payload};
|
|
15
|
+
case Action.DATA_LOADED:
|
|
16
|
+
return {...currentState, paginationInfo: action.payload?.paginationInfo};
|
|
17
|
+
}
|
|
18
|
+
return currentState;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const LoadControlReducer = new LoadControlReducerImpl();
|
|
23
|
+
|
|
24
|
+
export const getPaginationInfo = (stateManager: StateManager): PaginationInfo|void => {
|
|
25
|
+
const state: LoadControlState = stateManager.select(LoadControlReducer.sliceName, (state: LoadControlState) => state);
|
|
26
|
+
return state ? state.paginationInfo : undefined;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const getCurrentRequest = (stateManager: StateManager): LoadDataRequest|void => {
|
|
30
|
+
const state: LoadControlState = stateManager.select(LoadControlReducer.sliceName, (state: LoadControlState) => state);
|
|
31
|
+
return state ? state.lastRequest : undefined;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const getCurrentPage = (stateManager: StateManager): number => {
|
|
35
|
+
const paginationInfo = getPaginationInfo(stateManager);
|
|
36
|
+
return paginationInfo ? paginationInfo.currentPage : 0;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const getLastPage = (stateManager: StateManager, pageSize: number): number => {
|
|
40
|
+
const paginationInfo = getPaginationInfo(stateManager);
|
|
41
|
+
return paginationInfo ? Math.ceil(paginationInfo.total / pageSize) : 0;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const hasMorePages = (stateManager: StateManager): boolean => {
|
|
45
|
+
const paginationInfo = getPaginationInfo(stateManager);
|
|
46
|
+
if(paginationInfo && paginationInfo.hasMore){
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface LoadControlState{
|
|
53
|
+
lastRequest: LoadDataRequest;
|
|
54
|
+
paginationInfo: PaginationInfo;
|
|
55
|
+
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
2
1
|
import { ActionReducer, StateAction } from "../StateManager.js";
|
|
3
|
-
import { Action } from "../action/DataUnitAction.js";
|
|
4
2
|
import StateManager from "../StateManager.js";
|
|
5
|
-
import { Record, SavedRecord } from "../../DataUnit.js";
|
|
6
3
|
import { getRemovedRecords } from "./RemovedRecordsSlice.js";
|
|
7
|
-
|
|
4
|
+
import { Action } from "../action/DataUnitAction.js";
|
|
5
|
+
import { Record, SavedRecord } from "../../DataUnit.js";
|
|
8
6
|
|
|
9
7
|
class RecordsReducerImpl implements ActionReducer {
|
|
10
8
|
|
|
@@ -14,7 +12,7 @@ class RecordsReducerImpl implements ActionReducer {
|
|
|
14
12
|
switch (action.type) {
|
|
15
13
|
|
|
16
14
|
case Action.DATA_LOADED:
|
|
17
|
-
return action.payload;
|
|
15
|
+
return action.payload ? action.payload.records : undefined;
|
|
18
16
|
case Action.RECORDS_REMOVED:
|
|
19
17
|
|
|
20
18
|
const {records, buffered} = action.payload;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { WaitingChange } from "../../DataUnit.js";
|
|
3
3
|
import { Action } from "../action/DataUnitAction.js";
|
|
4
4
|
import StateManager, { ActionReducer, StateAction } from "../StateManager.js";
|
|
5
|
-
import { getSelection } from "./SelectionSlice.js";
|
|
6
5
|
|
|
7
6
|
class WaitingCheangesReducerImpl implements ActionReducer{
|
|
8
7
|
|