@jtandrelevicius/utils-js-library 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +414 -182
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,58 +1,102 @@
1
- /**
2
- * DataQueryService (Antigo JSK)
3
- * Responsável pela execução e processamento de consultas assíncronas.
4
- */
5
- class DataQueryService {
1
+ 'use strict';
2
+
3
+ class ServicoDados {
4
+
6
5
  /**
7
- * Define o executor de query padrão para a classe.
8
- * Isso remove a dependência de uma função global.
9
- * @param {Function} executorFunction Função que aceita (query, params, onSuccess, onError).
6
+ * Define o executor de query padrão para a classe (Legado).
7
+ * @param {Function} funcaoExecutor Função que aceita (query, params, onSuccess, onError).
10
8
  */
11
- static setExecutor(executorFunction) {
12
- this.executor = executorFunction;
9
+ static definirExecutor(funcaoExecutor) {
10
+ this.executor = funcaoExecutor;
11
+ }
12
+
13
+ /**
14
+ * Realiza requisições do tipo POST (Base para salvar/excluir).
15
+ * @param {string} url URL da requisição.
16
+ * @param {Object} corpo Corpo da requisição.
17
+ * @param {Object} opcoes Opções adicionais (headers, raw).
18
+ * @returns {Promise<Object>} Resposta da requisição.
19
+ */
20
+ static async post(url, corpo, { headers, raw } = { headers: {}, raw: false }) {
21
+ let isJSON = true;
22
+
23
+ if (headers) {
24
+ const cabecalhoTipoOriginal = headers['Content-Type'] ? String(headers['Content-Type']) : 'application/json; charset=UTF-8';
25
+ isJSON = headers['Content-Type'] ? RegExp(/json/i).exec(headers['Content-Type']) : isJSON;
26
+
27
+ if (headers['Content-Type']) delete headers['Content-Type'];
28
+ headers['Content-Type'] = cabecalhoTipoOriginal;
29
+ }
30
+
31
+ try {
32
+ let corpoRequisicaoFormatado = corpo;
33
+
34
+ if (corpo && typeof corpo === 'object') {
35
+ corpoRequisicaoFormatado = JSON.stringify(corpo);
36
+ }
37
+
38
+ if (typeof window === 'undefined' || !window.fetch) {
39
+ throw new Error("O método 'post' requer um ambiente de navegador com 'fetch' disponível.");
40
+ }
41
+
42
+ const resposta = await window.fetch.bind(window)(url, {
43
+ headers,
44
+ method: 'POST',
45
+ redirect: 'follow',
46
+ credentials: 'include',
47
+ body: corpoRequisicaoFormatado
48
+ });
49
+
50
+ if (raw) {
51
+ return resposta;
52
+ }
53
+
54
+ return isJSON ? resposta.json() : resposta.text();
55
+
56
+ } catch (erro) {
57
+ console.error("[ServicoDados] Erro no POST:", erro);
58
+ throw erro;
59
+ }
13
60
  }
14
61
 
15
62
  /**
63
+ * Normaliza a resposta da API (Método auxiliar).
16
64
  * @private
17
- * Normaliza a resposta da API, lidando com estruturas aninhadas legadas/específicas.
18
- * @param {unknown} rawValue O valor bruto retornado pela query.
19
- * @returns {Array<Object>} O array de dados normalizado.
20
65
  */
21
- static normalizeResponse(rawValue) {
66
+ static normalizarResposta(valorBruto) {
22
67
  try {
23
- const parsedValue = typeof rawValue === 'string' ? JSON.parse(rawValue) : rawValue;
68
+ const valorParseado = typeof valorBruto === 'string' ? JSON.parse(valorBruto) : valorBruto;
24
69
 
25
- if (!parsedValue) return [];
26
- if (Array.isArray(parsedValue)) return parsedValue;
70
+ if (!valorParseado) return [];
71
+ if (Array.isArray(valorParseado)) return valorParseado;
27
72
 
28
- let finalData = null;
73
+ let dadosFinais = null;
29
74
 
30
- if (typeof parsedValue === 'object') {
31
- if (typeof parsedValue.b === 'string') {
32
- finalData = JSON.parse(parsedValue.b);
33
- } else if (parsedValue.c?.b && typeof parsedValue.c.b === 'string') {
34
- finalData = JSON.parse(parsedValue.c.b);
35
- } else if (parsedValue.data?.responseBody || parsedValue.responseBody) {
36
- const body = parsedValue.data?.responseBody || parsedValue.responseBody;
37
- finalData = typeof body === 'string' ? JSON.parse(body) : body;
75
+ if (typeof valorParseado === 'object') {
76
+ if (typeof valorParseado.b === 'string') {
77
+ dadosFinais = JSON.parse(valorParseado.b);
78
+ } else if (valorParseado.c?.b && typeof valorParseado.c.b === 'string') {
79
+ dadosFinais = JSON.parse(valorParseado.c.b);
80
+ } else if (valorParseado.data?.responseBody || valorParseado.responseBody) {
81
+ const corpo = valorParseado.data?.responseBody || valorParseado.responseBody;
82
+ dadosFinais = typeof corpo === 'string' ? JSON.parse(corpo) : corpo;
38
83
  }
39
84
  }
40
85
 
41
- if (Array.isArray(finalData)) return finalData;
42
-
86
+ if (Array.isArray(dadosFinais)) return dadosFinais;
43
87
  throw new Error("Formato de resposta desconhecido ou inválido.");
44
- } catch (error) {
45
- throw new Error(`Falha ao normalizar resposta da query: ${error.message}`);
88
+ } catch (erro) {
89
+ throw new Error(`Falha ao normalizar resposta da query: ${erro.message}`);
46
90
  }
47
91
  }
48
92
 
49
93
  /**
50
- * Executa uma consulta de dados.
51
- * @param {string} query A string da consulta (SQL/HQL/etc).
52
- * @param {Object} [params=null] Parâmetros opcionais para a query.
94
+ * Executa uma consulta de dados (Via executor configurado ou executeQuery global).
95
+ * @param {string} query A string da consulta.
96
+ * @param {Object} [params=null] Parâmetros opcionais.
53
97
  * @returns {Promise<Array<Object>>} Promise resolvendo com os dados.
54
98
  */
55
- static async fetch(query, params = null) {
99
+ static async consultar(query, params = null) {
56
100
  const executor = this.executor || (typeof window !== 'undefined' ? window.executeQuery : null);
57
101
 
58
102
  if (typeof executor !== 'function') {
@@ -61,10 +105,10 @@ class DataQueryService {
61
105
 
62
106
  return new Promise((resolve, reject) => {
63
107
  executor(query, params,
64
- (rawValue) => {
108
+ (valorBruto) => {
65
109
  try {
66
- const data = DataQueryService.normalizeResponse(rawValue);
67
- resolve(data || []);
110
+ const dados = ServicoDados.normalizarResposta(valorBruto);
111
+ resolve(dados || []);
68
112
  } catch (err) {
69
113
  reject(err);
70
114
  }
@@ -76,154 +120,189 @@ class DataQueryService {
76
120
 
77
121
  /**
78
122
  * Executa uma consulta paginada.
79
- * @param {string} query A query base.
80
- * @param {Object} params Parâmetros da query.
81
- * @param {number} limit Registros por página.
82
- * @param {number} offset Ponto de início (pular x registros).
83
- * @returns {Promise<Object>} Objeto contendo dados e metadados de paginação.
84
123
  */
85
- static async fetchPaginated(query, params = null, limit, offset) {
86
- const safeLimit = Number(limit);
87
- const safeOffset = Number(offset);
124
+ static async consultarPaginado(query, params = null, limite, offset) {
125
+ const limiteSeguro = Number(limite);
126
+ const offsetSeguro = Number(offset);
88
127
 
89
- if (isNaN(safeLimit) || isNaN(safeOffset) || safeLimit < 0 || safeOffset < 0) {
90
- throw new Error("Parâmetros 'limit' e 'offset' devem ser números positivos válidos.");
128
+ if (isNaN(limiteSeguro) || isNaN(offsetSeguro) || limiteSeguro < 0 || offsetSeguro < 0) {
129
+ throw new Error("Parâmetros 'limite' e 'offset' devem ser números positivos válidos.");
91
130
  }
92
131
 
93
- const paginatedQuery = `${query} LIMIT ${safeLimit} OFFSET ${safeOffset}`;
94
-
95
- const data = await DataQueryService.fetch(paginatedQuery, params);
96
-
97
- const currentPage = Math.floor(safeOffset / safeLimit) + 1;
132
+ const queryPaginada = `${query} LIMIT ${limiteSeguro} OFFSET ${offsetSeguro}`;
133
+ const dados = await ServicoDados.consultar(queryPaginada, params);
134
+ const paginaAtual = Math.floor(offsetSeguro / limiteSeguro) + 1;
98
135
 
99
136
  return {
100
- data,
101
- meta: {
102
- currentPage,
103
- itemsPerPage: safeLimit,
104
- totalItems: null,
105
- totalPages: null
106
- }
137
+ dados,
138
+ meta: { paginaAtual, itensPorPagina: limiteSeguro, totalItens: null, totalPaginas: null }
107
139
  };
108
140
  }
109
- }
110
141
 
111
- /**
112
- * FormatUtils
113
- * Utilitários para formatação de moeda, números e datas (Locale pt-BR).
114
- */
115
- class FormatUtils {
116
142
  /**
117
- * Formata valor para moeda BRL (R$).
143
+ * Salva (Insert) ou Atualiza (Update) um registro usando DatasetSP.
144
+ * * Lógica Automática:
145
+ * 1. Se 'chavesPrimarias' for informado -> Realiza UPDATE no registro específico.
146
+ * 2. Se 'chavesPrimarias' for NULO/UNDEFINED -> Realiza INSERT de um novo registro.
147
+ * * @param {Object} dados Objeto com os dados a serem gravados { CAMPO: valor }.
148
+ * @param {string} entidade Nome da entidade/tabela (ex: 'Parceiro', 'TGFCAB').
149
+ * @param {Object} [chavesPrimarias=null] Chaves primárias { PK: valor } para edição.
150
+ * @returns {Promise<Object>} Resposta da requisição.
118
151
  */
119
- static currency(value) {
120
- const numberVal = parseFloat(value);
121
- if (isNaN(numberVal)) return "R$ 0,00";
122
-
123
- return new Intl.NumberFormat('pt-BR', {
124
- style: 'currency',
125
- currency: 'BRL'
126
- }).format(numberVal);
152
+ static async salvar(dados, entidade, chavesPrimarias = null) {
153
+ const url = `${window.location.origin}/mge/service.sbr?serviceName=DatasetSP.save&outputType=json`;
154
+
155
+ const chavesDados = Object.keys(dados);
156
+ const fields = chavesDados.map(campo => campo.toUpperCase());
157
+
158
+ const values = {};
159
+ chavesDados.forEach((chave, indice) => {
160
+ values[indice.toString()] = String(dados[chave]);
161
+ });
162
+
163
+ const record = { values: values };
164
+
165
+ if (chavesPrimarias) {
166
+ const pk = {};
167
+ Object.keys(chavesPrimarias).forEach(chave => {
168
+ pk[chave.toUpperCase()] = String(chavesPrimarias[chave]);
169
+ });
170
+ record.pk = pk;
171
+ }
172
+
173
+ const dadosEnvio = {
174
+ serviceName: 'DatasetSP.save',
175
+ requestBody: {
176
+ entityName: entidade,
177
+ fields: fields,
178
+ records: [record]
179
+ }
180
+ };
181
+
182
+ return await ServicoDados.post(url, dadosEnvio);
127
183
  }
128
184
 
129
185
  /**
130
- * Formata número inteiro com separadores de milhar.
186
+ * Exclui registros da base de dados.
187
+ * @param {string} entidade Nome da Entidade.
188
+ * @param {Object|Array} chavesPrimarias Objeto PK { COD: 1 } ou Array de PKs.
189
+ * @returns {Promise<Object>} Resposta da exclusão.
131
190
  */
132
- static number(value) {
133
- const numberVal = parseFloat(value);
134
- if (isNaN(numberVal)) return "0";
191
+ static async excluir(entidade, chavesPrimarias) {
192
+ const url = `${window.location.origin}/mge/service.sbr?serviceName=DatasetSP.removeRecord&outputType=json`;
193
+
194
+ const dadosEnvio = {
195
+ serviceName: 'DatasetSP.removeRecord',
196
+ requestBody: {
197
+ entityName: entidade,
198
+ pks: Array.isArray(chavesPrimarias) ? chavesPrimarias : [chavesPrimarias]
199
+ }
200
+ };
201
+
202
+ return ServicoDados.post(url, dadosEnvio);
203
+ }
204
+ }
135
205
 
136
- return new Intl.NumberFormat('pt-BR', {
137
- maximumFractionDigits: 0
138
- }).format(numberVal);
206
+ /**
207
+ * UtilitariosFormatacao
208
+ */
209
+ class UtilitariosFormatacao {
210
+ static moeda(valor) {
211
+ const valorNumerico = parseFloat(valor);
212
+ if (isNaN(valorNumerico)) return "R$ 0,00";
213
+ return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(valorNumerico);
214
+ }
215
+
216
+ static numerico(valor) {
217
+ const valorNumerico = parseFloat(valor);
218
+ if (isNaN(valorNumerico)) return "0";
219
+ return new Intl.NumberFormat('pt-BR', { maximumFractionDigits: 0 }).format(valorNumerico);
139
220
  }
140
221
 
141
- /**
142
- * Formata número decimal com 2 casas fixas.
143
- */
144
- static decimal(value) {
145
- const numberVal = parseFloat(value);
146
- if (isNaN(numberVal)) return "0,00";
147
-
148
- return new Intl.NumberFormat('pt-BR', {
149
- minimumFractionDigits: 2,
150
- maximumFractionDigits: 2
151
- }).format(numberVal);
222
+ static decimal(valor) {
223
+ const valorNumerico = parseFloat(valor);
224
+ if (isNaN(valorNumerico)) return "0,00";
225
+ return new Intl.NumberFormat('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(valorNumerico);
152
226
  }
153
227
 
154
- /**
155
- * Retorna data atual no formato DD/MM/YYYY.
156
- */
157
- static currentDate() {
228
+ static data() {
158
229
  return new Intl.DateTimeFormat('pt-BR').format(new Date());
159
230
  }
160
231
 
161
- /**
162
- * Converte string ISO (YYYY-MM-DD) para PT-BR (DD/MM/YYYY).
163
- */
164
- static formatDateToBR(isoDateString) {
165
- if (!isoDateString) return '';
166
- const parts = isoDateString.split('-');
167
- if (parts.length !== 3) return isoDateString;
168
- return `${parts[2]}/${parts[1]}/${parts[0]}`;
232
+ static formatarDataParaDMY(stringDataIso) {
233
+ if (!stringDataIso) return '';
234
+ const partes = stringDataIso.split('-');
235
+ if (partes.length !== 3) return stringDataIso;
236
+ return `${partes[2]}/${partes[1]}/${partes[0]}`;
169
237
  }
170
238
 
171
- /**
172
- * Retorna data atual em ISO (YYYY-MM-DD).
173
- */
174
- static currentIsoDate() {
239
+ static normalizarStringData(entradaData) {
240
+ if (!entradaData) return '01/01/2025';
241
+ let str = String(entradaData).trim();
242
+
243
+ if (str.includes('/')) {
244
+ const partes = str.split('/');
245
+ if (partes.length >= 3) {
246
+ const dia = String(parseInt(partes[0], 10)).padStart(2, '0');
247
+ const mes = String(parseInt(partes[1], 10)).padStart(2, '0');
248
+ const ano = partes[2].substring(0, 4);
249
+ return `${dia}/${mes}/${ano}`;
250
+ }
251
+ }
252
+
253
+ if (str.includes('-')) {
254
+ const partes = str.split('-');
255
+ if (partes.length === 3) {
256
+ return `${partes[2].substring(0, 2)}/${partes[1]}/${partes[0]}`;
257
+ }
258
+ }
259
+
260
+ return str;
261
+ }
262
+
263
+ static obterDataAtualISO() {
175
264
  return new Date().toISOString().split('T')[0];
176
265
  }
177
266
 
178
- /**
179
- * Data e Hora atuais (DD/MM/YYYY HH:mm).
180
- */
181
- static currentDateTime() {
182
- const now = new Date();
183
- const datePart = new Intl.DateTimeFormat('pt-BR').format(now);
184
- const timePart = now.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' });
185
- return `${datePart} ${timePart}`;
267
+ static dataHora() {
268
+ const agora = new Date();
269
+ const parteData = new Intl.DateTimeFormat('pt-BR').format(agora);
270
+ const parteHora = agora.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' });
271
+ return `${parteData} ${parteHora}`;
186
272
  }
187
273
  }
188
274
 
189
275
  /**
190
- * SortUtils
191
- * Utilitários para ordenação de listas.
276
+ * UtilitariosOrdenacao
192
277
  */
193
- class SortUtils {
194
- static sortBy(data, key, direction = 'asc') {
195
- if (!Array.isArray(data) || !key) return data;
196
-
197
- const multiplier = direction === 'asc' ? 1 : -1;
198
-
199
- return [...data].sort((a, b) => {
200
- const valA = a[key];
201
- const valB = b[key];
202
-
278
+ class UtilitariosOrdenacao {
279
+ static ordenar(dados, chave, direcao = 'asc') {
280
+ if (!Array.isArray(dados) || !chave) return dados;
281
+ const multiplicador = direcao === 'asc' ? 1 : -1;
282
+
283
+ return [...dados].sort((a, b) => {
284
+ const valA = a[chave];
285
+ const valB = b[chave];
203
286
  if (valA == null) return 1;
204
287
  if (valB == null) return -1;
205
-
206
288
  if (typeof valA === 'string' && typeof valB === 'string') {
207
- return valA.localeCompare(valB) * multiplier;
289
+ return valA.localeCompare(valB) * multiplicador;
208
290
  }
209
-
210
- if (valA < valB) return -1 * multiplier;
211
- if (valA > valB) return 1 * multiplier;
291
+ if (valA < valB) return -1 * multiplicador;
292
+ if (valA > valB) return 1 * multiplicador;
212
293
  return 0;
213
294
  });
214
295
  }
215
296
  }
216
297
 
217
298
  /**
218
- * ExportService
219
- * Exportação para Excel (.xlsx) e CSV.
299
+ * ServicoExportacao
220
300
  */
221
- class ExportService {
301
+ class ServicoExportacao {
222
302
  static CDN_URL = "https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js";
223
303
 
224
- static async loadDependency() {
304
+ static async carregarDependencia() {
225
305
  if (typeof window !== 'undefined' && window.XLSX) return;
226
-
227
306
  return new Promise((resolve, reject) => {
228
307
  const script = document.createElement('script');
229
308
  script.src = this.CDN_URL;
@@ -234,38 +313,36 @@ class ExportService {
234
313
  });
235
314
  }
236
315
 
237
- static async toExcel(data, columns, filename, sheetName = 'Dados') {
238
- await this.loadDependency();
239
- const formattedData = data.map(item => {
240
- const row = {};
241
- columns.forEach(col => {
242
- row[col.display] = item[col.key];
243
- });
244
- return row;
316
+ static async paraExcel(dados, colunas, nomeArquivo, nomePlanilha = 'Dados') {
317
+ await this.carregarDependencia();
318
+ const dadosFormatados = dados.map(item => {
319
+ const linha = {};
320
+ colunas.forEach(col => { linha[col.display] = item[col.key]; });
321
+ return linha;
245
322
  });
246
323
 
247
- const worksheet = XLSX.utils.json_to_sheet(formattedData);
248
- const workbook = XLSX.utils.book_new();
249
- XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
250
- XLSX.writeFile(workbook, `${filename}.xlsx`);
324
+ const planilha = XLSX.utils.json_to_sheet(dadosFormatados);
325
+ const pastaTrabalho = XLSX.utils.book_new();
326
+ XLSX.utils.book_append_sheet(pastaTrabalho, planilha, nomePlanilha);
327
+ XLSX.writeFile(pastaTrabalho, `${nomeArquivo}.xlsx`);
251
328
  }
252
329
 
253
- static toCSV(data, columns, filename) {
254
- const headerRow = columns.map(c => `"${c.display}"`).join(';');
255
- const bodyRows = data.map(item => {
256
- return columns.map(col => {
330
+ static paraCSV(dados, colunas, nomeArquivo) {
331
+ const linhaCabecalho = colunas.map(c => `"${c.display}"`).join(';');
332
+ const linhasCorpo = dados.map(item => {
333
+ return colunas.map(col => {
257
334
  const val = item[col.key] ?? '';
258
- const stringVal = String(val).replace(/"/g, '""').replace(/\r?\n|\r/g, ' ');
259
- return `"${stringVal}"`;
335
+ const valString = String(val).replace(/"/g, '""').replace(/\r?\n|\r/g, ' ');
336
+ return `"${valString}"`;
260
337
  }).join(';');
261
338
  });
262
- const csvContent = [headerRow, ...bodyRows].join('\r\n');
263
- const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
339
+ const conteudoCsv = [linhaCabecalho, ...linhasCorpo].join('\r\n');
340
+ const blob = new Blob([conteudoCsv], { type: 'text/csv;charset=utf-8;' });
264
341
  const link = document.createElement('a');
265
342
  if (link.download !== undefined) {
266
343
  const url = URL.createObjectURL(blob);
267
344
  link.setAttribute('href', url);
268
- link.setAttribute('download', `${filename}.csv`);
345
+ link.setAttribute('download', `${nomeArquivo}.csv`);
269
346
  link.style.visibility = 'hidden';
270
347
  document.body.appendChild(link);
271
348
  link.click();
@@ -273,40 +350,195 @@ class ExportService {
273
350
  }
274
351
  }
275
352
 
276
- static async export(data, columns, filename = 'export', format = 'xlsx') {
277
- if (!data?.length) throw new Error("Sem dados para exportar.");
278
- if (!columns?.length) throw new Error("Colunas não definidas.");
353
+ static async exportar(dados, colunas, nomeArquivo = 'exportacao', formato = 'xlsx') {
354
+ if (!dados?.length) throw new Error("Sem dados para exportar.");
355
+ if (!colunas?.length) throw new Error("Colunas não definidas.");
279
356
 
280
- const fmt = format.toLowerCase();
281
- if (fmt === 'xlsx') await this.toExcel(data, columns, filename);
282
- else if (fmt === 'csv') this.toCSV(data, columns, filename);
283
- else throw new Error(`Formato '${format}' não suportado.`);
357
+ const fmt = formato.toLowerCase();
358
+ if (fmt === 'xlsx') await this.paraExcel(dados, colunas, nomeArquivo);
359
+ else if (fmt === 'csv') this.paraCSV(dados, colunas, nomeArquivo);
360
+ else throw new Error(`Formato '${formato}' não suportado.`);
284
361
  }
285
362
  }
286
363
 
364
+ /**
365
+ * ServicoPagina
366
+ * Manipuladores de Página e Navegação Sankhya-W
367
+ */
368
+ class ServicoPagina {
369
+ /**
370
+ * Retorna a URL atual da pagina com o caminho opcional.
371
+ * @param { String } path Caminho a ser adicionado a URL atual
372
+ * @returns { String } A URL com o protocolo HTTPS ou HTTP
373
+ */
374
+ static getUrl(path) {
375
+ return `${window.location.origin}${path ? '/' + path.replace('/', '') : ''}`;
376
+ }
377
+
378
+ /**
379
+ * Remove o frame da página de BI
380
+ * * @param { { instancia: String, paginaInicial: String, opcoes: any } } configuracoes Configuracoes gerais da pagina
381
+ * * **instancia**: Nome exato do componente de BI
382
+ * * **paginaInicial**: URL (a partir da pasta raiz) e nome do arquivo da pagina inicial
383
+ * * **opcoes**: [opcional] Campos com valores a serem recebidos pela pagina
384
+ * * _Padrao_: `{ instancia: '', paginaInicial: 'app.jsp' }`
385
+ * * @example JPSK.removerFrame ({ instancia: 'TELA_HTML5', paginaInicial: 'index.jsp'});
386
+ */
387
+ static removerFrame({ instancia, paginaInicial, ...opcoes } = { instancia: '', paginaInicial: 'app.jsp' }) {
388
+
389
+ new Promise(resolve => {
390
+
391
+ if (window.parent.document.getElementsByTagName('body').length) {
392
+
393
+ if (window.parent.document.querySelector('div.gwt-PopupPanel.alert-box.box-shadow'))
394
+ window.parent.document.querySelector('div.gwt-PopupPanel.alert-box.box-shadow')
395
+ .style.display = 'none';
396
+
397
+ window.parent.document.getElementsByTagName('body')[0].style.overflow = 'hidden';
398
+ }
399
+
400
+ if (window.parent.parent.document.getElementsByTagName('body').length) {
401
+
402
+ if (window.parent.parent.document.querySelector('div.gwt-PopupPanel.alert-box.box-shadow'))
403
+ window.parent.parent.document.querySelector('div.gwt-PopupPanel.alert-box.box-shadow')
404
+ .style.display = 'none';
405
+
406
+ window.parent.parent.document.getElementsByTagName('body')[0].style.overflow = 'hidden';
407
+ }
408
+
409
+ if (
410
+ window.parent.document
411
+ .querySelector('div.GI-BUHVBPVC > div > div > div > div > div > table > tbody > tr > td > div')
412
+ ) {
413
+ instancia = window.parent.document
414
+ .querySelector('div.GI-BUHVBPVC > div > div > div > div > div > table > tbody > tr > td > div')
415
+ .textContent;
416
+ }
417
+
418
+ if (instancia && instancia.length > 0) {
419
+ ServicoDados.consultar(`SELECT NUGDG FROM TSIGDG WHERE TITULO = '${instancia}'`).
420
+ then(e => resolve({ gadGetID: 'html5_z6dld', nuGdt: e[0].NUGDG, ...opcoes }));
421
+ }
422
+ else {
423
+ resolve({ gadGetID: 'html5_z6dld', nuGdt: 0, ...opcoes });
424
+ }
425
+ }).
426
+ then(o =>
427
+ setTimeout(() => {
428
+ if (typeof window.parent.document.getElementsByClassName('DashWindow')[0] != 'undefined') {
429
+
430
+ const opcoesUrl =
431
+ Object.
432
+ keys(o).
433
+ filter(item => !['params', 'UID', 'instance', 'nuGdg', 'gadGetID'].includes(item)).
434
+ map(item => `&${item}=${o[item]}`).
435
+ join('');
436
+
437
+ const url = `/mge/html5component.mge?entryPoint=${paginaInicial}&nuGdg=${o.nuGdt}${opcoesUrl}`
438
+
439
+ setTimeout(() =>
440
+ window.parent.document.getElementsByClassName('dyna-gadget')[0].innerHTML =
441
+ `<iframe src="${url}" class="gwt-Frame" style="width: 100%; height: 100%;"></iframe>`
442
+ , 500);
443
+
444
+ setTimeout(() => document.getElementsByClassName('popupContent').length
445
+ ? document.getElementsByClassName('popupContent')[0].parentElement.remove()
446
+ : (() => { /**/ })()
447
+ , 20000);
448
+
449
+ setTimeout(() => (document.getElementById('stndz-style').parentElement.parentElement)
450
+ .getElementsByTagName('body')[0].style.overflow = 'hidden'
451
+ , 20000);
452
+ }
453
+ })
454
+ );
455
+ }
456
+
457
+ /**
458
+ * Abre uma nova guia com a pagina atual
459
+ *
460
+ * @param { boolean } forcado - [Opcional] Indica se a abertura da nova guia deve ser forcada
461
+ * * @example JPSK.novaGuia ();
462
+ */
463
+ static novaGuia(forcado = false) {
464
+
465
+ if ((window.parent.parent.document.querySelector('.Taskbar-container') && !forcado) || forcado) {
466
+ Object.assign(document.createElement('a'), { target: '_blank', href: window.location.href }).click();
467
+ }
468
+
469
+ }
470
+
471
+ /**
472
+ * Abre uma pagina dentro do Sankhya-W.
473
+ * * - Se o resourceID nao existir, o sistema informara que a tela nao existe.
474
+ * - Se as chaves primarias nao forem informadas, a tela sera aberta na pagina inicial.
475
+ * - Se existirem chaves primarias, mas nao forem encontradas, a tela ssera aberta como visualizacao de um registro vazio (para inclusao)
476
+ * - Se existirem chaves primarias e forem encontradas, a tela sera aberta no registro encontrado.
477
+ * * @param { String } resourceID ID do recurso a ser aberto
478
+ * @param { Object } chavesPrimarias Chaves de identificacao do registro
479
+ * * @example JPSK.abrirPagina ('br.com.sankhya.core.cad.marcas', { CODIGO: 999 });
480
+ */
481
+ static abrirPagina(resourceID, chavesPrimarias) {
482
+
483
+ let url = ServicoPagina.getUrl(`/mge/system.jsp#app/%resID`);
484
+ url = url.replace('%resID', btoa(resourceID));
485
+
486
+ if (chavesPrimarias) {
487
+
488
+ let body = {};
489
+
490
+ Object.keys(chavesPrimarias).forEach(function (chave) {
491
+ body[chave] = isNaN(chavesPrimarias[chave])
492
+ ? String(chavesPrimarias[chave])
493
+ : Number(chavesPrimarias[chave])
494
+ });
495
+
496
+ url = url.concat(`/${btoa(JSON.stringify(body))}`);
497
+
498
+ }
499
+
500
+ Object.assign(document.createElement('a'), {
501
+ target: '_top',
502
+ href: url
503
+ }).click();
504
+
505
+ }
506
+
507
+ /**
508
+ * Fecha a pagina atual.
509
+ * * Ele verifica se a pagina atual esta dentro do Sankhya-W para fechar, senao ele fecha a aba do navegador.
510
+ */
511
+ static fecharPagina() {
512
+ if (window.parent.parent.document.querySelector('.Taskbar-container')) {
513
+ window.parent.parent.document.querySelector(
514
+ 'li.ListItem.AppItem.AppItem-selected div.Taskbar-icon.icon-close').click();
515
+ } else {
516
+ window.close();
517
+ }
518
+ }
519
+ }
287
520
 
288
521
  const lib = {
289
- DataQueryService,
290
- FormatUtils,
291
- SortUtils,
292
- ExportService,
293
-
294
- JSK: DataQueryService,
295
- JFSK: FormatUtils,
296
- JOSK: SortUtils,
297
- JEXSK: ExportService
522
+ ServicoDados,
523
+ UtilitariosFormatacao,
524
+ UtilitariosOrdenacao,
525
+ ServicoExportacao,
526
+ ServicoPagina,
527
+
528
+ // Aliases
529
+ JSK: ServicoDados,
530
+ JFSK: UtilitariosFormatacao,
531
+ JOSK: UtilitariosOrdenacao,
532
+ JEXSK: ServicoExportacao,
533
+ JPSK: ServicoPagina
298
534
  };
299
535
 
300
-
301
536
  if (typeof module !== 'undefined' && module.exports) {
302
537
  module.exports = lib;
303
- }
304
-
305
- else if (typeof window !== 'undefined') {
538
+ } else if (typeof window !== 'undefined') {
306
539
  Object.assign(window, lib);
307
-
308
540
  if (typeof window.executeQuery === 'function') {
309
- DataQueryService.setExecutor(window.executeQuery);
310
- console.log("[DataQueryService] Executor 'executeQuery' detectado e configurado automaticamente.");
541
+ ServicoDados.definirExecutor(window.executeQuery);
542
+ console.log("[JSK] Executor 'executeQuery' detectado e configurado automaticamente.");
311
543
  }
312
544
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jtandrelevicius/utils-js-library",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {