@bildvitta/quasar-ui-asteroid 3.17.0-beta.9 → 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 +11 -2
- package/src/components/select/QasSelect.yml +1 -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/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,
|
|
@@ -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>
|
|
@@ -247,7 +247,16 @@ export default {
|
|
|
247
247
|
},
|
|
248
248
|
|
|
249
249
|
canSetDefaultOption () {
|
|
250
|
-
|
|
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
|
|
251
260
|
},
|
|
252
261
|
|
|
253
262
|
// redesign
|
|
@@ -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' }} }"]
|
|
@@ -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
|
|
@@ -2,7 +2,17 @@
|
|
|
2
2
|
<div ref="parent" :class="classes">
|
|
3
3
|
<div class="no-wrap row text-no-wrap">
|
|
4
4
|
<div ref="truncate" class="ellipsis">
|
|
5
|
-
<slot>
|
|
5
|
+
<slot>
|
|
6
|
+
<div v-if="hasBadges" class="items-center q-col-gutter-sm row" :class="badgeParentClasses">
|
|
7
|
+
<div v-for="(item, index) in normalizedBadgesList" :key="index">
|
|
8
|
+
<qas-badge v-bind="getBadgeProps(item)" />
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<div v-else class="ellipsis">
|
|
13
|
+
{{ formattedText }}
|
|
14
|
+
</div>
|
|
15
|
+
</slot>
|
|
6
16
|
</div>
|
|
7
17
|
|
|
8
18
|
<qas-btn v-if="hasButton" class="q-ml-sm" :label="buttonLabel" @click.stop.prevent="toggle" />
|
|
@@ -10,7 +20,7 @@
|
|
|
10
20
|
|
|
11
21
|
<qas-dialog v-model="show" v-bind="defaultProps" aria-label="Diálogo de texto completo" role="dialog">
|
|
12
22
|
<template v-if="isCounterMode" #description>
|
|
13
|
-
<div class="q-col-gutter-y-
|
|
23
|
+
<div class="q-col-gutter-y-sm row">
|
|
14
24
|
<div
|
|
15
25
|
v-for="(item, index) in normalizedList"
|
|
16
26
|
:key="index"
|
|
@@ -25,17 +35,19 @@
|
|
|
25
35
|
</template>
|
|
26
36
|
|
|
27
37
|
<script setup>
|
|
38
|
+
import QasDialog from '../dialog/QasDialog.vue'
|
|
39
|
+
|
|
40
|
+
import { baseProps } from '../../shared/badge-config'
|
|
41
|
+
|
|
28
42
|
import {
|
|
29
43
|
computed,
|
|
44
|
+
nextTick,
|
|
30
45
|
onMounted,
|
|
31
46
|
onUnmounted,
|
|
32
47
|
ref,
|
|
33
48
|
watch
|
|
34
49
|
} from 'vue'
|
|
35
50
|
|
|
36
|
-
import QasDialog from '../dialog/QasDialog.vue'
|
|
37
|
-
|
|
38
|
-
// define component name
|
|
39
51
|
defineOptions({ name: 'QasTextTruncate' })
|
|
40
52
|
|
|
41
53
|
// props
|
|
@@ -55,6 +67,11 @@ const props = defineProps({
|
|
|
55
67
|
default: ''
|
|
56
68
|
},
|
|
57
69
|
|
|
70
|
+
emptyText: {
|
|
71
|
+
type: String,
|
|
72
|
+
default: '-'
|
|
73
|
+
},
|
|
74
|
+
|
|
58
75
|
maxWidth: {
|
|
59
76
|
type: Number,
|
|
60
77
|
default: 0
|
|
@@ -85,13 +102,16 @@ const props = defineProps({
|
|
|
85
102
|
default: () => []
|
|
86
103
|
},
|
|
87
104
|
|
|
105
|
+
useBadge: {
|
|
106
|
+
type: Boolean
|
|
107
|
+
},
|
|
108
|
+
|
|
88
109
|
useObjectList: {
|
|
89
110
|
type: Boolean
|
|
90
111
|
},
|
|
91
112
|
|
|
92
|
-
|
|
93
|
-
type:
|
|
94
|
-
default: '-'
|
|
113
|
+
useWrapBadge: {
|
|
114
|
+
type: Boolean
|
|
95
115
|
}
|
|
96
116
|
})
|
|
97
117
|
|
|
@@ -100,11 +120,18 @@ const truncate = ref(null)
|
|
|
100
120
|
const parent = ref(null)
|
|
101
121
|
|
|
102
122
|
// composable
|
|
123
|
+
const {
|
|
124
|
+
hasBadges,
|
|
125
|
+
badgeParentClasses,
|
|
126
|
+
normalizedBadgesList,
|
|
127
|
+
getBadgeProps
|
|
128
|
+
} = useBadgeHandler()
|
|
129
|
+
|
|
103
130
|
const {
|
|
104
131
|
textContent,
|
|
105
132
|
isTruncated,
|
|
106
133
|
truncateText
|
|
107
|
-
} = useTruncate({ parent, props })
|
|
134
|
+
} = useTruncate({ parent, props, hasBadges })
|
|
108
135
|
|
|
109
136
|
const {
|
|
110
137
|
defaultProps,
|
|
@@ -122,6 +149,7 @@ const {
|
|
|
122
149
|
|
|
123
150
|
useMutationObserver({ truncate, callbackFn: truncateText })
|
|
124
151
|
|
|
152
|
+
// computeds
|
|
125
153
|
const classes = computed(() => [`text-${props.color}`, `text-${props.typography}`])
|
|
126
154
|
|
|
127
155
|
const formattedText = computed(() => props.list.length || props.text ? displayText.value : props.emptyText)
|
|
@@ -182,7 +210,7 @@ function useMutationObserver ({ truncate, callbackFn = () => {} }) {
|
|
|
182
210
|
}
|
|
183
211
|
}
|
|
184
212
|
|
|
185
|
-
function useTruncate ({ parent, props }) {
|
|
213
|
+
function useTruncate ({ parent, props, hasBadges }) {
|
|
186
214
|
// reactive vars
|
|
187
215
|
const maxPossibleWidth = ref('')
|
|
188
216
|
const textContent = ref('')
|
|
@@ -191,14 +219,19 @@ function useTruncate ({ parent, props }) {
|
|
|
191
219
|
// lifecycle
|
|
192
220
|
onMounted(() => truncateText())
|
|
193
221
|
|
|
194
|
-
// watch
|
|
195
|
-
watch(() => props.maxWidth, truncateText)
|
|
196
|
-
|
|
197
222
|
// computed
|
|
198
223
|
const isTruncated = computed(() => textWidth.value > maxPossibleWidth.value)
|
|
199
224
|
|
|
225
|
+
// watch
|
|
226
|
+
watch(() => props.maxWidth, truncateText)
|
|
227
|
+
|
|
200
228
|
// functions
|
|
201
|
-
function truncateText () {
|
|
229
|
+
async function truncateText () {
|
|
230
|
+
await nextTick()
|
|
231
|
+
|
|
232
|
+
// Se tiver badges, então não pode ser feito calculo de width.
|
|
233
|
+
if (hasBadges.value) return
|
|
234
|
+
|
|
202
235
|
parent.value.style.maxWidth = '100%'
|
|
203
236
|
textWidth.value = truncate.value.clientWidth
|
|
204
237
|
textContent.value = truncate.value?.innerHTML
|
|
@@ -271,4 +304,34 @@ function useCounter () {
|
|
|
271
304
|
counterLabel
|
|
272
305
|
}
|
|
273
306
|
}
|
|
307
|
+
|
|
308
|
+
function useBadgeHandler () {
|
|
309
|
+
const hasBadges = computed(() => props.useBadge && props.useObjectList && props.list.length)
|
|
310
|
+
|
|
311
|
+
const normalizedBadgesList = computed(() => props.list.slice(0, props.maxVisibleItem))
|
|
312
|
+
const badgeParentClasses = computed(() => ({ 'no-wrap': !props.useWrapBadge }))
|
|
313
|
+
|
|
314
|
+
function getBadgeProps (item) {
|
|
315
|
+
const itemProps = {}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* recupera somente keys que estão em baseProps do QasBadge
|
|
319
|
+
* pra evitar que passe propriedades desnecessárias
|
|
320
|
+
*/
|
|
321
|
+
for (const key in item) {
|
|
322
|
+
if (baseProps[key]) {
|
|
323
|
+
itemProps[key] = item[key]
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return itemProps
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return {
|
|
331
|
+
hasBadges,
|
|
332
|
+
badgeParentClasses,
|
|
333
|
+
normalizedBadgesList,
|
|
334
|
+
getBadgeProps
|
|
335
|
+
}
|
|
336
|
+
}
|
|
274
337
|
</script>
|