@bildvitta/quasar-ui-asteroid 3.12.0 → 3.13.0-beta.1
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/package.json +1 -1
- package/src/components/app-user/QasAppUser.vue +2 -2
- package/src/components/dialog/QasDialog.vue +65 -18
- package/src/components/dialog/QasDialog.yml +7 -0
- package/src/components/form-view/QasFormView.vue +12 -5
- package/src/components/form-view/QasFormView.yml +28 -4
- package/src/components/infinite-scroll/QasInfiniteScroll.vue +165 -0
- package/src/components/infinite-scroll/QasInfiniteScroll.yml +49 -0
- package/src/components/tabs-generator/QasTabsGenerator.vue +10 -2
- package/src/components/tabs-generator/QasTabsGenerator.yml +5 -0
- package/src/vue-plugin.js +3 -0
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="cursor-pointer items-center no-wrap q-gutter-sm qas-app-user row">
|
|
2
|
+
<div class="cursor-pointer items-center no-wrap q-gutter-sm qas-app-user row" data-cy="app-user">
|
|
3
3
|
<div class="relative-position">
|
|
4
4
|
<qas-avatar :image="user.photo" :size="avatarSize" :title="userName" />
|
|
5
5
|
<q-badge v-if="hasNotifications" color="red" floating>{{ notifications.count }}</q-badge>
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<div class="ellipsis qas-app-user__menu-name">{{ userName }}</div>
|
|
18
18
|
<div class="ellipsis">{{ user.email }}</div>
|
|
19
19
|
|
|
20
|
-
<qas-select v-if="hasCompaniesSelect" v-model="companiesModel" class="q-my-md" label="Vínculo" :loading="loading" :options="companiesOptions" @update:model-value="setCompanies" />
|
|
20
|
+
<qas-select v-if="hasCompaniesSelect" v-model="companiesModel" class="q-my-md" data-cy="app-user-companies-select" label="Vínculo" :loading="loading" :options="companiesOptions" @update:model-value="setCompanies" />
|
|
21
21
|
|
|
22
22
|
<q-list class="q-mt-md">
|
|
23
23
|
<q-item v-close-popup :active="false" class="qas-app-user__menu-item" clickable :to="user.to">
|
|
@@ -12,26 +12,26 @@
|
|
|
12
12
|
</header>
|
|
13
13
|
|
|
14
14
|
<section class="text-body1 text-grey-8">
|
|
15
|
-
<component :is="componentTag" ref="form">
|
|
15
|
+
<component :is="componentTag" ref="form" v-bind="componentProps">
|
|
16
16
|
<slot name="description">
|
|
17
17
|
<component :is="descriptionComponentTag">{{ card.description }}</component>
|
|
18
18
|
</slot>
|
|
19
|
+
|
|
20
|
+
<div v-if="!isInfoDialog">
|
|
21
|
+
<slot name="actions">
|
|
22
|
+
<qas-actions v-bind="formattedActionsProps">
|
|
23
|
+
<template v-if="hasOk" #primary>
|
|
24
|
+
<qas-btn v-close-popup="!useForm" class="full-width" variant="primary" v-bind="defaultOk" />
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<template v-if="hasCancel" #secondary>
|
|
28
|
+
<qas-btn v-close-popup class="full-width" v-bind="defaultCancel" variant="secondary" />
|
|
29
|
+
</template>
|
|
30
|
+
</qas-actions>
|
|
31
|
+
</slot>
|
|
32
|
+
</div>
|
|
19
33
|
</component>
|
|
20
34
|
</section>
|
|
21
|
-
|
|
22
|
-
<footer v-if="!isInfoDialog">
|
|
23
|
-
<slot name="actions">
|
|
24
|
-
<qas-actions v-bind="formattedActionsProps">
|
|
25
|
-
<template v-if="hasOk" #primary>
|
|
26
|
-
<qas-btn v-close-popup="!useForm" class="full-width" variant="primary" v-bind="defaultOk" @click="submitHandler" />
|
|
27
|
-
</template>
|
|
28
|
-
|
|
29
|
-
<template v-if="hasCancel" #secondary>
|
|
30
|
-
<qas-btn v-close-popup class="full-width" v-bind="defaultCancel" variant="secondary" />
|
|
31
|
-
</template>
|
|
32
|
-
</qas-actions>
|
|
33
|
-
</slot>
|
|
34
|
-
</footer>
|
|
35
35
|
</div>
|
|
36
36
|
</q-dialog>
|
|
37
37
|
</template>
|
|
@@ -106,8 +106,13 @@ export default {
|
|
|
106
106
|
},
|
|
107
107
|
|
|
108
108
|
emits: [
|
|
109
|
+
// model
|
|
109
110
|
'update:modelValue',
|
|
110
|
-
|
|
111
|
+
|
|
112
|
+
// actions
|
|
113
|
+
'validate',
|
|
114
|
+
'ok',
|
|
115
|
+
'cancel'
|
|
111
116
|
],
|
|
112
117
|
|
|
113
118
|
computed: {
|
|
@@ -115,15 +120,24 @@ export default {
|
|
|
115
120
|
return {
|
|
116
121
|
label: 'Cancelar',
|
|
117
122
|
outline: true,
|
|
118
|
-
|
|
123
|
+
|
|
124
|
+
...this.cancel,
|
|
125
|
+
|
|
126
|
+
onClick: this.onCancel
|
|
119
127
|
}
|
|
120
128
|
},
|
|
121
129
|
|
|
122
130
|
defaultOk () {
|
|
131
|
+
const { onClick, ...attrs } = this.ok
|
|
132
|
+
|
|
123
133
|
return {
|
|
124
134
|
label: 'Ok',
|
|
125
135
|
type: this.ok?.type || this.useForm ? 'submit' : 'button',
|
|
126
|
-
|
|
136
|
+
|
|
137
|
+
...attrs,
|
|
138
|
+
|
|
139
|
+
// adiciona somente se não estiver usando useForm pois o controle ficará no submit.
|
|
140
|
+
...(!this.useForm && { onClick: this.onOk })
|
|
127
141
|
}
|
|
128
142
|
},
|
|
129
143
|
|
|
@@ -139,6 +153,16 @@ export default {
|
|
|
139
153
|
return this.useForm ? 'q-form' : 'div'
|
|
140
154
|
},
|
|
141
155
|
|
|
156
|
+
componentProps () {
|
|
157
|
+
/**
|
|
158
|
+
* adiciona evento de submit caso useForm seja true,
|
|
159
|
+
* uma vez que somente o q-form possui este evento.
|
|
160
|
+
*/
|
|
161
|
+
return {
|
|
162
|
+
...(this.useForm && { onSubmit: this.onSubmit })
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
|
|
142
166
|
dialogProps () {
|
|
143
167
|
return {
|
|
144
168
|
...(!this.usePlugin && { modelValue: this.modelValue }),
|
|
@@ -235,6 +259,29 @@ export default {
|
|
|
235
259
|
|
|
236
260
|
updateModelValue (value) {
|
|
237
261
|
this.$emit('update:modelValue', value)
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
onOk () {
|
|
265
|
+
this.ok?.onClick?.()
|
|
266
|
+
this.$emit('ok')
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
onCancel () {
|
|
270
|
+
this.cancel?.onClick?.()
|
|
271
|
+
this.$emit('cancel')
|
|
272
|
+
},
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Sem este método, ao clicar enter com a prop useForm ativada a tela era recarregada,
|
|
276
|
+
* e a ação de click do botão não era chamada pois ele não esta dentro do form.
|
|
277
|
+
*/
|
|
278
|
+
onSubmit (event) {
|
|
279
|
+
event.preventDefault()
|
|
280
|
+
|
|
281
|
+
if (this.hasOk) {
|
|
282
|
+
this.onOk()
|
|
283
|
+
this.submitHandler()
|
|
284
|
+
}
|
|
238
285
|
}
|
|
239
286
|
}
|
|
240
287
|
}
|
|
@@ -83,3 +83,10 @@ events:
|
|
|
83
83
|
value:
|
|
84
84
|
desc: Retorna se os campos passou ou não na validação
|
|
85
85
|
type: Boolean
|
|
86
|
+
|
|
87
|
+
'@cancel: -> function ()':
|
|
88
|
+
desc: Dispara toda vez que é clicado no botão "cancel".
|
|
89
|
+
|
|
90
|
+
'@ok: -> function ()':
|
|
91
|
+
desc: Dispara toda vez que é clicado no botão "ok" ou quando useForm for true e o for clicado "enter" estando com foco em algum input (evento de submit).
|
|
92
|
+
|
|
@@ -213,6 +213,10 @@ export default {
|
|
|
213
213
|
watch: {
|
|
214
214
|
isSubmitting (value) {
|
|
215
215
|
this.$emit('update:submitting', value)
|
|
216
|
+
},
|
|
217
|
+
|
|
218
|
+
'$route.path' () {
|
|
219
|
+
this.ignoreRouterGuard = false
|
|
216
220
|
}
|
|
217
221
|
},
|
|
218
222
|
|
|
@@ -374,10 +378,9 @@ export default {
|
|
|
374
378
|
if (!this.ignoreKeysInUnsavedChanges.length) return
|
|
375
379
|
|
|
376
380
|
this.ignoreKeysInUnsavedChanges.forEach(key => {
|
|
377
|
-
if (
|
|
381
|
+
if (firstValue) delete firstValue[key]
|
|
378
382
|
|
|
379
|
-
delete
|
|
380
|
-
delete secondValue[key]
|
|
383
|
+
if (secondValue) delete secondValue[key]
|
|
381
384
|
})
|
|
382
385
|
},
|
|
383
386
|
|
|
@@ -426,14 +429,16 @@ export default {
|
|
|
426
429
|
payload
|
|
427
430
|
})
|
|
428
431
|
|
|
432
|
+
const modelValue = { ...this.modelValue, ...response.data.result }
|
|
433
|
+
|
|
429
434
|
if (this.useDialogOnUnsavedChanges) {
|
|
430
|
-
this.cachedResult = extend(true, {},
|
|
435
|
+
this.cachedResult = extend(true, {}, modelValue)
|
|
431
436
|
}
|
|
432
437
|
|
|
433
438
|
this.mx_setErrors()
|
|
434
439
|
this.$emit('update:errors', this.mx_errors)
|
|
435
440
|
|
|
436
|
-
|
|
441
|
+
this.$emit('update:modelValue', modelValue)
|
|
437
442
|
this.$emit('submit-success', response, this.modelValue)
|
|
438
443
|
|
|
439
444
|
this.createSubmitSuccessEvent({ ...payload, entity: this.entity })
|
|
@@ -441,6 +446,8 @@ export default {
|
|
|
441
446
|
this.$qas.logger.group(
|
|
442
447
|
`QasFormView - submit -> resposta da action ${this.entity}/${this.mode}`, [response]
|
|
443
448
|
)
|
|
449
|
+
|
|
450
|
+
NotifySuccess(response.data.status.text || this.defaultNotifyMessages.success)
|
|
444
451
|
} catch (error) {
|
|
445
452
|
const errors = error?.response?.data?.errors
|
|
446
453
|
const message = error?.response?.data?.status?.text
|
|
@@ -157,17 +157,21 @@ slots:
|
|
|
157
157
|
desc: Slot para acessar o header.
|
|
158
158
|
|
|
159
159
|
events:
|
|
160
|
-
'@fetch-success -> function(
|
|
160
|
+
'@fetch-success -> function(response, modelValue)':
|
|
161
161
|
desc: Dispara quando a action "fetchSingle" é executada com sucesso.
|
|
162
162
|
params:
|
|
163
|
-
|
|
163
|
+
response:
|
|
164
164
|
desc: Retorna todos os dados "cru" respondido pelo fetch.
|
|
165
165
|
type: Object
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
modelValue:
|
|
168
|
+
desc: Retorna o model anterior ao fetch.
|
|
169
|
+
type: Object
|
|
170
|
+
|
|
171
|
+
'@fetch-error -> function(error)':
|
|
168
172
|
desc: Dispara quando a action "fetchSingle" cai em uma exceção.
|
|
169
173
|
params:
|
|
170
|
-
|
|
174
|
+
error:
|
|
171
175
|
desc: Retorna todos os dados "cru" respondido na exceção do fetch.
|
|
172
176
|
type: Object
|
|
173
177
|
|
|
@@ -212,3 +216,23 @@ events:
|
|
|
212
216
|
value:
|
|
213
217
|
desc: Retorna se está ou não fazendo fetching de dados.
|
|
214
218
|
type: Boolean
|
|
219
|
+
|
|
220
|
+
'@submit-success -> function(response, modelValue)':
|
|
221
|
+
desc: Dispara quando a action "submit" é executada com sucesso.
|
|
222
|
+
params:
|
|
223
|
+
response:
|
|
224
|
+
desc: Retorna todos os dados "cru" respondido pelo submit.
|
|
225
|
+
type: Object
|
|
226
|
+
|
|
227
|
+
modelValue:
|
|
228
|
+
desc: Retorna o model anterior ao submit.
|
|
229
|
+
type: Object
|
|
230
|
+
|
|
231
|
+
'@submit-error -> function(error)':
|
|
232
|
+
desc: Dispara quando a action "submit" cai em uma exceção.
|
|
233
|
+
params:
|
|
234
|
+
error:
|
|
235
|
+
desc: Retorna todos os dados "cru" respondido na exceção do submit.
|
|
236
|
+
type: Object
|
|
237
|
+
|
|
238
|
+
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="qas-infinite-scroll" :style="containerStyle">
|
|
3
|
+
<q-infinite-scroll
|
|
4
|
+
ref="infiniteScroll"
|
|
5
|
+
v-bind="attributes"
|
|
6
|
+
@load="onLoad"
|
|
7
|
+
>
|
|
8
|
+
<slot />
|
|
9
|
+
|
|
10
|
+
<template #loading>
|
|
11
|
+
<div class="justify-center q-my-md row">
|
|
12
|
+
<q-spinner-dots
|
|
13
|
+
color="primary"
|
|
14
|
+
size="3em"
|
|
15
|
+
/>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
</q-infinite-scroll>
|
|
19
|
+
|
|
20
|
+
<qas-empty-result-text v-if="hasNoResults" />
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script setup>
|
|
25
|
+
import { ref, computed, inject, nextTick } from 'vue'
|
|
26
|
+
import { NotifyError } from '../../plugins'
|
|
27
|
+
|
|
28
|
+
defineOptions({ name: 'QasInfiniteScroll' })
|
|
29
|
+
|
|
30
|
+
const props = defineProps({
|
|
31
|
+
list: {
|
|
32
|
+
type: Array,
|
|
33
|
+
default: () => []
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
limitPerPage: {
|
|
37
|
+
type: Number,
|
|
38
|
+
default: 12
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
url: {
|
|
42
|
+
type: String,
|
|
43
|
+
default: '',
|
|
44
|
+
required: true
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
params: {
|
|
48
|
+
type: Object,
|
|
49
|
+
default: () => ({})
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
infiniteScrollProps: {
|
|
53
|
+
type: Object,
|
|
54
|
+
default: () => ({})
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
maxHeight: {
|
|
58
|
+
type: String,
|
|
59
|
+
default: ''
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
defineExpose({ refresh, remove })
|
|
64
|
+
|
|
65
|
+
const emits = defineEmits(['update:list'])
|
|
66
|
+
|
|
67
|
+
const axios = inject('axios')
|
|
68
|
+
|
|
69
|
+
const infiniteScroll = ref(null)
|
|
70
|
+
|
|
71
|
+
const hasFetchingError = ref(false)
|
|
72
|
+
const isFetching = ref(false)
|
|
73
|
+
const hasMadeFirstFetch = ref(false)
|
|
74
|
+
const count = ref(0)
|
|
75
|
+
const offset = ref(0)
|
|
76
|
+
|
|
77
|
+
const listLength = computed(() => model.value.length)
|
|
78
|
+
|
|
79
|
+
const attributes = computed(() => ({
|
|
80
|
+
offset: 100,
|
|
81
|
+
debounce: 0,
|
|
82
|
+
...(props.maxHeight && { scrollTarget: '.qas-infinite-scroll' }),
|
|
83
|
+
...props.infiniteScrollProps
|
|
84
|
+
}))
|
|
85
|
+
|
|
86
|
+
const isEmptyList = computed(() => !listLength.value && !isFetching.value)
|
|
87
|
+
|
|
88
|
+
const hasNoResults = computed(() => isEmptyList.value && hasMadeFirstFetch.value)
|
|
89
|
+
|
|
90
|
+
const containerStyle = computed(() => ({
|
|
91
|
+
...(props.maxHeight && { maxHeight: props.maxHeight, overflow: 'auto' })
|
|
92
|
+
}))
|
|
93
|
+
|
|
94
|
+
const model = computed({
|
|
95
|
+
get () {
|
|
96
|
+
return props.list
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
set (newList) {
|
|
100
|
+
emits('update:list', newList)
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
async function onLoad (_, done) {
|
|
105
|
+
const hasMadeFirstFetchAndHasNoData = hasMadeFirstFetch.value && !listLength.value
|
|
106
|
+
const hasFetchAllData = listLength.value && listLength.value >= count.value
|
|
107
|
+
const stop = hasFetchingError.value || isFetching.value || hasMadeFirstFetchAndHasNoData || hasFetchAllData
|
|
108
|
+
|
|
109
|
+
if (stop) {
|
|
110
|
+
infiniteScroll.value.stop()
|
|
111
|
+
} else {
|
|
112
|
+
infiniteScroll.value.resume()
|
|
113
|
+
await fetchList()
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
done()
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function fetchList () {
|
|
120
|
+
try {
|
|
121
|
+
isFetching.value = true
|
|
122
|
+
|
|
123
|
+
const { data } = await axios.get(props.url, {
|
|
124
|
+
params: { offset: offset.value, limit: props.limitPerPage, ...props.params }
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
const newList = [...model.value, ...(data.results || [])]
|
|
128
|
+
|
|
129
|
+
model.value = newList
|
|
130
|
+
offset.value = newList.length
|
|
131
|
+
count.value = data.count
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Sinalizar que houve já uma busca, para evitar que onLoad entre em looping,
|
|
135
|
+
* após buscar uma vez e retornar uma lista vazia.
|
|
136
|
+
*/
|
|
137
|
+
hasMadeFirstFetch.value = true
|
|
138
|
+
} catch {
|
|
139
|
+
NotifyError('Ops… Não conseguimos acessar as informações. Por favor, tente novamente em alguns minutos.')
|
|
140
|
+
|
|
141
|
+
hasFetchingError.value = true
|
|
142
|
+
} finally {
|
|
143
|
+
isFetching.value = false
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function refresh () {
|
|
148
|
+
count.value = 0
|
|
149
|
+
offset.value = 0
|
|
150
|
+
model.value = []
|
|
151
|
+
|
|
152
|
+
hasMadeFirstFetch.value = false
|
|
153
|
+
|
|
154
|
+
nextTick(() => {
|
|
155
|
+
infiniteScroll.value.reset()
|
|
156
|
+
infiniteScroll.value.resume()
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function remove (index) {
|
|
161
|
+
model.value.splice(index, 1)
|
|
162
|
+
count.value -= 1
|
|
163
|
+
offset.value -= 1
|
|
164
|
+
}
|
|
165
|
+
</script>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
type: component
|
|
2
|
+
|
|
3
|
+
meta:
|
|
4
|
+
desc: Componente de infinite scroll que implementa o "QInfiniteScroll".
|
|
5
|
+
|
|
6
|
+
props:
|
|
7
|
+
list:
|
|
8
|
+
desc: Model da lista de itens.
|
|
9
|
+
default: []
|
|
10
|
+
type: Array
|
|
11
|
+
examples: [v-model:list="list"]
|
|
12
|
+
model: true
|
|
13
|
+
|
|
14
|
+
limitPerPage:
|
|
15
|
+
desc: é repassado na query da requição sendo responsavel pela quantidade de itens por busca.
|
|
16
|
+
default: 12
|
|
17
|
+
type: Number
|
|
18
|
+
|
|
19
|
+
url:
|
|
20
|
+
desc: URL utilizado para fazer a busca dos itens.
|
|
21
|
+
type: String
|
|
22
|
+
|
|
23
|
+
params:
|
|
24
|
+
desc: Parâmetros passados na requisição de busca dos itens.
|
|
25
|
+
default: {}
|
|
26
|
+
type: Object
|
|
27
|
+
examples: ["{ status: 'is_active' }"]
|
|
28
|
+
|
|
29
|
+
infinite-scroll-props:
|
|
30
|
+
desc: Propriedades repassadas para o QInfiniteScroll
|
|
31
|
+
default: {}
|
|
32
|
+
type: Object
|
|
33
|
+
examples: ["{ offset: 500 }"]
|
|
34
|
+
|
|
35
|
+
max-height:
|
|
36
|
+
desc: Seta a altura do container do infinite scroll, caso queira que o infinite scroll fique em um box por exemplo.
|
|
37
|
+
type: String
|
|
38
|
+
|
|
39
|
+
events:
|
|
40
|
+
'@update:list -> function (newList)':
|
|
41
|
+
desc: Dispara toda vez que é feito uma nova busca e a lista é atualizada.
|
|
42
|
+
params:
|
|
43
|
+
newList:
|
|
44
|
+
desc: Novo valor do list
|
|
45
|
+
type: Array
|
|
46
|
+
|
|
47
|
+
slots:
|
|
48
|
+
default:
|
|
49
|
+
desc: slot para exibir a lista na qual o componente fez a busca.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="qas-tabs-generator">
|
|
3
3
|
<q-tabs v-model="model" active-color="primary" align="left" :breakpoint="0" content-class="text-grey-8" dense inline-label left-icon="sym_r_chevron_left" outside-arrows right-icon="sym_r_chevron_right">
|
|
4
4
|
<slot v-for="(tab, key) in formattedTabs" :item="tab" :name="`tab-${tab.value}`">
|
|
5
|
-
<
|
|
5
|
+
<component :is="tabComponent" :key="key" v-bind="getTabProps(tab)" class="text-body1" :name="tab.value" no-caps :ripple="false">
|
|
6
6
|
<slot :item="tab" :name="`tab-after-${tab.value}`">
|
|
7
7
|
<q-icon v-if="tab.icon" :name="tab.icon" size="sm" />
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
{{ getFormattedLabel(tab) }}
|
|
13
13
|
</div>
|
|
14
14
|
</slot>
|
|
15
|
-
</
|
|
15
|
+
</component>
|
|
16
16
|
</slot>
|
|
17
17
|
</q-tabs>
|
|
18
18
|
</div>
|
|
@@ -45,6 +45,10 @@ export default {
|
|
|
45
45
|
default: () => ({}),
|
|
46
46
|
required: true,
|
|
47
47
|
type: [Object, Array]
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
useRouteTab: {
|
|
51
|
+
type: Boolean
|
|
48
52
|
}
|
|
49
53
|
},
|
|
50
54
|
|
|
@@ -77,6 +81,10 @@ export default {
|
|
|
77
81
|
|
|
78
82
|
this.$emit('update:modelValue', value)
|
|
79
83
|
}
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
tabComponent () {
|
|
87
|
+
return this.useRouteTab ? 'q-route-tab' : 'q-tab'
|
|
80
88
|
}
|
|
81
89
|
},
|
|
82
90
|
|
|
@@ -24,6 +24,11 @@ props:
|
|
|
24
24
|
type: [Object, Array]
|
|
25
25
|
examples: ["{ tab1: 'tab1', tab2: 'tab2' }"]
|
|
26
26
|
|
|
27
|
+
useRouteTab:
|
|
28
|
+
desc: Quando "true" será utilizado o componente "QRouteTab" do Quasar (https://quasar.dev/vue-components/tabs#qroutetab-api).
|
|
29
|
+
default: false
|
|
30
|
+
type: Boolean
|
|
31
|
+
|
|
27
32
|
slots:
|
|
28
33
|
'tab-[nome-da-chave]':
|
|
29
34
|
desc: Slot dinâmico gerado a partir das chave passada na prop "tabs", substitui todo o "q-tab".
|
package/src/vue-plugin.js
CHANGED
|
@@ -28,6 +28,7 @@ import QasGallery from './components/gallery/QasGallery.vue'
|
|
|
28
28
|
import QasGalleryCard from './components/gallery-card/QasGalleryCard.vue'
|
|
29
29
|
import QasGridGenerator from './components/grid-generator/QasGridGenerator.vue'
|
|
30
30
|
import QasHeaderActions from './components/header-actions/QasHeaderActions.vue'
|
|
31
|
+
import QasInfiniteScroll from './components/infinite-scroll/QasInfiniteScroll.vue'
|
|
31
32
|
import QasInput from './components/input/QasInput.vue'
|
|
32
33
|
import QasLabel from './components/label/QasLabel.vue'
|
|
33
34
|
import QasLayout from './components/layout/QasLayout.vue'
|
|
@@ -111,6 +112,7 @@ async function install (app) {
|
|
|
111
112
|
app.component('QasGalleryCard', QasGalleryCard)
|
|
112
113
|
app.component('QasGridGenerator', QasGridGenerator)
|
|
113
114
|
app.component('QasHeaderActions', QasHeaderActions)
|
|
115
|
+
app.component('QasInfiniteScroll', QasInfiniteScroll)
|
|
114
116
|
app.component('QasInput', QasInput)
|
|
115
117
|
app.component('QasLabel', QasLabel)
|
|
116
118
|
app.component('QasLayout', QasLayout)
|
|
@@ -192,6 +194,7 @@ export {
|
|
|
192
194
|
QasGalleryCard,
|
|
193
195
|
QasGridGenerator,
|
|
194
196
|
QasHeaderActions,
|
|
197
|
+
QasInfiniteScroll,
|
|
195
198
|
QasInput,
|
|
196
199
|
QasLabel,
|
|
197
200
|
QasLayout,
|