@sankhyalabs/core 5.20.0-dev.9 → 5.20.0-rc.10

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 (54) hide show
  1. package/.docs/classes/Change.md +11 -11
  2. package/.docs/classes/DataUnit.md +145 -115
  3. package/.docs/classes/ObjectUtils.md +48 -0
  4. package/.docs/classes/OverflowWatcher.md +310 -46
  5. package/.docs/classes/SelectionInfo.md +11 -11
  6. package/.docs/enumerations/ChangeOperation.md +4 -4
  7. package/.docs/enumerations/SelectionMode.md +2 -2
  8. package/.docs/globals.md +6 -0
  9. package/.docs/interfaces/DUActionInterceptor.md +1 -1
  10. package/.docs/interfaces/OverFlowWatcherParams.md +67 -0
  11. package/.docs/interfaces/PageRequest.md +3 -3
  12. package/.docs/interfaces/QuickFilter.md +3 -3
  13. package/.docs/interfaces/Record.md +4 -4
  14. package/.docs/interfaces/SavedRecord.md +5 -5
  15. package/.docs/interfaces/WaitingChange.md +3 -3
  16. package/.docs/type-aliases/DataUnitEventOptions.md +17 -0
  17. package/.docs/variables/OVERFLOWED_CLASS_NAME.md +13 -0
  18. package/dist/dataunit/DataUnit.d.ts +7 -2
  19. package/dist/dataunit/DataUnit.js +31 -20
  20. package/dist/dataunit/DataUnit.js.map +1 -1
  21. package/dist/dataunit/formatting/PrettyFormatter.js +7 -5
  22. package/dist/dataunit/formatting/PrettyFormatter.js.map +1 -1
  23. package/dist/dataunit/metadata/DataType.js +3 -0
  24. package/dist/dataunit/metadata/DataType.js.map +1 -1
  25. package/dist/dataunit/state/slice/SelectionSlice.js +1 -1
  26. package/dist/dataunit/state/slice/SelectionSlice.js.map +1 -1
  27. package/dist/index.d.ts +3 -3
  28. package/dist/index.js +2 -2
  29. package/dist/index.js.map +1 -1
  30. package/dist/utils/ElementUtils.d.ts +2 -0
  31. package/dist/utils/ElementUtils.js +9 -0
  32. package/dist/utils/ElementUtils.js.map +1 -0
  33. package/dist/utils/ObjectUtils.d.ts +14 -0
  34. package/dist/utils/ObjectUtils.js +18 -0
  35. package/dist/utils/ObjectUtils.js.map +1 -1
  36. package/dist/utils/OverflowWatcher/index.d.ts +35 -7
  37. package/dist/utils/OverflowWatcher/index.js +140 -59
  38. package/dist/utils/OverflowWatcher/index.js.map +1 -1
  39. package/jest.config.ts +2 -0
  40. package/package.json +2 -1
  41. package/reports/test-report.xml +151 -0
  42. package/setupTests.js +7 -0
  43. package/sonar-project.properties +6 -3
  44. package/src/dataunit/DataUnit.ts +35 -21
  45. package/src/dataunit/formatting/PrettyFormatter.ts +6 -5
  46. package/src/dataunit/metadata/DataType.ts +3 -0
  47. package/src/dataunit/state/slice/SelectionSlice.ts +1 -1
  48. package/src/index.ts +6 -3
  49. package/src/utils/ElementUtils.ts +10 -0
  50. package/src/utils/ObjectUtils.ts +20 -0
  51. package/src/utils/OverflowWatcher/index.ts +170 -78
  52. package/test/dataunit/formatting/PrettyFormatter.spec.ts +177 -0
  53. package/test/util/ElementUtils.spec.ts +34 -0
  54. package/test/util/OverflowWatcher.spec.ts +152 -118
package/jest.config.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  module.exports = {
2
+ preset: 'ts-jest',
3
+ setupFiles: ['./setupTests.js'],
2
4
  transform: {'^.+\\.ts?$': 'ts-jest'},
3
5
  testEnvironment: 'jsdom',
4
6
  testRegex: '\\.(test|spec)?\\.(ts|tsx)$',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sankhyalabs/core",
3
- "version": "5.20.0-dev.9",
3
+ "version": "5.20.0-rc.10",
4
4
  "description": "Modulo core JavaScript da Sankhya.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -45,6 +45,7 @@
45
45
  "jest": "^29.4.1",
46
46
  "jest-environment-jsdom": "^29.4.1",
47
47
  "jest-sonar-reporter": "^2.0.0",
48
+ "resize-observer-polyfill": "^1.5.1",
48
49
  "ts-jest": "^29.0.5",
49
50
  "ts-node": "^10.9.1",
50
51
  "typedoc": "^0.25.13",
@@ -0,0 +1,151 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <unitTest version="1">
3
+ <file path="/builds/dti/design-system/sankhyacore/test/util/MaskFormatter.spec.ts">
4
+ <testCase name="Mask Formatter mask:CPF complete valid" duration="7"/>
5
+ <testCase name="Mask Formatter mask:CPF complete valid literals" duration="1"/>
6
+ <testCase name="Mask Formatter mask:CPF incomplete valid" duration="1"/>
7
+ <testCase name="Mask Formatter mask:CPF incomplete valid placeholder" duration="10"/>
8
+ <testCase name="Mask Formatter mask:CPF too long valid" duration="1"/>
9
+ <testCase name="Mask Formatter mask:CPF invalid for string" duration="111"/>
10
+ <testCase name="Mask Formatter mask:CPF invalid for being too long" duration="1"/>
11
+ <testCase name="Mask Formatter mask:Licence plate valid uppercase" duration="0"/>
12
+ <testCase name="Mask Formatter mask:Licence plate valid lowercase" duration="0"/>
13
+ <testCase name="Mask Formatter mask:Licence plate invalid" duration="2"/>
14
+ <testCase name="Mask Formatter mask:Licence plate invalid for being too short" duration="1"/>
15
+ <testCase name="Mask Formatter mask:Licence plate invalid for being too short with placeholder" duration="0"/>
16
+ <testCase name="Mask Formatter mask:Licence plate invalid" duration="2"/>
17
+ <testCase name="Mask Formatter mask:Licence plate with AlphaNumerical Mask" duration="79"/>
18
+ <testCase name="Mask Formatter mask:Licence plate with AlphaNumerical Mask with placeholder" duration="0"/>
19
+ <testCase name="Mask Formatter mask:Licence plate invalid" duration="1"/>
20
+ <testCase name="Mask Formatter mask:Licence plate with AlphaNumerical Mask" duration="0"/>
21
+ <testCase name="Mask Formatter mask:Licence plate with AlphaNumerical Mask with placeholder" duration="1"/>
22
+ <testCase name="Mask Formatter mask:Licence plate invalid" duration="1"/>
23
+ <testCase name="Mask Formatter mask:Licence plate with AlphaNumerical Mask" duration="0"/>
24
+ <testCase name="Mask Formatter mask:Licence plate with AlphaNumerical Mask with placeholder" duration="0"/>
25
+ <testCase name="Mask Formatter mask:Licence plate invalid" duration="1"/>
26
+ </file>
27
+ <file path="/builds/dti/design-system/sankhyacore/test/util/CriteriaModel.spec.ts">
28
+ <testCase name="StringUtils it should return the undefined and [] to Criteria Props through new class with empty constructor" duration="13"/>
29
+ <testCase name="StringUtils it should modify &quot;expressions&quot; and &quot;parameters&quot; properties through Setters methods" duration="1"/>
30
+ <testCase name="StringUtils it should return &quot;expression&quot; and &quot;parameters&quot; setted through constructor method" duration="1"/>
31
+ <testCase name="StringUtils it should return a Criteria class with &quot;expression&quot; and &quot;parameters&quot; as needed setted through &quot;append&quot; method" duration="1"/>
32
+ <testCase name="StringUtils it should return a Criteria class with &quot;Criteria class&quot; and &quot;parameters&quot; concatenaded as needed setted through &quot;append&quot; method" duration="1"/>
33
+ <testCase name="StringUtils it should return undefined as &quot;expression&quot; and &quot;[]&quot; as parameters as we use an empty criteria as first entry in the constructor" duration="1"/>
34
+ <testCase name="StringUtils it should return a Criteria class with &quot;Expression&quot; and &quot;parameters&quot; concatenaded as needed setted through &quot;OR&quot; method" duration="1"/>
35
+ <testCase name="StringUtils it should return a Criteria class with &quot;Criteria class&quot; and &quot;parameters&quot; concatenaded as needed setted through &quot;OR&quot; method" duration="1"/>
36
+ <testCase name="StringUtils it should return a Criteria class with &quot;Criteria class&quot; and &quot;parameters&quot; concatenaded as needed setted through &quot;OR&quot; method" duration="3"/>
37
+ <testCase name="StringUtils it should return a Criteria class with &quot;Expression&quot; and &quot;parameters&quot; concatenaded as needed setted through &quot;AND&quot; method" duration="2"/>
38
+ <testCase name="StringUtils it should return a Criteria class with &quot;Criteria class&quot; and &quot;parameters&quot; concatenaded as needed setted through &quot;AND&quot; method" duration="1"/>
39
+ <testCase name="StringUtils it should return a Criteria class with &quot;Criteria class&quot; and &quot;parameters&quot; concatenaded as needed setted through &quot;AND&quot; method" duration="1"/>
40
+ <testCase name="StringUtils it should return a toJSON object with &quot;Criteria class&quot; and &quot;parameters&quot; concatenaded as needed setted through &quot;AND&quot; method" duration="1"/>
41
+ <testCase name="StringUtils it should return a toJSON object with through empty constructor" duration="0"/>
42
+ </file>
43
+ <file path="/builds/dti/design-system/sankhyacore/test/util/NumberUtils.spec.ts">
44
+ <testCase name="StringUtils stringToNumber" duration="87"/>
45
+ <testCase name="StringUtils format" duration="93"/>
46
+ <testCase name="StringUtils format without formatnumber parameter" duration="1"/>
47
+ <testCase name="StringUtils format without formatnumber parameter" duration="1"/>
48
+ <testCase name="StringUtils format round number" duration="83"/>
49
+ </file>
50
+ <file path="/builds/dti/design-system/sankhyacore/test/util/StringUtils.spec.ts">
51
+ <testCase name="StringUtils valor vazio" duration="2"/>
52
+ <testCase name="StringUtils valor em branco" duration="0"/>
53
+ <testCase name="StringUtils valor null" duration="1"/>
54
+ <testCase name="StringUtils valor undefined" duration="0"/>
55
+ <testCase name="StringUtils valor 0" duration="0"/>
56
+ <testCase name="StringUtils com valor" duration="0"/>
57
+ <testCase name="StringUtils substitui vogais com acento por vogais sem acento" duration="1"/>
58
+ <testCase name="StringUtils should return the original value when called with an object without a toString method" duration="2"/>
59
+ <testCase name="StringUtils should return the original value when called with undefined" duration="1"/>
60
+ </file>
61
+ <file path="/builds/dti/design-system/sankhyacore/test/http/HttpProvider.spec.ts">
62
+ <testCase name="HttpProvider Metodo GET" duration="1"/>
63
+ </file>
64
+ <file path="/builds/dti/design-system/sankhyacore/test/util/OverflowWatcher.spec.ts">
65
+ <testCase name="OverflowWatcher should initialize with provided parameters" duration="78"/>
66
+ <testCase name="OverflowWatcher should disconect ResizeObserver when destroy is called" duration="2"/>
67
+ <testCase name="OverflowWatcher Should call callback on forceUpdate" duration="307"/>
68
+ <testCase name="OverflowWatcher Should call callback on forceUpdate with childSpan" duration="98"/>
69
+ <testCase name="OverflowWatcher Should call callback on forceUpdate with childSpan when notOverFlow is empty" duration="87"/>
70
+ <testCase name="OverflowWatcher Should call callback on forceUpdate with childSpan considering overflowed elements" duration="7"/>
71
+ <testCase name="OverflowWatcher Should call callback on forceUpdate with empty list" duration="4"/>
72
+ <testCase name="OverflowWatcher should ignore elements that can not overflow" duration="190"/>
73
+ <testCase name="OverflowWatcher Should not call callback on forceUpdate" duration="1"/>
74
+ </file>
75
+ <file path="/builds/dti/design-system/sankhyacore/test/http/SkwHttpProvider.ts.spec.ts">
76
+ <testCase name="HttpProvider Metodo POST" duration="1"/>
77
+ </file>
78
+ <file path="/builds/dti/design-system/sankhyacore/test/util/CriteriaParameter.spec.ts">
79
+ <testCase name="StringUtils it should return the correct values of &quot;value&quot; and &quot;type&quot; through the getters methods initial setted by the constructor" duration="1"/>
80
+ <testCase name="StringUtils it should return the correct values of &quot;value&quot; and &quot;type&quot; through the getters methods initial setted by the setters methods" duration="0"/>
81
+ <testCase name="StringUtils it should return the correct JSON/Object value through the buildParam method" duration="0"/>
82
+ </file>
83
+ <file path="/builds/dti/design-system/sankhyacore/test/util/TimeFormatter.spec.ts">
84
+ <testCase name="TimeFormatter Case: input string unformated with showSeconds" duration="5"/>
85
+ <testCase name="TimeFormatter Case: input string unformated without showSeconds" duration="0"/>
86
+ <testCase name="TimeFormatter Case: validateTime" duration="2"/>
87
+ </file>
88
+ <file path="/builds/dti/design-system/sankhyacore/test/util/DataUnitStorage.spec.ts">
89
+ <testCase name="DataUnitStorage put should store a DataUnit instance in the DataUnitStorage" duration="68"/>
90
+ <testCase name="DataUnitStorage get should return the stored DataUnit instance from the DataUnitStorage" duration="1"/>
91
+ <testCase name="DataUnitStorage get should return undefined if the DataUnit instance is not found in the DataUnitStorage" duration="1"/>
92
+ <testCase name="DataUnitStorage remove should remove the specified DataUnit instance from the DataUnitStorage" duration="1"/>
93
+ <testCase name="DataUnitStorage remove should remove the DataUnit instance with the specified name from the DataUnitStorage" duration="1"/>
94
+ <testCase name="DataUnitStorage remove should not remove any DataUnit instance if the specified DataUnit instance or name is not found in the DataUnitStorage" duration="0"/>
95
+ </file>
96
+ <file path="/builds/dti/design-system/sankhyacore/test/util/ElementIDUtils.spec.ts">
97
+ <testCase name="addIDInfo 1 - should add data-element-id with valid id &quot;movFinanceira_snkApplication&quot;" duration="10"/>
98
+ <testCase name="addIDInfo 2 - should add data-element-id with valid id &quot;brComSankhyaFinCadMovimentacaofinanceira_snkApplication&quot;" duration="2"/>
99
+ <testCase name="addIDInfo 3 - should add data-element-id with valid id &quot;movFinanceira_br.com.sankhya.fin.cad.movimentacaoFinanceira&quot;" duration="2"/>
100
+ <testCase name="addIDInfo 4 - should add data-element-id with valid id &quot;meuID2_snkApplication&quot;" duration="1"/>
101
+ <testCase name="addIDInfo 5 - should add data-element-id with valid id &quot;movFinanceira_snkApplication&quot;" duration="1"/>
102
+ <testCase name="addIDInfo 6 - should add data-element-id with valid id &quot;movFinanceira_snkApplication&quot;" duration="1"/>
103
+ <testCase name="addIDInfo 7 - should add data-element-id with valid id &quot;componenteNameTest_snkApplication&quot;" duration="1"/>
104
+ <testCase name="addIDInfo 8 - should add data-element-id with valid id &quot;componentLabel_snkApplication&quot;" duration="1"/>
105
+ <testCase name="addIDInfo 9 - should add data-element-id with valid id &quot;dataunitFinanceiro_br.com.sankhya.fin.cad.movimentacaoFinanceira&quot;" duration="2"/>
106
+ <testCase name="addIDInfo 10 - should add data-element-id with valid id &quot;dataunitFinanceiro_meuIDTeste_br.com.sankhya.fin.cad.movimentacaoFinanceira&quot;" duration="2"/>
107
+ <testCase name="addIDInfo 11 - should add data-element-id with valid id &quot;dataunitFinanceiro_meuIDTeste_movimentacaoFinanceira&quot;" duration="2"/>
108
+ <testCase name="addIDInfo 12 - should add data-element-id with valid id &quot;dataunitFinanceiro_movFinanceira_movimentacaoFinanceira&quot;" duration="1"/>
109
+ <testCase name="addIDInfo 13 - should add data-element-id with valid id &quot;dataunitFinanceiro_meuIDTeste_movimentacaoFinanceira&quot;" duration="2"/>
110
+ <testCase name="addIDInfo 14 - should add data-element-id with valid id &quot;dataunitFinanceiro_meuIdTeste_movimentacaoFinanceira&quot;" duration="65"/>
111
+ <testCase name="addIDInfo 15 - should add data-element-id with valid id &quot;dataunitFinanceiro_meuIdTeste_snkApplication&quot;" duration="1"/>
112
+ <testCase name="addIDInfo 16 - should add data-element-id with valid id &quot;dataunitFinanceiro_meuIdTeste_snkApplication&quot;" duration="10"/>
113
+ <testCase name="addIDInfo 17 - should add data-element-id with valid id &quot;movFinanceira_movimentacaoFinanceira&quot;" duration="1"/>
114
+ <testCase name="addIDInfo 18 - should add data-element-id with valid id &quot;movFinanceira_movimentacaoFinanceira&quot;" duration="1"/>
115
+ <testCase name="addIDInfo 19 - should add data-element-id with valid id &quot;movFinanceira_movimentacaoFinanceira&quot;" duration="0"/>
116
+ <testCase name="addIDInfo 20 - should add data-element-id with valid id &quot;movFinanceira_movimentacaoFinanceira&quot;" duration="1"/>
117
+ <testCase name="addIDInfo 21 - should add data-element-id with valid id &quot;movFinanceira_movimentacaoFinanceira&quot;" duration="1"/>
118
+ <testCase name="addIDInfo 22 - should add data-element-id with valid id &quot;bancoObrigatorio_movimentacaoFinanceira&quot;" duration="1"/>
119
+ </file>
120
+ <file path="/builds/dti/design-system/sankhyacore/test/dataunit/formatting/PrettyFormatter.spec.ts">
121
+ <testCase name="getFormattedValue should return empty string when value is null" duration="5"/>
122
+ <testCase name="getFormattedValue should return empty string when value is not an array" duration="0"/>
123
+ <testCase name="getFormattedValue should return empty string when value is an empty array" duration="0"/>
124
+ <testCase name="getFormattedValue should return file name when value is an array with one file object" duration="0"/>
125
+ <testCase name="getFormattedValue should return file count when value is an array with multiple file objects" duration="0"/>
126
+ <testCase name="getFormattedValue should return empty string for undefined file" duration="1"/>
127
+ <testCase name="getFormattedValue should handle OBJECT type with value field" duration="0"/>
128
+ <testCase name="getFormattedValue should return empty string when value is undefined" duration="1"/>
129
+ <testCase name="getFormattedValue should return value as string when value is not an object" duration="0"/>
130
+ <testCase name="getFormattedValue should return value.toString() when value is an object without value property" duration="0"/>
131
+ <testCase name="getFormattedValue should handle BOOLEAN type" duration="1"/>
132
+ <testCase name="getFormattedValue should format numbers correctly" duration="14"/>
133
+ <testCase name="getFormattedValue should format dates correctly" duration="3"/>
134
+ <testCase name="getFormattedValue should format times correctly" duration="1"/>
135
+ <testCase name="getFormattedValue should format datetime correctly" duration="1"/>
136
+ <testCase name="getFormattedValue should call toString with correct parameters" duration="0"/>
137
+ <testCase name="getFormattedValue should handle undefined descriptor gracefully" duration="0"/>
138
+ <testCase name="getFormattedValue should format value correctly with OPTIONSELECTOR and matching option" duration="0"/>
139
+ <testCase name="getFormattedValue should return value with OPTIONSELECTOR and no matching option" duration="16"/>
140
+ <testCase name="getFormattedValue should format value correctly with OPTIONSELECTOR and value as object" duration="1"/>
141
+ <testCase name="getFormattedValue should return empty string with OPTIONSELECTOR and value as null" duration="0"/>
142
+ <testCase name="getFormattedValue should format value correctly with OPTIONSELECTOR and options as JSON string" duration="0"/>
143
+ <testCase name="getFormattedValue should return value with OPTIONSELECTOR and options as empty array" duration="0"/>
144
+ <testCase name="getFormattedValue should format masked values correctly" duration="2"/>
145
+ </file>
146
+ <file path="/builds/dti/design-system/sankhyacore/test/util/ElementUtils.spec.ts">
147
+ <testCase name="calcMarginSize should calculate correctly the size of horizontal margin" duration="35"/>
148
+ <testCase name="calcMarginSize should calculate correctly the size of vertical margin" duration="2"/>
149
+ <testCase name="calcMarginSize should threat values defined as zero" duration="20"/>
150
+ </file>
151
+ </unitTest>
package/setupTests.js ADDED
@@ -0,0 +1,7 @@
1
+ global.ResizeObserver = require('resize-observer-polyfill');
2
+
3
+ if (!Object.hasOwn) {
4
+ Object.hasOwn = function (obj, prop) {
5
+ return Object.prototype.hasOwnProperty.call(obj, prop);
6
+ };
7
+ }
@@ -1,7 +1,10 @@
1
1
  sonar.testExecutionReportPaths=./reports/test-report.xml
2
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=.
3
+ sonar.test.inclusions=coverage/**,**/test/*.e2e.ts,**/test/*.spec.ts,**/test/*.spec.tsx,**/utils/*.spec.ts,**/test/**/*.ts
4
+ sonar.tests=test
5
+ sonar.sourceEncoding=UTF-8
5
6
  sonar.c.file.suffixes=-
6
7
  sonar.cpp.file.suffixes=-
7
- sonar.objc.file.suffixes=-
8
+ sonar.objc.file.suffixes=-
9
+ sonar.qualitygate.wait=true
10
+ sonar.host.url=http://sonarqube.sankhya.com.br
@@ -37,17 +37,18 @@ export default class DataUnit {
37
37
 
38
38
  private _uuid: string;
39
39
  private _name: string;
40
- private _observers: Array<(action: DataUnitAction) => void>;
40
+ private _observers: Array<(action: DataUnitAction, options?:DataUnitEventOptions) => void>;
41
41
  private _sortingProvider?: SortingProvider;
42
42
  private _filterProviders: Map<string, FilterProvider>;
43
43
  private _stateManager: StateManager;
44
- private _interceptors: Array<DUActionInterceptor>;
44
+ private _interceptors: Map<string, DUActionInterceptor>;
45
45
  private _pageSize: number;
46
46
  private _childByName = new Map<string, DataUnit>();
47
47
  private _parentDataUnit: DataUnit | undefined;
48
48
  private _loadingLockers: Promise<void>[];
49
49
  private _savingLockers: Promise<any>[] = [];
50
50
  private _defaultSorting: Array<Sort>;
51
+ private _allowReleaseCallbacks: boolean;
51
52
 
52
53
  public metadataLoader?: (dataUnit: DataUnit) => Promise<UnitMetadata>;
53
54
  public dataLoader?: (dataUnit: DataUnit, request: LoadDataRequest) => Promise<LoadDataResponse>;
@@ -79,7 +80,8 @@ export default class DataUnit {
79
80
  this._filterProviders = new Map<string, FilterProvider>();
80
81
  this._sortingProvider = undefined;
81
82
  this._defaultSorting = [];
82
- this._interceptors = [];
83
+ this._allowReleaseCallbacks = true;
84
+ this._interceptors = new Map();
83
85
  this._parentDataUnit = parentDataUnit;
84
86
  this._parentDataUnit?.subscribe(this.onDataUnitParentEvent);
85
87
  this._loadingLockers = [];
@@ -110,10 +112,12 @@ export default class DataUnit {
110
112
  * - Sorting Providers
111
113
  */
112
114
  public releaseCallbacks(){
115
+ if(!this._allowReleaseCallbacks) return;
116
+
113
117
  this._observers = [];
114
118
  this._filterProviders = new Map<string, FilterProvider>();
115
119
  this._sortingProvider = undefined;
116
- this._interceptors = [];
120
+ this._interceptors = new Map();
117
121
  }
118
122
 
119
123
  /**
@@ -180,6 +184,8 @@ export default class DataUnit {
180
184
  case Action.NEXT_SELECTED:
181
185
  case Action.PREVIOUS_SELECTED:
182
186
  case Action.DATA_LOADED:
187
+ case Action.RECORDS_ADDED:
188
+ case Action.EDITION_CANCELED:
183
189
  this.clearDataUnit();
184
190
  const selectedRecord = this._parentDataUnit?.getSelectedRecord();
185
191
  if(selectedRecord != undefined && !this.isNewRecord(selectedRecord.__record__id__)){
@@ -241,10 +247,10 @@ export default class DataUnit {
241
247
  async response => {
242
248
  await this.dispatchAction(
243
249
  Action.DATA_LOADED,
244
- {...response, keepSelection: request.keepSelection, filters: request.filters},
250
+ {...response, keepSelection: request.keepSelection, filters: request.filters, selectFirstRecord},
245
251
  executionCtx
246
252
  );
247
-
253
+
248
254
  await this.dispatchAction(Action.LOADING_PROPERTIES_CLEANED);
249
255
 
250
256
  if(selectFirstRecord){
@@ -317,13 +323,16 @@ export default class DataUnit {
317
323
 
318
324
  await this.processLoadingLockers();
319
325
 
320
- if (this._parentDataUnit && !this._parentDataUnit.getSelectedRecord()) {
326
+ if (this._parentDataUnit) {
327
+ const parentRecord = this._parentDataUnit.getSelectedRecord();
328
+ if(parentRecord == undefined || this._parentDataUnit.isNewRecord(parentRecord.__record__id__)){
321
329
  if(this.records){
322
330
  this.clearDataUnit();
323
331
  }
324
332
  return Promise.resolve({
325
333
  records: []
326
334
  });
335
+ }
327
336
  }
328
337
 
329
338
  const loadDataRequest = this.getLoadDataRequest(quickFilter, source);
@@ -336,7 +345,7 @@ export default class DataUnit {
336
345
  *
337
346
  * @param page - Número da página desejada.
338
347
  * @param executionCtx - Contexto de execução do carregamento dos registros do DataUnit.
339
- *
348
+ *
340
349
  * @returns - Registros da página desejada.
341
350
  *
342
351
  */
@@ -643,15 +652,14 @@ export default class DataUnit {
643
652
  *
644
653
  */
645
654
  public getFormattedValue(fieldName: string, value?: any): string {
646
-
647
655
  const descriptor = this.getField(fieldName);
648
- if (value == undefined) {
656
+ if (value === undefined) {
649
657
  value = this.getFieldValue(fieldName);
650
658
  } else if (typeof value === "string" && descriptor?.dataType != DataType.TEXT){
651
659
  value = this.valueFromString(fieldName, value);
652
660
  }
653
661
 
654
- if(value == undefined){
662
+ if(value === undefined){
655
663
  return "";
656
664
  }
657
665
 
@@ -666,7 +674,7 @@ export default class DataUnit {
666
674
  *
667
675
  */
668
676
  public addInterceptor(interceptor: DUActionInterceptor): void {
669
- this._interceptors.push(interceptor);
677
+ this._interceptors.set(interceptor.interceptAction.toString(), interceptor);
670
678
  }
671
679
 
672
680
  /**
@@ -677,7 +685,7 @@ export default class DataUnit {
677
685
  *
678
686
  */
679
687
  public removeInterceptor(interceptor: DUActionInterceptor) {
680
- this._interceptors = this._interceptors.filter(i => i !== interceptor);
688
+ this._interceptors.delete(interceptor.interceptAction.toString())
681
689
  }
682
690
 
683
691
  /**
@@ -949,7 +957,7 @@ export default class DataUnit {
949
957
  * @returns - Promise que será resolvida quando o novo valor for persistido no state.
950
958
  *
951
959
  */
952
- public async setFieldValue(fieldName: string, newValue: any, records?: Array<string>): Promise<boolean> {
960
+ public async setFieldValue(fieldName: string, newValue: any, records?: Array<string>, options?:DataUnitEventOptions): Promise<boolean> {
953
961
 
954
962
  if(!this.hasNewRecord() && !this.getSelectedRecord()) await this.addRecord();
955
963
 
@@ -968,7 +976,7 @@ export default class DataUnit {
968
976
  }
969
977
 
970
978
  if (currentValue !== typedValue) {
971
- const promise = this.dispatchAction(Action.DATA_CHANGED, { [fieldName]: typedValue, records }, undefined);
979
+ const promise = this.dispatchAction(Action.DATA_CHANGED, { [fieldName]: typedValue, records }, undefined, options);
972
980
  this._savingLockers.push(promise);
973
981
  return promise;
974
982
  }
@@ -1435,17 +1443,17 @@ export default class DataUnit {
1435
1443
  * @returns - Verdadeiro se ação iniciada.
1436
1444
  *
1437
1445
  */
1438
- private async dispatchAction(actionType: Action, payload?: any, executionCtx?: ExecutionContext): Promise<boolean> {
1446
+ private async dispatchAction(actionType: Action, payload?: any, executionCtx?: ExecutionContext, options?:DataUnitEventOptions): Promise<boolean> {
1439
1447
  return new Promise(async resolve => {
1440
1448
  let action = new DataUnitAction(actionType, payload);
1441
1449
  if (executionCtx && executionCtx.before) {
1442
1450
  action = executionCtx.before(action);
1443
1451
  }
1444
- if (action && this._interceptors && this._interceptors.length > 0) {
1452
+ if (action && this._interceptors && this._interceptors.size > 0) {
1445
1453
  action = await this.intercept(action, this._interceptors.values());
1446
1454
  }
1447
1455
  if (action) {
1448
- this.doDispatchAction(action);
1456
+ this.doDispatchAction(action, options);
1449
1457
  if (executionCtx && executionCtx.after) {
1450
1458
  executionCtx.after(action)
1451
1459
  }
@@ -1483,7 +1491,7 @@ export default class DataUnit {
1483
1491
  * @param action - Ações em execução no DataUnit.
1484
1492
  *
1485
1493
  */
1486
- private doDispatchAction(action: DataUnitAction): void {
1494
+ private doDispatchAction(action: DataUnitAction, options:DataUnitEventOptions = {}): void {
1487
1495
  this._stateManager.process(action);
1488
1496
  this?._parentDataUnit?.dispatchAction(Action.CHILD_CHANGED, { srcAction: action, srcDataUnit: this });
1489
1497
  this._observers.forEach(f => {
@@ -1492,7 +1500,7 @@ export default class DataUnit {
1492
1500
  should be continued
1493
1501
  */
1494
1502
  try {
1495
- f(action);
1503
+ f(action, options);
1496
1504
  } catch (e) {
1497
1505
  console.warn("[DataUnit] error while call observer", e);
1498
1506
  }
@@ -1531,7 +1539,7 @@ export default class DataUnit {
1531
1539
  * @param observer - Função que recebe como parâmetro as ações que serão monitoradas.
1532
1540
  *
1533
1541
  */
1534
- public subscribe(observer: (action: DataUnitAction) => void) {
1542
+ public subscribe(observer: (action: DataUnitAction, options?:DataUnitEventOptions) => void | Promise<void>) {
1535
1543
  this._observers.push(observer);
1536
1544
  }
1537
1545
 
@@ -1765,6 +1773,10 @@ export default class DataUnit {
1765
1773
  return loadingLockerResolver || Promise.resolve;
1766
1774
  }
1767
1775
 
1776
+ public set allowReleaseCallbacks(allow: boolean){
1777
+ this._allowReleaseCallbacks = allow;
1778
+ }
1779
+
1768
1780
  private async processLoadingLockers(){
1769
1781
  if(this._loadingLockers.length) {
1770
1782
  await Promise.all(this._loadingLockers);
@@ -1952,3 +1964,5 @@ export class SelectionInfo{
1952
1964
  return this.length === 0;
1953
1965
  }
1954
1966
  }
1967
+
1968
+ export type DataUnitEventOptions = {[key:string]: any};
@@ -10,10 +10,10 @@ export const getFormattedValue = (value: any, descriptor?: FieldDescriptor) => {
10
10
  }
11
11
 
12
12
  if(descriptor?.dataType === DataType.OBJECT){
13
- if(Object.hasOwn(value, "value")){
13
+ if(value && Object.hasOwn(value, "value")){
14
14
  return getSearchFormat(value, descriptor);
15
15
  }
16
- return value == 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
  }
@@ -84,7 +85,7 @@ const getOptionFormat = (value: any, descriptor: FieldDescriptor) => {
84
85
  }
85
86
  }
86
87
 
87
- if(typeof value === "object"){
88
+ if(value && typeof value === "object" ){
88
89
  value = value.value
89
90
  }
90
91
 
@@ -92,7 +93,7 @@ const getOptionFormat = (value: any, descriptor: FieldDescriptor) => {
92
93
  return options[value];
93
94
  }
94
95
 
95
- return value;
96
+ return value ?? "";
96
97
  }
97
98
 
98
99
 
@@ -103,7 +104,7 @@ const getMask = (value: string, descriptor: FieldDescriptor | undefined): string
103
104
  }
104
105
 
105
106
  const mask = descriptor.properties?.mask;
106
- if(mask == undefined){
107
+ if(mask == undefined || !value){
107
108
  return;
108
109
  }
109
110
 
@@ -119,6 +119,9 @@ export const toString = ( dataType: DataType|undefined, value: any): string => {
119
119
  } else if (dataType === DataType.DATE) {
120
120
  if (typeof value === "string") {
121
121
  value = DateUtils.strToDate(value);
122
+ if (value == undefined) {
123
+ return value;
124
+ }
122
125
  }
123
126
  return DateUtils.formatRfc3339(value as Date);
124
127
  } else {
@@ -68,7 +68,7 @@ class SelectionReducerImpl implements ActionReducer {
68
68
  if(currentState?.lastSelection){
69
69
  return { currentSelection: currentState.lastSelection };
70
70
  }
71
- return { currentSelection: [] }
71
+ return { currentSelection: currentState?.currentSelection || [] }
72
72
  }
73
73
 
74
74
  return currentState;
package/src/index.ts CHANGED
@@ -9,7 +9,7 @@ import { HttpProvider } from "./http/HttpProvider.js";
9
9
  import { SkwHttpProvider } from "./http/SkwHttpProvider.js";
10
10
  import { RequestMetadata } from "./http/RequestMetadata.js";
11
11
  import { AuthorizedServiceCaller } from "./http/AuthorizedServiceCaller.js";
12
- import DataUnit, {SavedRecord, Record, Change, ChangeOperation, DUActionInterceptor, WaitingChange, PageRequest, QuickFilter, SelectionMode, SelectionInfo} from "./dataunit/DataUnit.js";
12
+ import DataUnit, {SavedRecord, Record, Change, ChangeOperation, DUActionInterceptor, WaitingChange, PageRequest, QuickFilter, SelectionMode, SelectionInfo, DataUnitEventOptions} from "./dataunit/DataUnit.js";
13
13
  import { DataType } from "./dataunit/metadata/DataType.js";
14
14
  import { UnitMetadata, FieldDescriptor, UserInterface, Sort, SortMode, SortingProvider, Filter, DependencyType, ChildDescriptor, ChildLink } from "./dataunit/metadata/UnitMetadata.js";
15
15
  import { DataUnitAction, Action, ExecutionContext } from "./dataunit/state/action/DataUnitAction.js";
@@ -39,7 +39,7 @@ 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
41
  import { SearchUtils } from "./utils/SearchUtils.js";
42
- import OverflowWatcher, { OnOverflowCallBack, OverflowDirection } from "./utils/OverflowWatcher/index.js";
42
+ import OverflowWatcher, { OnOverflowCallBack, OverflowDirection, OverFlowWatcherParams, OVERFLOWED_CLASS_NAME } from "./utils/OverflowWatcher/index.js";
43
43
 
44
44
  /*Classes públicas no pacote*/
45
45
  export {
@@ -109,5 +109,8 @@ export {
109
109
  SearchUtils,
110
110
  OverflowWatcher,
111
111
  OnOverflowCallBack,
112
- OverflowDirection
112
+ OverflowDirection,
113
+ OverFlowWatcherParams,
114
+ OVERFLOWED_CLASS_NAME,
115
+ DataUnitEventOptions
113
116
  };
@@ -0,0 +1,10 @@
1
+ import { OverflowDirection } from './OverflowWatcher/types/overflow-direction.js';
2
+
3
+ export function calcMarginSize(el:Element, scrollDirection: OverflowDirection){
4
+ const computedStyle = getComputedStyle(el);
5
+ if(OverflowDirection.HORIZONTAL === scrollDirection){
6
+ return (parseInt(computedStyle.marginLeft || '0') + parseInt(computedStyle.marginRight || '0'));
7
+ }
8
+
9
+ return (parseInt(computedStyle.marginTop || '0') + parseInt(computedStyle.marginBottom || '0'));
10
+ }
@@ -84,4 +84,24 @@ export default class ObjectUtils{
84
84
  public static equals(obj1: any, obj2: any): any {
85
85
  return ObjectUtils.objectToString(obj1) === ObjectUtils.objectToString(obj2);
86
86
  }
87
+
88
+ /**
89
+ * Verifica se o objeto está vazio (sem atributos).
90
+ *
91
+ * @param obj - Objeto a ser verificado.
92
+ * @returns - True caso o objeto esteja vazio.
93
+ */
94
+ public static isEmpty(obj: object): boolean{
95
+ return Object.keys(obj).length === 0 && obj.constructor === Object;
96
+ }
97
+
98
+ /**
99
+ * Verifica se o objeto NÃO está vazio (sem atributos).
100
+ *
101
+ * @param obj - Objeto a ser verificado.
102
+ * @returns - True caso o objeto NÃO esteja vazio
103
+ */
104
+ public static isNotEmpty(obj: object): boolean{
105
+ return !this.isEmpty(obj);
106
+ }
87
107
  }