@bildvitta/quasar-ui-asteroid 3.1.0 → 3.2.0-beta.0
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/api/QasTransfer.json +2 -1
- package/dist/api/QasTreeGenerator.json +89 -0
- package/dist/asteroid.cjs.css +1 -1
- package/dist/asteroid.cjs.js +2926 -2153
- package/dist/asteroid.cjs.min.js +2 -2
- package/dist/asteroid.esm.css +1 -1
- package/dist/asteroid.esm.js +2727 -1955
- package/dist/asteroid.esm.min.js +2 -2
- package/dist/asteroid.umd.css +1 -1
- package/dist/asteroid.umd.js +2728 -1956
- package/dist/asteroid.umd.min.js +2 -2
- package/dist/vetur/asteroid-attributes.json +56 -0
- package/dist/vetur/asteroid-tags.json +19 -0
- package/package.json +1 -1
- package/src/components/nested-fields/QasNestedFields.vue +9 -1
- package/src/components/transfer/QasTransfer.yml +1 -0
- package/src/components/tree-generator/QasTreeForm.vue +62 -0
- package/src/components/tree-generator/QasTreeGenerator.vue +488 -0
- package/src/components/tree-generator/QasTreeGenerator.yml +81 -0
- package/src/helpers/destroy-nested-children-by-key.js +33 -0
- package/src/helpers/find-children-by-key.js +14 -0
- package/src/helpers/index.js +4 -0
- package/src/helpers/promise-handler.js +37 -0
- package/src/helpers/rules.js +7 -0
- package/src/vue-plugin.js +3 -0
|
@@ -1247,6 +1247,62 @@
|
|
|
1247
1247
|
"description": "Nos options, você pode passar um array de objeto com qualquer chave/valor, esta prop serve para identificar qual será o equivalente ao \"value\".",
|
|
1248
1248
|
"type": "string"
|
|
1249
1249
|
},
|
|
1250
|
+
"qas-tree-generator/form-generator-props": {
|
|
1251
|
+
"description": "Propriedades enviadas para o \"QasFormGenerator\".",
|
|
1252
|
+
"type": "object"
|
|
1253
|
+
},
|
|
1254
|
+
"qas-tree-generator/form-view-props": {
|
|
1255
|
+
"description": "Propriedades enviadas para o \"QasFormView\".",
|
|
1256
|
+
"type": "object"
|
|
1257
|
+
},
|
|
1258
|
+
"qas-tree-generator/label-key": {
|
|
1259
|
+
"description": "Chave identificadora da label, por padrão o componente considera label, é possível alterar o valor enviado para API através desta chave.",
|
|
1260
|
+
"type": "string"
|
|
1261
|
+
},
|
|
1262
|
+
"qas-tree-generator/lazy-nodes": {
|
|
1263
|
+
"description": "Model do lazy, toda vez que é adicionado/editado/excluído um nó este model é atualizado, ele não é um \"two way data binding\" alterações fora do componente não afetarão o componente.",
|
|
1264
|
+
"type": "array"
|
|
1265
|
+
},
|
|
1266
|
+
"qas-tree-generator/nodes": {
|
|
1267
|
+
"description": "Nested de Array de objeto contendo label, uuid, lazy e children, é a propriedade responsável por montar a árvore, precisa ser enviado toda a árvore de uma vez.",
|
|
1268
|
+
"type": "array"
|
|
1269
|
+
},
|
|
1270
|
+
"qas-tree-generator/readonly": {
|
|
1271
|
+
"description": "Habilita a árvore para modo de visualização somente, não sendo possível adicionar/editar/remover nenhum ramo.",
|
|
1272
|
+
"type": "boolean"
|
|
1273
|
+
},
|
|
1274
|
+
"qas-tree-generator/resource": {
|
|
1275
|
+
"description": "Usado como endpoint da API para adicionar/remover/excluir, quando não utilizar o QasFormView.",
|
|
1276
|
+
"type": "string"
|
|
1277
|
+
},
|
|
1278
|
+
"qas-tree-generator/tree-props": {
|
|
1279
|
+
"description": "Propriedades enviada para o QTree.",
|
|
1280
|
+
"type": "object"
|
|
1281
|
+
},
|
|
1282
|
+
"qas-tree-generator/use-add-button": {
|
|
1283
|
+
"description": "Habilita o botão de adicionar novos ramos.",
|
|
1284
|
+
"type": "boolean"
|
|
1285
|
+
},
|
|
1286
|
+
"qas-tree-generator/use-destroy-button": {
|
|
1287
|
+
"description": "Habilita o botão de remover os ramos.",
|
|
1288
|
+
"type": "boolean"
|
|
1289
|
+
},
|
|
1290
|
+
"qas-tree-generator/use-destroy-on-first-node": {
|
|
1291
|
+
"description": "Habilita o botão de remover o primeiro ramo da árvore.",
|
|
1292
|
+
"type": "boolean"
|
|
1293
|
+
},
|
|
1294
|
+
"qas-tree-generator/use-edit-button": {
|
|
1295
|
+
"description": "Habilita o botão de editar os ramos.",
|
|
1296
|
+
"type": "boolean"
|
|
1297
|
+
},
|
|
1298
|
+
"qas-tree-generator/use-form-view-edit": {
|
|
1299
|
+
"description": "Habilita o form-view como componente a ser renderizado ao abrir o dialog em modo de edição.",
|
|
1300
|
+
"type": "boolean"
|
|
1301
|
+
},
|
|
1302
|
+
"qas-tree-generator/use-form-view-add": {
|
|
1303
|
+
"description": "Habilita o form-view como componente a ser renderizado ao abrir o dialog em modo de adição.",
|
|
1304
|
+
"type": "boolean"
|
|
1305
|
+
},
|
|
1250
1306
|
"qas-uploader/accept-resize-types": {
|
|
1251
1307
|
"description": "Tipos de arquivos aceitos para fazer o redimensionamento antes de upar.",
|
|
1252
1308
|
"type": "array"
|
|
@@ -545,6 +545,25 @@
|
|
|
545
545
|
],
|
|
546
546
|
"description": "Componente para transferir itens entre 2 lista (colunas)."
|
|
547
547
|
},
|
|
548
|
+
"qas-tree-generator": {
|
|
549
|
+
"attributes": [
|
|
550
|
+
"form-generator-props",
|
|
551
|
+
"form-view-props",
|
|
552
|
+
"label-key",
|
|
553
|
+
"lazy-nodes",
|
|
554
|
+
"nodes",
|
|
555
|
+
"readonly",
|
|
556
|
+
"resource",
|
|
557
|
+
"tree-props",
|
|
558
|
+
"use-add-button",
|
|
559
|
+
"use-destroy-button",
|
|
560
|
+
"use-destroy-on-first-node",
|
|
561
|
+
"use-edit-button",
|
|
562
|
+
"use-form-view-edit",
|
|
563
|
+
"use-form-view-add"
|
|
564
|
+
],
|
|
565
|
+
"description": "Componente de árvore onde é possível adicionar/editar/excluir sem limites de ramos."
|
|
566
|
+
},
|
|
548
567
|
"qas-uploader": {
|
|
549
568
|
"attributes": [
|
|
550
569
|
"accept-resize-types",
|
package/package.json
CHANGED
|
@@ -320,8 +320,16 @@ export default {
|
|
|
320
320
|
return this.$emit('update:modelValue', value || this.nested)
|
|
321
321
|
},
|
|
322
322
|
|
|
323
|
+
/*
|
|
324
|
+
* Se o item que for removido não tiver o identificador (uuid por ex) e "useRemoveOnDestroy" for "false"
|
|
325
|
+
* ou "useRemoveOnDestroy" for "true" removemos o item do array, senão adicionamos a flag [destroyKey]
|
|
326
|
+
* no item referente do array.
|
|
327
|
+
*
|
|
328
|
+
* Ex: ao adicionar um item e remover sem salvar, mesmo que useRemoveOnDestroy for false ele será removido
|
|
329
|
+
* ao invés de adicionar a flag [destroyKey]
|
|
330
|
+
*/
|
|
323
331
|
destroy (index, row) {
|
|
324
|
-
!row[this.identifierItemKey]
|
|
332
|
+
!row[this.identifierItemKey] || this.useRemoveOnDestroy
|
|
325
333
|
? this.nested.splice(index, 1)
|
|
326
334
|
: this.nested.splice(index, 1, { [this.destroyKey]: true, ...row })
|
|
327
335
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
* Este é um componente interno para ser utilizado dentro do componente "QasTreeGenerator"
|
|
3
|
+
* por isto não existe documentação para este componente e nem é exportado para fora do asteroid
|
|
4
|
+
-->
|
|
5
|
+
<template>
|
|
6
|
+
<qas-form-view ref="formView" v-model="values" v-model:errors="errors" v-model:fields="fields" :use-actions="false" :use-boundary="false" v-bind="formViewProps">
|
|
7
|
+
<template #default>
|
|
8
|
+
<qas-form-generator v-model="values" :errors="errors" :fields="fields" v-bind="formGeneratorProps" />
|
|
9
|
+
</template>
|
|
10
|
+
</qas-form-view>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script>
|
|
14
|
+
import QasFormGenerator from '../form-generator/QasFormGenerator.vue'
|
|
15
|
+
import QasFormView from '../form-view/QasFormView.vue'
|
|
16
|
+
|
|
17
|
+
export default {
|
|
18
|
+
name: 'QasTreeForm',
|
|
19
|
+
|
|
20
|
+
components: {
|
|
21
|
+
QasFormGenerator,
|
|
22
|
+
QasFormView
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
props: {
|
|
26
|
+
formGeneratorProps: {
|
|
27
|
+
type: Object,
|
|
28
|
+
default: () => ({})
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
formViewProps: {
|
|
32
|
+
type: Object,
|
|
33
|
+
default: () => ({})
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
parent: {
|
|
37
|
+
type: String,
|
|
38
|
+
default: ''
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
data () {
|
|
43
|
+
return {
|
|
44
|
+
errors: {},
|
|
45
|
+
fields: {},
|
|
46
|
+
values: {}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
watch: {
|
|
51
|
+
parent (parent) {
|
|
52
|
+
Object.assign(this.values, { parent })
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
methods: {
|
|
57
|
+
submit () {
|
|
58
|
+
return this.$refs.formView.submitHandler()
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
</script>
|
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="qas-tree-generator">
|
|
3
|
+
<q-tree ref="tree" v-bind="treeProps" node-key="uuid" :nodes="parsedNodes" @lazy-load="onLazyLoad">
|
|
4
|
+
<template #default-header="{ node, tree }">
|
|
5
|
+
<div>
|
|
6
|
+
<span>
|
|
7
|
+
{{ node.label }}
|
|
8
|
+
</span>
|
|
9
|
+
|
|
10
|
+
<span v-if="hasMenuButton(node)" class="q-ml-sm">
|
|
11
|
+
<qas-btn dense flat icon="o_more_vert" round @click.stop>
|
|
12
|
+
<q-menu auto-close>
|
|
13
|
+
<q-list separator>
|
|
14
|
+
<q-item v-if="useAddButton" v-ripple class="qas-tree-generator__item" clickable @click="handleTreeFormDialog(node, true, tree)">
|
|
15
|
+
<q-item-section avatar>
|
|
16
|
+
<q-icon name="o_add_circle_outline" />
|
|
17
|
+
</q-item-section>
|
|
18
|
+
|
|
19
|
+
<q-item-section>Adicionar subnível</q-item-section>
|
|
20
|
+
</q-item>
|
|
21
|
+
|
|
22
|
+
<q-item v-if="useEditButton" v-ripple class="qas-tree-generator__item" clickable @click="handleTreeFormDialog(node)">
|
|
23
|
+
<q-item-section avatar>
|
|
24
|
+
<q-icon name="o_edit" />
|
|
25
|
+
</q-item-section>
|
|
26
|
+
|
|
27
|
+
<q-item-section>Editar</q-item-section>
|
|
28
|
+
</q-item>
|
|
29
|
+
|
|
30
|
+
<q-item v-if="hasDestroyButton(node)" v-ripple class="qas-tree-generator__item" clickable @click="onDestroy(node)">
|
|
31
|
+
<q-item-section avatar>
|
|
32
|
+
<q-icon name="o_highlight_off" />
|
|
33
|
+
</q-item-section>
|
|
34
|
+
|
|
35
|
+
<q-item-section>Excluir</q-item-section>
|
|
36
|
+
</q-item>
|
|
37
|
+
</q-list>
|
|
38
|
+
</q-menu>
|
|
39
|
+
</qas-btn>
|
|
40
|
+
</span>
|
|
41
|
+
</div>
|
|
42
|
+
</template>
|
|
43
|
+
</q-tree>
|
|
44
|
+
|
|
45
|
+
<qas-dialog v-model="showDestroyDialog" v-bind="destroyDialogConfig" />
|
|
46
|
+
|
|
47
|
+
<qas-dialog v-model="showFormDialog" v-bind="formDialogConfig" use-form @hide="resetModels" @validate="onValidate">
|
|
48
|
+
<template #description>
|
|
49
|
+
<div>
|
|
50
|
+
<qas-field v-if="hasAddField" v-model="editModel" :disable="isAdd" :field="addField" :label="nodeTitle" :rules="[required]" />
|
|
51
|
+
|
|
52
|
+
<qas-nested-fields v-if="hasNestedAdd" v-model="nestedModel" class="q-mt-md" :field="nestedFieldProp" :fields-props="fieldsProps" :form-columns="nestedColumns" :row-object="rowObject" :use-duplicate="false" use-inline-actions />
|
|
53
|
+
|
|
54
|
+
<qas-tree-form v-if="hasFormView" ref="treeForm" v-model:submitting="isSubmitting" :form-generator-props="formGeneratorProps" :form-view-props="defaultFormViewProps" @submit-success="onSubmitSuccess" />
|
|
55
|
+
</div>
|
|
56
|
+
</template>
|
|
57
|
+
</qas-dialog>
|
|
58
|
+
</div>
|
|
59
|
+
</template>
|
|
60
|
+
|
|
61
|
+
<script>
|
|
62
|
+
import destroyNestedChildrenByKey from '../../helpers/destroy-nested-children-by-key.js'
|
|
63
|
+
import findChildrenByKey from '../../helpers/find-children-by-key.js'
|
|
64
|
+
import promiseHandler from '../../helpers/promise-handler.js'
|
|
65
|
+
import { required } from '../../helpers/rules.js'
|
|
66
|
+
import { extend } from 'quasar'
|
|
67
|
+
import axios from 'axios'
|
|
68
|
+
|
|
69
|
+
import QasTreeForm from './QasTreeForm.vue'
|
|
70
|
+
|
|
71
|
+
export default {
|
|
72
|
+
name: 'QasTreeGenerator',
|
|
73
|
+
|
|
74
|
+
components: {
|
|
75
|
+
QasTreeForm
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
props: {
|
|
79
|
+
formGeneratorProps: {
|
|
80
|
+
type: Object,
|
|
81
|
+
default: () => ({})
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
formViewProps: {
|
|
85
|
+
type: Object,
|
|
86
|
+
default: () => ({})
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
labelKey: {
|
|
90
|
+
type: String,
|
|
91
|
+
default: 'name'
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
lazyNodes: {
|
|
95
|
+
type: Array,
|
|
96
|
+
default: () => []
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
nodes: {
|
|
100
|
+
type: Array,
|
|
101
|
+
default: () => []
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
readonly: {
|
|
105
|
+
type: Boolean
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
resource: {
|
|
109
|
+
type: String,
|
|
110
|
+
default: ''
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
treeProps: {
|
|
114
|
+
type: Object,
|
|
115
|
+
default: () => ({})
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
useAddButton: {
|
|
119
|
+
type: Boolean,
|
|
120
|
+
default: true
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
useDestroyButton: {
|
|
124
|
+
type: Boolean,
|
|
125
|
+
default: true
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
useDestroyOnFirstNode: {
|
|
129
|
+
type: Boolean
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
useEditButton: {
|
|
133
|
+
type: Boolean,
|
|
134
|
+
default: true
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
useFormViewEdit: {
|
|
138
|
+
type: Boolean
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
useFormViewAdd: {
|
|
142
|
+
type: Boolean
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
emits: [
|
|
147
|
+
'update:lazyNodes'
|
|
148
|
+
],
|
|
149
|
+
|
|
150
|
+
data () {
|
|
151
|
+
return {
|
|
152
|
+
showDestroyDialog: false,
|
|
153
|
+
currentNode: {},
|
|
154
|
+
showFormDialog: false,
|
|
155
|
+
nestedModel: [],
|
|
156
|
+
singleModel: { label: '' },
|
|
157
|
+
editModel: '',
|
|
158
|
+
isAdd: true,
|
|
159
|
+
parsedNodes: [],
|
|
160
|
+
isSubmitting: false
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
computed: {
|
|
165
|
+
addField () {
|
|
166
|
+
return { name: 'add', type: 'text', label: this.nodeTitle }
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
destroyDialogConfig () {
|
|
170
|
+
return {
|
|
171
|
+
card: {
|
|
172
|
+
title: 'Excluir ramo da árvore?',
|
|
173
|
+
description: 'Todas as informações serão perdidas. Deseja realmente continuar?'
|
|
174
|
+
},
|
|
175
|
+
ok: {
|
|
176
|
+
label: 'Excluir',
|
|
177
|
+
onClick: this.destroy
|
|
178
|
+
},
|
|
179
|
+
cancel: {
|
|
180
|
+
onClick: this.resetCurrentNode
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
formDialogConfig () {
|
|
186
|
+
return {
|
|
187
|
+
card: {
|
|
188
|
+
title: this.isAdd ? 'Adicionar ramo' : 'Editar ramo'
|
|
189
|
+
},
|
|
190
|
+
ok: {
|
|
191
|
+
label: 'Salvar',
|
|
192
|
+
loading: this.isSubmitting
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
nestedFieldProp () {
|
|
198
|
+
return {
|
|
199
|
+
type: 'nested',
|
|
200
|
+
label: 'Adicionar itens',
|
|
201
|
+
name: 'nested',
|
|
202
|
+
children: {
|
|
203
|
+
label: {
|
|
204
|
+
type: 'text',
|
|
205
|
+
label: 'Adicionar um novo item',
|
|
206
|
+
name: 'label'
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
rowObject () {
|
|
213
|
+
return { label: '' }
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
nestedColumns () {
|
|
217
|
+
return {
|
|
218
|
+
label: {
|
|
219
|
+
col: 12
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
nodeTitle () {
|
|
225
|
+
if (!this.isAdd) {
|
|
226
|
+
return 'Nome do ramo'
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return this.currentNode.label || 'ramo'
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
fieldsProps () {
|
|
233
|
+
return {
|
|
234
|
+
label: {
|
|
235
|
+
rules: [required]
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
|
|
240
|
+
messages () {
|
|
241
|
+
return {
|
|
242
|
+
error: 'Ops! Erro ao salvar item.',
|
|
243
|
+
success: 'Item salvo com sucesso!'
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
|
|
247
|
+
defaultFormViewProps () {
|
|
248
|
+
return {
|
|
249
|
+
...this.formViewProps,
|
|
250
|
+
...(!this.isAdd && { customId: this.currentNode.uuid }),
|
|
251
|
+
...(this.isAdd && { parent: this.currentNode.uuid }),
|
|
252
|
+
mode: this.isAdd ? 'create' : 'replace'
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
hasAddField () {
|
|
257
|
+
return this.isAdd || !this.hasFormView
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
hasNestedAdd () {
|
|
261
|
+
return (!this.hasFormView || !this.useFormViewAdd) && this.isAdd
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
hasFormView () {
|
|
265
|
+
return this.isAdd ? this.useFormViewAdd : this.useFormViewEdit
|
|
266
|
+
},
|
|
267
|
+
|
|
268
|
+
parentsList () {
|
|
269
|
+
return this.nodes.map(({ uuid }) => uuid)
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
watch: {
|
|
274
|
+
nodes: {
|
|
275
|
+
handler () {
|
|
276
|
+
this.setInitialValue()
|
|
277
|
+
},
|
|
278
|
+
immediate: true,
|
|
279
|
+
deep: true
|
|
280
|
+
},
|
|
281
|
+
|
|
282
|
+
parsedNodes: {
|
|
283
|
+
handler (nodes) {
|
|
284
|
+
this.$emit('update:lazyNodes', nodes)
|
|
285
|
+
},
|
|
286
|
+
immediate: true,
|
|
287
|
+
deep: true
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
|
|
291
|
+
methods: {
|
|
292
|
+
required,
|
|
293
|
+
|
|
294
|
+
handleTreeFormDialog (node, isAdd) {
|
|
295
|
+
this.showFormDialog = !this.showFormDialog
|
|
296
|
+
this.isAdd = !!isAdd
|
|
297
|
+
this.currentNode = node
|
|
298
|
+
|
|
299
|
+
if (!this.isAdd) {
|
|
300
|
+
this.editModel = node.label
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
|
|
304
|
+
async add () {
|
|
305
|
+
const { data, error } = await promiseHandler(
|
|
306
|
+
this.nestedModel.map(({ label }) => {
|
|
307
|
+
return axios.post(this.resource, { parent: this.currentNode.uuid, [this.labelKey]: label, lazy: true })
|
|
308
|
+
}),
|
|
309
|
+
{
|
|
310
|
+
successMessage: this.messages.success,
|
|
311
|
+
errorMessage: this.messages.error
|
|
312
|
+
}
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
if (error) return
|
|
316
|
+
|
|
317
|
+
const nestedResponse = data.map(response => {
|
|
318
|
+
const { result } = response.data
|
|
319
|
+
const { name, uuid } = result
|
|
320
|
+
|
|
321
|
+
return {
|
|
322
|
+
label: name,
|
|
323
|
+
lazy: true,
|
|
324
|
+
uuid
|
|
325
|
+
}
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
// Precisa abrir antes de adicionar para casos de ramos que ainda não foram abertos.
|
|
329
|
+
this.$refs.tree.setExpanded(this.currentNode.uuid, true)
|
|
330
|
+
|
|
331
|
+
if (this.currentNode.children) {
|
|
332
|
+
this.currentNode.children.push(...nestedResponse)
|
|
333
|
+
} else {
|
|
334
|
+
this.currentNode.children = [...nestedResponse]
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
this.$nextTick(() => this.$refs.tree.setExpanded(this.currentNode.uuid, true))
|
|
338
|
+
},
|
|
339
|
+
|
|
340
|
+
async edit () {
|
|
341
|
+
const { uuid } = this.currentNode
|
|
342
|
+
|
|
343
|
+
const { error } = await promiseHandler(
|
|
344
|
+
axios.put(
|
|
345
|
+
`${this.resource}/${uuid}`,
|
|
346
|
+
{
|
|
347
|
+
[this.labelKey]: this.editModel,
|
|
348
|
+
uuid,
|
|
349
|
+
lazy: true
|
|
350
|
+
}
|
|
351
|
+
),
|
|
352
|
+
{
|
|
353
|
+
successMessage: this.messages.success,
|
|
354
|
+
errorMessage: this.messages.error
|
|
355
|
+
}
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
if (error) return
|
|
359
|
+
|
|
360
|
+
this.currentNode.label = this.editModel
|
|
361
|
+
this.$refs.tree.setExpanded(uuid, true)
|
|
362
|
+
},
|
|
363
|
+
|
|
364
|
+
onDestroy (children) {
|
|
365
|
+
this.showDestroyDialog = !this.showDestroyDialog
|
|
366
|
+
this.currentNode = children
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
async destroy () {
|
|
370
|
+
const { error } = await promiseHandler(
|
|
371
|
+
axios.delete(`${this.resource}/${this.currentNode.uuid}`),
|
|
372
|
+
{
|
|
373
|
+
successMessage: 'Item deletado com sucesso!',
|
|
374
|
+
errorMessage: 'Ops! Não foi possível deletar o item.'
|
|
375
|
+
}
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
if (error) return
|
|
379
|
+
|
|
380
|
+
this.currentNode.destroyed = true
|
|
381
|
+
destroyNestedChildrenByKey(this.parsedNodes)
|
|
382
|
+
},
|
|
383
|
+
|
|
384
|
+
resetCurrentNode () {
|
|
385
|
+
this.currentNode = {}
|
|
386
|
+
},
|
|
387
|
+
|
|
388
|
+
resetModels () {
|
|
389
|
+
this.nestedModel = [{ label: '' }]
|
|
390
|
+
this.singleModel = {}
|
|
391
|
+
this.editModel = ''
|
|
392
|
+
},
|
|
393
|
+
|
|
394
|
+
async onValidate (isValid) {
|
|
395
|
+
if (isValid) {
|
|
396
|
+
const canUseFormViewOnAdd = this.isAdd && this.useFormViewAdd
|
|
397
|
+
const canUseFormViewOnEdit = !this.isAdd && this.useFormViewEdit
|
|
398
|
+
|
|
399
|
+
if (canUseFormViewOnAdd || canUseFormViewOnEdit) {
|
|
400
|
+
this.$refs.treeForm.submit()
|
|
401
|
+
return
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// espera requisição finalizar para poder adicionar/editar
|
|
405
|
+
this.isAdd ? await this.add() : await this.edit()
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
this.showFormDialog = !isValid
|
|
409
|
+
},
|
|
410
|
+
|
|
411
|
+
/*
|
|
412
|
+
* neste método pode ser implementado uma logica para receber os nós da árvore parcialmente
|
|
413
|
+
* utilizando chamadas de API.
|
|
414
|
+
*/
|
|
415
|
+
onLazyLoad ({ key, done }) {
|
|
416
|
+
// retorna um proximo nó caso exista.
|
|
417
|
+
return done(this.findNextNode(this.nodes, key, true) || [])
|
|
418
|
+
},
|
|
419
|
+
|
|
420
|
+
setInitialValue () {
|
|
421
|
+
const { children, ...payload } = { ...this.nodes?.[0] }
|
|
422
|
+
this.parsedNodes = Object.keys(payload).length ? [payload] : []
|
|
423
|
+
},
|
|
424
|
+
|
|
425
|
+
findNextNode (list, key, deleteMode) {
|
|
426
|
+
const children = findChildrenByKey(list, 'uuid', key)?.children
|
|
427
|
+
|
|
428
|
+
if (!children?.length) return []
|
|
429
|
+
|
|
430
|
+
// retorna um proximo nó caso exista.
|
|
431
|
+
return (extend(true, [], children).map(item => {
|
|
432
|
+
if (deleteMode) {
|
|
433
|
+
delete item.children
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
return item
|
|
437
|
+
}))
|
|
438
|
+
},
|
|
439
|
+
|
|
440
|
+
onSubmitSuccess (response) {
|
|
441
|
+
const { data: { result } } = response
|
|
442
|
+
|
|
443
|
+
this.currentNode.label = result[this.labelKey]
|
|
444
|
+
this.showFormDialog = false
|
|
445
|
+
},
|
|
446
|
+
|
|
447
|
+
hasDestroyButton ({ uuid }) {
|
|
448
|
+
if (!this.useDestroyButton) return false
|
|
449
|
+
|
|
450
|
+
return !this.useDestroyOnFirstNode ? !this.parentsList.includes(uuid) : true
|
|
451
|
+
},
|
|
452
|
+
|
|
453
|
+
hasMenuButton (node) {
|
|
454
|
+
if (this.readonly) return false
|
|
455
|
+
|
|
456
|
+
const hasEditOrAddButton = this.useAddButton || this.useEditButton
|
|
457
|
+
|
|
458
|
+
if (!this.useDestroyOnFirstNode) {
|
|
459
|
+
const hasDestroyButton = this.hasDestroyButton(node)
|
|
460
|
+
|
|
461
|
+
return hasEditOrAddButton || hasDestroyButton
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
return hasEditOrAddButton || this.useDestroyButton
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
</script>
|
|
469
|
+
|
|
470
|
+
<style lang="scss">
|
|
471
|
+
.qas-tree-generator {
|
|
472
|
+
&__item:hover {
|
|
473
|
+
color: var(--q-primary);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.q-tree__node-header {
|
|
477
|
+
margin-top: 16px;
|
|
478
|
+
|
|
479
|
+
&::before {
|
|
480
|
+
top: -16px;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
&::after {
|
|
484
|
+
top: -16px;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
</style>
|