@sankhyalabs/core 5.20.0-dev.8 → 5.20.0-dev.81
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/classes/Base64Utils.md +39 -0
- package/.docs/classes/Change.md +11 -11
- package/.docs/classes/ColumnFilterManager.md +145 -0
- package/.docs/classes/DataUnit.md +429 -139
- package/.docs/classes/DataUnitInMemoryLoader.md +303 -0
- package/.docs/classes/DataUnitLoaderUtils.md +151 -0
- package/.docs/classes/DateUtils.md +8 -8
- package/.docs/classes/FieldComparator.md +2 -2
- package/.docs/classes/IDBRepository.md +22 -0
- package/.docs/classes/KeyboardManager.md +99 -9
- package/.docs/classes/LockManager.md +249 -0
- package/.docs/classes/MaskFormatter.md +66 -14
- package/.docs/classes/ObjectUtils.md +189 -0
- package/.docs/classes/OverflowWatcher.md +533 -0
- package/.docs/classes/SelectionInfo.md +25 -11
- package/.docs/classes/ServiceCanceledException.md +193 -0
- package/.docs/classes/ServiceUtils.md +67 -0
- package/.docs/classes/SilentException.md +193 -0
- package/.docs/classes/StringUtils.md +33 -9
- package/.docs/classes/UserAgentUtils.md +15 -1
- package/.docs/enumerations/Action.md +41 -21
- package/.docs/enumerations/ChangeOperation.md +4 -4
- package/.docs/enumerations/LockManagerOperation.md +33 -0
- package/.docs/enumerations/OverflowDirection.md +29 -0
- package/.docs/enumerations/RECORD_DATE_FORMAT.md +27 -0
- package/.docs/enumerations/SelectionMode.md +2 -2
- package/.docs/enumerations/StorageType.md +37 -0
- package/.docs/enumerations/UserInterface.md +15 -5
- package/.docs/globals.md +25 -0
- package/.docs/interfaces/DUActionInterceptor.md +1 -1
- package/.docs/interfaces/DataUnitInMemoryLoaderConfig.md +37 -0
- package/.docs/interfaces/IRepository.md +18 -0
- package/.docs/interfaces/LoadDataRequest.md +1 -1
- package/.docs/interfaces/OverFlowWatcherParams.md +67 -0
- package/.docs/interfaces/PageRequest.md +3 -3
- package/.docs/interfaces/PaginationInfo.md +25 -0
- package/.docs/interfaces/PaginationInfoBuilderParams.md +37 -0
- package/.docs/interfaces/QuickFilter.md +3 -3
- package/.docs/interfaces/Record.md +4 -4
- package/.docs/interfaces/SavedRecord.md +5 -5
- package/.docs/interfaces/WaitingChange.md +3 -3
- package/.docs/namespaces/MaskFormatter/type-aliases/MaskCharacter.md +1 -1
- package/.docs/namespaces/MaskFormatter/variables/MaskCharacter.md +1 -1
- 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/.releaserc +1 -0
- package/bun.lockb +0 -0
- package/dist/dataunit/DataUnit.d.ts +92 -13
- package/dist/dataunit/DataUnit.js +227 -71
- package/dist/dataunit/DataUnit.js.map +1 -1
- package/dist/dataunit/DataUnitHelper.js +6 -5
- package/dist/dataunit/DataUnitHelper.js.map +1 -1
- package/dist/dataunit/formatting/PrettyFormatter.js +17 -6
- package/dist/dataunit/formatting/PrettyFormatter.js.map +1 -1
- package/dist/dataunit/loader/DataUnitInMemoryLoaderConfig.d.ts +9 -0
- package/dist/dataunit/loader/DataUnitInMemoryLoaderConfig.js +6 -0
- package/dist/dataunit/loader/DataUnitInMemoryLoaderConfig.js.map +1 -0
- package/dist/dataunit/loader/dataUnitInMemoryLoader.d.ts +25 -0
- package/dist/dataunit/loader/dataUnitInMemoryLoader.js +131 -0
- package/dist/dataunit/loader/dataUnitInMemoryLoader.js.map +1 -0
- package/dist/dataunit/loader/utils/dataUnitLoaderUtils.d.ts +20 -0
- package/dist/dataunit/loader/utils/dataUnitLoaderUtils.js +62 -0
- package/dist/dataunit/loader/utils/dataUnitLoaderUtils.js.map +1 -0
- package/dist/dataunit/loading/LoadDataRequest.d.ts +1 -1
- package/dist/dataunit/loading/PaginationInfo.d.ts +8 -0
- package/dist/dataunit/metadata/DataType.js +7 -1
- package/dist/dataunit/metadata/DataType.js.map +1 -1
- package/dist/dataunit/metadata/UnitMetadata.d.ts +1 -0
- package/dist/dataunit/metadata/UnitMetadata.js +1 -0
- package/dist/dataunit/metadata/UnitMetadata.js.map +1 -1
- package/dist/dataunit/sorting/FieldComparator.d.ts +2 -2
- package/dist/dataunit/sorting/FieldComparator.js +4 -9
- package/dist/dataunit/sorting/FieldComparator.js.map +1 -1
- package/dist/dataunit/state/action/DataUnitAction.d.ts +2 -0
- package/dist/dataunit/state/action/DataUnitAction.js +2 -0
- package/dist/dataunit/state/action/DataUnitAction.js.map +1 -1
- package/dist/dataunit/state/slice/LoadingControlSlice.js +16 -0
- package/dist/dataunit/state/slice/LoadingControlSlice.js.map +1 -1
- package/dist/dataunit/state/slice/RecordsSlice.js +1 -1
- package/dist/dataunit/state/slice/RecordsSlice.js.map +1 -1
- package/dist/dataunit/state/slice/SelectionSlice.js +4 -4
- package/dist/dataunit/state/slice/SelectionSlice.js.map +1 -1
- package/dist/exceptions/ServiceCanceledException.d.ts +14 -0
- package/dist/exceptions/ServiceCanceledException.js +13 -0
- package/dist/exceptions/ServiceCanceledException.js.map +1 -0
- package/dist/exceptions/SilentException.d.ts +14 -0
- package/dist/exceptions/SilentException.js +13 -0
- package/dist/exceptions/SilentException.js.map +1 -0
- package/dist/index.d.ts +13 -2
- package/dist/index.js +12 -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/Base64Utils.d.ts +7 -0
- package/dist/utils/Base64Utils.js +13 -0
- package/dist/utils/Base64Utils.js.map +1 -0
- package/dist/utils/CacheManager/index.d.ts +52 -0
- package/dist/utils/CacheManager/index.js +101 -0
- package/dist/utils/CacheManager/index.js.map +1 -0
- package/dist/utils/CacheManager/interfaces/index.d.ts +5 -0
- package/dist/utils/CacheManager/interfaces/index.js +7 -0
- package/dist/utils/CacheManager/interfaces/index.js.map +1 -0
- package/dist/utils/ColumnFilterManager.d.ts +19 -0
- package/dist/utils/ColumnFilterManager.js +73 -0
- package/dist/utils/ColumnFilterManager.js.map +1 -0
- package/dist/utils/DateUtils.js +3 -0
- package/dist/utils/DateUtils.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/KeyboardManager/index.d.ts +9 -0
- package/dist/utils/KeyboardManager/index.js +45 -1
- package/dist/utils/KeyboardManager/index.js.map +1 -1
- package/dist/utils/KeyboardManager/interface.d.ts +1 -0
- package/dist/utils/LockManager.d.ts +58 -0
- package/dist/utils/LockManager.js +188 -0
- package/dist/utils/LockManager.js.map +1 -0
- package/dist/utils/MaskFormatter.d.ts +16 -1
- package/dist/utils/MaskFormatter.js +82 -2
- package/dist/utils/MaskFormatter.js.map +1 -1
- package/dist/utils/ObjectUtils.d.ts +52 -0
- package/dist/utils/ObjectUtils.js +71 -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/ServiceUtils.d.ts +24 -0
- package/dist/utils/ServiceUtils.js +40 -0
- package/dist/utils/ServiceUtils.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/dist/utils/StringUtils.d.ts +6 -0
- package/dist/utils/StringUtils.js +23 -6
- package/dist/utils/StringUtils.js.map +1 -1
- package/dist/utils/UserAgentUtils/index.d.ts +1 -0
- package/dist/utils/UserAgentUtils/index.js +5 -0
- package/dist/utils/UserAgentUtils/index.js.map +1 -1
- package/jest.config.ts +2 -0
- package/package.json +2 -1
- package/reports/test-report.xml +760 -0
- package/setupTests.js +7 -0
- package/sonar-project.properties +6 -3
- package/src/dataunit/DataUnit.ts +278 -86
- package/src/dataunit/DataUnitHelper.ts +6 -5
- package/src/dataunit/formatting/PrettyFormatter.ts +19 -6
- package/src/dataunit/loader/DataUnitInMemoryLoaderConfig.ts +10 -0
- package/src/dataunit/loader/dataUnitInMemoryLoader.ts +176 -0
- package/src/dataunit/loader/utils/dataUnitLoaderUtils.ts +86 -0
- package/src/dataunit/loading/LoadDataRequest.ts +1 -1
- package/src/dataunit/loading/PaginationInfo.ts +10 -0
- package/src/dataunit/metadata/DataType.ts +8 -1
- package/src/dataunit/metadata/UnitMetadata.ts +1 -0
- package/src/dataunit/sorting/FieldComparator.ts +18 -32
- package/src/dataunit/state/action/DataUnitAction.ts +2 -0
- package/src/dataunit/state/slice/LoadingControlSlice.ts +42 -0
- package/src/dataunit/state/slice/RecordsSlice.ts +1 -1
- package/src/dataunit/state/slice/SelectionSlice.ts +4 -4
- package/src/dataunit/state/slice/test/RecordsSlice.spec.ts +45 -0
- package/src/dataunit/test/DataUnit.spec.ts +44 -0
- package/src/exceptions/ServiceCanceledException.ts +25 -0
- package/src/exceptions/SilentException.ts +25 -0
- package/src/index.ts +32 -1
- package/src/repository/IRepository.ts +7 -0
- package/src/repository/indexeddb/IDBRepository.ts +4 -0
- package/src/utils/Base64Utils.ts +13 -0
- package/src/utils/CacheManager/index.ts +103 -0
- package/src/utils/CacheManager/interfaces/index.ts +5 -0
- package/src/utils/ColumnFilterManager.ts +104 -0
- package/src/utils/DateUtils.ts +3 -0
- package/src/utils/ElementUtils.ts +10 -0
- package/src/utils/KeyboardManager/index.ts +57 -0
- package/src/utils/KeyboardManager/interface.ts +1 -0
- package/src/utils/LockManager.ts +207 -0
- package/src/utils/MaskFormatter.ts +93 -2
- package/src/utils/ObjectUtils.ts +77 -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/ServiceUtils.ts +36 -0
- package/src/utils/SortingUtils.ts +30 -0
- package/src/utils/StringUtils.ts +23 -6
- package/src/utils/UserAgentUtils/index.ts +6 -1
- package/test/dataunit/formatting/PrettyFormatter.spec.ts +177 -0
- package/test/dataunit/loader/dataUnitInMemoryLoader.spec.ts +221 -0
- package/test/dataunit/loader/utils/dataUnitLoaderUtils.spec.ts +158 -0
- package/test/testCases/NumberUtilsTestCases.ts +190 -0
- package/test/testCases/StringUtilsTestCases.ts +435 -0
- package/test/testCases/TimeFormatterTestUtils.ts +43 -0
- package/test/util/ColumnFilterManager.spec.ts +133 -0
- package/test/util/ElementUtils.spec.ts +34 -0
- package/test/util/NumberUtils.spec.ts +72 -150
- package/test/util/ObjectUtils.spec.ts +572 -0
- package/test/util/OverflowWatcher.spec.ts +152 -0
- package/test/util/StringUtils.spec.ts +260 -36
- package/test/util/TimeFormatter.spec.ts +65 -18
|
@@ -31,17 +31,18 @@ export function defaultDataLoader(dataUnit: DataUnit, request: LoadDataRequest,
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
function buildPaginationInfo({ offset, limit }: LoadDataRequest, records: Array<Record>): PaginationInfo | undefined {
|
|
34
|
-
if (offset === undefined || limit === undefined) {
|
|
34
|
+
if (offset === undefined || limit === undefined || records === undefined) {
|
|
35
35
|
return undefined;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const
|
|
38
|
+
const total = records?.length || 0;
|
|
39
|
+
const lastRecord = Math.min(offset + limit, total);
|
|
39
40
|
return {
|
|
40
|
-
currentPage: Math.ceil(offset / limit),
|
|
41
|
+
currentPage: limit === 0 ? 0 : Math.ceil(offset / limit),
|
|
41
42
|
firstRecord: offset,
|
|
42
43
|
lastRecord: lastRecord,
|
|
43
|
-
total:
|
|
44
|
-
hasMore: !!(
|
|
44
|
+
total: total,
|
|
45
|
+
hasMore: !!(total - lastRecord),
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
48
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import DateUtils from '../../utils/DateUtils.js';
|
|
2
2
|
import { MaskFormatter } from '../../utils/MaskFormatter.js';
|
|
3
3
|
import { NumberUtils } from '../../utils/NumberUtils.js';
|
|
4
|
+
import { TimeFormatter } from '../../utils/TimeFormatter.js';
|
|
4
5
|
import { DataType, toString } from '../metadata/DataType.js';
|
|
5
6
|
import { FieldDescriptor, UserInterface } from '../metadata/UnitMetadata.js';
|
|
6
7
|
|
|
@@ -10,10 +11,13 @@ export const getFormattedValue = (value: any, descriptor?: FieldDescriptor) => {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if(descriptor?.dataType === DataType.OBJECT){
|
|
13
|
-
if(Object.hasOwn(value, "value")){
|
|
14
|
+
if(value && Object.hasOwn(value, "value")){
|
|
14
15
|
return getSearchFormat(value, descriptor);
|
|
15
16
|
}
|
|
16
|
-
|
|
17
|
+
|
|
18
|
+
if(value === null || value === undefined) return "";
|
|
19
|
+
|
|
20
|
+
return value.toString();
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
if(descriptor?.userInterface === UserInterface.OPTIONSELECTOR){
|
|
@@ -36,6 +40,10 @@ export const getFormattedValue = (value: any, descriptor?: FieldDescriptor) => {
|
|
|
36
40
|
return DateUtils.formatTime(value);
|
|
37
41
|
}
|
|
38
42
|
|
|
43
|
+
if(descriptor?.userInterface === UserInterface.ELAPSEDTIME){
|
|
44
|
+
return TimeFormatter.prepareValue(value, true);
|
|
45
|
+
}
|
|
46
|
+
|
|
39
47
|
if(descriptor?.userInterface === UserInterface.DATETIME){
|
|
40
48
|
return DateUtils.formatDateTime(value);
|
|
41
49
|
}
|
|
@@ -43,7 +51,7 @@ export const getFormattedValue = (value: any, descriptor?: FieldDescriptor) => {
|
|
|
43
51
|
const mask = getMask(value, descriptor);
|
|
44
52
|
if(mask != undefined){
|
|
45
53
|
try{
|
|
46
|
-
return new MaskFormatter(mask).format(value);
|
|
54
|
+
return new MaskFormatter(mask).format(value, true);
|
|
47
55
|
} catch(error){
|
|
48
56
|
console.warn(`Erro ao formatar valor: ${value}. Mascara: ${mask}. Erro: ${error}`);
|
|
49
57
|
}
|
|
@@ -53,6 +61,7 @@ export const getFormattedValue = (value: any, descriptor?: FieldDescriptor) => {
|
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
const getNumberFormat = (value: any, descriptor: FieldDescriptor) => {
|
|
64
|
+
if(value === undefined || value === null) return "";
|
|
56
65
|
if(descriptor.userInterface === UserInterface.INTEGERNUMBER){
|
|
57
66
|
return value;
|
|
58
67
|
}
|
|
@@ -68,6 +77,10 @@ const getSearchFormat = (value: any, descriptor: FieldDescriptor) => {
|
|
|
68
77
|
return label ? `${codeValue} - ${label}` : codeValue;
|
|
69
78
|
}
|
|
70
79
|
|
|
80
|
+
if(descriptor.userInterface === UserInterface.SEARCHPLUS){
|
|
81
|
+
return codeValue;
|
|
82
|
+
}
|
|
83
|
+
|
|
71
84
|
return label ? label : codeValue;
|
|
72
85
|
}
|
|
73
86
|
|
|
@@ -84,7 +97,7 @@ const getOptionFormat = (value: any, descriptor: FieldDescriptor) => {
|
|
|
84
97
|
}
|
|
85
98
|
}
|
|
86
99
|
|
|
87
|
-
if(typeof value === "object"){
|
|
100
|
+
if(value && typeof value === "object" ){
|
|
88
101
|
value = value.value
|
|
89
102
|
}
|
|
90
103
|
|
|
@@ -92,7 +105,7 @@ const getOptionFormat = (value: any, descriptor: FieldDescriptor) => {
|
|
|
92
105
|
return options[value];
|
|
93
106
|
}
|
|
94
107
|
|
|
95
|
-
return value;
|
|
108
|
+
return value ?? "";
|
|
96
109
|
}
|
|
97
110
|
|
|
98
111
|
|
|
@@ -103,7 +116,7 @@ const getMask = (value: string, descriptor: FieldDescriptor | undefined): string
|
|
|
103
116
|
}
|
|
104
117
|
|
|
105
118
|
const mask = descriptor.properties?.mask;
|
|
106
|
-
if(mask == undefined){
|
|
119
|
+
if(mask == undefined || !value){
|
|
107
120
|
return;
|
|
108
121
|
}
|
|
109
122
|
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Change,
|
|
3
|
+
ChangeOperation,
|
|
4
|
+
DataType,
|
|
5
|
+
DataUnit,
|
|
6
|
+
DateUtils,
|
|
7
|
+
FieldDescriptor,
|
|
8
|
+
LoadDataRequest,
|
|
9
|
+
LoadDataResponse,
|
|
10
|
+
Record,
|
|
11
|
+
SavedRecord,
|
|
12
|
+
StringUtils,
|
|
13
|
+
UnitMetadata,
|
|
14
|
+
} from '../../index.js';
|
|
15
|
+
import { DataUnitInMemoryLoaderConfig, RECORD_DATE_FORMAT } from './DataUnitInMemoryLoaderConfig.js';
|
|
16
|
+
import { DataUnitLoaderUtils } from './utils/dataUnitLoaderUtils.js';
|
|
17
|
+
|
|
18
|
+
export class DataUnitInMemoryLoader {
|
|
19
|
+
private _dataUnit: DataUnit;
|
|
20
|
+
private _metadata: UnitMetadata | undefined;
|
|
21
|
+
private _initialRecords: Array<Record> = [];
|
|
22
|
+
private recordDateFormat: RECORD_DATE_FORMAT;
|
|
23
|
+
public static readonly IN_MEMORY_DATA_UNIT_NAME = 'InMemoryDataUnit';
|
|
24
|
+
public static readonly DEFAULT_PAGE_SIZE = 150;
|
|
25
|
+
|
|
26
|
+
constructor(metadata?: UnitMetadata, records?: Array<Record>, config?: DataUnitInMemoryLoaderConfig) {
|
|
27
|
+
|
|
28
|
+
this.metadata = metadata as UnitMetadata;
|
|
29
|
+
this.recordDateFormat = config?.recordDateFormat ?? RECORD_DATE_FORMAT.DD_MM_YYYY;
|
|
30
|
+
this.records = records ?? [] as Array<Record>;
|
|
31
|
+
|
|
32
|
+
this._dataUnit = new DataUnit(DataUnitInMemoryLoader.IN_MEMORY_DATA_UNIT_NAME);
|
|
33
|
+
this._dataUnit.pageSize = config?.pageSize ?? DataUnitInMemoryLoader.DEFAULT_PAGE_SIZE;
|
|
34
|
+
this._dataUnit.metadataLoader = () => this.metadaLoader();
|
|
35
|
+
this._dataUnit.dataLoader = (dataUnit: DataUnit, request: LoadDataRequest) => this.inMemoryLoader(dataUnit, request, this.getRecordsToLoad());
|
|
36
|
+
this._dataUnit.saveLoader = (_dataUnit: DataUnit, changes: Array<Change>) => this.saveLoader(_dataUnit, changes);
|
|
37
|
+
this._dataUnit.removeLoader = (_dataUnit: DataUnit, recordIds: Array<string>) => this.removeLoader(_dataUnit, recordIds);
|
|
38
|
+
|
|
39
|
+
this.dataUnit.loadMetadata().then(() => {
|
|
40
|
+
if (config?.autoLoad !== false) {
|
|
41
|
+
this.dataUnit.loadData();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private getRecordsToLoad(): Array<Record> {
|
|
47
|
+
if (this._initialRecords == undefined && this.dataUnit.records.length > 0) {
|
|
48
|
+
this._initialRecords = this.dataUnit.records;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const addedRecords = this.dataUnit.getAddedRecords();
|
|
52
|
+
if (addedRecords) {
|
|
53
|
+
return [...this._initialRecords, ...addedRecords];
|
|
54
|
+
}
|
|
55
|
+
return this._initialRecords;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public get dataUnit(): DataUnit {
|
|
59
|
+
return this._dataUnit;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public get records(): Array<Record> {
|
|
63
|
+
return this.dataUnit.records;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public set records(records: Array<Record>) {
|
|
67
|
+
const columns = this.buildColumns();
|
|
68
|
+
|
|
69
|
+
this._initialRecords = this.buildInitialRecords(records, columns);
|
|
70
|
+
|
|
71
|
+
if (!this._dataUnit) return;
|
|
72
|
+
|
|
73
|
+
//Isso força o refresh internamente no datunit
|
|
74
|
+
this._dataUnit.loadData();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public static getConvertedValue(descriptor: FieldDescriptor, strValue: string, dateFormat?: RECORD_DATE_FORMAT) {
|
|
78
|
+
if (!descriptor) return strValue;
|
|
79
|
+
if (descriptor.dataType === DataType.BOOLEAN) return strValue === 'S';
|
|
80
|
+
if (descriptor.dataType === DataType.NUMBER) return Number(strValue);
|
|
81
|
+
if (descriptor.dataType === DataType.OBJECT) return JSON.parse(strValue);
|
|
82
|
+
|
|
83
|
+
if (descriptor.dataType === DataType.DATE) {
|
|
84
|
+
return dateFormat === RECORD_DATE_FORMAT.ISO
|
|
85
|
+
? DateUtils.validateDate(new Date(strValue), true)
|
|
86
|
+
: DateUtils.strToDate(strValue, true);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return strValue;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private buildColumns() {
|
|
93
|
+
return this._metadata
|
|
94
|
+
? new Map(this._metadata.fields.map(descriptor => [descriptor.name, descriptor]))
|
|
95
|
+
: undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private buildInitialRecords(records: Array<Record>, columns: Map<string, FieldDescriptor> | undefined) {
|
|
99
|
+
const newRecords = records?.map(record => {
|
|
100
|
+
|
|
101
|
+
if (!record['__record__id__']) {
|
|
102
|
+
record['__record__id__'] = this.generateUniqueId();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!columns) return record;
|
|
106
|
+
|
|
107
|
+
for (const fieldName in record) {
|
|
108
|
+
const value = record[fieldName];
|
|
109
|
+
const fieldDescriptor = columns.get(fieldName);
|
|
110
|
+
|
|
111
|
+
if (typeof value === 'string' && fieldDescriptor) {
|
|
112
|
+
record[fieldName] = DataUnitInMemoryLoader.getConvertedValue(fieldDescriptor, value, this.recordDateFormat);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return record;
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
return newRecords;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
public get metadata(): UnitMetadata {
|
|
123
|
+
return this._metadata as UnitMetadata;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public set metadata(metadata: UnitMetadata) {
|
|
127
|
+
this._metadata = metadata;
|
|
128
|
+
|
|
129
|
+
if (this._dataUnit) {
|
|
130
|
+
this._dataUnit.metadata = metadata as UnitMetadata;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private generateUniqueId(): string {
|
|
135
|
+
return StringUtils.generateUUID();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
private inMemoryLoader(dataUnit: DataUnit, request: LoadDataRequest, recordsIn: Array<Record>): Promise<LoadDataResponse> {
|
|
139
|
+
return DataUnitLoaderUtils.buildLoadDataResponse(recordsIn, dataUnit, request);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private metadaLoader(): Promise<UnitMetadata> {
|
|
143
|
+
return Promise.resolve(this._metadata as UnitMetadata);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private saveLoader(_dataUnit: DataUnit, changes: Array<Change>): Promise<Array<SavedRecord>> {
|
|
147
|
+
return new Promise((resolve) => {
|
|
148
|
+
let dataUnitRecords: SavedRecord[] = [];
|
|
149
|
+
|
|
150
|
+
changes.forEach(change => {
|
|
151
|
+
let { record, updatingFields, operation } = change;
|
|
152
|
+
|
|
153
|
+
const changedRecord = { ...record, ...updatingFields };
|
|
154
|
+
|
|
155
|
+
if (operation === ChangeOperation.INSERT ||
|
|
156
|
+
operation === ChangeOperation.COPY) {
|
|
157
|
+
changedRecord['__old__id__'] = record['__record__id__'];
|
|
158
|
+
changedRecord['__record__id__'] = this.generateUniqueId();
|
|
159
|
+
|
|
160
|
+
this.records.push(changedRecord);
|
|
161
|
+
} else {
|
|
162
|
+
const recordIndex = this.records.findIndex(r => r['__record__id__'] == changedRecord['__record__id__']);
|
|
163
|
+
this.records[recordIndex] = changedRecord;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
dataUnitRecords.push(changedRecord);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
resolve(dataUnitRecords);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public removeLoader(_dataUnit: DataUnit, recordIds: Array<string>): Promise<Array<string>> {
|
|
174
|
+
return new Promise((resolve) => resolve(recordIds));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import DataUnit, { Record } from '../../DataUnit.js';
|
|
2
|
+
import { Filter, Sort } from '../../metadata/UnitMetadata.js';
|
|
3
|
+
import { LoadDataRequest } from '../../loading/LoadDataRequest.js';
|
|
4
|
+
import { PaginationInfo } from '../../loading/PaginationInfo.js';
|
|
5
|
+
import { IColumnFilter, ColumnFilterManager } from '../../../utils/ColumnFilterManager.js';
|
|
6
|
+
import SortingUtils from '../../../utils/SortingUtils.js';
|
|
7
|
+
|
|
8
|
+
export class DataUnitLoaderUtils {
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
public static applyFilter(records: Array<Record>, dataUnit: DataUnit, filters: Array<Filter>): Array<Record> {
|
|
12
|
+
const columnFilters: Map<string, IColumnFilter> = ColumnFilterManager.getColumnFilters(filters, "");
|
|
13
|
+
if (!columnFilters?.size) return records;
|
|
14
|
+
|
|
15
|
+
const filterFunction: ((record: Record) => boolean) | undefined = ColumnFilterManager.getFilterFunction(dataUnit, Array.from(columnFilters.values()));
|
|
16
|
+
return (filterFunction) ? records.filter(filterFunction) : records;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
public static buildLoadDataResponse(recordsIn: Array<Record>, dataUnit: DataUnit, request: LoadDataRequest) {
|
|
21
|
+
let records = recordsIn ? [...recordsIn] : [];
|
|
22
|
+
records = DataUnitLoaderUtils.applyFilter(records, dataUnit, request?.filters ?? []);
|
|
23
|
+
records = DataUnitLoaderUtils.applySorting(records, dataUnit, request?.sort ?? []);
|
|
24
|
+
|
|
25
|
+
const { offset, limit } = request;
|
|
26
|
+
|
|
27
|
+
const paginationInfoBuilderParams = {
|
|
28
|
+
recordsLength: records.length,
|
|
29
|
+
offset,
|
|
30
|
+
recordsPerPage: limit,
|
|
31
|
+
} as PaginationInfoBuilderParams;
|
|
32
|
+
|
|
33
|
+
return Promise.resolve({
|
|
34
|
+
records: DataUnitLoaderUtils.getPagesByRecords(records, offset, limit),
|
|
35
|
+
paginationInfo: dataUnit.pageSize ? DataUnitLoaderUtils.buildPaginationInfo(paginationInfoBuilderParams) : undefined,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
public static applySorting(records: Array<Record>, dataUnit: DataUnit, sorting: Array<Sort>): Array<Record> {
|
|
41
|
+
if (sorting == undefined || sorting.length == 0) {
|
|
42
|
+
return records;
|
|
43
|
+
}
|
|
44
|
+
const sortingFunction = SortingUtils.getSortingFunction(dataUnit, sorting);
|
|
45
|
+
if (sortingFunction == undefined) {
|
|
46
|
+
return records;
|
|
47
|
+
}
|
|
48
|
+
return records.sort(sortingFunction);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public static getPagesByRecords(records: Record[], offset = 0, limit = 0){
|
|
52
|
+
if(!records || !records.length || !this.hasValidLimitAndOffset(offset, limit)) return [];
|
|
53
|
+
if(limit === 0 && offset === 0) return records;
|
|
54
|
+
return records.slice(offset, offset + limit);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private static hasValidLimitAndOffset(offset: number, limit: number) {
|
|
58
|
+
return offset >= 0 && limit >= 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public static buildPaginationInfo({recordsLength = 0, offset = 0, recordsPerPage = 0}: PaginationInfoBuilderParams): PaginationInfo | undefined {
|
|
62
|
+
|
|
63
|
+
if (!recordsLength) {
|
|
64
|
+
return { currentPage: 0, firstRecord: 0, lastRecord: 0, total: 0, hasMore: false };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const lastRecordIndex = offset + recordsPerPage;
|
|
68
|
+
const lastRecord = lastRecordIndex ? Math.min(lastRecordIndex, recordsLength) : recordsLength;
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
currentPage: recordsPerPage === 0 ? 0 : Math.ceil(offset / recordsPerPage),
|
|
72
|
+
firstRecord: offset + 1,
|
|
73
|
+
lastRecord: lastRecord,
|
|
74
|
+
total: recordsLength,
|
|
75
|
+
hasMore: lastRecord < recordsLength,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
export interface PaginationInfoBuilderParams {
|
|
83
|
+
recordsLength: number,
|
|
84
|
+
offset: number,
|
|
85
|
+
recordsPerPage: number
|
|
86
|
+
}
|
|
@@ -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;
|
|
@@ -18,4 +18,14 @@ export interface PaginationInfo {
|
|
|
18
18
|
|
|
19
19
|
/** Se ainda existem mais registros */
|
|
20
20
|
hasMore: boolean;
|
|
21
|
+
|
|
22
|
+
/** Informa se o carregamento de dados em background está sendo executado
|
|
23
|
+
* Caso o dataunit não tenha carga paralela o valor será indefinido
|
|
24
|
+
*/
|
|
25
|
+
loadingInProgress?: boolean;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Informa se deve exibir diálogo para cancelar carregamento de registros
|
|
29
|
+
*/
|
|
30
|
+
askRowsLimit?: number;
|
|
21
31
|
}
|
|
@@ -119,6 +119,9 @@ export const toString = ( dataType: DataType|undefined, value: any): string => {
|
|
|
119
119
|
} else if (dataType === DataType.DATE) {
|
|
120
120
|
if (typeof value === "string") {
|
|
121
121
|
value = DateUtils.strToDate(value);
|
|
122
|
+
if (value == undefined) {
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
122
125
|
}
|
|
123
126
|
return DateUtils.formatRfc3339(value as Date);
|
|
124
127
|
} else {
|
|
@@ -141,6 +144,10 @@ export const toString = ( dataType: DataType|undefined, value: any): string => {
|
|
|
141
144
|
}
|
|
142
145
|
}
|
|
143
146
|
|
|
147
|
+
const isSearchField = (userInterface:UserInterface | undefined): boolean => {
|
|
148
|
+
return userInterface === UserInterface.SEARCH || userInterface === UserInterface.SEARCHPLUS;
|
|
149
|
+
}
|
|
150
|
+
|
|
144
151
|
export const compareValues = (valueA: any, valueB: any, descriptor: FieldDescriptor): number => {
|
|
145
152
|
|
|
146
153
|
if(useStringForComparison(descriptor)){
|
|
@@ -148,7 +155,7 @@ export const compareValues = (valueA: any, valueB: any, descriptor: FieldDescrip
|
|
|
148
155
|
}
|
|
149
156
|
|
|
150
157
|
const {dataType, userInterface} = descriptor;
|
|
151
|
-
if(userInterface
|
|
158
|
+
if(isSearchField(userInterface) || userInterface === UserInterface.OPTIONSELECTOR){
|
|
152
159
|
const optionValueA = valueA?.value || valueA;
|
|
153
160
|
const optionValueB = valueB?.value || valueB;
|
|
154
161
|
if(isNaN(optionValueA) || isNaN(optionValueB)){
|
|
@@ -1,38 +1,24 @@
|
|
|
1
|
-
import { Record } from
|
|
2
|
-
import { compareValues } from
|
|
3
|
-
import { FieldDescriptor } from
|
|
1
|
+
import { Record } from '../DataUnit.js';
|
|
2
|
+
import { compareValues } from '../metadata/DataType.js';
|
|
3
|
+
import { FieldDescriptor } from '../metadata/UnitMetadata.js';
|
|
4
4
|
|
|
5
|
-
export class FieldComparator{
|
|
5
|
+
export class FieldComparator {
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
public static compare(field: FieldDescriptor, recordA: Record, recordB: Record, asc: boolean = true): number {
|
|
8
|
+
const valueA = (asc ? recordA : recordB)[field.name];
|
|
9
|
+
const valueB = (asc ? recordB : recordA)[field.name];
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
return FieldComparator.compareValues(field, valueA, valueB);
|
|
12
|
+
}
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
public static compareValues(descriptor: FieldDescriptor, valueA: any, valueB: any): number{
|
|
17
|
-
const undefinedComparison = this.compareUndefined(valueA == undefined, valueB == undefined);
|
|
18
|
-
|
|
19
|
-
if(undefinedComparison != undefined){
|
|
20
|
-
return undefinedComparison;
|
|
21
|
-
}
|
|
14
|
+
public static compareValues(descriptor: FieldDescriptor, valueA: any, valueB: any): number {
|
|
15
|
+
const undefinedComparison = this.compareUndefined(valueA == undefined, valueB == undefined);
|
|
16
|
+
return (undefinedComparison != undefined) ? undefinedComparison : compareValues(valueA, valueB, descriptor);
|
|
17
|
+
}
|
|
22
18
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if(!isUndefinedA && !isUndefinedB){
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if(isUndefinedA && isUndefinedB){
|
|
33
|
-
return 0;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return isUndefinedA ? -1 : 1;
|
|
37
|
-
}
|
|
19
|
+
public static compareUndefined(isUndefinedA: boolean, isUndefinedB: boolean): number | undefined {
|
|
20
|
+
if (!isUndefinedA && !isUndefinedB) return;
|
|
21
|
+
if (isUndefinedA && isUndefinedB) return 0;
|
|
22
|
+
return isUndefinedA ? -1 : 1;
|
|
23
|
+
}
|
|
38
24
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
|
|
2
|
+
import { ChangeOperation } from "../../DataUnit.js";
|
|
2
3
|
import { LoadDataRequest } from "../../loading/LoadDataRequest.js";
|
|
3
4
|
import { PaginationInfo } from "../../loading/PaginationInfo.js";
|
|
4
5
|
import { Action } from "../action/DataUnitAction.js";
|
|
@@ -16,6 +17,9 @@ class LoadingControlReducerImpl implements ActionReducer {
|
|
|
16
17
|
return {...currentState, paginationInfo: action.payload?.paginationInfo};
|
|
17
18
|
case Action.PAGINATION_UPDATED:
|
|
18
19
|
return {...currentState, paginationInfo: action.payload};
|
|
20
|
+
case Action.DATA_SAVED:
|
|
21
|
+
return {...currentState, paginationInfo: updatePaginationInfo(stateManager, action.payload)};
|
|
22
|
+
|
|
19
23
|
}
|
|
20
24
|
return currentState;
|
|
21
25
|
}
|
|
@@ -56,7 +60,45 @@ export const hasPreviousPages = (stateManager: StateManager): boolean => {
|
|
|
56
60
|
return paginationInfo ? paginationInfo.currentPage > 0 : false;
|
|
57
61
|
}
|
|
58
62
|
|
|
63
|
+
const updatePaginationInfo = (stateManager: StateManager, payload: Payload): PaginationInfo =>{
|
|
64
|
+
const paginationInfo = getPaginationInfo(stateManager);
|
|
65
|
+
let { records, changes } = payload;
|
|
66
|
+
|
|
67
|
+
if(!records || !changes || !paginationInfo || !validateNewRecordOperation(changes)) return paginationInfo as PaginationInfo;
|
|
68
|
+
|
|
69
|
+
const { count, firstRecord, lastRecord, total } = paginationInfo;
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
...paginationInfo,
|
|
73
|
+
count: (count ?? 0) + records.length,
|
|
74
|
+
firstRecord: firstRecord === 0 && records.length > 0 ? 1 : firstRecord,
|
|
75
|
+
lastRecord: lastRecord + records.length,
|
|
76
|
+
total: (total ?? 0) + records.length
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const validateNewRecordOperation = (changes: Array<Change>): boolean => {
|
|
82
|
+
return changes.every(change => isNewRecordOperation(change._operation));
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const isNewRecordOperation = (operation: string): operation is ChangeOperation => {
|
|
86
|
+
return ["INSERT", "COPY"].includes(operation);
|
|
87
|
+
};
|
|
88
|
+
|
|
59
89
|
interface LoadingControlState{
|
|
60
90
|
lastRequest: LoadDataRequest;
|
|
61
91
|
paginationInfo: PaginationInfo;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
interface Change {
|
|
95
|
+
dataUnit: string;
|
|
96
|
+
record: Record<string, any>;
|
|
97
|
+
updatingFields: Record<string, any>;
|
|
98
|
+
_operation: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
interface Payload {
|
|
102
|
+
changes: Change[];
|
|
103
|
+
records: Record<string, any>[];
|
|
62
104
|
}
|
|
@@ -47,7 +47,7 @@ class RecordsReducerImpl implements ActionReducer {
|
|
|
47
47
|
newRecords.push(newRecord);
|
|
48
48
|
}
|
|
49
49
|
});
|
|
50
|
-
return
|
|
50
|
+
return Array.from(recordsMap.values()).concat(newRecords);
|
|
51
51
|
|
|
52
52
|
case Action.RECORD_LOADED:
|
|
53
53
|
action.payload.forEach((record: any) => {
|
|
@@ -31,7 +31,7 @@ class SelectionReducerImpl implements ActionReducer {
|
|
|
31
31
|
if (currentRecords && currentRecords.size > 0) {
|
|
32
32
|
let index: number;
|
|
33
33
|
if (!currentState || currentSelection.length === 0) {
|
|
34
|
-
index = action.type === Action.PREVIOUS_SELECTED ? 0 : Math.min(
|
|
34
|
+
index = action.type === Action.PREVIOUS_SELECTED ? 0 : Math.min(0, currentRecords.size);
|
|
35
35
|
} else {
|
|
36
36
|
index = getItemIndex(currentSelection[0], currentRecords) + (action.type === Action.PREVIOUS_SELECTED ? -1 : 1);
|
|
37
37
|
}
|
|
@@ -68,7 +68,7 @@ class SelectionReducerImpl implements ActionReducer {
|
|
|
68
68
|
if(currentState?.lastSelection){
|
|
69
69
|
return { currentSelection: currentState.lastSelection };
|
|
70
70
|
}
|
|
71
|
-
return { currentSelection: [] }
|
|
71
|
+
return { currentSelection: currentState?.currentSelection || [] }
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
return currentState;
|
|
@@ -94,8 +94,8 @@ export const getSelection = (stateManager: StateManager): Array<string> => {
|
|
|
94
94
|
export const getSelectionInfo = (stateManager: StateManager): SelectionInfo => {
|
|
95
95
|
|
|
96
96
|
const selection = getSelectionState(stateManager);
|
|
97
|
+
const currentRequest = getCurrentRequest(stateManager);
|
|
97
98
|
if(selection && selection.mode === SelectionMode.ALL_RECORDS){
|
|
98
|
-
const currentRequest = getCurrentRequest(stateManager);
|
|
99
99
|
const paginationInfo: PaginationInfo | undefined = getPaginationInfo(stateManager);
|
|
100
100
|
return new SelectionInfo(
|
|
101
101
|
[],
|
|
@@ -106,7 +106,7 @@ export const getSelectionInfo = (stateManager: StateManager): SelectionInfo => {
|
|
|
106
106
|
);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
return new SelectionInfo(getSelectionRecords(stateManager) || [], SelectionMode.SOME_RECORDS, undefined);
|
|
109
|
+
return new SelectionInfo(getSelectionRecords(stateManager) || [], SelectionMode.SOME_RECORDS, undefined, undefined, currentRequest?.sort);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
export const hasNext = (stateManager: StateManager): boolean => {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
|
|
2
|
+
import * as RecordsReducerModule from '../RecordsSlice';
|
|
3
|
+
import StateManager from '../../StateManager';
|
|
4
|
+
import { Record } from '../../../DataUnit';
|
|
5
|
+
import { Action } from '../../action/DataUnitAction';
|
|
6
|
+
|
|
7
|
+
jest.spyOn(RecordsReducerModule, "getRecords").mockImplementation(() => [
|
|
8
|
+
{
|
|
9
|
+
__record__id__: '0',
|
|
10
|
+
}, {
|
|
11
|
+
__record__id__: '1',
|
|
12
|
+
}]);
|
|
13
|
+
|
|
14
|
+
describe('RecordsSlice', () => {
|
|
15
|
+
let stateManager: StateManager;
|
|
16
|
+
let currentState: Array<Record>;
|
|
17
|
+
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
stateManager = new StateManager([RecordsReducerModule.RecordsReducer]);
|
|
20
|
+
currentState = [{
|
|
21
|
+
__record__id__: '0',
|
|
22
|
+
}, {
|
|
23
|
+
__record__id__: '1',
|
|
24
|
+
}]
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should return newlines at the end', () => {
|
|
28
|
+
let records = RecordsReducerModule.RecordsReducer.reduce(stateManager, currentState, {
|
|
29
|
+
type: Action.DATA_SAVED,
|
|
30
|
+
payload: {
|
|
31
|
+
records: [
|
|
32
|
+
{__record__id__: '0'},
|
|
33
|
+
{__record__id__: '2'},
|
|
34
|
+
{__record__id__: '1'},
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
expect(records).toEqual([
|
|
39
|
+
{__record__id__: '0'},
|
|
40
|
+
{__record__id__: '1'},
|
|
41
|
+
{__record__id__: '2'}
|
|
42
|
+
]);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
});
|