@sankhyalabs/sankhyablocks 1.3.31-beta.16 → 1.3.31-beta.18
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.
- package/dist/cjs/{SnkMessageBuilder-79cf15c5.js → SnkMessageBuilder-02c2ca02.js} +137 -1
- package/dist/cjs/app-globals-3a1e7e63.js +5 -0
- package/dist/cjs/css-shim-b8158822.js +6 -0
- package/dist/cjs/dom-36862b77.js +75 -0
- package/dist/cjs/filter-item-type.enum-e2e1bc5b.js +14 -0
- package/dist/cjs/index-02201bc9.js +2397 -0
- package/dist/cjs/{index-5575fe3d.js → index-b0b676c5.js} +1598 -145
- package/dist/cjs/loader.cjs.js +18 -2
- package/dist/cjs/sankhyablocks.cjs.js +116 -4
- package/dist/cjs/shadow-css-346c0795.js +389 -0
- package/dist/cjs/snk-application.cjs.entry.js +662 -66
- package/dist/cjs/snk-crud.cjs.entry.js +3 -2
- package/dist/cjs/snk-data-unit.cjs.entry.js +23 -24
- package/dist/cjs/snk-filter-bar.cjs.entry.js +247 -0
- package/dist/cjs/snk-filter-binary-select.cjs.entry.js +47 -0
- package/dist/cjs/snk-filter-detail.cjs.entry.js +49 -0
- package/dist/cjs/snk-filter-item.cjs.entry.js +143 -0
- package/dist/cjs/snk-filter-list.cjs.entry.js +91 -0
- package/dist/cjs/snk-filter-multi-select.cjs.entry.js +23 -0
- package/dist/cjs/snk-filter-number.cjs.entry.js +24 -0
- package/dist/cjs/snk-filter-period.cjs.entry.js +26 -0
- package/dist/cjs/snk-filter-search.cjs.entry.js +44 -0
- package/dist/cjs/snk-filter-text.cjs.entry.js +22 -0
- package/dist/cjs/{snk-form_2.cjs.entry.js → snk-form.cjs.entry.js} +21 -65
- package/dist/cjs/snk-grid.cjs.entry.js +79 -0
- package/dist/cjs/snk-pesquisa.cjs.entry.js +5 -5
- package/dist/cjs/snk-taskbar.cjs.entry.js +17 -13
- package/dist/cjs/{taskbar-elements-2ae0d005.js → taskbar-elements-283c737e.js} +37 -18
- package/dist/cjs/taskbar-processor-6bd0d35c.js +47 -0
- package/dist/cjs/teste-pesquisa.cjs.entry.js +5 -5
- package/dist/collection/collection-manifest.json +10 -0
- package/dist/collection/components/snk-application/errorhandler/snk-error-handler.js +7 -0
- package/dist/collection/components/snk-application/snk-application.js +89 -17
- package/dist/collection/components/snk-crud/snk-crud.js +41 -3
- package/dist/collection/components/snk-filter-bar/filter-item/editors/snk-filter-binary-select.js +88 -0
- package/dist/collection/components/snk-filter-bar/filter-item/editors/snk-filter-multi-select.js +64 -0
- package/dist/collection/components/snk-filter-bar/filter-item/editors/snk-filter-number.js +65 -0
- package/dist/collection/components/snk-filter-bar/filter-item/editors/snk-filter-period.js +69 -0
- package/dist/collection/components/snk-filter-bar/filter-item/editors/snk-filter-search.js +118 -0
- package/dist/collection/components/snk-filter-bar/filter-item/editors/snk-filter-text.js +63 -0
- package/dist/collection/components/snk-filter-bar/filter-item/filter-item-type.enum.js +10 -0
- package/dist/collection/components/snk-filter-bar/filter-item/snk-filter-detail.js +118 -0
- package/dist/collection/components/snk-filter-bar/filter-item/snk-filter-item.js +244 -0
- package/dist/collection/components/snk-filter-bar/filter-list/snk-filter-list.js +233 -0
- package/dist/collection/components/snk-filter-bar/snk-filter-bar.css +114 -0
- package/dist/collection/components/snk-filter-bar/snk-filter-bar.js +305 -0
- package/dist/collection/components/snk-form/snk-form.js +41 -1
- package/dist/collection/components/snk-grid/snk-grid.css +14 -1
- package/dist/collection/components/snk-grid/snk-grid.js +35 -3
- package/dist/collection/components/snk-taskbar/elements/taskbar-elements.js +35 -17
- package/dist/collection/components/snk-taskbar/processor/taskbar-processor.js +43 -0
- package/dist/collection/components/snk-taskbar/snk-taskbar.js +36 -11
- package/dist/collection/lib/http/data-fetcher/DataFetcher.js +24 -2
- package/dist/collection/lib/http/data-fetcher/fetchers/dataunit-fetcher.js +1 -1
- package/dist/collection/lib/http/data-fetcher/fetchers/filter-bar-config-fetcher.js +388 -0
- package/dist/collection/lib/message/SnkMessageBuilder.js +3 -1
- package/dist/collection/lib/message/resources/snk-filter-bar.msg.js +18 -0
- package/dist/components/SnkMessageBuilder.js +137 -2
- package/dist/components/filter-item-type.enum.js +12 -0
- package/dist/components/index.d.ts +10 -0
- package/dist/components/index.js +14 -0
- package/dist/components/index2.js +2384 -0
- package/dist/components/snk-application2.js +628 -30
- package/dist/components/snk-crud.js +29 -3
- package/dist/components/snk-data-unit.js +2 -3
- package/dist/components/snk-filter-bar.d.ts +11 -0
- package/dist/components/snk-filter-bar.js +6 -0
- package/dist/components/snk-filter-bar2.js +278 -0
- package/dist/components/snk-filter-binary-select.d.ts +11 -0
- package/dist/components/snk-filter-binary-select.js +63 -0
- package/dist/components/snk-filter-detail.d.ts +11 -0
- package/dist/components/snk-filter-detail.js +6 -0
- package/dist/components/snk-filter-detail2.js +63 -0
- package/dist/components/snk-filter-item.d.ts +11 -0
- package/dist/components/snk-filter-item.js +6 -0
- package/dist/components/snk-filter-item2.js +164 -0
- package/dist/components/snk-filter-list.d.ts +11 -0
- package/dist/components/snk-filter-list.js +6 -0
- package/dist/components/snk-filter-list2.js +111 -0
- package/dist/components/snk-filter-multi-select.d.ts +11 -0
- package/dist/components/snk-filter-multi-select.js +39 -0
- package/dist/components/snk-filter-number.d.ts +11 -0
- package/dist/components/snk-filter-number.js +40 -0
- package/dist/components/snk-filter-period.d.ts +11 -0
- package/dist/components/snk-filter-period.js +42 -0
- package/dist/components/snk-filter-search.d.ts +11 -0
- package/dist/components/snk-filter-search.js +62 -0
- package/dist/components/snk-filter-text.d.ts +11 -0
- package/dist/components/snk-filter-text.js +38 -0
- package/dist/components/snk-form2.js +21 -2
- package/dist/components/snk-grid2.js +42 -7
- package/dist/components/snk-pesquisa2.js +1 -1
- package/dist/components/snk-taskbar2.js +50 -27
- package/dist/components/taskbar-processor.js +45 -0
- package/dist/components/teste-pesquisa.js +1 -1
- package/dist/esm/{SnkMessageBuilder-3cdde541.js → SnkMessageBuilder-65d431bd.js} +137 -2
- package/dist/esm/app-globals-0f993ce5.js +3 -0
- package/dist/esm/css-shim-b3f2ee8d.js +4 -0
- package/dist/esm/dom-665d6011.js +73 -0
- package/dist/esm/filter-item-type.enum-61fbf80a.js +12 -0
- package/dist/esm/index-2b4d2d14.js +3262 -0
- package/dist/esm/index-e5b61043.js +2384 -0
- package/dist/esm/loader.js +18 -2
- package/dist/esm/sankhyablocks.js +116 -4
- package/dist/esm/shadow-css-b18e99d7.js +387 -0
- package/dist/esm/snk-application.entry.js +627 -31
- package/dist/esm/snk-crud.entry.js +3 -2
- package/dist/esm/snk-data-unit.entry.js +3 -4
- package/dist/esm/snk-filter-bar.entry.js +243 -0
- package/dist/esm/snk-filter-binary-select.entry.js +43 -0
- package/dist/esm/snk-filter-detail.entry.js +45 -0
- package/dist/esm/snk-filter-item.entry.js +139 -0
- package/dist/esm/snk-filter-list.entry.js +87 -0
- package/dist/esm/snk-filter-multi-select.entry.js +19 -0
- package/dist/esm/snk-filter-number.entry.js +20 -0
- package/dist/esm/snk-filter-period.entry.js +22 -0
- package/dist/esm/snk-filter-search.entry.js +40 -0
- package/dist/esm/snk-filter-text.entry.js +18 -0
- package/dist/esm/{snk-form_2.entry.js → snk-form.entry.js} +21 -64
- package/dist/esm/snk-grid.entry.js +75 -0
- package/dist/esm/snk-pesquisa.entry.js +2 -2
- package/dist/esm/snk-taskbar.entry.js +16 -12
- package/dist/esm/taskbar-elements-35d64ff9.js +90 -0
- package/dist/esm/taskbar-processor-aa6772c9.js +45 -0
- package/dist/esm/teste-pesquisa.entry.js +2 -2
- package/dist/sankhyablocks/SnkMessageBuilder-65d431bd.js +303 -0
- package/dist/sankhyablocks/app-globals-0f993ce5.js +3 -0
- package/dist/sankhyablocks/css-shim-b3f2ee8d.js +4 -0
- package/dist/sankhyablocks/dom-665d6011.js +73 -0
- package/dist/sankhyablocks/filter-item-type.enum-61fbf80a.js +12 -0
- package/dist/sankhyablocks/index-2b4d2d14.js +3262 -0
- package/dist/sankhyablocks/index-e5b61043.js +2384 -0
- package/dist/sankhyablocks/index.esm.js +1 -0
- package/dist/sankhyablocks/sankhyablocks.esm.js +129 -1
- package/dist/sankhyablocks/shadow-css-b18e99d7.js +387 -0
- package/dist/sankhyablocks/snk-application.entry.js +8426 -0
- package/dist/sankhyablocks/snk-crud.entry.js +61 -0
- package/dist/sankhyablocks/snk-data-unit.entry.js +272 -0
- package/dist/sankhyablocks/snk-filter-bar.entry.js +243 -0
- package/dist/sankhyablocks/snk-filter-binary-select.entry.js +43 -0
- package/dist/sankhyablocks/snk-filter-detail.entry.js +45 -0
- package/dist/sankhyablocks/snk-filter-item.entry.js +139 -0
- package/dist/sankhyablocks/snk-filter-list.entry.js +87 -0
- package/dist/sankhyablocks/snk-filter-multi-select.entry.js +19 -0
- package/dist/sankhyablocks/snk-filter-number.entry.js +20 -0
- package/dist/sankhyablocks/snk-filter-period.entry.js +22 -0
- package/dist/sankhyablocks/snk-filter-search.entry.js +40 -0
- package/dist/sankhyablocks/snk-filter-text.entry.js +18 -0
- package/dist/sankhyablocks/snk-form.entry.js +129 -0
- package/dist/sankhyablocks/snk-grid.entry.js +75 -0
- package/dist/sankhyablocks/snk-pesquisa.entry.js +311 -0
- package/dist/sankhyablocks/snk-taskbar.entry.js +156 -0
- package/dist/sankhyablocks/taskbar-elements-35d64ff9.js +90 -0
- package/dist/sankhyablocks/taskbar-processor-aa6772c9.js +45 -0
- package/dist/sankhyablocks/teste-pesquisa.entry.js +33 -0
- package/dist/types/components/snk-application/errorhandler/snk-error-handler.d.ts +1 -0
- package/dist/types/components/snk-application/snk-application.d.ts +9 -0
- package/dist/types/components/snk-filter-bar/filter-item/editors/snk-filter-binary-select.d.ts +12 -0
- package/dist/types/components/snk-filter-bar/filter-item/editors/snk-filter-multi-select.d.ts +7 -0
- package/dist/types/components/snk-filter-bar/filter-item/editors/snk-filter-number.d.ts +7 -0
- package/dist/types/components/snk-filter-bar/filter-item/editors/snk-filter-period.d.ts +13 -0
- package/dist/types/components/snk-filter-bar/filter-item/editors/snk-filter-search.d.ts +12 -0
- package/dist/types/components/snk-filter-bar/filter-item/editors/snk-filter-text.d.ts +7 -0
- package/dist/types/components/snk-filter-bar/filter-item/filter-item-type.enum.d.ts +9 -0
- package/dist/types/components/snk-filter-bar/filter-item/snk-filter-detail.d.ts +14 -0
- package/dist/types/components/snk-filter-bar/filter-list/snk-filter-list.d.ts +40 -0
- package/dist/types/components/snk-filter-bar/snk-filter-bar.d.ts +45 -0
- package/dist/types/components/snk-taskbar/elements/taskbar-elements.d.ts +3 -2
- package/dist/types/components/snk-taskbar/processor/taskbar-processor.d.ts +12 -0
- package/dist/types/components/snk-taskbar/snk-taskbar.d.ts +17 -1
- package/dist/types/components.d.ts +277 -2
- package/dist/types/lib/http/data-fetcher/DataFetcher.d.ts +1 -0
- package/dist/types/lib/http/data-fetcher/fetchers/filter-bar-config-fetcher.d.ts +5 -0
- package/dist/types/lib/message/resources/snk-filter-bar.msg.d.ts +2 -0
- package/package.json +2 -2
- package/react/components.d.ts +0 -7
- package/react/components.js +0 -7
- package/react/components.js.map +1 -1
- package/dist/esm/index-cf91f542.js +0 -1817
- package/dist/esm/taskbar-elements-bcccc0ff.js +0 -72
- package/dist/sankhyablocks/p-1ba29824.entry.js +0 -74
- package/dist/sankhyablocks/p-2266555e.entry.js +0 -1
- package/dist/sankhyablocks/p-23c4c94f.js +0 -2
- package/dist/sankhyablocks/p-2454be94.js +0 -1
- package/dist/sankhyablocks/p-49743bc5.js +0 -1
- package/dist/sankhyablocks/p-4fa389bd.entry.js +0 -1
- package/dist/sankhyablocks/p-5327ba05.entry.js +0 -1
- package/dist/sankhyablocks/p-7a922fb4.entry.js +0 -1
- package/dist/sankhyablocks/p-92d6f826.entry.js +0 -1
- package/dist/sankhyablocks/p-bdeef7f2.entry.js +0 -1
|
@@ -0,0 +1,2397 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Classe com utiliários comuns para Strings.
|
|
5
|
+
*/
|
|
6
|
+
class StringUtils {
|
|
7
|
+
/**
|
|
8
|
+
* Verifica se a string está vazia.
|
|
9
|
+
* Valores null e undefined são considerados como vazio.
|
|
10
|
+
*
|
|
11
|
+
* @param value String para ser validada.
|
|
12
|
+
*/
|
|
13
|
+
static isEmpty(value) {
|
|
14
|
+
if (value == undefined || value === null) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
value = value.toString();
|
|
18
|
+
value = value.trim();
|
|
19
|
+
if (value.length === 0) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Remove acentos de vogais, substitui Ç por c e retorna a string em caixa alta.
|
|
26
|
+
*
|
|
27
|
+
* @param value String para ser transformada.
|
|
28
|
+
*/
|
|
29
|
+
static replaceAccentuatedChars(text) {
|
|
30
|
+
text = text.toUpperCase();
|
|
31
|
+
text = text.replace(/[À]/, "A");
|
|
32
|
+
text = text.replace(/[Á]/, "A");
|
|
33
|
+
text = text.replace(/[Â]/, "A");
|
|
34
|
+
text = text.replace(/[Ã]/, "A");
|
|
35
|
+
text = text.replace(/[Ä]/, "A");
|
|
36
|
+
text = text.replace(/[È]/, "E");
|
|
37
|
+
text = text.replace(/[É]/, "E");
|
|
38
|
+
text = text.replace(/[Ê]/, "E");
|
|
39
|
+
text = text.replace(/[Ë]/, "E");
|
|
40
|
+
text = text.replace(/[Ì]/, "I");
|
|
41
|
+
text = text.replace(/[Í]/, "I");
|
|
42
|
+
text = text.replace(/[Î]/, "I");
|
|
43
|
+
text = text.replace(/[Ï]/, "I");
|
|
44
|
+
text = text.replace(/[Ò]/, "O");
|
|
45
|
+
text = text.replace(/[Ó]/, "O");
|
|
46
|
+
text = text.replace(/[Ô]/, "O");
|
|
47
|
+
text = text.replace(/[Ö]/, "O");
|
|
48
|
+
text = text.replace(/[Ù]/, "U");
|
|
49
|
+
text = text.replace(/[Ú]/, "U");
|
|
50
|
+
text = text.replace(/[Û]/, "U");
|
|
51
|
+
text = text.replace(/[Ü]/, "U");
|
|
52
|
+
text = text.replace(/[Ç]/, "C");
|
|
53
|
+
return text.replace(/[^a-z0-9]/gi, "");
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Remove acentos de vogais, substitui Ç por c e retorna a string em caixa alta mantendo espaços e símbolos.
|
|
57
|
+
* @param text String para ser transformada.
|
|
58
|
+
*/
|
|
59
|
+
static replaceAccentuatedCharsKeepSymbols(text) {
|
|
60
|
+
return text.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toUpperCase();
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Calcula um código hash para uma string.
|
|
64
|
+
* @param value String que será gerado o hash code.
|
|
65
|
+
*/
|
|
66
|
+
static hashCode(value) {
|
|
67
|
+
let hash = 0, i, chr;
|
|
68
|
+
if (value.length === 0)
|
|
69
|
+
return hash.toString();
|
|
70
|
+
for (i = 0; i < value.length; i++) {
|
|
71
|
+
chr = value.charCodeAt(i);
|
|
72
|
+
hash = ((hash << 5) - hash) + chr;
|
|
73
|
+
hash |= 0; // Convert to 32bit integer
|
|
74
|
+
}
|
|
75
|
+
return hash.toString();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Converte um valor em string para booleano
|
|
79
|
+
* @param value Valor a ser convertido
|
|
80
|
+
* @param defaultValue Será retornado esse caso seja passado valores diferentes do esperado(true, false, "true", "false", "S", "N")
|
|
81
|
+
*/
|
|
82
|
+
static getBooleanValue(value, defaultValue = false) {
|
|
83
|
+
if ([true, "true", "S"].includes(value)) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
else if ([false, "false", "N"].includes(value)) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
return defaultValue;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
static padStart(str, len, pad = " ") {
|
|
94
|
+
str = str != undefined ? str : "";
|
|
95
|
+
while (str.length < len) {
|
|
96
|
+
str = pad + str;
|
|
97
|
+
}
|
|
98
|
+
return str;
|
|
99
|
+
}
|
|
100
|
+
static padEnd(str, len, pad = " ") {
|
|
101
|
+
str = str != undefined ? str : "";
|
|
102
|
+
while (str.length < len) {
|
|
103
|
+
str = str + pad;
|
|
104
|
+
}
|
|
105
|
+
return str;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Utilitário para determinar a ordem de strings. Geralmente usado no método "sort" de um array.
|
|
109
|
+
* Retorna um número negativo se o primeiro argumento é menor que o segundo, zero se os dois são iguais
|
|
110
|
+
* e um número positivo quando o primeiro é maior que o segundo.if they're equal, and a positive value otherwise.
|
|
111
|
+
* @param a - Primeira string para comparação
|
|
112
|
+
* @param b - Segunda string para comparação
|
|
113
|
+
* @returns Um valor maior, menor ou igual a zero para determinar se a ordem precisa ser alterada.
|
|
114
|
+
*/
|
|
115
|
+
static compare(a, b) {
|
|
116
|
+
if (a === undefined) {
|
|
117
|
+
return b === undefined ? 0 : 1;
|
|
118
|
+
}
|
|
119
|
+
else if (b === undefined) {
|
|
120
|
+
return -1;
|
|
121
|
+
}
|
|
122
|
+
if (a === null) {
|
|
123
|
+
return b === null ? 0 : 1;
|
|
124
|
+
}
|
|
125
|
+
else if (b === null) {
|
|
126
|
+
return -1;
|
|
127
|
+
}
|
|
128
|
+
return a.localeCompare(b);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const NUMBERINPUTS_REGEX_SCIENTIFIC_PARTS = /^([+-])?(\d+).?(\d*)[eE]([-+]?\d+)$/;
|
|
133
|
+
/**
|
|
134
|
+
* `NumberUtils` é uma biblioteca para manipulação de números
|
|
135
|
+
*
|
|
136
|
+
* `Métodos`:
|
|
137
|
+
*
|
|
138
|
+
* @stringToNumber: converte um número em formato de string em um valor numérico nativo do javascript
|
|
139
|
+
* @format: arredonda um número em formato de string baseado nos parâmetros "presision" e "prettyPrecision";
|
|
140
|
+
*/
|
|
141
|
+
class NumberUtils {
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* @stringToNumber: converte um numero em formato de string em numero
|
|
145
|
+
*
|
|
146
|
+
* @param value numero em formato de string a ser convertido (Importante: formato PT-BR ou já em formato numérico: ######.##)
|
|
147
|
+
*
|
|
148
|
+
* @returns string based number
|
|
149
|
+
*
|
|
150
|
+
* @Exemples
|
|
151
|
+
* @"100,12" | 100.12
|
|
152
|
+
* @"100.12" | 100.12
|
|
153
|
+
* @"-100,12" | -100.12
|
|
154
|
+
* @"R$100,12" | 100.12
|
|
155
|
+
* @"-R$100,12" | -100.12
|
|
156
|
+
* @"string" | NaN
|
|
157
|
+
*/
|
|
158
|
+
NumberUtils.stringToNumber = (value) => {
|
|
159
|
+
if (value === '' || value === null || value === undefined) {
|
|
160
|
+
return NaN;
|
|
161
|
+
}
|
|
162
|
+
if (value) {
|
|
163
|
+
value = value.toString();
|
|
164
|
+
const negative = (value.charAt(0) === '-');
|
|
165
|
+
if (!NUMBERINPUTS_REGEX_SCIENTIFIC_PARTS.test(value)) {
|
|
166
|
+
value = value.replace(/[^\d.,]/g, '');
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
value = value.replace(/^-/g, '');
|
|
170
|
+
}
|
|
171
|
+
//In case of simple string such as: "@@@@@@@"
|
|
172
|
+
if (value === '') {
|
|
173
|
+
return Number(NaN);
|
|
174
|
+
}
|
|
175
|
+
const indexV = value.indexOf(',');
|
|
176
|
+
const indexP = value.indexOf('.');
|
|
177
|
+
if (indexP > indexV) {
|
|
178
|
+
value = value.replace(',', '');
|
|
179
|
+
}
|
|
180
|
+
else if (indexP < indexV) {
|
|
181
|
+
value = value.replace(/\./g, '@').replace(',', '.').replace(/@/g, '');
|
|
182
|
+
}
|
|
183
|
+
if (negative) {
|
|
184
|
+
value = '-' + value;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return Number(value);
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* @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"
|
|
191
|
+
*
|
|
192
|
+
* @param value numero em formato de string a ser convertido (Importante: formato PT-BR ou já em formato numérico<sem separadors de milhares>: ######.##)
|
|
193
|
+
* @param precision (numero de decimais)
|
|
194
|
+
* @param prettyPrecision (numero de zeros nos decimais)
|
|
195
|
+
*
|
|
196
|
+
* @returns numero em formato de string formatado em PT-BR
|
|
197
|
+
*/
|
|
198
|
+
NumberUtils.format = (value, precision, prettyPrecision = NaN) => {
|
|
199
|
+
if (value === '' || value === undefined || value === "NaN") {
|
|
200
|
+
return NaN.toString();
|
|
201
|
+
}
|
|
202
|
+
const newValue = NumberUtils.stringToNumber(value);
|
|
203
|
+
if (isNaN(newValue)) {
|
|
204
|
+
return NaN.toString();
|
|
205
|
+
}
|
|
206
|
+
//Validation "precision":
|
|
207
|
+
// Case1: precision < 0 => does not use precision
|
|
208
|
+
// Case2: presicion not int => does not use precision
|
|
209
|
+
if (precision < 0 || Math.abs(Math.round(precision * 1) / 1) !== precision) {
|
|
210
|
+
//Once stringToNumber returns number format, we need to change to pt-br
|
|
211
|
+
return NumberUtils.changeFormat(newValue.toString());
|
|
212
|
+
}
|
|
213
|
+
//Validation "prettyPrecision"
|
|
214
|
+
let prettyPrecisionInternal = 0;
|
|
215
|
+
// Case1: prettyPrecision < 0 => prettyPrecision does not change de format that means: prettyPrecisionInternal = precision;
|
|
216
|
+
// Case2: prettyPrecision not int => prettyPrecision does not change de format that means: prettyPrecisionInternal = precision;
|
|
217
|
+
if (isNaN(prettyPrecision) || Math.abs(Math.round(prettyPrecision * 1) / 1) !== prettyPrecision) {
|
|
218
|
+
prettyPrecisionInternal = precision;
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
prettyPrecisionInternal = prettyPrecision;
|
|
222
|
+
}
|
|
223
|
+
let newValueStr;
|
|
224
|
+
newValueStr = (Math.round(newValue * Math.pow(10, precision)) / Math.pow(10, precision)).toLocaleString('pt-br', { minimumFractionDigits: precision });
|
|
225
|
+
//prettyPrecision
|
|
226
|
+
const varSettingPP = precision - prettyPrecisionInternal;
|
|
227
|
+
if (varSettingPP > 0) {
|
|
228
|
+
for (let i = 0; i < varSettingPP; i++) {
|
|
229
|
+
if (newValueStr.substring(newValueStr.length - 1) == "0" && precision > 0) {
|
|
230
|
+
newValueStr = newValueStr.substring(0, newValueStr.length - 1);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//in Case "." or "," in the end of the string
|
|
235
|
+
if (newValueStr.substring(newValueStr.length - 1) == "." || newValueStr.substring(newValueStr.length - 1) == ",") {
|
|
236
|
+
newValueStr = newValueStr.substring(0, newValueStr.length - 1);
|
|
237
|
+
}
|
|
238
|
+
return newValueStr;
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
241
|
+
* @keepOnlyDecimalSeparator: retira os separadores de milhar de um número em formato de string
|
|
242
|
+
*
|
|
243
|
+
* @param value numero em formato de string a ser convertido
|
|
244
|
+
* @param formatnumber (formatação de ENTRADA e SAÍDA do utilitário: pt-BR="###.###,##" en-US="###,###.##"; Default: "pt-BR")
|
|
245
|
+
*
|
|
246
|
+
* @returns numero em formato de string formatado apenas com separador decimal
|
|
247
|
+
*/
|
|
248
|
+
NumberUtils.keepOnlyDecimalSeparator = (value, formatnumber = 'pt-BR') => {
|
|
249
|
+
//Formatting formatnumber to be able to get lowercases
|
|
250
|
+
formatnumber = formatnumber.toUpperCase();
|
|
251
|
+
//Formatting value following formatnumber parameter
|
|
252
|
+
//keep only decimal character in order to correct format the string
|
|
253
|
+
//This transformation is due the "stringtoNumber" method is a general method that tries to convert all formated strings
|
|
254
|
+
if (formatnumber === 'EN-US') {
|
|
255
|
+
value = value.replace(/\,/g, '');
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
value = value.replace(/\./g, '');
|
|
259
|
+
}
|
|
260
|
+
return value;
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* @changeFormat: troca o formato do numero string de "PT-BR" para "EN-US" e vice-versa
|
|
264
|
+
*
|
|
265
|
+
* @param value numero em formato de string a ser convertido
|
|
266
|
+
*
|
|
267
|
+
* @returns numero em formato de string formatado de "PT-BR" para "EN-US" e vice-versa
|
|
268
|
+
*/
|
|
269
|
+
NumberUtils.changeFormat = (value) => {
|
|
270
|
+
//Formatting output following formatnumber
|
|
271
|
+
return value.replace(/\./g, '_').replace(/\,/g, '.').replace(/\_/g, ',');
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* `MaskFormatter` é usado para formatar strings. Seu comportamento
|
|
276
|
+
* é controlado pela formato do atributo `mask` que especifica quais
|
|
277
|
+
* caracteres são válidos e onde devem estar posicionados, intercalando-os
|
|
278
|
+
* com eventuais caracteres literais expressados no padrão informado.
|
|
279
|
+
* Sua implementação é inspirada pela implementação em Java do [MaskFormatter](https://docs.oracle.com/javase/7/docs/api/javax/swing/text/MaskFormatter.html).
|
|
280
|
+
*
|
|
281
|
+
* Para o padrão da máscara podem ser usados os seguintes caracteres especiais:
|
|
282
|
+
*
|
|
283
|
+
* | Caractere | Comportamento |
|
|
284
|
+
* |:---------:|-------------------------------------------------------------------------------------------------------------|
|
|
285
|
+
* | # | Qualquer número |
|
|
286
|
+
* | ' | "Escapa" o caractere que vem na sequência. Útil quando desejamos converter um caractere especial em literal.|
|
|
287
|
+
* | U | Qualquer letra. Transforma letras maiúsculas em maiúsculas. |
|
|
288
|
+
* | L | Qualquer letra. Transforma letras maiúsculas em minúsculas. |
|
|
289
|
+
* | A | Qualquer letra ou número. |
|
|
290
|
+
* | ? | Qualquer letra. Preserva maiúsculas e minúsculas. |
|
|
291
|
+
* | * | Qualquer caractere. |
|
|
292
|
+
*
|
|
293
|
+
* Os demais caracteres presentes no padrão serão tratados como literais, isto é,
|
|
294
|
+
* serão apenas inseridos naquela posição.
|
|
295
|
+
*
|
|
296
|
+
* Quando o o valor a ser formatado é menor que a máscara um 'placeHolder'
|
|
297
|
+
* será inserido em cada posição ausente, completando a formatação.
|
|
298
|
+
* Por padrão será usado um espaço em branco como 'placeHolder' mas
|
|
299
|
+
* esse valor pode ser alterado.
|
|
300
|
+
*
|
|
301
|
+
* For por exemplo:
|
|
302
|
+
* '''
|
|
303
|
+
* const formatter: MaskFormatter = new MaskFormatter("###-####");
|
|
304
|
+
* formatter.placeholder = '_';
|
|
305
|
+
* console.log(formatter.format("123"));
|
|
306
|
+
* '''
|
|
307
|
+
* resultaria na string '123-____'.
|
|
308
|
+
*
|
|
309
|
+
* ##Veja mais alguns exemplos:
|
|
310
|
+
* |Padrão |Máscara |Entrada |Saída |
|
|
311
|
+
* |----------------|------------------|--------------|------------------|
|
|
312
|
+
* |Telefone |(##) ####-#### |3432192515 |(34) 3219-2515 |
|
|
313
|
+
* |CPF |###.###.###-## |12345678901 |123.456.789-01 |
|
|
314
|
+
* |CNPJ |##.###.###/####-##|12345678901234|12.345.678/9012-34|
|
|
315
|
+
* |CEP |##.###-### |12345678 |12.345-678 |
|
|
316
|
+
* |PLACA (veículo) |UUU-#### |abc1234 |ABC-1234 |
|
|
317
|
+
* |Cor RGB |'#AAAAAA |00000F0 |#0000F0 |
|
|
318
|
+
*
|
|
319
|
+
*/
|
|
320
|
+
class MaskFormatter {
|
|
321
|
+
constructor(mask) {
|
|
322
|
+
this._mask = '';
|
|
323
|
+
this._maskChars = new Array();
|
|
324
|
+
/**
|
|
325
|
+
* Determina qual caractere será usado dos caracteres não presentes no valor
|
|
326
|
+
* ou seja, aqueles que o usuário ainda não informou. Por padrão usamos um espaço
|
|
327
|
+
*/
|
|
328
|
+
this.placeholder = ' ';
|
|
329
|
+
this.mask = mask;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Setter para mask. Trata-se do padrão que se espera ao formatar o texto.
|
|
333
|
+
*/
|
|
334
|
+
set mask(mask) {
|
|
335
|
+
this._mask = mask;
|
|
336
|
+
this.updateInternalMask();
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Getter para mask
|
|
340
|
+
*
|
|
341
|
+
* @return A última máscara informada.
|
|
342
|
+
*/
|
|
343
|
+
get mask() {
|
|
344
|
+
return this._mask;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Formata a string passada baseada na máscara definda pelo atributo mask.
|
|
348
|
+
*
|
|
349
|
+
* @param value Valor a ser formatado
|
|
350
|
+
* @return O valor processado de acordo com o padrão
|
|
351
|
+
*/
|
|
352
|
+
format(value) {
|
|
353
|
+
let result = '';
|
|
354
|
+
const index = [0];
|
|
355
|
+
let counter = 0;
|
|
356
|
+
const maxCounter = this._maskChars.length;
|
|
357
|
+
while (counter < maxCounter) {
|
|
358
|
+
result = this._maskChars[counter].append(result, value, index);
|
|
359
|
+
counter++;
|
|
360
|
+
}
|
|
361
|
+
return result;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Preparamos a formatação internamente de acordo com o padrão.
|
|
365
|
+
*/
|
|
366
|
+
updateInternalMask() {
|
|
367
|
+
this._maskChars.length = 0;
|
|
368
|
+
if (this.mask != null) {
|
|
369
|
+
let counter = 0;
|
|
370
|
+
const maxCounter = this.mask.length;
|
|
371
|
+
while (counter < maxCounter) {
|
|
372
|
+
let maskChar = this.mask.charAt(counter);
|
|
373
|
+
switch (maskChar) {
|
|
374
|
+
case MaskFormatter.DIGIT_KEY:
|
|
375
|
+
this._maskChars.push(new MaskFormatter.DigitMaskCharacter(this, maskChar));
|
|
376
|
+
break;
|
|
377
|
+
case MaskFormatter.LITERAL_KEY:
|
|
378
|
+
if (++counter < maxCounter) {
|
|
379
|
+
maskChar = this.mask.charAt(counter);
|
|
380
|
+
this._maskChars.push(new MaskFormatter.LiteralCharacter(this, maskChar));
|
|
381
|
+
}
|
|
382
|
+
break;
|
|
383
|
+
case MaskFormatter.UPPERCASE_KEY:
|
|
384
|
+
this._maskChars.push(new MaskFormatter.UpperCaseCharacter(this, maskChar));
|
|
385
|
+
break;
|
|
386
|
+
case MaskFormatter.LOWERCASE_KEY:
|
|
387
|
+
this._maskChars.push(new MaskFormatter.LowerCaseCharacter(this, maskChar));
|
|
388
|
+
break;
|
|
389
|
+
case MaskFormatter.ALPHA_NUMERIC_KEY:
|
|
390
|
+
this._maskChars.push(new MaskFormatter.AlphaNumericCharacter(this, maskChar));
|
|
391
|
+
break;
|
|
392
|
+
case MaskFormatter.CHARACTER_KEY:
|
|
393
|
+
this._maskChars.push(new MaskFormatter.CharCharacter(this, maskChar));
|
|
394
|
+
break;
|
|
395
|
+
case MaskFormatter.ANYTHING_KEY:
|
|
396
|
+
this._maskChars.push(new MaskFormatter.MaskCharacter(this, maskChar));
|
|
397
|
+
break;
|
|
398
|
+
default:
|
|
399
|
+
this._maskChars.push(new MaskFormatter.LiteralCharacter(this, maskChar));
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
counter++;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
MaskFormatter.DIGIT_KEY = "#";
|
|
408
|
+
MaskFormatter.LITERAL_KEY = "'";
|
|
409
|
+
MaskFormatter.UPPERCASE_KEY = "U";
|
|
410
|
+
MaskFormatter.LOWERCASE_KEY = "L";
|
|
411
|
+
MaskFormatter.ALPHA_NUMERIC_KEY = "A";
|
|
412
|
+
MaskFormatter.CHARACTER_KEY = "?";
|
|
413
|
+
MaskFormatter.ANYTHING_KEY = "*";
|
|
414
|
+
//
|
|
415
|
+
// Classes internas usadas para representar a máscara.
|
|
416
|
+
//
|
|
417
|
+
MaskFormatter.MaskCharacter = class {
|
|
418
|
+
constructor(maskFormatter, type) {
|
|
419
|
+
this.maskFormatter = maskFormatter;
|
|
420
|
+
this.type = type;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Cada subclasse deve sobrescrever o retornando true, caso represente
|
|
424
|
+
* um caractere literal. Por padrão o retorno é false.
|
|
425
|
+
*/
|
|
426
|
+
isLiteral() {
|
|
427
|
+
return false;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Returns true if <code>aChar</code> is a valid reprensentation of
|
|
431
|
+
* the receiver. The default implementation returns true if the
|
|
432
|
+
* receiver represents a literal character and <code>getChar</code>
|
|
433
|
+
* == aChar. Otherwise, this will return true is <code>aChar</code>
|
|
434
|
+
* is contained in the valid characters and not contained
|
|
435
|
+
* in the invalid characters.
|
|
436
|
+
*/
|
|
437
|
+
isValidCharacter(aChar) {
|
|
438
|
+
if (this.isLiteral()) {
|
|
439
|
+
return (this.getChar(aChar) == aChar);
|
|
440
|
+
}
|
|
441
|
+
aChar = this.getChar(aChar);
|
|
442
|
+
return true;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Returns the character to insert for <code>aChar</code>. The
|
|
446
|
+
* default implementation returns <code>aChar</code>. Subclasses
|
|
447
|
+
* that wish to do some sort of mapping, perhaps lower case to upper
|
|
448
|
+
* case should override this and do the necessary mapping.
|
|
449
|
+
*/
|
|
450
|
+
getChar(aChar) {
|
|
451
|
+
return aChar;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Appends the necessary character in <code>formatting</code> at
|
|
455
|
+
* <code>index</code> to <code>buff</code>.
|
|
456
|
+
*/
|
|
457
|
+
append(result, formatting, index) {
|
|
458
|
+
const inString = index[0] < formatting.length;
|
|
459
|
+
const aChar = inString ? formatting.charAt(index[0]) : '';
|
|
460
|
+
if (this.isLiteral()) {
|
|
461
|
+
const literal = this.getChar(aChar);
|
|
462
|
+
result += literal;
|
|
463
|
+
if (literal === aChar) {
|
|
464
|
+
index[0] = index[0] + 1;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
else if (index[0] >= formatting.length) {
|
|
468
|
+
result += this.maskFormatter.placeholder;
|
|
469
|
+
index[0] = index[0] + 1;
|
|
470
|
+
}
|
|
471
|
+
else if (this.isValidCharacter(aChar)) {
|
|
472
|
+
result += this.getChar(aChar);
|
|
473
|
+
index[0] = index[0] + 1;
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
throw new Error(`Valor inválido: "${aChar}". Na posição ${index[0] + 1} espera-se ${this.getFormatMessage()}.`);
|
|
477
|
+
}
|
|
478
|
+
return result;
|
|
479
|
+
}
|
|
480
|
+
getFormatMessage() {
|
|
481
|
+
let message;
|
|
482
|
+
switch (this.type) {
|
|
483
|
+
case MaskFormatter.UPPERCASE_KEY:
|
|
484
|
+
case MaskFormatter.LOWERCASE_KEY:
|
|
485
|
+
case MaskFormatter.CHARACTER_KEY:
|
|
486
|
+
message = 'uma letra';
|
|
487
|
+
break;
|
|
488
|
+
case MaskFormatter.DIGIT_KEY:
|
|
489
|
+
message = 'um número';
|
|
490
|
+
break;
|
|
491
|
+
case MaskFormatter.ALPHA_NUMERIC_KEY:
|
|
492
|
+
message = 'uma letra ou um número';
|
|
493
|
+
break;
|
|
494
|
+
default:
|
|
495
|
+
message = '';
|
|
496
|
+
}
|
|
497
|
+
return message;
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
MaskFormatter.LiteralCharacter = class extends MaskFormatter.MaskCharacter {
|
|
501
|
+
constructor(maskFormatter, fixedChar) {
|
|
502
|
+
super(maskFormatter, fixedChar);
|
|
503
|
+
this._fixedChar = fixedChar;
|
|
504
|
+
}
|
|
505
|
+
isLiteral() {
|
|
506
|
+
return true;
|
|
507
|
+
}
|
|
508
|
+
getChar(aChar) {
|
|
509
|
+
aChar;
|
|
510
|
+
return this._fixedChar;
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
MaskFormatter.DigitMaskCharacter = class extends MaskFormatter.MaskCharacter {
|
|
514
|
+
isValidCharacter(aChar) {
|
|
515
|
+
return (this.isDigit(aChar) && super.isValidCharacter(aChar));
|
|
516
|
+
}
|
|
517
|
+
isDigit(char) {
|
|
518
|
+
return char >= '0' && char <= '9';
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
MaskFormatter.UpperCaseCharacter = class extends MaskFormatter.MaskCharacter {
|
|
522
|
+
isValidCharacter(aChar) {
|
|
523
|
+
return (/[a-z]/i.test(aChar) && super.isValidCharacter(aChar));
|
|
524
|
+
}
|
|
525
|
+
getChar(aChar) {
|
|
526
|
+
return aChar.toUpperCase();
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
MaskFormatter.LowerCaseCharacter = class extends MaskFormatter.MaskCharacter {
|
|
530
|
+
isValidCharacter(aChar) {
|
|
531
|
+
return (/[a-z]/i.test(aChar) && super.isValidCharacter(aChar));
|
|
532
|
+
}
|
|
533
|
+
getChar(aChar) {
|
|
534
|
+
return aChar.toLocaleLowerCase();
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
MaskFormatter.AlphaNumericCharacter = class extends MaskFormatter.MaskCharacter {
|
|
538
|
+
isValidCharacter(aChar) {
|
|
539
|
+
//FIXME: talvez seja problema usar regex aqui... avaliar se existe forma mais barata
|
|
540
|
+
return (/[a-z0-9]/i.test(aChar)) && super.isValidCharacter(aChar);
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
MaskFormatter.CharCharacter = class extends MaskFormatter.MaskCharacter {
|
|
544
|
+
isValidCharacter(aChar) {
|
|
545
|
+
//FIXME: talvez seja problema usar regex aqui... avaliar se existe forma mais barata
|
|
546
|
+
return (/[a-z]/i.test(aChar) && super.isValidCharacter(aChar));
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
|
|
550
|
+
class FloatingEntry {
|
|
551
|
+
constructor(parent, content, opts) {
|
|
552
|
+
try {
|
|
553
|
+
this.weakRefParent = new WeakRef(parent);
|
|
554
|
+
this.weakRefContent = new WeakRef(content);
|
|
555
|
+
}
|
|
556
|
+
catch (error) {
|
|
557
|
+
this.strongRefParent = parent;
|
|
558
|
+
this.strongRefContent = content;
|
|
559
|
+
}
|
|
560
|
+
this.options = opts;
|
|
561
|
+
}
|
|
562
|
+
get parent() {
|
|
563
|
+
if (this.weakRefParent) {
|
|
564
|
+
return this.weakRefParent.deref();
|
|
565
|
+
}
|
|
566
|
+
return this.strongRefParent;
|
|
567
|
+
}
|
|
568
|
+
get content() {
|
|
569
|
+
if (this.weakRefContent) {
|
|
570
|
+
return this.weakRefContent.deref();
|
|
571
|
+
}
|
|
572
|
+
return this.strongRefContent;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
class FloatingManager {
|
|
576
|
+
static init() {
|
|
577
|
+
FloatingManager.entries = [];
|
|
578
|
+
document.addEventListener('mousedown', FloatingManager.handleDocumentEvent);
|
|
579
|
+
document.addEventListener('keydown', FloatingManager.handleKeyboardEvent);
|
|
580
|
+
FloatingManager.initialized = true;
|
|
581
|
+
}
|
|
582
|
+
static innerClick(container, node) {
|
|
583
|
+
if (container.contains(node)) {
|
|
584
|
+
return true;
|
|
585
|
+
}
|
|
586
|
+
if (container.shadowRoot && container.shadowRoot.contains(node)) {
|
|
587
|
+
return true;
|
|
588
|
+
}
|
|
589
|
+
return false;
|
|
590
|
+
}
|
|
591
|
+
static doClose(id, entry, target, event) {
|
|
592
|
+
if (!target || entry.options.autoClose) {
|
|
593
|
+
const parent = entry.parent;
|
|
594
|
+
const content = entry.content;
|
|
595
|
+
if (parent && content) {
|
|
596
|
+
const innerClickFunction = entry.options.innerClickTest ? entry.options.innerClickTest : FloatingManager.innerClick;
|
|
597
|
+
const backClickFunction = entry.options.backClickListener ? entry.options.backClickListener : () => { };
|
|
598
|
+
if (!target || !innerClickFunction(content, target, event)) {
|
|
599
|
+
content.remove();
|
|
600
|
+
delete FloatingManager.entries[id];
|
|
601
|
+
backClickFunction();
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
else {
|
|
605
|
+
delete FloatingManager.entries[id];
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
static handleDocumentEvent(event) {
|
|
610
|
+
FloatingManager.entries.forEach((entry, index) => {
|
|
611
|
+
FloatingManager.doClose(index, entry, event.composedPath()[0], event);
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
static handleKeyboardEvent(event) {
|
|
615
|
+
if (event.key === 'Escape') {
|
|
616
|
+
for (let index = FloatingManager.entries.length; index >= 0; index--) {
|
|
617
|
+
const entry = FloatingManager.entries[index];
|
|
618
|
+
if (entry) {
|
|
619
|
+
FloatingManager.close(index);
|
|
620
|
+
break;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
static applyStyle(element, propertyName, value) {
|
|
626
|
+
if (value) {
|
|
627
|
+
element.style.setProperty(propertyName, value);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
static getFloatIndex(content, parent) {
|
|
631
|
+
for (let index = 0; index < FloatingManager.entries.length; index++) {
|
|
632
|
+
const entry = FloatingManager.entries[index];
|
|
633
|
+
if (entry && content === entry.content && parent === entry.parent) {
|
|
634
|
+
return index;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
return -1;
|
|
638
|
+
}
|
|
639
|
+
static isFloating(id) {
|
|
640
|
+
return FloatingManager.entries[id] !== undefined;
|
|
641
|
+
}
|
|
642
|
+
static float(content, parent, options = { autoClose: true }) {
|
|
643
|
+
if (!FloatingManager.initialized) {
|
|
644
|
+
FloatingManager.init();
|
|
645
|
+
}
|
|
646
|
+
const alreadyFloatingIndex = FloatingManager.getFloatIndex(content, parent);
|
|
647
|
+
if (alreadyFloatingIndex > -1) {
|
|
648
|
+
return alreadyFloatingIndex;
|
|
649
|
+
}
|
|
650
|
+
content.style.position = options.isFixed ? 'fixed' : 'absolute';
|
|
651
|
+
FloatingManager.applyStyle(content, "top", options.top);
|
|
652
|
+
FloatingManager.applyStyle(content, "left", options.left);
|
|
653
|
+
FloatingManager.applyStyle(content, "right", options.right);
|
|
654
|
+
FloatingManager.applyStyle(content, "bottom", options.bottom);
|
|
655
|
+
parent.appendChild(content);
|
|
656
|
+
FloatingManager.entries.push(new FloatingEntry(parent, content, options));
|
|
657
|
+
return FloatingManager.entries.length - 1;
|
|
658
|
+
}
|
|
659
|
+
static updateFloatPosition(content, parent, options = { autoClose: true }) {
|
|
660
|
+
const alreadyFloatingIndex = FloatingManager.getFloatIndex(content, parent);
|
|
661
|
+
if (alreadyFloatingIndex > -1) {
|
|
662
|
+
FloatingManager.applyStyle(content, "top", options.top);
|
|
663
|
+
FloatingManager.applyStyle(content, "left", options.left);
|
|
664
|
+
FloatingManager.applyStyle(content, "right", options.right);
|
|
665
|
+
FloatingManager.applyStyle(content, "bottom", options.bottom);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
static close(id) {
|
|
669
|
+
if (FloatingManager.entries[id]) {
|
|
670
|
+
FloatingManager.doClose(id, FloatingManager.entries[id], undefined);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
class DateUtils {
|
|
676
|
+
static clearTime(date, adjustDayLightSavingTime = true) {
|
|
677
|
+
const newDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0);
|
|
678
|
+
return adjustDayLightSavingTime ? DateUtils.adjustDLST(newDate) : newDate;
|
|
679
|
+
}
|
|
680
|
+
static strToDate(strValue, adjustDayLightSavingTime = true, monthYearMode = false) {
|
|
681
|
+
/** monthYearMode é um booleano para usar o formato MM/YYYY.
|
|
682
|
+
* Quando ativado, é retornado o primeiro dia do mês apenas para construir a data.
|
|
683
|
+
* Não há necessidade de verificar o horário de verão quando utilizado esse modo. */
|
|
684
|
+
let parts;
|
|
685
|
+
if (monthYearMode) {
|
|
686
|
+
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);
|
|
687
|
+
}
|
|
688
|
+
else {
|
|
689
|
+
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);
|
|
690
|
+
}
|
|
691
|
+
if (!parts) {
|
|
692
|
+
return undefined;
|
|
693
|
+
}
|
|
694
|
+
const day = monthYearMode ? 1 : Number(parts[1]);
|
|
695
|
+
const month = Number(parts[(monthYearMode ? 1 : 2)]);
|
|
696
|
+
let year = Number(parts[(monthYearMode ? 2 : 3)]);
|
|
697
|
+
const hour = Number(parts[(monthYearMode ? 3 : 4)] || 0);
|
|
698
|
+
const min = Number(parts[(monthYearMode ? 4 : 5)] || 0);
|
|
699
|
+
const sec = Number(parts[(monthYearMode ? 5 : 6)] || 0);
|
|
700
|
+
if (year < 100) {
|
|
701
|
+
year += year < 30 ? 2000 : 1900;
|
|
702
|
+
}
|
|
703
|
+
let date = new Date(year, month - 1, day, hour, min, sec, 0);
|
|
704
|
+
if (adjustDayLightSavingTime === true && !monthYearMode && hour == 0) {
|
|
705
|
+
date = DateUtils.adjustDLST(date);
|
|
706
|
+
}
|
|
707
|
+
return date;
|
|
708
|
+
}
|
|
709
|
+
static adjustDLST(date) {
|
|
710
|
+
//Work around para corrigir o Bug do horário de verão.
|
|
711
|
+
if (date.getHours() == 23) {
|
|
712
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1, 1, 0, 0, 0);
|
|
713
|
+
}
|
|
714
|
+
return date;
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
class ArrayUtils {
|
|
719
|
+
/**
|
|
720
|
+
* Filtra um array a partir de um critério textual.
|
|
721
|
+
*
|
|
722
|
+
* @param argument - Texto a ser usado no filtro
|
|
723
|
+
* @param originalArray - Array no formato original
|
|
724
|
+
* @param alphabeticalSorting - Determina se o resultado deve ser ordenado ou mantido na ordem original. Por padrão ordena.
|
|
725
|
+
* @param fieldName - Caso o objeto deva ser filtrado por um campo diferente de "label", pode-se usar esse parâmetro
|
|
726
|
+
* @returns Um array filtrado e ordenado conforme necessidade. Se "argument" for omitido, ou nulo, o array original é retornado.
|
|
727
|
+
*/
|
|
728
|
+
static applyStringFilter(argument, originalArray, alphabeticalSorting = true, fieldName = "label") {
|
|
729
|
+
if (!argument) {
|
|
730
|
+
return originalArray;
|
|
731
|
+
}
|
|
732
|
+
const normalizedArgument = ArrayUtils.normalizeSearchString(argument);
|
|
733
|
+
const filteredArray = originalArray.filter(item => {
|
|
734
|
+
const itemValue = ArrayUtils.normalizeSearchString(item[fieldName]);
|
|
735
|
+
return itemValue.includes(normalizedArgument);
|
|
736
|
+
});
|
|
737
|
+
return alphabeticalSorting ? filteredArray.sort((a, b) => StringUtils.compare(a[fieldName], b[fieldName])) : filteredArray;
|
|
738
|
+
}
|
|
739
|
+
static normalizeSearchString(original) {
|
|
740
|
+
return StringUtils.replaceAccentuatedCharsKeepSymbols(original.toUpperCase());
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* `TimeFormatter` é um utilitário para formatação de strings desformatadas em strings válidas de horários
|
|
746
|
+
*/
|
|
747
|
+
class TimeFormatter {
|
|
748
|
+
/**
|
|
749
|
+
* @prepareValue: converts an unformated time string into a formatted time.
|
|
750
|
+
*
|
|
751
|
+
* @param value unformated time string to convert
|
|
752
|
+
*
|
|
753
|
+
* @returns formatted time string
|
|
754
|
+
*
|
|
755
|
+
* @Exemples
|
|
756
|
+
* @"1012" | "10:12"
|
|
757
|
+
* @"10:12" | "10:12:00"
|
|
758
|
+
* @"100112" | "10:01:12"
|
|
759
|
+
*/
|
|
760
|
+
static prepareValue(value, showSeconds) {
|
|
761
|
+
if (value && value.length > 0 && value != "NaN") {
|
|
762
|
+
let validationValue = value.replace(/:/g, "");
|
|
763
|
+
if (showSeconds) {
|
|
764
|
+
this._maskFormatter.mask = "##:##:##";
|
|
765
|
+
if (validationValue.length < 6) {
|
|
766
|
+
while (validationValue.length < 6) {
|
|
767
|
+
validationValue = "0".concat(validationValue);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
else {
|
|
772
|
+
this._maskFormatter.mask = "##:##";
|
|
773
|
+
if (validationValue.length < 4) {
|
|
774
|
+
while (validationValue.length < 4) {
|
|
775
|
+
validationValue = "0".concat(validationValue);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
if (this._maskFormatter) {
|
|
780
|
+
try {
|
|
781
|
+
value = this._maskFormatter.format(validationValue);
|
|
782
|
+
return value;
|
|
783
|
+
}
|
|
784
|
+
catch (e) {
|
|
785
|
+
throw new Error(e.message);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
return '';
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* @validateTime: validates if an input string has the corect time format.
|
|
793
|
+
*
|
|
794
|
+
* @param value input string to validate
|
|
795
|
+
*
|
|
796
|
+
* @returns true or false
|
|
797
|
+
*
|
|
798
|
+
* @Exemples
|
|
799
|
+
* @"1012" | true
|
|
800
|
+
* @"14e4" | false
|
|
801
|
+
* @"2624" | false
|
|
802
|
+
*/
|
|
803
|
+
static validateTime(value, showSeconds) {
|
|
804
|
+
let isValid = true;
|
|
805
|
+
if (value) {
|
|
806
|
+
let validationValue = value.replace(/:/g, "");
|
|
807
|
+
if (showSeconds) {
|
|
808
|
+
if (!["1", "2", "0"].includes(validationValue[0])) {
|
|
809
|
+
isValid = false;
|
|
810
|
+
}
|
|
811
|
+
if (!["0", "1", "2", "3", "4", "5"].includes(validationValue[2])) {
|
|
812
|
+
isValid = false;
|
|
813
|
+
}
|
|
814
|
+
if (!["0", "1", "2", "3", "4", "5"].includes(validationValue[4])) {
|
|
815
|
+
isValid = false;
|
|
816
|
+
}
|
|
817
|
+
if (validationValue[0] == "2" && !["0", "1", "2", "3"].includes(validationValue[1])) {
|
|
818
|
+
isValid = false;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
else {
|
|
822
|
+
if (!["1", "2", "0"].includes(validationValue[0])) {
|
|
823
|
+
isValid = false;
|
|
824
|
+
}
|
|
825
|
+
if (!["0", "1", "2", "3", "4", "5"].includes(validationValue[2])) {
|
|
826
|
+
isValid = false;
|
|
827
|
+
}
|
|
828
|
+
if (validationValue[0] == "2" && !["0", "1", "2", "3"].includes(validationValue[1])) {
|
|
829
|
+
isValid = false;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
else {
|
|
834
|
+
isValid = false;
|
|
835
|
+
}
|
|
836
|
+
return isValid;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
TimeFormatter._maskFormatter = new MaskFormatter("##:##");
|
|
840
|
+
|
|
841
|
+
/**
|
|
842
|
+
* Representa as propriedades necessárias para se executar uma requisição.
|
|
843
|
+
*/
|
|
844
|
+
class RequestMetadata {
|
|
845
|
+
/**
|
|
846
|
+
* @param {string} url A URL que deve ser chamada.
|
|
847
|
+
* @param {Method} method O Método da requisição (GET, PUT, POST ou DELETE).
|
|
848
|
+
*/
|
|
849
|
+
constructor(url, method, headers) {
|
|
850
|
+
/** Tempo limite de espera pela resposta */
|
|
851
|
+
this.timeout = 30000;
|
|
852
|
+
this.url = url;
|
|
853
|
+
this.method = method;
|
|
854
|
+
this.headers = headers || [];
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
/** Representa os verbos HTTP suportados */
|
|
858
|
+
var Method;
|
|
859
|
+
(function (Method) {
|
|
860
|
+
Method[Method["GET"] = 0] = "GET";
|
|
861
|
+
Method[Method["PUT"] = 1] = "PUT";
|
|
862
|
+
Method[Method["POST"] = 2] = "POST";
|
|
863
|
+
Method[Method["DELETE"] = 3] = "DELETE";
|
|
864
|
+
})(Method || (Method = {}));
|
|
865
|
+
|
|
866
|
+
/**
|
|
867
|
+
* Abstração do XMLHttpRequest. Este serviço é responsável por realizar as requisições
|
|
868
|
+
* ao backend. Todos os métodos são estáticos.
|
|
869
|
+
*/
|
|
870
|
+
class HttpProvider {
|
|
871
|
+
/**
|
|
872
|
+
* Faz uma requisição usando o método GET do HTTP para uma URL específica.
|
|
873
|
+
*
|
|
874
|
+
* @param {string} url A URL que deve ser chamada.
|
|
875
|
+
* @param {Array<Header>} headers [Opcional] Cabeçalhos HTTP.
|
|
876
|
+
* @returns {Promise<Object>} Uma promessa de que a requisição será preenchida.
|
|
877
|
+
*/
|
|
878
|
+
static get(url, headers) {
|
|
879
|
+
return this.dispatch(new RequestMetadata(url, Method.GET, headers));
|
|
880
|
+
}
|
|
881
|
+
/**
|
|
882
|
+
* Faz uma requisição usando o método POST do HTTP para uma URL específica.
|
|
883
|
+
*
|
|
884
|
+
* @param {string} url A URL que deve ser chamada.
|
|
885
|
+
* @param {Object} payload Informações a serem enviadas.
|
|
886
|
+
* @param {Array<Header>} headers [Opcional] Cabeçalhos HTTP.
|
|
887
|
+
* @returns {Promise<Object>} Uma promessa de que a requisição será preenchida.
|
|
888
|
+
*/
|
|
889
|
+
static post(url, payload, headers) {
|
|
890
|
+
return this.dispatch(new RequestMetadata(url, Method.POST, headers), payload);
|
|
891
|
+
}
|
|
892
|
+
static dispatch(requestMetadata, payload) {
|
|
893
|
+
return new Promise((resolve, reject) => {
|
|
894
|
+
const request = new XMLHttpRequest();
|
|
895
|
+
request.timeout = requestMetadata.timeout;
|
|
896
|
+
request.onerror = function handleError() {
|
|
897
|
+
reject({
|
|
898
|
+
status: 404,
|
|
899
|
+
statusText: 'Not Found'
|
|
900
|
+
});
|
|
901
|
+
};
|
|
902
|
+
request.ontimeout = function handleTimeout() {
|
|
903
|
+
reject({
|
|
904
|
+
status: 408,
|
|
905
|
+
statusText: 'Request Timeout'
|
|
906
|
+
});
|
|
907
|
+
};
|
|
908
|
+
request.onreadystatechange = () => {
|
|
909
|
+
// While readState isn't done, there's nothing to do...
|
|
910
|
+
if (request.readyState != 4) {
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
const status = request.status;
|
|
914
|
+
// The request has failed so we'll handled by onerror instead
|
|
915
|
+
if (status === 0) {
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
918
|
+
const response = {
|
|
919
|
+
status,
|
|
920
|
+
statusText: request.statusText,
|
|
921
|
+
};
|
|
922
|
+
// Anything out of this range is an error, so we just send the status and statusText.
|
|
923
|
+
if (status >= 200 && status < 300) {
|
|
924
|
+
resolve(Object.assign(Object.assign({}, response), { data: request.response, dataAsString: request.responseText }));
|
|
925
|
+
}
|
|
926
|
+
else {
|
|
927
|
+
reject(response);
|
|
928
|
+
}
|
|
929
|
+
};
|
|
930
|
+
request.open(requestMetadata.method.toString(), requestMetadata.url, true);
|
|
931
|
+
requestMetadata.headers.map((h) => request.setRequestHeader(h.name, h.value));
|
|
932
|
+
if (payload != null) {
|
|
933
|
+
request.send(JSON.stringify(payload));
|
|
934
|
+
}
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
class SkwHttpProvider {
|
|
940
|
+
static callService(serviceName, content) {
|
|
941
|
+
return new Promise((resolve, reject) => {
|
|
942
|
+
let host = "http://192.168.1.218:8503/mge/";
|
|
943
|
+
let appName = "ListaTarefa";
|
|
944
|
+
let module = 'mge';
|
|
945
|
+
this._counter++;
|
|
946
|
+
if (serviceName.indexOf("@") > -1) {
|
|
947
|
+
let s = serviceName.split("@");
|
|
948
|
+
module = s[0];
|
|
949
|
+
serviceName = s[1];
|
|
950
|
+
}
|
|
951
|
+
let url = `${host}/${module}/service.sbr?serviceName=${serviceName}&counter=${this._counter}&application=${appName}&outputType=json&preventTransform=false`;
|
|
952
|
+
let requestContent = {
|
|
953
|
+
serviceName: serviceName,
|
|
954
|
+
requestBody: content
|
|
955
|
+
};
|
|
956
|
+
let headers = new Headers();
|
|
957
|
+
headers.append("Content-Type", "application/json");
|
|
958
|
+
//headers.append("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, PATCH, DELETE");
|
|
959
|
+
//headers.append("Access-Control-Allow-Origin", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
|
|
960
|
+
fetch(url, {
|
|
961
|
+
body: JSON.stringify(requestContent),
|
|
962
|
+
method: 'POST',
|
|
963
|
+
headers: headers
|
|
964
|
+
})
|
|
965
|
+
.then(res => res.json())
|
|
966
|
+
.then((data) => {
|
|
967
|
+
console.log(data);
|
|
968
|
+
});
|
|
969
|
+
/*HttpProvider.post(url, requestContent, headers)
|
|
970
|
+
.then(res => {
|
|
971
|
+
if (!res.hasOwnProperty('status') ||
|
|
972
|
+
res.status == this.STATUS_ERROR ||
|
|
973
|
+
res.status == this.STATUS_TIMEOUT) {
|
|
974
|
+
|
|
975
|
+
let statusMessage = res.statusMessage;
|
|
976
|
+
|
|
977
|
+
if (!statusMessage) {
|
|
978
|
+
statusMessage = 'Erro não identificado.'
|
|
979
|
+
}
|
|
980
|
+
//TODO: No futuro, exibir mensagens de erro. (MessageUtils.showError)
|
|
981
|
+
reject(new Error(statusMessage));
|
|
982
|
+
}else if (res.status == this.STATUS_CANCELED) {
|
|
983
|
+
if (res.statusMessage){
|
|
984
|
+
console.warn(res.statusMessage);
|
|
985
|
+
}
|
|
986
|
+
}else{
|
|
987
|
+
resolve(res);
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
if (res.status == this.STATUS_INFO) {
|
|
991
|
+
//TODO: No futuro, exibir mensagens de erro. (MessageUtils.showAlert)
|
|
992
|
+
console.info(res.statusMessage);
|
|
993
|
+
}
|
|
994
|
+
})
|
|
995
|
+
.catch((e)=>{reject(e)});*/
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
SkwHttpProvider._counter = 0;
|
|
1000
|
+
SkwHttpProvider.STATUS_ERROR = 0;
|
|
1001
|
+
SkwHttpProvider.STATUS_OK = 1;
|
|
1002
|
+
SkwHttpProvider.STATUS_INFO = 2;
|
|
1003
|
+
SkwHttpProvider.STATUS_TIMEOUT = 3;
|
|
1004
|
+
SkwHttpProvider.STATUS_CANCELED = 4;
|
|
1005
|
+
|
|
1006
|
+
var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
1007
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1008
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1009
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1010
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1011
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1012
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1013
|
+
});
|
|
1014
|
+
};
|
|
1015
|
+
class AuthorizedServiceCaller {
|
|
1016
|
+
constructor(serverURL, unauthorizedPath) {
|
|
1017
|
+
this.serverURL = "http://192.168.1.218:8503"; //todo request deve fazer replace de ${serverURL} pelo conteúdo da variável
|
|
1018
|
+
this.unauthorizedPath = "/";
|
|
1019
|
+
this.serverURL = serverURL;
|
|
1020
|
+
this.unauthorizedPath = unauthorizedPath;
|
|
1021
|
+
}
|
|
1022
|
+
requestService(request, callback) {
|
|
1023
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
1024
|
+
const token = localStorage.getItem('token');
|
|
1025
|
+
const body = request === null || request === void 0 ? void 0 : request.body;
|
|
1026
|
+
const method = request === null || request === void 0 ? void 0 : request.method;
|
|
1027
|
+
let headers;
|
|
1028
|
+
if (!token) {
|
|
1029
|
+
window.location.pathname = this.unauthorizedPath;
|
|
1030
|
+
}
|
|
1031
|
+
else {
|
|
1032
|
+
headers = {
|
|
1033
|
+
'Authorization': `${token}`,
|
|
1034
|
+
'Content-Type': 'application/json',
|
|
1035
|
+
'Customer-Host': 'http://localhost:8080/sankhyaw'
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
const response = yield yield fetch(this.serverURL, {
|
|
1039
|
+
method: method,
|
|
1040
|
+
headers: headers,
|
|
1041
|
+
body: body
|
|
1042
|
+
})
|
|
1043
|
+
.catch(e => {
|
|
1044
|
+
console.log(e);
|
|
1045
|
+
});
|
|
1046
|
+
if (response instanceof Response && response.status === 401) {
|
|
1047
|
+
localStorage.removeItem('token');
|
|
1048
|
+
window.location.pathname = this.unauthorizedPath;
|
|
1049
|
+
}
|
|
1050
|
+
if (callback && response instanceof Response) {
|
|
1051
|
+
callback(response.json().then());
|
|
1052
|
+
}
|
|
1053
|
+
else {
|
|
1054
|
+
return response;
|
|
1055
|
+
}
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
exports.DataType = void 0;
|
|
1061
|
+
(function (DataType) {
|
|
1062
|
+
DataType["NUMBER"] = "NUMBER";
|
|
1063
|
+
DataType["DATE"] = "DATE";
|
|
1064
|
+
DataType["TEXT"] = "TEXT";
|
|
1065
|
+
DataType["BOOLEAN"] = "BOOLEAN";
|
|
1066
|
+
DataType["OBJECT"] = "OBJECT";
|
|
1067
|
+
})(exports.DataType || (exports.DataType = {}));
|
|
1068
|
+
const convertType = (dataType, value) => {
|
|
1069
|
+
if (value === undefined || value === null) {
|
|
1070
|
+
return value;
|
|
1071
|
+
}
|
|
1072
|
+
if (typeof value === "object" && dataType !== exports.DataType.OBJECT && "value" in value) {
|
|
1073
|
+
value = value.value;
|
|
1074
|
+
}
|
|
1075
|
+
switch (dataType) {
|
|
1076
|
+
case exports.DataType.NUMBER:
|
|
1077
|
+
return value === "" || isNaN(value) ? null : Number(value);
|
|
1078
|
+
case exports.DataType.OBJECT:
|
|
1079
|
+
return typeof value === "string" ? JSON.parse(value) : value;
|
|
1080
|
+
case exports.DataType.BOOLEAN:
|
|
1081
|
+
if (typeof value == 'string') {
|
|
1082
|
+
return Boolean(value === 'true');
|
|
1083
|
+
}
|
|
1084
|
+
return Boolean(value);
|
|
1085
|
+
case exports.DataType.DATE:
|
|
1086
|
+
return new Date(value.toString());
|
|
1087
|
+
default:
|
|
1088
|
+
return value;
|
|
1089
|
+
}
|
|
1090
|
+
};
|
|
1091
|
+
const toString = (dataType, value) => {
|
|
1092
|
+
if (value === undefined || value === null) {
|
|
1093
|
+
return value;
|
|
1094
|
+
}
|
|
1095
|
+
if (dataType) {
|
|
1096
|
+
if (dataType === exports.DataType.OBJECT) {
|
|
1097
|
+
return JSON.stringify(value);
|
|
1098
|
+
}
|
|
1099
|
+
else if (dataType === exports.DataType.DATE) {
|
|
1100
|
+
return value.toISOString();
|
|
1101
|
+
}
|
|
1102
|
+
else {
|
|
1103
|
+
return value.toString();
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
else {
|
|
1107
|
+
if (typeof value === "string") {
|
|
1108
|
+
return value;
|
|
1109
|
+
}
|
|
1110
|
+
else if (value instanceof Date) {
|
|
1111
|
+
return value.toISOString();
|
|
1112
|
+
}
|
|
1113
|
+
else {
|
|
1114
|
+
try {
|
|
1115
|
+
return JSON.stringify(value);
|
|
1116
|
+
}
|
|
1117
|
+
catch (_a) {
|
|
1118
|
+
value = value.toString();
|
|
1119
|
+
}
|
|
1120
|
+
return value;
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
};
|
|
1124
|
+
|
|
1125
|
+
class DataUnitAction {
|
|
1126
|
+
constructor(type, payload) {
|
|
1127
|
+
this._type = type;
|
|
1128
|
+
this._payload = payload;
|
|
1129
|
+
}
|
|
1130
|
+
get type() {
|
|
1131
|
+
return this._type;
|
|
1132
|
+
}
|
|
1133
|
+
get payload() {
|
|
1134
|
+
return this._payload;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
exports.Action = void 0;
|
|
1138
|
+
(function (Action) {
|
|
1139
|
+
Action["LOADING_METADATA"] = "loadingMetadata";
|
|
1140
|
+
Action["METADATA_LOADED"] = "metadataLoaded";
|
|
1141
|
+
Action["LOADING_DATA"] = "loadingData";
|
|
1142
|
+
Action["DATA_LOADED"] = "dataLoaded";
|
|
1143
|
+
Action["SAVING_DATA"] = "savingData";
|
|
1144
|
+
Action["DATA_SAVED"] = "dataSaved";
|
|
1145
|
+
Action["REMOVING_RECORDS"] = "removingRecords";
|
|
1146
|
+
Action["RECORDS_REMOVED"] = "recordsRemoved";
|
|
1147
|
+
Action["RECORDS_ADDED"] = "recordsAdded";
|
|
1148
|
+
Action["RECORDS_COPIED"] = "recordsCopied";
|
|
1149
|
+
Action["CHANGING_DATA"] = "changingData";
|
|
1150
|
+
Action["WAITING_CHANGE_CANCELED"] = "waitingChangeCanceled";
|
|
1151
|
+
Action["DATA_CHANGED"] = "dataChanged";
|
|
1152
|
+
Action["EDITION_CANCELED"] = "editionCanceled";
|
|
1153
|
+
Action["CHANGE_UNDONE"] = "changeUndone";
|
|
1154
|
+
Action["CHANGE_REDONE"] = "changeRedone";
|
|
1155
|
+
Action["SELECTION_CHANGED"] = "selectionChanged";
|
|
1156
|
+
Action["NEXT_SELECTED"] = "nextSelected";
|
|
1157
|
+
Action["PREVIOUS_SELECTED"] = "previousSelected";
|
|
1158
|
+
Action["STATE_CHANGED"] = "stateChanged";
|
|
1159
|
+
})(exports.Action || (exports.Action = {}));
|
|
1160
|
+
|
|
1161
|
+
/**
|
|
1162
|
+
* Essa classe representa uma interpretação do padrão de projetos Flux.
|
|
1163
|
+
* No padrão Flux os dados da aplicação são chamados de "estado" e existem
|
|
1164
|
+
* algumas regras para gerenciamento/manipulação desse estado:
|
|
1165
|
+
*
|
|
1166
|
+
* 1 - O estado é imutável.
|
|
1167
|
+
* 2 - Toda modificação de estado é representada por uma "ação".
|
|
1168
|
+
* 3 - Quando "ações" acontecem a "store" cria um novo estado e notifica a todos interessados.
|
|
1169
|
+
*
|
|
1170
|
+
* Nessa interpretação desse design pattern, o StateManager faz o papel da store,
|
|
1171
|
+
* notificando os manipuladores de estado (handlers), que são responsáveis por pedaços
|
|
1172
|
+
* do estado (slices).
|
|
1173
|
+
*
|
|
1174
|
+
* O StateManager mantém dois tipos de estados: "Histórico" e "Não Histórico". No estado
|
|
1175
|
+
* "Histórico", sempre que uma alteração de estado acontece, o estado anterior é guardado em
|
|
1176
|
+
* uma pilha, o que permite que possamos voltar no tempo, desfazendo algumas ações
|
|
1177
|
+
*/
|
|
1178
|
+
class StateManager {
|
|
1179
|
+
constructor(reducers) {
|
|
1180
|
+
this._past = [];
|
|
1181
|
+
this._future = [];
|
|
1182
|
+
this._present = {};
|
|
1183
|
+
this._nonHist = {};
|
|
1184
|
+
this._histClean = false;
|
|
1185
|
+
this._reducers = reducers;
|
|
1186
|
+
}
|
|
1187
|
+
process(action) {
|
|
1188
|
+
const oldPresent = this._present;
|
|
1189
|
+
let hasHistChange = false;
|
|
1190
|
+
this._histClean = false;
|
|
1191
|
+
this._reducers.forEach(reducer => {
|
|
1192
|
+
const sliceName = reducer.sliceName;
|
|
1193
|
+
const isHistoric = this.isHistoric(sliceName);
|
|
1194
|
+
const oldSlice = this.getSlice(sliceName, isHistoric);
|
|
1195
|
+
const newSlice = reducer.reduce(this, oldSlice, action);
|
|
1196
|
+
if (newSlice !== oldSlice) {
|
|
1197
|
+
this.updateSlice(sliceName, newSlice, isHistoric);
|
|
1198
|
+
hasHistChange || (hasHistChange = isHistoric);
|
|
1199
|
+
}
|
|
1200
|
+
});
|
|
1201
|
+
if (hasHistChange && !this._histClean) {
|
|
1202
|
+
this._past.push(oldPresent);
|
|
1203
|
+
this._future = [];
|
|
1204
|
+
document.dispatchEvent(new CustomEvent("undoableAction", { detail: this }));
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
select(sliceName, selector) {
|
|
1208
|
+
const isHistoric = this.isHistoric(sliceName);
|
|
1209
|
+
return selector(this.getSlice(sliceName, isHistoric));
|
|
1210
|
+
}
|
|
1211
|
+
isHistoric(slice) {
|
|
1212
|
+
return slice.startsWith("hist::");
|
|
1213
|
+
}
|
|
1214
|
+
updateSlice(name, slice, isHistoric) {
|
|
1215
|
+
if (isHistoric) {
|
|
1216
|
+
this._present = Object.assign(Object.assign({}, this._present), { [name]: slice });
|
|
1217
|
+
if (slice === undefined) {
|
|
1218
|
+
delete this._present[name];
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
else {
|
|
1222
|
+
this._nonHist = Object.assign(Object.assign({}, this._nonHist), { [name]: slice });
|
|
1223
|
+
if (slice === undefined) {
|
|
1224
|
+
delete this._nonHist[name];
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
getSlice(name, isHistoric) {
|
|
1229
|
+
return isHistoric ? this._present[name] : this._nonHist[name];
|
|
1230
|
+
}
|
|
1231
|
+
canUndo() {
|
|
1232
|
+
return this._past.length > 0;
|
|
1233
|
+
}
|
|
1234
|
+
canRedo() {
|
|
1235
|
+
return this._future.length > 0;
|
|
1236
|
+
}
|
|
1237
|
+
undo() {
|
|
1238
|
+
if (this.canUndo()) {
|
|
1239
|
+
this._future.push(this._present);
|
|
1240
|
+
this._present = this._past.pop();
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
redo() {
|
|
1244
|
+
if (this.canRedo()) {
|
|
1245
|
+
this._past.push(this._present);
|
|
1246
|
+
this._present = this._future.pop();
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
clearUndo() {
|
|
1250
|
+
this._histClean = true;
|
|
1251
|
+
this._past = [];
|
|
1252
|
+
this._future = [];
|
|
1253
|
+
}
|
|
1254
|
+
persist() {
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
class ErrorException extends Error {
|
|
1259
|
+
constructor(title, message, errorCode = "") {
|
|
1260
|
+
super(message);
|
|
1261
|
+
this.title = title;
|
|
1262
|
+
this.message = message;
|
|
1263
|
+
this.errorCode = errorCode;
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
class WaitingChangeException extends Error {
|
|
1268
|
+
constructor(title, message) {
|
|
1269
|
+
super(message);
|
|
1270
|
+
this.title = title;
|
|
1271
|
+
this.message = message;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
class AddedRecordsReducerImpl {
|
|
1276
|
+
constructor() {
|
|
1277
|
+
this.sliceName = "hist::addedRecords";
|
|
1278
|
+
}
|
|
1279
|
+
reduce(_stateManager, currentState, action) {
|
|
1280
|
+
switch (action.type) {
|
|
1281
|
+
case exports.Action.RECORDS_ADDED:
|
|
1282
|
+
case exports.Action.RECORDS_COPIED:
|
|
1283
|
+
return (currentState || []).concat(action.payload);
|
|
1284
|
+
case exports.Action.DATA_SAVED:
|
|
1285
|
+
case exports.Action.EDITION_CANCELED:
|
|
1286
|
+
return undefined;
|
|
1287
|
+
}
|
|
1288
|
+
return currentState;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
const AddedRecordsReducer = new AddedRecordsReducerImpl();
|
|
1292
|
+
const getAddedRecords = (stateManager) => {
|
|
1293
|
+
return stateManager.select(AddedRecordsReducer.sliceName, (state) => state);
|
|
1294
|
+
};
|
|
1295
|
+
const prepareAddedRecordId = (stateManager, source) => {
|
|
1296
|
+
let index = (getAddedRecords(stateManager) || []).length;
|
|
1297
|
+
return source.map(item => { return Object.assign(Object.assign({}, item), { __record__id__: "NEW_" + (index++) }); });
|
|
1298
|
+
};
|
|
1299
|
+
const prepareCopiedRecord = (stateManager, source) => {
|
|
1300
|
+
let index = (getAddedRecords(stateManager) || []).length;
|
|
1301
|
+
return source.map(item => { return Object.assign(Object.assign({}, item), { __record__id__: "NEW_" + (index++), __record__source__id__: item.__record__id__, __copy__: true }); });
|
|
1302
|
+
};
|
|
1303
|
+
|
|
1304
|
+
class RemovedRecordsReducerImpl {
|
|
1305
|
+
constructor() {
|
|
1306
|
+
this.sliceName = "hist::removedRecords";
|
|
1307
|
+
}
|
|
1308
|
+
reduce(_stateManager, currentState, action) {
|
|
1309
|
+
switch (action.type) {
|
|
1310
|
+
case exports.Action.RECORDS_REMOVED:
|
|
1311
|
+
const { records, buffered } = action.payload;
|
|
1312
|
+
if (buffered) {
|
|
1313
|
+
return (currentState || []).concat(records);
|
|
1314
|
+
}
|
|
1315
|
+
return currentState;
|
|
1316
|
+
case exports.Action.EDITION_CANCELED:
|
|
1317
|
+
case exports.Action.DATA_SAVED:
|
|
1318
|
+
return undefined;
|
|
1319
|
+
}
|
|
1320
|
+
return currentState;
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
const RemovedRecordsReducer = new RemovedRecordsReducerImpl();
|
|
1324
|
+
const getRemovedRecords = (stateManager) => {
|
|
1325
|
+
return stateManager.select(RemovedRecordsReducer.sliceName, (state) => state);
|
|
1326
|
+
};
|
|
1327
|
+
|
|
1328
|
+
class RecordsReducerImpl {
|
|
1329
|
+
constructor() {
|
|
1330
|
+
this.sliceName = "records";
|
|
1331
|
+
}
|
|
1332
|
+
reduce(stateManager, currentState, action) {
|
|
1333
|
+
switch (action.type) {
|
|
1334
|
+
case exports.Action.DATA_LOADED:
|
|
1335
|
+
return action.payload ? action.payload.records : undefined;
|
|
1336
|
+
case exports.Action.RECORDS_REMOVED:
|
|
1337
|
+
const { records, buffered } = action.payload;
|
|
1338
|
+
if (!buffered) {
|
|
1339
|
+
return currentState.filter(r => !records.includes(r.__record__id__));
|
|
1340
|
+
}
|
|
1341
|
+
return currentState;
|
|
1342
|
+
case exports.Action.DATA_SAVED:
|
|
1343
|
+
const recordsMap = new Map();
|
|
1344
|
+
const currentRecords = getRecords(stateManager);
|
|
1345
|
+
if (currentRecords) {
|
|
1346
|
+
const removed = getRemovedRecords(stateManager) || [];
|
|
1347
|
+
currentRecords.forEach(r => {
|
|
1348
|
+
if (!removed.includes(r.__record__id__)) {
|
|
1349
|
+
recordsMap.set(r.__record__id__, r);
|
|
1350
|
+
}
|
|
1351
|
+
});
|
|
1352
|
+
}
|
|
1353
|
+
const newRecords = [];
|
|
1354
|
+
const savedRecords = action.payload.records;
|
|
1355
|
+
savedRecords.forEach(sr => {
|
|
1356
|
+
const recordId = sr.__old__id__ || sr.__record__id__;
|
|
1357
|
+
const newRecord = Object.assign({}, sr);
|
|
1358
|
+
delete newRecord["__old__id__"];
|
|
1359
|
+
if (recordsMap.has(recordId)) {
|
|
1360
|
+
recordsMap.set(recordId, newRecord);
|
|
1361
|
+
}
|
|
1362
|
+
else {
|
|
1363
|
+
newRecords.push(newRecord);
|
|
1364
|
+
}
|
|
1365
|
+
});
|
|
1366
|
+
return newRecords.concat(Array.from(recordsMap.values()));
|
|
1367
|
+
}
|
|
1368
|
+
return currentState;
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
const RecordsReducer = new RecordsReducerImpl();
|
|
1372
|
+
const getRecords = (stateManager) => {
|
|
1373
|
+
return stateManager.select(RecordsReducer.sliceName, (state) => state);
|
|
1374
|
+
};
|
|
1375
|
+
|
|
1376
|
+
class CurrentRecordsReducerImpl {
|
|
1377
|
+
constructor() {
|
|
1378
|
+
this.sliceName = "currentRecords";
|
|
1379
|
+
}
|
|
1380
|
+
reduce(stateManager) {
|
|
1381
|
+
let records = getRecords(stateManager);
|
|
1382
|
+
const added = getAddedRecords(stateManager);
|
|
1383
|
+
if (!records && !added) {
|
|
1384
|
+
return undefined;
|
|
1385
|
+
}
|
|
1386
|
+
if (added) {
|
|
1387
|
+
records = (added || []).concat(records || []);
|
|
1388
|
+
}
|
|
1389
|
+
const removedRecords = getRemovedRecords(stateManager);
|
|
1390
|
+
if (removedRecords) {
|
|
1391
|
+
records = records.filter(r => !removedRecords.includes(r.__record__id__));
|
|
1392
|
+
}
|
|
1393
|
+
const changes = getChanges(stateManager);
|
|
1394
|
+
return new Map(records.map(r => {
|
|
1395
|
+
const recordId = r.__record__id__;
|
|
1396
|
+
const record = Object.assign(Object.assign({}, r), changes === null || changes === void 0 ? void 0 : changes.get(recordId));
|
|
1397
|
+
return [recordId, record];
|
|
1398
|
+
}));
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
const CurrentRecordsReducer = new CurrentRecordsReducerImpl();
|
|
1402
|
+
const getCurrentRecords = (stateManager) => {
|
|
1403
|
+
return stateManager.select(CurrentRecordsReducer.sliceName, (state) => state);
|
|
1404
|
+
};
|
|
1405
|
+
const getModifiedRecords = (stateManager) => {
|
|
1406
|
+
const currentRecords = getCurrentRecords(stateManager);
|
|
1407
|
+
if (!currentRecords) {
|
|
1408
|
+
return undefined;
|
|
1409
|
+
}
|
|
1410
|
+
const changes = getChanges(stateManager);
|
|
1411
|
+
const added = getAddedRecords(stateManager);
|
|
1412
|
+
if (!changes && !added) {
|
|
1413
|
+
return undefined;
|
|
1414
|
+
}
|
|
1415
|
+
let modifiedIDs = changes ? Array.from(changes.keys()) : [];
|
|
1416
|
+
if (added) {
|
|
1417
|
+
modifiedIDs = modifiedIDs.concat(added.map(r => r.__record__id__));
|
|
1418
|
+
}
|
|
1419
|
+
return Array.from(currentRecords.values()).filter(r => modifiedIDs.includes(r.__record__id__));
|
|
1420
|
+
};
|
|
1421
|
+
const getFieldValue = (stateManager, fieldName) => {
|
|
1422
|
+
const selection = getSelection(stateManager);
|
|
1423
|
+
if (selection && selection.length > 0) {
|
|
1424
|
+
const currentRecords = getCurrentRecords(stateManager);
|
|
1425
|
+
if (currentRecords) {
|
|
1426
|
+
const record = currentRecords.get(selection[0]);
|
|
1427
|
+
return record ? record[fieldName] : undefined;
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
return undefined;
|
|
1431
|
+
};
|
|
1432
|
+
|
|
1433
|
+
class SelectionReducerImpl {
|
|
1434
|
+
constructor() {
|
|
1435
|
+
this.sliceName = "hist::selection";
|
|
1436
|
+
}
|
|
1437
|
+
reduce(stateManager, currentState, action) {
|
|
1438
|
+
switch (action.type) {
|
|
1439
|
+
case exports.Action.RECORDS_ADDED:
|
|
1440
|
+
case exports.Action.RECORDS_COPIED:
|
|
1441
|
+
return { currentSelection: action.payload.map((r) => r.__record__id__), lastSelection: currentState === null || currentState === void 0 ? void 0 : currentState.currentSelection };
|
|
1442
|
+
case exports.Action.DATA_SAVED:
|
|
1443
|
+
return { currentSelection: updateSavedIds(stateManager, action.payload.records) };
|
|
1444
|
+
case exports.Action.RECORDS_REMOVED:
|
|
1445
|
+
const removed = action.payload.records;
|
|
1446
|
+
if (currentState && removed) {
|
|
1447
|
+
const currentSelection = currentState.currentSelection;
|
|
1448
|
+
const record = currentSelection.filter(recordId => !removed.includes(recordId));
|
|
1449
|
+
if (record.length === 0) {
|
|
1450
|
+
const currentRecords = getCurrentRecords(stateManager);
|
|
1451
|
+
let removedIndex = action.payload.removedIndex.slice(-1)[0];
|
|
1452
|
+
let currentIndex = 0;
|
|
1453
|
+
if (removedIndex >= currentRecords.size - 1) {
|
|
1454
|
+
removedIndex--;
|
|
1455
|
+
}
|
|
1456
|
+
else {
|
|
1457
|
+
removedIndex++;
|
|
1458
|
+
}
|
|
1459
|
+
currentRecords.forEach((value, key) => {
|
|
1460
|
+
if (currentIndex === removedIndex) {
|
|
1461
|
+
record.push(key);
|
|
1462
|
+
}
|
|
1463
|
+
currentIndex++;
|
|
1464
|
+
});
|
|
1465
|
+
}
|
|
1466
|
+
return { currentSelection: record };
|
|
1467
|
+
}
|
|
1468
|
+
return currentState;
|
|
1469
|
+
case exports.Action.NEXT_SELECTED:
|
|
1470
|
+
case exports.Action.PREVIOUS_SELECTED:
|
|
1471
|
+
const currentRecords = getCurrentRecords(stateManager);
|
|
1472
|
+
const currentSelection = currentState === null || currentState === void 0 ? void 0 : currentState.currentSelection;
|
|
1473
|
+
if (currentRecords && currentRecords.size > 0) {
|
|
1474
|
+
let index;
|
|
1475
|
+
if (!currentState || currentSelection.length === 0) {
|
|
1476
|
+
index = action.type === exports.Action.PREVIOUS_SELECTED ? 0 : Math.min(1, currentRecords.size);
|
|
1477
|
+
}
|
|
1478
|
+
else {
|
|
1479
|
+
index = getItemIndex(currentSelection[0], currentRecords) + (action.type === exports.Action.PREVIOUS_SELECTED ? -1 : 1);
|
|
1480
|
+
}
|
|
1481
|
+
if (index < currentRecords.size && index >= 0) {
|
|
1482
|
+
return { currentSelection: [Array.from(currentRecords.values())[index].__record__id__] };
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
return undefined;
|
|
1486
|
+
case exports.Action.SELECTION_CHANGED:
|
|
1487
|
+
const { type, selection: selectionSource } = action.payload;
|
|
1488
|
+
if (selectionSource && type === "index") {
|
|
1489
|
+
const currentRecords = getCurrentRecords(stateManager);
|
|
1490
|
+
if (currentRecords) {
|
|
1491
|
+
const records = Array.from(currentRecords.values());
|
|
1492
|
+
const selectionById = [];
|
|
1493
|
+
selectionSource.forEach((i) => {
|
|
1494
|
+
if (i >= 0 && i < currentRecords.size) {
|
|
1495
|
+
selectionById.push(records[i].__record__id__);
|
|
1496
|
+
}
|
|
1497
|
+
});
|
|
1498
|
+
return { currentSelection: selectionById };
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
return { currentSelection: selectionSource };
|
|
1502
|
+
case exports.Action.EDITION_CANCELED:
|
|
1503
|
+
if (currentState === null || currentState === void 0 ? void 0 : currentState.lastSelection) {
|
|
1504
|
+
return { currentSelection: currentState.lastSelection };
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
return currentState;
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
const SelectionReducer = new SelectionReducerImpl();
|
|
1511
|
+
const getSelection = (stateManager) => {
|
|
1512
|
+
let selection = getCurrentSelection(stateManager);
|
|
1513
|
+
if (!selection || selection.length === 0) {
|
|
1514
|
+
return [];
|
|
1515
|
+
}
|
|
1516
|
+
return selection;
|
|
1517
|
+
};
|
|
1518
|
+
const hasNext = (stateManager) => {
|
|
1519
|
+
const records = getCurrentRecords(stateManager);
|
|
1520
|
+
if (records) {
|
|
1521
|
+
const selection = getCurrentSelection(stateManager);
|
|
1522
|
+
if (!selection || selection.length === 0) {
|
|
1523
|
+
return records.size > 0;
|
|
1524
|
+
}
|
|
1525
|
+
return records.size > (getItemIndex(selection[0], records) + 1);
|
|
1526
|
+
}
|
|
1527
|
+
return false;
|
|
1528
|
+
};
|
|
1529
|
+
const hasPrevious = (stateManager) => {
|
|
1530
|
+
const records = getCurrentRecords(stateManager);
|
|
1531
|
+
if (records) {
|
|
1532
|
+
const selection = getCurrentSelection(stateManager);
|
|
1533
|
+
if (!selection || selection.length === 0) {
|
|
1534
|
+
return false;
|
|
1535
|
+
}
|
|
1536
|
+
return getItemIndex(selection[0], records) > 0;
|
|
1537
|
+
}
|
|
1538
|
+
return false;
|
|
1539
|
+
};
|
|
1540
|
+
function getItemIndex(key, map) {
|
|
1541
|
+
return Array.from(map.keys()).indexOf(key);
|
|
1542
|
+
}
|
|
1543
|
+
function updateSavedIds(stateManager, savedRecords) {
|
|
1544
|
+
const currentSelection = getSelection(stateManager);
|
|
1545
|
+
if (currentSelection) {
|
|
1546
|
+
const newSelection = [];
|
|
1547
|
+
currentSelection.forEach(id => {
|
|
1548
|
+
const record = savedRecords.find(r => r.__old__id__ === id);
|
|
1549
|
+
if (record) {
|
|
1550
|
+
newSelection.push(record.__record__id__);
|
|
1551
|
+
}
|
|
1552
|
+
else {
|
|
1553
|
+
newSelection.push(id);
|
|
1554
|
+
}
|
|
1555
|
+
});
|
|
1556
|
+
return newSelection;
|
|
1557
|
+
}
|
|
1558
|
+
return currentSelection;
|
|
1559
|
+
}
|
|
1560
|
+
function getCurrentSelection(stateManager) {
|
|
1561
|
+
var _a;
|
|
1562
|
+
return (_a = stateManager.select(SelectionReducer.sliceName, (state) => state)) === null || _a === void 0 ? void 0 : _a.currentSelection;
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
class WaitingCheangesReducerImpl {
|
|
1566
|
+
constructor() {
|
|
1567
|
+
this.sliceName = "waitingChanges";
|
|
1568
|
+
}
|
|
1569
|
+
reduce(stateManager, currentState, action) {
|
|
1570
|
+
let newState;
|
|
1571
|
+
switch (action.type) {
|
|
1572
|
+
case exports.Action.CHANGING_DATA:
|
|
1573
|
+
newState = new Map(currentState);
|
|
1574
|
+
Object.entries(action.payload).forEach(([key, value]) => {
|
|
1575
|
+
newState.set(key, value);
|
|
1576
|
+
});
|
|
1577
|
+
return newState;
|
|
1578
|
+
case exports.Action.WAITING_CHANGE_CANCELED:
|
|
1579
|
+
newState = new Map(currentState);
|
|
1580
|
+
newState.delete(action.payload.fieldName);
|
|
1581
|
+
return newState.size === 0 ? undefined : newState;
|
|
1582
|
+
case exports.Action.DATA_CHANGED:
|
|
1583
|
+
newState = new Map(currentState);
|
|
1584
|
+
Object.entries(action.payload).forEach(([key]) => {
|
|
1585
|
+
newState.delete(key);
|
|
1586
|
+
});
|
|
1587
|
+
return newState.size === 0 ? undefined : newState;
|
|
1588
|
+
case exports.Action.DATA_SAVED:
|
|
1589
|
+
case exports.Action.EDITION_CANCELED:
|
|
1590
|
+
return undefined;
|
|
1591
|
+
}
|
|
1592
|
+
return currentState;
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
const WaitingChangesReducer = new WaitingCheangesReducerImpl();
|
|
1596
|
+
const getWaitingChanges = (stateManager) => {
|
|
1597
|
+
return stateManager.select(WaitingChangesReducer.sliceName, (state) => state);
|
|
1598
|
+
};
|
|
1599
|
+
const isWaiting = (stateManager, fieldName) => {
|
|
1600
|
+
const allWC = getWaitingChanges(stateManager);
|
|
1601
|
+
return allWC ? allWC.has(fieldName) : false;
|
|
1602
|
+
};
|
|
1603
|
+
const getBlockingWaitingChanges = (stateManager) => {
|
|
1604
|
+
const allWC = getWaitingChanges(stateManager);
|
|
1605
|
+
if (allWC) {
|
|
1606
|
+
return new Map(Array.from(allWC.entries())
|
|
1607
|
+
.filter(entry => entry[1].blocking)
|
|
1608
|
+
.map(entry => [entry[0], entry[1]]));
|
|
1609
|
+
}
|
|
1610
|
+
};
|
|
1611
|
+
const getWaitingChangePromisses = (stateManager) => {
|
|
1612
|
+
const allWC = getWaitingChanges(stateManager);
|
|
1613
|
+
if (allWC) {
|
|
1614
|
+
return Array.from(allWC.values())
|
|
1615
|
+
.filter(wc => !wc.blocking)
|
|
1616
|
+
.map(wc => wc.promise);
|
|
1617
|
+
}
|
|
1618
|
+
};
|
|
1619
|
+
|
|
1620
|
+
class ChangesReducerImpl {
|
|
1621
|
+
constructor() {
|
|
1622
|
+
this.sliceName = "hist::changes";
|
|
1623
|
+
}
|
|
1624
|
+
reduce(stateManager, currentState, action) {
|
|
1625
|
+
switch (action.type) {
|
|
1626
|
+
case exports.Action.RECORDS_COPIED:
|
|
1627
|
+
const records = action.payload;
|
|
1628
|
+
const changes = new Map(getChanges(stateManager));
|
|
1629
|
+
records.forEach(r => {
|
|
1630
|
+
const rChanges = Object.assign(Object.assign({}, changes.get(r.__record__id__)), r);
|
|
1631
|
+
delete rChanges.__old__id__;
|
|
1632
|
+
delete rChanges.__record__id__;
|
|
1633
|
+
delete rChanges.__parent__record__id__;
|
|
1634
|
+
delete rChanges.__record__source__id__;
|
|
1635
|
+
delete rChanges.__copy__;
|
|
1636
|
+
changes.set(r.__record__id__, rChanges);
|
|
1637
|
+
});
|
|
1638
|
+
return changes;
|
|
1639
|
+
case exports.Action.DATA_CHANGED:
|
|
1640
|
+
const selection = action.payload.records || getSelection(stateManager);
|
|
1641
|
+
if (selection) {
|
|
1642
|
+
const newState = new Map(currentState);
|
|
1643
|
+
selection.forEach(recordId => {
|
|
1644
|
+
const newChanges = Object.assign(Object.assign({}, newState.get(recordId)), action.payload);
|
|
1645
|
+
delete newChanges.records;
|
|
1646
|
+
newState.set(recordId, newChanges);
|
|
1647
|
+
});
|
|
1648
|
+
return newState;
|
|
1649
|
+
}
|
|
1650
|
+
return currentState;
|
|
1651
|
+
case exports.Action.DATA_SAVED:
|
|
1652
|
+
case exports.Action.EDITION_CANCELED:
|
|
1653
|
+
return undefined;
|
|
1654
|
+
}
|
|
1655
|
+
return currentState;
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
const ChangesReducer = new ChangesReducerImpl();
|
|
1659
|
+
const getChanges = (stateManager) => {
|
|
1660
|
+
return stateManager.select(ChangesReducer.sliceName, (state) => state);
|
|
1661
|
+
};
|
|
1662
|
+
const isDirty = (stateManager) => {
|
|
1663
|
+
if (getAddedRecords(stateManager) !== undefined) {
|
|
1664
|
+
return true;
|
|
1665
|
+
}
|
|
1666
|
+
if (getRemovedRecords(stateManager) !== undefined) {
|
|
1667
|
+
return true;
|
|
1668
|
+
}
|
|
1669
|
+
return hasDirtyRecords(stateManager);
|
|
1670
|
+
};
|
|
1671
|
+
const hasDirtyRecords = (stateManager) => {
|
|
1672
|
+
if (getWaitingChanges(stateManager) !== undefined) {
|
|
1673
|
+
return true;
|
|
1674
|
+
}
|
|
1675
|
+
return getChanges(stateManager) !== undefined;
|
|
1676
|
+
};
|
|
1677
|
+
const getChangesToSave = (dataUnit, stateManager) => {
|
|
1678
|
+
const result = [];
|
|
1679
|
+
const changes = getChanges(stateManager);
|
|
1680
|
+
const records = getRecords(stateManager);
|
|
1681
|
+
records === null || records === void 0 ? void 0 : records.forEach(r => {
|
|
1682
|
+
if (changes) {
|
|
1683
|
+
const c = changes.get(r.__record__id__);
|
|
1684
|
+
if (c) {
|
|
1685
|
+
result.push(new Change(dataUnit, r, c, exports.ChangeOperation.UPDATE));
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
});
|
|
1689
|
+
const addedRecords = getAddedRecords(stateManager);
|
|
1690
|
+
if (addedRecords) {
|
|
1691
|
+
addedRecords.forEach(r => {
|
|
1692
|
+
const operation = r.__copy__ ? exports.ChangeOperation.COPY : exports.ChangeOperation.INSERT;
|
|
1693
|
+
result.push(new Change(dataUnit, r, changes === null || changes === void 0 ? void 0 : changes.get(r.__record__id__), operation, r.__record__source__id__));
|
|
1694
|
+
});
|
|
1695
|
+
}
|
|
1696
|
+
const removedRecords = getRemovedRecords(stateManager);
|
|
1697
|
+
const recordsById = {};
|
|
1698
|
+
records === null || records === void 0 ? void 0 : records.forEach(r => recordsById[r.__record__id__] = r);
|
|
1699
|
+
if (removedRecords) {
|
|
1700
|
+
removedRecords.forEach(id => {
|
|
1701
|
+
result.push(new Change(dataUnit, recordsById[id], undefined, exports.ChangeOperation.DELETE));
|
|
1702
|
+
});
|
|
1703
|
+
}
|
|
1704
|
+
return result;
|
|
1705
|
+
};
|
|
1706
|
+
|
|
1707
|
+
class LoadingControlReducerImpl {
|
|
1708
|
+
constructor() {
|
|
1709
|
+
this.sliceName = "loadingControl";
|
|
1710
|
+
}
|
|
1711
|
+
reduce(stateManager, currentState, action) {
|
|
1712
|
+
var _a;
|
|
1713
|
+
switch (action.type) {
|
|
1714
|
+
case exports.Action.LOADING_DATA:
|
|
1715
|
+
return Object.assign(Object.assign({}, currentState), { lastRequest: action.payload });
|
|
1716
|
+
case exports.Action.DATA_LOADED:
|
|
1717
|
+
return Object.assign(Object.assign({}, currentState), { paginationInfo: (_a = action.payload) === null || _a === void 0 ? void 0 : _a.paginationInfo });
|
|
1718
|
+
}
|
|
1719
|
+
return currentState;
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
const LoadingControlReducer = new LoadingControlReducerImpl();
|
|
1723
|
+
const getPaginationInfo = (stateManager) => {
|
|
1724
|
+
const state = stateManager.select(LoadingControlReducer.sliceName, (state) => state);
|
|
1725
|
+
return state ? state.paginationInfo : undefined;
|
|
1726
|
+
};
|
|
1727
|
+
const getCurrentRequest = (stateManager) => {
|
|
1728
|
+
const state = stateManager.select(LoadingControlReducer.sliceName, (state) => state);
|
|
1729
|
+
return state ? state.lastRequest : undefined;
|
|
1730
|
+
};
|
|
1731
|
+
const getCurrentPage = (stateManager) => {
|
|
1732
|
+
const paginationInfo = getPaginationInfo(stateManager);
|
|
1733
|
+
return paginationInfo ? paginationInfo.currentPage : 0;
|
|
1734
|
+
};
|
|
1735
|
+
const getLastPage = (stateManager, pageSize) => {
|
|
1736
|
+
const paginationInfo = getPaginationInfo(stateManager);
|
|
1737
|
+
return paginationInfo ? Math.ceil(paginationInfo.total / pageSize) : 0;
|
|
1738
|
+
};
|
|
1739
|
+
const hasMorePages = (stateManager) => {
|
|
1740
|
+
const paginationInfo = getPaginationInfo(stateManager);
|
|
1741
|
+
if (paginationInfo && paginationInfo.hasMore) {
|
|
1742
|
+
return true;
|
|
1743
|
+
}
|
|
1744
|
+
return false;
|
|
1745
|
+
};
|
|
1746
|
+
const hasPreviousPages = (stateManager) => {
|
|
1747
|
+
const paginationInfo = getPaginationInfo(stateManager);
|
|
1748
|
+
return paginationInfo ? paginationInfo.currentPage > 0 : false;
|
|
1749
|
+
};
|
|
1750
|
+
|
|
1751
|
+
class UnitMetadataReducerImpl {
|
|
1752
|
+
constructor() {
|
|
1753
|
+
this.sliceName = "unitMetadata";
|
|
1754
|
+
}
|
|
1755
|
+
reduce(_stateManager, currentState, action) {
|
|
1756
|
+
if (action.type === exports.Action.METADATA_LOADED) {
|
|
1757
|
+
return action.payload;
|
|
1758
|
+
}
|
|
1759
|
+
return currentState;
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
const UnitMetadataReducer = new UnitMetadataReducerImpl();
|
|
1763
|
+
const getMetadata = (stateManager) => {
|
|
1764
|
+
return stateManager.select(UnitMetadataReducer.sliceName, (state) => state);
|
|
1765
|
+
};
|
|
1766
|
+
const getField = (stateManager, fieldName) => {
|
|
1767
|
+
const md = getMetadata(stateManager);
|
|
1768
|
+
return md ? md.fields.find(fmd => fmd.name === fieldName) : undefined;
|
|
1769
|
+
};
|
|
1770
|
+
|
|
1771
|
+
class HistReducerImpl {
|
|
1772
|
+
constructor() {
|
|
1773
|
+
this.sliceName = "";
|
|
1774
|
+
}
|
|
1775
|
+
reduce(stateManager, _currentState, action) {
|
|
1776
|
+
switch (action.type) {
|
|
1777
|
+
case exports.Action.DATA_SAVED:
|
|
1778
|
+
case exports.Action.EDITION_CANCELED:
|
|
1779
|
+
stateManager.clearUndo();
|
|
1780
|
+
break;
|
|
1781
|
+
case exports.Action.CHANGE_UNDONE:
|
|
1782
|
+
stateManager.undo();
|
|
1783
|
+
break;
|
|
1784
|
+
case exports.Action.CHANGE_REDONE:
|
|
1785
|
+
stateManager.redo();
|
|
1786
|
+
break;
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
const HistReducer = new HistReducerImpl();
|
|
1791
|
+
const canUndo = (stateManager) => {
|
|
1792
|
+
return stateManager.canUndo();
|
|
1793
|
+
};
|
|
1794
|
+
const canRedo = (stateManager) => {
|
|
1795
|
+
return stateManager.canRedo();
|
|
1796
|
+
};
|
|
1797
|
+
|
|
1798
|
+
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
1799
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1800
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1801
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1802
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1803
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1804
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1805
|
+
});
|
|
1806
|
+
};
|
|
1807
|
+
class DataUnit {
|
|
1808
|
+
constructor(name) {
|
|
1809
|
+
this._name = name;
|
|
1810
|
+
this._pageSize = 0;
|
|
1811
|
+
this._stateManager = new StateManager([
|
|
1812
|
+
HistReducer,
|
|
1813
|
+
UnitMetadataReducer,
|
|
1814
|
+
LoadingControlReducer,
|
|
1815
|
+
RecordsReducer,
|
|
1816
|
+
RemovedRecordsReducer,
|
|
1817
|
+
AddedRecordsReducer,
|
|
1818
|
+
SelectionReducer,
|
|
1819
|
+
ChangesReducer,
|
|
1820
|
+
WaitingChangesReducer,
|
|
1821
|
+
CurrentRecordsReducer
|
|
1822
|
+
]);
|
|
1823
|
+
this._observers = [];
|
|
1824
|
+
this._filterProviders = new Map();
|
|
1825
|
+
this._sortingProvider = undefined;
|
|
1826
|
+
this._interceptors = [];
|
|
1827
|
+
}
|
|
1828
|
+
get name() {
|
|
1829
|
+
return this._name;
|
|
1830
|
+
}
|
|
1831
|
+
// Métodos privados
|
|
1832
|
+
validateAndTypeValue(fieldName, newValue) {
|
|
1833
|
+
const descriptor = this.getField(fieldName);
|
|
1834
|
+
return descriptor ? convertType(descriptor.dataType, newValue) : newValue;
|
|
1835
|
+
}
|
|
1836
|
+
getFilters() {
|
|
1837
|
+
let filters = undefined;
|
|
1838
|
+
this._filterProviders.forEach(p => {
|
|
1839
|
+
const f = p.getFilter(this.name);
|
|
1840
|
+
if (f) {
|
|
1841
|
+
filters = (filters || []).concat(f);
|
|
1842
|
+
}
|
|
1843
|
+
});
|
|
1844
|
+
return filters;
|
|
1845
|
+
}
|
|
1846
|
+
getSort() {
|
|
1847
|
+
return this._sortingProvider ? this._sortingProvider.getSort(this._name) : undefined;
|
|
1848
|
+
}
|
|
1849
|
+
getFielterProviderKey(provider) {
|
|
1850
|
+
if (provider.getKey) {
|
|
1851
|
+
return provider.getKey();
|
|
1852
|
+
}
|
|
1853
|
+
return StringUtils.hashCode(provider.getFilter.toString());
|
|
1854
|
+
}
|
|
1855
|
+
executeLoadData(request, executionCtx) {
|
|
1856
|
+
return new Promise((resolve, fail) => __awaiter(this, void 0, void 0, function* () {
|
|
1857
|
+
if (yield this.dispatchAction(exports.Action.LOADING_DATA, request, executionCtx)) {
|
|
1858
|
+
if (this.dataLoader) {
|
|
1859
|
+
this.dataLoader(this, request).then(response => {
|
|
1860
|
+
this.dispatchAction(exports.Action.DATA_LOADED, response, executionCtx);
|
|
1861
|
+
resolve(response);
|
|
1862
|
+
}).catch(error => {
|
|
1863
|
+
const { errorCode } = error;
|
|
1864
|
+
fail(new ErrorException("Problema carregando registros", error, errorCode));
|
|
1865
|
+
});
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
}));
|
|
1869
|
+
}
|
|
1870
|
+
// Loaders
|
|
1871
|
+
loadMetadata(executionCtx) {
|
|
1872
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1873
|
+
if (yield this.dispatchAction(exports.Action.LOADING_METADATA, undefined, executionCtx)) {
|
|
1874
|
+
return new Promise((resolve, fail) => {
|
|
1875
|
+
if (this.metadataLoader) {
|
|
1876
|
+
this.metadataLoader(this).then(metadata => {
|
|
1877
|
+
this.metadata = metadata;
|
|
1878
|
+
resolve(this.metadata);
|
|
1879
|
+
}).catch(error => {
|
|
1880
|
+
const { errorCode } = error;
|
|
1881
|
+
fail(new ErrorException("Problema carregando metadados", error, errorCode));
|
|
1882
|
+
});
|
|
1883
|
+
}
|
|
1884
|
+
});
|
|
1885
|
+
}
|
|
1886
|
+
});
|
|
1887
|
+
}
|
|
1888
|
+
loadData(quickFilter, executionCtx) {
|
|
1889
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1890
|
+
const loadDataRequest = {
|
|
1891
|
+
quickFilter,
|
|
1892
|
+
filters: this.getFilters(),
|
|
1893
|
+
sort: this.getSort()
|
|
1894
|
+
};
|
|
1895
|
+
if (this._pageSize > 0) {
|
|
1896
|
+
loadDataRequest.limit = this._pageSize;
|
|
1897
|
+
loadDataRequest.offset = 0;
|
|
1898
|
+
}
|
|
1899
|
+
return this.executeLoadData(loadDataRequest, executionCtx);
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
gotoPage(page, executionCtx) {
|
|
1903
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1904
|
+
let request = getCurrentRequest(this._stateManager);
|
|
1905
|
+
if (!request) {
|
|
1906
|
+
request = {
|
|
1907
|
+
filters: this.getFilters(),
|
|
1908
|
+
sort: this.getSort()
|
|
1909
|
+
};
|
|
1910
|
+
}
|
|
1911
|
+
if (page >= 0 && page <= getLastPage(this._stateManager, this._pageSize)) {
|
|
1912
|
+
return this.executeLoadData(Object.assign(Object.assign({}, request), { limit: this._pageSize, offset: page * this._pageSize }), executionCtx);
|
|
1913
|
+
}
|
|
1914
|
+
});
|
|
1915
|
+
}
|
|
1916
|
+
nextPage(executionCtx) {
|
|
1917
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1918
|
+
return this.gotoPage(getCurrentPage(this._stateManager) + 1, executionCtx);
|
|
1919
|
+
});
|
|
1920
|
+
}
|
|
1921
|
+
previousPage(executionCtx) {
|
|
1922
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1923
|
+
return this.gotoPage(getCurrentPage(this._stateManager) - 1, executionCtx);
|
|
1924
|
+
});
|
|
1925
|
+
}
|
|
1926
|
+
saveData(executionCtx) {
|
|
1927
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1928
|
+
const blockingWaitingChanges = getBlockingWaitingChanges(this._stateManager);
|
|
1929
|
+
if (blockingWaitingChanges && blockingWaitingChanges.size > 0) {
|
|
1930
|
+
const [field, waitingChange] = blockingWaitingChanges.entries().next().value;
|
|
1931
|
+
return Promise.reject(new WaitingChangeException("Aguardando alteração de campo", waitingChange.waitmessage));
|
|
1932
|
+
}
|
|
1933
|
+
else {
|
|
1934
|
+
if (isDirty(this._stateManager)) {
|
|
1935
|
+
if (yield this.dispatchAction(exports.Action.SAVING_DATA, undefined, executionCtx)) {
|
|
1936
|
+
const promisses = getWaitingChangePromisses(this._stateManager);
|
|
1937
|
+
return new Promise((resolve, fail) => {
|
|
1938
|
+
Promise.all(promisses || []).then(() => {
|
|
1939
|
+
if (this.saveLoader) {
|
|
1940
|
+
const changes = getChangesToSave(this._name, this._stateManager);
|
|
1941
|
+
this.saveLoader(this, changes).then(records => {
|
|
1942
|
+
this.dispatchAction(exports.Action.DATA_SAVED, { changes, records }, executionCtx);
|
|
1943
|
+
resolve();
|
|
1944
|
+
}).catch(cause => {
|
|
1945
|
+
const { errorCode } = cause;
|
|
1946
|
+
fail(new ErrorException("Erro salvando alterações", cause, errorCode));
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1949
|
+
else {
|
|
1950
|
+
resolve();
|
|
1951
|
+
}
|
|
1952
|
+
});
|
|
1953
|
+
});
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
return Promise.resolve();
|
|
1958
|
+
});
|
|
1959
|
+
}
|
|
1960
|
+
removeSelectedRecords(buffered = false) {
|
|
1961
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1962
|
+
const selection = getSelection(this._stateManager);
|
|
1963
|
+
if (selection) {
|
|
1964
|
+
const records = this.getSelectedRecords() || [];
|
|
1965
|
+
return this.removeRecords(selection, records, buffered);
|
|
1966
|
+
}
|
|
1967
|
+
return Promise.resolve(selection);
|
|
1968
|
+
});
|
|
1969
|
+
}
|
|
1970
|
+
removeRecords(recordIds, cachedRecords, buffered = false, executionCtx) {
|
|
1971
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1972
|
+
if (recordIds) {
|
|
1973
|
+
if (buffered || !this.removeLoader) {
|
|
1974
|
+
this.dispatchAction(exports.Action.RECORDS_REMOVED, { records: recordIds, cachedRecords, buffered: true }, executionCtx);
|
|
1975
|
+
}
|
|
1976
|
+
else {
|
|
1977
|
+
if (yield this.dispatchAction(exports.Action.REMOVING_RECORDS, undefined, executionCtx)) {
|
|
1978
|
+
return new Promise((resolve, fail) => {
|
|
1979
|
+
if (this.removeLoader) {
|
|
1980
|
+
this.removeLoader(this, recordIds).then(removedIds => {
|
|
1981
|
+
let currentIndex = 0;
|
|
1982
|
+
const removedIndex = [];
|
|
1983
|
+
const currentRecords = getCurrentRecords(this._stateManager);
|
|
1984
|
+
currentRecords.forEach((value, key) => {
|
|
1985
|
+
if (removedIds.includes(key)) {
|
|
1986
|
+
removedIndex.push(currentIndex);
|
|
1987
|
+
}
|
|
1988
|
+
currentIndex++;
|
|
1989
|
+
});
|
|
1990
|
+
this.dispatchAction(exports.Action.RECORDS_REMOVED, { records: removedIds, cachedRecords, removedIndex, buffered: false }, executionCtx);
|
|
1991
|
+
resolve(removedIds);
|
|
1992
|
+
}).catch(error => {
|
|
1993
|
+
const { errorCode } = error;
|
|
1994
|
+
fail(new ErrorException("Problema removendo registros", error, errorCode));
|
|
1995
|
+
});
|
|
1996
|
+
}
|
|
1997
|
+
});
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
return Promise.resolve(recordIds);
|
|
2002
|
+
});
|
|
2003
|
+
}
|
|
2004
|
+
// API
|
|
2005
|
+
valueFromString(fieldName, value) {
|
|
2006
|
+
const descriptor = this.getField(fieldName);
|
|
2007
|
+
return descriptor ? convertType(descriptor.dataType, value) : value;
|
|
2008
|
+
}
|
|
2009
|
+
valueToString(fieldName, value) {
|
|
2010
|
+
const descriptor = this.getField(fieldName);
|
|
2011
|
+
return toString(descriptor === null || descriptor === void 0 ? void 0 : descriptor.dataType, value);
|
|
2012
|
+
}
|
|
2013
|
+
addInterceptor(interceptor) {
|
|
2014
|
+
this._interceptors.push(interceptor);
|
|
2015
|
+
}
|
|
2016
|
+
removeInterceptor(interceptor) {
|
|
2017
|
+
this._interceptors = this._interceptors.filter(i => i !== interceptor);
|
|
2018
|
+
}
|
|
2019
|
+
addFilterProvider(provider) {
|
|
2020
|
+
this._filterProviders.set(this.getFielterProviderKey(provider), provider);
|
|
2021
|
+
}
|
|
2022
|
+
getPaginationInfo() {
|
|
2023
|
+
return getPaginationInfo(this._stateManager);
|
|
2024
|
+
}
|
|
2025
|
+
set sortingProvider(provider) {
|
|
2026
|
+
this._sortingProvider = provider;
|
|
2027
|
+
}
|
|
2028
|
+
set metadata(md) {
|
|
2029
|
+
this.dispatchAction(exports.Action.METADATA_LOADED, md, undefined);
|
|
2030
|
+
}
|
|
2031
|
+
get metadata() {
|
|
2032
|
+
return getMetadata(this._stateManager);
|
|
2033
|
+
}
|
|
2034
|
+
set records(r) {
|
|
2035
|
+
this.dispatchAction(exports.Action.DATA_LOADED, { records: this.records }, undefined);
|
|
2036
|
+
}
|
|
2037
|
+
get records() {
|
|
2038
|
+
const records = getCurrentRecords(this._stateManager);
|
|
2039
|
+
return records ? Array.from(records.values()) : [];
|
|
2040
|
+
}
|
|
2041
|
+
set pageSize(size) {
|
|
2042
|
+
this._pageSize = size;
|
|
2043
|
+
}
|
|
2044
|
+
get pageSize() {
|
|
2045
|
+
return this._pageSize;
|
|
2046
|
+
}
|
|
2047
|
+
getModifiedRecords() {
|
|
2048
|
+
const modified = getModifiedRecords(this._stateManager);
|
|
2049
|
+
return modified || [];
|
|
2050
|
+
}
|
|
2051
|
+
getField(fieldName) {
|
|
2052
|
+
return getField(this._stateManager, fieldName);
|
|
2053
|
+
}
|
|
2054
|
+
addRecord(executionCtx) {
|
|
2055
|
+
this.dispatchAction(exports.Action.RECORDS_ADDED, prepareAddedRecordId(this._stateManager, [{}]), executionCtx);
|
|
2056
|
+
}
|
|
2057
|
+
copySelected(executionCtx) {
|
|
2058
|
+
const selectedRecords = this.getSelectedRecords();
|
|
2059
|
+
if (selectedRecords) {
|
|
2060
|
+
this.dispatchAction(exports.Action.RECORDS_COPIED, prepareCopiedRecord(this._stateManager, selectedRecords), executionCtx);
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
waitingForChange(fieldName) {
|
|
2064
|
+
return isWaiting(this._stateManager, fieldName);
|
|
2065
|
+
}
|
|
2066
|
+
getFieldValue(fieldName) {
|
|
2067
|
+
return getFieldValue(this._stateManager, fieldName);
|
|
2068
|
+
}
|
|
2069
|
+
setFieldValue(fieldName, newValue, records) {
|
|
2070
|
+
const typedValue = this.validateAndTypeValue(fieldName, newValue);
|
|
2071
|
+
const currentValue = this.getFieldValue(fieldName);
|
|
2072
|
+
if (currentValue !== typedValue) {
|
|
2073
|
+
this.dispatchAction(exports.Action.DATA_CHANGED, { [fieldName]: typedValue, records }, undefined);
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
startChange(fieldName, waitingChange) {
|
|
2077
|
+
this.dispatchAction(exports.Action.CHANGING_DATA, { [fieldName]: waitingChange }, undefined);
|
|
2078
|
+
}
|
|
2079
|
+
cancelWaitingChange(fieldName) {
|
|
2080
|
+
this.dispatchAction(exports.Action.WAITING_CHANGE_CANCELED, { fieldName }, undefined);
|
|
2081
|
+
}
|
|
2082
|
+
getSelection() {
|
|
2083
|
+
return getSelection(this._stateManager);
|
|
2084
|
+
}
|
|
2085
|
+
setSelection(selection, executionCtx) {
|
|
2086
|
+
this.dispatchAction(exports.Action.SELECTION_CHANGED, { type: "id", selection }, executionCtx);
|
|
2087
|
+
}
|
|
2088
|
+
selectFirst(executionCtx) {
|
|
2089
|
+
if (this.records.length > 0) {
|
|
2090
|
+
this.setSelectionByIndex([0], executionCtx);
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
selectLast(executionCtx) {
|
|
2094
|
+
if (this.records.length > 0) {
|
|
2095
|
+
this.setSelectionByIndex([this.records.length - 1], executionCtx);
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
setSelectionByIndex(selection, executionCtx) {
|
|
2099
|
+
this.dispatchAction(exports.Action.SELECTION_CHANGED, { type: "index", selection }, executionCtx);
|
|
2100
|
+
}
|
|
2101
|
+
getSelectedRecords() {
|
|
2102
|
+
const selection = this.getSelection();
|
|
2103
|
+
if (selection) {
|
|
2104
|
+
const currentRecords = this.records;
|
|
2105
|
+
return currentRecords === null || currentRecords === void 0 ? void 0 : currentRecords.filter(r => selection.includes(r.__record__id__));
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
nextRecord(executionCtx) {
|
|
2109
|
+
if (!hasNext(this._stateManager)) {
|
|
2110
|
+
if (hasMorePages(this._stateManager)) {
|
|
2111
|
+
this.nextPage({
|
|
2112
|
+
before: act => {
|
|
2113
|
+
if (executionCtx && executionCtx.before) {
|
|
2114
|
+
act = executionCtx.before(act);
|
|
2115
|
+
}
|
|
2116
|
+
return act;
|
|
2117
|
+
},
|
|
2118
|
+
after: act => {
|
|
2119
|
+
this.selectFirst(executionCtx);
|
|
2120
|
+
}
|
|
2121
|
+
});
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
else {
|
|
2125
|
+
this.dispatchAction(exports.Action.NEXT_SELECTED, undefined, executionCtx);
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
previousRecord(executionCtx) {
|
|
2129
|
+
if (!hasPrevious(this._stateManager)) {
|
|
2130
|
+
if (hasPreviousPages(this._stateManager)) {
|
|
2131
|
+
this.previousPage({
|
|
2132
|
+
before: act => {
|
|
2133
|
+
if (executionCtx && executionCtx.before) {
|
|
2134
|
+
act = executionCtx.before(act);
|
|
2135
|
+
}
|
|
2136
|
+
return act;
|
|
2137
|
+
},
|
|
2138
|
+
after: act => {
|
|
2139
|
+
this.selectLast(executionCtx);
|
|
2140
|
+
}
|
|
2141
|
+
});
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
else {
|
|
2145
|
+
this.dispatchAction(exports.Action.PREVIOUS_SELECTED, undefined, executionCtx);
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
cancelEdition(executionCtx) {
|
|
2149
|
+
this.dispatchAction(exports.Action.EDITION_CANCELED, undefined, executionCtx);
|
|
2150
|
+
}
|
|
2151
|
+
isDirty() {
|
|
2152
|
+
return isDirty(this._stateManager);
|
|
2153
|
+
}
|
|
2154
|
+
hasDirtyRecords() {
|
|
2155
|
+
return hasDirtyRecords(this._stateManager);
|
|
2156
|
+
}
|
|
2157
|
+
hasNext() {
|
|
2158
|
+
let result = hasNext(this._stateManager);
|
|
2159
|
+
if (!result) {
|
|
2160
|
+
result = hasMorePages(this._stateManager);
|
|
2161
|
+
}
|
|
2162
|
+
return result;
|
|
2163
|
+
}
|
|
2164
|
+
hasPrevious() {
|
|
2165
|
+
let result = hasPrevious(this._stateManager);
|
|
2166
|
+
if (!result) {
|
|
2167
|
+
result = hasPreviousPages(this._stateManager);
|
|
2168
|
+
}
|
|
2169
|
+
return result;
|
|
2170
|
+
}
|
|
2171
|
+
canUndo() {
|
|
2172
|
+
return canUndo(this._stateManager);
|
|
2173
|
+
}
|
|
2174
|
+
canRedo() {
|
|
2175
|
+
return canRedo(this._stateManager);
|
|
2176
|
+
}
|
|
2177
|
+
undo(executionCtx) {
|
|
2178
|
+
this.dispatchAction(exports.Action.CHANGE_UNDONE, undefined, executionCtx);
|
|
2179
|
+
}
|
|
2180
|
+
redo(executionCtx) {
|
|
2181
|
+
this.dispatchAction(exports.Action.CHANGE_REDONE, undefined, executionCtx);
|
|
2182
|
+
}
|
|
2183
|
+
toString() {
|
|
2184
|
+
return this.name;
|
|
2185
|
+
}
|
|
2186
|
+
// Actions / State manager
|
|
2187
|
+
dispatchAction(actionType, payload, executionCtx) {
|
|
2188
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2189
|
+
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
|
|
2190
|
+
let action = new DataUnitAction(actionType, payload);
|
|
2191
|
+
if (executionCtx && executionCtx.before) {
|
|
2192
|
+
action = executionCtx.before(action);
|
|
2193
|
+
}
|
|
2194
|
+
if (action && this._interceptors && this._interceptors.length > 0) {
|
|
2195
|
+
action = yield this.intercept(action, this._interceptors.values());
|
|
2196
|
+
}
|
|
2197
|
+
if (action) {
|
|
2198
|
+
this.doDispatchAction(action);
|
|
2199
|
+
if (executionCtx && executionCtx.after) {
|
|
2200
|
+
executionCtx.after(action);
|
|
2201
|
+
}
|
|
2202
|
+
resolve(true);
|
|
2203
|
+
}
|
|
2204
|
+
else {
|
|
2205
|
+
resolve(false);
|
|
2206
|
+
}
|
|
2207
|
+
}));
|
|
2208
|
+
});
|
|
2209
|
+
}
|
|
2210
|
+
intercept(action, interceptors) {
|
|
2211
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2212
|
+
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
|
|
2213
|
+
let ite;
|
|
2214
|
+
while (action && !(ite = interceptors.next()).done) {
|
|
2215
|
+
action = yield ite.value.interceptAction(action);
|
|
2216
|
+
}
|
|
2217
|
+
resolve(action);
|
|
2218
|
+
}));
|
|
2219
|
+
});
|
|
2220
|
+
}
|
|
2221
|
+
doDispatchAction(action) {
|
|
2222
|
+
this._stateManager.process(action);
|
|
2223
|
+
this._observers.forEach(f => {
|
|
2224
|
+
/*
|
|
2225
|
+
if some observer throws exceptions,
|
|
2226
|
+
should be continued
|
|
2227
|
+
*/
|
|
2228
|
+
try {
|
|
2229
|
+
f(action);
|
|
2230
|
+
}
|
|
2231
|
+
catch (e) {
|
|
2232
|
+
console.warn("[DataUnit] error while call observer", e);
|
|
2233
|
+
}
|
|
2234
|
+
});
|
|
2235
|
+
}
|
|
2236
|
+
subscribe(observer) {
|
|
2237
|
+
this._observers.push(observer);
|
|
2238
|
+
}
|
|
2239
|
+
unsubscribe(observer) {
|
|
2240
|
+
this._observers = this._observers.filter(f => f !== observer);
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
exports.ChangeOperation = void 0;
|
|
2244
|
+
(function (ChangeOperation) {
|
|
2245
|
+
ChangeOperation["INSERT"] = "INSERT";
|
|
2246
|
+
ChangeOperation["COPY"] = "COPY";
|
|
2247
|
+
ChangeOperation["UPDATE"] = "UPDATE";
|
|
2248
|
+
ChangeOperation["DELETE"] = "DELETE";
|
|
2249
|
+
})(exports.ChangeOperation || (exports.ChangeOperation = {}));
|
|
2250
|
+
class Change {
|
|
2251
|
+
constructor(dataUnit, record, updates, operation, sourceId) {
|
|
2252
|
+
this.dataUnit = dataUnit;
|
|
2253
|
+
this.record = record;
|
|
2254
|
+
this.sourceId = sourceId;
|
|
2255
|
+
this.updatingFields = updates;
|
|
2256
|
+
this._operation = operation;
|
|
2257
|
+
}
|
|
2258
|
+
get operation() {
|
|
2259
|
+
return this._operation.toString();
|
|
2260
|
+
}
|
|
2261
|
+
isInsert() {
|
|
2262
|
+
return this._operation === exports.ChangeOperation.INSERT;
|
|
2263
|
+
}
|
|
2264
|
+
isCopy() {
|
|
2265
|
+
return this._operation === exports.ChangeOperation.COPY;
|
|
2266
|
+
}
|
|
2267
|
+
isDelete() {
|
|
2268
|
+
return this._operation === exports.ChangeOperation.DELETE;
|
|
2269
|
+
}
|
|
2270
|
+
isUpdate() {
|
|
2271
|
+
return this._operation === exports.ChangeOperation.UPDATE;
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
|
|
2275
|
+
var SortMode;
|
|
2276
|
+
(function (SortMode) {
|
|
2277
|
+
SortMode["ASC"] = "ASC";
|
|
2278
|
+
SortMode["DESC"] = "DESC";
|
|
2279
|
+
})(SortMode || (SortMode = {}));
|
|
2280
|
+
exports.DependencyType = void 0;
|
|
2281
|
+
(function (DependencyType) {
|
|
2282
|
+
DependencyType["SEARCHING"] = "SEARCHING";
|
|
2283
|
+
DependencyType["REQUIREMENT"] = "REQUIREMENT";
|
|
2284
|
+
DependencyType["VISIBILITY"] = "REQUIREMENT";
|
|
2285
|
+
})(exports.DependencyType || (exports.DependencyType = {}));
|
|
2286
|
+
exports.UserInterface = void 0;
|
|
2287
|
+
(function (UserInterface) {
|
|
2288
|
+
UserInterface["FILE"] = "FILE";
|
|
2289
|
+
UserInterface["IMAGE"] = "IMAGE";
|
|
2290
|
+
UserInterface["DATE"] = "DATE";
|
|
2291
|
+
UserInterface["DATETIME"] = "DATETIME";
|
|
2292
|
+
UserInterface["TIME"] = "TIME";
|
|
2293
|
+
UserInterface["ELAPSEDTIME"] = "ELAPSEDTIME";
|
|
2294
|
+
UserInterface["CHECKBOX"] = "CHECKBOX";
|
|
2295
|
+
UserInterface["SWITCH"] = "SWITCH";
|
|
2296
|
+
UserInterface["OPTIONSELECTOR"] = "OPTIONSELECTOR";
|
|
2297
|
+
UserInterface["DECIMALNUMBER"] = "DECIMALNUMBER";
|
|
2298
|
+
UserInterface["INTEGERNUMBER"] = "INTEGERNUMBER";
|
|
2299
|
+
UserInterface["SEARCH"] = "SEARCH";
|
|
2300
|
+
UserInterface["SHORTTEXT"] = "SHORTTEXT";
|
|
2301
|
+
UserInterface["PASSWORD"] = "PASSWORD";
|
|
2302
|
+
UserInterface["MASKEDTEXT"] = "MASKEDTEXT";
|
|
2303
|
+
UserInterface["LONGTEXT"] = "LONGTEXT";
|
|
2304
|
+
UserInterface["HTML"] = "HTML";
|
|
2305
|
+
})(exports.UserInterface || (exports.UserInterface = {}));
|
|
2306
|
+
|
|
2307
|
+
class ApplicationContext {
|
|
2308
|
+
static getContextValue(key) {
|
|
2309
|
+
return ApplicationContext.getCtx()[key];
|
|
2310
|
+
}
|
|
2311
|
+
static setContextValue(key, value) {
|
|
2312
|
+
ApplicationContext.getCtx()[key] = value;
|
|
2313
|
+
}
|
|
2314
|
+
static getCtx() {
|
|
2315
|
+
let ctx = window.___snkcore___ctx___;
|
|
2316
|
+
if (!ctx) {
|
|
2317
|
+
ctx = {};
|
|
2318
|
+
window.___snkcore___ctx___ = ctx;
|
|
2319
|
+
}
|
|
2320
|
+
return ctx;
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
|
|
2324
|
+
class ReadyUtil {
|
|
2325
|
+
clean() {
|
|
2326
|
+
this.resolve = undefined;
|
|
2327
|
+
this.promise = undefined;
|
|
2328
|
+
}
|
|
2329
|
+
start() {
|
|
2330
|
+
if (!this.promise)
|
|
2331
|
+
this.promise = new Promise((accept) => {
|
|
2332
|
+
this.resolve = () => accept(true);
|
|
2333
|
+
});
|
|
2334
|
+
}
|
|
2335
|
+
end() {
|
|
2336
|
+
this.resolve && this.resolve();
|
|
2337
|
+
}
|
|
2338
|
+
whenReady() {
|
|
2339
|
+
this.start();
|
|
2340
|
+
return new Promise((accept) => {
|
|
2341
|
+
this.promise.then(() => {
|
|
2342
|
+
accept(true);
|
|
2343
|
+
this.clean();
|
|
2344
|
+
});
|
|
2345
|
+
});
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
class ObjectUtils {
|
|
2350
|
+
static copy(data) {
|
|
2351
|
+
return this.stringToObject(this.objectToString(data));
|
|
2352
|
+
}
|
|
2353
|
+
static objectToString(data) {
|
|
2354
|
+
return JSON.stringify(data);
|
|
2355
|
+
}
|
|
2356
|
+
static stringToObject(data) {
|
|
2357
|
+
return JSON.parse(data);
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
|
|
2361
|
+
class WarningException extends Error {
|
|
2362
|
+
constructor(title, message, errorCode = "") {
|
|
2363
|
+
super(message);
|
|
2364
|
+
this.title = title;
|
|
2365
|
+
this.message = message;
|
|
2366
|
+
this.errorCode = errorCode;
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
|
|
2370
|
+
class ErrorTracking {
|
|
2371
|
+
static init() {
|
|
2372
|
+
const rollbar = window.Rollbar;
|
|
2373
|
+
if (rollbar) {
|
|
2374
|
+
rollbar.configure({
|
|
2375
|
+
checkIgnore: function (isUncaught, args, payload) {
|
|
2376
|
+
return args[1] ? ErrorTracking.isInternalException(args[1]) : false;
|
|
2377
|
+
}
|
|
2378
|
+
});
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
static isInternalException(error) {
|
|
2382
|
+
return (error instanceof ErrorException || error instanceof WaitingChangeException || error instanceof WarningException);
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
exports.ApplicationContext = ApplicationContext;
|
|
2387
|
+
exports.ArrayUtils = ArrayUtils;
|
|
2388
|
+
exports.DataUnit = DataUnit;
|
|
2389
|
+
exports.DateUtils = DateUtils;
|
|
2390
|
+
exports.ErrorException = ErrorException;
|
|
2391
|
+
exports.ErrorTracking = ErrorTracking;
|
|
2392
|
+
exports.FloatingManager = FloatingManager;
|
|
2393
|
+
exports.ObjectUtils = ObjectUtils;
|
|
2394
|
+
exports.StringUtils = StringUtils;
|
|
2395
|
+
exports.WaitingChangeException = WaitingChangeException;
|
|
2396
|
+
exports.WarningException = WarningException;
|
|
2397
|
+
exports.toString = toString;
|