@sankhyalabs/core 0.0.0-bugfix-dev-KB-17130.1 → 0.0.0-bugfix-dev-KB-35840.0

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 (152) hide show
  1. package/.docs/README.md +3 -1
  2. package/.docs/classes/ApplicationContext.md +31 -32
  3. package/.docs/classes/ArrayUtils.md +183 -41
  4. package/.docs/classes/AuthorizedServiceCaller.md +25 -34
  5. package/.docs/classes/Change.md +59 -74
  6. package/.docs/classes/DataUnit.md +1025 -1078
  7. package/.docs/classes/DataUnitAction.md +25 -42
  8. package/.docs/classes/DataUnitStorage.md +40 -43
  9. package/.docs/classes/DateUtils.md +140 -133
  10. package/.docs/classes/ElementIDUtils.md +123 -122
  11. package/.docs/classes/ErrorException.md +67 -88
  12. package/.docs/classes/ErrorTracking.md +20 -23
  13. package/.docs/classes/FieldComparator.md +35 -39
  14. package/.docs/classes/FloatingManager.md +195 -198
  15. package/.docs/classes/HTMLBuilder.md +14 -20
  16. package/.docs/classes/HttpProvider.md +45 -41
  17. package/.docs/classes/IDBRepository.md +179 -196
  18. package/.docs/classes/JSUtils.md +82 -58
  19. package/.docs/classes/KeyboardManager.md +95 -87
  20. package/.docs/classes/{MaskFormatter-1.md → MaskFormatter.md} +81 -120
  21. package/.docs/classes/NumberUtils.md +163 -152
  22. package/.docs/classes/ObjectUtils.md +82 -61
  23. package/.docs/classes/OnboardingUtils.md +36 -51
  24. package/.docs/classes/OverflowWatcher.md +269 -0
  25. package/.docs/classes/PromiseSync.md +25 -42
  26. package/.docs/classes/ReadyUtil.md +31 -41
  27. package/.docs/classes/RequestMetadata.md +29 -30
  28. package/.docs/classes/SearchUtils.md +41 -0
  29. package/.docs/classes/SelectionInfo.md +59 -74
  30. package/.docs/classes/SkwHttpProvider.md +33 -45
  31. package/.docs/classes/StringUtils.md +397 -268
  32. package/.docs/classes/TimeFormatter.md +43 -44
  33. package/.docs/classes/UserAgentUtils.md +17 -20
  34. package/.docs/classes/VersionUtils.md +15 -18
  35. package/.docs/classes/WaitingChangeException.md +63 -84
  36. package/.docs/classes/WarningException.md +67 -88
  37. package/.docs/enumerations/Action.md +297 -0
  38. package/.docs/enumerations/ChangeOperation.md +47 -0
  39. package/.docs/enumerations/DataType.md +57 -0
  40. package/.docs/enumerations/DependencyType.md +37 -0
  41. package/.docs/enumerations/OverflowDirection.md +29 -0
  42. package/.docs/enumerations/SelectionMode.md +27 -0
  43. package/.docs/enumerations/SortMode.md +27 -0
  44. package/.docs/enumerations/UserInterface.md +177 -0
  45. package/.docs/functions/defaultDataLoader.md +25 -0
  46. package/.docs/{modules.md → globals.md} +22 -37
  47. package/.docs/interfaces/ChildDescriptor.md +12 -16
  48. package/.docs/interfaces/ChildLink.md +9 -12
  49. package/.docs/interfaces/DUActionInterceptor.md +10 -14
  50. package/.docs/interfaces/ExecutionContext.md +17 -32
  51. package/.docs/interfaces/FieldDescriptor.md +52 -66
  52. package/.docs/interfaces/Filter.md +13 -17
  53. package/.docs/interfaces/IElementIDInfo.md +11 -14
  54. package/.docs/interfaces/ILoadResult.md +11 -16
  55. package/.docs/interfaces/IRepository.md +88 -93
  56. package/.docs/interfaces/IRepositoryIndex.md +23 -30
  57. package/.docs/interfaces/LoadDataRequest.md +36 -45
  58. package/.docs/interfaces/LoadDataResponse.md +11 -14
  59. package/.docs/interfaces/PageRequest.md +16 -20
  60. package/.docs/interfaces/PaginationInfo.md +24 -31
  61. package/.docs/interfaces/PromiseSyncCallback.md +13 -17
  62. package/.docs/interfaces/QuickFilter.md +17 -21
  63. package/.docs/interfaces/Record.md +26 -33
  64. package/.docs/interfaces/SavedRecord.md +33 -41
  65. package/.docs/interfaces/Sort.md +12 -16
  66. package/.docs/interfaces/SortingProvider.md +10 -13
  67. package/.docs/interfaces/UnitMetadata.md +16 -21
  68. package/.docs/interfaces/WaitingChange.md +16 -20
  69. package/.docs/namespaces/MaskFormatter/README.md +17 -0
  70. package/.docs/namespaces/MaskFormatter/type-aliases/MaskCharacter.md +13 -0
  71. package/.docs/namespaces/MaskFormatter/variables/MaskCharacter.md +13 -0
  72. package/.docs/type-aliases/OnOverflowCallBack.md +25 -0
  73. package/.releaserc +10 -10
  74. package/dist/dataunit/DataUnit.d.ts +24 -2
  75. package/dist/dataunit/DataUnit.js +49 -9
  76. package/dist/dataunit/DataUnit.js.map +1 -1
  77. package/dist/dataunit/formatting/PrettyFormatter.js +9 -5
  78. package/dist/dataunit/formatting/PrettyFormatter.js.map +1 -1
  79. package/dist/dataunit/metadata/DataType.js +10 -1
  80. package/dist/dataunit/metadata/DataType.js.map +1 -1
  81. package/dist/dataunit/state/action/DataUnitAction.d.ts +3 -1
  82. package/dist/dataunit/state/action/DataUnitAction.js +2 -0
  83. package/dist/dataunit/state/action/DataUnitAction.js.map +1 -1
  84. package/dist/dataunit/state/slice/ChangesSlice.js +12 -11
  85. package/dist/dataunit/state/slice/ChangesSlice.js.map +1 -1
  86. package/dist/dataunit/state/slice/InvalidFieldsSlice.js +2 -0
  87. package/dist/dataunit/state/slice/InvalidFieldsSlice.js.map +1 -1
  88. package/dist/dataunit/state/slice/LoadingProperties.d.ts +9 -0
  89. package/dist/dataunit/state/slice/LoadingProperties.js +31 -0
  90. package/dist/dataunit/state/slice/LoadingProperties.js.map +1 -0
  91. package/dist/dataunit/state/slice/SelectionSlice.js +3 -2
  92. package/dist/dataunit/state/slice/SelectionSlice.js.map +1 -1
  93. package/dist/index.d.ts +3 -1
  94. package/dist/index.js +3 -1
  95. package/dist/index.js.map +1 -1
  96. package/dist/utils/ArrayUtils.d.ts +39 -0
  97. package/dist/utils/ArrayUtils.js +69 -0
  98. package/dist/utils/ArrayUtils.js.map +1 -1
  99. package/dist/utils/DateUtils.js +4 -0
  100. package/dist/utils/DateUtils.js.map +1 -1
  101. package/dist/utils/JSUtils.d.ts +7 -0
  102. package/dist/utils/JSUtils.js +16 -0
  103. package/dist/utils/JSUtils.js.map +1 -1
  104. package/dist/utils/ObjectUtils.d.ts +8 -0
  105. package/dist/utils/ObjectUtils.js +10 -0
  106. package/dist/utils/ObjectUtils.js.map +1 -1
  107. package/dist/utils/OverflowWatcher/index.d.ts +31 -0
  108. package/dist/utils/OverflowWatcher/index.js +107 -0
  109. package/dist/utils/OverflowWatcher/index.js.map +1 -0
  110. package/dist/utils/OverflowWatcher/types/overflow-callback.d.ts +6 -0
  111. package/dist/utils/OverflowWatcher/types/overflow-callback.js +2 -0
  112. package/dist/utils/OverflowWatcher/types/overflow-callback.js.map +1 -0
  113. package/dist/utils/OverflowWatcher/types/overflow-direction.d.ts +7 -0
  114. package/dist/utils/OverflowWatcher/types/overflow-direction.js +9 -0
  115. package/dist/utils/OverflowWatcher/types/overflow-direction.js.map +1 -0
  116. package/dist/utils/SearchUtils.d.ts +6 -0
  117. package/dist/utils/SearchUtils.js +17 -0
  118. package/dist/utils/SearchUtils.js.map +1 -0
  119. package/dist/utils/StringUtils.d.ts +7 -0
  120. package/dist/utils/StringUtils.js +97 -0
  121. package/dist/utils/StringUtils.js.map +1 -1
  122. package/jest.config.ts +1 -1
  123. package/package.json +11 -4
  124. package/sonar-project.properties +7 -0
  125. package/src/dataunit/DataUnit.ts +57 -10
  126. package/src/dataunit/formatting/PrettyFormatter.ts +8 -5
  127. package/src/dataunit/metadata/DataType.ts +10 -1
  128. package/src/dataunit/state/action/DataUnitAction.ts +3 -1
  129. package/src/dataunit/state/slice/ChangesSlice.ts +15 -14
  130. package/src/dataunit/state/slice/InvalidFieldsSlice.ts +2 -0
  131. package/src/dataunit/state/slice/LoadingProperties.ts +37 -0
  132. package/src/dataunit/state/slice/SelectionSlice.ts +3 -2
  133. package/src/index.ts +6 -0
  134. package/src/utils/ArrayUtils.ts +73 -0
  135. package/src/utils/DateUtils.ts +2 -0
  136. package/src/utils/JSUtils.ts +18 -0
  137. package/src/utils/ObjectUtils.ts +11 -0
  138. package/src/utils/OverflowWatcher/index.ts +151 -0
  139. package/src/utils/OverflowWatcher/types/overflow-callback.ts +6 -0
  140. package/src/utils/OverflowWatcher/types/overflow-direction.ts +7 -0
  141. package/src/utils/SearchUtils.ts +18 -0
  142. package/src/utils/StringUtils.ts +124 -0
  143. package/test/util/OverflowWatcher.spec.ts +118 -0
  144. package/.docs/.nojekyll +0 -1
  145. package/.docs/enums/Action.md +0 -305
  146. package/.docs/enums/ChangeOperation.md +0 -52
  147. package/.docs/enums/DataType.md +0 -63
  148. package/.docs/enums/DependencyType.md +0 -41
  149. package/.docs/enums/SelectionMode.md +0 -30
  150. package/.docs/enums/SortMode.md +0 -30
  151. package/.docs/enums/UserInterface.md +0 -195
  152. package/.docs/modules/MaskFormatter.md +0 -37
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sankhyalabs/core",
3
- "version": "0.0.0-bugfix-dev-KB-17130.1",
3
+ "version": "0.0.0-bugfix-dev-KB-35840.0",
4
4
  "description": "Modulo core JavaScript da Sankhya.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -10,7 +10,7 @@
10
10
  "build": "tsc",
11
11
  "build:watch": "tsc --watch",
12
12
  "compile": "tsc",
13
- "test": "jest",
13
+ "test": "jest --coverage --silent --testResultsProcessor jest-sonar-reporter",
14
14
  "coverage": "jest --coverage",
15
15
  "serve": "es-dev-server --node-resolve --watch",
16
16
  "eslint": "eslint src/**",
@@ -43,11 +43,18 @@
43
43
  "eslint-plugin-import": "^2.26.0",
44
44
  "husky": "^8.0.3",
45
45
  "jest": "^29.4.1",
46
+ "jest-sonar-reporter": "^2.0.0",
46
47
  "jest-environment-jsdom": "^29.4.1",
47
48
  "ts-jest": "^29.0.5",
48
49
  "ts-node": "^10.9.1",
49
- "typedoc": "^0.23.24",
50
- "typedoc-plugin-markdown": "^3.14.0",
50
+ "typedoc": "^0.25.13",
51
+ "typedoc-plugin-markdown": "^4.0.1",
51
52
  "typescript": "^4.9.5"
53
+ },
54
+ "jestSonar": {
55
+ "sonar56x": true,
56
+ "reportPath": "reports",
57
+ "reportFile": "test-report.xml",
58
+ "indent": 4
52
59
  }
53
60
  }
@@ -0,0 +1,7 @@
1
+ sonar.testExecutionReportPaths=./reports/test-report.xml
2
+ sonar.typescript.lcov.reportPaths=./coverage/lcov.info
3
+ sonar.test.inclusions="**/test/*.e2e.ts","**/test/*.spec.ts","**/test/*.spec.tsx","**/utils/*.spec.ts"
4
+ sonar.tests=.
5
+ sonar.c.file.suffixes=-
6
+ sonar.cpp.file.suffixes=-
7
+ sonar.objc.file.suffixes=-
@@ -25,6 +25,7 @@ import { getFormattedValue } from "./formatting/PrettyFormatter.js";
25
25
  import { v4 as uuid } from "uuid";
26
26
  import { DataUnitStorage } from "./DataUnitStorage.js";
27
27
  import { getInvalidFieldMessage, InvalidFieldsReducer } from "./state/slice/InvalidFieldsSlice.js";
28
+ import { getLoadingProperties, LoadingPropertiesReducer } from "./state/slice/LoadingProperties.js";
28
29
 
29
30
  /***
30
31
  * `DataUnit`: Atua como uma camada de abstração entre o back-end e a interface do usuário.
@@ -61,6 +62,7 @@ export default class DataUnit {
61
62
  this._stateManager = new StateManager(
62
63
  [
63
64
  HistReducer,
65
+ LoadingPropertiesReducer,
64
66
  UnitMetadataReducer,
65
67
  LoadingControlReducer,
66
68
  RecordsReducer,
@@ -114,6 +116,27 @@ export default class DataUnit {
114
116
  this._interceptors = [];
115
117
  }
116
118
 
119
+ /**
120
+ * Adiciona uma propriedade transacional que será envida aos
121
+ * loaders (dataLoader, saveLoader, removeLoader e recordLoader) na chamada.
122
+ * Essas propriedades serão limpas ao final da execução de cada método.
123
+ *
124
+ * @param name - Nome da propriedade
125
+ * @param value - Valor da propriedade
126
+ *
127
+ */
128
+ public addGlobalLoaderProp(name: string, value: string):void{
129
+ this.dispatchAction(Action.LOADING_PROPERTY_ADDED, {[name]: value});
130
+ }
131
+
132
+ /**
133
+ * Retorna as propriedades transacionais adicionados anteriores à chamada.
134
+ *
135
+ * @returns - Todas as propriedades desde o final do último loader.
136
+ */
137
+ public getGlobalLoaderProps(): Map<string, string>{
138
+ return getLoadingProperties(this._stateManager) || new Map();
139
+ }
117
140
 
118
141
  public get dataUnitId(): string{
119
142
  return this._uuid;
@@ -215,18 +238,24 @@ export default class DataUnit {
215
238
  if (await this.dispatchAction(Action.LOADING_DATA, request, executionCtx)) {
216
239
  if (this.dataLoader) {
217
240
  this.dataLoader(this, request).then(
218
- response => {
219
- this.dispatchAction(Action.DATA_LOADED, {...response, keepSelection: request.keepSelection}, executionCtx);
241
+ async response => {
242
+ await this.dispatchAction(
243
+ Action.DATA_LOADED,
244
+ {...response, keepSelection: request.keepSelection, filters: request.filters},
245
+ executionCtx
246
+ );
247
+
248
+ await this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
220
249
 
221
250
  if(selectFirstRecord){
222
251
  this.requestSelectFirst(executionCtx);
223
252
  }
224
-
225
253
  resolve(response);
226
254
  }
227
255
  ).catch(error => {
228
256
  console.error(error);
229
257
  const {errorCode} = error;
258
+ this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
230
259
  fail(new ErrorException("Erro ao carregar registros", error, errorCode))
231
260
  });
232
261
  }
@@ -427,6 +456,7 @@ export default class DataUnit {
427
456
  const changes: Array<Change> = this.getAllChangesToSave();
428
457
 
429
458
  this.saveLoader(this, changes).then((records) => {
459
+ this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
430
460
  const recordsByDataUnit = this.getRecordsByDataUnit(records);
431
461
 
432
462
  const dispatchPromisses = [];
@@ -441,9 +471,11 @@ export default class DataUnit {
441
471
  Promise.all(dispatchPromisses).then(() => resolve());
442
472
  }).catch(cause => {
443
473
  const {errorCode} = cause;
474
+ this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
444
475
  fail(new ErrorException("Erro ao salvar alterações", cause, errorCode));
445
476
  });
446
477
  } else {
478
+ this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
447
479
  resolve();
448
480
  }
449
481
  });
@@ -532,6 +564,7 @@ export default class DataUnit {
532
564
  public async removeRecords(recordIds: Array<string>, cachedRecords: Array<Record>, buffered: boolean = false, executionCtx?: ExecutionContext, silent: boolean = false): Promise<Array<string>> {
533
565
  if (recordIds) {
534
566
  if (buffered || !this.removeLoader) {
567
+ this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
535
568
  this.dispatchAction(Action.RECORDS_REMOVED, { records: recordIds, cachedRecords, buffered: true }, executionCtx);
536
569
  } else {
537
570
  if (await this.dispatchAction(Action.REMOVING_RECORDS, {silent}, executionCtx)) {
@@ -549,9 +582,11 @@ export default class DataUnit {
549
582
  const selectionAfterRemove = [currentRecordsKeys[nextIndex]];
550
583
 
551
584
  this.dispatchAction(Action.RECORDS_REMOVED, { records: removedIds, cachedRecords, removedIndex, buffered: false, selectionAfterRemove }, executionCtx);
585
+ this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
552
586
  resolve(removedIds);
553
587
  }
554
588
  ).catch(error => {
589
+ this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
555
590
  const {errorCode} = error;
556
591
  fail(new ErrorException("Erro ao remover registros", error, errorCode))
557
592
  });
@@ -608,15 +643,14 @@ export default class DataUnit {
608
643
  *
609
644
  */
610
645
  public getFormattedValue(fieldName: string, value?: any): string {
611
-
612
646
  const descriptor = this.getField(fieldName);
613
- if (value == undefined) {
647
+ if (value === undefined) {
614
648
  value = this.getFieldValue(fieldName);
615
649
  } else if (typeof value === "string" && descriptor?.dataType != DataType.TEXT){
616
650
  value = this.valueFromString(fieldName, value);
617
651
  }
618
652
 
619
- if(value == undefined){
653
+ if(value === undefined){
620
654
  return "";
621
655
  }
622
656
 
@@ -1496,7 +1530,7 @@ export default class DataUnit {
1496
1530
  * @param observer - Função que recebe como parâmetro as ações que serão monitoradas.
1497
1531
  *
1498
1532
  */
1499
- public subscribe(observer: (action: DataUnitAction) => void) {
1533
+ public subscribe(observer: (action: DataUnitAction) => void | Promise<void>) {
1500
1534
  this._observers.push(observer);
1501
1535
  }
1502
1536
 
@@ -1523,12 +1557,16 @@ export default class DataUnit {
1523
1557
  const selection = getSelection(this._stateManager);
1524
1558
  this.dispatchAction(Action.LOADING_RECORD, selection);
1525
1559
 
1526
- if(!this.dataLoader) return;
1527
- if(!this.recordLoader) return;
1560
+ if(!this.recordLoader || !this.dataLoader) {
1561
+ this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
1562
+ return;
1563
+ }
1528
1564
 
1529
1565
  this.recordLoader(this, selection).then(response => {
1530
1566
  this.dispatchAction(Action.RECORD_LOADED, response)
1567
+ this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
1531
1568
  }).catch(cause => {
1569
+ this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
1532
1570
  const {errorCode} = cause;
1533
1571
  fail(new ErrorException("Erro ao recarregar registro", cause, errorCode));
1534
1572
  });
@@ -1693,12 +1731,21 @@ export default class DataUnit {
1693
1731
  return selection?.recordIds || [];
1694
1732
  }
1695
1733
 
1734
+ /**
1735
+ * Adiciona um campo stand-alone ao dataUnit.
1736
+ *
1737
+ * @deprecated - metodo depreciado, utilizar o metodo addField
1738
+ */
1739
+ public addStandAloneField() : void {
1740
+ console.warn("metodo depreciado, para adicionar um campo standAlone, utilizar o metodo addField")
1741
+ }
1742
+
1696
1743
  /**
1697
1744
  * Adiciona um campo stand-alone ao dataUnit.
1698
1745
  *
1699
1746
  * @param field - Campo a ser adicionado.
1700
1747
  */
1701
- public addStandAloneField(field: Omit<FieldDescriptor, 'standAlone'>) : void {
1748
+ public addField(field: Omit<FieldDescriptor, 'standAlone'>) : void {
1702
1749
  const standAloneField = {...field, standAlone: true};
1703
1750
  this.metadata = {...this.metadata, fields: [...this.metadata.fields, standAloneField]};
1704
1751
  }
@@ -10,10 +10,10 @@ export const getFormattedValue = (value: any, descriptor?: FieldDescriptor) => {
10
10
  }
11
11
 
12
12
  if(descriptor?.dataType === DataType.OBJECT){
13
- if(Object.hasOwn(value, "value")){
13
+ if(value && Object.hasOwn(value, "value")){
14
14
  return getSearchFormat(value, descriptor);
15
15
  }
16
- return value == undefined ? "" : value.toString();
16
+ return !value ? "" : value.toString();
17
17
  }
18
18
 
19
19
  if(descriptor?.userInterface === UserInterface.OPTIONSELECTOR){
@@ -53,6 +53,7 @@ export const getFormattedValue = (value: any, descriptor?: FieldDescriptor) => {
53
53
  }
54
54
 
55
55
  const getNumberFormat = (value: any, descriptor: FieldDescriptor) => {
56
+ if(!value) return "";
56
57
  if(descriptor.userInterface === UserInterface.INTEGERNUMBER){
57
58
  return value;
58
59
  }
@@ -79,10 +80,12 @@ const getOptionFormat = (value: any, descriptor: FieldDescriptor) => {
79
80
  options = JSON.parse(prop);
80
81
  } else {
81
82
  options = {};
82
- prop.forEach(opt => options[opt.label] = opt.value);
83
+ if(prop != undefined){
84
+ prop.forEach(opt => options[opt.label] = opt.value);
85
+ }
83
86
  }
84
87
 
85
- if(typeof value === "object"){
88
+ if(value && typeof value === "object" ){
86
89
  value = value.value
87
90
  }
88
91
 
@@ -90,7 +93,7 @@ const getOptionFormat = (value: any, descriptor: FieldDescriptor) => {
90
93
  return options[value];
91
94
  }
92
95
 
93
- return value;
96
+ return value ?? "";
94
97
  }
95
98
 
96
99
 
@@ -67,7 +67,16 @@ export const getConvertedValue = (dataType: DataType, value: any): any => {
67
67
  case DataType.NUMBER:
68
68
  return value === "" || isNaN(Number(value)) ? null : Number(value);
69
69
  case DataType.OBJECT:
70
- return typeof value === "string" ? JSON.parse(value) : value;
70
+ //Caso de uso campo DataType do tipo STRING e UserInterface do tipo TEXT, que tem relacionamento (TGFPRO.GRUPOPIS)
71
+ if(typeof value === "string") {
72
+ try{
73
+ return JSON.parse(value);
74
+ }catch(e){
75
+ console.warn(`Erro ao fazer parse do valor ${value} para objeto, dataType: ${dataType}`);
76
+ }
77
+ }
78
+
79
+ return value;
71
80
  case DataType.BOOLEAN:
72
81
  if (typeof value === "string") {
73
82
  return Boolean(value === 'true');
@@ -63,6 +63,8 @@ export enum Action{
63
63
  CHILD_CHANGED = "childChanged",
64
64
 
65
65
  FIELD_INVALIDATED = "fieldInvalidated",
66
- INVALIDATE_CLEAN = "invalidateClean"
66
+ INVALIDATE_CLEAN = "invalidateClean",
67
67
 
68
+ LOADING_PROPERTY_ADDED = "loadingPropertyAdded",
69
+ LOADING_PROPERTIES_CLEANED = "loadingPropertiesCleaned"
68
70
  }
@@ -94,27 +94,28 @@ export const getChangedFieldValue = (fieldName: string, record: Record, stateMan
94
94
  }
95
95
 
96
96
  export const getChangesToSave = (dataUnit: string, stateManager: StateManager): Array<Change> => {
97
- const result: Array<Change> = [];
98
-
97
+
99
98
  const changes = getChanges(stateManager);
100
99
  const selectedRecords = getSelectionRecords(stateManager) || [];
101
- const records: Set<Record> = new Set(
100
+ const records: Map<string, Record> = new Map(
102
101
  getRecords(stateManager)
103
102
  .concat(
104
- selectedRecords
105
- .filter(record => !isAddedRecord(record.__record__id__, stateManager)
106
- )
103
+ selectedRecords.filter(record => !isAddedRecord(record.__record__id__, stateManager))
107
104
  )
105
+ .map(r => [r.__record__id__, r])
108
106
  );
109
-
110
- records?.forEach(r => {
111
- if(changes){
112
- const c = changes.get(r.__record__id__);
113
- if (c) {
114
- result.push(new Change(dataUnit, r, c, ChangeOperation.UPDATE, r.__record__source__id__));
107
+
108
+ const result: Array<Change> = [];
109
+
110
+ if(changes != undefined){
111
+ Array.from(changes.entries())
112
+ .forEach(([recordId, change]) =>{
113
+ const record = records.get(recordId);
114
+ if(record != undefined){
115
+ result.push(new Change(dataUnit, record, change, ChangeOperation.UPDATE, record.__record__source__id__));
115
116
  }
116
- }
117
- });
117
+ });
118
+ }
118
119
 
119
120
  const addedRecords = getAddedRecords(stateManager);
120
121
  if (addedRecords) {
@@ -15,6 +15,8 @@ class InvalidFieldsReducerImpl implements ActionReducer{
15
15
  return makeInvalid(currentState, action.payload);
16
16
  case Action.INVALIDATE_CLEAN:
17
17
  return clearRecord(currentState, action.payload);
18
+ case Action.EDITION_CANCELED:
19
+ return undefined;
18
20
  }
19
21
 
20
22
  return currentState;
@@ -0,0 +1,37 @@
1
+
2
+ import { ActionReducer, StateAction } from "../StateManager.js";
3
+ import { Action } from "../action/DataUnitAction.js";
4
+ import StateManager from "../StateManager.js";
5
+
6
+ class LoadingPropertiesImpl implements ActionReducer{
7
+
8
+ public sliceName: string = "loadingProperties";
9
+
10
+ public reduce(_stateManager:StateManager, currentState: Map<string, string>, action: StateAction): Map<string, string>|undefined {
11
+ switch(action.type){
12
+ case Action.LOADING_PROPERTY_ADDED:
13
+ return buildNewState(currentState, action.payload);
14
+ case Action.LOADING_PROPERTIES_CLEANED:
15
+ return undefined;
16
+ }
17
+ return currentState;
18
+ }
19
+ }
20
+
21
+ export const LoadingPropertiesReducer = new LoadingPropertiesImpl();
22
+
23
+ export const getLoadingProperties = (stateManager: StateManager): Map<string, string>|undefined => {
24
+ return stateManager.select(LoadingPropertiesReducer.sliceName, (state: Map<string, string>) => state);
25
+ };
26
+
27
+ function buildNewState(currentState: Map<string, string>, payload: any): Map<string, string>{
28
+ const newState = new Map(currentState);
29
+ if(payload != undefined){
30
+ for (const [key, value] of Object.entries(payload)) {
31
+ if(typeof key === "string" && typeof value === "string"){
32
+ newState.set(key, value);
33
+ }
34
+ }
35
+ }
36
+ return newState;
37
+ }
@@ -17,7 +17,8 @@ class SelectionReducerImpl implements ActionReducer {
17
17
  return !action.payload?.keepSelection ? undefined : currentState;
18
18
  case Action.RECORDS_ADDED:
19
19
  case Action.RECORDS_COPIED:
20
- return {currentSelection: action.payload.map((r: Record)=>r.__record__id__), lastSelection: currentState?.currentSelection};
20
+ const lastSelection = currentState?.currentSelection || [];
21
+ return {currentSelection: action.payload.map((r: Record)=>r.__record__id__), lastSelection};
21
22
  case Action.DATA_SAVED:
22
23
  return {currentSelection: updateSavedIds(stateManager, action.payload.records)};
23
24
  case Action.RECORDS_REMOVED:
@@ -67,7 +68,7 @@ class SelectionReducerImpl implements ActionReducer {
67
68
  if(currentState?.lastSelection){
68
69
  return { currentSelection: currentState.lastSelection };
69
70
  }
70
- break;
71
+ return { currentSelection: [] }
71
72
  }
72
73
 
73
74
  return currentState;
package/src/index.ts CHANGED
@@ -38,6 +38,8 @@ import { ILoadResult } from "./repository/ILoadResult.js";
38
38
  import { IRepositoryIndex } from "./repository/indexeddb/IRepositoryIndex.js"
39
39
  import { FieldComparator } from "./dataunit/sorting/FieldComparator.js";
40
40
  import { KeyboardManager } from "./utils/KeyboardManager/index.js";
41
+ import { SearchUtils } from "./utils/SearchUtils.js";
42
+ import OverflowWatcher, { OnOverflowCallBack, OverflowDirection } from "./utils/OverflowWatcher/index.js";
41
43
 
42
44
  /*Classes públicas no pacote*/
43
45
  export {
@@ -104,4 +106,8 @@ export {
104
106
  FieldComparator,
105
107
  defaultDataLoader,
106
108
  KeyboardManager,
109
+ SearchUtils,
110
+ OverflowWatcher,
111
+ OnOverflowCallBack,
112
+ OverflowDirection
107
113
  };
@@ -1,5 +1,6 @@
1
1
  import { StringUtils } from "./StringUtils.js";
2
2
  import { NumberUtils } from './NumberUtils.js';
3
+ import ObjectUtils from "./ObjectUtils.js";
3
4
 
4
5
  /**
5
6
  * `ArrayUtils`: Utilitário com a responsabilidade de manipular Arrays.
@@ -58,4 +59,76 @@ export default class ArrayUtils {
58
59
  }
59
60
  });
60
61
  }
62
+
63
+ /**
64
+ * Ordena valores de um array alfabeticamente.
65
+ *
66
+ * @param arr - Array a ser ordenado.
67
+ * @returns - Array ordenado alfabeticamente..
68
+ */
69
+ public static find(arr: any, checkerFn: any) {
70
+ if (arr) {
71
+ for (let i = 0, length = arr.length; i < length; i++) {
72
+ if (checkerFn(arr[i], i, arr)) {
73
+ return arr[i];
74
+ }
75
+ }
76
+ } else {
77
+ return undefined;
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Retorna o objeto se for encontrado no array, ou -1 se não for encontrado.
83
+ *
84
+ * @param arr - Array onde está o objeto.
85
+ * @param obj - Objeto a ser procurado.
86
+ * @returns - Array ordenado alfabeticamente..
87
+ */
88
+ public static indexOf(arr: any, obj: any) {
89
+ let index = -1;
90
+ if (Array.isArray(arr)) {
91
+ ArrayUtils.find(arr, (item: any, i: number) => {
92
+ index = i;
93
+ return ObjectUtils.equals(obj, item);
94
+ });
95
+ }
96
+ return index;
97
+ }
98
+
99
+ /**
100
+ * Remove um item de array de acordo com o index.
101
+ *
102
+ * @param array - Array onde está o item.
103
+ * @param index - Index do item a ser removido.
104
+ * @returns - Array sem o item do index informado.
105
+ */
106
+ public static removeAtIndex(array: any, index: number) {
107
+ if (index >= 0 && index < array.length) {
108
+ return array.splice(index, 1)[0];
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Remove um objeto do array.
114
+ *
115
+ * @param array - Array onde está o objeto.
116
+ * @param obj - Objeto a ser removido.
117
+ * @returns - Array sem o Objeto informado.
118
+ */
119
+ public static removeReference(array: any, obj: any) {
120
+ let index = ArrayUtils.indexOf(array, obj);
121
+ return ArrayUtils.removeAtIndex(array, index);
122
+ }
123
+
124
+ /**
125
+ * Remove um objeto do array.
126
+ *
127
+ * @param array - Array onde está o objeto.
128
+ * @param obj - Objeto a ser removido.
129
+ * @returns - Array sem o Objeto informado.
130
+ */
131
+ public static isIn(arr: any, obj: any) {
132
+ return ArrayUtils.indexOf(arr, obj) > -1;
133
+ }
61
134
  }
@@ -39,6 +39,7 @@ export default class DateUtils{
39
39
  * @returns - Uma string com as horas no formato HH:MM ou HH:MM:SS.
40
40
  */
41
41
  public static formatTime(date: Date, showSeconds: boolean = false): string{
42
+ if(!date) return "";
42
43
  const timeOptions:Intl.DateTimeFormatOptions = {hour: "2-digit", minute: "2-digit", second: showSeconds ? "2-digit" : undefined};
43
44
  return new Intl.DateTimeFormat("pt-BR", timeOptions).format(date);
44
45
  }
@@ -51,6 +52,7 @@ export default class DateUtils{
51
52
  * @returns - Uma string com as horas no formato DD/MM/YYYY HH:MM ou DD/MM/YYYY HH:MM:SS.
52
53
  */
53
54
  public static formatDateTime(date: Date, showSeconds: boolean = false): string{
55
+ if(!date) return "";
54
56
  return `${DateUtils.formatDate(date)} ${DateUtils.formatTime(date, showSeconds)}`;
55
57
  }
56
58
 
@@ -95,4 +95,22 @@ export class JSUtils{
95
95
  public static generateUUID(): string {
96
96
  return uuid();
97
97
  }
98
+
99
+ /**
100
+ * Substitui caracteres para suas entidades HTML.
101
+ *
102
+ * @param source - String a ter os caracteres substituidos.
103
+ * @returns - Retorna um UUID.
104
+ */
105
+ public static replaceHtmlEntities(source: string) {
106
+ if (source == undefined) {
107
+ return source;
108
+ }
109
+
110
+ return String(source)
111
+ .replace(/&/g, '&amp;')
112
+ .replace(/</g, '&lt;')
113
+ .replace(/>/g, '&gt;')
114
+ .replace(/"/g, '&quot;');
115
+ }
98
116
  }
@@ -73,4 +73,15 @@ export default class ObjectUtils{
73
73
  );
74
74
 
75
75
  }
76
+
77
+ /**
78
+ * Compara se um objeto é igual a outro objeto.
79
+ *
80
+ * @param obj1 - Objeto a ser comparado.
81
+ * @param obj2 - Objeto a ser comparado.
82
+ * @returns - Se o objeto 1 é igual ao objeto 2.
83
+ */
84
+ public static equals(obj1: any, obj2: any): any {
85
+ return ObjectUtils.objectToString(obj1) === ObjectUtils.objectToString(obj2);
86
+ }
76
87
  }