@nixweb/nixloc-ui 0.0.93 → 0.0.96

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 (30) hide show
  1. package/package.json +3 -2
  2. package/src/component/forms/DateTime.vue +16 -3
  3. package/src/component/forms/EscolherEstatico.vue +0 -3
  4. package/src/component/layout/BarraRolagem.vue +9 -2
  5. package/src/component/layout/Menu.vue +19 -12
  6. package/src/component/layout/Tag.vue +66 -0
  7. package/src/component/shared/Confirmacao.vue +80 -0
  8. package/src/component/shared/FiltroHorizontal.vue +8 -2
  9. package/src/component/shared/Progresso.vue +14 -1
  10. package/src/component/shared/Tabela.vue +3 -13
  11. package/src/component/shared/query-builder/Campo.vue +116 -0
  12. package/src/component/shared/query-builder/ConverteParaOdata.js +73 -0
  13. package/src/component/shared/query-builder/Filtro.vue +85 -0
  14. package/src/component/shared/query-builder/QueryBuilder.vue +164 -0
  15. package/src/component/shared/query-builder/Rodape.vue +38 -0
  16. package/src/component/shared/query-builder/Tags.vue +84 -0
  17. package/src/component/shared/query-builder/components/CustomSelect.vue +115 -0
  18. package/src/component/shared/query-builder/components/QueryBuilderChildren.vue +46 -0
  19. package/src/component/shared/query-builder/components/QueryBuilderGroup.vue +151 -0
  20. package/src/component/shared/query-builder/components/QueryBuilderRule.vue +81 -0
  21. package/src/component/shared/query-builder/layouts/Bootstrap/BootstrapGroup.vue +120 -0
  22. package/src/component/shared/query-builder/layouts/Bootstrap/BootstrapRule.vue +171 -0
  23. package/src/component/shared/query-builder/main.js +81 -0
  24. package/src/component/shared/query-builder/utilities.js +22 -0
  25. package/src/component/template/ModeloRelatorioListaView.vue +101 -32
  26. package/src/component/template/ModeloRelatorioView.vue +467 -0
  27. package/src/component/template/Relatorio.js +10 -0
  28. package/src/component/template/RelatorioAdicionarModificar.vue +106 -0
  29. package/src/store/modulos/generic.js +11 -0
  30. package/src/store/modulos/relatorio.js +169 -0
@@ -0,0 +1,164 @@
1
+ <template>
2
+ <div class="vue-query-builder">
3
+ <slot v-bind="vqbProps">
4
+ <query-builder-group v-bind="vqbProps" :query.sync="query" />
5
+ </slot>
6
+ </div>
7
+ </template>
8
+
9
+ <script>
10
+ /* eslint-disable vue/require-default-prop */
11
+ import QueryBuilderGroup from "./layouts/Bootstrap/BootstrapGroup.vue";
12
+ import deepClone from "./utilities.js";
13
+
14
+ var defaultLabels = {
15
+ matchType: "Construtor de Consulta",
16
+ matchTypes: [
17
+ { id: "all", label: "All" },
18
+ { id: "any", label: "Any" },
19
+ ],
20
+ addRule: "+ Adicionar",
21
+ removeRule: "&times;",
22
+ addGroup: "+ Adicionar",
23
+ removeGroup: "&times;",
24
+ textInputPlaceholder: "Valor",
25
+ };
26
+
27
+ export default {
28
+ name: "VueQueryBuilder",
29
+
30
+ components: {
31
+ QueryBuilderGroup,
32
+ },
33
+
34
+ props: {
35
+ rules: Array,
36
+ labels: {
37
+ type: Object,
38
+ default() {
39
+ return defaultLabels;
40
+ },
41
+ },
42
+ maxDepth: {
43
+ type: Number,
44
+ default: 3,
45
+ validator: function (value) {
46
+ return value >= 1;
47
+ },
48
+ },
49
+ value: Object,
50
+ },
51
+
52
+ data() {
53
+ return {
54
+ query: {
55
+ logicalOperator: this.labels.matchTypes[0].id,
56
+ children: [],
57
+ },
58
+ ruleTypes: {
59
+ text: {
60
+ operators: ["igual", "diferente", "contem"],
61
+ inputType: "text",
62
+ id: "text-field",
63
+ },
64
+ numeric: {
65
+ operators: ["=", "!=", "<", "<=", ">", ">="],
66
+ inputType: "number",
67
+ id: "number-field",
68
+ },
69
+ custom: {
70
+ operators: [],
71
+ inputType: "text",
72
+ id: "custom-field",
73
+ },
74
+ radio: {
75
+ operators: [],
76
+ choices: [],
77
+ inputType: "radio",
78
+ id: "radio-field",
79
+ },
80
+ checkbox: {
81
+ operators: ["checkbox"],
82
+ choices: [],
83
+ inputType: "checkbox",
84
+ id: "checkbox-field",
85
+ },
86
+ select: {
87
+ operators: [],
88
+ choices: [],
89
+ inputType: "select",
90
+ id: "select-field",
91
+ },
92
+ "multi-select": {
93
+ operators: ["="],
94
+ choices: [],
95
+ inputType: "select",
96
+ id: "multi-select-field",
97
+ },
98
+ },
99
+ };
100
+ },
101
+
102
+ computed: {
103
+ mergedLabels() {
104
+ return Object.assign({}, defaultLabels, this.labels);
105
+ },
106
+
107
+ mergedRules() {
108
+ var mergedRules = [];
109
+ var vm = this;
110
+
111
+ vm.rules.forEach(function (rule) {
112
+ if (typeof vm.ruleTypes[rule.type] !== "undefined") {
113
+ mergedRules.push(Object.assign({}, vm.ruleTypes[rule.type], rule));
114
+ } else {
115
+ mergedRules.push(rule);
116
+ }
117
+ });
118
+
119
+ return mergedRules;
120
+ },
121
+
122
+ vqbProps() {
123
+ return {
124
+ index: 0,
125
+ depth: 1,
126
+ maxDepth: this.maxDepth,
127
+ ruleTypes: this.ruleTypes,
128
+ rules: this.mergedRules,
129
+ labels: this.mergedLabels,
130
+ };
131
+ },
132
+ },
133
+
134
+ mounted() {
135
+ this.$watch(
136
+ "query",
137
+ (newQuery) => {
138
+ if (JSON.stringify(newQuery) !== JSON.stringify(this.value)) {
139
+ this.$emit("input", deepClone(newQuery));
140
+ }
141
+ },
142
+ {
143
+ deep: true,
144
+ }
145
+ );
146
+
147
+ this.$watch(
148
+ "value",
149
+ (newValue) => {
150
+ if (JSON.stringify(newValue) !== JSON.stringify(this.query)) {
151
+ this.query = deepClone(newValue);
152
+ }
153
+ },
154
+ {
155
+ deep: true,
156
+ }
157
+ );
158
+
159
+ if (typeof this.$options.propsData.value !== "undefined") {
160
+ this.query = Object.assign(this.query, this.$options.propsData.value);
161
+ }
162
+ },
163
+ };
164
+ </script>
@@ -0,0 +1,38 @@
1
+ <template>
2
+ <div>
3
+ <Moldura>
4
+ <div v-for="item in dados" :key="item.titulo">
5
+ <div :class="item.classeCss">
6
+ <b-row>
7
+ <b-col class="text-right" sm="10">
8
+ <span class="titulo">{{ item.titulo }}</span>
9
+ </b-col>
10
+ <b-col class="text-right" sm="2">
11
+ <span class="titulo">{{ item.valor }}</span>
12
+ </b-col>
13
+ </b-row>
14
+ </div>
15
+ </div>
16
+ </Moldura>
17
+ </div>
18
+ </template>
19
+ <script>
20
+ import Moldura from "@nixweb/nixloc-ui/src/component/layout/Moldura";
21
+
22
+ export default {
23
+ name: "RodapeRelatorio",
24
+ components: {
25
+ Moldura,
26
+ },
27
+ props: {
28
+ dados: Array,
29
+ },
30
+ };
31
+ </script>
32
+
33
+ <style scoped>
34
+ .titulo {
35
+ font-size: 15px;
36
+ font-weight: 400;
37
+ }
38
+ </style>
@@ -0,0 +1,84 @@
1
+ <template>
2
+ <div>
3
+ <div class="lado-a-lado div-tag" v-for="tag in tags" :key="tag.id">
4
+ <Tag
5
+ :nomeEvento="nomeEvento"
6
+ :dadosEvento="tag"
7
+ :titulo="tag.titulo"
8
+ :valor="tag.valor"
9
+ />
10
+ </div>
11
+ </div>
12
+ </template>
13
+
14
+ <script>
15
+ import Tag from "@nixweb/nixloc-ui/src/component/layout/Tag";
16
+
17
+ import { mapGetters, mapMutations } from "vuex";
18
+
19
+ export default {
20
+ name: "Tags",
21
+ components: { Tag },
22
+ props: {
23
+ nomeEvento: String,
24
+ },
25
+ data() {
26
+ return {
27
+ tags: [],
28
+ };
29
+ },
30
+ computed: {
31
+ ...mapGetters("relatorio", ["filtroSelecionado"]),
32
+ ...mapGetters("generic", ["mostrarModal", "evento"]),
33
+ },
34
+ methods: {
35
+ ...mapMutations("relatorio", ["removeFiltroSelecionado"]),
36
+ },
37
+ watch: {
38
+ filtroSelecionado: {
39
+ handler(filtro) {
40
+ let self = this;
41
+ this.tags = [];
42
+ filtro.children.forEach(function (value) {
43
+ let valor = "";
44
+ let type = value.query.type;
45
+
46
+ if (type == "custom-component" && value.query.label == "Período") {
47
+ valor = `${value.query.value[0]} - ${value.query.value[1]}`;
48
+ }
49
+
50
+ if (type == "text" || type == "numeric") {
51
+ valor = `${value.query.operator} "${value.query.value}"`;
52
+ }
53
+
54
+ if (type == "checkbox") {
55
+ value.query.choices.forEach(function (opcoes) {
56
+ value.query.value.forEach(function (value) {
57
+ if (opcoes.value == value) {
58
+ valor += `${opcoes.label},`;
59
+ }
60
+ });
61
+ });
62
+ }
63
+
64
+ let tag = { id: value.query.id, titulo: value.query.label, valor: valor };
65
+ if (value.query.value != null) self.tags.push(tag);
66
+ });
67
+ },
68
+ deep: true,
69
+ },
70
+ evento: {
71
+ handler(evento) {
72
+ if (evento.nome == "tagRemovida") {
73
+ var tags = this.tags.filter((x) => {
74
+ return x.id != evento.dados.id;
75
+ });
76
+ this.tags = tags;
77
+ this.removeFiltroSelecionado(evento.dados.id);
78
+ }
79
+ },
80
+ deep: true,
81
+ },
82
+ },
83
+ };
84
+ </script>
@@ -0,0 +1,115 @@
1
+ <template>
2
+ <div class="custom-escolher" :tabindex="tabindex" @blur="open = false">
3
+ <div class="selected" :class="{ open: open }" @click="open = !open">
4
+ {{ selected }}
5
+ </div>
6
+ <div class="items" :class="{ selectHide: !open }">
7
+ <div v-for="(option, i) of options" :key="i">
8
+ <div @click="selecionar(option)">
9
+ <span :class="option.classeCss">
10
+ <i :class="option.icone"></i>
11
+ <span> {{ option.label }}</span>
12
+ </span>
13
+ </div>
14
+ </div>
15
+ </div>
16
+ </div>
17
+ </template>
18
+
19
+ <script>
20
+ export default {
21
+ props: [
22
+ "options",
23
+ "tabindex",
24
+ "value",
25
+ ] /* {
26
+ options: {
27
+ type: Array,
28
+ required: true,
29
+ },
30
+ default: {
31
+ type: String,
32
+ required: false,
33
+ default: null,
34
+ },
35
+ tabindex: {
36
+ type: Number,
37
+ required: false,
38
+ default: 0,
39
+ },
40
+ value: Object,
41
+ },*/,
42
+ data() {
43
+ return {
44
+ selected: "Selecione os filtros",
45
+ open: false,
46
+ };
47
+ },
48
+ mounted() {
49
+ this.$emit("input", this.selected);
50
+ },
51
+ methods: {
52
+ selecionar(option) {
53
+ this.$emit("input", option);
54
+ this.selected = option.label;
55
+ this.open = false;
56
+ },
57
+ },
58
+ };
59
+ </script>
60
+
61
+ <style scoped>
62
+ .custom-escolher {
63
+ position: relative;
64
+ width: 100%;
65
+ text-align: left;
66
+ outline: none;
67
+ height: 40px;
68
+ line-height: 40px;
69
+ }
70
+
71
+ .custom-escolher .selected {
72
+ background-color: white;
73
+ border-bottom: 1px solid #dbdee0;
74
+ color: black;
75
+ padding-left: 1em;
76
+ cursor: pointer;
77
+ user-select: none;
78
+ }
79
+
80
+ .custom-escolher .selected:after {
81
+ position: absolute;
82
+ content: "";
83
+ top: 22px;
84
+ right: 1em;
85
+ width: 0;
86
+ height: 0;
87
+ border: 5px solid transparent;
88
+ border-color: black transparent transparent transparent;
89
+ }
90
+
91
+ .custom-escolher .items {
92
+ color: black;
93
+ border-radius: 0px 0px 6px 6px;
94
+ overflow: hidden;
95
+ position: absolute;
96
+ background-color: #fafafc;
97
+ left: 0;
98
+ right: 0;
99
+ z-index: 1;
100
+ height: 200px;
101
+ overflow-y: visible;
102
+ overflow-x: hidden;
103
+ }
104
+
105
+ .custom-escolher .items div {
106
+ color: black;
107
+ padding-left: 1em;
108
+ cursor: pointer;
109
+ user-select: none;
110
+ }
111
+
112
+ .selectHide {
113
+ display: none;
114
+ }
115
+ </style>
@@ -0,0 +1,46 @@
1
+ <template>
2
+ <div class="vqb-children">
3
+ <component
4
+ :is="getComponent(child.type)"
5
+ v-for="(child, index) in query.children"
6
+ :key="index"
7
+ :type="child.type"
8
+ :query.sync="child.query"
9
+ :rule-types="ruleTypes"
10
+ :rules="rules"
11
+ :rule="$parent.ruleById(child.query.rule)"
12
+ :index="index"
13
+ :max-depth="maxDepth"
14
+ :depth="depth + 1"
15
+ :labels="labels"
16
+ @child-deletion-requested="$parent.removeChild"
17
+ />
18
+ </div>
19
+ </template>
20
+
21
+ <script>
22
+ export default {
23
+ // eslint-disable-next-line vue/require-prop-types
24
+ props: ['query', 'ruleTypes', 'rules', 'maxDepth', 'labels', 'depth'],
25
+
26
+ data() {
27
+ return {
28
+ groupComponent: null,
29
+ ruleComponent: null
30
+ }
31
+ },
32
+
33
+ mounted() {
34
+ this.groupComponent = this.$parent.$options.components['QueryBuilderGroup'];
35
+ this.ruleComponent = this.$parent.$options.components['QueryBuilderRule'];
36
+ },
37
+
38
+ methods: {
39
+ getComponent(type) {
40
+ return type === 'query-builder-group'
41
+ ? this.groupComponent
42
+ : this.ruleComponent;
43
+ }
44
+ }
45
+ }
46
+ </script>
@@ -0,0 +1,151 @@
1
+ <template>
2
+ <div></div>
3
+ </template>
4
+
5
+ <script>
6
+ /* eslint-disable vue/require-default-prop */
7
+ import deepClone from "../utilities.js";
8
+ import QueryBuilderChildren from "./QueryBuilderChildren.vue";
9
+
10
+ import { mapMutations, mapGetters } from "vuex";
11
+
12
+ export default {
13
+ components: {
14
+ // eslint-disable-next-line vue/no-unused-components
15
+ QueryBuilderChildren,
16
+ },
17
+
18
+ props: {
19
+ ruleTypes: Object,
20
+ type: {
21
+ type: String,
22
+ default: "query-builder-group",
23
+ },
24
+ query: Object,
25
+ rules: Array,
26
+ index: Number,
27
+ maxDepth: Number,
28
+ depth: Number,
29
+ labels: Object,
30
+ },
31
+
32
+ data() {
33
+ return {
34
+ selectedRule: this.rules[0],
35
+ valida: [],
36
+ };
37
+ },
38
+ computed: {
39
+ ...mapGetters("generic", ["evento"]),
40
+ },
41
+ methods: {
42
+ ...mapMutations("generic", ["insereNotificacao"]),
43
+
44
+ ruleById(ruleId) {
45
+ var rule = null;
46
+
47
+ this.rules.forEach(function (value) {
48
+ if (value.id === ruleId) {
49
+ rule = value;
50
+ return false;
51
+ }
52
+ });
53
+
54
+ return rule;
55
+ },
56
+
57
+ addRule() {
58
+ let updated_query = deepClone(this.query);
59
+ let child = {
60
+ type: "query-builder-rule",
61
+ query: {
62
+ id: Math.random()
63
+ .toString(36)
64
+ .replace(/[^a-z]+/g, "")
65
+ .substr(0, 5),
66
+ obrigatorio: this.selectedRule.obrigatorio,
67
+ type: this.selectedRule.type,
68
+ choices: this.selectedRule.choices,
69
+ classeCss: this.selectedRule.classeCss,
70
+ valida: this.selectedRule.valida,
71
+ tipo: this.selectedRule.tipo,
72
+ label: this.selectedRule.label,
73
+ rule: this.selectedRule.id,
74
+ operator: this.selectedRule.operators[0],
75
+ operand:
76
+ typeof this.selectedRule.operands === "undefined"
77
+ ? this.selectedRule.label
78
+ : this.selectedRule.operands[0],
79
+ value: null,
80
+ },
81
+ };
82
+ // A bit hacky, but `v-model` on `select` requires an array.
83
+ if (this.ruleById(child.query.rule).type === "multi-select") {
84
+ child.query.value = [];
85
+ }
86
+
87
+ if (!this.jaExiste(child.query.rule)) {
88
+ updated_query.children.push(child);
89
+ if (child.query.valida) this.valida.push(child);
90
+ } else {
91
+ var erro = {
92
+ property: "ERRO QUERY BUILDER",
93
+ mensagem: `Não é possível adicionar o filtro ${child.query.label} 2 vezes!`,
94
+ };
95
+ this.insereNotificacao([erro]);
96
+ }
97
+
98
+ this.$emit("update:query", updated_query);
99
+ },
100
+
101
+ addGroup() {
102
+ let updated_query = deepClone(this.query);
103
+ if (this.depth < this.maxDepth) {
104
+ updated_query.children.push({
105
+ type: "query-builder-group",
106
+ query: {
107
+ logicalOperator: this.labels.matchTypes[0].id,
108
+ children: [],
109
+ },
110
+ });
111
+ this.$emit("update:query", updated_query);
112
+ }
113
+ },
114
+
115
+ remove() {
116
+ this.$emit("child-deletion-requested", this.index);
117
+ },
118
+
119
+ removeChild(index) {
120
+ this.valida.splice(this.valida.indexOf(index, 1));
121
+
122
+ let updated_query = deepClone(this.query);
123
+
124
+ updated_query.children.splice(index, 1);
125
+
126
+ this.$emit("update:query", updated_query);
127
+ },
128
+
129
+ jaExiste(chave) {
130
+ var existe = this.valida.find((value) => {
131
+ return value.query.rule === chave;
132
+ });
133
+ if (existe) return true;
134
+ return false;
135
+ },
136
+ },
137
+ watch: {
138
+ evento: {
139
+ handler(evento) {
140
+ if (evento.nome == "tagRemovida") {
141
+ var valida = this.valida.filter((x) => {
142
+ return x.query.id != evento.dados.id;
143
+ });
144
+ this.valida = valida;
145
+ }
146
+ },
147
+ deep: true,
148
+ },
149
+ },
150
+ };
151
+ </script>
@@ -0,0 +1,81 @@
1
+ <template>
2
+ <div></div>
3
+ </template>
4
+
5
+ <script>
6
+ import deepClone from "../utilities.js";
7
+
8
+ export default {
9
+ // eslint-disable-next-line vue/require-prop-types
10
+ props: ["query", "index", "rule", "labels", "depth"],
11
+
12
+ computed: {
13
+ isCustomComponent() {
14
+ return this.rule.type === "custom-component";
15
+ },
16
+
17
+ selectOptions() {
18
+ if (typeof this.rule.choices === "undefined") {
19
+ return {};
20
+ }
21
+
22
+ // Nest items to support <optgroup> if the rule's choices have
23
+ // defined groups. Otherwise just return a single-level array
24
+ return this.rule.choices.reduce(function (groups, item, index) {
25
+ let key = item["group"];
26
+ if (typeof key !== "undefined") {
27
+ groups[key] = groups[key] || [];
28
+ groups[key].push(item);
29
+ } else {
30
+ groups[index] = item;
31
+ }
32
+
33
+ return groups;
34
+ }, {});
35
+ },
36
+
37
+ hasOptionGroups() {
38
+ return this.selectOptions.length && Array.isArray(this.selectOptions[0]);
39
+ },
40
+ },
41
+
42
+ beforeMount() {
43
+ if (this.rule.type === "custom-component") {
44
+ this.$options.components[this.id] = this.rule.component;
45
+ }
46
+ },
47
+
48
+ mounted() {
49
+ let updated_query = deepClone(this.query);
50
+
51
+ // Set a default value for these types if one isn't provided already
52
+ if (this.query.value === null) {
53
+ if (this.rule.inputType === "checkbox") {
54
+ updated_query.value = [];
55
+ }
56
+ if (this.rule.type === "select") {
57
+ updated_query.value = this.rule.choices[0].value;
58
+ }
59
+ if (this.rule.type === "custom-component") {
60
+ updated_query.value = null;
61
+ if (typeof this.rule.default !== "undefined") {
62
+ updated_query.value = deepClone(this.rule.default);
63
+ }
64
+ }
65
+
66
+ this.$emit("update:query", updated_query);
67
+ }
68
+ },
69
+
70
+ methods: {
71
+ remove: function () {
72
+ this.$emit("child-deletion-requested", this.index);
73
+ },
74
+ updateQuery(value) {
75
+ let updated_query = deepClone(this.query);
76
+ updated_query.value = value;
77
+ this.$emit("update:query", updated_query);
78
+ },
79
+ },
80
+ };
81
+ </script>