@sankhyalabs/core 1.0.72 → 2.0.0-beta.1

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 (76) hide show
  1. package/.eslintrc.cjs +2 -1
  2. package/.releaserc +3 -2
  3. package/dist/dataunit/DataUnit.d.ts +35 -18
  4. package/dist/dataunit/DataUnit.js +237 -100
  5. package/dist/dataunit/DataUnit.js.map +1 -1
  6. package/dist/dataunit/loading/LoadDataRequest.d.ts +9 -0
  7. package/dist/dataunit/loading/LoadDataRequest.js +2 -0
  8. package/dist/dataunit/loading/LoadDataRequest.js.map +1 -0
  9. package/dist/dataunit/loading/LoadDataResponse.d.ts +6 -0
  10. package/dist/dataunit/loading/LoadDataResponse.js +2 -0
  11. package/dist/dataunit/loading/LoadDataResponse.js.map +1 -0
  12. package/dist/dataunit/loading/PaginationInfo.d.ts +7 -0
  13. package/dist/dataunit/loading/PaginationInfo.js +2 -0
  14. package/dist/dataunit/loading/PaginationInfo.js.map +1 -0
  15. package/dist/dataunit/metadata/DataType.d.ts +1 -0
  16. package/dist/dataunit/metadata/DataType.js +14 -3
  17. package/dist/dataunit/metadata/DataType.js.map +1 -1
  18. package/dist/dataunit/state/action/DataUnitAction.d.ts +7 -1
  19. package/dist/dataunit/state/action/DataUnitAction.js +2 -0
  20. package/dist/dataunit/state/action/DataUnitAction.js.map +1 -1
  21. package/dist/dataunit/state/slice/ChangesSlice.d.ts +1 -0
  22. package/dist/dataunit/state/slice/ChangesSlice.js +3 -0
  23. package/dist/dataunit/state/slice/ChangesSlice.js.map +1 -1
  24. package/dist/dataunit/state/slice/LoadingControlSlice.d.ts +19 -0
  25. package/dist/dataunit/state/slice/LoadingControlSlice.js +45 -0
  26. package/dist/dataunit/state/slice/LoadingControlSlice.js.map +1 -0
  27. package/dist/dataunit/state/slice/RecordsSlice.js +10 -2
  28. package/dist/dataunit/state/slice/RecordsSlice.js.map +1 -1
  29. package/dist/dataunit/state/slice/SelectionSlice.js +0 -4
  30. package/dist/dataunit/state/slice/SelectionSlice.js.map +1 -1
  31. package/dist/dataunit/state/slice/WaitingChangesSlice.js.map +1 -1
  32. package/dist/exceptions/ErrorException.d.ts +2 -1
  33. package/dist/exceptions/ErrorException.js +2 -1
  34. package/dist/exceptions/ErrorException.js.map +1 -1
  35. package/dist/exceptions/WarningException.d.ts +2 -1
  36. package/dist/exceptions/WarningException.js +2 -1
  37. package/dist/exceptions/WarningException.js.map +1 -1
  38. package/dist/index.d.ts +8 -4
  39. package/dist/index.js +4 -3
  40. package/dist/index.js.map +1 -1
  41. package/dist/ui/FloatingManager.d.ts +10 -0
  42. package/dist/ui/FloatingManager.js +62 -1
  43. package/dist/ui/FloatingManager.js.map +1 -1
  44. package/dist/utils/ArrayUtils.d.ts +14 -0
  45. package/dist/utils/ArrayUtils.js +30 -0
  46. package/dist/utils/ArrayUtils.js.map +1 -0
  47. package/dist/utils/DateUtils.d.ts +3 -2
  48. package/dist/utils/DateUtils.js +13 -4
  49. package/dist/utils/DateUtils.js.map +1 -1
  50. package/dist/utils/NumberUtils.d.ts +17 -0
  51. package/dist/utils/NumberUtils.js +27 -0
  52. package/dist/utils/NumberUtils.js.map +1 -1
  53. package/dist/utils/StringUtils.d.ts +14 -2
  54. package/dist/utils/StringUtils.js +30 -2
  55. package/dist/utils/StringUtils.js.map +1 -1
  56. package/jest.config.ts +4 -4
  57. package/package.json +1 -1
  58. package/src/dataunit/DataUnit.ts +261 -107
  59. package/src/dataunit/loading/LoadDataRequest.ts +10 -0
  60. package/src/dataunit/loading/LoadDataResponse.ts +7 -0
  61. package/src/dataunit/loading/PaginationInfo.ts +8 -0
  62. package/src/dataunit/metadata/DataType.ts +28 -15
  63. package/src/dataunit/state/action/DataUnitAction.ts +8 -1
  64. package/src/dataunit/state/slice/ChangesSlice.ts +5 -1
  65. package/src/dataunit/state/slice/LoadingControlSlice.ts +60 -0
  66. package/src/dataunit/state/slice/RecordsSlice.ts +12 -5
  67. package/src/dataunit/state/slice/SelectionSlice.ts +0 -5
  68. package/src/dataunit/state/slice/WaitingChangesSlice.ts +0 -1
  69. package/src/exceptions/ErrorException.ts +3 -1
  70. package/src/exceptions/WarningException.ts +4 -1
  71. package/src/index.ts +16 -4
  72. package/src/ui/FloatingManager.ts +75 -5
  73. package/src/utils/ArrayUtils.ts +32 -0
  74. package/src/utils/DateUtils.ts +18 -8
  75. package/src/utils/NumberUtils.ts +33 -0
  76. 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
  }
package/.releaserc CHANGED
@@ -30,6 +30,7 @@
30
30
  ],
31
31
  "branches": [
32
32
  {"name": "master"},
33
- {"name": "beta", "channel": "beta", "prerelease": true}
33
+ {"name": "beta", "channel": "beta", "prerelease": true},
34
+ "+([0-9])?(.{+([0-9]),x}).x"
34
35
  ]
35
- }
36
+ }
@@ -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;
@@ -7,29 +7,30 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { UserInterface } from "./metadata/UnitMetadata.js";
11
10
  import { convertType, toString } from "./metadata/DataType.js";
12
- import { DataUnitAction, Action } from "./state/action/DataUnitAction.js";
11
+ import { Action, DataUnitAction } from "./state/action/DataUnitAction.js";
13
12
  import StateManager from "./state/StateManager.js";
14
- import { HistReducer, canRedo, canUndo } from "./state/HistReducer.js";
15
- import { UnitMetadataReducer, getField, getMetadata } from "./state/slice/UnitMetadataSlice.js";
16
- import { RecordsReducer } from "./state/slice/RecordsSlice.js";
17
- import { SelectionReducer, getSelection, hasNext, hasPrevious } from "./state/slice/SelectionSlice.js";
18
- import { ChangesReducer, isDirty, getChangesToSave } from "./state/slice/ChangesSlice.js";
19
- 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";
20
16
  import { AddedRecordsReducer, prepareAddedRecordId, prepareCopiedRecord } from "./state/slice/AddedRecordsSlice.js";
17
+ import { ChangesReducer, getChangesToSave, isDirty, hasDirtyRecords } from "./state/slice/ChangesSlice.js";
21
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";
22
24
  import { getBlockingWaitingChanges, getWaitingChangePromisses, isWaiting, WaitingChangesReducer } from "./state/slice/WaitingChangesSlice.js";
23
- import WaitingChangeException from "../exceptions/WaitingChangeException.js";
24
- import ErrorException from "../exceptions/ErrorException.js";
25
- import { DateUtils } from "../utils/DateUtils.js";
26
- import { StringUtils } from "../utils/StringUtils.js";
25
+ import { canRedo, canUndo, HistReducer } from "./state/HistReducer.js";
27
26
  export default class DataUnit {
28
27
  constructor(name) {
29
28
  this._name = name;
29
+ this._pageSize = 0;
30
30
  this._stateManager = new StateManager([
31
31
  HistReducer,
32
32
  UnitMetadataReducer,
33
+ LoadingControlReducer,
33
34
  RecordsReducer,
34
35
  RemovedRecordsReducer,
35
36
  AddedRecordsReducer,
@@ -48,7 +49,6 @@ export default class DataUnit {
48
49
  }
49
50
  // Métodos privados
50
51
  validateAndTypeValue(fieldName, newValue) {
51
- //FIXME: Validações devem ser feitas aqui
52
52
  const descriptor = this.getField(fieldName);
53
53
  return descriptor ? convertType(descriptor.dataType, newValue) : newValue;
54
54
  }
@@ -71,38 +71,78 @@ export default class DataUnit {
71
71
  }
72
72
  return StringUtils.hashCode(provider.getFilter.toString());
73
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
+ }
74
89
  // Loaders
75
- loadMetadata() {
90
+ loadMetadata(executionCtx) {
76
91
  return __awaiter(this, void 0, void 0, function* () {
77
- if (this.dispatchAction(Action.LOADING_METADATA)) {
92
+ if (yield this.dispatchAction(Action.LOADING_METADATA, undefined, executionCtx)) {
78
93
  return new Promise((resolve, fail) => {
79
94
  if (this.metadataLoader) {
80
95
  this.metadataLoader(this).then(metadata => {
81
96
  this.metadata = metadata;
82
97
  resolve(this.metadata);
83
- }).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
+ });
84
102
  }
85
103
  });
86
104
  }
87
105
  });
88
106
  }
89
- loadData(page) {
107
+ loadData(quickFilter, executionCtx) {
90
108
  return __awaiter(this, void 0, void 0, function* () {
91
- if (this.dispatchAction(Action.LOADING_DATA)) {
92
- return new Promise((resolve, fail) => {
93
- if (this.dataLoader) {
94
- const sort = this.getSort();
95
- const filters = this.getFilters();
96
- this.dataLoader(this, page, sort, filters).then(pageRes => {
97
- this.records = pageRes.records;
98
- resolve(pageRes);
99
- }).catch(error => fail(new ErrorException("Problema carregando registros", error)));
100
- }
101
- });
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;
102
117
  }
118
+ return this.executeLoadData(loadDataRequest, executionCtx);
103
119
  });
104
120
  }
105
- 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) {
106
146
  return __awaiter(this, void 0, void 0, function* () {
107
147
  const blockingWaitingChanges = getBlockingWaitingChanges(this._stateManager);
108
148
  if (blockingWaitingChanges && blockingWaitingChanges.size > 0) {
@@ -111,16 +151,19 @@ export default class DataUnit {
111
151
  }
112
152
  else {
113
153
  if (isDirty(this._stateManager)) {
114
- if (this.dispatchAction(Action.SAVING_DATA)) {
154
+ if (yield this.dispatchAction(Action.SAVING_DATA, undefined, executionCtx)) {
115
155
  const promisses = getWaitingChangePromisses(this._stateManager);
116
156
  return new Promise((resolve, fail) => {
117
157
  Promise.all(promisses || []).then(() => {
118
158
  if (this.saveLoader) {
119
159
  const changes = getChangesToSave(this._name, this._stateManager);
120
160
  this.saveLoader(this, changes).then(records => {
121
- this.dispatchAction(Action.DATA_SAVED, { changes, records });
161
+ this.dispatchAction(Action.DATA_SAVED, { changes, records }, executionCtx);
122
162
  resolve();
123
- }).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
+ });
124
167
  }
125
168
  else {
126
169
  resolve();
@@ -137,40 +180,44 @@ export default class DataUnit {
137
180
  return __awaiter(this, void 0, void 0, function* () {
138
181
  const selection = getSelection(this._stateManager);
139
182
  if (selection) {
140
- return this.removeRecords(selection, buffered);
183
+ const records = this.getSelectedRecords() || [];
184
+ return this.removeRecords(selection, records, buffered);
141
185
  }
142
186
  return Promise.resolve(selection);
143
187
  });
144
188
  }
145
- removeRecords(records, buffered = false) {
189
+ removeRecords(recordIds, cachedRecords, buffered = false, executionCtx) {
146
190
  return __awaiter(this, void 0, void 0, function* () {
147
- if (records) {
191
+ if (recordIds) {
148
192
  if (buffered || !this.removeLoader) {
149
- this.dispatchAction(Action.RECORDS_REMOVED, { records, buffered: true });
193
+ this.dispatchAction(Action.RECORDS_REMOVED, { records: recordIds, cachedRecords, buffered: true }, executionCtx);
150
194
  }
151
195
  else {
152
- if (this.dispatchAction(Action.REMOVING_RECORDS)) {
196
+ if (yield this.dispatchAction(Action.REMOVING_RECORDS, undefined, executionCtx)) {
153
197
  return new Promise((resolve, fail) => {
154
198
  if (this.removeLoader) {
155
- this.removeLoader(this, records).then(records => {
199
+ this.removeLoader(this, recordIds).then(removedIds => {
156
200
  let currentIndex = 0;
157
201
  const removedIndex = [];
158
202
  const currentRecords = getCurrentRecords(this._stateManager);
159
203
  currentRecords.forEach((value, key) => {
160
- if (records.includes(key)) {
204
+ if (removedIds.includes(key)) {
161
205
  removedIndex.push(currentIndex);
162
206
  }
163
207
  currentIndex++;
164
208
  });
165
- this.dispatchAction(Action.RECORDS_REMOVED, { records, removedIndex, buffered: false });
166
- resolve(records);
167
- }).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
+ });
168
215
  }
169
216
  });
170
217
  }
171
218
  }
172
219
  }
173
- return Promise.resolve(records);
220
+ return Promise.resolve(recordIds);
174
221
  });
175
222
  }
176
223
  // API
@@ -191,22 +238,31 @@ export default class DataUnit {
191
238
  addFilterProvider(provider) {
192
239
  this._filterProviders.set(this.getFielterProviderKey(provider), provider);
193
240
  }
241
+ getPaginationInfo() {
242
+ return getPaginationInfo(this._stateManager);
243
+ }
194
244
  set sortingProvider(provider) {
195
245
  this._sortingProvider = provider;
196
246
  }
197
247
  set metadata(md) {
198
- this.dispatchAction(Action.METADATA_LOADED, md);
248
+ this.dispatchAction(Action.METADATA_LOADED, md, undefined);
199
249
  }
200
250
  get metadata() {
201
251
  return getMetadata(this._stateManager);
202
252
  }
203
253
  set records(r) {
204
- this.dispatchAction(Action.DATA_LOADED, r);
254
+ this.dispatchAction(Action.DATA_LOADED, { records: this.records }, undefined);
205
255
  }
206
256
  get records() {
207
257
  const records = getCurrentRecords(this._stateManager);
208
258
  return records ? Array.from(records.values()) : [];
209
259
  }
260
+ set pageSize(size) {
261
+ this._pageSize = size;
262
+ }
263
+ get pageSize() {
264
+ return this._pageSize;
265
+ }
210
266
  getModifiedRecords() {
211
267
  const modified = getModifiedRecords(this._stateManager);
212
268
  return modified || [];
@@ -214,13 +270,13 @@ export default class DataUnit {
214
270
  getField(fieldName) {
215
271
  return getField(this._stateManager, fieldName);
216
272
  }
217
- addRecord() {
218
- this.dispatchAction(Action.RECORDS_ADDED, prepareAddedRecordId(this._stateManager, [{}]));
273
+ addRecord(executionCtx) {
274
+ this.dispatchAction(Action.RECORDS_ADDED, prepareAddedRecordId(this._stateManager, [{}]), executionCtx);
219
275
  }
220
- copySelected() {
276
+ copySelected(executionCtx) {
221
277
  const selectedRecords = this.getSelectedRecords();
222
278
  if (selectedRecords) {
223
- this.dispatchAction(Action.RECORDS_COPIED, prepareCopiedRecord(this._stateManager, selectedRecords));
279
+ this.dispatchAction(Action.RECORDS_COPIED, prepareCopiedRecord(this._stateManager, selectedRecords), executionCtx);
224
280
  }
225
281
  }
226
282
  waitingForChange(fieldName) {
@@ -230,38 +286,37 @@ export default class DataUnit {
230
286
  return getFieldValue(this._stateManager, fieldName);
231
287
  }
232
288
  setFieldValue(fieldName, newValue, records) {
233
- var _a;
234
289
  const typedValue = this.validateAndTypeValue(fieldName, newValue);
235
290
  const currentValue = this.getFieldValue(fieldName);
236
- const clearTime = ((_a = this.getField(fieldName)) === null || _a === void 0 ? void 0 : _a.userInterface) === UserInterface.DATE;
237
- const typedValueConverted = DateUtils.convertToTime(typedValue, clearTime);
238
- const currentValueConverted = DateUtils.convertToTime(currentValue, clearTime);
239
- if (typedValueConverted !== currentValueConverted) {
240
- this.dispatchAction(Action.DATA_CHANGED, { [fieldName]: typedValue, records });
291
+ if (currentValue !== typedValue) {
292
+ this.dispatchAction(Action.DATA_CHANGED, { [fieldName]: typedValue, records }, undefined);
241
293
  }
242
294
  }
243
295
  startChange(fieldName, waitingChange) {
244
- this.dispatchAction(Action.CHANGING_DATA, { [fieldName]: waitingChange });
296
+ this.dispatchAction(Action.CHANGING_DATA, { [fieldName]: waitingChange }, undefined);
245
297
  }
246
298
  cancelWaitingChange(fieldName) {
247
- this.dispatchAction(Action.WAITING_CHANGE_CANCELED, { fieldName });
299
+ this.dispatchAction(Action.WAITING_CHANGE_CANCELED, { fieldName }, undefined);
248
300
  }
249
301
  getSelection() {
250
302
  return getSelection(this._stateManager);
251
303
  }
252
- setSelection(selection) {
253
- this.dispatchAction(Action.SELECTION_CHANGED, { type: "id", selection });
304
+ setSelection(selection, executionCtx) {
305
+ this.dispatchAction(Action.SELECTION_CHANGED, { type: "id", selection }, executionCtx);
254
306
  }
255
- selectFirst() {
307
+ selectFirst(executionCtx) {
256
308
  if (this.records.length > 0) {
257
- this.dispatchAction(Action.SELECTION_CHANGED, { type: "index", selection: [0] });
309
+ this.setSelectionByIndex([0], executionCtx);
258
310
  }
259
311
  }
260
- selectLast() {
312
+ selectLast(executionCtx) {
261
313
  if (this.records.length > 0) {
262
- this.dispatchAction(Action.SELECTION_CHANGED, { type: "index", selection: [this.records.length - 1] });
314
+ this.setSelectionByIndex([this.records.length - 1], executionCtx);
263
315
  }
264
316
  }
317
+ setSelectionByIndex(selection, executionCtx) {
318
+ this.dispatchAction(Action.SELECTION_CHANGED, { type: "index", selection }, executionCtx);
319
+ }
265
320
  getSelectedRecords() {
266
321
  const selection = this.getSelection();
267
322
  if (selection) {
@@ -269,23 +324,68 @@ export default class DataUnit {
269
324
  return currentRecords === null || currentRecords === void 0 ? void 0 : currentRecords.filter(r => selection.includes(r.__record__id__));
270
325
  }
271
326
  }
272
- nextRecord() {
273
- 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
+ }
274
346
  }
275
- previousRecord() {
276
- 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
+ }
277
366
  }
278
- cancelEdition() {
279
- this.dispatchAction(Action.EDITION_CANCELED);
367
+ cancelEdition(executionCtx) {
368
+ this.dispatchAction(Action.EDITION_CANCELED, undefined, executionCtx);
280
369
  }
281
370
  isDirty() {
282
371
  return isDirty(this._stateManager);
283
372
  }
373
+ hasDirtyRecords() {
374
+ return hasDirtyRecords(this._stateManager);
375
+ }
284
376
  hasNext() {
285
- return hasNext(this._stateManager);
377
+ let result = hasNext(this._stateManager);
378
+ if (!result) {
379
+ result = hasMorePages(this._stateManager);
380
+ }
381
+ return result;
286
382
  }
287
383
  hasPrevious() {
288
- return hasPrevious(this._stateManager);
384
+ let result = hasPrevious(this._stateManager);
385
+ if (!result) {
386
+ result = hasPreviousPages(this._stateManager);
387
+ }
388
+ return result;
289
389
  }
290
390
  canUndo() {
291
391
  return canUndo(this._stateManager);
@@ -293,43 +393,64 @@ export default class DataUnit {
293
393
  canRedo() {
294
394
  return canRedo(this._stateManager);
295
395
  }
296
- undo() {
297
- this.dispatchAction(Action.CHANGE_UNDONE);
396
+ undo(executionCtx) {
397
+ this.dispatchAction(Action.CHANGE_UNDONE, undefined, executionCtx);
298
398
  }
299
- redo() {
300
- this.dispatchAction(Action.CHANGE_REDONE);
399
+ redo(executionCtx) {
400
+ this.dispatchAction(Action.CHANGE_REDONE, undefined, executionCtx);
301
401
  }
302
402
  toString() {
303
403
  return this.name;
304
404
  }
305
405
  // Actions / State manager
306
- dispatchAction(actionType, payload) {
307
- var _a;
308
- let action = new DataUnitAction(actionType, payload);
309
- (_a = this._interceptors) === null || _a === void 0 ? void 0 : _a.forEach(interceptor => {
310
- if (action) {
311
- action = interceptor.interceptAction(action);
312
- }
313
- });
314
- if (!action) {
315
- return false;
316
- }
317
- else {
318
- this._stateManager.process(action);
319
- this._observers.forEach(f => {
320
- /*
321
- if some observer throws exceptions,
322
- should be continued
323
- */
324
- try {
325
- 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);
326
412
  }
327
- catch (e) {
328
- 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());
329
415
  }
330
- });
331
- }
332
- 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
+ });
333
454
  }
334
455
  subscribe(observer) {
335
456
  this._observers.push(observer);
@@ -337,6 +458,22 @@ export default class DataUnit {
337
458
  unsubscribe(observer) {
338
459
  this._observers = this._observers.filter(f => f !== observer);
339
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
+ }
340
477
  }
341
478
  export var ChangeOperation;
342
479
  (function (ChangeOperation) {