@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.
Files changed (71) hide show
  1. package/.docs/classes/Change.md +11 -11
  2. package/.docs/classes/DataUnit.md +230 -122
  3. package/.docs/classes/FieldComparator.md +6 -2
  4. package/.docs/classes/KeyboardManager.md +99 -9
  5. package/.docs/classes/LockManager.md +4 -4
  6. package/.docs/classes/ObjectUtils.md +50 -2
  7. package/.docs/classes/SelectionInfo.md +12 -12
  8. package/.docs/classes/StringUtils.md +10 -10
  9. package/.docs/enumerations/Action.md +41 -31
  10. package/.docs/enumerations/ChangeOperation.md +4 -4
  11. package/.docs/enumerations/SelectionMode.md +2 -2
  12. package/.docs/enumerations/UserInterface.md +15 -5
  13. package/.docs/interfaces/DUActionInterceptor.md +1 -1
  14. package/.docs/interfaces/PageRequest.md +3 -3
  15. package/.docs/interfaces/QuickFilter.md +3 -3
  16. package/.docs/interfaces/Record.md +4 -4
  17. package/.docs/interfaces/SavedRecord.md +5 -5
  18. package/.docs/interfaces/WaitingChange.md +3 -3
  19. package/.docs/type-aliases/DataUnitEventOptions.md +1 -1
  20. package/dist/dataunit/DataUnit.d.ts +19 -0
  21. package/dist/dataunit/DataUnit.js +43 -3
  22. package/dist/dataunit/DataUnit.js.map +1 -1
  23. package/dist/dataunit/formatting/PrettyFormatter.js +8 -3
  24. package/dist/dataunit/formatting/PrettyFormatter.js.map +1 -1
  25. package/dist/dataunit/metadata/DataType.d.ts +1 -1
  26. package/dist/dataunit/metadata/DataType.js +7 -4
  27. package/dist/dataunit/metadata/DataType.js.map +1 -1
  28. package/dist/dataunit/metadata/UnitMetadata.d.ts +1 -0
  29. package/dist/dataunit/metadata/UnitMetadata.js +1 -0
  30. package/dist/dataunit/metadata/UnitMetadata.js.map +1 -1
  31. package/dist/dataunit/sorting/FieldComparator.d.ts +2 -2
  32. package/dist/dataunit/sorting/FieldComparator.js +4 -4
  33. package/dist/dataunit/sorting/FieldComparator.js.map +1 -1
  34. package/dist/dataunit/state/action/DataUnitAction.d.ts +1 -0
  35. package/dist/dataunit/state/action/DataUnitAction.js +1 -0
  36. package/dist/dataunit/state/action/DataUnitAction.js.map +1 -1
  37. package/dist/utils/KeyboardManager/index.d.ts +9 -0
  38. package/dist/utils/KeyboardManager/index.js +45 -1
  39. package/dist/utils/KeyboardManager/index.js.map +1 -1
  40. package/dist/utils/KeyboardManager/interface.d.ts +1 -0
  41. package/dist/utils/LockManager.js.map +1 -1
  42. package/dist/utils/ObjectUtils.d.ts +14 -0
  43. package/dist/utils/ObjectUtils.js +20 -0
  44. package/dist/utils/ObjectUtils.js.map +1 -1
  45. package/dist/utils/SortingUtils.js +9 -1
  46. package/dist/utils/SortingUtils.js.map +1 -1
  47. package/dist/utils/StringUtils.js +12 -6
  48. package/dist/utils/StringUtils.js.map +1 -1
  49. package/package.json +1 -1
  50. package/reports/test-report.xml +669 -124
  51. package/src/dataunit/DataUnit.ts +51 -3
  52. package/src/dataunit/formatting/PrettyFormatter.ts +8 -5
  53. package/src/dataunit/metadata/DataType.ts +8 -4
  54. package/src/dataunit/metadata/UnitMetadata.ts +1 -0
  55. package/src/dataunit/sorting/FieldComparator.ts +4 -4
  56. package/src/dataunit/state/action/DataUnitAction.ts +2 -0
  57. package/src/utils/KeyboardManager/index.ts +57 -0
  58. package/src/utils/KeyboardManager/interface.ts +1 -0
  59. package/src/utils/LockManager.ts +0 -1
  60. package/src/utils/ObjectUtils.ts +21 -0
  61. package/src/utils/SortingUtils.ts +10 -1
  62. package/src/utils/StringUtils.ts +10 -6
  63. package/test/dataunit/formatting/PrettyFormatter.spec.ts +1 -1
  64. package/test/testCases/NumberUtilsTestCases.ts +190 -0
  65. package/test/testCases/StringUtilsTestCases.ts +435 -0
  66. package/test/testCases/TimeFormatterTestUtils.ts +43 -0
  67. package/test/util/NumberUtils.spec.ts +72 -150
  68. package/test/util/ObjectUtils.spec.ts +572 -0
  69. package/test/util/StringUtils.spec.ts +260 -36
  70. package/test/util/TimeFormatter.spec.ts +65 -18
  71. package/src/utils/test/objectUtils.spec.ts +0 -109
@@ -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(!(newValue instanceof Promise) && ObjectUtils.hasEquivalentProps(currentValue, typedValue)){
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 = () => this.allRecordsLoader?.(this);
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 getFileFotmat(value);
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 getFileFotmat = (value: any) =>{
131
- if (!value || !Array.isArray(value)) return '';
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
- export const compareValues = (valueA: any, valueB: any, descriptor: FieldDescriptor): number => {
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 === UserInterface.SEARCH || userInterface === UserInterface.OPTIONSELECTOR){
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
  }
@@ -91,6 +91,7 @@ export enum UserInterface {
91
91
  DECIMALNUMBER = "DECIMALNUMBER",
92
92
  INTEGERNUMBER = "INTEGERNUMBER",
93
93
  SEARCH = "SEARCH",
94
+ SEARCHPLUS = "SEARCHPLUS",
94
95
  SHORTTEXT = "SHORTTEXT",
95
96
  PASSWORD = "PASSWORD",
96
97
  MASKEDTEXT = "MASKEDTEXT",
@@ -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 {
@@ -26,6 +26,8 @@ export interface ExecutionContext{
26
26
 
27
27
  export enum Action{
28
28
 
29
+ MULTIPLE_EDITION_CHANGED = "multipleEditionChanged",
30
+
29
31
  LOADING_METADATA = "loadingMetadata",
30
32
  METADATA_LOADED = "metadataLoaded",
31
33
 
@@ -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
 
@@ -1,6 +1,7 @@
1
1
  export interface IKeyboardOptions {
2
2
  type: 'keydown' | 'keyup',
3
3
  propagate: boolean,
4
+ enableShadowDom: boolean,
4
5
  element: HTMLElement | Document,
5
6
  debounceTime: number,
6
7
  description?: string,
@@ -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);
@@ -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
- const result = FieldComparator.compare(dataUnit.getField(sort.field) as FieldDescriptor, recordA, recordB, sort.mode === SortMode.ASC);
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
  }
@@ -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.toString()}B`;
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.toString()}B`;
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
+ ];