@sankhyalabs/ezui 1.1.104 → 1.1.107

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 (60) hide show
  1. package/dist/cjs/{AssetsUtils-69356e76.js → AssetsUtils-697927e8.js} +52 -52
  2. package/dist/cjs/{FloatingManager-6cfeb947.js → FloatingManager-751368a8.js} +121 -121
  3. package/dist/cjs/{UnitMetadata-4b90ead3.js → UnitMetadata-de809a4b.js} +1305 -1305
  4. package/dist/cjs/ez-calendar_16.cjs.entry.js +89 -75
  5. package/dist/cjs/ez-dialog.cjs.entry.js +1 -1
  6. package/dist/cjs/ez-grid.cjs.entry.js +20 -2
  7. package/dist/cjs/ez-modal_2.cjs.entry.js +2 -2
  8. package/dist/cjs/ez-popover.cjs.entry.js +2 -2
  9. package/dist/cjs/ez-toast.cjs.entry.js +8 -4
  10. package/dist/cjs/ezui.cjs.js +1 -1
  11. package/dist/cjs/loader.cjs.js +1 -1
  12. package/dist/collection/components/ez-check/ez-check.js +3 -0
  13. package/dist/collection/components/ez-dialog/ez-dialog.css +1 -1
  14. package/dist/collection/components/ez-form/ez-form.js +8 -1
  15. package/dist/collection/components/ez-form/fieldbuilder/tpl/CheckBox.tpl.js +1 -1
  16. package/dist/collection/components/ez-form/fieldbuilder/tpl/ComboBox.tpl.js +1 -1
  17. package/dist/collection/components/ez-form/fieldbuilder/tpl/DateInput.tpl.js +3 -3
  18. package/dist/collection/components/ez-form/fieldbuilder/tpl/FileInput.tpl.js +1 -1
  19. package/dist/collection/components/ez-form/fieldbuilder/tpl/NumberInput.tpl.js +1 -1
  20. package/dist/collection/components/ez-form/fieldbuilder/tpl/SearchInput.tpl.js +1 -1
  21. package/dist/collection/components/ez-form/fieldbuilder/tpl/TextArea.tpl.js +1 -1
  22. package/dist/collection/components/ez-form/fieldbuilder/tpl/TextInput.tpl.js +1 -1
  23. package/dist/collection/components/ez-form/structure/FormSheet.js +2 -1
  24. package/dist/collection/components/ez-grid/controller/ag-grid/AgGridController.js +20 -2
  25. package/dist/collection/components/ez-text-area/ez-text-area.css +1 -1
  26. package/dist/collection/components/ez-text-area/ez-text-area.js +1 -1
  27. package/dist/collection/components/ez-text-input/ez-text-input.css +1 -2
  28. package/dist/collection/components/ez-toast/ez-toast.css +8 -2
  29. package/dist/collection/components/ez-toast/ez-toast.js +27 -8
  30. package/dist/collection/utils/ApplicationUtils.js +6 -1
  31. package/dist/custom-elements/index.js +1624 -1588
  32. package/dist/esm/{AssetsUtils-0e207bec.js → AssetsUtils-f75711ac.js} +52 -52
  33. package/dist/esm/{FloatingManager-bb90ef41.js → FloatingManager-ee1f7fdf.js} +121 -121
  34. package/dist/esm/{UnitMetadata-8951d803.js → UnitMetadata-d300ae38.js} +1305 -1305
  35. package/dist/esm/ez-calendar_16.entry.js +89 -75
  36. package/dist/esm/ez-dialog.entry.js +1 -1
  37. package/dist/esm/ez-grid.entry.js +20 -2
  38. package/dist/esm/ez-modal_2.entry.js +2 -2
  39. package/dist/esm/ez-popover.entry.js +2 -2
  40. package/dist/esm/ez-toast.entry.js +8 -4
  41. package/dist/esm/ezui.js +1 -1
  42. package/dist/esm/loader.js +1 -1
  43. package/dist/ezui/ezui.esm.js +1 -1
  44. package/dist/ezui/{p-e06e47f1.entry.js → p-24ff7d92.entry.js} +1 -1
  45. package/dist/ezui/{p-18c00d88.entry.js → p-3e6fa4ca.entry.js} +1 -1
  46. package/dist/ezui/{p-ec7c1b86.js → p-47cf74f0.js} +0 -0
  47. package/dist/ezui/p-780fbe22.entry.js +1 -0
  48. package/dist/ezui/p-81fc41a5.js +1 -0
  49. package/dist/ezui/p-9ea5b22e.entry.js +1 -0
  50. package/dist/ezui/{p-ddd0ef12.js → p-b05feb1f.js} +0 -0
  51. package/dist/ezui/{p-7294c815.entry.js → p-c451d6e6.entry.js} +1 -1
  52. package/dist/ezui/{p-da0f5393.entry.js → p-db1797d7.entry.js} +26 -26
  53. package/dist/types/components/ez-form/ez-form.d.ts +1 -0
  54. package/dist/types/components/ez-toast/ez-toast.d.ts +4 -0
  55. package/dist/types/components.d.ts +8 -0
  56. package/dist/types/utils/ApplicationUtils.d.ts +5 -1
  57. package/package.json +1 -1
  58. package/dist/ezui/p-2259c926.entry.js +0 -1
  59. package/dist/ezui/p-b217f40b.entry.js +0 -1
  60. package/dist/ezui/p-c6760545.js +0 -1
@@ -1,1342 +1,1342 @@
1
1
  'use strict';
2
2
 
3
- const NUMBERINPUTS_REGEX_SCIENTIFIC_PARTS = /^([+-])?(\d+).?(\d*)[eE]([-+]?\d+)$/;
4
- /**
5
- * `NumberUtils` é uma biblioteca para manipulação de números
6
- *
7
- * `Métodos`:
8
- *
9
- * @stringToNumber: converte um número em formato de string em um valor numérico nativo do javascript
10
- * @format: arredonda um número em formato de string baseado nos parâmetros "presision" e "prettyPrecision";
11
- */
12
- class NumberUtils {
13
- }
14
- /**
15
- * @stringToNumber: converte um numero em formato de string em numero
16
- *
17
- * @param value numero em formato de string a ser convertido (Importante: formato PT-BR ou já em formato numérico: ######.##)
18
- *
19
- * @returns string based number
20
- *
21
- * @Exemples
22
- * @"100,12" | 100.12
23
- * @"100.12" | 100.12
24
- * @"-100,12" | -100.12
25
- * @"R$100,12" | 100.12
26
- * @"-R$100,12" | -100.12
27
- * @"string" | NaN
28
- */
29
- NumberUtils.stringToNumber = (value) => {
30
- if (value === '' || value === null || value === undefined) {
31
- return NaN;
32
- }
33
- if (value) {
34
- value = value.toString();
35
- var negative = (value.charAt(0) === '-');
36
- if (!NUMBERINPUTS_REGEX_SCIENTIFIC_PARTS.test(value)) {
37
- value = value.replace(/[^\d.,]/g, '');
38
- }
39
- else {
40
- value = value.replace(/^-/g, '');
41
- }
42
- //In case of simple string such as: "@@@@@@@"
43
- if (value === '') {
44
- return Number(NaN);
45
- }
46
- var indexV = value.indexOf(',');
47
- var indexP = value.indexOf('.');
48
- if (indexP > indexV) {
49
- value = value.replace(',', '');
50
- }
51
- else if (indexP < indexV) {
52
- value = value.replace(/\./g, '@').replace(',', '.').replace(/@/g, '');
53
- }
54
- if (negative) {
55
- value = '-' + value;
56
- }
57
- }
58
- return Number(value);
59
- };
60
- /**
61
- * @format: converte um numero em formato de string em um numero em formato de string formatado de acordo com os parametros de "precision" e "prettyPrecision"
62
- *
63
- * @param value numero em formato de string a ser convertido (Importante: formato PT-BR ou já em formato numérico<sem separadors de milhares>: ######.##)
64
- * @param precision (numero de decimais)
65
- * @param prettyPrecision (numero de zeros nos decimais)
66
- *
67
- * @returns numero em formato de string formatado em PT-BR
68
- */
69
- NumberUtils.format = (value, precision, prettyPrecision = NaN) => {
70
- if (value === '' || value === undefined || value === "NaN") {
71
- return NaN.toString();
72
- }
73
- let newValue = NumberUtils.stringToNumber(value);
74
- if (newValue === NaN) {
75
- return NaN.toString();
76
- }
77
- //Validation "precision":
78
- // Case1: precision < 0 => does not use precision
79
- // Case2: presicion not int => does not use precision
80
- if (precision < 0 || Math.abs(Math.round(precision * 1) / 1) !== precision) {
81
- //Once stringToNumber returns number format, we need to change to pt-br
82
- return NumberUtils.changeFormat(newValue.toString());
83
- }
84
- //Validation "prettyPrecision"
85
- let prettyPrecisionInternal = 0;
86
- // Case1: prettyPrecision < 0 => prettyPrecision does not change de format that means: prettyPrecisionInternal = precision;
87
- // Case2: prettyPrecision not int => prettyPrecision does not change de format that means: prettyPrecisionInternal = precision;
88
- if (prettyPrecision === NaN || Math.abs(Math.round(prettyPrecision * 1) / 1) !== prettyPrecision) {
89
- prettyPrecisionInternal = precision;
90
- }
91
- else {
92
- prettyPrecisionInternal = prettyPrecision;
93
- }
94
- let newValueStr;
95
- newValueStr = (Math.round(newValue * Math.pow(10, precision)) / Math.pow(10, precision)).toLocaleString('pt-br', { minimumFractionDigits: precision });
96
- //prettyPrecision
97
- const varSettingPP = precision - prettyPrecisionInternal;
98
- if (varSettingPP > 0) {
99
- for (let i = 0; i < varSettingPP; i++) {
100
- if (newValueStr.substring(newValueStr.length - 1) == "0" && precision > 0) {
101
- newValueStr = newValueStr.substring(0, newValueStr.length - 1);
102
- }
103
- }
104
- }
105
- //in Case "." or "," in the end of the string
106
- if (newValueStr.substring(newValueStr.length - 1) == "." || newValueStr.substring(newValueStr.length - 1) == ",") {
107
- newValueStr = newValueStr.substring(0, newValueStr.length - 1);
108
- }
109
- return newValueStr;
110
- };
111
- /**
112
- * @keepOnlyDecimalSeparator: retira os separadores de milhar de um número em formato de string
113
- *
114
- * @param value numero em formato de string a ser convertido
115
- * @param formatnumber (formatação de ENTRADA e SAÍDA do utilitário: pt-BR="###.###,##" en-US="###,###.##"; Default: "pt-BR")
116
- *
117
- * @returns numero em formato de string formatado apenas com separador decimal
118
- */
119
- NumberUtils.keepOnlyDecimalSeparator = (value, formatnumber = 'pt-BR') => {
120
- //Formatting formatnumber to be able to get lowercases
121
- formatnumber = formatnumber.toUpperCase();
122
- //Formatting value following formatnumber parameter
123
- //keep only decimal character in order to correct format the string
124
- //This transformation is due the "stringtoNumber" method is a general method that tries to convert all formated strings
125
- if (formatnumber === 'EN-US') {
126
- value = value.replace(/\,/g, '');
127
- }
128
- else {
129
- value = value.replace(/\./g, '');
130
- }
131
- return value;
132
- };
133
- /**
134
- * @changeFormat: troca o formato do numero string de "PT-BR" para "EN-US" e vice-versa
135
- *
136
- * @param value numero em formato de string a ser convertido
137
- *
138
- * @returns numero em formato de string formatado de "PT-BR" para "EN-US" e vice-versa
139
- */
140
- NumberUtils.changeFormat = (value) => {
141
- //Formatting output following formatnumber
142
- return value.replace(/\./g, '_').replace(/\,/g, '.').replace(/\_/g, ',');
3
+ const NUMBERINPUTS_REGEX_SCIENTIFIC_PARTS = /^([+-])?(\d+).?(\d*)[eE]([-+]?\d+)$/;
4
+ /**
5
+ * `NumberUtils` é uma biblioteca para manipulação de números
6
+ *
7
+ * `Métodos`:
8
+ *
9
+ * @stringToNumber: converte um número em formato de string em um valor numérico nativo do javascript
10
+ * @format: arredonda um número em formato de string baseado nos parâmetros "presision" e "prettyPrecision";
11
+ */
12
+ class NumberUtils {
13
+ }
14
+ /**
15
+ * @stringToNumber: converte um numero em formato de string em numero
16
+ *
17
+ * @param value numero em formato de string a ser convertido (Importante: formato PT-BR ou já em formato numérico: ######.##)
18
+ *
19
+ * @returns string based number
20
+ *
21
+ * @Exemples
22
+ * @"100,12" | 100.12
23
+ * @"100.12" | 100.12
24
+ * @"-100,12" | -100.12
25
+ * @"R$100,12" | 100.12
26
+ * @"-R$100,12" | -100.12
27
+ * @"string" | NaN
28
+ */
29
+ NumberUtils.stringToNumber = (value) => {
30
+ if (value === '' || value === null || value === undefined) {
31
+ return NaN;
32
+ }
33
+ if (value) {
34
+ value = value.toString();
35
+ const negative = (value.charAt(0) === '-');
36
+ if (!NUMBERINPUTS_REGEX_SCIENTIFIC_PARTS.test(value)) {
37
+ value = value.replace(/[^\d.,]/g, '');
38
+ }
39
+ else {
40
+ value = value.replace(/^-/g, '');
41
+ }
42
+ //In case of simple string such as: "@@@@@@@"
43
+ if (value === '') {
44
+ return Number(NaN);
45
+ }
46
+ const indexV = value.indexOf(',');
47
+ const indexP = value.indexOf('.');
48
+ if (indexP > indexV) {
49
+ value = value.replace(',', '');
50
+ }
51
+ else if (indexP < indexV) {
52
+ value = value.replace(/\./g, '@').replace(',', '.').replace(/@/g, '');
53
+ }
54
+ if (negative) {
55
+ value = '-' + value;
56
+ }
57
+ }
58
+ return Number(value);
59
+ };
60
+ /**
61
+ * @format: converte um numero em formato de string em um numero em formato de string formatado de acordo com os parametros de "precision" e "prettyPrecision"
62
+ *
63
+ * @param value numero em formato de string a ser convertido (Importante: formato PT-BR ou já em formato numérico<sem separadors de milhares>: ######.##)
64
+ * @param precision (numero de decimais)
65
+ * @param prettyPrecision (numero de zeros nos decimais)
66
+ *
67
+ * @returns numero em formato de string formatado em PT-BR
68
+ */
69
+ NumberUtils.format = (value, precision, prettyPrecision = NaN) => {
70
+ if (value === '' || value === undefined || value === "NaN") {
71
+ return NaN.toString();
72
+ }
73
+ const newValue = NumberUtils.stringToNumber(value);
74
+ if (isNaN(newValue)) {
75
+ return NaN.toString();
76
+ }
77
+ //Validation "precision":
78
+ // Case1: precision < 0 => does not use precision
79
+ // Case2: presicion not int => does not use precision
80
+ if (precision < 0 || Math.abs(Math.round(precision * 1) / 1) !== precision) {
81
+ //Once stringToNumber returns number format, we need to change to pt-br
82
+ return NumberUtils.changeFormat(newValue.toString());
83
+ }
84
+ //Validation "prettyPrecision"
85
+ let prettyPrecisionInternal = 0;
86
+ // Case1: prettyPrecision < 0 => prettyPrecision does not change de format that means: prettyPrecisionInternal = precision;
87
+ // Case2: prettyPrecision not int => prettyPrecision does not change de format that means: prettyPrecisionInternal = precision;
88
+ if (isNaN(prettyPrecision) || Math.abs(Math.round(prettyPrecision * 1) / 1) !== prettyPrecision) {
89
+ prettyPrecisionInternal = precision;
90
+ }
91
+ else {
92
+ prettyPrecisionInternal = prettyPrecision;
93
+ }
94
+ let newValueStr;
95
+ newValueStr = (Math.round(newValue * Math.pow(10, precision)) / Math.pow(10, precision)).toLocaleString('pt-br', { minimumFractionDigits: precision });
96
+ //prettyPrecision
97
+ const varSettingPP = precision - prettyPrecisionInternal;
98
+ if (varSettingPP > 0) {
99
+ for (let i = 0; i < varSettingPP; i++) {
100
+ if (newValueStr.substring(newValueStr.length - 1) == "0" && precision > 0) {
101
+ newValueStr = newValueStr.substring(0, newValueStr.length - 1);
102
+ }
103
+ }
104
+ }
105
+ //in Case "." or "," in the end of the string
106
+ if (newValueStr.substring(newValueStr.length - 1) == "." || newValueStr.substring(newValueStr.length - 1) == ",") {
107
+ newValueStr = newValueStr.substring(0, newValueStr.length - 1);
108
+ }
109
+ return newValueStr;
110
+ };
111
+ /**
112
+ * @keepOnlyDecimalSeparator: retira os separadores de milhar de um número em formato de string
113
+ *
114
+ * @param value numero em formato de string a ser convertido
115
+ * @param formatnumber (formatação de ENTRADA e SAÍDA do utilitário: pt-BR="###.###,##" en-US="###,###.##"; Default: "pt-BR")
116
+ *
117
+ * @returns numero em formato de string formatado apenas com separador decimal
118
+ */
119
+ NumberUtils.keepOnlyDecimalSeparator = (value, formatnumber = 'pt-BR') => {
120
+ //Formatting formatnumber to be able to get lowercases
121
+ formatnumber = formatnumber.toUpperCase();
122
+ //Formatting value following formatnumber parameter
123
+ //keep only decimal character in order to correct format the string
124
+ //This transformation is due the "stringtoNumber" method is a general method that tries to convert all formated strings
125
+ if (formatnumber === 'EN-US') {
126
+ value = value.replace(/\,/g, '');
127
+ }
128
+ else {
129
+ value = value.replace(/\./g, '');
130
+ }
131
+ return value;
132
+ };
133
+ /**
134
+ * @changeFormat: troca o formato do numero string de "PT-BR" para "EN-US" e vice-versa
135
+ *
136
+ * @param value numero em formato de string a ser convertido
137
+ *
138
+ * @returns numero em formato de string formatado de "PT-BR" para "EN-US" e vice-versa
139
+ */
140
+ NumberUtils.changeFormat = (value) => {
141
+ //Formatting output following formatnumber
142
+ return value.replace(/\./g, '_').replace(/\,/g, '.').replace(/\_/g, ',');
143
143
  };
144
144
 
145
- /**
146
- * `MaskFormatter` é usado para formatar strings. Seu comportamento
147
- * é controlado pela formato do atributo `mask` que especifica quais
148
- * caracteres são válidos e onde devem estar posicionados, intercalando-os
149
- * com eventuais caracteres literais expressados no padrão informado.
150
- * Sua implementação é inspirada pela implementação em Java do [MaskFormatter](https://docs.oracle.com/javase/7/docs/api/javax/swing/text/MaskFormatter.html).
151
- *
152
- * Para o padrão da máscara podem ser usados os seguintes caracteres especiais:
153
- *
154
- * | Caractere | Comportamento |
155
- * |:---------:|-------------------------------------------------------------------------------------------------------------|
156
- * | # | Qualquer número |
157
- * | ' | "Escapa" o caractere que vem na sequência. Útil quando desejamos converter um caractere especial em literal.|
158
- * | U | Qualquer letra. Transforma letras maiúsculas em maiúsculas. |
159
- * | L | Qualquer letra. Transforma letras maiúsculas em minúsculas. |
160
- * | A | Qualquer letra ou número. |
161
- * | ? | Qualquer letra. Preserva maiúsculas e minúsculas. |
162
- * | * | Qualquer caractere. |
163
- *
164
- * Os demais caracteres presentes no padrão serão tratados como literais, isto é,
165
- * serão apenas inseridos naquela posição.
166
- *
167
- * Quando o o valor a ser formatado é menor que a máscara um 'placeHolder'
168
- * será inserido em cada posição ausente, completando a formatação.
169
- * Por padrão será usado um espaço em branco como 'placeHolder' mas
170
- * esse valor pode ser alterado.
171
- *
172
- * For por exemplo:
173
- * '''
174
- * const formatter: MaskFormatter = new MaskFormatter("###-####");
175
- * formatter.placeholder = '_';
176
- * console.log(formatter.format("123"));
177
- * '''
178
- * resultaria na string '123-____'.
179
- *
180
- * ##Veja mais alguns exemplos:
181
- * |Padrão |Máscara |Entrada |Saída |
182
- * |----------------|------------------|--------------|------------------|
183
- * |Telefone |(##) ####-#### |3432192515 |(34) 3219-2515 |
184
- * |CPF |###.###.###-## |12345678901 |123.456.789-01 |
185
- * |CNPJ |##.###.###/####-##|12345678901234|12.345.678/9012-34|
186
- * |CEP |##.###-### |12345678 |12.345-678 |
187
- * |PLACA (veículo) |UUU-#### |abc1234 |ABC-1234 |
188
- * |Cor RGB |'#AAAAAA |00000F0 |#0000F0 |
189
- *
190
- */
191
- class MaskFormatter {
192
- constructor(mask) {
193
- this._mask = '';
194
- this._maskChars = new Array();
195
- /**
196
- * Determina qual caractere será usado dos caracteres não presentes no valor
197
- * ou seja, aqueles que o usuário ainda não informou. Por padrão usamos um espaço
198
- */
199
- this.placeholder = ' ';
200
- this.mask = mask;
201
- }
202
- /**
203
- * Setter para mask. Trata-se do padrão que se espera ao formatar o texto.
204
- */
205
- set mask(mask) {
206
- this._mask = mask;
207
- this.updateInternalMask();
208
- }
209
- /**
210
- * Getter para mask
211
- *
212
- * @return A última máscara informada.
213
- */
214
- get mask() {
215
- return this._mask;
216
- }
217
- /**
218
- * Formata a string passada baseada na máscara definda pelo atributo mask.
219
- *
220
- * @param value Valor a ser formatado
221
- * @return O valor processado de acordo com o padrão
222
- */
223
- format(value) {
224
- let result = '';
225
- const index = [0];
226
- let counter = 0;
227
- const maxCounter = this._maskChars.length;
228
- while (counter < maxCounter) {
229
- result = this._maskChars[counter].append(result, value, index);
230
- counter++;
231
- }
232
- return result;
233
- }
234
- /**
235
- * Preparamos a formatação internamente de acordo com o padrão.
236
- */
237
- updateInternalMask() {
238
- this._maskChars.length = 0;
239
- if (this.mask != null) {
240
- let counter = 0;
241
- const maxCounter = this.mask.length;
242
- while (counter < maxCounter) {
243
- let maskChar = this.mask.charAt(counter);
244
- switch (maskChar) {
245
- case MaskFormatter.DIGIT_KEY:
246
- this._maskChars.push(new MaskFormatter.DigitMaskCharacter(this, maskChar));
247
- break;
248
- case MaskFormatter.LITERAL_KEY:
249
- if (++counter < maxCounter) {
250
- maskChar = this.mask.charAt(counter);
251
- this._maskChars.push(new MaskFormatter.LiteralCharacter(this, maskChar));
252
- }
253
- break;
254
- case MaskFormatter.UPPERCASE_KEY:
255
- this._maskChars.push(new MaskFormatter.UpperCaseCharacter(this, maskChar));
256
- break;
257
- case MaskFormatter.LOWERCASE_KEY:
258
- this._maskChars.push(new MaskFormatter.LowerCaseCharacter(this, maskChar));
259
- break;
260
- case MaskFormatter.ALPHA_NUMERIC_KEY:
261
- this._maskChars.push(new MaskFormatter.AlphaNumericCharacter(this, maskChar));
262
- break;
263
- case MaskFormatter.CHARACTER_KEY:
264
- this._maskChars.push(new MaskFormatter.CharCharacter(this, maskChar));
265
- break;
266
- case MaskFormatter.ANYTHING_KEY:
267
- this._maskChars.push(new MaskFormatter.MaskCharacter(this, maskChar));
268
- break;
269
- default:
270
- this._maskChars.push(new MaskFormatter.LiteralCharacter(this, maskChar));
271
- break;
272
- }
273
- counter++;
274
- }
275
- }
276
- }
277
- }
278
- MaskFormatter.DIGIT_KEY = "#";
279
- MaskFormatter.LITERAL_KEY = "'";
280
- MaskFormatter.UPPERCASE_KEY = "U";
281
- MaskFormatter.LOWERCASE_KEY = "L";
282
- MaskFormatter.ALPHA_NUMERIC_KEY = "A";
283
- MaskFormatter.CHARACTER_KEY = "?";
284
- MaskFormatter.ANYTHING_KEY = "*";
285
- //
286
- // Classes internas usadas para representar a máscara.
287
- //
288
- MaskFormatter.MaskCharacter = class {
289
- constructor(maskFormatter, type) {
290
- this.maskFormatter = maskFormatter;
291
- this.type = type;
292
- }
293
- /**
294
- * Cada subclasse deve sobrescrever o retornando true, caso represente
295
- * um caractere literal. Por padrão o retorno é false.
296
- */
297
- isLiteral() {
298
- return false;
299
- }
300
- /**
301
- * Returns true if <code>aChar</code> is a valid reprensentation of
302
- * the receiver. The default implementation returns true if the
303
- * receiver represents a literal character and <code>getChar</code>
304
- * == aChar. Otherwise, this will return true is <code>aChar</code>
305
- * is contained in the valid characters and not contained
306
- * in the invalid characters.
307
- */
308
- isValidCharacter(aChar) {
309
- if (this.isLiteral()) {
310
- return (this.getChar(aChar) == aChar);
311
- }
312
- aChar = this.getChar(aChar);
313
- return true;
314
- }
315
- /**
316
- * Returns the character to insert for <code>aChar</code>. The
317
- * default implementation returns <code>aChar</code>. Subclasses
318
- * that wish to do some sort of mapping, perhaps lower case to upper
319
- * case should override this and do the necessary mapping.
320
- */
321
- getChar(aChar) {
322
- return aChar;
323
- }
324
- /**
325
- * Appends the necessary character in <code>formatting</code> at
326
- * <code>index</code> to <code>buff</code>.
327
- */
328
- append(result, formatting, index) {
329
- const inString = index[0] < formatting.length;
330
- const aChar = inString ? formatting.charAt(index[0]) : '';
331
- if (this.isLiteral()) {
332
- const literal = this.getChar(aChar);
333
- result += literal;
334
- if (literal === aChar) {
335
- index[0] = index[0] + 1;
336
- }
337
- }
338
- else if (index[0] >= formatting.length) {
339
- result += this.maskFormatter.placeholder;
340
- index[0] = index[0] + 1;
341
- }
342
- else if (this.isValidCharacter(aChar)) {
343
- result += this.getChar(aChar);
344
- index[0] = index[0] + 1;
345
- }
346
- else {
347
- throw new Error(`Valor inválido: "${aChar}". Na posição ${index[0] + 1} espera-se ${this.getFormatMessage()}.`);
348
- }
349
- return result;
350
- }
351
- getFormatMessage() {
352
- let message;
353
- switch (this.type) {
354
- case MaskFormatter.UPPERCASE_KEY:
355
- case MaskFormatter.LOWERCASE_KEY:
356
- case MaskFormatter.CHARACTER_KEY:
357
- message = 'uma letra';
358
- break;
359
- case MaskFormatter.DIGIT_KEY:
360
- message = 'um número';
361
- break;
362
- case MaskFormatter.ALPHA_NUMERIC_KEY:
363
- message = 'uma letra ou um número';
364
- break;
365
- default:
366
- message = '';
367
- }
368
- return message;
369
- }
370
- };
371
- MaskFormatter.LiteralCharacter = class extends MaskFormatter.MaskCharacter {
372
- constructor(maskFormatter, fixedChar) {
373
- super(maskFormatter, fixedChar);
374
- this._fixedChar = fixedChar;
375
- }
376
- isLiteral() {
377
- return true;
378
- }
379
- getChar(aChar) {
380
- return this._fixedChar;
381
- }
382
- };
383
- MaskFormatter.DigitMaskCharacter = class extends MaskFormatter.MaskCharacter {
384
- isValidCharacter(aChar) {
385
- return (this.isDigit(aChar) && super.isValidCharacter(aChar));
386
- }
387
- isDigit(char) {
388
- return char >= '0' && char <= '9';
389
- }
390
- };
391
- MaskFormatter.UpperCaseCharacter = class extends MaskFormatter.MaskCharacter {
392
- isValidCharacter(aChar) {
393
- return (/[a-z]/i.test(aChar) && super.isValidCharacter(aChar));
394
- }
395
- getChar(aChar) {
396
- return aChar.toUpperCase();
397
- }
398
- };
399
- MaskFormatter.LowerCaseCharacter = class extends MaskFormatter.MaskCharacter {
400
- isValidCharacter(aChar) {
401
- return (/[a-z]/i.test(aChar) && super.isValidCharacter(aChar));
402
- }
403
- getChar(aChar) {
404
- return aChar.toLocaleLowerCase();
405
- }
406
- };
407
- MaskFormatter.AlphaNumericCharacter = class extends MaskFormatter.MaskCharacter {
408
- isValidCharacter(aChar) {
409
- //FIXME: talvez seja problema usar regex aqui... avaliar se existe forma mais barata
410
- return (/[a-z0-9]/i.test(aChar)) && super.isValidCharacter(aChar);
411
- }
412
- };
413
- MaskFormatter.CharCharacter = class extends MaskFormatter.MaskCharacter {
414
- isValidCharacter(aChar) {
415
- //FIXME: talvez seja problema usar regex aqui... avaliar se existe forma mais barata
416
- return (/[a-z]/i.test(aChar) && super.isValidCharacter(aChar));
417
- }
145
+ /**
146
+ * `MaskFormatter` é usado para formatar strings. Seu comportamento
147
+ * é controlado pela formato do atributo `mask` que especifica quais
148
+ * caracteres são válidos e onde devem estar posicionados, intercalando-os
149
+ * com eventuais caracteres literais expressados no padrão informado.
150
+ * Sua implementação é inspirada pela implementação em Java do [MaskFormatter](https://docs.oracle.com/javase/7/docs/api/javax/swing/text/MaskFormatter.html).
151
+ *
152
+ * Para o padrão da máscara podem ser usados os seguintes caracteres especiais:
153
+ *
154
+ * | Caractere | Comportamento |
155
+ * |:---------:|-------------------------------------------------------------------------------------------------------------|
156
+ * | # | Qualquer número |
157
+ * | ' | "Escapa" o caractere que vem na sequência. Útil quando desejamos converter um caractere especial em literal.|
158
+ * | U | Qualquer letra. Transforma letras maiúsculas em maiúsculas. |
159
+ * | L | Qualquer letra. Transforma letras maiúsculas em minúsculas. |
160
+ * | A | Qualquer letra ou número. |
161
+ * | ? | Qualquer letra. Preserva maiúsculas e minúsculas. |
162
+ * | * | Qualquer caractere. |
163
+ *
164
+ * Os demais caracteres presentes no padrão serão tratados como literais, isto é,
165
+ * serão apenas inseridos naquela posição.
166
+ *
167
+ * Quando o o valor a ser formatado é menor que a máscara um 'placeHolder'
168
+ * será inserido em cada posição ausente, completando a formatação.
169
+ * Por padrão será usado um espaço em branco como 'placeHolder' mas
170
+ * esse valor pode ser alterado.
171
+ *
172
+ * For por exemplo:
173
+ * '''
174
+ * const formatter: MaskFormatter = new MaskFormatter("###-####");
175
+ * formatter.placeholder = '_';
176
+ * console.log(formatter.format("123"));
177
+ * '''
178
+ * resultaria na string '123-____'.
179
+ *
180
+ * ##Veja mais alguns exemplos:
181
+ * |Padrão |Máscara |Entrada |Saída |
182
+ * |----------------|------------------|--------------|------------------|
183
+ * |Telefone |(##) ####-#### |3432192515 |(34) 3219-2515 |
184
+ * |CPF |###.###.###-## |12345678901 |123.456.789-01 |
185
+ * |CNPJ |##.###.###/####-##|12345678901234|12.345.678/9012-34|
186
+ * |CEP |##.###-### |12345678 |12.345-678 |
187
+ * |PLACA (veículo) |UUU-#### |abc1234 |ABC-1234 |
188
+ * |Cor RGB |'#AAAAAA |00000F0 |#0000F0 |
189
+ *
190
+ */
191
+ class MaskFormatter {
192
+ constructor(mask) {
193
+ this._mask = '';
194
+ this._maskChars = new Array();
195
+ /**
196
+ * Determina qual caractere será usado dos caracteres não presentes no valor
197
+ * ou seja, aqueles que o usuário ainda não informou. Por padrão usamos um espaço
198
+ */
199
+ this.placeholder = ' ';
200
+ this.mask = mask;
201
+ }
202
+ /**
203
+ * Setter para mask. Trata-se do padrão que se espera ao formatar o texto.
204
+ */
205
+ set mask(mask) {
206
+ this._mask = mask;
207
+ this.updateInternalMask();
208
+ }
209
+ /**
210
+ * Getter para mask
211
+ *
212
+ * @return A última máscara informada.
213
+ */
214
+ get mask() {
215
+ return this._mask;
216
+ }
217
+ /**
218
+ * Formata a string passada baseada na máscara definda pelo atributo mask.
219
+ *
220
+ * @param value Valor a ser formatado
221
+ * @return O valor processado de acordo com o padrão
222
+ */
223
+ format(value) {
224
+ let result = '';
225
+ const index = [0];
226
+ let counter = 0;
227
+ const maxCounter = this._maskChars.length;
228
+ while (counter < maxCounter) {
229
+ result = this._maskChars[counter].append(result, value, index);
230
+ counter++;
231
+ }
232
+ return result;
233
+ }
234
+ /**
235
+ * Preparamos a formatação internamente de acordo com o padrão.
236
+ */
237
+ updateInternalMask() {
238
+ this._maskChars.length = 0;
239
+ if (this.mask != null) {
240
+ let counter = 0;
241
+ const maxCounter = this.mask.length;
242
+ while (counter < maxCounter) {
243
+ let maskChar = this.mask.charAt(counter);
244
+ switch (maskChar) {
245
+ case MaskFormatter.DIGIT_KEY:
246
+ this._maskChars.push(new MaskFormatter.DigitMaskCharacter(this, maskChar));
247
+ break;
248
+ case MaskFormatter.LITERAL_KEY:
249
+ if (++counter < maxCounter) {
250
+ maskChar = this.mask.charAt(counter);
251
+ this._maskChars.push(new MaskFormatter.LiteralCharacter(this, maskChar));
252
+ }
253
+ break;
254
+ case MaskFormatter.UPPERCASE_KEY:
255
+ this._maskChars.push(new MaskFormatter.UpperCaseCharacter(this, maskChar));
256
+ break;
257
+ case MaskFormatter.LOWERCASE_KEY:
258
+ this._maskChars.push(new MaskFormatter.LowerCaseCharacter(this, maskChar));
259
+ break;
260
+ case MaskFormatter.ALPHA_NUMERIC_KEY:
261
+ this._maskChars.push(new MaskFormatter.AlphaNumericCharacter(this, maskChar));
262
+ break;
263
+ case MaskFormatter.CHARACTER_KEY:
264
+ this._maskChars.push(new MaskFormatter.CharCharacter(this, maskChar));
265
+ break;
266
+ case MaskFormatter.ANYTHING_KEY:
267
+ this._maskChars.push(new MaskFormatter.MaskCharacter(this, maskChar));
268
+ break;
269
+ default:
270
+ this._maskChars.push(new MaskFormatter.LiteralCharacter(this, maskChar));
271
+ break;
272
+ }
273
+ counter++;
274
+ }
275
+ }
276
+ }
277
+ }
278
+ MaskFormatter.DIGIT_KEY = "#";
279
+ MaskFormatter.LITERAL_KEY = "'";
280
+ MaskFormatter.UPPERCASE_KEY = "U";
281
+ MaskFormatter.LOWERCASE_KEY = "L";
282
+ MaskFormatter.ALPHA_NUMERIC_KEY = "A";
283
+ MaskFormatter.CHARACTER_KEY = "?";
284
+ MaskFormatter.ANYTHING_KEY = "*";
285
+ //
286
+ // Classes internas usadas para representar a máscara.
287
+ //
288
+ MaskFormatter.MaskCharacter = class {
289
+ constructor(maskFormatter, type) {
290
+ this.maskFormatter = maskFormatter;
291
+ this.type = type;
292
+ }
293
+ /**
294
+ * Cada subclasse deve sobrescrever o retornando true, caso represente
295
+ * um caractere literal. Por padrão o retorno é false.
296
+ */
297
+ isLiteral() {
298
+ return false;
299
+ }
300
+ /**
301
+ * Returns true if <code>aChar</code> is a valid reprensentation of
302
+ * the receiver. The default implementation returns true if the
303
+ * receiver represents a literal character and <code>getChar</code>
304
+ * == aChar. Otherwise, this will return true is <code>aChar</code>
305
+ * is contained in the valid characters and not contained
306
+ * in the invalid characters.
307
+ */
308
+ isValidCharacter(aChar) {
309
+ if (this.isLiteral()) {
310
+ return (this.getChar(aChar) == aChar);
311
+ }
312
+ aChar = this.getChar(aChar);
313
+ return true;
314
+ }
315
+ /**
316
+ * Returns the character to insert for <code>aChar</code>. The
317
+ * default implementation returns <code>aChar</code>. Subclasses
318
+ * that wish to do some sort of mapping, perhaps lower case to upper
319
+ * case should override this and do the necessary mapping.
320
+ */
321
+ getChar(aChar) {
322
+ return aChar;
323
+ }
324
+ /**
325
+ * Appends the necessary character in <code>formatting</code> at
326
+ * <code>index</code> to <code>buff</code>.
327
+ */
328
+ append(result, formatting, index) {
329
+ const inString = index[0] < formatting.length;
330
+ const aChar = inString ? formatting.charAt(index[0]) : '';
331
+ if (this.isLiteral()) {
332
+ const literal = this.getChar(aChar);
333
+ result += literal;
334
+ if (literal === aChar) {
335
+ index[0] = index[0] + 1;
336
+ }
337
+ }
338
+ else if (index[0] >= formatting.length) {
339
+ result += this.maskFormatter.placeholder;
340
+ index[0] = index[0] + 1;
341
+ }
342
+ else if (this.isValidCharacter(aChar)) {
343
+ result += this.getChar(aChar);
344
+ index[0] = index[0] + 1;
345
+ }
346
+ else {
347
+ throw new Error(`Valor inválido: "${aChar}". Na posição ${index[0] + 1} espera-se ${this.getFormatMessage()}.`);
348
+ }
349
+ return result;
350
+ }
351
+ getFormatMessage() {
352
+ let message;
353
+ switch (this.type) {
354
+ case MaskFormatter.UPPERCASE_KEY:
355
+ case MaskFormatter.LOWERCASE_KEY:
356
+ case MaskFormatter.CHARACTER_KEY:
357
+ message = 'uma letra';
358
+ break;
359
+ case MaskFormatter.DIGIT_KEY:
360
+ message = 'um número';
361
+ break;
362
+ case MaskFormatter.ALPHA_NUMERIC_KEY:
363
+ message = 'uma letra ou um número';
364
+ break;
365
+ default:
366
+ message = '';
367
+ }
368
+ return message;
369
+ }
370
+ };
371
+ MaskFormatter.LiteralCharacter = class extends MaskFormatter.MaskCharacter {
372
+ constructor(maskFormatter, fixedChar) {
373
+ super(maskFormatter, fixedChar);
374
+ this._fixedChar = fixedChar;
375
+ }
376
+ isLiteral() {
377
+ return true;
378
+ }
379
+ getChar(aChar) {
380
+ return this._fixedChar;
381
+ }
382
+ };
383
+ MaskFormatter.DigitMaskCharacter = class extends MaskFormatter.MaskCharacter {
384
+ isValidCharacter(aChar) {
385
+ return (this.isDigit(aChar) && super.isValidCharacter(aChar));
386
+ }
387
+ isDigit(char) {
388
+ return char >= '0' && char <= '9';
389
+ }
390
+ };
391
+ MaskFormatter.UpperCaseCharacter = class extends MaskFormatter.MaskCharacter {
392
+ isValidCharacter(aChar) {
393
+ return (/[a-z]/i.test(aChar) && super.isValidCharacter(aChar));
394
+ }
395
+ getChar(aChar) {
396
+ return aChar.toUpperCase();
397
+ }
398
+ };
399
+ MaskFormatter.LowerCaseCharacter = class extends MaskFormatter.MaskCharacter {
400
+ isValidCharacter(aChar) {
401
+ return (/[a-z]/i.test(aChar) && super.isValidCharacter(aChar));
402
+ }
403
+ getChar(aChar) {
404
+ return aChar.toLocaleLowerCase();
405
+ }
406
+ };
407
+ MaskFormatter.AlphaNumericCharacter = class extends MaskFormatter.MaskCharacter {
408
+ isValidCharacter(aChar) {
409
+ //FIXME: talvez seja problema usar regex aqui... avaliar se existe forma mais barata
410
+ return (/[a-z0-9]/i.test(aChar)) && super.isValidCharacter(aChar);
411
+ }
412
+ };
413
+ MaskFormatter.CharCharacter = class extends MaskFormatter.MaskCharacter {
414
+ isValidCharacter(aChar) {
415
+ //FIXME: talvez seja problema usar regex aqui... avaliar se existe forma mais barata
416
+ return (/[a-z]/i.test(aChar) && super.isValidCharacter(aChar));
417
+ }
418
418
  };
419
419
 
420
- /**
421
- * `TimeFormatter` é um utilitário para formatação de strings desformatadas em strings válidas de horários
422
- */
423
- class TimeFormatter {
424
- /**
425
- * @prepareValue: converts an unformated time string into a formatted time.
426
- *
427
- * @param value unformated time string to convert
428
- *
429
- * @returns formatted time string
430
- *
431
- * @Exemples
432
- * @"1012" | "10:12"
433
- * @"10:12" | "10:12:00"
434
- * @"100112" | "10:01:12"
435
- */
436
- static prepareValue(value, showSeconds) {
437
- if (value && value.length > 0 && value != "NaN") {
438
- let validationValue = value.replace(/:/g, "");
439
- if (showSeconds) {
440
- this._maskFormatter.mask = "##:##:##";
441
- if (validationValue.length < 6) {
442
- while (validationValue.length < 6) {
443
- validationValue = "0".concat(validationValue);
444
- }
445
- }
446
- }
447
- else {
448
- this._maskFormatter.mask = "##:##";
449
- if (validationValue.length < 4) {
450
- while (validationValue.length < 4) {
451
- validationValue = "0".concat(validationValue);
452
- }
453
- }
454
- }
455
- if (this._maskFormatter) {
456
- try {
457
- value = this._maskFormatter.format(validationValue);
458
- return value;
459
- }
460
- catch (e) {
461
- throw new Error(e.message);
462
- }
463
- }
464
- }
465
- return '';
466
- }
467
- /**
468
- * @validateTime: validates if an input string has the corect time format.
469
- *
470
- * @param value input string to validate
471
- *
472
- * @returns true or false
473
- *
474
- * @Exemples
475
- * @"1012" | true
476
- * @"14e4" | false
477
- * @"2624" | false
478
- */
479
- static validateTime(value, showSeconds) {
480
- let isValid = true;
481
- if (value) {
482
- let validationValue = value.replace(/:/g, "");
483
- if (showSeconds) {
484
- if (!["1", "2", "0"].includes(validationValue[0])) {
485
- isValid = false;
486
- }
487
- if (!["0", "1", "2", "3", "4", "5"].includes(validationValue[2])) {
488
- isValid = false;
489
- }
490
- if (!["0", "1", "2", "3", "4", "5"].includes(validationValue[4])) {
491
- isValid = false;
492
- }
493
- if (validationValue[0] == "2" && !["0", "1", "2", "3"].includes(validationValue[1])) {
494
- isValid = false;
495
- }
496
- }
497
- else {
498
- if (!["1", "2", "0"].includes(validationValue[0])) {
499
- isValid = false;
500
- }
501
- if (!["0", "1", "2", "3", "4", "5"].includes(validationValue[2])) {
502
- isValid = false;
503
- }
504
- if (validationValue[0] == "2" && !["0", "1", "2", "3"].includes(validationValue[1])) {
505
- isValid = false;
506
- }
507
- }
508
- }
509
- else {
510
- isValid = false;
511
- }
512
- return isValid;
513
- }
514
- }
420
+ /**
421
+ * `TimeFormatter` é um utilitário para formatação de strings desformatadas em strings válidas de horários
422
+ */
423
+ class TimeFormatter {
424
+ /**
425
+ * @prepareValue: converts an unformated time string into a formatted time.
426
+ *
427
+ * @param value unformated time string to convert
428
+ *
429
+ * @returns formatted time string
430
+ *
431
+ * @Exemples
432
+ * @"1012" | "10:12"
433
+ * @"10:12" | "10:12:00"
434
+ * @"100112" | "10:01:12"
435
+ */
436
+ static prepareValue(value, showSeconds) {
437
+ if (value && value.length > 0 && value != "NaN") {
438
+ let validationValue = value.replace(/:/g, "");
439
+ if (showSeconds) {
440
+ this._maskFormatter.mask = "##:##:##";
441
+ if (validationValue.length < 6) {
442
+ while (validationValue.length < 6) {
443
+ validationValue = "0".concat(validationValue);
444
+ }
445
+ }
446
+ }
447
+ else {
448
+ this._maskFormatter.mask = "##:##";
449
+ if (validationValue.length < 4) {
450
+ while (validationValue.length < 4) {
451
+ validationValue = "0".concat(validationValue);
452
+ }
453
+ }
454
+ }
455
+ if (this._maskFormatter) {
456
+ try {
457
+ value = this._maskFormatter.format(validationValue);
458
+ return value;
459
+ }
460
+ catch (e) {
461
+ throw new Error(e.message);
462
+ }
463
+ }
464
+ }
465
+ return '';
466
+ }
467
+ /**
468
+ * @validateTime: validates if an input string has the corect time format.
469
+ *
470
+ * @param value input string to validate
471
+ *
472
+ * @returns true or false
473
+ *
474
+ * @Exemples
475
+ * @"1012" | true
476
+ * @"14e4" | false
477
+ * @"2624" | false
478
+ */
479
+ static validateTime(value, showSeconds) {
480
+ let isValid = true;
481
+ if (value) {
482
+ let validationValue = value.replace(/:/g, "");
483
+ if (showSeconds) {
484
+ if (!["1", "2", "0"].includes(validationValue[0])) {
485
+ isValid = false;
486
+ }
487
+ if (!["0", "1", "2", "3", "4", "5"].includes(validationValue[2])) {
488
+ isValid = false;
489
+ }
490
+ if (!["0", "1", "2", "3", "4", "5"].includes(validationValue[4])) {
491
+ isValid = false;
492
+ }
493
+ if (validationValue[0] == "2" && !["0", "1", "2", "3"].includes(validationValue[1])) {
494
+ isValid = false;
495
+ }
496
+ }
497
+ else {
498
+ if (!["1", "2", "0"].includes(validationValue[0])) {
499
+ isValid = false;
500
+ }
501
+ if (!["0", "1", "2", "3", "4", "5"].includes(validationValue[2])) {
502
+ isValid = false;
503
+ }
504
+ if (validationValue[0] == "2" && !["0", "1", "2", "3"].includes(validationValue[1])) {
505
+ isValid = false;
506
+ }
507
+ }
508
+ }
509
+ else {
510
+ isValid = false;
511
+ }
512
+ return isValid;
513
+ }
514
+ }
515
515
  TimeFormatter._maskFormatter = new MaskFormatter("##:##");
516
516
 
517
- /**
518
- * Representa as propriedades necessárias para se executar uma requisição.
519
- */
520
- /** Representa os verbos HTTP suportados */
521
- var Method;
522
- (function (Method) {
523
- Method[Method["GET"] = 0] = "GET";
524
- Method[Method["PUT"] = 1] = "PUT";
525
- Method[Method["POST"] = 2] = "POST";
526
- Method[Method["DELETE"] = 3] = "DELETE";
517
+ /**
518
+ * Representa as propriedades necessárias para se executar uma requisição.
519
+ */
520
+ /** Representa os verbos HTTP suportados */
521
+ var Method;
522
+ (function (Method) {
523
+ Method[Method["GET"] = 0] = "GET";
524
+ Method[Method["PUT"] = 1] = "PUT";
525
+ Method[Method["POST"] = 2] = "POST";
526
+ Method[Method["DELETE"] = 3] = "DELETE";
527
527
  })(Method || (Method = {}));
528
528
 
529
- exports.DataType = void 0;
530
- (function (DataType) {
531
- DataType["NUMBER"] = "NUMBER";
532
- DataType["DATE"] = "DATE";
533
- DataType["TEXT"] = "TEXT";
534
- DataType["BOOLEAN"] = "BOOLEAN";
535
- DataType["OBJECT"] = "OBJECT";
536
- })(exports.DataType || (exports.DataType = {}));
537
- const convertType = (dataType, value) => {
538
- if (value === undefined || value === null) {
539
- return value;
540
- }
541
- switch (dataType) {
542
- case exports.DataType.NUMBER:
543
- return value === "" || isNaN(value) ? null : Number(value);
544
- case exports.DataType.OBJECT:
545
- return typeof value === "string" ? JSON.parse(value) : value;
546
- case exports.DataType.BOOLEAN:
547
- return Boolean(value);
548
- case exports.DataType.DATE:
549
- return new Date(value.toString());
550
- default:
551
- return value;
552
- }
529
+ exports.DataType = void 0;
530
+ (function (DataType) {
531
+ DataType["NUMBER"] = "NUMBER";
532
+ DataType["DATE"] = "DATE";
533
+ DataType["TEXT"] = "TEXT";
534
+ DataType["BOOLEAN"] = "BOOLEAN";
535
+ DataType["OBJECT"] = "OBJECT";
536
+ })(exports.DataType || (exports.DataType = {}));
537
+ const convertType = (dataType, value) => {
538
+ if (value === undefined || value === null) {
539
+ return value;
540
+ }
541
+ switch (dataType) {
542
+ case exports.DataType.NUMBER:
543
+ return value === "" || isNaN(value) ? null : Number(value);
544
+ case exports.DataType.OBJECT:
545
+ return typeof value === "string" ? JSON.parse(value) : value;
546
+ case exports.DataType.BOOLEAN:
547
+ return Boolean(value);
548
+ case exports.DataType.DATE:
549
+ return new Date(value.toString());
550
+ default:
551
+ return value;
552
+ }
553
553
  };
554
554
 
555
- class DataUnitAction {
556
- constructor(type, payload) {
557
- this._type = type;
558
- this._payload = payload;
559
- }
560
- get type() {
561
- return this._type;
562
- }
563
- get payload() {
564
- return this._payload;
565
- }
566
- }
567
- exports.Action = void 0;
568
- (function (Action) {
569
- Action["LOADING_METADATA"] = "loadingMetadata";
570
- Action["METADATA_LOADED"] = "metadataLoaded";
571
- Action["LOADING_DATA"] = "loadingData";
572
- Action["DATA_LOADED"] = "dataLoaded";
573
- Action["SAVING_DATA"] = "savingData";
574
- Action["DATA_SAVED"] = "dataSaved";
575
- Action["REMOVING_RECORDS"] = "removingRecords";
576
- Action["RECORDS_REMOVED"] = "recordsRemoved";
577
- Action["RECORDS_ADDED"] = "recordsAdded";
578
- Action["RECORDS_COPIED"] = "recordsCopied";
579
- Action["DATA_CHANGED"] = "dataChanged";
580
- Action["EDITION_CANCELED"] = "editionCanceled";
581
- Action["CHANGE_UNDONE"] = "changeUndone";
582
- Action["CHANGE_REDONE"] = "changeRedone";
583
- Action["SELECTION_CHANGED"] = "selectionChanged";
584
- Action["NEXT_SELECTED"] = "nextSelected";
585
- Action["PREVIOUS_SELECTED"] = "previousSelected";
586
- Action["STATE_CHANGED"] = "stateChanged";
555
+ class DataUnitAction {
556
+ constructor(type, payload) {
557
+ this._type = type;
558
+ this._payload = payload;
559
+ }
560
+ get type() {
561
+ return this._type;
562
+ }
563
+ get payload() {
564
+ return this._payload;
565
+ }
566
+ }
567
+ exports.Action = void 0;
568
+ (function (Action) {
569
+ Action["LOADING_METADATA"] = "loadingMetadata";
570
+ Action["METADATA_LOADED"] = "metadataLoaded";
571
+ Action["LOADING_DATA"] = "loadingData";
572
+ Action["DATA_LOADED"] = "dataLoaded";
573
+ Action["SAVING_DATA"] = "savingData";
574
+ Action["DATA_SAVED"] = "dataSaved";
575
+ Action["REMOVING_RECORDS"] = "removingRecords";
576
+ Action["RECORDS_REMOVED"] = "recordsRemoved";
577
+ Action["RECORDS_ADDED"] = "recordsAdded";
578
+ Action["RECORDS_COPIED"] = "recordsCopied";
579
+ Action["DATA_CHANGED"] = "dataChanged";
580
+ Action["EDITION_CANCELED"] = "editionCanceled";
581
+ Action["CHANGE_UNDONE"] = "changeUndone";
582
+ Action["CHANGE_REDONE"] = "changeRedone";
583
+ Action["SELECTION_CHANGED"] = "selectionChanged";
584
+ Action["NEXT_SELECTED"] = "nextSelected";
585
+ Action["PREVIOUS_SELECTED"] = "previousSelected";
586
+ Action["STATE_CHANGED"] = "stateChanged";
587
587
  })(exports.Action || (exports.Action = {}));
588
588
 
589
- /**
590
- * Essa classe representa uma interpretação do padrão de projetos Flux.
591
- * No padrão Flux os dados da aplicação são chamados de "estado" e existem
592
- * algumas regras para gerenciamento/manipulação desse estado:
593
- *
594
- * 1 - O estado é imutável.
595
- * 2 - Toda modificação de estado é representada por uma "ação".
596
- * 3 - Quando "ações" acontecem a "store" cria um novo estado e notifica a todos interessados.
597
- *
598
- * Nessa interpretação desse design pattern, o StateManager faz o papel da store,
599
- * notificando os manipuladores de estado (handlers), que são responsáveis por pedaços
600
- * do estado (slices).
601
- *
602
- * O StateManager mantém dois tipos de estados: "Histórico" e "Não Histórico". No estado
603
- * "Histórico", sempre que uma alteração de estado acontece, o estado anterior é guardado em
604
- * uma pilha, o que permite que possamos voltar no tempo, desfazendo algumas ações
605
- */
606
- class StateManager {
607
- constructor(reducers) {
608
- this._past = [];
609
- this._future = [];
610
- this._present = {};
611
- this._nonHist = {};
612
- this._histClean = false;
613
- this._reducers = reducers;
614
- }
615
- process(action) {
616
- const oldPresent = this._present;
617
- let hasHistChange = false;
618
- this._histClean = false;
619
- this._reducers.forEach(reducer => {
620
- const sliceName = reducer.sliceName;
621
- const isHistoric = this.isHistoric(sliceName);
622
- const oldSlice = this.getSlice(sliceName, isHistoric);
623
- const newSlice = reducer.reduce(this, oldSlice, action);
624
- if (newSlice !== oldSlice) {
625
- this.updateSlice(sliceName, newSlice, isHistoric);
626
- hasHistChange || (hasHistChange = isHistoric);
627
- }
628
- });
629
- if (hasHistChange && !this._histClean) {
630
- this._past.push(oldPresent);
631
- this._future = [];
632
- document.dispatchEvent(new CustomEvent("undoableAction", { detail: this }));
633
- }
634
- }
635
- select(sliceName, selector) {
636
- const isHistoric = this.isHistoric(sliceName);
637
- return selector(this.getSlice(sliceName, isHistoric));
638
- }
639
- isHistoric(slice) {
640
- return slice.startsWith("hist::");
641
- }
642
- updateSlice(name, slice, isHistoric) {
643
- if (isHistoric) {
644
- this._present = Object.assign(Object.assign({}, this._present), { [name]: slice });
645
- if (slice === undefined) {
646
- delete this._present[name];
647
- }
648
- }
649
- else {
650
- this._nonHist = Object.assign(Object.assign({}, this._nonHist), { [name]: slice });
651
- if (slice === undefined) {
652
- delete this._nonHist[name];
653
- }
654
- }
655
- }
656
- getSlice(name, isHistoric) {
657
- return isHistoric ? this._present[name] : this._nonHist[name];
658
- }
659
- canUndo() {
660
- return this._past.length > 0;
661
- }
662
- canRedo() {
663
- return this._future.length > 0;
664
- }
665
- undo() {
666
- if (this.canUndo()) {
667
- this._future.push(this._present);
668
- this._present = this._past.pop();
669
- }
670
- }
671
- redo() {
672
- if (this.canRedo()) {
673
- this._past.push(this._present);
674
- this._present = this._future.pop();
675
- }
676
- }
677
- clearUndo() {
678
- this._histClean = true;
679
- this._past = [];
680
- this._future = [];
681
- }
682
- persist() {
683
- }
589
+ /**
590
+ * Essa classe representa uma interpretação do padrão de projetos Flux.
591
+ * No padrão Flux os dados da aplicação são chamados de "estado" e existem
592
+ * algumas regras para gerenciamento/manipulação desse estado:
593
+ *
594
+ * 1 - O estado é imutável.
595
+ * 2 - Toda modificação de estado é representada por uma "ação".
596
+ * 3 - Quando "ações" acontecem a "store" cria um novo estado e notifica a todos interessados.
597
+ *
598
+ * Nessa interpretação desse design pattern, o StateManager faz o papel da store,
599
+ * notificando os manipuladores de estado (handlers), que são responsáveis por pedaços
600
+ * do estado (slices).
601
+ *
602
+ * O StateManager mantém dois tipos de estados: "Histórico" e "Não Histórico". No estado
603
+ * "Histórico", sempre que uma alteração de estado acontece, o estado anterior é guardado em
604
+ * uma pilha, o que permite que possamos voltar no tempo, desfazendo algumas ações
605
+ */
606
+ class StateManager {
607
+ constructor(reducers) {
608
+ this._past = [];
609
+ this._future = [];
610
+ this._present = {};
611
+ this._nonHist = {};
612
+ this._histClean = false;
613
+ this._reducers = reducers;
614
+ }
615
+ process(action) {
616
+ const oldPresent = this._present;
617
+ let hasHistChange = false;
618
+ this._histClean = false;
619
+ this._reducers.forEach(reducer => {
620
+ const sliceName = reducer.sliceName;
621
+ const isHistoric = this.isHistoric(sliceName);
622
+ const oldSlice = this.getSlice(sliceName, isHistoric);
623
+ const newSlice = reducer.reduce(this, oldSlice, action);
624
+ if (newSlice !== oldSlice) {
625
+ this.updateSlice(sliceName, newSlice, isHistoric);
626
+ hasHistChange || (hasHistChange = isHistoric);
627
+ }
628
+ });
629
+ if (hasHistChange && !this._histClean) {
630
+ this._past.push(oldPresent);
631
+ this._future = [];
632
+ document.dispatchEvent(new CustomEvent("undoableAction", { detail: this }));
633
+ }
634
+ }
635
+ select(sliceName, selector) {
636
+ const isHistoric = this.isHistoric(sliceName);
637
+ return selector(this.getSlice(sliceName, isHistoric));
638
+ }
639
+ isHistoric(slice) {
640
+ return slice.startsWith("hist::");
641
+ }
642
+ updateSlice(name, slice, isHistoric) {
643
+ if (isHistoric) {
644
+ this._present = Object.assign(Object.assign({}, this._present), { [name]: slice });
645
+ if (slice === undefined) {
646
+ delete this._present[name];
647
+ }
648
+ }
649
+ else {
650
+ this._nonHist = Object.assign(Object.assign({}, this._nonHist), { [name]: slice });
651
+ if (slice === undefined) {
652
+ delete this._nonHist[name];
653
+ }
654
+ }
655
+ }
656
+ getSlice(name, isHistoric) {
657
+ return isHistoric ? this._present[name] : this._nonHist[name];
658
+ }
659
+ canUndo() {
660
+ return this._past.length > 0;
661
+ }
662
+ canRedo() {
663
+ return this._future.length > 0;
664
+ }
665
+ undo() {
666
+ if (this.canUndo()) {
667
+ this._future.push(this._present);
668
+ this._present = this._past.pop();
669
+ }
670
+ }
671
+ redo() {
672
+ if (this.canRedo()) {
673
+ this._past.push(this._present);
674
+ this._present = this._future.pop();
675
+ }
676
+ }
677
+ clearUndo() {
678
+ this._histClean = true;
679
+ this._past = [];
680
+ this._future = [];
681
+ }
682
+ persist() {
683
+ }
684
684
  }
685
685
 
686
- class HistReducerImpl {
687
- constructor() {
688
- this.sliceName = "";
689
- }
690
- reduce(stateManager, _currentState, action) {
691
- switch (action.type) {
692
- case exports.Action.DATA_SAVED:
693
- case exports.Action.EDITION_CANCELED:
694
- stateManager.clearUndo();
695
- break;
696
- case exports.Action.CHANGE_UNDONE:
697
- stateManager.undo();
698
- break;
699
- case exports.Action.CHANGE_REDONE:
700
- stateManager.redo();
701
- break;
702
- }
703
- }
704
- }
705
- const HistReducer = new HistReducerImpl();
706
- const canUndo = (stateManager) => {
707
- return stateManager.canUndo();
708
- };
709
- const canRedo = (stateManager) => {
710
- return stateManager.canRedo();
686
+ class HistReducerImpl {
687
+ constructor() {
688
+ this.sliceName = "";
689
+ }
690
+ reduce(stateManager, _currentState, action) {
691
+ switch (action.type) {
692
+ case exports.Action.DATA_SAVED:
693
+ case exports.Action.EDITION_CANCELED:
694
+ stateManager.clearUndo();
695
+ break;
696
+ case exports.Action.CHANGE_UNDONE:
697
+ stateManager.undo();
698
+ break;
699
+ case exports.Action.CHANGE_REDONE:
700
+ stateManager.redo();
701
+ break;
702
+ }
703
+ }
704
+ }
705
+ const HistReducer = new HistReducerImpl();
706
+ const canUndo = (stateManager) => {
707
+ return stateManager.canUndo();
708
+ };
709
+ const canRedo = (stateManager) => {
710
+ return stateManager.canRedo();
711
711
  };
712
712
 
713
- class UnitMetadataReducerImpl {
714
- constructor() {
715
- this.sliceName = "unitMetadata";
716
- }
717
- reduce(_stateManager, currentState, action) {
718
- if (action.type === exports.Action.METADATA_LOADED) {
719
- return action.payload;
720
- }
721
- return currentState;
722
- }
723
- }
724
- const UnitMetadataReducer = new UnitMetadataReducerImpl();
725
- const getMetadata = (stateManager) => {
726
- return stateManager.select(UnitMetadataReducer.sliceName, (state) => state);
727
- };
728
- const getField = (stateManager, fieldName) => {
729
- const md = getMetadata(stateManager);
730
- return md ? md.fields.find(fmd => fmd.name === fieldName) : undefined;
713
+ class UnitMetadataReducerImpl {
714
+ constructor() {
715
+ this.sliceName = "unitMetadata";
716
+ }
717
+ reduce(_stateManager, currentState, action) {
718
+ if (action.type === exports.Action.METADATA_LOADED) {
719
+ return action.payload;
720
+ }
721
+ return currentState;
722
+ }
723
+ }
724
+ const UnitMetadataReducer = new UnitMetadataReducerImpl();
725
+ const getMetadata = (stateManager) => {
726
+ return stateManager.select(UnitMetadataReducer.sliceName, (state) => state);
727
+ };
728
+ const getField = (stateManager, fieldName) => {
729
+ const md = getMetadata(stateManager);
730
+ return md ? md.fields.find(fmd => fmd.name === fieldName) : undefined;
731
731
  };
732
732
 
733
- class RemovedRecordsReducerImpl {
734
- constructor() {
735
- this.sliceName = "hist::removedRecords";
736
- }
737
- reduce(_stateManager, currentState, action) {
738
- switch (action.type) {
739
- case exports.Action.RECORDS_REMOVED:
740
- const { records, buffered } = action.payload;
741
- if (buffered) {
742
- return (currentState || []).concat(records);
743
- }
744
- return currentState;
745
- case exports.Action.EDITION_CANCELED:
746
- case exports.Action.DATA_SAVED:
747
- return undefined;
748
- }
749
- return currentState;
750
- }
751
- }
752
- const RemovedRecordsReducer = new RemovedRecordsReducerImpl();
753
- const getRemovedRecords = (stateManager) => {
754
- return stateManager.select(RemovedRecordsReducer.sliceName, (state) => state);
733
+ class RemovedRecordsReducerImpl {
734
+ constructor() {
735
+ this.sliceName = "hist::removedRecords";
736
+ }
737
+ reduce(_stateManager, currentState, action) {
738
+ switch (action.type) {
739
+ case exports.Action.RECORDS_REMOVED:
740
+ const { records, buffered } = action.payload;
741
+ if (buffered) {
742
+ return (currentState || []).concat(records);
743
+ }
744
+ return currentState;
745
+ case exports.Action.EDITION_CANCELED:
746
+ case exports.Action.DATA_SAVED:
747
+ return undefined;
748
+ }
749
+ return currentState;
750
+ }
751
+ }
752
+ const RemovedRecordsReducer = new RemovedRecordsReducerImpl();
753
+ const getRemovedRecords = (stateManager) => {
754
+ return stateManager.select(RemovedRecordsReducer.sliceName, (state) => state);
755
755
  };
756
756
 
757
- class RecordsReducerImpl {
758
- constructor() {
759
- this.sliceName = "records";
760
- }
761
- reduce(stateManager, currentState, action) {
762
- switch (action.type) {
763
- case exports.Action.DATA_LOADED:
764
- return action.payload;
765
- case exports.Action.RECORDS_REMOVED:
766
- const { records, buffered } = action.payload;
767
- if (!buffered) {
768
- return currentState.filter(r => !records.includes(r.__record__id__));
769
- }
770
- return currentState;
771
- case exports.Action.DATA_SAVED:
772
- const recordsMap = new Map();
773
- const currentRecords = getRecords(stateManager);
774
- if (currentRecords) {
775
- const removed = getRemovedRecords(stateManager) || [];
776
- currentRecords.forEach(r => {
777
- if (!removed.includes(r.__record__id__)) {
778
- recordsMap.set(r.__record__id__, r);
779
- }
780
- });
781
- }
782
- const savedRecords = action.payload.records;
783
- savedRecords.forEach(sr => {
784
- const recordId = sr.__old__id__ || sr.__record__id__;
785
- const newRecord = Object.assign({}, sr);
786
- delete newRecord["__old__id__"];
787
- recordsMap.set(recordId, newRecord);
788
- });
789
- return Array.from(recordsMap.values());
790
- }
791
- return currentState;
792
- }
793
- }
794
- const RecordsReducer = new RecordsReducerImpl();
795
- const getRecords = (stateManager) => {
796
- return stateManager.select(RecordsReducer.sliceName, (state) => state);
757
+ class RecordsReducerImpl {
758
+ constructor() {
759
+ this.sliceName = "records";
760
+ }
761
+ reduce(stateManager, currentState, action) {
762
+ switch (action.type) {
763
+ case exports.Action.DATA_LOADED:
764
+ return action.payload;
765
+ case exports.Action.RECORDS_REMOVED:
766
+ const { records, buffered } = action.payload;
767
+ if (!buffered) {
768
+ return currentState.filter(r => !records.includes(r.__record__id__));
769
+ }
770
+ return currentState;
771
+ case exports.Action.DATA_SAVED:
772
+ const recordsMap = new Map();
773
+ const currentRecords = getRecords(stateManager);
774
+ if (currentRecords) {
775
+ const removed = getRemovedRecords(stateManager) || [];
776
+ currentRecords.forEach(r => {
777
+ if (!removed.includes(r.__record__id__)) {
778
+ recordsMap.set(r.__record__id__, r);
779
+ }
780
+ });
781
+ }
782
+ const savedRecords = action.payload.records;
783
+ savedRecords.forEach(sr => {
784
+ const recordId = sr.__old__id__ || sr.__record__id__;
785
+ const newRecord = Object.assign({}, sr);
786
+ delete newRecord["__old__id__"];
787
+ recordsMap.set(recordId, newRecord);
788
+ });
789
+ return Array.from(recordsMap.values());
790
+ }
791
+ return currentState;
792
+ }
793
+ }
794
+ const RecordsReducer = new RecordsReducerImpl();
795
+ const getRecords = (stateManager) => {
796
+ return stateManager.select(RecordsReducer.sliceName, (state) => state);
797
797
  };
798
798
 
799
- class AddedRecordsReducerImpl {
800
- constructor() {
801
- this.sliceName = "hist::addedRecords";
802
- }
803
- reduce(_stateManager, currentState, action) {
804
- switch (action.type) {
805
- case exports.Action.RECORDS_ADDED:
806
- case exports.Action.RECORDS_COPIED:
807
- return (currentState || []).concat(action.payload);
808
- case exports.Action.DATA_SAVED:
809
- case exports.Action.EDITION_CANCELED:
810
- return undefined;
811
- }
812
- return currentState;
813
- }
814
- }
815
- const AddedRecordsReducer = new AddedRecordsReducerImpl();
816
- const getAddedRecords = (stateManager) => {
817
- return stateManager.select(AddedRecordsReducer.sliceName, (state) => state);
818
- };
819
- const prepareAddedRecordId = (stateManager, source) => {
820
- let index = (getAddedRecords(stateManager) || []).length;
821
- return source.map(item => { return Object.assign(Object.assign({}, item), { __record__id__: "NEW_" + (index++) }); });
799
+ class AddedRecordsReducerImpl {
800
+ constructor() {
801
+ this.sliceName = "hist::addedRecords";
802
+ }
803
+ reduce(_stateManager, currentState, action) {
804
+ switch (action.type) {
805
+ case exports.Action.RECORDS_ADDED:
806
+ case exports.Action.RECORDS_COPIED:
807
+ return (currentState || []).concat(action.payload);
808
+ case exports.Action.DATA_SAVED:
809
+ case exports.Action.EDITION_CANCELED:
810
+ return undefined;
811
+ }
812
+ return currentState;
813
+ }
814
+ }
815
+ const AddedRecordsReducer = new AddedRecordsReducerImpl();
816
+ const getAddedRecords = (stateManager) => {
817
+ return stateManager.select(AddedRecordsReducer.sliceName, (state) => state);
818
+ };
819
+ const prepareAddedRecordId = (stateManager, source) => {
820
+ let index = (getAddedRecords(stateManager) || []).length;
821
+ return source.map(item => { return Object.assign(Object.assign({}, item), { __record__id__: "NEW_" + (index++) }); });
822
822
  };
823
823
 
824
- class ChangesReducerImpl {
825
- constructor() {
826
- this.sliceName = "hist::changes";
827
- }
828
- reduce(stateManager, currentState, action) {
829
- switch (action.type) {
830
- case exports.Action.DATA_CHANGED:
831
- const selection = action.payload.records || getSelection(stateManager);
832
- if (selection) {
833
- const newState = new Map(currentState);
834
- selection.forEach(recordId => {
835
- const newChanges = Object.assign(Object.assign({}, newState.get(recordId)), action.payload);
836
- delete newChanges.records;
837
- newState.set(recordId, newChanges);
838
- });
839
- return newState;
840
- }
841
- return currentState;
842
- case exports.Action.DATA_SAVED:
843
- case exports.Action.EDITION_CANCELED:
844
- return undefined;
845
- }
846
- return currentState;
847
- }
848
- }
849
- const ChangesReducer = new ChangesReducerImpl();
850
- const getChanges = (stateManager) => {
851
- return stateManager.select(ChangesReducer.sliceName, (state) => state);
852
- };
853
- const isDirty = (stateManager) => {
854
- if (getAddedRecords(stateManager) !== undefined) {
855
- return true;
856
- }
857
- if (getRemovedRecords(stateManager) !== undefined) {
858
- return true;
859
- }
860
- return getChanges(stateManager) !== undefined;
861
- };
862
- const getChangesToSave = (dataUnit, stateManager) => {
863
- const result = [];
864
- const changes = getChanges(stateManager);
865
- const records = getRecords(stateManager);
866
- records === null || records === void 0 ? void 0 : records.forEach(r => {
867
- if (changes) {
868
- const c = changes.get(r.__record__id__);
869
- if (c) {
870
- result.push(new Change(dataUnit, r, c, ChangeOperation.UPDATE));
871
- }
872
- }
873
- });
874
- const addedRecords = getAddedRecords(stateManager);
875
- if (addedRecords) {
876
- addedRecords.forEach(r => {
877
- result.push(new Change(dataUnit, r, changes === null || changes === void 0 ? void 0 : changes.get(r.__record__id__), ChangeOperation.INSERT));
878
- });
879
- }
880
- const removedRecords = getRemovedRecords(stateManager);
881
- const recordsById = {};
882
- records === null || records === void 0 ? void 0 : records.forEach(r => recordsById[r.__record__id__] = r);
883
- if (removedRecords) {
884
- removedRecords.forEach(id => {
885
- result.push(new Change(dataUnit, recordsById[id], undefined, ChangeOperation.DELETE));
886
- });
887
- }
888
- return result;
824
+ class ChangesReducerImpl {
825
+ constructor() {
826
+ this.sliceName = "hist::changes";
827
+ }
828
+ reduce(stateManager, currentState, action) {
829
+ switch (action.type) {
830
+ case exports.Action.DATA_CHANGED:
831
+ const selection = action.payload.records || getSelection(stateManager);
832
+ if (selection) {
833
+ const newState = new Map(currentState);
834
+ selection.forEach(recordId => {
835
+ const newChanges = Object.assign(Object.assign({}, newState.get(recordId)), action.payload);
836
+ delete newChanges.records;
837
+ newState.set(recordId, newChanges);
838
+ });
839
+ return newState;
840
+ }
841
+ return currentState;
842
+ case exports.Action.DATA_SAVED:
843
+ case exports.Action.EDITION_CANCELED:
844
+ return undefined;
845
+ }
846
+ return currentState;
847
+ }
848
+ }
849
+ const ChangesReducer = new ChangesReducerImpl();
850
+ const getChanges = (stateManager) => {
851
+ return stateManager.select(ChangesReducer.sliceName, (state) => state);
852
+ };
853
+ const isDirty = (stateManager) => {
854
+ if (getAddedRecords(stateManager) !== undefined) {
855
+ return true;
856
+ }
857
+ if (getRemovedRecords(stateManager) !== undefined) {
858
+ return true;
859
+ }
860
+ return getChanges(stateManager) !== undefined;
861
+ };
862
+ const getChangesToSave = (dataUnit, stateManager) => {
863
+ const result = [];
864
+ const changes = getChanges(stateManager);
865
+ const records = getRecords(stateManager);
866
+ records === null || records === void 0 ? void 0 : records.forEach(r => {
867
+ if (changes) {
868
+ const c = changes.get(r.__record__id__);
869
+ if (c) {
870
+ result.push(new Change(dataUnit, r, c, ChangeOperation.UPDATE));
871
+ }
872
+ }
873
+ });
874
+ const addedRecords = getAddedRecords(stateManager);
875
+ if (addedRecords) {
876
+ addedRecords.forEach(r => {
877
+ result.push(new Change(dataUnit, r, changes === null || changes === void 0 ? void 0 : changes.get(r.__record__id__), ChangeOperation.INSERT));
878
+ });
879
+ }
880
+ const removedRecords = getRemovedRecords(stateManager);
881
+ const recordsById = {};
882
+ records === null || records === void 0 ? void 0 : records.forEach(r => recordsById[r.__record__id__] = r);
883
+ if (removedRecords) {
884
+ removedRecords.forEach(id => {
885
+ result.push(new Change(dataUnit, recordsById[id], undefined, ChangeOperation.DELETE));
886
+ });
887
+ }
888
+ return result;
889
889
  };
890
890
 
891
- class CurrentRecordsReducerImpl {
892
- constructor() {
893
- this.sliceName = "currentRecords";
894
- }
895
- reduce(stateManager, _currentState, _action) {
896
- let records = getRecords(stateManager);
897
- const added = getAddedRecords(stateManager);
898
- if (!records && !added) {
899
- return undefined;
900
- }
901
- if (added) {
902
- records = (records || []).concat(added);
903
- }
904
- const removedRecords = getRemovedRecords(stateManager);
905
- if (removedRecords) {
906
- records = records.filter(r => !removedRecords.includes(r.__record__id__));
907
- }
908
- const changes = getChanges(stateManager);
909
- return new Map(records.map(r => {
910
- const recordId = r.__record__id__;
911
- const record = Object.assign(Object.assign({}, r), changes === null || changes === void 0 ? void 0 : changes.get(recordId));
912
- return [recordId, record];
913
- }));
914
- }
915
- }
916
- const CurrentRecordsReducer = new CurrentRecordsReducerImpl();
917
- const getCurrentRecords = (stateManager) => {
918
- return stateManager.select(CurrentRecordsReducer.sliceName, (state) => state);
919
- };
920
- const getFieldValue = (stateManager, fieldName) => {
921
- const selection = getSelection(stateManager);
922
- if (selection && selection.length > 0) {
923
- const currentRecords = getCurrentRecords(stateManager);
924
- if (currentRecords) {
925
- const record = currentRecords.get(selection[0]);
926
- return record ? record[fieldName] : undefined;
927
- }
928
- }
929
- return undefined;
891
+ class CurrentRecordsReducerImpl {
892
+ constructor() {
893
+ this.sliceName = "currentRecords";
894
+ }
895
+ reduce(stateManager) {
896
+ let records = getRecords(stateManager);
897
+ const added = getAddedRecords(stateManager);
898
+ if (!records && !added) {
899
+ return undefined;
900
+ }
901
+ if (added) {
902
+ records = (records || []).concat(added);
903
+ }
904
+ const removedRecords = getRemovedRecords(stateManager);
905
+ if (removedRecords) {
906
+ records = records.filter(r => !removedRecords.includes(r.__record__id__));
907
+ }
908
+ const changes = getChanges(stateManager);
909
+ return new Map(records.map(r => {
910
+ const recordId = r.__record__id__;
911
+ const record = Object.assign(Object.assign({}, r), changes === null || changes === void 0 ? void 0 : changes.get(recordId));
912
+ return [recordId, record];
913
+ }));
914
+ }
915
+ }
916
+ const CurrentRecordsReducer = new CurrentRecordsReducerImpl();
917
+ const getCurrentRecords = (stateManager) => {
918
+ return stateManager.select(CurrentRecordsReducer.sliceName, (state) => state);
919
+ };
920
+ const getFieldValue = (stateManager, fieldName) => {
921
+ const selection = getSelection(stateManager);
922
+ if (selection && selection.length > 0) {
923
+ const currentRecords = getCurrentRecords(stateManager);
924
+ if (currentRecords) {
925
+ const record = currentRecords.get(selection[0]);
926
+ return record ? record[fieldName] : undefined;
927
+ }
928
+ }
929
+ return undefined;
930
930
  };
931
931
 
932
- class SelectionReducerImpl {
933
- constructor() {
934
- this.sliceName = "hist::selection";
935
- }
936
- reduce(stateManager, currentState, action) {
937
- switch (action.type) {
938
- case exports.Action.RECORDS_ADDED:
939
- case exports.Action.RECORDS_COPIED:
940
- return action.payload.map((r) => r.__record__id__);
941
- case exports.Action.DATA_SAVED:
942
- return updateSavedIds(stateManager, action.payload.records);
943
- case exports.Action.RECORDS_REMOVED:
944
- const removed = action.payload.records;
945
- if (currentState && removed) {
946
- return currentState.filter(recordId => !removed.includes(recordId));
947
- }
948
- return currentState;
949
- case exports.Action.NEXT_SELECTED:
950
- case exports.Action.PREVIOUS_SELECTED:
951
- const currentRecords = getCurrentRecords(stateManager);
952
- if (currentRecords && currentRecords.size > 0) {
953
- let index;
954
- if (!currentState || currentState.length === 0) {
955
- index = action.type === exports.Action.PREVIOUS_SELECTED ? 0 : Math.min(1, currentRecords.size);
956
- }
957
- else {
958
- index = getItemIndex(currentState[0], currentRecords) + (action.type === exports.Action.PREVIOUS_SELECTED ? -1 : 1);
959
- }
960
- if (index < currentRecords.size && index >= 0) {
961
- return [Array.from(currentRecords.values())[index].__record__id__];
962
- }
963
- }
964
- return undefined;
965
- case exports.Action.SELECTION_CHANGED:
966
- const { type, selection: selectionSource } = action.payload;
967
- if (selectionSource && type === "index") {
968
- const currentRecords = getCurrentRecords(stateManager);
969
- if (currentRecords) {
970
- const records = Array.from(currentRecords.values());
971
- const selectionById = [];
972
- selectionSource.forEach((i) => {
973
- if (i > 0 && i < currentRecords.size) {
974
- selectionById.push(records[i].__record__id__);
975
- }
976
- });
977
- return selectionById;
978
- }
979
- }
980
- return selectionSource;
981
- }
982
- return currentState;
983
- }
984
- }
985
- const SelectionReducer = new SelectionReducerImpl();
986
- const getSelection = (stateManager) => {
987
- let selection = stateManager.select(SelectionReducer.sliceName, (state) => state);
988
- const currentRecords = Array.from((getCurrentRecords(stateManager) || new Map()).keys());
989
- if (selection) {
990
- selection = selection.filter(id => currentRecords.includes(id));
991
- }
992
- if (!selection || selection.length === 0) {
993
- if (currentRecords && currentRecords.length > 0) {
994
- return [currentRecords[0]];
995
- }
996
- }
997
- return selection;
998
- };
999
- const hasNext = (stateManager) => {
1000
- const records = getCurrentRecords(stateManager);
1001
- if (records) {
1002
- const selection = stateManager.select(SelectionReducer.sliceName, (state) => state);
1003
- if (!selection || selection.length === 0) {
1004
- return records.size > 0;
1005
- }
1006
- return records.size > (getItemIndex(selection[0], records) + 1);
1007
- }
1008
- return false;
1009
- };
1010
- const hasPrevious = (stateManager) => {
1011
- const records = getCurrentRecords(stateManager);
1012
- if (records) {
1013
- const selection = stateManager.select(SelectionReducer.sliceName, (state) => state);
1014
- if (!selection || selection.length === 0) {
1015
- return false;
1016
- }
1017
- return getItemIndex(selection[0], records) > 0;
1018
- }
1019
- return false;
1020
- };
1021
- function getItemIndex(key, map) {
1022
- return Array.from(map.keys()).indexOf(key);
1023
- }
1024
- function updateSavedIds(stateManager, savedRecords) {
1025
- const currentSelection = getSelection(stateManager);
1026
- if (currentSelection) {
1027
- const newSelection = [];
1028
- currentSelection.forEach(id => {
1029
- const record = savedRecords.find(r => r.__old__id__ === id);
1030
- if (record) {
1031
- newSelection.push(record.__record__id__);
1032
- }
1033
- else {
1034
- newSelection.push(id);
1035
- }
1036
- });
1037
- return newSelection;
1038
- }
1039
- return currentSelection;
932
+ class SelectionReducerImpl {
933
+ constructor() {
934
+ this.sliceName = "hist::selection";
935
+ }
936
+ reduce(stateManager, currentState, action) {
937
+ switch (action.type) {
938
+ case exports.Action.RECORDS_ADDED:
939
+ case exports.Action.RECORDS_COPIED:
940
+ return action.payload.map((r) => r.__record__id__);
941
+ case exports.Action.DATA_SAVED:
942
+ return updateSavedIds(stateManager, action.payload.records);
943
+ case exports.Action.RECORDS_REMOVED:
944
+ const removed = action.payload.records;
945
+ if (currentState && removed) {
946
+ return currentState.filter(recordId => !removed.includes(recordId));
947
+ }
948
+ return currentState;
949
+ case exports.Action.NEXT_SELECTED:
950
+ case exports.Action.PREVIOUS_SELECTED:
951
+ const currentRecords = getCurrentRecords(stateManager);
952
+ if (currentRecords && currentRecords.size > 0) {
953
+ let index;
954
+ if (!currentState || currentState.length === 0) {
955
+ index = action.type === exports.Action.PREVIOUS_SELECTED ? 0 : Math.min(1, currentRecords.size);
956
+ }
957
+ else {
958
+ index = getItemIndex(currentState[0], currentRecords) + (action.type === exports.Action.PREVIOUS_SELECTED ? -1 : 1);
959
+ }
960
+ if (index < currentRecords.size && index >= 0) {
961
+ return [Array.from(currentRecords.values())[index].__record__id__];
962
+ }
963
+ }
964
+ return undefined;
965
+ case exports.Action.SELECTION_CHANGED:
966
+ const { type, selection: selectionSource } = action.payload;
967
+ if (selectionSource && type === "index") {
968
+ const currentRecords = getCurrentRecords(stateManager);
969
+ if (currentRecords) {
970
+ const records = Array.from(currentRecords.values());
971
+ const selectionById = [];
972
+ selectionSource.forEach((i) => {
973
+ if (i > 0 && i < currentRecords.size) {
974
+ selectionById.push(records[i].__record__id__);
975
+ }
976
+ });
977
+ return selectionById;
978
+ }
979
+ }
980
+ return selectionSource;
981
+ }
982
+ return currentState;
983
+ }
984
+ }
985
+ const SelectionReducer = new SelectionReducerImpl();
986
+ const getSelection = (stateManager) => {
987
+ let selection = stateManager.select(SelectionReducer.sliceName, (state) => state);
988
+ const currentRecords = Array.from((getCurrentRecords(stateManager) || new Map()).keys());
989
+ if (selection) {
990
+ selection = selection.filter(id => currentRecords.includes(id));
991
+ }
992
+ if (!selection || selection.length === 0) {
993
+ if (currentRecords && currentRecords.length > 0) {
994
+ return [currentRecords[0]];
995
+ }
996
+ }
997
+ return selection;
998
+ };
999
+ const hasNext = (stateManager) => {
1000
+ const records = getCurrentRecords(stateManager);
1001
+ if (records) {
1002
+ const selection = stateManager.select(SelectionReducer.sliceName, (state) => state);
1003
+ if (!selection || selection.length === 0) {
1004
+ return records.size > 0;
1005
+ }
1006
+ return records.size > (getItemIndex(selection[0], records) + 1);
1007
+ }
1008
+ return false;
1009
+ };
1010
+ const hasPrevious = (stateManager) => {
1011
+ const records = getCurrentRecords(stateManager);
1012
+ if (records) {
1013
+ const selection = stateManager.select(SelectionReducer.sliceName, (state) => state);
1014
+ if (!selection || selection.length === 0) {
1015
+ return false;
1016
+ }
1017
+ return getItemIndex(selection[0], records) > 0;
1018
+ }
1019
+ return false;
1020
+ };
1021
+ function getItemIndex(key, map) {
1022
+ return Array.from(map.keys()).indexOf(key);
1023
+ }
1024
+ function updateSavedIds(stateManager, savedRecords) {
1025
+ const currentSelection = getSelection(stateManager);
1026
+ if (currentSelection) {
1027
+ const newSelection = [];
1028
+ currentSelection.forEach(id => {
1029
+ const record = savedRecords.find(r => r.__old__id__ === id);
1030
+ if (record) {
1031
+ newSelection.push(record.__record__id__);
1032
+ }
1033
+ else {
1034
+ newSelection.push(id);
1035
+ }
1036
+ });
1037
+ return newSelection;
1038
+ }
1039
+ return currentSelection;
1040
1040
  }
1041
1041
 
1042
- var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
1043
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1044
- return new (P || (P = Promise))(function (resolve, reject) {
1045
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1046
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1047
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1048
- step((generator = generator.apply(thisArg, _arguments || [])).next());
1049
- });
1050
- };
1051
- class DataUnit {
1052
- constructor(name) {
1053
- this._name = name;
1054
- this._stateManager = new StateManager([
1055
- HistReducer,
1056
- UnitMetadataReducer,
1057
- RecordsReducer,
1058
- RemovedRecordsReducer,
1059
- AddedRecordsReducer,
1060
- SelectionReducer,
1061
- ChangesReducer,
1062
- CurrentRecordsReducer
1063
- ]);
1064
- this._observers = [];
1065
- this._filterProviders = [];
1066
- this._sortingProvider = undefined;
1067
- this._interceptors = [];
1068
- }
1069
- get name() {
1070
- return this._name;
1071
- }
1072
- // Métodos privados
1073
- validateAndTypeValue(fieldName, newValue) {
1074
- //FIXME: Validações devem ser feitas aqui
1075
- const descriptor = this.getField(fieldName);
1076
- return descriptor ? convertType(descriptor.dataType, newValue) : newValue;
1077
- }
1078
- getFilters() {
1079
- let filters = undefined;
1080
- this._filterProviders.forEach(p => {
1081
- const f = p.getFilter(this.name);
1082
- if (f) {
1083
- filters = (filters || []).concat(f);
1084
- }
1085
- });
1086
- return filters;
1087
- }
1088
- getSort() {
1089
- return this._sortingProvider ? this._sortingProvider.getSort(this._name) : undefined;
1090
- }
1091
- // Loaders
1092
- loadMetadata() {
1093
- return __awaiter(this, void 0, void 0, function* () {
1094
- this.dispatchAction(exports.Action.LOADING_METADATA);
1095
- return new Promise((resolve, fail) => {
1096
- if (this.metadataLoader) {
1097
- this.metadataLoader(this).then(metadata => {
1098
- this.metadata = metadata;
1099
- resolve(this.metadata);
1100
- }).catch(error => fail(error));
1101
- }
1102
- });
1103
- });
1104
- }
1105
- loadData() {
1106
- return __awaiter(this, void 0, void 0, function* () {
1107
- this.dispatchAction(exports.Action.LOADING_DATA);
1108
- return new Promise((resolve, fail) => {
1109
- if (this.dataLoader) {
1110
- const sort = this.getSort();
1111
- const filters = this.getFilters();
1112
- this.dataLoader(this, sort, filters).then(records => {
1113
- this.records = records;
1114
- resolve(this.records);
1115
- }).catch(error => fail(error));
1116
- }
1117
- });
1118
- });
1119
- }
1120
- saveData() {
1121
- return __awaiter(this, void 0, void 0, function* () {
1122
- const changes = getChangesToSave(this._name, this._stateManager);
1123
- if (changes.length > 0) {
1124
- this.dispatchAction(exports.Action.SAVING_DATA);
1125
- return new Promise((resolve, fail) => {
1126
- if (this.saveLoader) {
1127
- this.saveLoader(this, changes).then(records => this.dispatchAction(exports.Action.DATA_SAVED, { changes, records })).catch(error => fail(error));
1128
- }
1129
- });
1130
- }
1131
- return Promise.resolve();
1132
- });
1133
- }
1134
- removeSelectedRecords(buffered = false) {
1135
- return __awaiter(this, void 0, void 0, function* () {
1136
- const selection = getSelection(this._stateManager);
1137
- if (selection) {
1138
- return this.removeRecords(selection, buffered);
1139
- }
1140
- return Promise.resolve(selection);
1141
- });
1142
- }
1143
- removeRecords(records, buffered = false) {
1144
- return __awaiter(this, void 0, void 0, function* () {
1145
- if (records) {
1146
- if (buffered || !this.removeLoader) {
1147
- this.dispatchAction(exports.Action.RECORDS_REMOVED, { records, buffered: true });
1148
- }
1149
- else {
1150
- this.dispatchAction(exports.Action.REMOVING_RECORDS);
1151
- return new Promise((resolve, fail) => {
1152
- if (this.removeLoader) {
1153
- this.removeLoader(this, records).then(records => {
1154
- this.dispatchAction(exports.Action.RECORDS_REMOVED, { records, buffered: false });
1155
- resolve(records);
1156
- }).catch(error => fail(error));
1157
- }
1158
- });
1159
- }
1160
- }
1161
- return Promise.resolve(records);
1162
- });
1163
- }
1164
- // API
1165
- valueFromString(fieldName, value) {
1166
- const descriptor = this.getField(fieldName);
1167
- return descriptor ? convertType(descriptor.dataType, value) : value;
1168
- }
1169
- addInterceptor(interceptor) {
1170
- this._interceptors.push(interceptor);
1171
- }
1172
- addFilterProvider(provider) {
1173
- this._filterProviders.push(provider);
1174
- }
1175
- set sortingProvider(provider) {
1176
- this._sortingProvider = provider;
1177
- }
1178
- set metadata(md) {
1179
- this.dispatchAction(exports.Action.METADATA_LOADED, md);
1180
- }
1181
- get metadata() {
1182
- return getMetadata(this._stateManager);
1183
- }
1184
- set records(r) {
1185
- this.dispatchAction(exports.Action.DATA_LOADED, r);
1186
- }
1187
- get records() {
1188
- const records = getCurrentRecords(this._stateManager);
1189
- return records ? Array.from(records.values()) : [];
1190
- }
1191
- getField(fieldName) {
1192
- return getField(this._stateManager, fieldName);
1193
- }
1194
- addRecord() {
1195
- this.dispatchAction(exports.Action.RECORDS_ADDED, prepareAddedRecordId(this._stateManager, [{}]));
1196
- }
1197
- copySelected() {
1198
- const selectedRecords = this.getSelectedRecords();
1199
- if (selectedRecords) {
1200
- this.dispatchAction(exports.Action.RECORDS_COPIED, prepareAddedRecordId(this._stateManager, selectedRecords));
1201
- }
1202
- }
1203
- getFieldValue(fieldName) {
1204
- return getFieldValue(this._stateManager, fieldName);
1205
- }
1206
- setFieldValue(fieldName, newValue, records) {
1207
- const typedValue = this.validateAndTypeValue(fieldName, newValue);
1208
- const currentValue = this.getFieldValue(fieldName);
1209
- if (currentValue !== typedValue) {
1210
- this.dispatchAction(exports.Action.DATA_CHANGED, { [fieldName]: typedValue, records });
1211
- }
1212
- }
1213
- getSelection() {
1214
- return getSelection(this._stateManager);
1215
- }
1216
- setSelection(selection) {
1217
- this.dispatchAction(exports.Action.SELECTION_CHANGED, { type: "id", selection });
1218
- }
1219
- setSelectionByIndex(selection) {
1220
- this.dispatchAction(exports.Action.SELECTION_CHANGED, { type: "index", selection });
1221
- }
1222
- getSelectedRecords() {
1223
- const selection = this.getSelection();
1224
- if (selection) {
1225
- const currentRecords = this.records;
1226
- return currentRecords === null || currentRecords === void 0 ? void 0 : currentRecords.filter(r => selection.includes(r.__record__id__));
1227
- }
1228
- }
1229
- nextRecord() {
1230
- this.dispatchAction(exports.Action.NEXT_SELECTED);
1231
- }
1232
- previousRecord() {
1233
- this.dispatchAction(exports.Action.PREVIOUS_SELECTED);
1234
- }
1235
- cancelEdition() {
1236
- this.dispatchAction(exports.Action.EDITION_CANCELED);
1237
- }
1238
- isDirty() {
1239
- return isDirty(this._stateManager);
1240
- }
1241
- hasNext() {
1242
- return hasNext(this._stateManager);
1243
- }
1244
- hasPrevious() {
1245
- return hasPrevious(this._stateManager);
1246
- }
1247
- canUndo() {
1248
- return canUndo(this._stateManager);
1249
- }
1250
- canRedo() {
1251
- return canRedo(this._stateManager);
1252
- }
1253
- undo() {
1254
- this.dispatchAction(exports.Action.CHANGE_UNDONE);
1255
- }
1256
- redo() {
1257
- this.dispatchAction(exports.Action.CHANGE_REDONE);
1258
- }
1259
- toString() {
1260
- return this.name;
1261
- }
1262
- // Actions / State manager
1263
- dispatchAction(actionType, payload) {
1264
- var _a;
1265
- let action = new DataUnitAction(actionType, payload);
1266
- (_a = this._interceptors) === null || _a === void 0 ? void 0 : _a.forEach(interceptor => {
1267
- if (action) {
1268
- action = interceptor.interceptAction(action);
1269
- }
1270
- });
1271
- if (action) {
1272
- this._stateManager.process(action);
1273
- this._observers.forEach(f => f(action));
1274
- }
1275
- }
1276
- subscribe(observer) {
1277
- this._observers.push(observer);
1278
- }
1279
- unsubscribe(observer) {
1280
- this._observers = this._observers.filter(f => f !== observer);
1281
- }
1282
- }
1283
- var ChangeOperation;
1284
- (function (ChangeOperation) {
1285
- ChangeOperation["INSERT"] = "INSERT";
1286
- ChangeOperation["UPDATE"] = "UPDATE";
1287
- ChangeOperation["DELETE"] = "DELETE";
1288
- })(ChangeOperation || (ChangeOperation = {}));
1289
- class Change {
1290
- constructor(dataUnit, record, updates, operation) {
1291
- this.dataUnit = dataUnit;
1292
- this.record = record;
1293
- this.updatingFields = updates;
1294
- this._operation = operation;
1295
- }
1296
- get operation() {
1297
- return this._operation.toString();
1298
- }
1299
- isInsert() {
1300
- return this._operation === ChangeOperation.INSERT;
1301
- }
1302
- isDelete() {
1303
- return this._operation === ChangeOperation.DELETE;
1304
- }
1305
- isUpdate() {
1306
- return this._operation === ChangeOperation.UPDATE;
1307
- }
1042
+ var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
1043
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1044
+ return new (P || (P = Promise))(function (resolve, reject) {
1045
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1046
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1047
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1048
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
1049
+ });
1050
+ };
1051
+ class DataUnit {
1052
+ constructor(name) {
1053
+ this._name = name;
1054
+ this._stateManager = new StateManager([
1055
+ HistReducer,
1056
+ UnitMetadataReducer,
1057
+ RecordsReducer,
1058
+ RemovedRecordsReducer,
1059
+ AddedRecordsReducer,
1060
+ SelectionReducer,
1061
+ ChangesReducer,
1062
+ CurrentRecordsReducer
1063
+ ]);
1064
+ this._observers = [];
1065
+ this._filterProviders = [];
1066
+ this._sortingProvider = undefined;
1067
+ this._interceptors = [];
1068
+ }
1069
+ get name() {
1070
+ return this._name;
1071
+ }
1072
+ // Métodos privados
1073
+ validateAndTypeValue(fieldName, newValue) {
1074
+ //FIXME: Validações devem ser feitas aqui
1075
+ const descriptor = this.getField(fieldName);
1076
+ return descriptor ? convertType(descriptor.dataType, newValue) : newValue;
1077
+ }
1078
+ getFilters() {
1079
+ let filters = undefined;
1080
+ this._filterProviders.forEach(p => {
1081
+ const f = p.getFilter(this.name);
1082
+ if (f) {
1083
+ filters = (filters || []).concat(f);
1084
+ }
1085
+ });
1086
+ return filters;
1087
+ }
1088
+ getSort() {
1089
+ return this._sortingProvider ? this._sortingProvider.getSort(this._name) : undefined;
1090
+ }
1091
+ // Loaders
1092
+ loadMetadata() {
1093
+ return __awaiter(this, void 0, void 0, function* () {
1094
+ this.dispatchAction(exports.Action.LOADING_METADATA);
1095
+ return new Promise((resolve, fail) => {
1096
+ if (this.metadataLoader) {
1097
+ this.metadataLoader(this).then(metadata => {
1098
+ this.metadata = metadata;
1099
+ resolve(this.metadata);
1100
+ }).catch(error => fail(error));
1101
+ }
1102
+ });
1103
+ });
1104
+ }
1105
+ loadData() {
1106
+ return __awaiter(this, void 0, void 0, function* () {
1107
+ this.dispatchAction(exports.Action.LOADING_DATA);
1108
+ return new Promise((resolve, fail) => {
1109
+ if (this.dataLoader) {
1110
+ const sort = this.getSort();
1111
+ const filters = this.getFilters();
1112
+ this.dataLoader(this, sort, filters).then(records => {
1113
+ this.records = records;
1114
+ resolve(this.records);
1115
+ }).catch(error => fail(error));
1116
+ }
1117
+ });
1118
+ });
1119
+ }
1120
+ saveData() {
1121
+ return __awaiter(this, void 0, void 0, function* () {
1122
+ const changes = getChangesToSave(this._name, this._stateManager);
1123
+ if (changes.length > 0) {
1124
+ this.dispatchAction(exports.Action.SAVING_DATA);
1125
+ return new Promise((resolve, fail) => {
1126
+ if (this.saveLoader) {
1127
+ this.saveLoader(this, changes).then(records => this.dispatchAction(exports.Action.DATA_SAVED, { changes, records })).catch(error => fail(error));
1128
+ }
1129
+ });
1130
+ }
1131
+ return Promise.resolve();
1132
+ });
1133
+ }
1134
+ removeSelectedRecords(buffered = false) {
1135
+ return __awaiter(this, void 0, void 0, function* () {
1136
+ const selection = getSelection(this._stateManager);
1137
+ if (selection) {
1138
+ return this.removeRecords(selection, buffered);
1139
+ }
1140
+ return Promise.resolve(selection);
1141
+ });
1142
+ }
1143
+ removeRecords(records, buffered = false) {
1144
+ return __awaiter(this, void 0, void 0, function* () {
1145
+ if (records) {
1146
+ if (buffered || !this.removeLoader) {
1147
+ this.dispatchAction(exports.Action.RECORDS_REMOVED, { records, buffered: true });
1148
+ }
1149
+ else {
1150
+ this.dispatchAction(exports.Action.REMOVING_RECORDS);
1151
+ return new Promise((resolve, fail) => {
1152
+ if (this.removeLoader) {
1153
+ this.removeLoader(this, records).then(records => {
1154
+ this.dispatchAction(exports.Action.RECORDS_REMOVED, { records, buffered: false });
1155
+ resolve(records);
1156
+ }).catch(error => fail(error));
1157
+ }
1158
+ });
1159
+ }
1160
+ }
1161
+ return Promise.resolve(records);
1162
+ });
1163
+ }
1164
+ // API
1165
+ valueFromString(fieldName, value) {
1166
+ const descriptor = this.getField(fieldName);
1167
+ return descriptor ? convertType(descriptor.dataType, value) : value;
1168
+ }
1169
+ addInterceptor(interceptor) {
1170
+ this._interceptors.push(interceptor);
1171
+ }
1172
+ addFilterProvider(provider) {
1173
+ this._filterProviders.push(provider);
1174
+ }
1175
+ set sortingProvider(provider) {
1176
+ this._sortingProvider = provider;
1177
+ }
1178
+ set metadata(md) {
1179
+ this.dispatchAction(exports.Action.METADATA_LOADED, md);
1180
+ }
1181
+ get metadata() {
1182
+ return getMetadata(this._stateManager);
1183
+ }
1184
+ set records(r) {
1185
+ this.dispatchAction(exports.Action.DATA_LOADED, r);
1186
+ }
1187
+ get records() {
1188
+ const records = getCurrentRecords(this._stateManager);
1189
+ return records ? Array.from(records.values()) : [];
1190
+ }
1191
+ getField(fieldName) {
1192
+ return getField(this._stateManager, fieldName);
1193
+ }
1194
+ addRecord() {
1195
+ this.dispatchAction(exports.Action.RECORDS_ADDED, prepareAddedRecordId(this._stateManager, [{}]));
1196
+ }
1197
+ copySelected() {
1198
+ const selectedRecords = this.getSelectedRecords();
1199
+ if (selectedRecords) {
1200
+ this.dispatchAction(exports.Action.RECORDS_COPIED, prepareAddedRecordId(this._stateManager, selectedRecords));
1201
+ }
1202
+ }
1203
+ getFieldValue(fieldName) {
1204
+ return getFieldValue(this._stateManager, fieldName);
1205
+ }
1206
+ setFieldValue(fieldName, newValue, records) {
1207
+ const typedValue = this.validateAndTypeValue(fieldName, newValue);
1208
+ const currentValue = this.getFieldValue(fieldName);
1209
+ if (currentValue !== typedValue) {
1210
+ this.dispatchAction(exports.Action.DATA_CHANGED, { [fieldName]: typedValue, records });
1211
+ }
1212
+ }
1213
+ getSelection() {
1214
+ return getSelection(this._stateManager);
1215
+ }
1216
+ setSelection(selection) {
1217
+ this.dispatchAction(exports.Action.SELECTION_CHANGED, { type: "id", selection });
1218
+ }
1219
+ setSelectionByIndex(selection) {
1220
+ this.dispatchAction(exports.Action.SELECTION_CHANGED, { type: "index", selection });
1221
+ }
1222
+ getSelectedRecords() {
1223
+ const selection = this.getSelection();
1224
+ if (selection) {
1225
+ const currentRecords = this.records;
1226
+ return currentRecords === null || currentRecords === void 0 ? void 0 : currentRecords.filter(r => selection.includes(r.__record__id__));
1227
+ }
1228
+ }
1229
+ nextRecord() {
1230
+ this.dispatchAction(exports.Action.NEXT_SELECTED);
1231
+ }
1232
+ previousRecord() {
1233
+ this.dispatchAction(exports.Action.PREVIOUS_SELECTED);
1234
+ }
1235
+ cancelEdition() {
1236
+ this.dispatchAction(exports.Action.EDITION_CANCELED);
1237
+ }
1238
+ isDirty() {
1239
+ return isDirty(this._stateManager);
1240
+ }
1241
+ hasNext() {
1242
+ return hasNext(this._stateManager);
1243
+ }
1244
+ hasPrevious() {
1245
+ return hasPrevious(this._stateManager);
1246
+ }
1247
+ canUndo() {
1248
+ return canUndo(this._stateManager);
1249
+ }
1250
+ canRedo() {
1251
+ return canRedo(this._stateManager);
1252
+ }
1253
+ undo() {
1254
+ this.dispatchAction(exports.Action.CHANGE_UNDONE);
1255
+ }
1256
+ redo() {
1257
+ this.dispatchAction(exports.Action.CHANGE_REDONE);
1258
+ }
1259
+ toString() {
1260
+ return this.name;
1261
+ }
1262
+ // Actions / State manager
1263
+ dispatchAction(actionType, payload) {
1264
+ var _a;
1265
+ let action = new DataUnitAction(actionType, payload);
1266
+ (_a = this._interceptors) === null || _a === void 0 ? void 0 : _a.forEach(interceptor => {
1267
+ if (action) {
1268
+ action = interceptor.interceptAction(action);
1269
+ }
1270
+ });
1271
+ if (action) {
1272
+ this._stateManager.process(action);
1273
+ this._observers.forEach(f => f(action));
1274
+ }
1275
+ }
1276
+ subscribe(observer) {
1277
+ this._observers.push(observer);
1278
+ }
1279
+ unsubscribe(observer) {
1280
+ this._observers = this._observers.filter(f => f !== observer);
1281
+ }
1282
+ }
1283
+ var ChangeOperation;
1284
+ (function (ChangeOperation) {
1285
+ ChangeOperation["INSERT"] = "INSERT";
1286
+ ChangeOperation["UPDATE"] = "UPDATE";
1287
+ ChangeOperation["DELETE"] = "DELETE";
1288
+ })(ChangeOperation || (ChangeOperation = {}));
1289
+ class Change {
1290
+ constructor(dataUnit, record, updates, operation) {
1291
+ this.dataUnit = dataUnit;
1292
+ this.record = record;
1293
+ this.updatingFields = updates;
1294
+ this._operation = operation;
1295
+ }
1296
+ get operation() {
1297
+ return this._operation.toString();
1298
+ }
1299
+ isInsert() {
1300
+ return this._operation === ChangeOperation.INSERT;
1301
+ }
1302
+ isDelete() {
1303
+ return this._operation === ChangeOperation.DELETE;
1304
+ }
1305
+ isUpdate() {
1306
+ return this._operation === ChangeOperation.UPDATE;
1307
+ }
1308
1308
  }
1309
1309
 
1310
- exports.SortMode = void 0;
1311
- (function (SortMode) {
1312
- SortMode["ASC"] = "ASC";
1313
- SortMode["DESC"] = "DESC";
1314
- })(exports.SortMode || (exports.SortMode = {}));
1315
- var DependencyType;
1316
- (function (DependencyType) {
1317
- DependencyType["SEARCHING"] = "SEARCHING";
1318
- DependencyType["REQUIREMENT"] = "REQUIREMENT";
1319
- DependencyType["VISIBILITY"] = "REQUIREMENT";
1320
- })(DependencyType || (DependencyType = {}));
1321
- exports.UserInterface = void 0;
1322
- (function (UserInterface) {
1323
- UserInterface["FILE"] = "FILE";
1324
- UserInterface["IMAGE"] = "IMAGE";
1325
- UserInterface["DATE"] = "DATE";
1326
- UserInterface["DATETIME"] = "DATETIME";
1327
- UserInterface["TIME"] = "TIME";
1328
- UserInterface["ELAPSEDTIME"] = "ELAPSEDTIME";
1329
- UserInterface["CHECKBOX"] = "CHECKBOX";
1330
- UserInterface["SWITCH"] = "SWITCH";
1331
- UserInterface["OPTIONSELECTOR"] = "OPTIONSELECTOR";
1332
- UserInterface["DECIMALNUMBER"] = "DECIMALNUMBER";
1333
- UserInterface["INTEGERNUMBER"] = "INTEGERNUMBER";
1334
- UserInterface["SEARCH"] = "SEARCH";
1335
- UserInterface["SHORTTEXT"] = "SHORTTEXT";
1336
- UserInterface["PASSWORD"] = "PASSWORD";
1337
- UserInterface["MASKEDTEXT"] = "MASKEDTEXT";
1338
- UserInterface["LONGTEXT"] = "LONGTEXT";
1339
- UserInterface["HTML"] = "HTML";
1310
+ exports.SortMode = void 0;
1311
+ (function (SortMode) {
1312
+ SortMode["ASC"] = "ASC";
1313
+ SortMode["DESC"] = "DESC";
1314
+ })(exports.SortMode || (exports.SortMode = {}));
1315
+ var DependencyType;
1316
+ (function (DependencyType) {
1317
+ DependencyType["SEARCHING"] = "SEARCHING";
1318
+ DependencyType["REQUIREMENT"] = "REQUIREMENT";
1319
+ DependencyType["VISIBILITY"] = "REQUIREMENT";
1320
+ })(DependencyType || (DependencyType = {}));
1321
+ exports.UserInterface = void 0;
1322
+ (function (UserInterface) {
1323
+ UserInterface["FILE"] = "FILE";
1324
+ UserInterface["IMAGE"] = "IMAGE";
1325
+ UserInterface["DATE"] = "DATE";
1326
+ UserInterface["DATETIME"] = "DATETIME";
1327
+ UserInterface["TIME"] = "TIME";
1328
+ UserInterface["ELAPSEDTIME"] = "ELAPSEDTIME";
1329
+ UserInterface["CHECKBOX"] = "CHECKBOX";
1330
+ UserInterface["SWITCH"] = "SWITCH";
1331
+ UserInterface["OPTIONSELECTOR"] = "OPTIONSELECTOR";
1332
+ UserInterface["DECIMALNUMBER"] = "DECIMALNUMBER";
1333
+ UserInterface["INTEGERNUMBER"] = "INTEGERNUMBER";
1334
+ UserInterface["SEARCH"] = "SEARCH";
1335
+ UserInterface["SHORTTEXT"] = "SHORTTEXT";
1336
+ UserInterface["PASSWORD"] = "PASSWORD";
1337
+ UserInterface["MASKEDTEXT"] = "MASKEDTEXT";
1338
+ UserInterface["LONGTEXT"] = "LONGTEXT";
1339
+ UserInterface["HTML"] = "HTML";
1340
1340
  })(exports.UserInterface || (exports.UserInterface = {}));
1341
1341
 
1342
1342
  exports.DataUnit = DataUnit;