@sankhyalabs/core 5.20.0-dev.4 → 5.20.0-dev.41
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/.docs/README.md +3 -1
- package/.docs/classes/ApplicationContext.md +31 -32
- package/.docs/classes/ArrayUtils.md +95 -83
- package/.docs/classes/AuthorizedServiceCaller.md +25 -34
- package/.docs/classes/Change.md +59 -74
- package/.docs/classes/DataUnit.md +1110 -1086
- package/.docs/classes/DataUnitAction.md +25 -42
- package/.docs/classes/DataUnitStorage.md +40 -43
- package/.docs/classes/DateUtils.md +133 -126
- package/.docs/classes/ElementIDUtils.md +123 -122
- package/.docs/classes/ErrorException.md +67 -88
- package/.docs/classes/ErrorTracking.md +20 -23
- package/.docs/classes/FieldComparator.md +35 -39
- package/.docs/classes/FloatingManager.md +195 -198
- package/.docs/classes/HTMLBuilder.md +14 -20
- package/.docs/classes/HttpProvider.md +45 -41
- package/.docs/classes/IDBRepository.md +201 -196
- package/.docs/classes/JSUtils.md +65 -66
- package/.docs/classes/KeyboardManager.md +95 -87
- package/.docs/classes/{MaskFormatter-1.md → MaskFormatter.md} +93 -128
- package/.docs/classes/NumberUtils.md +163 -152
- package/.docs/classes/ObjectUtils.md +206 -70
- package/.docs/classes/OnboardingUtils.md +36 -51
- package/.docs/classes/OverflowWatcher.md +533 -0
- package/.docs/classes/PromiseSync.md +25 -42
- package/.docs/classes/ReadyUtil.md +31 -41
- package/.docs/classes/RequestMetadata.md +29 -30
- package/.docs/classes/SearchUtils.md +18 -20
- package/.docs/classes/SelectionInfo.md +73 -74
- package/.docs/classes/SkwHttpProvider.md +33 -45
- package/.docs/classes/StringUtils.md +297 -322
- package/.docs/classes/TimeFormatter.md +43 -44
- package/.docs/classes/UserAgentUtils.md +17 -20
- package/.docs/classes/VersionUtils.md +15 -18
- package/.docs/classes/WaitingChangeException.md +63 -84
- package/.docs/classes/WarningException.md +67 -88
- package/.docs/enumerations/Action.md +307 -0
- package/.docs/enumerations/ChangeOperation.md +47 -0
- package/.docs/enumerations/DataType.md +57 -0
- package/.docs/enumerations/DependencyType.md +37 -0
- package/.docs/enumerations/OverflowDirection.md +29 -0
- package/.docs/enumerations/SelectionMode.md +27 -0
- package/.docs/enumerations/SortMode.md +27 -0
- package/.docs/enumerations/UserInterface.md +177 -0
- package/.docs/functions/defaultDataLoader.md +25 -0
- package/.docs/{modules.md → globals.md} +26 -36
- package/.docs/interfaces/ChildDescriptor.md +12 -16
- package/.docs/interfaces/ChildLink.md +9 -12
- package/.docs/interfaces/DUActionInterceptor.md +10 -14
- package/.docs/interfaces/ExecutionContext.md +17 -32
- package/.docs/interfaces/FieldDescriptor.md +52 -66
- package/.docs/interfaces/Filter.md +13 -17
- package/.docs/interfaces/IElementIDInfo.md +11 -14
- package/.docs/interfaces/ILoadResult.md +11 -16
- package/.docs/interfaces/IRepository.md +106 -93
- package/.docs/interfaces/IRepositoryIndex.md +23 -30
- package/.docs/interfaces/LoadDataRequest.md +36 -45
- package/.docs/interfaces/LoadDataResponse.md +11 -14
- package/.docs/interfaces/OverFlowWatcherParams.md +67 -0
- package/.docs/interfaces/PageRequest.md +16 -20
- package/.docs/interfaces/PaginationInfo.md +24 -31
- package/.docs/interfaces/PromiseSyncCallback.md +13 -17
- package/.docs/interfaces/QuickFilter.md +17 -21
- package/.docs/interfaces/Record.md +26 -33
- package/.docs/interfaces/SavedRecord.md +33 -41
- package/.docs/interfaces/Sort.md +12 -16
- package/.docs/interfaces/SortingProvider.md +10 -13
- package/.docs/interfaces/UnitMetadata.md +16 -21
- package/.docs/interfaces/WaitingChange.md +16 -20
- package/.docs/namespaces/MaskFormatter/README.md +17 -0
- package/.docs/namespaces/MaskFormatter/type-aliases/MaskCharacter.md +13 -0
- package/.docs/namespaces/MaskFormatter/variables/MaskCharacter.md +13 -0
- package/.docs/type-aliases/DataUnitEventOptions.md +17 -0
- package/.docs/type-aliases/OnOverflowCallBack.md +25 -0
- package/.docs/variables/OVERFLOWED_CLASS_NAME.md +13 -0
- package/dist/dataunit/DataUnit.d.ts +45 -6
- package/dist/dataunit/DataUnit.js +118 -31
- package/dist/dataunit/DataUnit.js.map +1 -1
- package/dist/dataunit/formatting/PrettyFormatter.js +11 -7
- package/dist/dataunit/formatting/PrettyFormatter.js.map +1 -1
- package/dist/dataunit/loading/LoadDataRequest.d.ts +1 -1
- package/dist/dataunit/metadata/DataType.js +13 -1
- package/dist/dataunit/metadata/DataType.js.map +1 -1
- package/dist/dataunit/state/action/DataUnitAction.d.ts +4 -1
- package/dist/dataunit/state/action/DataUnitAction.js +3 -0
- package/dist/dataunit/state/action/DataUnitAction.js.map +1 -1
- package/dist/dataunit/state/slice/ChangesSlice.js +12 -11
- package/dist/dataunit/state/slice/ChangesSlice.js.map +1 -1
- package/dist/dataunit/state/slice/InvalidFieldsSlice.js +2 -0
- package/dist/dataunit/state/slice/InvalidFieldsSlice.js.map +1 -1
- package/dist/dataunit/state/slice/LoadingProperties.d.ts +9 -0
- package/dist/dataunit/state/slice/LoadingProperties.js +31 -0
- package/dist/dataunit/state/slice/LoadingProperties.js.map +1 -0
- package/dist/dataunit/state/slice/SelectionSlice.js +4 -4
- package/dist/dataunit/state/slice/SelectionSlice.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/repository/IRepository.d.ts +6 -0
- package/dist/repository/indexeddb/IDBRepository.d.ts +1 -0
- package/dist/repository/indexeddb/IDBRepository.js +3 -0
- package/dist/repository/indexeddb/IDBRepository.js.map +1 -1
- package/dist/utils/ElementUtils.d.ts +2 -0
- package/dist/utils/ElementUtils.js +9 -0
- package/dist/utils/ElementUtils.js.map +1 -0
- package/dist/utils/MaskFormatter.d.ts +2 -1
- package/dist/utils/MaskFormatter.js +5 -1
- package/dist/utils/MaskFormatter.js.map +1 -1
- package/dist/utils/ObjectUtils.d.ts +38 -0
- package/dist/utils/ObjectUtils.js +51 -0
- package/dist/utils/ObjectUtils.js.map +1 -1
- package/dist/utils/OnboardingUtils.js +1 -1
- package/dist/utils/OnboardingUtils.js.map +1 -1
- package/dist/utils/OverflowWatcher/index.d.ts +59 -0
- package/dist/utils/OverflowWatcher/index.js +188 -0
- package/dist/utils/OverflowWatcher/index.js.map +1 -0
- package/dist/utils/OverflowWatcher/types/overflow-callback.d.ts +6 -0
- package/dist/utils/OverflowWatcher/types/overflow-callback.js +2 -0
- package/dist/utils/OverflowWatcher/types/overflow-callback.js.map +1 -0
- package/dist/utils/OverflowWatcher/types/overflow-direction.d.ts +7 -0
- package/dist/utils/OverflowWatcher/types/overflow-direction.js +9 -0
- package/dist/utils/OverflowWatcher/types/overflow-direction.js.map +1 -0
- package/dist/utils/SortingUtils.d.ts +9 -0
- package/dist/utils/SortingUtils.js +24 -0
- package/dist/utils/SortingUtils.js.map +1 -0
- package/jest.config.ts +3 -1
- package/package.json +12 -4
- package/reports/test-report.xml +166 -0
- package/setupTests.js +7 -0
- package/sonar-project.properties +10 -0
- package/src/dataunit/DataUnit.ts +141 -41
- package/src/dataunit/formatting/PrettyFormatter.ts +10 -7
- package/src/dataunit/loading/LoadDataRequest.ts +1 -1
- package/src/dataunit/metadata/DataType.ts +13 -1
- package/src/dataunit/state/action/DataUnitAction.ts +4 -1
- package/src/dataunit/state/slice/ChangesSlice.ts +15 -14
- package/src/dataunit/state/slice/InvalidFieldsSlice.ts +2 -0
- package/src/dataunit/state/slice/LoadingProperties.ts +37 -0
- package/src/dataunit/state/slice/SelectionSlice.ts +4 -4
- package/src/index.ts +8 -1
- package/src/repository/IRepository.ts +7 -0
- package/src/repository/indexeddb/IDBRepository.ts +4 -0
- package/src/utils/ElementUtils.ts +10 -0
- package/src/utils/MaskFormatter.ts +5 -1
- package/src/utils/ObjectUtils.ts +56 -0
- package/src/utils/OnboardingUtils.ts +1 -1
- package/src/utils/OverflowWatcher/index.ts +243 -0
- package/src/utils/OverflowWatcher/types/overflow-callback.ts +6 -0
- package/src/utils/OverflowWatcher/types/overflow-direction.ts +7 -0
- package/src/utils/SortingUtils.ts +30 -0
- package/src/utils/test/objectUtils.spec.ts +109 -0
- package/test/dataunit/formatting/PrettyFormatter.spec.ts +177 -0
- package/test/util/ElementUtils.spec.ts +34 -0
- package/test/util/OverflowWatcher.spec.ts +152 -0
- package/.docs/.nojekyll +0 -1
- package/.docs/enums/Action.md +0 -305
- package/.docs/enums/ChangeOperation.md +0 -52
- package/.docs/enums/DataType.md +0 -63
- package/.docs/enums/DependencyType.md +0 -41
- package/.docs/enums/SelectionMode.md +0 -30
- package/.docs/enums/SortMode.md +0 -30
- package/.docs/enums/UserInterface.md +0 -195
- package/.docs/modules/MaskFormatter.md +0 -37
package/src/dataunit/DataUnit.ts
CHANGED
|
@@ -25,6 +25,8 @@ import { getFormattedValue } from "./formatting/PrettyFormatter.js";
|
|
|
25
25
|
import { v4 as uuid } from "uuid";
|
|
26
26
|
import { DataUnitStorage } from "./DataUnitStorage.js";
|
|
27
27
|
import { getInvalidFieldMessage, InvalidFieldsReducer } from "./state/slice/InvalidFieldsSlice.js";
|
|
28
|
+
import { getLoadingProperties, LoadingPropertiesReducer } from "./state/slice/LoadingProperties.js";
|
|
29
|
+
import SortingUtils from "../utils/SortingUtils.js";
|
|
28
30
|
|
|
29
31
|
/***
|
|
30
32
|
* `DataUnit`: Atua como uma camada de abstração entre o back-end e a interface do usuário.
|
|
@@ -32,27 +34,30 @@ import { getInvalidFieldMessage, InvalidFieldsReducer } from "./state/slice/Inva
|
|
|
32
34
|
export default class DataUnit {
|
|
33
35
|
|
|
34
36
|
public static CHANGING_PAGE_LOADING_SOURCE = "CHANGING_PAGE_LOADING_SOURCE";
|
|
37
|
+
public static ALL_RECORDS_SELECTION_SOURCE = "ALL_RECORDS_SELECTION_SOURCE";
|
|
35
38
|
public static DEFAULT_DATAUNIT_NAME = "dataunit";
|
|
36
39
|
|
|
37
40
|
private _uuid: string;
|
|
38
41
|
private _name: string;
|
|
39
|
-
private _observers: Array<(action: DataUnitAction) => void>;
|
|
42
|
+
private _observers: Array<(action: DataUnitAction, options?:DataUnitEventOptions) => void>;
|
|
40
43
|
private _sortingProvider?: SortingProvider;
|
|
41
44
|
private _filterProviders: Map<string, FilterProvider>;
|
|
42
45
|
private _stateManager: StateManager;
|
|
43
|
-
private _interceptors:
|
|
46
|
+
private _interceptors: Map<string, DUActionInterceptor>;
|
|
44
47
|
private _pageSize: number;
|
|
45
48
|
private _childByName = new Map<string, DataUnit>();
|
|
46
49
|
private _parentDataUnit: DataUnit | undefined;
|
|
47
50
|
private _loadingLockers: Promise<void>[];
|
|
48
51
|
private _savingLockers: Promise<any>[] = [];
|
|
49
52
|
private _defaultSorting: Array<Sort>;
|
|
53
|
+
private _allowReleaseCallbacks: boolean;
|
|
50
54
|
|
|
51
55
|
public metadataLoader?: (dataUnit: DataUnit) => Promise<UnitMetadata>;
|
|
52
56
|
public dataLoader?: (dataUnit: DataUnit, request: LoadDataRequest) => Promise<LoadDataResponse>;
|
|
53
57
|
public saveLoader?: (dataUnit: DataUnit, changes: Array<Change>) => Promise<Array<SavedRecord>>;
|
|
54
58
|
public removeLoader?: (dataUnit: DataUnit, recordIds: Array<string>) => Promise<Array<string>>;
|
|
55
59
|
public recordLoader?: (dataUnit: DataUnit, recordIds: Array<string>) => Promise<Array<Record>>;
|
|
60
|
+
public allRecordsLoader?: (dataUnit: DataUnit) => Array<Record> | undefined;
|
|
56
61
|
|
|
57
62
|
constructor(name: string = DataUnit.DEFAULT_DATAUNIT_NAME, parentDataUnit?: DataUnit) {
|
|
58
63
|
this._uuid = uuid()
|
|
@@ -61,6 +66,7 @@ export default class DataUnit {
|
|
|
61
66
|
this._stateManager = new StateManager(
|
|
62
67
|
[
|
|
63
68
|
HistReducer,
|
|
69
|
+
LoadingPropertiesReducer,
|
|
64
70
|
UnitMetadataReducer,
|
|
65
71
|
LoadingControlReducer,
|
|
66
72
|
RecordsReducer,
|
|
@@ -77,7 +83,8 @@ export default class DataUnit {
|
|
|
77
83
|
this._filterProviders = new Map<string, FilterProvider>();
|
|
78
84
|
this._sortingProvider = undefined;
|
|
79
85
|
this._defaultSorting = [];
|
|
80
|
-
this.
|
|
86
|
+
this._allowReleaseCallbacks = true;
|
|
87
|
+
this._interceptors = new Map();
|
|
81
88
|
this._parentDataUnit = parentDataUnit;
|
|
82
89
|
this._parentDataUnit?.subscribe(this.onDataUnitParentEvent);
|
|
83
90
|
this._loadingLockers = [];
|
|
@@ -108,12 +115,35 @@ export default class DataUnit {
|
|
|
108
115
|
* - Sorting Providers
|
|
109
116
|
*/
|
|
110
117
|
public releaseCallbacks(){
|
|
118
|
+
if(!this._allowReleaseCallbacks) return;
|
|
119
|
+
|
|
111
120
|
this._observers = [];
|
|
112
121
|
this._filterProviders = new Map<string, FilterProvider>();
|
|
113
122
|
this._sortingProvider = undefined;
|
|
114
|
-
this._interceptors =
|
|
123
|
+
this._interceptors = new Map();
|
|
115
124
|
}
|
|
116
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Adiciona uma propriedade transacional que será envida aos
|
|
128
|
+
* loaders (dataLoader, saveLoader, removeLoader e recordLoader) na chamada.
|
|
129
|
+
* Essas propriedades serão limpas ao final da execução de cada método.
|
|
130
|
+
*
|
|
131
|
+
* @param name - Nome da propriedade
|
|
132
|
+
* @param value - Valor da propriedade
|
|
133
|
+
*
|
|
134
|
+
*/
|
|
135
|
+
public addGlobalLoaderProp(name: string, value: string):void{
|
|
136
|
+
this.dispatchAction(Action.LOADING_PROPERTY_ADDED, {[name]: value});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Retorna as propriedades transacionais adicionados anteriores à chamada.
|
|
141
|
+
*
|
|
142
|
+
* @returns - Todas as propriedades desde o final do último loader.
|
|
143
|
+
*/
|
|
144
|
+
public getGlobalLoaderProps(): Map<string, string>{
|
|
145
|
+
return getLoadingProperties(this._stateManager) || new Map();
|
|
146
|
+
}
|
|
117
147
|
|
|
118
148
|
public get dataUnitId(): string{
|
|
119
149
|
return this._uuid;
|
|
@@ -157,6 +187,8 @@ export default class DataUnit {
|
|
|
157
187
|
case Action.NEXT_SELECTED:
|
|
158
188
|
case Action.PREVIOUS_SELECTED:
|
|
159
189
|
case Action.DATA_LOADED:
|
|
190
|
+
case Action.RECORDS_ADDED:
|
|
191
|
+
case Action.EDITION_CANCELED:
|
|
160
192
|
this.clearDataUnit();
|
|
161
193
|
const selectedRecord = this._parentDataUnit?.getSelectedRecord();
|
|
162
194
|
if(selectedRecord != undefined && !this.isNewRecord(selectedRecord.__record__id__)){
|
|
@@ -215,22 +247,24 @@ export default class DataUnit {
|
|
|
215
247
|
if (await this.dispatchAction(Action.LOADING_DATA, request, executionCtx)) {
|
|
216
248
|
if (this.dataLoader) {
|
|
217
249
|
this.dataLoader(this, request).then(
|
|
218
|
-
response => {
|
|
219
|
-
this.dispatchAction(
|
|
250
|
+
async response => {
|
|
251
|
+
await this.dispatchAction(
|
|
220
252
|
Action.DATA_LOADED,
|
|
221
|
-
{...response, keepSelection: request.keepSelection, filters: request.filters},
|
|
253
|
+
{...response, keepSelection: request.keepSelection, filters: request.filters, selectFirstRecord},
|
|
222
254
|
executionCtx
|
|
223
255
|
);
|
|
224
256
|
|
|
257
|
+
await this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
|
|
258
|
+
|
|
225
259
|
if(selectFirstRecord){
|
|
226
260
|
this.requestSelectFirst(executionCtx);
|
|
227
261
|
}
|
|
228
|
-
|
|
229
262
|
resolve(response);
|
|
230
263
|
}
|
|
231
264
|
).catch(error => {
|
|
232
265
|
console.error(error);
|
|
233
266
|
const {errorCode} = error;
|
|
267
|
+
this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
|
|
234
268
|
fail(new ErrorException("Erro ao carregar registros", error, errorCode))
|
|
235
269
|
});
|
|
236
270
|
}
|
|
@@ -292,13 +326,16 @@ export default class DataUnit {
|
|
|
292
326
|
|
|
293
327
|
await this.processLoadingLockers();
|
|
294
328
|
|
|
295
|
-
if (this._parentDataUnit
|
|
329
|
+
if (this._parentDataUnit) {
|
|
330
|
+
const parentRecord = this._parentDataUnit.getSelectedRecord();
|
|
331
|
+
if(parentRecord == undefined || this._parentDataUnit.isNewRecord(parentRecord.__record__id__)){
|
|
296
332
|
if(this.records){
|
|
297
333
|
this.clearDataUnit();
|
|
298
334
|
}
|
|
299
335
|
return Promise.resolve({
|
|
300
336
|
records: []
|
|
301
337
|
});
|
|
338
|
+
}
|
|
302
339
|
}
|
|
303
340
|
|
|
304
341
|
const loadDataRequest = this.getLoadDataRequest(quickFilter, source);
|
|
@@ -311,7 +348,7 @@ export default class DataUnit {
|
|
|
311
348
|
*
|
|
312
349
|
* @param page - Número da página desejada.
|
|
313
350
|
* @param executionCtx - Contexto de execução do carregamento dos registros do DataUnit.
|
|
314
|
-
*
|
|
351
|
+
*
|
|
315
352
|
* @returns - Registros da página desejada.
|
|
316
353
|
*
|
|
317
354
|
*/
|
|
@@ -431,6 +468,7 @@ export default class DataUnit {
|
|
|
431
468
|
const changes: Array<Change> = this.getAllChangesToSave();
|
|
432
469
|
|
|
433
470
|
this.saveLoader(this, changes).then((records) => {
|
|
471
|
+
this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
|
|
434
472
|
const recordsByDataUnit = this.getRecordsByDataUnit(records);
|
|
435
473
|
|
|
436
474
|
const dispatchPromisses = [];
|
|
@@ -445,9 +483,12 @@ export default class DataUnit {
|
|
|
445
483
|
Promise.all(dispatchPromisses).then(() => resolve());
|
|
446
484
|
}).catch(cause => {
|
|
447
485
|
const {errorCode} = cause;
|
|
486
|
+
this.dispatchAction(Action.SAVING_ERROR);
|
|
487
|
+
this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
|
|
448
488
|
fail(new ErrorException("Erro ao salvar alterações", cause, errorCode));
|
|
449
489
|
});
|
|
450
490
|
} else {
|
|
491
|
+
this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
|
|
451
492
|
resolve();
|
|
452
493
|
}
|
|
453
494
|
});
|
|
@@ -513,8 +554,8 @@ export default class DataUnit {
|
|
|
513
554
|
if(selection.isAllRecords()){
|
|
514
555
|
throw new Error("Exclusão remota não implementada.");
|
|
515
556
|
}
|
|
516
|
-
const records = selection?.records || [];
|
|
517
|
-
const recordIds = selection?.recordIds || [];
|
|
557
|
+
const records = selection?.records as Array<Record> || [];
|
|
558
|
+
const recordIds = selection?.recordIds as Array<string> || [];
|
|
518
559
|
return this.removeRecords(recordIds, records, buffered, undefined, silent);
|
|
519
560
|
}
|
|
520
561
|
return Promise.resolve([]);
|
|
@@ -536,6 +577,7 @@ export default class DataUnit {
|
|
|
536
577
|
public async removeRecords(recordIds: Array<string>, cachedRecords: Array<Record>, buffered: boolean = false, executionCtx?: ExecutionContext, silent: boolean = false): Promise<Array<string>> {
|
|
537
578
|
if (recordIds) {
|
|
538
579
|
if (buffered || !this.removeLoader) {
|
|
580
|
+
this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
|
|
539
581
|
this.dispatchAction(Action.RECORDS_REMOVED, { records: recordIds, cachedRecords, buffered: true }, executionCtx);
|
|
540
582
|
} else {
|
|
541
583
|
if (await this.dispatchAction(Action.REMOVING_RECORDS, {silent}, executionCtx)) {
|
|
@@ -547,15 +589,18 @@ export default class DataUnit {
|
|
|
547
589
|
const currentRecordsKeys = Array.from(getCurrentRecords(this._stateManager).keys());
|
|
548
590
|
const removedIndex: Array<number> = recordIds
|
|
549
591
|
.map(id => currentRecordsKeys.indexOf(id))
|
|
550
|
-
.filter(index => index > -1)
|
|
592
|
+
.filter(index => index > -1)
|
|
593
|
+
.sort();
|
|
551
594
|
|
|
552
595
|
const nextIndex = Math.min(removedIndex.slice(-1)[0] + 1, currentRecordsKeys.length);
|
|
553
|
-
const selectionAfterRemove = [currentRecordsKeys[nextIndex]];
|
|
596
|
+
const selectionAfterRemove = currentRecordsKeys[nextIndex] ? [currentRecordsKeys[nextIndex]] : [];
|
|
554
597
|
|
|
555
598
|
this.dispatchAction(Action.RECORDS_REMOVED, { records: removedIds, cachedRecords, removedIndex, buffered: false, selectionAfterRemove }, executionCtx);
|
|
599
|
+
this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
|
|
556
600
|
resolve(removedIds);
|
|
557
601
|
}
|
|
558
602
|
).catch(error => {
|
|
603
|
+
this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
|
|
559
604
|
const {errorCode} = error;
|
|
560
605
|
fail(new ErrorException("Erro ao remover registros", error, errorCode))
|
|
561
606
|
});
|
|
@@ -612,7 +657,6 @@ export default class DataUnit {
|
|
|
612
657
|
*
|
|
613
658
|
*/
|
|
614
659
|
public getFormattedValue(fieldName: string, value?: any): string {
|
|
615
|
-
|
|
616
660
|
const descriptor = this.getField(fieldName);
|
|
617
661
|
if (value == undefined) {
|
|
618
662
|
value = this.getFieldValue(fieldName);
|
|
@@ -635,7 +679,7 @@ export default class DataUnit {
|
|
|
635
679
|
*
|
|
636
680
|
*/
|
|
637
681
|
public addInterceptor(interceptor: DUActionInterceptor): void {
|
|
638
|
-
this._interceptors.
|
|
682
|
+
this._interceptors.set(interceptor.interceptAction.toString(), interceptor);
|
|
639
683
|
}
|
|
640
684
|
|
|
641
685
|
/**
|
|
@@ -646,7 +690,7 @@ export default class DataUnit {
|
|
|
646
690
|
*
|
|
647
691
|
*/
|
|
648
692
|
public removeInterceptor(interceptor: DUActionInterceptor) {
|
|
649
|
-
this._interceptors
|
|
693
|
+
this._interceptors.delete(interceptor.interceptAction.toString())
|
|
650
694
|
}
|
|
651
695
|
|
|
652
696
|
/**
|
|
@@ -848,8 +892,12 @@ export default class DataUnit {
|
|
|
848
892
|
public copySelected(executionCtx?: ExecutionContext): void {
|
|
849
893
|
const selectionInfo = this.getSelectionInfo();
|
|
850
894
|
if (selectionInfo) {
|
|
851
|
-
|
|
895
|
+
if(selectionInfo.isAllRecords()){
|
|
896
|
+
throw new Error("Erro interno: Impossível copiar os registros selecionados pois a seleção atual é virtual.");
|
|
897
|
+
}
|
|
898
|
+
const selectedRecords = selectionInfo.records as Array<Record>;
|
|
852
899
|
if(selectedRecords){
|
|
900
|
+
|
|
853
901
|
this.dispatchAction(Action.RECORDS_COPIED, prepareCopiedRecord(this._stateManager, selectedRecords, this.getParentRecordId()), executionCtx);
|
|
854
902
|
}
|
|
855
903
|
}
|
|
@@ -918,12 +966,16 @@ export default class DataUnit {
|
|
|
918
966
|
* @returns - Promise que será resolvida quando o novo valor for persistido no state.
|
|
919
967
|
*
|
|
920
968
|
*/
|
|
921
|
-
public async setFieldValue(fieldName: string, newValue: any, records?: Array<string
|
|
969
|
+
public async setFieldValue(fieldName: string, newValue: any, records?: Array<string>, options?:DataUnitEventOptions): Promise<boolean> {
|
|
922
970
|
|
|
923
971
|
if(!this.hasNewRecord() && !this.getSelectedRecord()) await this.addRecord();
|
|
924
972
|
|
|
925
973
|
const typedValue = this.validateAndTypeValue(fieldName, newValue);
|
|
926
974
|
const currentValue = this.getFieldValue(fieldName);
|
|
975
|
+
|
|
976
|
+
if(ObjectUtils.hasEquivalentProps(currentValue, typedValue)){
|
|
977
|
+
return Promise.resolve(false);
|
|
978
|
+
}
|
|
927
979
|
|
|
928
980
|
if(newValue instanceof Promise){
|
|
929
981
|
const promise:Promise<boolean> = new Promise(accept => {
|
|
@@ -937,7 +989,7 @@ export default class DataUnit {
|
|
|
937
989
|
}
|
|
938
990
|
|
|
939
991
|
if (currentValue !== typedValue) {
|
|
940
|
-
const promise = this.dispatchAction(Action.DATA_CHANGED, { [fieldName]: typedValue, records }, undefined);
|
|
992
|
+
const promise = this.dispatchAction(Action.DATA_CHANGED, { [fieldName]: typedValue, records }, undefined, options);
|
|
941
993
|
this._savingLockers.push(promise);
|
|
942
994
|
return promise;
|
|
943
995
|
}
|
|
@@ -1065,7 +1117,7 @@ export default class DataUnit {
|
|
|
1065
1117
|
public setSelection(selection: Array<string> | SelectionMode.ALL_RECORDS, executionCtx?: ExecutionContext): Promise<SelectionInfo> {
|
|
1066
1118
|
return new Promise(resolve => {
|
|
1067
1119
|
this.dispatchAction(Action.SELECTION_CHANGED, { type: "id", selection }, executionCtx)
|
|
1068
|
-
.then(()=>resolve(getSelectionInfo(
|
|
1120
|
+
.then(()=>resolve(this.getSelectionInfo()));
|
|
1069
1121
|
});
|
|
1070
1122
|
}
|
|
1071
1123
|
|
|
@@ -1122,8 +1174,16 @@ export default class DataUnit {
|
|
|
1122
1174
|
* @returns - Objeto com informações como registros selecionados e seleção por critério.
|
|
1123
1175
|
*
|
|
1124
1176
|
**/
|
|
1125
|
-
public getSelectionInfo(): SelectionInfo
|
|
1126
|
-
|
|
1177
|
+
public getSelectionInfo(): SelectionInfo{
|
|
1178
|
+
const selectionInfo: SelectionInfo = getSelectionInfo(this._stateManager);
|
|
1179
|
+
selectionInfo.getAllRecords = () => this.allRecordsLoader?.(this);
|
|
1180
|
+
|
|
1181
|
+
if (selectionInfo.sort != undefined && selectionInfo.sort.length > 0) {
|
|
1182
|
+
const sortingFunction = SortingUtils.getSortingFunction(this, selectionInfo.sort)
|
|
1183
|
+
selectionInfo.records?.sort(sortingFunction)
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
return selectionInfo;
|
|
1127
1187
|
}
|
|
1128
1188
|
|
|
1129
1189
|
/**
|
|
@@ -1137,6 +1197,15 @@ export default class DataUnit {
|
|
|
1137
1197
|
return getSelectedRecord(this._stateManager);
|
|
1138
1198
|
}
|
|
1139
1199
|
|
|
1200
|
+
/**
|
|
1201
|
+
* Retorna o DataUnit pai
|
|
1202
|
+
*
|
|
1203
|
+
* @returns DataUnit pai ou undefined
|
|
1204
|
+
*/
|
|
1205
|
+
public getParentDataUnit(): DataUnit | undefined {
|
|
1206
|
+
return this._parentDataUnit;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1140
1209
|
/**
|
|
1141
1210
|
*
|
|
1142
1211
|
* Limpa todos os registros do DataUnit
|
|
@@ -1224,14 +1293,28 @@ export default class DataUnit {
|
|
|
1224
1293
|
/**
|
|
1225
1294
|
*
|
|
1226
1295
|
* Retorna se existe algum tipo de alteração pendente.
|
|
1227
|
-
*
|
|
1296
|
+
*
|
|
1297
|
+
* @param ignoreChildren: Define se deverá ignorar alterações pendentes no DataUnit filho.
|
|
1228
1298
|
* @returns Verdadeiro se existir alterações pendentes.
|
|
1229
1299
|
*
|
|
1230
1300
|
*/
|
|
1231
|
-
public isDirty(): boolean {
|
|
1301
|
+
public isDirty(ignoreChildren?: boolean): boolean {
|
|
1302
|
+
if(ignoreChildren) return isDirty(this._stateManager);
|
|
1303
|
+
|
|
1232
1304
|
return isDirty(this._stateManager) || this.childrenIsDirty();
|
|
1233
1305
|
}
|
|
1234
1306
|
|
|
1307
|
+
/**
|
|
1308
|
+
*
|
|
1309
|
+
* Retorna se existe alterações pendentes no DataUnit pai.
|
|
1310
|
+
*
|
|
1311
|
+
* @returns Verdadeiro se existir alterações pendentes e Falso caso não exista alterações ou não exista DataUnit pai.
|
|
1312
|
+
*
|
|
1313
|
+
*/
|
|
1314
|
+
public isParentDirty(): boolean {
|
|
1315
|
+
return this._parentDataUnit ? this._parentDataUnit.isDirty(true) : false;
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1235
1318
|
/**
|
|
1236
1319
|
*
|
|
1237
1320
|
* Retorna se existe algum DataUnit detail com alterações pendentes.
|
|
@@ -1404,17 +1487,17 @@ export default class DataUnit {
|
|
|
1404
1487
|
* @returns - Verdadeiro se ação iniciada.
|
|
1405
1488
|
*
|
|
1406
1489
|
*/
|
|
1407
|
-
private async dispatchAction(actionType: Action, payload?: any, executionCtx?: ExecutionContext): Promise<boolean> {
|
|
1490
|
+
private async dispatchAction(actionType: Action, payload?: any, executionCtx?: ExecutionContext, options?:DataUnitEventOptions): Promise<boolean> {
|
|
1408
1491
|
return new Promise(async resolve => {
|
|
1409
1492
|
let action = new DataUnitAction(actionType, payload);
|
|
1410
1493
|
if (executionCtx && executionCtx.before) {
|
|
1411
1494
|
action = executionCtx.before(action);
|
|
1412
1495
|
}
|
|
1413
|
-
if (action && this._interceptors && this._interceptors.
|
|
1496
|
+
if (action && this._interceptors && this._interceptors.size > 0) {
|
|
1414
1497
|
action = await this.intercept(action, this._interceptors.values());
|
|
1415
1498
|
}
|
|
1416
1499
|
if (action) {
|
|
1417
|
-
this.doDispatchAction(action);
|
|
1500
|
+
this.doDispatchAction(action, options);
|
|
1418
1501
|
if (executionCtx && executionCtx.after) {
|
|
1419
1502
|
executionCtx.after(action)
|
|
1420
1503
|
}
|
|
@@ -1452,7 +1535,7 @@ export default class DataUnit {
|
|
|
1452
1535
|
* @param action - Ações em execução no DataUnit.
|
|
1453
1536
|
*
|
|
1454
1537
|
*/
|
|
1455
|
-
private doDispatchAction(action: DataUnitAction): void {
|
|
1538
|
+
private doDispatchAction(action: DataUnitAction, options:DataUnitEventOptions = {}): void {
|
|
1456
1539
|
this._stateManager.process(action);
|
|
1457
1540
|
this?._parentDataUnit?.dispatchAction(Action.CHILD_CHANGED, { srcAction: action, srcDataUnit: this });
|
|
1458
1541
|
this._observers.forEach(f => {
|
|
@@ -1461,7 +1544,7 @@ export default class DataUnit {
|
|
|
1461
1544
|
should be continued
|
|
1462
1545
|
*/
|
|
1463
1546
|
try {
|
|
1464
|
-
f(action);
|
|
1547
|
+
f(action, options);
|
|
1465
1548
|
} catch (e) {
|
|
1466
1549
|
console.warn("[DataUnit] error while call observer", e);
|
|
1467
1550
|
}
|
|
@@ -1500,7 +1583,7 @@ export default class DataUnit {
|
|
|
1500
1583
|
* @param observer - Função que recebe como parâmetro as ações que serão monitoradas.
|
|
1501
1584
|
*
|
|
1502
1585
|
*/
|
|
1503
|
-
public subscribe(observer: (action: DataUnitAction) => void) {
|
|
1586
|
+
public subscribe(observer: (action: DataUnitAction, options?:DataUnitEventOptions) => void | Promise<void>) {
|
|
1504
1587
|
this._observers.push(observer);
|
|
1505
1588
|
}
|
|
1506
1589
|
|
|
@@ -1527,12 +1610,16 @@ export default class DataUnit {
|
|
|
1527
1610
|
const selection = getSelection(this._stateManager);
|
|
1528
1611
|
this.dispatchAction(Action.LOADING_RECORD, selection);
|
|
1529
1612
|
|
|
1530
|
-
if(!this.dataLoader)
|
|
1531
|
-
|
|
1613
|
+
if(!this.recordLoader || !this.dataLoader) {
|
|
1614
|
+
this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
|
|
1615
|
+
return;
|
|
1616
|
+
}
|
|
1532
1617
|
|
|
1533
1618
|
this.recordLoader(this, selection).then(response => {
|
|
1534
1619
|
this.dispatchAction(Action.RECORD_LOADED, response)
|
|
1620
|
+
this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
|
|
1535
1621
|
}).catch(cause => {
|
|
1622
|
+
this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
|
|
1536
1623
|
const {errorCode} = cause;
|
|
1537
1624
|
fail(new ErrorException("Erro ao recarregar registro", cause, errorCode));
|
|
1538
1625
|
});
|
|
@@ -1671,7 +1758,7 @@ export default class DataUnit {
|
|
|
1671
1758
|
}
|
|
1672
1759
|
|
|
1673
1760
|
if (selection) {
|
|
1674
|
-
return selection.records
|
|
1761
|
+
return selection.records as Array<Record>;
|
|
1675
1762
|
}
|
|
1676
1763
|
}
|
|
1677
1764
|
|
|
@@ -1689,12 +1776,15 @@ export default class DataUnit {
|
|
|
1689
1776
|
public getSelection(): Array<string> {
|
|
1690
1777
|
console.warn("DataUnit: O método `getSelection` foi descontinuado. Use o método `getSelectionInfo`.");
|
|
1691
1778
|
const selection = this.getSelectionInfo();
|
|
1779
|
+
if(selection == undefined){
|
|
1780
|
+
return [];
|
|
1781
|
+
}
|
|
1692
1782
|
|
|
1693
|
-
if(selection
|
|
1783
|
+
if(selection.isAllRecords()){
|
|
1694
1784
|
throw new Error("Erro interno: Impossível retornar os registros selecionados. A seleção atual é virtual. Use o método `getSelectionInfo`.");
|
|
1695
1785
|
}
|
|
1696
1786
|
|
|
1697
|
-
return selection?.recordIds
|
|
1787
|
+
return selection?.recordIds as Array<string>;
|
|
1698
1788
|
}
|
|
1699
1789
|
|
|
1700
1790
|
/**
|
|
@@ -1730,6 +1820,10 @@ export default class DataUnit {
|
|
|
1730
1820
|
return loadingLockerResolver || Promise.resolve;
|
|
1731
1821
|
}
|
|
1732
1822
|
|
|
1823
|
+
public set allowReleaseCallbacks(allow: boolean){
|
|
1824
|
+
this._allowReleaseCallbacks = allow;
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1733
1827
|
private async processLoadingLockers(){
|
|
1734
1828
|
if(this._loadingLockers.length) {
|
|
1735
1829
|
await Promise.all(this._loadingLockers);
|
|
@@ -1871,12 +1965,13 @@ export enum SelectionMode{
|
|
|
1871
1965
|
|
|
1872
1966
|
export class SelectionInfo{
|
|
1873
1967
|
|
|
1874
|
-
private _records: Array<Record>;
|
|
1875
1968
|
public mode: SelectionMode;
|
|
1876
|
-
private _total?: number;
|
|
1877
1969
|
public filters?: Array<Filter>;
|
|
1878
1970
|
public sort?: Array<Sort>;
|
|
1879
|
-
|
|
1971
|
+
public getAllRecords?: () => Array<Record> | undefined;
|
|
1972
|
+
private _records: Array<Record>;
|
|
1973
|
+
private _total?: number;
|
|
1974
|
+
|
|
1880
1975
|
constructor(records: Array<Record>, mode: SelectionMode = SelectionMode.SOME_RECORDS, total?:number, filters?: Array<Filter>, sort?: Array<Sort>){
|
|
1881
1976
|
this._records = records;
|
|
1882
1977
|
this._total = total;
|
|
@@ -1887,7 +1982,10 @@ export class SelectionInfo{
|
|
|
1887
1982
|
|
|
1888
1983
|
public get records(): Array<Record> | undefined{
|
|
1889
1984
|
if(this.isAllRecords()){
|
|
1890
|
-
|
|
1985
|
+
if(this.getAllRecords != undefined){
|
|
1986
|
+
return this.getAllRecords();
|
|
1987
|
+
}
|
|
1988
|
+
throw new Error("Erro interno: Impossível retornar os registros selecionados numa seleção virtual.");
|
|
1891
1989
|
}
|
|
1892
1990
|
return this._records;
|
|
1893
1991
|
}
|
|
@@ -1906,7 +2004,7 @@ export class SelectionInfo{
|
|
|
1906
2004
|
if(this.isAllRecords()){
|
|
1907
2005
|
return this._total || 0;
|
|
1908
2006
|
}
|
|
1909
|
-
return this.records == undefined ? 0: this.records.length;
|
|
2007
|
+
return this.records == undefined ? 0 : (this.records as Array<Record>).length;
|
|
1910
2008
|
}
|
|
1911
2009
|
|
|
1912
2010
|
public isAllRecords(): boolean{
|
|
@@ -1917,3 +2015,5 @@ export class SelectionInfo{
|
|
|
1917
2015
|
return this.length === 0;
|
|
1918
2016
|
}
|
|
1919
2017
|
}
|
|
2018
|
+
|
|
2019
|
+
export type DataUnitEventOptions = {[key:string]: any};
|
|
@@ -10,10 +10,10 @@ export const getFormattedValue = (value: any, descriptor?: FieldDescriptor) => {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
if(descriptor?.dataType === DataType.OBJECT){
|
|
13
|
-
if(Object.hasOwn(value, "value")){
|
|
13
|
+
if(value && Object.hasOwn(value, "value")){
|
|
14
14
|
return getSearchFormat(value, descriptor);
|
|
15
15
|
}
|
|
16
|
-
return value
|
|
16
|
+
return !value ? "" : value.toString();
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
if(descriptor?.userInterface === UserInterface.OPTIONSELECTOR){
|
|
@@ -43,7 +43,7 @@ export const getFormattedValue = (value: any, descriptor?: FieldDescriptor) => {
|
|
|
43
43
|
const mask = getMask(value, descriptor);
|
|
44
44
|
if(mask != undefined){
|
|
45
45
|
try{
|
|
46
|
-
return new MaskFormatter(mask).format(value);
|
|
46
|
+
return new MaskFormatter(mask).format(value, true);
|
|
47
47
|
} catch(error){
|
|
48
48
|
console.warn(`Erro ao formatar valor: ${value}. Mascara: ${mask}. Erro: ${error}`);
|
|
49
49
|
}
|
|
@@ -53,6 +53,7 @@ export const getFormattedValue = (value: any, descriptor?: FieldDescriptor) => {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
const getNumberFormat = (value: any, descriptor: FieldDescriptor) => {
|
|
56
|
+
if(value === undefined || value === null) return "";
|
|
56
57
|
if(descriptor.userInterface === UserInterface.INTEGERNUMBER){
|
|
57
58
|
return value;
|
|
58
59
|
}
|
|
@@ -79,10 +80,12 @@ const getOptionFormat = (value: any, descriptor: FieldDescriptor) => {
|
|
|
79
80
|
options = JSON.parse(prop);
|
|
80
81
|
} else {
|
|
81
82
|
options = {};
|
|
82
|
-
prop
|
|
83
|
+
if(prop != undefined){
|
|
84
|
+
prop.forEach(opt => options[opt.label] = opt.value);
|
|
85
|
+
}
|
|
83
86
|
}
|
|
84
87
|
|
|
85
|
-
if(typeof value === "object"){
|
|
88
|
+
if(value && typeof value === "object" ){
|
|
86
89
|
value = value.value
|
|
87
90
|
}
|
|
88
91
|
|
|
@@ -90,7 +93,7 @@ const getOptionFormat = (value: any, descriptor: FieldDescriptor) => {
|
|
|
90
93
|
return options[value];
|
|
91
94
|
}
|
|
92
95
|
|
|
93
|
-
return value;
|
|
96
|
+
return value ?? "";
|
|
94
97
|
}
|
|
95
98
|
|
|
96
99
|
|
|
@@ -101,7 +104,7 @@ const getMask = (value: string, descriptor: FieldDescriptor | undefined): string
|
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
const mask = descriptor.properties?.mask;
|
|
104
|
-
if(mask == undefined){
|
|
107
|
+
if(mask == undefined || !value){
|
|
105
108
|
return;
|
|
106
109
|
}
|
|
107
110
|
|
|
@@ -4,7 +4,7 @@ import { Filter, Sort } from "../metadata/UnitMetadata.js";
|
|
|
4
4
|
/** Atributos enviados na requisição de carregamento dos registros */
|
|
5
5
|
export interface LoadDataRequest {
|
|
6
6
|
/** De onde partiu o refresh. Por padrão a fonte não é identificada */
|
|
7
|
-
source?:
|
|
7
|
+
source?: string;
|
|
8
8
|
|
|
9
9
|
/** Indice inicial dos registros que será retornado */
|
|
10
10
|
offset?: number;
|
|
@@ -67,7 +67,16 @@ export const getConvertedValue = (dataType: DataType, value: any): any => {
|
|
|
67
67
|
case DataType.NUMBER:
|
|
68
68
|
return value === "" || isNaN(Number(value)) ? null : Number(value);
|
|
69
69
|
case DataType.OBJECT:
|
|
70
|
-
|
|
70
|
+
//Caso de uso campo DataType do tipo STRING e UserInterface do tipo TEXT, que tem relacionamento (TGFPRO.GRUPOPIS)
|
|
71
|
+
if(typeof value === "string") {
|
|
72
|
+
try{
|
|
73
|
+
return JSON.parse(value);
|
|
74
|
+
}catch(e){
|
|
75
|
+
console.warn(`Erro ao fazer parse do valor ${value} para objeto, dataType: ${dataType}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return value;
|
|
71
80
|
case DataType.BOOLEAN:
|
|
72
81
|
if (typeof value === "string") {
|
|
73
82
|
return Boolean(value === 'true');
|
|
@@ -110,6 +119,9 @@ export const toString = ( dataType: DataType|undefined, value: any): string => {
|
|
|
110
119
|
} else if (dataType === DataType.DATE) {
|
|
111
120
|
if (typeof value === "string") {
|
|
112
121
|
value = DateUtils.strToDate(value);
|
|
122
|
+
if (value == undefined) {
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
113
125
|
}
|
|
114
126
|
return DateUtils.formatRfc3339(value as Date);
|
|
115
127
|
} else {
|
|
@@ -35,6 +35,7 @@ export enum Action{
|
|
|
35
35
|
|
|
36
36
|
SAVING_DATA = "savingData",
|
|
37
37
|
DATA_SAVED = "dataSaved",
|
|
38
|
+
SAVING_ERROR = "savingError",
|
|
38
39
|
|
|
39
40
|
REMOVING_RECORDS = "removingRecords",
|
|
40
41
|
RECORDS_REMOVED = "recordsRemoved",
|
|
@@ -63,6 +64,8 @@ export enum Action{
|
|
|
63
64
|
CHILD_CHANGED = "childChanged",
|
|
64
65
|
|
|
65
66
|
FIELD_INVALIDATED = "fieldInvalidated",
|
|
66
|
-
INVALIDATE_CLEAN = "invalidateClean"
|
|
67
|
+
INVALIDATE_CLEAN = "invalidateClean",
|
|
67
68
|
|
|
69
|
+
LOADING_PROPERTY_ADDED = "loadingPropertyAdded",
|
|
70
|
+
LOADING_PROPERTIES_CLEANED = "loadingPropertiesCleaned"
|
|
68
71
|
}
|
|
@@ -94,27 +94,28 @@ export const getChangedFieldValue = (fieldName: string, record: Record, stateMan
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
export const getChangesToSave = (dataUnit: string, stateManager: StateManager): Array<Change> => {
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
|
|
99
98
|
const changes = getChanges(stateManager);
|
|
100
99
|
const selectedRecords = getSelectionRecords(stateManager) || [];
|
|
101
|
-
const records:
|
|
100
|
+
const records: Map<string, Record> = new Map(
|
|
102
101
|
getRecords(stateManager)
|
|
103
102
|
.concat(
|
|
104
|
-
selectedRecords
|
|
105
|
-
.filter(record => !isAddedRecord(record.__record__id__, stateManager)
|
|
106
|
-
)
|
|
103
|
+
selectedRecords.filter(record => !isAddedRecord(record.__record__id__, stateManager))
|
|
107
104
|
)
|
|
105
|
+
.map(r => [r.__record__id__, r])
|
|
108
106
|
);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
107
|
+
|
|
108
|
+
const result: Array<Change> = [];
|
|
109
|
+
|
|
110
|
+
if(changes != undefined){
|
|
111
|
+
Array.from(changes.entries())
|
|
112
|
+
.forEach(([recordId, change]) =>{
|
|
113
|
+
const record = records.get(recordId);
|
|
114
|
+
if(record != undefined){
|
|
115
|
+
result.push(new Change(dataUnit, record, change, ChangeOperation.UPDATE, record.__record__source__id__));
|
|
115
116
|
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
118
119
|
|
|
119
120
|
const addedRecords = getAddedRecords(stateManager);
|
|
120
121
|
if (addedRecords) {
|
|
@@ -15,6 +15,8 @@ class InvalidFieldsReducerImpl implements ActionReducer{
|
|
|
15
15
|
return makeInvalid(currentState, action.payload);
|
|
16
16
|
case Action.INVALIDATE_CLEAN:
|
|
17
17
|
return clearRecord(currentState, action.payload);
|
|
18
|
+
case Action.EDITION_CANCELED:
|
|
19
|
+
return undefined;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
return currentState;
|