@bildvitta/quasar-ui-asteroid 3.17.0-beta.8 → 3.17.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/package.json +3 -2
- package/src/assets/sounds/nave-notification.mp3 +0 -0
- package/src/components/app-menu/QasAppMenu.vue +73 -15
- package/src/components/app-menu/QasAppMenu.yml +5 -5
- package/src/components/app-user/QasAppUser.vue +49 -40
- package/src/components/avatar/QasAvatar.vue +7 -8
- package/src/components/badge/QasBadge.vue +3 -29
- package/src/components/board-generator/QasBoardGenerator.vue +442 -40
- package/src/components/board-generator/QasBoardGenerator.yml +107 -12
- package/src/components/card/QasCard.vue +13 -4
- package/src/components/chart-view/QasChartView.vue +56 -3
- package/src/components/chart-view/QasChartView.yml +6 -0
- package/src/components/checkbox/QasCheckbox.vue +67 -11
- package/src/components/checkbox/QasCheckbox.yml +18 -0
- package/src/components/copy/QasCopy.vue +12 -2
- package/src/components/copy/QasCopy.yml +8 -0
- package/src/components/expansion-item/QasExpansionItem.vue +108 -76
- package/src/components/expansion-item/QasExpansionItem.yml +38 -10
- package/src/components/field/QasField.vue +1 -1
- package/src/components/form-generator/QasFormGenerator.vue +23 -10
- package/src/components/form-generator/QasFormGenerator.yml +2 -2
- package/src/components/grabbable/QasGrabbable.vue +14 -6
- package/src/components/grabbable/QasGrabbable.yml +4 -0
- package/src/components/grid-generator/QasGridGenerator.vue +3 -3
- package/src/components/grid-generator/QasGridGenerator.yml +2 -2
- package/src/components/grid-item/QasGridItem.vue +1 -1
- package/src/components/header/QasHeader.vue +11 -9
- package/src/components/infinite-scroll/QasInfiniteScroll.vue +16 -17
- package/src/components/infinite-scroll/QasInfiniteScroll.yml +7 -0
- package/src/components/list-view/QasListView.vue +16 -2
- package/src/components/list-view/QasListView.yml +9 -0
- package/src/components/radio/QasRadio.vue +24 -5
- package/src/components/radio/QasRadio.yml +6 -0
- package/src/components/select/QasSelect.vue +54 -7
- package/src/components/select/QasSelect.yml +6 -1
- package/src/components/select-filter/QasSelectFilter.vue +65 -0
- package/src/components/select-filter/QasSelectFilter.yml +36 -0
- package/src/components/stepper/QasStepper.vue +50 -3
- package/src/components/stepper-form-view/QasStepperFormView.vue +6 -4
- package/src/components/stepper-form-view/QasStepperFormView.yml +1 -1
- package/src/components/table-generator/QasTableGenerator.vue +3 -0
- package/src/components/text-truncate/QasTextTruncate.vue +77 -14
- package/src/components/text-truncate/QasTextTruncate.yml +14 -3
- package/src/components/uploader/QasUploader.vue +70 -24
- package/src/components/uploader/QasUploader.yml +15 -1
- package/src/components/welcome/QasWelcome.vue +8 -0
- package/src/components/welcome/QasWelcome.yml +3 -0
- package/src/composables/index.js +3 -1
- package/src/composables/private/index.js +1 -0
- package/src/composables/private/use-auth-user.js +20 -0
- package/src/composables/private/use-generator.js +20 -5
- package/src/composables/use-default-filters.js +106 -0
- package/src/composables/use-notifications.js +14 -0
- package/src/composables/use-query-cache.js +1 -1
- package/src/css/components/field.scss +13 -6
- package/src/helpers/set-scroll-on-grab.js +9 -1
- package/src/shared/badge-config.js +29 -0
- package/src/vue-plugin.js +3 -0
- package/src/components/app-menu/private/PvAppMenuHelpChat.vue +0 -222
|
@@ -33,6 +33,11 @@ const props = defineProps({
|
|
|
33
33
|
default: () => []
|
|
34
34
|
},
|
|
35
35
|
|
|
36
|
+
fields: {
|
|
37
|
+
type: Object,
|
|
38
|
+
default: () => ({})
|
|
39
|
+
},
|
|
40
|
+
|
|
36
41
|
limitPerPage: {
|
|
37
42
|
type: Number,
|
|
38
43
|
default: 12
|
|
@@ -62,7 +67,10 @@ const props = defineProps({
|
|
|
62
67
|
|
|
63
68
|
defineExpose({ refresh, remove })
|
|
64
69
|
|
|
65
|
-
const emit = defineEmits(['
|
|
70
|
+
const emit = defineEmits(['fetch-success', 'fetch-error'])
|
|
71
|
+
|
|
72
|
+
const modelList = defineModel('list', { type: Array, default: () => [] })
|
|
73
|
+
const modelFields = defineModel('fields', { type: Object, default: () => ({}) })
|
|
66
74
|
|
|
67
75
|
const axios = inject('axios')
|
|
68
76
|
|
|
@@ -74,7 +82,7 @@ const hasMadeFirstFetch = ref(false)
|
|
|
74
82
|
const count = ref(0)
|
|
75
83
|
const offset = ref(0)
|
|
76
84
|
|
|
77
|
-
const listLength = computed(() =>
|
|
85
|
+
const listLength = computed(() => modelList.value.length)
|
|
78
86
|
|
|
79
87
|
const attributes = computed(() => ({
|
|
80
88
|
offset: 100,
|
|
@@ -91,16 +99,6 @@ const containerStyle = computed(() => ({
|
|
|
91
99
|
...(props.maxHeight && { maxHeight: props.maxHeight, overflow: 'auto' })
|
|
92
100
|
}))
|
|
93
101
|
|
|
94
|
-
const model = computed({
|
|
95
|
-
get () {
|
|
96
|
-
return props.list
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
set (newList) {
|
|
100
|
-
emit('update:list', newList)
|
|
101
|
-
}
|
|
102
|
-
})
|
|
103
|
-
|
|
104
102
|
async function onLoad (_, done) {
|
|
105
103
|
const hasMadeFirstFetchAndHasNoData = hasMadeFirstFetch.value && !listLength.value
|
|
106
104
|
const hasFetchAllData = listLength.value && listLength.value >= count.value
|
|
@@ -124,11 +122,12 @@ async function fetchList () {
|
|
|
124
122
|
params: { offset: offset.value, limit: props.limitPerPage, ...props.params }
|
|
125
123
|
})
|
|
126
124
|
|
|
127
|
-
const newList = [...
|
|
125
|
+
const newList = [...modelList.value, ...(data.results || [])]
|
|
128
126
|
|
|
129
|
-
|
|
127
|
+
modelList.value = newList
|
|
130
128
|
offset.value = newList.length
|
|
131
129
|
count.value = data.count
|
|
130
|
+
modelFields.value = data.fields
|
|
132
131
|
|
|
133
132
|
/**
|
|
134
133
|
* Sinalizar que houve já uma busca, para evitar que onLoad entre em looping,
|
|
@@ -136,7 +135,7 @@ async function fetchList () {
|
|
|
136
135
|
*/
|
|
137
136
|
hasMadeFirstFetch.value = true
|
|
138
137
|
|
|
139
|
-
emit('fetch-success', { list: newList, offset: offset.value, count: count.value })
|
|
138
|
+
emit('fetch-success', { list: newList, fields: modelFields.value, offset: offset.value, count: count.value })
|
|
140
139
|
} catch (error) {
|
|
141
140
|
NotifyError('Ops… Não conseguimos acessar as informações. Por favor, tente novamente em alguns minutos.')
|
|
142
141
|
|
|
@@ -151,7 +150,7 @@ async function fetchList () {
|
|
|
151
150
|
function refresh () {
|
|
152
151
|
count.value = 0
|
|
153
152
|
offset.value = 0
|
|
154
|
-
|
|
153
|
+
modelList.value = []
|
|
155
154
|
|
|
156
155
|
hasMadeFirstFetch.value = false
|
|
157
156
|
|
|
@@ -162,7 +161,7 @@ function refresh () {
|
|
|
162
161
|
}
|
|
163
162
|
|
|
164
163
|
function remove (index) {
|
|
165
|
-
|
|
164
|
+
modelList.value.splice(index, 1)
|
|
166
165
|
count.value -= 1
|
|
167
166
|
offset.value -= 1
|
|
168
167
|
}
|
|
@@ -4,6 +4,13 @@ meta:
|
|
|
4
4
|
desc: Componente de infinite scroll que implementa o "QInfiniteScroll".
|
|
5
5
|
|
|
6
6
|
props:
|
|
7
|
+
fields:
|
|
8
|
+
desc: Model dos fields.
|
|
9
|
+
default: {}
|
|
10
|
+
type: Object
|
|
11
|
+
examples: [v-model:fields="fields"]
|
|
12
|
+
model: true
|
|
13
|
+
|
|
7
14
|
list:
|
|
8
15
|
desc: Model da lista de itens.
|
|
9
16
|
default: []
|
|
@@ -43,10 +43,13 @@
|
|
|
43
43
|
<script>
|
|
44
44
|
import QasFilters from '../filters/QasFilters.vue'
|
|
45
45
|
import QasPagination from '../pagination/QasPagination.vue'
|
|
46
|
+
|
|
47
|
+
import { viewMixin, contextMixin } from '../../mixins'
|
|
48
|
+
|
|
46
49
|
import debug from 'debug'
|
|
47
50
|
import { extend } from 'quasar'
|
|
48
51
|
import { getState, getAction } from '@bildvitta/store-adapter'
|
|
49
|
-
import {
|
|
52
|
+
import { computed } from 'vue'
|
|
50
53
|
|
|
51
54
|
const log = debug('asteroid-ui:qas-list-view')
|
|
52
55
|
|
|
@@ -58,6 +61,13 @@ export default {
|
|
|
58
61
|
|
|
59
62
|
mixins: [contextMixin, viewMixin],
|
|
60
63
|
|
|
64
|
+
provide () {
|
|
65
|
+
return {
|
|
66
|
+
isFetchListSucceeded: computed(() => this.isFetchListSucceeded),
|
|
67
|
+
isListView: true
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
|
|
61
71
|
props: {
|
|
62
72
|
filtersProps: {
|
|
63
73
|
default: () => ({}),
|
|
@@ -107,7 +117,8 @@ export default {
|
|
|
107
117
|
data () {
|
|
108
118
|
return {
|
|
109
119
|
page: 1,
|
|
110
|
-
resultsQuantity: 0
|
|
120
|
+
resultsQuantity: 0,
|
|
121
|
+
isFetchListSucceeded: false
|
|
111
122
|
}
|
|
112
123
|
},
|
|
113
124
|
|
|
@@ -188,6 +199,7 @@ export default {
|
|
|
188
199
|
|
|
189
200
|
async fetchList (externalPayload = {}) {
|
|
190
201
|
this.mx_isFetching = true
|
|
202
|
+
this.isFetchListSucceeded = false
|
|
191
203
|
|
|
192
204
|
try {
|
|
193
205
|
const payload = {
|
|
@@ -215,6 +227,8 @@ export default {
|
|
|
215
227
|
metadata: this.mx_metadata
|
|
216
228
|
})
|
|
217
229
|
|
|
230
|
+
this.isFetchListSucceeded = true
|
|
231
|
+
|
|
218
232
|
this.$emit('fetch-success', response)
|
|
219
233
|
|
|
220
234
|
log(`[${this.entity}]:fetchList:success`, response)
|
|
@@ -158,3 +158,12 @@ events:
|
|
|
158
158
|
value:
|
|
159
159
|
desc: Retorna se está ou não fazendo fetching de dados.
|
|
160
160
|
type: Boolean
|
|
161
|
+
|
|
162
|
+
provide:
|
|
163
|
+
is-fetch-list-succeeded:
|
|
164
|
+
desc: Valor que diz se o `fetchList` foi realizado com sucesso ou não.
|
|
165
|
+
type: Boolean
|
|
166
|
+
|
|
167
|
+
is-list-view:
|
|
168
|
+
desc: Provide que diz quando se está utilizando o listView
|
|
169
|
+
type: Boolean
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<div>
|
|
3
|
+
<div v-if="canShowOptionGroupLabel" class="q-mb-sm text-body1">
|
|
4
|
+
{{ props.label }}
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<component :is="component.is" v-bind="component.props" />
|
|
8
|
+
</div>
|
|
3
9
|
</template>
|
|
4
10
|
|
|
5
11
|
<script setup>
|
|
@@ -10,8 +16,20 @@ defineOptions({
|
|
|
10
16
|
inheritAttrs: false
|
|
11
17
|
})
|
|
12
18
|
|
|
19
|
+
const props = defineProps({
|
|
20
|
+
label: {
|
|
21
|
+
default: '',
|
|
22
|
+
type: String
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
|
|
13
26
|
const attrs = useAttrs()
|
|
14
27
|
|
|
28
|
+
const isOptionGroup = computed(() => !!attrs.options?.length)
|
|
29
|
+
|
|
30
|
+
// Só mostra a label caso for q-option-group e tenha label vindo nas props
|
|
31
|
+
const canShowOptionGroupLabel = computed(() => isOptionGroup.value && !!props.label)
|
|
32
|
+
|
|
15
33
|
/**
|
|
16
34
|
* - quando é um grupo de opções, o componente é 'QOptionGroup', caso contrário,
|
|
17
35
|
* é 'QRadio'.
|
|
@@ -19,16 +37,17 @@ const attrs = useAttrs()
|
|
|
19
37
|
* - todos os casos é usado o dense.
|
|
20
38
|
*/
|
|
21
39
|
const component = computed(() => {
|
|
22
|
-
const isOptionGroup = !!attrs.options?.length
|
|
23
|
-
|
|
24
40
|
const { inline = true, ...payloadProps } = attrs
|
|
25
41
|
|
|
26
42
|
return {
|
|
27
|
-
is: isOptionGroup ? 'q-option-group' : 'q-radio',
|
|
43
|
+
is: isOptionGroup.value ? 'q-option-group' : 'q-radio',
|
|
44
|
+
|
|
28
45
|
props: {
|
|
29
46
|
...payloadProps,
|
|
30
47
|
|
|
31
|
-
|
|
48
|
+
label: props.label,
|
|
49
|
+
|
|
50
|
+
...(isOptionGroup.value && {
|
|
32
51
|
inline,
|
|
33
52
|
class: {
|
|
34
53
|
'q-gutter-x-md': inline,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<q-select v-model="model" v-bind="attributes" class="qas-select" :class="componentClasses" no-error-icon
|
|
3
|
-
<template v-if="
|
|
4
|
-
<q-icon name="
|
|
2
|
+
<q-select v-model="model" v-bind="attributes" class="qas-select" :class="componentClasses" no-error-icon>
|
|
3
|
+
<template v-if="hasIcon" #prepend>
|
|
4
|
+
<q-icon :name="defaultIcon" />
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<template #no-option>
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
{{ scope.opt.label }}
|
|
39
39
|
</q-item-label>
|
|
40
40
|
|
|
41
|
-
<div v-for="(badge, index) in getFilteredBadgeList(scope.opt)" :key="index">
|
|
41
|
+
<div v-for="(badge, index) in getFilteredBadgeList(scope.opt)" :key="index" class="flex">
|
|
42
42
|
<qas-badge v-if="hasBadge(badge)" v-bind="getBadgeProps(badge)" />
|
|
43
43
|
</div>
|
|
44
44
|
</div>
|
|
@@ -77,6 +77,11 @@ export default {
|
|
|
77
77
|
|
|
78
78
|
mixins: [searchFilterMixin],
|
|
79
79
|
|
|
80
|
+
inject: {
|
|
81
|
+
isBox: { default: false },
|
|
82
|
+
isDialog: { default: false }
|
|
83
|
+
},
|
|
84
|
+
|
|
80
85
|
props: {
|
|
81
86
|
badgeProps: {
|
|
82
87
|
default: () => ({}),
|
|
@@ -88,6 +93,11 @@ export default {
|
|
|
88
93
|
type: Object
|
|
89
94
|
},
|
|
90
95
|
|
|
96
|
+
icon: {
|
|
97
|
+
type: String,
|
|
98
|
+
default: ''
|
|
99
|
+
},
|
|
100
|
+
|
|
91
101
|
label: {
|
|
92
102
|
type: String,
|
|
93
103
|
default: ''
|
|
@@ -132,6 +142,10 @@ export default {
|
|
|
132
142
|
useSearch: {
|
|
133
143
|
type: Boolean,
|
|
134
144
|
default: undefined
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
useFilterMode: {
|
|
148
|
+
type: Boolean
|
|
135
149
|
}
|
|
136
150
|
},
|
|
137
151
|
|
|
@@ -150,7 +164,7 @@ export default {
|
|
|
150
164
|
clearable: this.isSearchable,
|
|
151
165
|
emitValue: true,
|
|
152
166
|
mapOptions: true,
|
|
153
|
-
outlined:
|
|
167
|
+
outlined: this.useFilterMode,
|
|
154
168
|
dense: true,
|
|
155
169
|
dropdownIcon: 'sym_r_expand_more',
|
|
156
170
|
clearIcon: 'sym_r_close',
|
|
@@ -188,6 +202,10 @@ export default {
|
|
|
188
202
|
return this.hasFuse || this.useLazyLoading
|
|
189
203
|
},
|
|
190
204
|
|
|
205
|
+
isBordered () {
|
|
206
|
+
return (this.isBox || this.isDialog) && this.useFilterMode
|
|
207
|
+
},
|
|
208
|
+
|
|
191
209
|
hasError () {
|
|
192
210
|
return this.mx_hasFetchError || this.$attrs.error
|
|
193
211
|
},
|
|
@@ -229,13 +247,28 @@ export default {
|
|
|
229
247
|
},
|
|
230
248
|
|
|
231
249
|
canSetDefaultOption () {
|
|
232
|
-
|
|
250
|
+
// Como o default do model pode ser um array (caso de multiple), é necessário validar o length
|
|
251
|
+
const hasModelValue = Array.isArray(this.modelValue) ? !!this.modelValue.length : !!this.modelValue
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Posso setar o default quando:
|
|
255
|
+
* - O campo for required ou tiver a prop useAutoSelect
|
|
256
|
+
* - Tiver apenas uma option
|
|
257
|
+
* - O modelValue estiver vazio
|
|
258
|
+
*/
|
|
259
|
+
return (this.required || this.useAutoSelect) && this.options.length === 1 && !hasModelValue
|
|
233
260
|
},
|
|
234
261
|
|
|
235
262
|
// redesign
|
|
236
263
|
componentClasses () {
|
|
237
264
|
return {
|
|
238
|
-
|
|
265
|
+
...(this.useFilterMode && {
|
|
266
|
+
'qas-select--filter rounded-borders': true,
|
|
267
|
+
'shadow-2': !this.isBordered,
|
|
268
|
+
bordered: this.isBordered
|
|
269
|
+
}),
|
|
270
|
+
|
|
271
|
+
'qas-select--has-icon': this.hasAppend || this.hasIcon,
|
|
239
272
|
'qas-select--closed': !this.isPopupContentOpen,
|
|
240
273
|
'qas-select--loading': this.hasLoading
|
|
241
274
|
}
|
|
@@ -251,6 +284,14 @@ export default {
|
|
|
251
284
|
|
|
252
285
|
hasAppend () {
|
|
253
286
|
return !!this.$slots.append
|
|
287
|
+
},
|
|
288
|
+
|
|
289
|
+
defaultIcon () {
|
|
290
|
+
return this.icon || 'sym_r_search'
|
|
291
|
+
},
|
|
292
|
+
|
|
293
|
+
hasIcon () {
|
|
294
|
+
return this.isSearchable || !!this.icon
|
|
254
295
|
}
|
|
255
296
|
},
|
|
256
297
|
|
|
@@ -429,6 +470,12 @@ export default {
|
|
|
429
470
|
}
|
|
430
471
|
}
|
|
431
472
|
|
|
473
|
+
&--filter {
|
|
474
|
+
.q-field__control:before {
|
|
475
|
+
border: 0;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
432
479
|
&__menu {
|
|
433
480
|
.q-item {
|
|
434
481
|
font-weight: 400 !important;
|
|
@@ -7,7 +7,7 @@ meta:
|
|
|
7
7
|
desc: Componente para select que implementa o "QSelect" repassando propriedades, slots e eventos.
|
|
8
8
|
|
|
9
9
|
props:
|
|
10
|
-
badge-
|
|
10
|
+
badge-props:
|
|
11
11
|
desc: Configuração das badges no qual cada key é um callback com o valor booleano retornado pelo back.
|
|
12
12
|
default: {}
|
|
13
13
|
examples: ["{ isTester: () => { return { color: 'grey-8', label: 'Tester', textColor: 'white' }} }"]
|
|
@@ -35,6 +35,11 @@ props:
|
|
|
35
35
|
keys: [label, value]
|
|
36
36
|
threshold: 0.4
|
|
37
37
|
|
|
38
|
+
icon:
|
|
39
|
+
desc: Ícone da esquerda.
|
|
40
|
+
type: String
|
|
41
|
+
default: ''
|
|
42
|
+
|
|
38
43
|
label:
|
|
39
44
|
desc: Label do componente.
|
|
40
45
|
type: String
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<qas-select v-model="internalModel" :label="props.label" :options="props.options" use-filter-mode @update:model-value="onUpdateModel" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup>
|
|
6
|
+
import useDefaultFilters from '../../composables/use-default-filters'
|
|
7
|
+
|
|
8
|
+
import { extend } from 'quasar'
|
|
9
|
+
import { watch, ref, nextTick } from 'vue'
|
|
10
|
+
import { useRouter, useRoute } from 'vue-router'
|
|
11
|
+
|
|
12
|
+
defineOptions({ name: 'QasSelectFilter' })
|
|
13
|
+
|
|
14
|
+
const props = defineProps({
|
|
15
|
+
label: {
|
|
16
|
+
type: String,
|
|
17
|
+
default: 'Selecione uma empresa vinculada'
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
name: {
|
|
21
|
+
type: String,
|
|
22
|
+
default: 'company'
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
options: {
|
|
26
|
+
type: Array,
|
|
27
|
+
default: () => []
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
// composables
|
|
32
|
+
const router = useRouter()
|
|
33
|
+
const route = useRoute()
|
|
34
|
+
const { setFilterQuery, triggerDefaultFiltersChange, filterQuery } = useDefaultFilters()
|
|
35
|
+
|
|
36
|
+
// models
|
|
37
|
+
const model = defineModel({ type: String, default: '' })
|
|
38
|
+
|
|
39
|
+
// refs
|
|
40
|
+
const internalModel = ref(route.query[props.name] || model.value)
|
|
41
|
+
|
|
42
|
+
// watch
|
|
43
|
+
watch(() => route.query[props.name], setModels)
|
|
44
|
+
|
|
45
|
+
// functions
|
|
46
|
+
/**
|
|
47
|
+
* Adiciona o valor na URL, atualizando a rota, isto vai fazer com que o componente
|
|
48
|
+
* seja atualizado com o novo valor, pois cai no watch que atualiza o model interno e externo.
|
|
49
|
+
*/
|
|
50
|
+
function onUpdateModel (value) {
|
|
51
|
+
const { ...query } = route.query
|
|
52
|
+
|
|
53
|
+
router.push({ query: { ...query, [props.name]: value } })
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function setModels (value) {
|
|
57
|
+
model.value = value
|
|
58
|
+
internalModel.value = value
|
|
59
|
+
|
|
60
|
+
const oldFilters = extend(true, {}, filterQuery.value)
|
|
61
|
+
|
|
62
|
+
setFilterQuery(value, props.name)
|
|
63
|
+
nextTick(() => triggerDefaultFiltersChange(filterQuery.value, oldFilters))
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
type: component
|
|
2
|
+
|
|
3
|
+
meta:
|
|
4
|
+
desc: Componente para gerar dinamicamente checkbox agrupados.
|
|
5
|
+
|
|
6
|
+
props:
|
|
7
|
+
inline:
|
|
8
|
+
desc: Controla se o componente vai aparece em linha ou em bloco.
|
|
9
|
+
default: true
|
|
10
|
+
type: Boolean
|
|
11
|
+
|
|
12
|
+
label:
|
|
13
|
+
desc: Label utilizada em casos de ser checkbox-group.
|
|
14
|
+
default: ''
|
|
15
|
+
type: String
|
|
16
|
+
|
|
17
|
+
model-value:
|
|
18
|
+
desc: Model do componente, usado para v-model.
|
|
19
|
+
default: []
|
|
20
|
+
type: Array
|
|
21
|
+
examples: [v-model"value"]
|
|
22
|
+
model: true
|
|
23
|
+
|
|
24
|
+
options:
|
|
25
|
+
desc: Opções para gerar os checkbox.
|
|
26
|
+
default: []
|
|
27
|
+
type: Array
|
|
28
|
+
|
|
29
|
+
events:
|
|
30
|
+
'@update:model-value -> function(value)':
|
|
31
|
+
desc: Dispara quando o model-value altera, também usado para v-model.
|
|
32
|
+
params:
|
|
33
|
+
value:
|
|
34
|
+
desc: Novo valor do model.
|
|
35
|
+
default: []
|
|
36
|
+
type: Array
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="qas-stepper" :class="classes">
|
|
3
|
-
<q-stepper ref="stepper" v-model="model"
|
|
3
|
+
<q-stepper ref="stepper" v-model="model" v-bind="stepperProps">
|
|
4
4
|
<template v-for="(_, name) in $slots" #[name]="context">
|
|
5
5
|
<slot :name="name" v-bind="getContext(context)" />
|
|
6
6
|
</template>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</template>
|
|
10
10
|
|
|
11
11
|
<script setup>
|
|
12
|
-
import { computed, ref } from 'vue'
|
|
12
|
+
import { computed, ref, useAttrs } from 'vue'
|
|
13
13
|
import { Spacing } from '../../enums/Spacing'
|
|
14
14
|
import { gutterValidator } from '../../helpers/private/gutter-validator'
|
|
15
15
|
import useScreen from '../../composables/use-screen'
|
|
@@ -35,6 +35,8 @@ const props = defineProps({
|
|
|
35
35
|
|
|
36
36
|
const stepper = ref(null)
|
|
37
37
|
|
|
38
|
+
const attrs = useAttrs()
|
|
39
|
+
|
|
38
40
|
const screen = useScreen()
|
|
39
41
|
|
|
40
42
|
const emit = defineEmits(['update:modelValue'])
|
|
@@ -53,7 +55,27 @@ const model = computed({
|
|
|
53
55
|
|
|
54
56
|
const classes = computed(() => ({ 'qas-stepper--disable': props.disable }))
|
|
55
57
|
|
|
56
|
-
const
|
|
58
|
+
const stepperProps = computed(() => {
|
|
59
|
+
const defaultProps = {
|
|
60
|
+
contracted: screen.untilLarge,
|
|
61
|
+
doneColor: 'primary',
|
|
62
|
+
flat: true,
|
|
63
|
+
animated: true,
|
|
64
|
+
activeColor: 'primary',
|
|
65
|
+
errorIcon: 'sym_r_close',
|
|
66
|
+
errorColor: 'white',
|
|
67
|
+
headerClass: `text-subtitle1 q-pb-${props.spacing}`,
|
|
68
|
+
inactiveColor: attrs['header-nav'] || attrs.headerNav ? 'grey-10' : 'grey-6'
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
activeIcon: 'none',
|
|
73
|
+
doneIcon: 'none',
|
|
74
|
+
keepAlive: true,
|
|
75
|
+
...attrs,
|
|
76
|
+
...defaultProps
|
|
77
|
+
}
|
|
78
|
+
})
|
|
57
79
|
|
|
58
80
|
function getContext (context) {
|
|
59
81
|
return {
|
|
@@ -87,6 +109,31 @@ function previous () {
|
|
|
87
109
|
|
|
88
110
|
&__tab {
|
|
89
111
|
padding: 0;
|
|
112
|
+
|
|
113
|
+
&--active {
|
|
114
|
+
.q-icon {
|
|
115
|
+
font-size: 14px;
|
|
116
|
+
color: white;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.q-stepper__dot {
|
|
120
|
+
background-color: var(--q-primary) !important;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
&:not(.q-stepper__tab--active).q-stepper__tab--error-with-icon {
|
|
125
|
+
.q-stepper__title {
|
|
126
|
+
color: $grey-10;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.q-stepper__dot {
|
|
130
|
+
background-color: $negative !important;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.q-icon {
|
|
134
|
+
font-size: 14px;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
90
137
|
}
|
|
91
138
|
|
|
92
139
|
&__caption {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<qas-stepper ref="stepper" v-model="model" v-bind="stepperProps">
|
|
3
3
|
<template #default>
|
|
4
|
-
<q-step v-for="(step, stepIndex) in props.steps" :key="stepIndex" :done="isDone(stepIndex)" :name="getStepName(stepIndex)" v-bind="stepPropsList[stepIndex]">
|
|
4
|
+
<q-step v-for="(step, stepIndex) in props.steps" :key="stepIndex" :done="isDone(stepIndex)" :name="getStepName({ step, stepIndex })" v-bind="stepPropsList[stepIndex]">
|
|
5
5
|
<component :is="step.component" />
|
|
6
6
|
</q-step>
|
|
7
7
|
</template>
|
|
@@ -30,7 +30,9 @@ const props = defineProps({
|
|
|
30
30
|
}
|
|
31
31
|
})
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
defineExpose({ setStepProps })
|
|
34
|
+
|
|
35
|
+
const model = defineModel({ type: [Number, String], default: 1 })
|
|
34
36
|
|
|
35
37
|
const values = ref({})
|
|
36
38
|
const stepPropsList = ref([])
|
|
@@ -68,8 +70,8 @@ function isDone (stepIndex) {
|
|
|
68
70
|
return model.value > stepIndex + 1
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
function getStepName (stepIndex) {
|
|
72
|
-
return stepIndex + 1
|
|
73
|
+
function getStepName ({ step, stepIndex }) {
|
|
74
|
+
return step.name || stepIndex + 1
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
provide('stepper', {
|
|
@@ -17,7 +17,7 @@ props:
|
|
|
17
17
|
desc: Propriedades que serão repassadas para o QasStepper.
|
|
18
18
|
type: Object
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
provide:
|
|
21
21
|
stepper-model:
|
|
22
22
|
desc: Model do stepper caso precise recuperar o step atual para alguma lógica. Possui reatividade, portanto para acessar é necessário do ".value"
|
|
23
23
|
type: Number
|