@nixweb/nixloc-ui 0.0.93 → 0.0.94

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 (25) hide show
  1. package/package.json +4 -2
  2. package/src/component/forms/EscolherEstatico.vue +0 -3
  3. package/src/component/layout/BarraRolagem.vue +9 -2
  4. package/src/component/layout/Menu.vue +16 -9
  5. package/src/component/layout/Tag.vue +66 -0
  6. package/src/component/shared/FiltroHorizontal.vue +8 -2
  7. package/src/component/shared/Progresso.vue +14 -1
  8. package/src/component/shared/Tabela.vue +2 -12
  9. package/src/component/shared/query-builder/Campo.vue +116 -0
  10. package/src/component/shared/query-builder/ConverteParaOdata.js +73 -0
  11. package/src/component/shared/query-builder/Filtro.vue +85 -0
  12. package/src/component/shared/query-builder/QueryBuilder.vue +164 -0
  13. package/src/component/shared/query-builder/Rodape.vue +38 -0
  14. package/src/component/shared/query-builder/Tags.vue +84 -0
  15. package/src/component/shared/query-builder/components/CustomSelect.vue +115 -0
  16. package/src/component/shared/query-builder/components/QueryBuilderChildren.vue +46 -0
  17. package/src/component/shared/query-builder/components/QueryBuilderGroup.vue +151 -0
  18. package/src/component/shared/query-builder/components/QueryBuilderRule.vue +81 -0
  19. package/src/component/shared/query-builder/layouts/Bootstrap/BootstrapGroup.vue +120 -0
  20. package/src/component/shared/query-builder/layouts/Bootstrap/BootstrapRule.vue +171 -0
  21. package/src/component/shared/query-builder/main.js +81 -0
  22. package/src/component/shared/query-builder/utilities.js +22 -0
  23. package/src/component/template/ModeloRelatorioView.vue +455 -0
  24. package/src/store/modulos/generic.js +11 -0
  25. package/src/store/modulos/relatorio.js +149 -0
@@ -0,0 +1,455 @@
1
+ <template>
2
+ <div>
3
+ <Painel
4
+ :modulo="painel.modulo"
5
+ :titulo="painel.titulo"
6
+ :mostrarFiltroVertical="painel.mostrarFiltroVertical"
7
+ :mostrarPesquisa="painel.mostrarPesquisa"
8
+ :mostrarBotoes="painel.mostrarBotoes"
9
+ >
10
+ <div slot="conteudo-principal">
11
+ <br />
12
+ <div class="div-progresso" v-if="carregando && tamanhoDados > 0">
13
+ <Progresso
14
+ :texto="`Carregando ${tamanhoDados} registro(s) de ${conteudo.totalRegistros}`"
15
+ :valor="tamanhoDados"
16
+ :maximo="conteudo.totalRegistros"
17
+ tamanho="medium"
18
+ />
19
+ </div>
20
+ <Moldura>
21
+ <div>
22
+ <div slot="conteudo-filtro-horizontal">
23
+ <b-row>
24
+ <b-col sm="6">
25
+ <div class="lado-a-lado">
26
+ <Botao
27
+ chave="buscarRelatorio"
28
+ tipo="primario"
29
+ titulo="Buscar"
30
+ classeIcone="fas fa-file-search"
31
+ tamanho="medio"
32
+ :desabilitado="invalido || btnDesativado"
33
+ :clique="obterTodos"
34
+ />
35
+ </div>
36
+ <div class="lado-a-lado">
37
+ <Botao
38
+ v-if="!invalido"
39
+ chave="salvarRelatorio"
40
+ tipo="sucesso"
41
+ titulo="Salvar"
42
+ classeIcone="fas fa-save"
43
+ :desabilitado="carregando || invalido"
44
+ tamanho="pequeno"
45
+ :clique="salvarRelatorio"
46
+ />
47
+ </div>
48
+ </b-col>
49
+ <b-col class="text-right" sm="6">
50
+ <div class="lado-a-lado">
51
+ <Botao
52
+ chave="abrirCampo"
53
+ tipo="info"
54
+ titulo="Campos"
55
+ classeIcone="fas fa-database"
56
+ tamanho="pequeno"
57
+ :desabilitado="carregando"
58
+ :clique="abrirCampo"
59
+ />
60
+ </div>
61
+ <div class="lado-a-lado">
62
+ <Botao
63
+ chave="abrirFiltro"
64
+ tipo="info"
65
+ titulo="Filtros"
66
+ classeIcone="fas fa-filter"
67
+ tamanho="pequeno"
68
+ :desabilitado="carregando"
69
+ :clique="abrirFiltro"
70
+ />
71
+ </div>
72
+ </b-col>
73
+ </b-row>
74
+ <Modal titulo="Filtros" :largura="900" v-show="mostrarModal('filtro')">
75
+ <slot name="filtro"></slot>
76
+ <br />
77
+ <b-row>
78
+ <b-col class="text-right" sm="12">
79
+ <div class="lado-a-lado">
80
+ <Botao
81
+ chave="aplicaFiltro"
82
+ tipo="primario"
83
+ titulo="Aplicar"
84
+ classeIcone="fas fa-filter"
85
+ tamanho="pequeno"
86
+ :clique="aplicarFiltro"
87
+ />
88
+ </div>
89
+ </b-col>
90
+ </b-row>
91
+ </Modal>
92
+ <Modal titulo="Campos" :largura="600" v-show="mostrarModal('campo')">
93
+ <slot name="campo"></slot>
94
+ <b-row>
95
+ <b-col class="text-right" sm="12">
96
+ <div class="lado-a-lado">
97
+ <Botao
98
+ chave="aplicaFiltro"
99
+ tipo="primario"
100
+ titulo="Aplicar"
101
+ classeIcone="fas fa-filter"
102
+ tamanho="pequeno"
103
+ :desabilitado="campoSelecionado.length == 0"
104
+ :clique="aplicarFiltro"
105
+ />
106
+ </div>
107
+ </b-col>
108
+ </b-row>
109
+ </Modal>
110
+ </div>
111
+ </div>
112
+ </Moldura>
113
+ <div class="div-obrigatorio" v-show="invalido">
114
+ <Alerta tipo="info" v-for="item in filtroObrigatorio">
115
+ É necessário o filtro <b>{{ item.label }}</b
116
+ >, clique no botão "Filtros" para adicionar.
117
+ </Alerta>
118
+ </div>
119
+
120
+ <div class="div-tags">
121
+ <Tags nomeEvento="tagRelatorio" />
122
+ </div>
123
+ <div class="g-div-moldura div-tabela" v-if="!carregando && tamanhoDados > 0">
124
+ <b-row>
125
+ <b-col sm="6">
126
+ <div class="lado-a-lado">
127
+ <Botao
128
+ chave="buscarRelatorio"
129
+ tipo="editar"
130
+ titulo="Excel"
131
+ classeIcone="fas fa-file-excel"
132
+ tamanho="pequeno"
133
+ :clique="obterTodos"
134
+ />
135
+ </div>
136
+ <div class="lado-a-lado">
137
+ <Botao
138
+ chave="buscarRelatorio"
139
+ tipo="editar"
140
+ titulo="PDF"
141
+ classeIcone="fas fa-file-pdf"
142
+ tamanho="pequeno"
143
+ :clique="obterTodos"
144
+ />
145
+ </div>
146
+ </b-col>
147
+ <b-col sm="6">
148
+ <Registro :totalRegistro="conteudo.totalRegistros" />
149
+ </b-col>
150
+ </b-row>
151
+ <BarraRolagem :alturaMinima="300" :alturaMaxima="500">
152
+ <Tabela
153
+ :cabecalhoTabela="conteudo.cabecalhoTabela"
154
+ :dados="conteudo.dados"
155
+ :mostrarChecks="modeloLista.mostrarChecks"
156
+ />
157
+ </BarraRolagem>
158
+ </div>
159
+ <div class="div-sem-dados" v-if="nenhumDadoRetornado">
160
+ <Alerta tipo="info">
161
+ <span> Nenhum registro foi encontrato!</span>
162
+ </Alerta>
163
+ </div>
164
+ <div class="div-rodape" v-if="conteudo.resumo.length > 0">
165
+ <Rodape :dados="conteudo.resumo" />
166
+ </div>
167
+ </div>
168
+ </Painel>
169
+ </div>
170
+ </template>
171
+
172
+ <script>
173
+ import Alerta from "@nixweb/nixloc-ui/src/component/layout/Alerta";
174
+ import Modal from "@nixweb/nixloc-ui/src/component/forms/Modal";
175
+ import Botao from "@nixweb/nixloc-ui/src/component/forms/Botao";
176
+ import Tabela from "../shared/Tabela.vue";
177
+ import Registro from "../shared/Registro.vue";
178
+ import Painel from "@nixweb/nixloc-ui/src/component/layout/Painel.vue";
179
+ import BarraRolagem from "@nixweb/nixloc-ui/src/component/layout/BarraRolagem.vue";
180
+ import Moldura from "@nixweb/nixloc-ui/src/component/layout/Moldura";
181
+ import Progresso from "@nixweb/nixloc-ui/src/component/shared/Progresso";
182
+ import Rodape from "@nixweb/nixloc-ui/src/component/shared/query-builder/Rodape.vue";
183
+ import Tags from "@nixweb/nixloc-ui/src/component/shared/query-builder/Tags.vue";
184
+
185
+ import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
186
+
187
+ export default {
188
+ name: "ModeloRelatorioView",
189
+ props: {
190
+ modeloLista: Object,
191
+ campo: Array,
192
+ painel: Object,
193
+ },
194
+ components: {
195
+ Alerta,
196
+ Modal,
197
+ Botao,
198
+ Registro,
199
+ Tabela,
200
+ Painel,
201
+ BarraRolagem,
202
+ Moldura,
203
+ Rodape,
204
+ Progresso,
205
+ Tags,
206
+ },
207
+ data() {
208
+ return {
209
+ conteudo: {
210
+ cabecalhoTabela: [],
211
+ dados: [],
212
+ resumo: [],
213
+ paginacao: 0,
214
+ paginaAtual: 1,
215
+ totalPorPagina: 100,
216
+ totalRegistros: 0,
217
+ },
218
+ btnDesativado: true,
219
+ carregando: false,
220
+ nenhumDadoRetornado: false,
221
+ };
222
+ },
223
+ mounted() {
224
+ this.removeCarregando(["painel"]);
225
+ },
226
+ computed: {
227
+ ...mapGetters("generic", ["mostrarModal", "evento"]),
228
+ ...mapGetters("relatorio", [
229
+ "cabecalhoTabela",
230
+ "filtroSelecionado",
231
+ "filtroObrigatorio",
232
+ "temCampoSelecionado",
233
+ "oDataSelect",
234
+ "oDataFilter",
235
+ "oDataOrderBy",
236
+ ]),
237
+ ...mapState("relatorio", ["relatorio", "campoSelecionado", "resumo"]),
238
+ urlConsulta() {
239
+ let baseUrl = `${this.modeloLista.urlGetApi}?${this.oDataSelect}&${this.oDataOrderBy}&${this.oDataFilter.consulta}&$skip=${this.skip}&$top=${this.conteudo.totalPorPagina}&$count=true`;
240
+ return baseUrl.replace("&&", "&");
241
+ },
242
+ urlResumo() {
243
+ let consulta = this.oDataFilter.resumo
244
+ ? `$apply=filter(${this.oDataFilter.consulta.replace("$filter=", "")})/`
245
+ : "$apply=";
246
+ let baseUrl = `${this.modeloLista.urlGetApi}?${consulta}aggregate(${this.oDataFilter.resumo})`;
247
+ return baseUrl;
248
+ },
249
+ skip() {
250
+ return (this.conteudo.paginaAtual - 1) * this.conteudo.totalPorPagina;
251
+ },
252
+ invalido() {
253
+ let retorno = true;
254
+ this.filtroObrigatorio.forEach((filtro) => {
255
+ var existe = this.filtroSelecionado.children.find((value) => {
256
+ if (filtro.label == value.query.label) retorno = false;
257
+ });
258
+ });
259
+
260
+ return retorno;
261
+ },
262
+ tamanhoDados() {
263
+ return this.conteudo.dados.length;
264
+ },
265
+ },
266
+ methods: {
267
+ ...mapActions("generic", ["getApiOdata"]),
268
+ ...mapMutations("generic", ["abrirModal", "fecharModal", "removeCarregando"]),
269
+ ...mapMutations("relatorio", ["atualizaCabecalhoTabela", "atualizaConsultaFiltro"]),
270
+
271
+ obterTodos() {
272
+ this.conteudo.dados = [];
273
+ this.conteudo.resumo = [];
274
+ this.btnDesativado = true;
275
+
276
+ if (!this.invalido) {
277
+ this.mostraEscondeCampos();
278
+ this.paginacao();
279
+ this.removeCarregando(["buscarRelatorio"]);
280
+
281
+ if (this.oDataFilter.resumo) this.resumoOData();
282
+ if (!this.oDataFilter.resumo) this.conteudo.resumo = [];
283
+ }
284
+ },
285
+ paginacao() {
286
+ let paramsConsulta = { url: this.urlConsulta };
287
+ this.reiniciaDados();
288
+
289
+ this.getApiOdata(paramsConsulta).then((response) => {
290
+ let totalRegistros = response["@odata.count"];
291
+ if (totalRegistros == 0) this.nenhumDadoRetornado = true;
292
+ this.conteudo.totalRegistros = totalRegistros;
293
+ this.conteudo.paginacao = Math.round(
294
+ totalRegistros / this.conteudo.totalPorPagina
295
+ );
296
+
297
+ if (totalRegistros <= this.conteudo.totalPorPagina) {
298
+ this.consultaOdata();
299
+ this.conteudo.cabecalhoTabela = this.cabecalhoTabela;
300
+ }
301
+ if (this.conteudo.paginacao == 0) this.carregando = false;
302
+ });
303
+ },
304
+ reiniciaDados() {
305
+ this.carregando = true;
306
+ this.conteudo.dados = [];
307
+ this.conteudo.paginaAtual = 1;
308
+ this.nenhumDadoRetornado = false;
309
+ },
310
+ consultaOdata() {
311
+ let paramsConsulta = { url: this.urlConsulta };
312
+ this.getApiOdata(paramsConsulta).then((response) => {
313
+ let self = this;
314
+ response.value.forEach(function (obj) {
315
+ self.conteudo.dados.push(obj);
316
+ });
317
+ this.conteudo.paginaAtual++;
318
+ });
319
+ this.conteudo.cabecalhoTabela = this.cabecalhoTabela;
320
+ },
321
+ resumoOData() {
322
+ let paramsResumo = { url: this.urlResumo };
323
+ this.getApiOdata(paramsResumo).then((response) => {
324
+ this.conteudo.resumo = [];
325
+ const result = Object.entries(response[0]);
326
+ let self = this;
327
+ result.forEach(function (value) {
328
+ self.resumo.forEach(function (legenda) {
329
+ let obj = {
330
+ titulo: "",
331
+ valor: value[1],
332
+ classeCss: legenda.classeCss,
333
+ tipo: legenda.tipo,
334
+ };
335
+ if (legenda.valor == value[0]) {
336
+ obj.titulo = legenda.titulo;
337
+ self.conteudo.resumo.push(obj);
338
+ }
339
+ });
340
+ });
341
+ });
342
+ },
343
+ abrirCampo() {
344
+ this.abrirModal("campo");
345
+ this.removeCarregando(["abrirCampo"]);
346
+ },
347
+ abrirFiltro() {
348
+ this.abrirModal("filtro");
349
+ this.removeCarregando(["abrirFiltro"]);
350
+ },
351
+ aplicarFiltro() {
352
+ this.fecharModal();
353
+ this.removeCarregando(["aplicaFiltro", "aplicaCampo"]);
354
+ },
355
+ salvarRelatorio() {},
356
+ mostraEscondeCampos() {
357
+ let self = this;
358
+ this.relatorio.campo.forEach(function (value) {
359
+ if (self.temCampoSelecionado(value.campo, self.campoSelecionado)) {
360
+ value.mostrar = true;
361
+ } else {
362
+ value.mostrar = false;
363
+ }
364
+ });
365
+ },
366
+ },
367
+ watch: {
368
+ evento: {
369
+ handler(evento) {
370
+ if (evento.nome == "tagRelatorio") this.abrirModal("filtro");
371
+ },
372
+ deep: true,
373
+ },
374
+ campoSelecionado: {
375
+ handler() {
376
+ this.mostraEscondeCampos();
377
+ },
378
+ deep: true,
379
+ },
380
+ filtroSelecionado: {
381
+ handler(filtro) {
382
+ this.atualizaConsultaFiltro(filtro);
383
+ },
384
+ deep: true,
385
+ },
386
+ "conteudo.paginaAtual": {
387
+ handler(value) {
388
+ if (value <= this.conteudo.paginacao - 1) {
389
+ let self = this;
390
+ setTimeout(function () {
391
+ self.consultaOdata();
392
+ }, 200);
393
+ }
394
+ if (value == this.conteudo.paginacao && value != 0) this.carregando = false;
395
+ },
396
+ deep: true,
397
+ },
398
+ "conteudo.paginacao": {
399
+ handler(value) {
400
+ this.consultaOdata();
401
+ },
402
+ deep: true,
403
+ },
404
+ "oDataFilter.consulta": {
405
+ handler(value) {
406
+ this.btnDesativado = false;
407
+ },
408
+ deep: true,
409
+ },
410
+ oDataSelect: {
411
+ handler(value) {
412
+ this.btnDesativado = false;
413
+ },
414
+ deep: true,
415
+ },
416
+ oDataOrderBy: {
417
+ handler(value) {
418
+ this.btnDesativado = false;
419
+ },
420
+ deep: true,
421
+ },
422
+ },
423
+ };
424
+ </script>
425
+
426
+ <style scoped>
427
+ .div-progresso {
428
+ margin-bottom: 10px;
429
+ }
430
+
431
+ .div-sem-dados {
432
+ margin-top: 20px;
433
+ }
434
+
435
+ .div-tabela {
436
+ margin-top: 20px;
437
+ }
438
+
439
+ .div-separacao {
440
+ margin-left: 10px;
441
+ margin-right: 5px;
442
+ }
443
+
444
+ .div-rodape {
445
+ margin-top: 20px;
446
+ }
447
+
448
+ .div-tags {
449
+ margin-top: 15px;
450
+ }
451
+
452
+ .div-obrigatorio {
453
+ margin-top: 20px;
454
+ }
455
+ </style>
@@ -237,6 +237,17 @@ export default {
237
237
  return false;
238
238
  })
239
239
  },
240
+ getApiOdata: async function (context, params) {
241
+ return axios.get(params.url, {
242
+ headers: new Token().tokenHeaders(),
243
+ })
244
+ .then((response) => {
245
+ return response.data;
246
+ }, (err) => {
247
+ context.commit('insereNotificacaoErroApi');
248
+ return false;
249
+ })
250
+ },
240
251
  deleteAllApi: async function (context, params) {
241
252
 
242
253
  context.commit('limpaMetodoExecutadoApi');
@@ -0,0 +1,149 @@
1
+ import ConverteParaOdata from "@nixweb/nixloc-ui/src/component/shared/query-builder/ConverteParaOdata.js";
2
+
3
+ export default {
4
+ namespaced: true,
5
+ state: {
6
+ relatorio: {
7
+ campo: [],
8
+ filtro: [],
9
+ },
10
+ campoSelecionado: [],
11
+ campoOrdenado: {},
12
+ filtroSelecionado: { children: [] },
13
+ consulta: [],
14
+ resumo: [],
15
+ },
16
+ getters: {
17
+ cabecalhoTabela: (state) => {
18
+ let lista = [];
19
+ state.relatorio.campo.forEach(function (value) {
20
+ if (value.mostrar) lista.push(value);
21
+ });
22
+ return lista;
23
+ },
24
+ opcoes: (state) => {
25
+ let obj = {
26
+ valorInicial: [],
27
+ opcoes: []
28
+ }
29
+ state.relatorio.campo.forEach(function (value) {
30
+ let opcoes = { text: value.titulo, value: value.campo };
31
+ obj.opcoes.push(opcoes);
32
+
33
+ if (value.mostrar) obj.valorInicial.push(value.campo);
34
+ });
35
+ return obj;
36
+ },
37
+ filtroObrigatorio: (state) => {
38
+ var filtroObrigatorio = state.relatorio.filtro.filter(x => x.obrigatorio == true);
39
+ return filtroObrigatorio;
40
+ },
41
+ filtroSelecionado: (state) => {
42
+ let filtro = { children: [] };
43
+
44
+ state.filtroSelecionado.children.forEach(function (value) {
45
+ if (value.query.value != null && value.query.value != "" && value.query.value != undefined)
46
+ filtro.children.push(value);
47
+ });
48
+
49
+ return filtro;
50
+ },
51
+ temCampoSelecionado: (state) => (campo, valor) => {
52
+ var existe = valor.find((value) => {
53
+ if (campo == value) return true;
54
+ });
55
+ return existe;
56
+ },
57
+ oDataOrderBy: (state) => {
58
+ let orderBy = `$orderby=${state.campoOrdenado.id} ${state.campoOrdenado.ordenar}`;
59
+ return orderBy;
60
+ },
61
+ oDataSelect: (state) => {
62
+ let consulta = "";
63
+ let seqConsulta = 0;
64
+
65
+ state.relatorio.campo.forEach(function (obj) {
66
+ if (obj.mostrar || obj.obrigatorioOData) {
67
+ if (seqConsulta == 0) consulta += `$select=${obj.campo}`;
68
+ if (seqConsulta > 0) consulta += `,${obj.campo}`;
69
+ seqConsulta++;
70
+ }
71
+ });
72
+
73
+ return consulta;
74
+ },
75
+ oDataFilter: (state) => {
76
+ let consulta = "";
77
+ let resumo = "";
78
+ let seqConsulta = 0;
79
+ let seqResumo = 0;
80
+ var tamanho = state.consulta.length;
81
+
82
+ state.consulta.forEach(function (valor) {
83
+ if (valor.tipo == "campo") {
84
+ if (seqConsulta == 0 && tamanho > 0) consulta += `$filter=${valor.filtro}`;
85
+ if (seqConsulta > 0 && tamanho > 0) consulta += ` and ${valor.filtro}`;
86
+ seqConsulta++;
87
+ } else {
88
+ if (seqResumo == 0 && tamanho > 0) resumo += `${valor.filtro}`;
89
+ if (seqResumo > 0 && tamanho > 0) resumo += `,${valor.filtro}`;
90
+ seqResumo++;
91
+ }
92
+ });
93
+
94
+ return { consulta, resumo };
95
+ },
96
+ },
97
+ mutations: {
98
+ insereRelatorio: (state, obj) => {
99
+ state.relatorio = obj;
100
+ },
101
+ atualizaCampoSelecionado: (state, value) => {
102
+ state.campoSelecionado = value;
103
+ },
104
+ atualizaFiltroSelecionado: (state, value) => {
105
+ state.filtroSelecionado = value;
106
+ },
107
+ atualizaCampoOrdenado: (state, value) => {
108
+ state.campoOrdenado = value;
109
+ },
110
+ removeFiltroSelecionado: (state, id) => {
111
+ var filtro = state.filtroSelecionado.children.filter((x) => {
112
+ return x.query.id != id;
113
+ });
114
+ state.filtroSelecionado.children = filtro;
115
+ },
116
+ atualizaConsultaFiltro: (state, filtro) => {
117
+ state.resumo = [];
118
+ state.consulta = [];
119
+
120
+ filtro.children.forEach(function (chave) {
121
+ let valor = chave.query.value;
122
+
123
+ if (chave.query.choices && chave.query.tipo == "resumo") {
124
+ chave.query.choices.forEach(function (value) {
125
+ let obj = {
126
+ titulo: value.como.titulo,
127
+ valor: value.como.valor,
128
+ classeCss: chave.query.classeCss,
129
+ tipo: value.como.tipo,
130
+ };
131
+ state.resumo.push(obj);
132
+ });
133
+ }
134
+ let converteParaOdata = new ConverteParaOdata();
135
+ let filtro = converteParaOdata.converteFiltro(chave.query);
136
+
137
+ if (valor != null && valor != undefined && valor != "") {
138
+ if (filtro != "") {
139
+ let obj = { filtro: filtro, tipo: chave.query.tipo };
140
+ state.consulta.push(obj);
141
+ }
142
+ }
143
+ });
144
+ }
145
+ },
146
+ actions: {
147
+
148
+ }
149
+ }