@sankhyalabs/core 6.0.1 → 6.1.0-dev.2
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/Change.md +11 -11
- package/.docs/classes/DataUnit.md +230 -122
- package/.docs/classes/FieldComparator.md +6 -2
- package/.docs/classes/KeyboardManager.md +99 -9
- package/.docs/classes/LockManager.md +4 -4
- package/.docs/classes/ObjectUtils.md +50 -2
- package/.docs/classes/SelectionInfo.md +12 -12
- package/.docs/classes/StringUtils.md +10 -10
- package/.docs/enumerations/Action.md +41 -31
- package/.docs/enumerations/ChangeOperation.md +4 -4
- package/.docs/enumerations/SelectionMode.md +2 -2
- package/.docs/enumerations/UserInterface.md +15 -5
- package/.docs/interfaces/DUActionInterceptor.md +1 -1
- package/.docs/interfaces/PageRequest.md +3 -3
- 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/type-aliases/DataUnitEventOptions.md +1 -1
- package/dist/dataunit/DataUnit.d.ts +19 -0
- package/dist/dataunit/DataUnit.js +43 -3
- package/dist/dataunit/DataUnit.js.map +1 -1
- package/dist/dataunit/formatting/PrettyFormatter.js +8 -3
- package/dist/dataunit/formatting/PrettyFormatter.js.map +1 -1
- package/dist/dataunit/metadata/DataType.d.ts +1 -1
- package/dist/dataunit/metadata/DataType.js +7 -4
- 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 -4
- package/dist/dataunit/sorting/FieldComparator.js.map +1 -1
- package/dist/dataunit/state/action/DataUnitAction.d.ts +1 -0
- package/dist/dataunit/state/action/DataUnitAction.js +1 -0
- package/dist/dataunit/state/action/DataUnitAction.js.map +1 -1
- 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.js.map +1 -1
- package/dist/utils/ObjectUtils.d.ts +14 -0
- package/dist/utils/ObjectUtils.js +20 -0
- package/dist/utils/ObjectUtils.js.map +1 -1
- package/dist/utils/SortingUtils.js +9 -1
- package/dist/utils/SortingUtils.js.map +1 -1
- package/dist/utils/StringUtils.js +12 -6
- package/dist/utils/StringUtils.js.map +1 -1
- package/package.json +1 -1
- package/reports/test-report.xml +669 -124
- package/src/dataunit/DataUnit.ts +51 -3
- package/src/dataunit/formatting/PrettyFormatter.ts +8 -5
- package/src/dataunit/metadata/DataType.ts +8 -4
- package/src/dataunit/metadata/UnitMetadata.ts +1 -0
- package/src/dataunit/sorting/FieldComparator.ts +4 -4
- package/src/dataunit/state/action/DataUnitAction.ts +2 -0
- package/src/utils/KeyboardManager/index.ts +57 -0
- package/src/utils/KeyboardManager/interface.ts +1 -0
- package/src/utils/LockManager.ts +0 -1
- package/src/utils/ObjectUtils.ts +21 -0
- package/src/utils/SortingUtils.ts +10 -1
- package/src/utils/StringUtils.ts +10 -6
- package/test/dataunit/formatting/PrettyFormatter.spec.ts +1 -1
- package/test/testCases/NumberUtilsTestCases.ts +190 -0
- package/test/testCases/StringUtilsTestCases.ts +435 -0
- package/test/testCases/TimeFormatterTestUtils.ts +43 -0
- package/test/util/NumberUtils.spec.ts +72 -150
- package/test/util/ObjectUtils.spec.ts +572 -0
- package/test/util/StringUtils.spec.ts +260 -36
- package/test/util/TimeFormatter.spec.ts +65 -18
- package/src/utils/test/objectUtils.spec.ts +0 -109
package/src/dataunit/DataUnit.ts
CHANGED
|
@@ -55,6 +55,8 @@ export default class DataUnit {
|
|
|
55
55
|
private _allowReleaseCallbacks: boolean;
|
|
56
56
|
private _waitingToReload: boolean = false;
|
|
57
57
|
private _cancelPagination: boolean = false;
|
|
58
|
+
private _isMultipleEdition: boolean = false;
|
|
59
|
+
private _fieldSourceValue: Map<string, string> = new Map<string, string>();
|
|
58
60
|
|
|
59
61
|
public metadataLoader?: (dataUnit: DataUnit) => Promise<UnitMetadata>;
|
|
60
62
|
public dataLoader?: (dataUnit: DataUnit, request: LoadDataRequest) => Promise<LoadDataResponse>;
|
|
@@ -183,6 +185,21 @@ export default class DataUnit {
|
|
|
183
185
|
this._cancelPagination = cancelPagination;
|
|
184
186
|
}
|
|
185
187
|
|
|
188
|
+
/**
|
|
189
|
+
* Informa se o DataUnit está no modo de edição de múltiplos registros.
|
|
190
|
+
*/
|
|
191
|
+
public get isMultipleEdition(): boolean {
|
|
192
|
+
return this._isMultipleEdition;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Define se o DataUnit está no modo de edição de múltiplos registros.
|
|
197
|
+
*/
|
|
198
|
+
public set isMultipleEdition(isMultipleEdition) {
|
|
199
|
+
this._isMultipleEdition = isMultipleEdition;
|
|
200
|
+
this.dispatchAction(Action.MULTIPLE_EDITION_CHANGED, {isMultipleEdition});
|
|
201
|
+
}
|
|
202
|
+
|
|
186
203
|
/**
|
|
187
204
|
*
|
|
188
205
|
* Obtém o nome de identificação do DataUnit (geralmente em formato de URI - Uniform Resource Identifier).
|
|
@@ -1031,7 +1048,7 @@ export default class DataUnit {
|
|
|
1031
1048
|
const typedValue = this.validateAndTypeValue(fieldName, newValue);
|
|
1032
1049
|
const currentValue = this.getFieldValue(fieldName);
|
|
1033
1050
|
|
|
1034
|
-
if(
|
|
1051
|
+
if(this.areEquivalentValues(newValue, currentValue, typedValue)) {
|
|
1035
1052
|
return Promise.resolve(false);
|
|
1036
1053
|
}
|
|
1037
1054
|
|
|
@@ -1046,7 +1063,7 @@ export default class DataUnit {
|
|
|
1046
1063
|
return promise;
|
|
1047
1064
|
}
|
|
1048
1065
|
|
|
1049
|
-
if (currentValue !== typedValue) {
|
|
1066
|
+
if (this.isMultipleEdition || currentValue !== typedValue) {
|
|
1050
1067
|
const promise = this.dispatchAction(Action.DATA_CHANGED, { [fieldName]: typedValue, records }, undefined, options);
|
|
1051
1068
|
this._savingLockers.push(promise);
|
|
1052
1069
|
return promise;
|
|
@@ -1055,6 +1072,12 @@ export default class DataUnit {
|
|
|
1055
1072
|
return Promise.resolve(false);
|
|
1056
1073
|
}
|
|
1057
1074
|
|
|
1075
|
+
private areEquivalentValues(newValue: any, currentValue: any, typedValue: any) {
|
|
1076
|
+
return !(newValue instanceof Promise)
|
|
1077
|
+
&& ObjectUtils.hasEquivalentProps(currentValue, typedValue)
|
|
1078
|
+
&& !this.isMultipleEdition;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1058
1081
|
/**
|
|
1059
1082
|
*
|
|
1060
1083
|
* Marca campos como inválidos.
|
|
@@ -1264,7 +1287,17 @@ export default class DataUnit {
|
|
|
1264
1287
|
**/
|
|
1265
1288
|
public getSelectionInfo(): SelectionInfo{
|
|
1266
1289
|
const selectionInfo: SelectionInfo = getSelectionInfo(this._stateManager);
|
|
1267
|
-
selectionInfo.getAllRecords = () =>
|
|
1290
|
+
selectionInfo.getAllRecords = () => {
|
|
1291
|
+
|
|
1292
|
+
let records = this.allRecordsLoader?.(this) ?? [];
|
|
1293
|
+
|
|
1294
|
+
if (selectionInfo.sort != undefined && selectionInfo.sort.length > 0) {
|
|
1295
|
+
const sortingFunction = SortingUtils.getSortingFunction(this, selectionInfo.sort)
|
|
1296
|
+
records = [...records].sort(sortingFunction);
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
return records;
|
|
1300
|
+
}
|
|
1268
1301
|
|
|
1269
1302
|
if (selectionInfo.sort != undefined && selectionInfo.sort.length > 0) {
|
|
1270
1303
|
const sortingFunction = SortingUtils.getSortingFunction(this, selectionInfo.sort)
|
|
@@ -1928,6 +1961,21 @@ export default class DataUnit {
|
|
|
1928
1961
|
this._allowReleaseCallbacks = allow;
|
|
1929
1962
|
}
|
|
1930
1963
|
|
|
1964
|
+
|
|
1965
|
+
/**
|
|
1966
|
+
* Adiciona um mapeamento de origem dos dados de um determinado campo
|
|
1967
|
+
*/
|
|
1968
|
+
public addSourceFieldValue(sourceFieldName:string, targetFieldName:string): void{
|
|
1969
|
+
this._fieldSourceValue.set(sourceFieldName, targetFieldName);
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
/**
|
|
1973
|
+
* Retornar o campo de origem dos dados caso exista mapeamento
|
|
1974
|
+
*/
|
|
1975
|
+
public getSourceFieldValue(targetFieldName:string): string | undefined{
|
|
1976
|
+
return this._fieldSourceValue.get(targetFieldName);
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1931
1979
|
private async processLoadingLockers(){
|
|
1932
1980
|
if(this._loadingLockers.length) {
|
|
1933
1981
|
await Promise.all(this._loadingLockers);
|
|
@@ -7,7 +7,7 @@ import { FieldDescriptor, UserInterface } from '../metadata/UnitMetadata.js';
|
|
|
7
7
|
|
|
8
8
|
export const getFormattedValue = (value: any, descriptor?: FieldDescriptor) => {
|
|
9
9
|
if(descriptor?.userInterface === UserInterface.FILE){
|
|
10
|
-
return
|
|
10
|
+
return getFileFormat(value);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
if(descriptor?.dataType === DataType.OBJECT){
|
|
@@ -77,6 +77,10 @@ const getSearchFormat = (value: any, descriptor: FieldDescriptor) => {
|
|
|
77
77
|
return label ? `${codeValue} - ${label}` : codeValue;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
if(descriptor.userInterface === UserInterface.SEARCHPLUS){
|
|
81
|
+
return codeValue;
|
|
82
|
+
}
|
|
83
|
+
|
|
80
84
|
return label ? label : codeValue;
|
|
81
85
|
}
|
|
82
86
|
|
|
@@ -127,10 +131,9 @@ const getMask = (value: string, descriptor: FieldDescriptor | undefined): string
|
|
|
127
131
|
return mask;
|
|
128
132
|
}
|
|
129
133
|
|
|
130
|
-
const
|
|
131
|
-
if (
|
|
132
|
-
|
|
134
|
+
const getFileFormat = (value: any) => {
|
|
135
|
+
if (value == undefined) return '';
|
|
136
|
+
if (!value || !Array.isArray(value)) return value;
|
|
133
137
|
if (value.length === 1) return value[0].name;
|
|
134
|
-
|
|
135
138
|
return `${value.length} arquivos`;
|
|
136
139
|
}
|
|
@@ -144,16 +144,20 @@ export const toString = ( dataType: DataType|undefined, value: any): string => {
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
const isSearchField = (userInterface:UserInterface | undefined): boolean => {
|
|
148
|
+
return userInterface === UserInterface.SEARCH || userInterface === UserInterface.SEARCHPLUS;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export const compareValues = (valueA: any, valueB: any, descriptor: FieldDescriptor, onlyLabel:boolean = false): number => {
|
|
148
152
|
|
|
149
153
|
if(useStringForComparison(descriptor)){
|
|
150
154
|
return (getFormattedValue(valueA, descriptor) as string).localeCompare(getFormattedValue(valueB, descriptor));
|
|
151
155
|
}
|
|
152
156
|
|
|
153
157
|
const {dataType, userInterface} = descriptor;
|
|
154
|
-
if(userInterface
|
|
155
|
-
const optionValueA = valueA?.value || valueA;
|
|
156
|
-
const optionValueB = valueB?.value || valueB;
|
|
158
|
+
if(isSearchField(userInterface) || userInterface === UserInterface.OPTIONSELECTOR){
|
|
159
|
+
const optionValueA = (onlyLabel ? valueA?.label : valueA?.value) || valueA;
|
|
160
|
+
const optionValueB = (onlyLabel ? valueB?.label : valueB?.value) || valueB;
|
|
157
161
|
if(isNaN(optionValueA) || isNaN(optionValueB)){
|
|
158
162
|
return (optionValueA as string).localeCompare(optionValueB);
|
|
159
163
|
}
|
|
@@ -4,16 +4,16 @@ import { FieldDescriptor } from '../metadata/UnitMetadata.js';
|
|
|
4
4
|
|
|
5
5
|
export class FieldComparator {
|
|
6
6
|
|
|
7
|
-
public static compare(field: FieldDescriptor, recordA: Record, recordB: Record, asc: boolean = true): number {
|
|
7
|
+
public static compare(field: FieldDescriptor, recordA: Record, recordB: Record, asc: boolean = true, onlyLabel: boolean = false): number {
|
|
8
8
|
const valueA = (asc ? recordA : recordB)[field.name];
|
|
9
9
|
const valueB = (asc ? recordB : recordA)[field.name];
|
|
10
10
|
|
|
11
|
-
return FieldComparator.compareValues(field, valueA, valueB);
|
|
11
|
+
return FieldComparator.compareValues(field, valueA, valueB, onlyLabel);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
public static compareValues(descriptor: FieldDescriptor, valueA: any, valueB: any): number {
|
|
14
|
+
public static compareValues(descriptor: FieldDescriptor, valueA: any, valueB: any, onlyLabel: boolean = false): number {
|
|
15
15
|
const undefinedComparison = this.compareUndefined(valueA == undefined, valueB == undefined);
|
|
16
|
-
return (undefinedComparison != undefined) ? undefinedComparison : compareValues(valueA, valueB, descriptor);
|
|
16
|
+
return (undefinedComparison != undefined) ? undefinedComparison : compareValues(valueA, valueB, descriptor, onlyLabel);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
public static compareUndefined(isUndefinedA: boolean, isUndefinedB: boolean): number | undefined {
|
|
@@ -9,6 +9,7 @@ import { keyCodeEventValues } from "./keyCodes/index.js";
|
|
|
9
9
|
*/
|
|
10
10
|
export class KeyboardManager {
|
|
11
11
|
private _options: IKeyboardOptions;
|
|
12
|
+
private _shadowRoots: ShadowRoot [] = [];
|
|
12
13
|
private _mappedElements: IKeyboardMappedKeysElements = {};
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -22,10 +23,48 @@ export class KeyboardManager {
|
|
|
22
23
|
propagate: false,
|
|
23
24
|
element: document.body,
|
|
24
25
|
debounceTime: 0,
|
|
26
|
+
enableShadowDom: false,
|
|
25
27
|
...options
|
|
26
28
|
}
|
|
29
|
+
|
|
30
|
+
if(this._options.enableShadowDom) {
|
|
31
|
+
this._shadowRoots = this.findAllNestedShadowRoots(this._options.element);
|
|
32
|
+
}
|
|
27
33
|
}
|
|
28
34
|
|
|
35
|
+
private findAllNestedShadowRoots(element: HTMLElement | Element | ChildNode | Document , results: ShadowRoot [] = []): ShadowRoot [] {
|
|
36
|
+
if (!element) {
|
|
37
|
+
return results;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const shadowRoot = (element as HTMLElement)?.shadowRoot;
|
|
41
|
+
if (shadowRoot) {
|
|
42
|
+
results.push(shadowRoot);
|
|
43
|
+
|
|
44
|
+
shadowRoot.querySelectorAll("*").forEach((child) => {
|
|
45
|
+
this.findAllNestedShadowRoots(child, results);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
element.childNodes.forEach((child) => {
|
|
50
|
+
this.findAllNestedShadowRoots(child, results);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return results;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private addEventListenerToNestedShadowRoots(event: 'keydown' | 'keyup', callback: VoidFunction) {
|
|
57
|
+
this._shadowRoots.forEach((shadowRoot) => {
|
|
58
|
+
shadowRoot.addEventListener(event, callback);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private removeEventListenerToNestedShadowRoots(event: 'keydown' | 'keyup', callback: VoidFunction) {
|
|
63
|
+
this._shadowRoots.forEach((shadowRoot) => {
|
|
64
|
+
shadowRoot.removeEventListener(event, callback);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
29
68
|
/**
|
|
30
69
|
* Associa um evento de teclado com uma função
|
|
31
70
|
*
|
|
@@ -61,9 +100,23 @@ export class KeyboardManager {
|
|
|
61
100
|
|
|
62
101
|
bindOptions.element.addEventListener(bindOptions.type, debounceFunction);
|
|
63
102
|
|
|
103
|
+
if(bindOptions.enableShadowDom) {
|
|
104
|
+
this.addEventListenerToNestedShadowRoots(bindOptions.type, debounceFunction);
|
|
105
|
+
}
|
|
106
|
+
|
|
64
107
|
return this;
|
|
65
108
|
}
|
|
66
109
|
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Remove todos os eventos de teclado ou de uma lista informada
|
|
113
|
+
*
|
|
114
|
+
*/
|
|
115
|
+
public unbindAllShortcutKeys(listShortcutKeys?: string[]): void {
|
|
116
|
+
const mappedKeys = [...Object.keys(listShortcutKeys || this._mappedElements)];
|
|
117
|
+
mappedKeys?.forEach(keyMap => this.unbind(keyMap));
|
|
118
|
+
}
|
|
119
|
+
|
|
67
120
|
/**
|
|
68
121
|
* Remove um evento de teclado
|
|
69
122
|
*
|
|
@@ -86,6 +139,10 @@ export class KeyboardManager {
|
|
|
86
139
|
|
|
87
140
|
element.removeEventListener(type, callback);
|
|
88
141
|
|
|
142
|
+
if(unbindElement.options.enableShadowDom) {
|
|
143
|
+
this.removeEventListenerToNestedShadowRoots(type, callback);
|
|
144
|
+
}
|
|
145
|
+
|
|
89
146
|
return this;
|
|
90
147
|
}
|
|
91
148
|
|
package/src/utils/LockManager.ts
CHANGED
|
@@ -94,7 +94,6 @@ export class LockManager {
|
|
|
94
94
|
const ctxId = LockManager.findExistingCtxId(startElement) ?? LockManager.buildContextID();
|
|
95
95
|
let currentElement: HTMLElement | null = startElement;
|
|
96
96
|
LockManager.traverseAndAddAttr(currentElement, ctxId);
|
|
97
|
-
|
|
98
97
|
return ctxId;
|
|
99
98
|
} catch (err) {
|
|
100
99
|
console.warn(`Erro ao registrar locks para o elemento: ${startElement?.tagName}`, err);
|
package/src/utils/ObjectUtils.ts
CHANGED
|
@@ -120,6 +120,17 @@ export default class ObjectUtils{
|
|
|
120
120
|
return Object.keys(obj).length === 0 && obj.constructor === Object;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Verifica se o objeto está vazio (sem atributos) e retorna true caso seja undefined ou null.
|
|
125
|
+
*
|
|
126
|
+
* @param obj - Objeto a ser verificado.
|
|
127
|
+
* @returns - True caso o objeto esteja vazio.
|
|
128
|
+
*/
|
|
129
|
+
public static isEmptySafetyCheck(obj: object): boolean{
|
|
130
|
+
if(obj === null || obj === undefined) return true;
|
|
131
|
+
return Object.keys(obj).length === 0 && obj.constructor === Object;
|
|
132
|
+
}
|
|
133
|
+
|
|
123
134
|
/**
|
|
124
135
|
* Verifica se o objeto NÃO está vazio (sem atributos).
|
|
125
136
|
*
|
|
@@ -130,6 +141,16 @@ export default class ObjectUtils{
|
|
|
130
141
|
return !this.isEmpty(obj);
|
|
131
142
|
}
|
|
132
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Verifica se o objeto NÃO está vazio (sem atributos) e retorna false caso objeto seja null ou undefined.
|
|
146
|
+
*
|
|
147
|
+
* @param obj - Objeto a ser verificado.
|
|
148
|
+
* @returns - True caso o objeto NÃO esteja vazio
|
|
149
|
+
*/
|
|
150
|
+
public static isNotEmptySafetyCheck(obj: object): boolean{
|
|
151
|
+
return !this.isEmptySafetyCheck(obj);
|
|
152
|
+
}
|
|
153
|
+
|
|
133
154
|
/**
|
|
134
155
|
* Busca a propriedade de um objeto baseado em seu caminho.
|
|
135
156
|
*
|
|
@@ -17,7 +17,16 @@ export default class SortingUtils {
|
|
|
17
17
|
return (recordA, recordB) => {
|
|
18
18
|
for (const sort of sorting) {
|
|
19
19
|
if (sort.field){
|
|
20
|
-
|
|
20
|
+
let field = dataUnit.getField(sort.field) as FieldDescriptor;
|
|
21
|
+
let onlyLabel = false;
|
|
22
|
+
if(!field){
|
|
23
|
+
const sourceFieldName = dataUnit.getSourceFieldValue(sort.field) ?? "";
|
|
24
|
+
|
|
25
|
+
field = dataUnit.getField(sourceFieldName) as FieldDescriptor;
|
|
26
|
+
onlyLabel = true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const result = FieldComparator.compare(field, recordA, recordB, sort.mode === SortMode.ASC, onlyLabel);
|
|
21
30
|
if (result != 0) {
|
|
22
31
|
return result;
|
|
23
32
|
}
|
package/src/utils/StringUtils.ts
CHANGED
|
@@ -289,7 +289,7 @@ export class StringUtils {
|
|
|
289
289
|
* @returns String convertida em PascalCase.
|
|
290
290
|
*/
|
|
291
291
|
static toPascalCase(value: string): string{
|
|
292
|
-
return value
|
|
292
|
+
return (value || "")
|
|
293
293
|
.toLowerCase()
|
|
294
294
|
.replace(/(?:^|\s)\w/g, (match: string) => match.toUpperCase())
|
|
295
295
|
.replace(/[\s-_]/g,'');
|
|
@@ -301,7 +301,7 @@ export class StringUtils {
|
|
|
301
301
|
* @returns String convertida em snake_case.
|
|
302
302
|
*/
|
|
303
303
|
static toSnakeCase(value: string): string{
|
|
304
|
-
return value
|
|
304
|
+
return (value || "")
|
|
305
305
|
.toLowerCase()
|
|
306
306
|
.replace(/[A-Z]/g, (match: string) => `_${match.toLowerCase()}`)
|
|
307
307
|
.replace(/[\s-]/g, '_')
|
|
@@ -314,7 +314,7 @@ export class StringUtils {
|
|
|
314
314
|
* @returns String convertida em KebabCase.
|
|
315
315
|
*/
|
|
316
316
|
static toKebabCase(value: string): string{
|
|
317
|
-
return value.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/[\s_]+/g, '-').toLowerCase();
|
|
317
|
+
return (value || "").replace(/([a-z])([A-Z])/g, '$1-$2').replace(/[\s_]+/g, '-').toLowerCase();
|
|
318
318
|
}
|
|
319
319
|
|
|
320
320
|
/**
|
|
@@ -336,13 +336,13 @@ export class StringUtils {
|
|
|
336
336
|
const units = ["B", "KB", "MB", "GB"];
|
|
337
337
|
|
|
338
338
|
if (bytes < 1024) {
|
|
339
|
-
return `${bytes
|
|
339
|
+
return `${bytes?.toString()}B`;
|
|
340
340
|
}
|
|
341
341
|
|
|
342
342
|
const base = Math.log(bytes) / Math.log(1024);
|
|
343
343
|
const offSet = Math.floor(base);
|
|
344
344
|
if (offSet >= units.length) {
|
|
345
|
-
return `${bytes
|
|
345
|
+
return `${bytes?.toString()}B`;
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
const value = this.prettyPrecision(Math.pow(1024, base - offSet).toFixed(2).toString());
|
|
@@ -389,6 +389,8 @@ export class StringUtils {
|
|
|
389
389
|
* @return {boolean} Se a string pode ser convertida
|
|
390
390
|
*/
|
|
391
391
|
static isCaseable(original: string): boolean {
|
|
392
|
+
if(original == null) return false;
|
|
393
|
+
|
|
392
394
|
const uppercase = original.toUpperCase()
|
|
393
395
|
const lowercase = original.toLowerCase()
|
|
394
396
|
|
|
@@ -402,6 +404,7 @@ export class StringUtils {
|
|
|
402
404
|
* @return {boolean} Se a string é minúscula
|
|
403
405
|
*/
|
|
404
406
|
static isLowerCase(original: string): boolean {
|
|
407
|
+
if(original == null) return false;
|
|
405
408
|
const uppercase = original.toUpperCase()
|
|
406
409
|
|
|
407
410
|
return this.isCaseable(original) && uppercase !== original
|
|
@@ -414,6 +417,7 @@ export class StringUtils {
|
|
|
414
417
|
* @return {string} A string invertida
|
|
415
418
|
*/
|
|
416
419
|
static getOppositeCase(original: string): string {
|
|
420
|
+
if(original == null) return "";
|
|
417
421
|
return this.isLowerCase(original) ? original.toUpperCase() : original.toLowerCase()
|
|
418
422
|
}
|
|
419
423
|
|
|
@@ -487,7 +491,7 @@ export class StringUtils {
|
|
|
487
491
|
}
|
|
488
492
|
|
|
489
493
|
public static highlightValue(argument: String, matchFields: any, value: string, fieldMD: any, forceMatch: boolean) {
|
|
490
|
-
const startHighlightTag = "<span class='card-item__highlight'>";
|
|
494
|
+
const startHighlightTag = "<span class='card-item__highlight'>"; //FIXME: valor hardcoded, não podemos reaproveitar para outros cenários, dessa forma.
|
|
491
495
|
const endHighlightTag = "</span>";
|
|
492
496
|
let valueAux = JSUtils.replaceHtmlEntities(value);
|
|
493
497
|
|
|
@@ -18,7 +18,7 @@ describe('getFormattedValue', () => {
|
|
|
18
18
|
it('should return empty string when value is not an array', () => {
|
|
19
19
|
const value = 'not an array';
|
|
20
20
|
const descriptor = getFileFieldDescriptor();
|
|
21
|
-
expect(getFormattedValue(value, descriptor)).toBe(
|
|
21
|
+
expect(getFormattedValue(value, descriptor)).toBe(value);
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
it('should return empty string when value is an empty array', () => {
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
export const stringToNumberCases = [
|
|
2
|
+
{ valueInput: '100', valueOutput: 100 },
|
|
3
|
+
{ valueInput: '100,12', valueOutput: 100.12 },
|
|
4
|
+
{ valueInput: '11500,12', valueOutput: 11500.12 },
|
|
5
|
+
{ valueInput: '11500', valueOutput: 11500 },
|
|
6
|
+
{ valueInput: '1.000', valueOutput: 1 },
|
|
7
|
+
{ valueInput: '11.500,003', valueOutput: 11500.003 },
|
|
8
|
+
{ valueInput: '-100', valueOutput: -100 },
|
|
9
|
+
{ valueInput: '-100,12', valueOutput: -100.12 },
|
|
10
|
+
{ valueInput: '-11500,1', valueOutput: -11500.1 },
|
|
11
|
+
{ valueInput: '-11500', valueOutput: -11500 },
|
|
12
|
+
{ valueInput: '-11.500,003', valueOutput: -11500.003 },
|
|
13
|
+
{ valueInput: 'R$100', valueOutput: 100 },
|
|
14
|
+
{ valueInput: 'R$100,12', valueOutput: 100.12 },
|
|
15
|
+
{ valueInput: 'R$11500,12', valueOutput: 11500.12 },
|
|
16
|
+
{ valueInput: 'R$11500', valueOutput: 11500 },
|
|
17
|
+
{ valueInput: 'R$11.500,003', valueOutput: 11500.003 },
|
|
18
|
+
{ valueInput: '-R$100', valueOutput: -100 },
|
|
19
|
+
{ valueInput: '-R$100,12', valueOutput: -100.12 },
|
|
20
|
+
{ valueInput: '-R$11500,12', valueOutput: -11500.12 },
|
|
21
|
+
{ valueInput: '-R$11500', valueOutput: -11500 },
|
|
22
|
+
{ valueInput: '-R$11.500,003', valueOutput: -11500.003 },
|
|
23
|
+
{ valueInput: '', valueOutput: NaN },
|
|
24
|
+
{ valueInput: 'OrdinaryString', valueOutput: NaN },
|
|
25
|
+
{ valueInput: '100.167.80', valueOutput: NaN },
|
|
26
|
+
{ valueInput: 'uahsuhas,auhsuhasu', valueOutput: NaN },
|
|
27
|
+
{ valueInput: '100,100,100', valueOutput: NaN },
|
|
28
|
+
{ valueInput: 'OrdinaryString,.OrdinaryString', valueOutput: NaN },
|
|
29
|
+
{ valueInput: 'OrdinaryString.,OrdinaryString', valueOutput: NaN },
|
|
30
|
+
{ valueInput: '.121212', valueOutput: 0.121212 },
|
|
31
|
+
{ valueInput: ',121212', valueOutput: 0.121212 },
|
|
32
|
+
{ valueInput: '1,232,333.345', valueOutput: NaN },
|
|
33
|
+
{ valueInput: '1232333,345', valueOutput: 1232333.345 },
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
export const formatCases = [
|
|
37
|
+
|
|
38
|
+
{ precision: 4, prettyprecision: 2, strvalue: '1.200.999,3333', strvalueOutPut: '1.200.999,3333' },
|
|
39
|
+
{ precision: 2, prettyprecision: 1, strvalue: '1.000', strvalueOutPut: '1,0' },
|
|
40
|
+
{ precision: 2, prettyprecision: 1, strvalue: '1200999,99', strvalueOutPut: '1.200.999,99' },
|
|
41
|
+
{ precision: 4, prettyprecision: 2, strvalue: '1,232,333.345', strvalueOutPut: 'NaN' },
|
|
42
|
+
{ precision: 2, prettyprecision: 1, strvalue: '1,23', strvalueOutPut: '1,23' },
|
|
43
|
+
{ precision: 4, prettyprecision: 2, strvalue: '1.200.999', strvalueOutPut: 'NaN' },
|
|
44
|
+
{ precision: 4, prettyprecision: 0, strvalue: '1200.00001', strvalueOutPut: '1.200' },
|
|
45
|
+
{ precision: 4, prettyprecision: 0, strvalue: 'String', strvalueOutPut: 'NaN' },
|
|
46
|
+
{ precision: 4, prettyprecision: 0, strvalue: '', strvalueOutPut: 'NaN' },
|
|
47
|
+
|
|
48
|
+
{ precision: 4, prettyprecision: undefined, strvalue: '1.200.999,3333', strvalueOutPut: '1.200.999,3333' },
|
|
49
|
+
{ precision: 2, prettyprecision: undefined, strvalue: '1.000', strvalueOutPut: '1,00' },
|
|
50
|
+
{ precision: 2, prettyprecision: undefined, strvalue: '1200999,99', strvalueOutPut: '1.200.999,99' },
|
|
51
|
+
{ precision: 4, prettyprecision: undefined, strvalue: '1,232,333.345', strvalueOutPut: 'NaN' },
|
|
52
|
+
{ precision: 2, prettyprecision: undefined, strvalue: '1,23', strvalueOutPut: '1,23' },
|
|
53
|
+
{ precision: 4, prettyprecision: undefined, strvalue: '1.200.999', strvalueOutPut: 'NaN' },
|
|
54
|
+
{ precision: 4, prettyprecision: undefined, strvalue: 'NaN', strvalueOutPut: 'NaN' },
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
{ precision: 1, prettyprecision: -1, strvalue: '111,199', strvalueOutPut: '111,2' },
|
|
58
|
+
{ precision: 1, prettyprecision: -1, strvalue: '111,1000', strvalueOutPut: '111,1' },
|
|
59
|
+
{ precision: 1, prettyprecision: 1.3, strvalue: '111,100', strvalueOutPut: '111,1' },
|
|
60
|
+
{ precision: -1, prettyprecision: 1, strvalue: '111,1009', strvalueOutPut: '111,1009' },
|
|
61
|
+
{ precision: -1, prettyprecision: 1, strvalue: '111,1000', strvalueOutPut: '111,1' },
|
|
62
|
+
{ precision: 1.2, prettyprecision: 1, strvalue: '111,1009', strvalueOutPut: '111,1009' },
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
{ precision: 2, prettyprecision: -1, strvalue: '111,199', strvalueOutPut: '111,20' },
|
|
66
|
+
{ precision: 2, prettyprecision: -1, strvalue: '111,1000', strvalueOutPut: '111,10' },
|
|
67
|
+
{ precision: -2, prettyprecision: 1, strvalue: '111,1009', strvalueOutPut: '111,1009' },
|
|
68
|
+
{ precision: -2, prettyprecision: 1, strvalue: '111,1000', strvalueOutPut: '111,1' },
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
export const changeFormatCases = [
|
|
74
|
+
{ inputValue: '1.200.999', outPutValue: '1,200,999' },
|
|
75
|
+
{ inputValue: '1.000,99', outPutValue: '1,000.99' },
|
|
76
|
+
{ inputValue: '1200999,99', outPutValue: '1200999.99' },
|
|
77
|
+
{ inputValue: 'R$ 1,232,333.345', outPutValue: 'R$ 1.232.333,345' },
|
|
78
|
+
{ inputValue: 'R$ 1.232.333,345', outPutValue: 'R$ 1,232,333.345' },
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
export const keepOnlyDecimalSeparatorCases = [
|
|
82
|
+
|
|
83
|
+
{ formatnumber: 'pt-BR', inputValue: '1.200.999', outPutValue: '1200999' },
|
|
84
|
+
{ formatnumber: 'pt-BR', inputValue: '1000,99', outPutValue: '1000,99' },
|
|
85
|
+
{ formatnumber: 'pt-BR', inputValue: '1200999,99', outPutValue: '1200999,99' },
|
|
86
|
+
{ formatnumber: 'pt-BR', inputValue: 'R$ 1.232.333,345', outPutValue: 'R$ 1232333,345' },
|
|
87
|
+
|
|
88
|
+
{ formatnumber: 'en-US', inputValue: '1,200,999', outPutValue: '1200999' },
|
|
89
|
+
{ formatnumber: 'en-US', inputValue: '1,000.99', outPutValue: '1000.99' },
|
|
90
|
+
{ formatnumber: 'en-US', inputValue: '1200999.99', outPutValue: '1200999.99' },
|
|
91
|
+
{ formatnumber: 'en-US', inputValue: 'EUR 1,232,333.345', outPutValue: 'EUR 1232333.345' },
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
export const roundTestCases = [
|
|
97
|
+
{ decimal: undefined, inputValue: 100.12, outPutValue: 100.12 },
|
|
98
|
+
{ decimal: 1, inputValue: 100.12, outPutValue: 100.1 },
|
|
99
|
+
{ decimal: 2, inputValue: 100.12, outPutValue: 100.12 },
|
|
100
|
+
{ decimal: 3, inputValue: 100.12, outPutValue: 100.12 },
|
|
101
|
+
{ decimal: 1, inputValue: 100.15, outPutValue: 100.2 },
|
|
102
|
+
{ decimal: 2, inputValue: 100.15, outPutValue: 100.15 },
|
|
103
|
+
{ decimal: 3, inputValue: 100.15, outPutValue: 100.15 },
|
|
104
|
+
{ decimal: 1, inputValue: 100.16, outPutValue: 100.2 },
|
|
105
|
+
{ decimal: 2, inputValue: 100.16, outPutValue: 100.16 },
|
|
106
|
+
{ decimal: 3, inputValue: 100.16, outPutValue: 100.16 },
|
|
107
|
+
{ decimal: 12, inputValue: 2118000000000.0002, outPutValue: 2118000000000.0002 },
|
|
108
|
+
{ decimal: 5, inputValue: 123.45, outPutValue: 123.45 },
|
|
109
|
+
{ decimal: 0, inputValue: 123.45, outPutValue: 123 },
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
export const safeFormatCases = [
|
|
113
|
+
|
|
114
|
+
{ precision: 4, prettyprecision: 2, strvalue: '1.200.999,3333', strvalueOutPut: '1.200.999,3333' },
|
|
115
|
+
{ precision: 2, prettyprecision: 1, strvalue: '1.000', strvalueOutPut: '1,0' },
|
|
116
|
+
{ precision: 2, prettyprecision: 1, strvalue: '1200999,99', strvalueOutPut: '1.200.999,99' },
|
|
117
|
+
{ precision: 4, prettyprecision: 2, strvalue: '1,232,333.345', strvalueOutPut: '0,00' },
|
|
118
|
+
{ precision: 2, prettyprecision: 1, strvalue: '1,23', strvalueOutPut: '1,23' },
|
|
119
|
+
{ precision: 4, prettyprecision: 2, strvalue: '1.200.999', strvalueOutPut: '0,00' },
|
|
120
|
+
{ precision: 4, prettyprecision: 0, strvalue: '1200.00001', strvalueOutPut: '1.200' },
|
|
121
|
+
{ precision: 4, prettyprecision: 0, strvalue: 'String', strvalueOutPut: '0,00' },
|
|
122
|
+
{ precision: 4, prettyprecision: 0, strvalue: '', strvalueOutPut: '0,00' },
|
|
123
|
+
|
|
124
|
+
{ precision: 4, prettyprecision: undefined, strvalue: '1.200.999,3333', strvalueOutPut: '1.200.999,3333' },
|
|
125
|
+
{ precision: 2, prettyprecision: undefined, strvalue: '1.000', strvalueOutPut: '1,00' },
|
|
126
|
+
{ precision: 2, prettyprecision: undefined, strvalue: '1200999,99', strvalueOutPut: '1.200.999,99' },
|
|
127
|
+
{ precision: 4, prettyprecision: undefined, strvalue: '1,232,333.345', strvalueOutPut: '0,00' },
|
|
128
|
+
{ precision: 2, prettyprecision: undefined, strvalue: '1,23', strvalueOutPut: '1,23' },
|
|
129
|
+
{ precision: 4, prettyprecision: undefined, strvalue: '1.200.999', strvalueOutPut: '0,00' },
|
|
130
|
+
{ precision: 4, prettyprecision: undefined, strvalue: 'NaN', strvalueOutPut: '0,00' },
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
{ precision: 1, prettyprecision: -1, strvalue: '111,199', strvalueOutPut: '111,2' },
|
|
134
|
+
{ precision: 1, prettyprecision: -1, strvalue: '111,1000', strvalueOutPut: '111,1' },
|
|
135
|
+
{ precision: 1, prettyprecision: 1.3, strvalue: '111,100', strvalueOutPut: '111,1' },
|
|
136
|
+
{ precision: -1, prettyprecision: 1, strvalue: '111,1009', strvalueOutPut: '111,1009' },
|
|
137
|
+
{ precision: -1, prettyprecision: 1, strvalue: '111,1000', strvalueOutPut: '111,1' },
|
|
138
|
+
{ precision: 1.2, prettyprecision: 1, strvalue: '111,1009', strvalueOutPut: '111,1009' },
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
{ precision: 2, prettyprecision: -1, strvalue: '111,199', strvalueOutPut: '111,20' },
|
|
142
|
+
{ precision: 2, prettyprecision: -1, strvalue: '111,1000', strvalueOutPut: '111,10' },
|
|
143
|
+
{ precision: -2, prettyprecision: 1, strvalue: '111,1009', strvalueOutPut: '111,1009' },
|
|
144
|
+
{ precision: -2, prettyprecision: 1, strvalue: '111,1000', strvalueOutPut: '111,1' },
|
|
145
|
+
];
|
|
146
|
+
|
|
147
|
+
export const getValueOrDefaultCases = [
|
|
148
|
+
{ value: undefined, defaultValue: 0, expected: 0 },
|
|
149
|
+
{ value: null, defaultValue: 10, expected: 10 },
|
|
150
|
+
{ value: '', defaultValue: 5, expected: 5 },
|
|
151
|
+
{ value: ' ', defaultValue: 7, expected: 7 },
|
|
152
|
+
{ value: '123', defaultValue: 0, expected: 123 },
|
|
153
|
+
{ value: '-123', defaultValue: 0, expected: -123 },
|
|
154
|
+
{ value: '123.45', defaultValue: 0, expected: 123.45 },
|
|
155
|
+
{ value: 'abc', defaultValue: 8, expected: 8 },
|
|
156
|
+
{ value: 'NaN', defaultValue: 15, expected: 15 },
|
|
157
|
+
{ value: '0', defaultValue: 5, expected: 0 },
|
|
158
|
+
{ value: 42, defaultValue: 0, expected: 42 },
|
|
159
|
+
{ value: -42, defaultValue: 0, expected: -42 },
|
|
160
|
+
{ value: 0, defaultValue: 100, expected: 0 },
|
|
161
|
+
{ value: NaN, defaultValue: 50, expected: 50 },
|
|
162
|
+
];
|
|
163
|
+
|
|
164
|
+
export const getValueOrZeroCases = [
|
|
165
|
+
{ value: undefined, expected: 0 },
|
|
166
|
+
{ value: null, expected: 0 },
|
|
167
|
+
{ value: '', expected: 0 },
|
|
168
|
+
{ value: ' ', expected: 0 },
|
|
169
|
+
{ value: '123', expected: 123 },
|
|
170
|
+
{ value: '-123', expected: -123 },
|
|
171
|
+
{ value: '123.45', expected: 123.45 },
|
|
172
|
+
{ value: 'abc', expected: 0 },
|
|
173
|
+
{ value: 'NaN', expected: 0 },
|
|
174
|
+
{ value: '0', expected: 0 },
|
|
175
|
+
{ value: 42, expected: 42 },
|
|
176
|
+
{ value: -42, expected: -42 },
|
|
177
|
+
{ value: 0, expected: 0 },
|
|
178
|
+
{ value: NaN, expected: 0 },
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
export const compareCases = [
|
|
182
|
+
{ a: 10, b: 5, expected: 1 },
|
|
183
|
+
{ a: 5, b: 10, expected: -1 },
|
|
184
|
+
{ a: 5, b: 5, expected: 0 },
|
|
185
|
+
{ a: -10, b: -5, expected: -1 },
|
|
186
|
+
{ a: -5, b: -10, expected: 1 },
|
|
187
|
+
{ a: 0, b: 0, expected: 0 },
|
|
188
|
+
{ a: 0, b: -1, expected: 1 },
|
|
189
|
+
{ a: -1, b: 0, expected: -1 },
|
|
190
|
+
];
|