@sankhyalabs/sankhyablocks 1.1.20 → 1.1.21

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