@bildvitta/quasar-ui-asteroid 3.17.0-beta.2 → 3.17.0-beta.21
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 +2 -2
- package/src/assets/sounds/nave-notification.mp3 +0 -0
- package/src/components/actions/QasActions.vue +1 -1
- package/src/components/app-menu/QasAppMenu.vue +6 -1
- package/src/components/avatar/QasAvatar.vue +7 -8
- package/src/components/board-generator/QasBoardGenerator.vue +407 -40
- package/src/components/board-generator/QasBoardGenerator.yml +53 -12
- package/src/components/btn-dropdown/QasBtnDropdown.vue +14 -1
- package/src/components/card/QasCard.vue +13 -4
- package/src/components/chart-view/QasChartView.vue +44 -20
- package/src/components/chart-view/QasChartView.yml +10 -0
- package/src/components/checkbox/QasCheckbox.vue +30 -9
- package/src/components/checkbox/QasCheckbox.yml +5 -0
- package/src/components/copy/QasCopy.vue +12 -2
- package/src/components/copy/QasCopy.yml +8 -0
- package/src/components/date-time-input/QasDateTimeInput.vue +1 -1
- package/src/components/dialog/QasDialog.vue +3 -3
- package/src/components/expansion-item/QasExpansionItem.vue +120 -34
- package/src/components/expansion-item/QasExpansionItem.yml +38 -5
- package/src/components/filters/QasFilters.vue +1 -1
- package/src/components/filters/private/PvFiltersButton.vue +1 -1
- package/src/components/form-generator/QasFormGenerator.vue +39 -27
- package/src/components/form-generator/QasFormGenerator.yml +3 -0
- package/src/components/grabbable/QasGrabbable.vue +14 -6
- package/src/components/grabbable/QasGrabbable.yml +4 -0
- package/src/components/grid-generator/QasGridGenerator.vue +67 -34
- package/src/components/grid-generator/QasGridGenerator.yml +15 -0
- package/src/components/header/QasHeader.vue +58 -12
- package/src/components/header/QasHeader.yml +5 -0
- package/src/components/infinite-scroll/QasInfiniteScroll.vue +16 -17
- package/src/components/infinite-scroll/QasInfiniteScroll.yml +7 -0
- package/src/components/list-items/QasListItems.vue +28 -4
- package/src/components/list-items/QasListItems.yml +10 -0
- package/src/components/list-view/QasListView.vue +17 -5
- package/src/components/list-view/QasListView.yml +9 -0
- package/src/components/nested-fields/QasNestedFields.vue +91 -36
- package/src/components/nested-fields/QasNestedFields.yml +23 -0
- package/src/components/radio/QasRadio.vue +24 -5
- package/src/components/radio/QasRadio.yml +6 -0
- package/src/components/select/QasSelect.vue +129 -5
- package/src/components/select/QasSelect.yml +11 -0
- package/src/components/stepper-form-view/QasStepperFormView.yml +1 -1
- package/src/components/table-generator/QasTableGenerator.vue +10 -1
- package/src/components/text-truncate/QasTextTruncate.vue +11 -4
- package/src/components/text-truncate/QasTextTruncate.yml +4 -0
- package/src/composables/private/use-generator.js +3 -9
- package/src/composables/use-notifications.js +14 -0
- package/src/css/components/field.scss +13 -6
- package/src/css/components/item.scss +5 -1
- package/src/enums/Spacing.js +33 -0
- package/src/helpers/set-scroll-on-grab.js +9 -1
|
@@ -1,31 +1,35 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
<component :is="component.is" v-bind="component.props">
|
|
3
|
+
<qas-header v-if="hasHeader" v-bind="props.headerProps" />
|
|
4
|
+
|
|
5
|
+
<div :class="classes">
|
|
6
|
+
<div v-for="(field, key) in fieldsByResult" :key="key" :class="getContainerClassses({ key })">
|
|
7
|
+
<slot :field="field" :name="`field-${field.name}`">
|
|
8
|
+
<qas-grid-item :use-ellipsis="hasEllipsis(field)" :use-inline="props.useInline">
|
|
9
|
+
<template #header>
|
|
10
|
+
<slot :field="field" :name="`header-field-${field.name}`">
|
|
11
|
+
<slot :field="field" name="header">
|
|
12
|
+
<div :class="headerClass" :data-cy="`grid-generator-${field.name}-field`" :title="getTitle(field, 'label')">
|
|
13
|
+
{{ field.label }}
|
|
14
|
+
</div>
|
|
15
|
+
</slot>
|
|
12
16
|
</slot>
|
|
13
|
-
</
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
</
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<template #content>
|
|
20
|
+
<slot :field="field" :name="`content-field-${field.name}`">
|
|
21
|
+
<slot :field="field" name="content">
|
|
22
|
+
<div :class="getContentClasses(field)" :data-cy="`grid-generator-${field.name}-result`" :title="getTitle(field, 'formattedResult')">
|
|
23
|
+
{{ field.formattedResult }}
|
|
24
|
+
</div>
|
|
25
|
+
</slot>
|
|
22
26
|
</slot>
|
|
23
|
-
</
|
|
24
|
-
</
|
|
25
|
-
</
|
|
26
|
-
</
|
|
27
|
+
</template>
|
|
28
|
+
</qas-grid-item>
|
|
29
|
+
</slot>
|
|
30
|
+
</div>
|
|
27
31
|
</div>
|
|
28
|
-
</
|
|
32
|
+
</component>
|
|
29
33
|
</template>
|
|
30
34
|
|
|
31
35
|
<script setup>
|
|
@@ -44,6 +48,11 @@ const screen = useScreen()
|
|
|
44
48
|
const props = defineProps({
|
|
45
49
|
...baseProps,
|
|
46
50
|
|
|
51
|
+
boxProps: {
|
|
52
|
+
type: Object,
|
|
53
|
+
default: () => ({})
|
|
54
|
+
},
|
|
55
|
+
|
|
47
56
|
contentClass: {
|
|
48
57
|
default: '',
|
|
49
58
|
type: [Array, Object, String]
|
|
@@ -54,6 +63,11 @@ const props = defineProps({
|
|
|
54
63
|
type: [Array, Object, String]
|
|
55
64
|
},
|
|
56
65
|
|
|
66
|
+
headerProps: {
|
|
67
|
+
type: Object,
|
|
68
|
+
default: () => ({})
|
|
69
|
+
},
|
|
70
|
+
|
|
57
71
|
emptyResultText: {
|
|
58
72
|
default: '-',
|
|
59
73
|
type: String
|
|
@@ -64,6 +78,10 @@ const props = defineProps({
|
|
|
64
78
|
type: Object
|
|
65
79
|
},
|
|
66
80
|
|
|
81
|
+
useBox: {
|
|
82
|
+
type: Boolean
|
|
83
|
+
},
|
|
84
|
+
|
|
67
85
|
useEmptyResult: {
|
|
68
86
|
default: true,
|
|
69
87
|
type: Boolean
|
|
@@ -85,15 +103,13 @@ const { classes, getFieldClass } = useGenerator({ props })
|
|
|
85
103
|
// computed
|
|
86
104
|
const hasResult = computed(() => Object.keys(props.result).length)
|
|
87
105
|
const hasFields = computed(() => Object.keys(props.fields).length)
|
|
106
|
+
const hasHeader = computed(() => Object.keys(props.headerProps).length)
|
|
88
107
|
|
|
89
|
-
const
|
|
90
|
-
return
|
|
91
|
-
props.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
ellipsis: !screen.isSmall && props.useEllipsis
|
|
95
|
-
}
|
|
96
|
-
]
|
|
108
|
+
const component = computed(() => {
|
|
109
|
+
return {
|
|
110
|
+
is: props.useBox ? 'qas-box' : 'div',
|
|
111
|
+
props: props.useBox ? props.boxProps : {}
|
|
112
|
+
}
|
|
97
113
|
})
|
|
98
114
|
|
|
99
115
|
const headerClass = computed(() => {
|
|
@@ -137,7 +153,7 @@ const formattedFields = computed(() => {
|
|
|
137
153
|
// watch
|
|
138
154
|
watch(() => formattedFields.value, setFieldsByResult, { immediate: true })
|
|
139
155
|
|
|
140
|
-
//
|
|
156
|
+
// functions
|
|
141
157
|
function getFieldsByResult () {
|
|
142
158
|
if (!hasResult.value || !hasFields.value) return {}
|
|
143
159
|
|
|
@@ -165,7 +181,7 @@ function setFieldsByResult () {
|
|
|
165
181
|
fieldsByResult.value = getFieldsByResult()
|
|
166
182
|
}
|
|
167
183
|
|
|
168
|
-
function
|
|
184
|
+
function getContainerClassses ({ key }) {
|
|
169
185
|
if (props.useInline) return 'row justify-between col-12'
|
|
170
186
|
|
|
171
187
|
return getFieldClass({ index: key, isGridGenerator: true })
|
|
@@ -174,4 +190,21 @@ function getContainerClass ({ key }) {
|
|
|
174
190
|
function getTitle (field, key) {
|
|
175
191
|
return props.useEllipsis ? field[key] : ''
|
|
176
192
|
}
|
|
193
|
+
|
|
194
|
+
function hasEllipsis (field) {
|
|
195
|
+
/**
|
|
196
|
+
* Para campos do tipo "textarea" vamos sempre exibir o conteúdo por completo.
|
|
197
|
+
*/
|
|
198
|
+
return (field.type === 'textarea') && !props.useInline ? false : props.useEllipsis
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function getContentClasses (field) {
|
|
202
|
+
return [
|
|
203
|
+
props.contentClass,
|
|
204
|
+
|
|
205
|
+
{
|
|
206
|
+
ellipsis: !screen.isSmall && hasEllipsis(field)
|
|
207
|
+
}
|
|
208
|
+
]
|
|
209
|
+
}
|
|
177
210
|
</script>
|
|
@@ -4,6 +4,11 @@ meta:
|
|
|
4
4
|
desc: Componente para criação de textos dinâmicos.
|
|
5
5
|
|
|
6
6
|
props:
|
|
7
|
+
box-props:
|
|
8
|
+
desc: Propriedades do "QasBox" que envolve o conteúdo.
|
|
9
|
+
default: {}
|
|
10
|
+
type: Object
|
|
11
|
+
|
|
7
12
|
columns:
|
|
8
13
|
desc: Colunas do grid de cada campo.
|
|
9
14
|
default: col-6
|
|
@@ -41,6 +46,11 @@ props:
|
|
|
41
46
|
default: 'text-bold'
|
|
42
47
|
type: [Array, Object, String]
|
|
43
48
|
|
|
49
|
+
header-props:
|
|
50
|
+
desc: Propriedades do "QasHeader".
|
|
51
|
+
default: {}
|
|
52
|
+
type: Object
|
|
53
|
+
|
|
44
54
|
result:
|
|
45
55
|
desc: Resultado contendo todas informações para serem exibidas na tela.
|
|
46
56
|
default: {}
|
|
@@ -52,6 +62,11 @@ props:
|
|
|
52
62
|
default: true
|
|
53
63
|
type: Boolean
|
|
54
64
|
|
|
65
|
+
use-box:
|
|
66
|
+
desc: Controla se o componente vai ter o QasBox englobando ou não.
|
|
67
|
+
default: false
|
|
68
|
+
type: Boolean
|
|
69
|
+
|
|
55
70
|
use-ellipsis:
|
|
56
71
|
desc: Adiciona a classe "ellipsis" para o elemento do conteúdo.
|
|
57
72
|
default: true
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="containerClasses">
|
|
3
|
-
<div v-if="hasLabelSection" class="items-center justify-between no-wrap row" :class="labelSectionClasses">
|
|
3
|
+
<div v-if="hasLabelSection" class="full-width items-center justify-between no-wrap row" :class="labelSectionClasses">
|
|
4
4
|
<div class="items-center q-col-gutter-sm row">
|
|
5
5
|
<slot name="label">
|
|
6
6
|
<qas-label v-if="hasLabel" v-bind="defaultLabelProps" />
|
|
@@ -13,25 +13,23 @@
|
|
|
13
13
|
</div>
|
|
14
14
|
</div>
|
|
15
15
|
|
|
16
|
-
<
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
</
|
|
16
|
+
<div v-if="hasActionsSection" class="text-right">
|
|
17
|
+
<slot name="actions">
|
|
18
|
+
<component :is="actionsComponent.is" v-if="hasActionsComponent" v-bind="actionsComponent.props" />
|
|
19
|
+
</slot>
|
|
20
|
+
</div>
|
|
21
21
|
</div>
|
|
22
22
|
|
|
23
|
-
<div class="items-start
|
|
23
|
+
<div class="items-start no-wrap q-col-gutter-sm row" :class="descriptionSectionClasses">
|
|
24
24
|
<div v-if="hasDescriptionSection" class="text-body1 text-grey-8">
|
|
25
25
|
<slot name="description">
|
|
26
26
|
{{ props.description }}
|
|
27
27
|
</slot>
|
|
28
28
|
</div>
|
|
29
29
|
|
|
30
|
-
<div v-if="!hasLabelSection" class="justify-end row">
|
|
30
|
+
<div v-if="!hasLabelSection" class="justify-end row text-right">
|
|
31
31
|
<slot name="actions">
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
<qas-btn v-if="hasDefaultButton" :use-label-on-small-screen="false" v-bind="props.buttonProps" />
|
|
32
|
+
<component :is="actionsComponent.is" v-if="hasActionsComponent" v-bind="actionsComponent.props" />
|
|
35
33
|
</slot>
|
|
36
34
|
</div>
|
|
37
35
|
</div>
|
|
@@ -67,6 +65,11 @@ const props = defineProps({
|
|
|
67
65
|
default: ''
|
|
68
66
|
},
|
|
69
67
|
|
|
68
|
+
filtersProps: {
|
|
69
|
+
default: () => ({}),
|
|
70
|
+
type: Object
|
|
71
|
+
},
|
|
72
|
+
|
|
70
73
|
labelProps: {
|
|
71
74
|
type: Object,
|
|
72
75
|
default: () => ({})
|
|
@@ -90,16 +93,59 @@ const labelSectionClasses = computed(() => {
|
|
|
90
93
|
}
|
|
91
94
|
})
|
|
92
95
|
|
|
96
|
+
const descriptionSectionClasses = computed(() => {
|
|
97
|
+
return {
|
|
98
|
+
'justify-between': hasDescriptionSection.value,
|
|
99
|
+
'justify-end': hasActionsSection.value && !hasDescriptionSection.value
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
|
|
93
103
|
const defaultLabelProps = computed(() => {
|
|
94
104
|
return {
|
|
95
|
-
margin:
|
|
105
|
+
margin: 'none',
|
|
96
106
|
...props.labelProps
|
|
97
107
|
}
|
|
98
108
|
})
|
|
99
109
|
|
|
110
|
+
const actionsComponent = computed(() => {
|
|
111
|
+
const component = {
|
|
112
|
+
[hasDefaultButton.value]: {
|
|
113
|
+
is: 'qas-btn',
|
|
114
|
+
props: {
|
|
115
|
+
...props.buttonProps,
|
|
116
|
+
useLabelOnSmallScreen: false
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
[hasDefaultActionsMenu.value]: {
|
|
121
|
+
is: 'qas-actions-menu',
|
|
122
|
+
props: props.actionsMenuProps
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
[hasDefaultFilters.value]: {
|
|
126
|
+
is: 'qas-filters',
|
|
127
|
+
props: {
|
|
128
|
+
useSearch: false,
|
|
129
|
+
useChip: false,
|
|
130
|
+
useSpacing: false,
|
|
131
|
+
...props.filtersProps
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return component.true
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
const hasActionsComponent = computed(() => {
|
|
140
|
+
return hasDefaultButton.value || hasDefaultActionsMenu.value || hasDefaultFilters.value
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
const hasActionsSection = computed(() => !!slots.actions || hasActionsComponent.value)
|
|
144
|
+
|
|
100
145
|
const hasBadges = computed(() => !!props.badges.length)
|
|
101
146
|
const hasLabel = computed(() => !!Object.keys(props.labelProps).length)
|
|
102
147
|
const hasDefaultButton = computed(() => !!Object.keys(props.buttonProps).length)
|
|
148
|
+
const hasDefaultFilters = computed(() => !!Object.keys(props.filtersProps).length)
|
|
103
149
|
const hasDefaultActionsMenu = computed(() => !!Object.keys(props.actionsMenuProps).length)
|
|
104
150
|
const hasDescriptionSection = computed(() => props.description || slots.description)
|
|
105
151
|
const hasLabelSection = computed(() => hasLabel.value || slots.label || hasBadges.value)
|
|
@@ -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: []
|
|
@@ -4,7 +4,18 @@
|
|
|
4
4
|
<q-item v-for="(item, index) in props.list" :key="index" :clickable="props.useClickableItem" @click="onClick({ item, index }, true)">
|
|
5
5
|
<slot :index="index" :item="item" name="item">
|
|
6
6
|
<q-item-section>
|
|
7
|
-
<slot :index="index" :item="item" name="item-section"
|
|
7
|
+
<slot :index="index" :item="item" name="item-section">
|
|
8
|
+
<qas-label
|
|
9
|
+
v-if="item[props.labelKey]"
|
|
10
|
+
:label="item[props.labelKey]"
|
|
11
|
+
:margin="getLabelMargin(item)"
|
|
12
|
+
typography="h5"
|
|
13
|
+
/>
|
|
14
|
+
|
|
15
|
+
<div v-if="item[props.descriptionKey]" class="text-body1">
|
|
16
|
+
{{ item[props.descriptionKey] }}
|
|
17
|
+
</div>
|
|
18
|
+
</slot>
|
|
8
19
|
</q-item-section>
|
|
9
20
|
|
|
10
21
|
<q-item-section v-if="props.useSectionActions" side>
|
|
@@ -26,11 +37,21 @@ import { computed } from 'vue'
|
|
|
26
37
|
defineOptions({ name: 'QasListItems' })
|
|
27
38
|
|
|
28
39
|
const props = defineProps({
|
|
40
|
+
descriptionKey: {
|
|
41
|
+
type: String,
|
|
42
|
+
default: 'description'
|
|
43
|
+
},
|
|
44
|
+
|
|
29
45
|
icon: {
|
|
30
46
|
type: String,
|
|
31
47
|
default: 'sym_r_chevron_right'
|
|
32
48
|
},
|
|
33
49
|
|
|
50
|
+
labelKey: {
|
|
51
|
+
type: String,
|
|
52
|
+
default: 'label'
|
|
53
|
+
},
|
|
54
|
+
|
|
34
55
|
list: {
|
|
35
56
|
default: () => [],
|
|
36
57
|
type: Array
|
|
@@ -57,17 +78,20 @@ const classes = computed(() => ({ 'qas-list-items--no-click': !props.useClickabl
|
|
|
57
78
|
|
|
58
79
|
const component = computed(() => props.useBox ? 'qas-box' : 'div')
|
|
59
80
|
|
|
81
|
+
// functions
|
|
60
82
|
function onClick ({ item, index }, fromItem) {
|
|
61
83
|
/**
|
|
62
84
|
* se o click veio do q-item e "useClickableItem" for "false", ou
|
|
63
85
|
* se o click não veio do q-item e "useClickableItem" for "true", então retorna sem emitir.
|
|
64
86
|
*/
|
|
65
|
-
if (
|
|
66
|
-
(fromItem && !props.useClickableItem) || (!fromItem && props.useClickableItem)
|
|
67
|
-
) return
|
|
87
|
+
if ((fromItem && !props.useClickableItem) || (!fromItem && props.useClickableItem)) return
|
|
68
88
|
|
|
69
89
|
emit('click-item', { item, index })
|
|
70
90
|
}
|
|
91
|
+
|
|
92
|
+
function getLabelMargin (item) {
|
|
93
|
+
return item[props.descriptionKey] ? 'xs' : 'none'
|
|
94
|
+
}
|
|
71
95
|
</script>
|
|
72
96
|
|
|
73
97
|
<style lang="scss">
|
|
@@ -4,11 +4,21 @@ meta:
|
|
|
4
4
|
desc: Componente para listagem.
|
|
5
5
|
|
|
6
6
|
props:
|
|
7
|
+
description-key:
|
|
8
|
+
desc: Chave para acessar a descrição do item.
|
|
9
|
+
default: description
|
|
10
|
+
type: String
|
|
11
|
+
|
|
7
12
|
icon:
|
|
8
13
|
desc: Nome do ícone
|
|
9
14
|
default: sym_r_chevron_right
|
|
10
15
|
type: String
|
|
11
16
|
|
|
17
|
+
label-key:
|
|
18
|
+
desc: Chave para acessar o label do item.
|
|
19
|
+
default: label
|
|
20
|
+
type: String
|
|
21
|
+
|
|
12
22
|
list:
|
|
13
23
|
desc: Lista para ser selecionada.
|
|
14
24
|
default: []
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
<main class="relative-position">
|
|
13
13
|
<div v-if="showResults">
|
|
14
14
|
<slot />
|
|
15
|
+
|
|
16
|
+
<q-inner-loading :showing="mx_isFetching">
|
|
17
|
+
<q-spinner color="grey" size="3em" />
|
|
18
|
+
</q-inner-loading>
|
|
15
19
|
</div>
|
|
16
20
|
|
|
17
21
|
<div v-else-if="!mx_isFetching">
|
|
@@ -29,10 +33,6 @@
|
|
|
29
33
|
<div v-if="hasPages" class="flex items-center q-mt-md" :class="paginationClasses">
|
|
30
34
|
<qas-pagination v-model="page" :max="totalPages" @click="changePage" />
|
|
31
35
|
</div>
|
|
32
|
-
|
|
33
|
-
<q-inner-loading :showing="hasResults && mx_isFetching">
|
|
34
|
-
<q-spinner color="grey" size="3em" />
|
|
35
|
-
</q-inner-loading>
|
|
36
36
|
</main>
|
|
37
37
|
</q-pull-to-refresh>
|
|
38
38
|
|
|
@@ -47,6 +47,7 @@ import debug from 'debug'
|
|
|
47
47
|
import { extend } from 'quasar'
|
|
48
48
|
import { getState, getAction } from '@bildvitta/store-adapter'
|
|
49
49
|
import { viewMixin, contextMixin } from '../../mixins'
|
|
50
|
+
import { computed } from 'vue'
|
|
50
51
|
|
|
51
52
|
const log = debug('asteroid-ui:qas-list-view')
|
|
52
53
|
|
|
@@ -58,6 +59,13 @@ export default {
|
|
|
58
59
|
|
|
59
60
|
mixins: [contextMixin, viewMixin],
|
|
60
61
|
|
|
62
|
+
provide () {
|
|
63
|
+
return {
|
|
64
|
+
isFetchListSucceeded: computed(() => this.isFetchListSucceeded),
|
|
65
|
+
isListView: true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
|
|
61
69
|
props: {
|
|
62
70
|
filtersProps: {
|
|
63
71
|
default: () => ({}),
|
|
@@ -107,7 +115,8 @@ export default {
|
|
|
107
115
|
data () {
|
|
108
116
|
return {
|
|
109
117
|
page: 1,
|
|
110
|
-
resultsQuantity: 0
|
|
118
|
+
resultsQuantity: 0,
|
|
119
|
+
isFetchListSucceeded: false
|
|
111
120
|
}
|
|
112
121
|
},
|
|
113
122
|
|
|
@@ -188,6 +197,7 @@ export default {
|
|
|
188
197
|
|
|
189
198
|
async fetchList (externalPayload = {}) {
|
|
190
199
|
this.mx_isFetching = true
|
|
200
|
+
this.isFetchListSucceeded = false
|
|
191
201
|
|
|
192
202
|
try {
|
|
193
203
|
const payload = {
|
|
@@ -215,6 +225,8 @@ export default {
|
|
|
215
225
|
metadata: this.mx_metadata
|
|
216
226
|
})
|
|
217
227
|
|
|
228
|
+
this.isFetchListSucceeded = true
|
|
229
|
+
|
|
218
230
|
this.$emit('fetch-success', response)
|
|
219
231
|
|
|
220
232
|
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
|