@sankhyalabs/core 1.0.71 → 2.0.0

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