@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.
Files changed (34) hide show
  1. package/.eslintrc.cjs +2 -1
  2. package/dist/dataunit/DataUnit.d.ts +32 -18
  3. package/dist/dataunit/DataUnit.js +195 -84
  4. package/dist/dataunit/DataUnit.js.map +1 -1
  5. package/dist/dataunit/loading/LoadDataRequest.d.ts +9 -0
  6. package/dist/dataunit/loading/LoadDataRequest.js +2 -0
  7. package/dist/dataunit/loading/LoadDataRequest.js.map +1 -0
  8. package/dist/dataunit/loading/LoadDataResponse.d.ts +6 -0
  9. package/dist/dataunit/loading/LoadDataResponse.js +2 -0
  10. package/dist/dataunit/loading/LoadDataResponse.js.map +1 -0
  11. package/dist/dataunit/loading/PaginationInfo.d.ts +7 -0
  12. package/dist/dataunit/loading/PaginationInfo.js +2 -0
  13. package/dist/dataunit/loading/PaginationInfo.js.map +1 -0
  14. package/dist/dataunit/state/action/DataUnitAction.d.ts +4 -0
  15. package/dist/dataunit/state/action/DataUnitAction.js.map +1 -1
  16. package/dist/dataunit/state/slice/LoadControlSlice.d.ts +18 -0
  17. package/dist/dataunit/state/slice/LoadControlSlice.js +41 -0
  18. package/dist/dataunit/state/slice/LoadControlSlice.js.map +1 -0
  19. package/dist/dataunit/state/slice/RecordsSlice.js +2 -2
  20. package/dist/dataunit/state/slice/RecordsSlice.js.map +1 -1
  21. package/dist/dataunit/state/slice/WaitingChangesSlice.js.map +1 -1
  22. package/dist/index.d.ts +6 -3
  23. package/dist/index.js +2 -2
  24. package/dist/index.js.map +1 -1
  25. package/package.json +1 -1
  26. package/src/dataunit/DataUnit.ts +213 -92
  27. package/src/dataunit/loading/LoadDataRequest.ts +10 -0
  28. package/src/dataunit/loading/LoadDataResponse.ts +7 -0
  29. package/src/dataunit/loading/PaginationInfo.ts +8 -0
  30. package/src/dataunit/state/action/DataUnitAction.ts +4 -0
  31. package/src/dataunit/state/slice/LoadControlSlice.ts +55 -0
  32. package/src/dataunit/state/slice/RecordsSlice.ts +3 -5
  33. package/src/dataunit/state/slice/WaitingChangesSlice.ts +0 -1
  34. package/src/index.ts +13 -3
@@ -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, Action } from "./state/action/DataUnitAction.js";
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, page?: PageRequest, sort?: Array<Sort>, filters?: Array<Filter>) => Promise<PageResponse>;
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(page?: PageRequest): Promise<PageResponse|void> {
105
- if(this.dispatchAction(Action.LOADING_DATA)){
106
- return new Promise((resolve, fail) => {
107
- if (this.dataLoader) {
108
- const sort = this.getSort();
109
- const filters = this.getFilters();
110
- this.dataLoader(this, page, sort, filters).then(
111
- pageRes => {
112
- this.records = pageRes.records;
113
- resolve(pageRes);
114
- }
115
- ).catch(error => fail(new ErrorException("Problema carregando registros", error)));
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 saveData(): Promise<void> {
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, r);
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>): void {
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.dispatchAction(Action.SELECTION_CHANGED, { type: "index", selection: [0] });
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.dispatchAction(Action.SELECTION_CHANGED, { type: "index", selection: [this.records.length - 1] });
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.dispatchAction(Action.NEXT_SELECTED);
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.dispatchAction(Action.PREVIOUS_SELECTED);
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
- return hasNext(this._stateManager);
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
- return hasPrevious(this._stateManager);
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
- let action = new DataUnitAction(actionType, payload);
362
-
363
- this._interceptors?.forEach(interceptor => {
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
- action = interceptor.interceptAction(action);
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
- if (!action) {
370
- return false;
371
- } else {
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
- this._stateManager.process(action);
374
- this._observers.forEach(f => {
375
- /*
376
- if some observer throws exceptions,
377
- should be continued
378
- */
379
- try {
380
- f(action);
381
- } catch (e) {
382
- console.warn("[DataUnit] error while call observer", e);
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
+ }
@@ -0,0 +1,7 @@
1
+ import { Record } from "../DataUnit.js";
2
+ import { PaginationInfo } from "./PaginationInfo.js";
3
+
4
+ export interface LoadDataResponse {
5
+ records: Array<Record>;
6
+ paginationInfo?: PaginationInfo;
7
+ }
@@ -0,0 +1,8 @@
1
+
2
+ export interface PaginationInfo {
3
+ currentPage: number;
4
+ firstRecord: number;
5
+ lastRecord: number;
6
+ total: number;
7
+ hasMore: boolean;
8
+ }
@@ -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