@bildvitta/quasar-ui-asteroid 3.17.0-beta.0 → 3.17.0-beta.10
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/actions/QasActions.vue +1 -1
- package/src/components/btn-dropdown/QasBtnDropdown.vue +14 -1
- package/src/components/chart-view/QasChartView.vue +43 -19
- package/src/components/chart-view/QasChartView.yml +10 -0
- package/src/components/date-time-input/QasDateTimeInput.vue +1 -1
- package/src/components/dialog/QasDialog.vue +6 -4
- package/src/components/expansion-item/QasExpansionItem.vue +100 -25
- package/src/components/expansion-item/QasExpansionItem.yml +35 -4
- package/src/components/filters/QasFilters.vue +1 -1
- package/src/components/filters/private/PvFiltersButton.vue +1 -1
- package/src/components/form-generator/QasFormGenerator.vue +51 -13
- package/src/components/form-generator/QasFormGenerator.yml +3 -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 +56 -12
- package/src/components/header/QasHeader.yml +5 -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 +4 -4
- package/src/components/nested-fields/QasNestedFields.vue +91 -36
- package/src/components/nested-fields/QasNestedFields.yml +23 -0
- package/src/components/search-input/QasSearchInput.vue +21 -2
- package/src/components/select/QasSelect.vue +154 -5
- package/src/components/select/QasSelect.yml +15 -0
- package/src/components/select-list-dialog/QasSelectListDialog.vue +14 -7
- package/src/components/table-generator/QasTableGenerator.vue +35 -1
- package/src/components/table-generator/QasTableGenerator.yml +9 -0
- 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/css/components/field.scss +13 -6
- package/src/css/components/item.scss +5 -1
- package/src/css/utils/border.scss +5 -0
- package/src/enums/Spacing.js +33 -0
package/package.json
CHANGED
|
@@ -72,7 +72,7 @@ const classes = computed(() => {
|
|
|
72
72
|
const columnClasses = computed(() => {
|
|
73
73
|
if (props.useEqualWidth) return 'col-12 col-sm-6'
|
|
74
74
|
|
|
75
|
-
return props.useFullWidth ? '
|
|
75
|
+
return props.useFullWidth ? 'full-width' : 'col-12 col-sm-auto'
|
|
76
76
|
})
|
|
77
77
|
|
|
78
78
|
const hasPrimarySlot = computed(() => !!slots.primary)
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
<div v-if="props.useSplit">
|
|
22
|
-
<qas-btn
|
|
22
|
+
<qas-btn v-bind="splittedButtonProps">
|
|
23
23
|
<q-menu v-if="hasDefaultSlot" anchor="bottom right" auto-close self="top right">
|
|
24
24
|
<div :class="classes.menuContent">
|
|
25
25
|
<slot />
|
|
@@ -103,6 +103,19 @@ const hasButtons = computed(() => !screen.isSmall || !props.useSplit)
|
|
|
103
103
|
const hasDefaultSlot = computed(() => !!slots.default)
|
|
104
104
|
const hasMenuOnLeftSide = computed(() => hasDefaultSlot.value && !props.useSplit && isSingleButton.value)
|
|
105
105
|
|
|
106
|
+
const splittedButtonProps = computed(() => {
|
|
107
|
+
const iconKey = screen.isSmall ? 'icon' : 'iconRight'
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
color: 'grey-10',
|
|
111
|
+
disable: props.disable,
|
|
112
|
+
[iconKey]: props.dropdownIcon,
|
|
113
|
+
variant: 'tertiary',
|
|
114
|
+
label: 'Opções',
|
|
115
|
+
useLabelOnSmallScreen: false
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
|
|
106
119
|
watch(() => props.menu, value => {
|
|
107
120
|
isMenuOpened.value = value
|
|
108
121
|
}, { immediate: true })
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
|
|
2
|
+
<component :is="parentComponent.is" v-bind="parentComponent.props">
|
|
3
|
+
<qas-header v-if="hasHeader" v-bind="headerProps">
|
|
4
|
+
<template #right>
|
|
5
|
+
<qas-filters v-bind="chartFiltersProps" />
|
|
6
|
+
</template>
|
|
7
|
+
</qas-header>
|
|
8
|
+
|
|
9
|
+
<div v-bind="parentComponentProps">
|
|
10
|
+
<component :is="chartComponent.is" v-if="showChart" v-bind="chartComponent.props" />
|
|
11
|
+
|
|
12
|
+
<div v-else-if="!isFetching">
|
|
13
|
+
<slot name="empty-results">
|
|
14
|
+
<qas-empty-result-text />
|
|
15
|
+
</slot>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<q-inner-loading :showing="isFetching">
|
|
19
|
+
<q-spinner color="grey" size="3em" />
|
|
20
|
+
</q-inner-loading>
|
|
15
21
|
</div>
|
|
16
|
-
|
|
17
|
-
<q-inner-loading :showing="isFetching">
|
|
18
|
-
<q-spinner color="grey" size="3em" />
|
|
19
|
-
</q-inner-loading>
|
|
20
|
-
</div>
|
|
22
|
+
</component>
|
|
21
23
|
</template>
|
|
22
24
|
|
|
23
25
|
<script>
|
|
@@ -69,6 +71,11 @@ export default {
|
|
|
69
71
|
type: Function
|
|
70
72
|
},
|
|
71
73
|
|
|
74
|
+
boxProps: {
|
|
75
|
+
default: () => ({}),
|
|
76
|
+
type: Object
|
|
77
|
+
},
|
|
78
|
+
|
|
72
79
|
colorsList: {
|
|
73
80
|
type: Array,
|
|
74
81
|
default: () => []
|
|
@@ -124,6 +131,11 @@ export default {
|
|
|
124
131
|
type: String
|
|
125
132
|
},
|
|
126
133
|
|
|
134
|
+
useBox: {
|
|
135
|
+
type: Boolean,
|
|
136
|
+
default: true
|
|
137
|
+
},
|
|
138
|
+
|
|
127
139
|
useFilterButton: {
|
|
128
140
|
type: Boolean
|
|
129
141
|
}
|
|
@@ -251,9 +263,11 @@ export default {
|
|
|
251
263
|
},
|
|
252
264
|
|
|
253
265
|
parentComponentProps () {
|
|
266
|
+
const hasMinHeight = this.isFetching || this.hasDataSets
|
|
267
|
+
|
|
254
268
|
return {
|
|
255
269
|
class: 'relative-position',
|
|
256
|
-
style: `min-height: ${this.height}`
|
|
270
|
+
style: `min-height: ${hasMinHeight ? this.height : 'auto'}`
|
|
257
271
|
}
|
|
258
272
|
},
|
|
259
273
|
|
|
@@ -308,6 +322,16 @@ export default {
|
|
|
308
322
|
label: this.title
|
|
309
323
|
}
|
|
310
324
|
}
|
|
325
|
+
},
|
|
326
|
+
|
|
327
|
+
parentComponent () {
|
|
328
|
+
return {
|
|
329
|
+
is: this.useBox ? 'qas-box' : 'div',
|
|
330
|
+
|
|
331
|
+
props: {
|
|
332
|
+
...(this.useBox && { ...this.boxProps })
|
|
333
|
+
}
|
|
334
|
+
}
|
|
311
335
|
}
|
|
312
336
|
},
|
|
313
337
|
|
|
@@ -10,6 +10,11 @@ props:
|
|
|
10
10
|
type: Function
|
|
11
11
|
examples: ['beforeFetch({ payload, resolve, done })']
|
|
12
12
|
|
|
13
|
+
box-props:
|
|
14
|
+
desc: Propriedades do "QasBox" que envolve o conteúdo.
|
|
15
|
+
default: {}
|
|
16
|
+
type: Object
|
|
17
|
+
|
|
13
18
|
colors-list:
|
|
14
19
|
desc: Lista de cores personalizadas para utilizar nos gráficos
|
|
15
20
|
default: []
|
|
@@ -65,6 +70,11 @@ props:
|
|
|
65
70
|
desc: Envia como parâmetro para a action "fetchList" do modulo correspondente a "entity".
|
|
66
71
|
type: String
|
|
67
72
|
|
|
73
|
+
use-box:
|
|
74
|
+
desc: Controla se o componente vai ter o QasBox englobando ou não.
|
|
75
|
+
default: true
|
|
76
|
+
type: Boolean
|
|
77
|
+
|
|
68
78
|
use-filter-button:
|
|
69
79
|
desc: Controla se o componente vai usar ou não o componente "QasFilters".
|
|
70
80
|
type: Boolean
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<qas-input ref="input" v-bind="attributes" v-model="currentValue" inputmode="numeric" :unmasked-value="false" @blur="validateDateTimeOnBlur" @focus="resetError" @update:model-value="updateModelValue">
|
|
3
3
|
<template #append>
|
|
4
|
-
<qas-btn v-if="!props.useTimeOnly" color="grey-10" :disable="attrs.readonly" icon="
|
|
4
|
+
<qas-btn v-if="!props.useTimeOnly" color="grey-10" :disable="attrs.readonly" icon="sym_r_calendar_today" variant="tertiary">
|
|
5
5
|
<q-popup-proxy ref="dateProxy" transition-hide="scale" transition-show="scale" v-bind="props.datePopupProxyProps">
|
|
6
6
|
<qas-date v-model="currentValue" v-bind="defaultDateProps" :mask="maskDate" width="290px" @update:model-value="updateModelValue" />
|
|
7
7
|
</q-popup-proxy>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<q-dialog ref="dialogRef" class="qas-dialog" :class="classes" data-cy="dialog" v-bind="dialogProps" :persistent="props.persistent" @update:model-value="updateModelValue">
|
|
3
|
-
<div class="bg-white q-pa-
|
|
4
|
-
<header v-if="hasHeader" class="q-mb-
|
|
3
|
+
<div class="bg-white q-pa-md" :style="style">
|
|
4
|
+
<header v-if="hasHeader" class="q-mb-md">
|
|
5
5
|
<slot name="header">
|
|
6
6
|
<div class="items-center justify-between row">
|
|
7
|
-
<
|
|
7
|
+
<qas-label data-cy="dialog-title" :label="props.card.title" margin="none" />
|
|
8
8
|
|
|
9
9
|
<qas-btn v-if="isInfoDialog" v-close-popup color="grey-10" data-cy="dialog-close-btn" icon="sym_r_close" variant="tertiary" />
|
|
10
10
|
</div>
|
|
@@ -45,7 +45,7 @@ import useDynamicComponents from './composables/use-dynamic-components'
|
|
|
45
45
|
import useOk from './composables/use-ok'
|
|
46
46
|
import { useScreen } from '../../composables'
|
|
47
47
|
|
|
48
|
-
import { computed, ref, useAttrs, useSlots } from 'vue'
|
|
48
|
+
import { computed, ref, useAttrs, useSlots, provide } from 'vue'
|
|
49
49
|
import { useDialogPluginComponent } from 'quasar'
|
|
50
50
|
|
|
51
51
|
defineOptions({ name: 'QasDialog' })
|
|
@@ -120,6 +120,8 @@ const emit = defineEmits([
|
|
|
120
120
|
...useDialogPluginComponent.emits
|
|
121
121
|
])
|
|
122
122
|
|
|
123
|
+
provide('isDialog', true)
|
|
124
|
+
|
|
123
125
|
const attrs = useAttrs()
|
|
124
126
|
const screen = useScreen()
|
|
125
127
|
const slots = useSlots()
|
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div ref="expansionItem" class="full-width qas-expansion-item" :class="
|
|
3
|
-
<component :is="component.is" class="qas-expansion-item__box">
|
|
4
|
-
<q-expansion-item header-class="text-bold q-mt-sm q-pa-none qas-expansion-item__header"
|
|
2
|
+
<div ref="expansionItem" class="full-width qas-expansion-item" :class="classes" v-bind="expansionProps.parent">
|
|
3
|
+
<component :is="component.is" class="qas-expansion-item__box" v-bind="boxProps">
|
|
4
|
+
<q-expansion-item v-model="modelValue" v-bind="expansionProps.item" header-class="text-bold q-mt-sm q-pa-none qas-expansion-item__header">
|
|
5
5
|
<template #header>
|
|
6
6
|
<slot name="header">
|
|
7
|
-
<div class="full-width">
|
|
8
|
-
<div
|
|
9
|
-
<slot name="
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
<div class="full-width justify-between no-wrap row">
|
|
8
|
+
<div>
|
|
9
|
+
<slot name="header-left">
|
|
10
|
+
<div class="items-center q-col-gutter-sm row">
|
|
11
|
+
<slot name="label">
|
|
12
|
+
<h5 class="col-auto qas-expansion-item__label text-h5">
|
|
13
|
+
{{ props.label }}
|
|
14
|
+
</h5>
|
|
15
|
+
</slot>
|
|
16
|
+
|
|
17
|
+
<div v-if="hasBadges" class="col-auto items-center q-col-gutter-sm row">
|
|
18
|
+
<div v-for="(badge, badgeIndex) in props.badges" :key="badgeIndex" class="col-auto">
|
|
19
|
+
<qas-badge v-bind="badge" />
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
14
23
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
<qas-badge v-bind="badge" />
|
|
24
|
+
<div v-if="hasHeaderBottom" class="q-mt-sm">
|
|
25
|
+
<slot name="header-bottom" />
|
|
18
26
|
</div>
|
|
19
|
-
</
|
|
27
|
+
</slot>
|
|
20
28
|
</div>
|
|
21
29
|
|
|
22
|
-
<
|
|
23
|
-
<slot name="header-bottom" />
|
|
24
|
-
</div>
|
|
30
|
+
<qas-btn class="qas-expansion-item__dropdown" color="grey-10" :disable="isDisabled" icon="sym_r_keyboard_arrow_up" />
|
|
25
31
|
</div>
|
|
26
32
|
</slot>
|
|
27
33
|
</template>
|
|
@@ -60,6 +66,14 @@ const props = defineProps({
|
|
|
60
66
|
default: () => []
|
|
61
67
|
},
|
|
62
68
|
|
|
69
|
+
disable: {
|
|
70
|
+
type: Boolean
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
disableButton: {
|
|
74
|
+
type: Boolean
|
|
75
|
+
},
|
|
76
|
+
|
|
63
77
|
error: {
|
|
64
78
|
type: Boolean
|
|
65
79
|
},
|
|
@@ -69,6 +83,11 @@ const props = defineProps({
|
|
|
69
83
|
default: ''
|
|
70
84
|
},
|
|
71
85
|
|
|
86
|
+
group: {
|
|
87
|
+
type: String,
|
|
88
|
+
default: ''
|
|
89
|
+
},
|
|
90
|
+
|
|
72
91
|
label: {
|
|
73
92
|
type: String,
|
|
74
93
|
default: ''
|
|
@@ -85,6 +104,8 @@ const props = defineProps({
|
|
|
85
104
|
}
|
|
86
105
|
})
|
|
87
106
|
|
|
107
|
+
const modelValue = defineModel({ type: Boolean })
|
|
108
|
+
|
|
88
109
|
const attrs = useAttrs()
|
|
89
110
|
|
|
90
111
|
provide('isExpansionItem', true)
|
|
@@ -100,11 +121,14 @@ onMounted(setHasNextSibling)
|
|
|
100
121
|
|
|
101
122
|
// constants
|
|
102
123
|
const isNestedExpansionItem = inject('isExpansionItem', false)
|
|
124
|
+
const isNestedBox = inject('isBox', false)
|
|
125
|
+
|
|
103
126
|
const component = {
|
|
104
127
|
is: isNestedExpansionItem ? 'div' : QasBox
|
|
105
128
|
}
|
|
106
129
|
|
|
107
130
|
// computed
|
|
131
|
+
const hasBadges = computed(() => !!props.badges.length)
|
|
108
132
|
const hasError = computed(() => props.error || !!props.errorMessage)
|
|
109
133
|
const hasGridGenerator = computed(() => !!Object.keys(props.gridGeneratorProps).length)
|
|
110
134
|
const hasBottomSeparator = computed(() => isNestedExpansionItem && hasNextSibling.value)
|
|
@@ -121,7 +145,13 @@ const hasHeaderSeparator = computed(() => {
|
|
|
121
145
|
return typeof props.useHeaderSeparator === 'undefined' ? !isNestedExpansionItem : props.useHeaderSeparator
|
|
122
146
|
})
|
|
123
147
|
|
|
124
|
-
const
|
|
148
|
+
const classes = computed(() => {
|
|
149
|
+
return {
|
|
150
|
+
'qas-expansion-item--error': hasError.value,
|
|
151
|
+
'qas-expansion-item--disabled': props.disable || props.disableButton,
|
|
152
|
+
'qas-expansion-item--disabled-full': props.disable
|
|
153
|
+
}
|
|
154
|
+
})
|
|
125
155
|
|
|
126
156
|
const contentClasses = computed(() => {
|
|
127
157
|
return {
|
|
@@ -142,11 +172,15 @@ const expansionProps = computed(() => {
|
|
|
142
172
|
} = attrs
|
|
143
173
|
|
|
144
174
|
return {
|
|
145
|
-
parent:
|
|
146
|
-
...propsPayload
|
|
147
|
-
},
|
|
175
|
+
parent: propsPayload,
|
|
148
176
|
|
|
149
177
|
item: {
|
|
178
|
+
disable: isDisabled.value,
|
|
179
|
+
hideExpandIcon: true,
|
|
180
|
+
label: props.label,
|
|
181
|
+
group: props.group,
|
|
182
|
+
|
|
183
|
+
// events
|
|
150
184
|
onUpdateModelValue,
|
|
151
185
|
onShow,
|
|
152
186
|
onBeforeShow,
|
|
@@ -157,6 +191,23 @@ const expansionProps = computed(() => {
|
|
|
157
191
|
}
|
|
158
192
|
})
|
|
159
193
|
|
|
194
|
+
const boxProps = computed(() => {
|
|
195
|
+
/**
|
|
196
|
+
* Caso o QasExpansionItem estiver dentro de um QasBox e não for um QasExpansionItem
|
|
197
|
+
* dentro de outro QasExpansionItem, o componente terá uma borda.
|
|
198
|
+
*/
|
|
199
|
+
const isBoxed = isNestedBox && !isNestedExpansionItem
|
|
200
|
+
|
|
201
|
+
if (!isBoxed) return {}
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
unelevated: isBoxed,
|
|
205
|
+
outlined: isBoxed
|
|
206
|
+
}
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
const isDisabled = computed(() => props.disable || props.disableButton)
|
|
210
|
+
|
|
160
211
|
// functions
|
|
161
212
|
|
|
162
213
|
/**
|
|
@@ -177,10 +228,16 @@ function setHasNextSibling (value) {
|
|
|
177
228
|
.qas-expansion-item {
|
|
178
229
|
$root: &;
|
|
179
230
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
231
|
+
&--disabled {
|
|
232
|
+
.q-item.disabled {
|
|
233
|
+
opacity: 1 !important;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
&--disabled-full {
|
|
238
|
+
#{$root}__label {
|
|
239
|
+
color: $grey-6 !important;
|
|
240
|
+
}
|
|
184
241
|
}
|
|
185
242
|
|
|
186
243
|
&--error {
|
|
@@ -193,6 +250,24 @@ function setHasNextSibling (value) {
|
|
|
193
250
|
}
|
|
194
251
|
}
|
|
195
252
|
|
|
253
|
+
// em alguns casos quando usado com grid, o espaçamento afetava o header, com z-index o problema é resolvido
|
|
254
|
+
&__header {
|
|
255
|
+
position: relative;
|
|
256
|
+
z-index: 1;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.q-expansion-item {
|
|
260
|
+
#{$root}__dropdown {
|
|
261
|
+
transition: transform var(--qas-generic-transition);;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
&--expanded {
|
|
265
|
+
#{$root}__dropdown {
|
|
266
|
+
transform: rotate(180deg);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
196
271
|
.q-item {
|
|
197
272
|
margin-top: 0;
|
|
198
273
|
min-height: auto;
|
|
@@ -8,6 +8,16 @@ props:
|
|
|
8
8
|
desc: Lista de badges que serão exibidas na parte superior do card.
|
|
9
9
|
type: Array
|
|
10
10
|
|
|
11
|
+
disable:
|
|
12
|
+
desc: Desabilita o componente e aplica estilo de desabilitado no label e no button.
|
|
13
|
+
default: false
|
|
14
|
+
type: Boolean
|
|
15
|
+
|
|
16
|
+
disable-button:
|
|
17
|
+
desc: Desabilita o componente sem aplicar o estilo de desabilitado no label (usar em casos onde não tem conteúdo no slot content).
|
|
18
|
+
default: false
|
|
19
|
+
type: Boolean
|
|
20
|
+
|
|
11
21
|
error:
|
|
12
22
|
desc: Booleano que caso seja true o card passa a ter uma borda vermelha.
|
|
13
23
|
type: Boolean
|
|
@@ -16,10 +26,20 @@ props:
|
|
|
16
26
|
desc: Mensagem de erro onde será exibida na parte inferior do card.
|
|
17
27
|
type: String
|
|
18
28
|
|
|
29
|
+
group:
|
|
30
|
+
desc: Agrupamento para estado aberto|fechado.
|
|
31
|
+
default: ''
|
|
32
|
+
type: String
|
|
33
|
+
|
|
19
34
|
label:
|
|
20
35
|
desc: Titulo exibido na parte superior do card.
|
|
21
36
|
type: String
|
|
22
37
|
|
|
38
|
+
model-value:
|
|
39
|
+
desc: Model que controla o estado aberto|fechado.
|
|
40
|
+
default: false
|
|
41
|
+
type: Boolean
|
|
42
|
+
|
|
23
43
|
grid-generator-props:
|
|
24
44
|
desc: Propriedades que serão repassadas para o QasGridGenerator.
|
|
25
45
|
type: Object
|
|
@@ -31,13 +51,24 @@ props:
|
|
|
31
51
|
|
|
32
52
|
slots:
|
|
33
53
|
header:
|
|
34
|
-
desc:
|
|
54
|
+
desc: Slot para substituir o conteúdo do header (incluindo o botão dropdown).
|
|
35
55
|
|
|
36
56
|
header-bottom:
|
|
37
|
-
desc:
|
|
57
|
+
desc: Slot para acessar o conteúdo que fica abaixo do header.
|
|
58
|
+
|
|
59
|
+
header-left:
|
|
60
|
+
desc: Slot para substituir o conteúdo do header á esquerda (não inclui o botão dropdown).
|
|
38
61
|
|
|
39
62
|
label:
|
|
40
|
-
desc:
|
|
63
|
+
desc: Slot para substituir o conteúdo da label do header.
|
|
41
64
|
|
|
42
65
|
content:
|
|
43
|
-
desc:
|
|
66
|
+
desc: Slot para substituir o conteúdo principal do card.
|
|
67
|
+
|
|
68
|
+
events:
|
|
69
|
+
'@update:model-value -> function(value)':
|
|
70
|
+
desc: Dispara quando o model-value altera, também usado para v-model.
|
|
71
|
+
params:
|
|
72
|
+
value:
|
|
73
|
+
desc: Novo valor do model.
|
|
74
|
+
type: Boolean
|
|
@@ -160,7 +160,7 @@ export default {
|
|
|
160
160
|
const field = { ...this.fields[key], ...this.formattedFieldsProps?.[decamelize(key)] }
|
|
161
161
|
const value = humanize(field, this.normalizeValues(filters[key], field?.multiple))
|
|
162
162
|
|
|
163
|
-
if (!value) continue
|
|
163
|
+
if (!value || (Array.isArray(value) && !value.length)) continue
|
|
164
164
|
|
|
165
165
|
const { label, name } = field
|
|
166
166
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<qas-btn data-cy="filters-btn" icon="sym_r_filter_alt" label="Filtrar" :use-label-on-small-screen="false" variant="tertiary">
|
|
3
|
-
<q-menu ref="menu" anchor="center right" class="full-width" max-width="270px"
|
|
3
|
+
<q-menu ref="menu" anchor="center right" class="full-width" max-width="270px" v-bind="menuProps" no-refocus self="top right">
|
|
4
4
|
<div v-if="loading" class="q-pa-xl text-center">
|
|
5
5
|
<q-spinner color="grey" size="2em" />
|
|
6
6
|
</div>
|
|
@@ -2,19 +2,25 @@
|
|
|
2
2
|
<div :class="fieldsetClasses">
|
|
3
3
|
<div v-for="(fieldsetItem, fieldsetItemKey) in normalizedFields" :key="fieldsetItemKey" :class="getFieldSetColumnClass(fieldsetItem.column)">
|
|
4
4
|
<component :is="containerComponent.is" v-bind="containerComponent.props">
|
|
5
|
-
<slot v-if="fieldsetItem.
|
|
6
|
-
<qas-
|
|
7
|
-
|
|
8
|
-
<div v-if="fieldsetItem.description" class="q-mb-md text-body1 text-grey-8">{{ fieldsetItem.description }}</div>
|
|
5
|
+
<slot v-if="fieldsetItem.__isFieldset" :name="`legend-${fieldsetItemKey}`">
|
|
6
|
+
<qas-header v-bind="getHeaderProps(fieldsetItem)" />
|
|
9
7
|
</slot>
|
|
10
8
|
|
|
11
9
|
<div>
|
|
12
10
|
<slot :fields="fieldsetItem.fields?.visible" :name="`legend-section-${fieldsetItemKey}`">
|
|
13
|
-
<div
|
|
14
|
-
<div
|
|
15
|
-
<
|
|
16
|
-
<
|
|
17
|
-
|
|
11
|
+
<div class="q-col-gutter-md row">
|
|
12
|
+
<div class="col">
|
|
13
|
+
<div :class="fieldContainerClasses">
|
|
14
|
+
<div v-for="(field, key) in fieldsetItem.fields.visible" :key="key" :class="getFieldClass({ index: key, fields: normalizedFields })">
|
|
15
|
+
<slot :field="field" :name="`field-${field.name}`">
|
|
16
|
+
<qas-field :disable="isFieldDisabled(field)" v-bind="props.fieldsProps[field.name]" :error="props.errors[key]" :field="field" :model-value="props.modelValue[field.name]" @update:model-value="updateModelValue({ key: field.name, value: $event })" />
|
|
17
|
+
</slot>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div v-if="hasButtonProps(fieldsetItem)" class="col-12 col-sm-auto items-end justify-end row">
|
|
23
|
+
<qas-btn v-bind="fieldsetItem.buttonProps" />
|
|
18
24
|
</div>
|
|
19
25
|
</div>
|
|
20
26
|
|
|
@@ -25,6 +31,8 @@
|
|
|
25
31
|
</div>
|
|
26
32
|
</slot>
|
|
27
33
|
</div>
|
|
34
|
+
|
|
35
|
+
<slot v-if="fieldsetItem.__isFieldset" :name="`legend-bottom-${fieldsetItemKey}`" />
|
|
28
36
|
</component>
|
|
29
37
|
</div>
|
|
30
38
|
</div>
|
|
@@ -34,6 +42,7 @@
|
|
|
34
42
|
import { gutterValidator } from '../../helpers/private/gutter-validator'
|
|
35
43
|
import useGenerator, { baseProps } from '../../composables/private/use-generator'
|
|
36
44
|
import { Spacing } from '../../enums/Spacing'
|
|
45
|
+
import { useScreen } from '../../composables'
|
|
37
46
|
import { computed, provide, inject } from 'vue'
|
|
38
47
|
|
|
39
48
|
defineOptions({ name: 'QasFormGenerator' })
|
|
@@ -96,6 +105,8 @@ const { classes, getFieldClass, getFieldSetColumnClass } = useGenerator({ props
|
|
|
96
105
|
|
|
97
106
|
const { fieldsetClasses, hasFieldset } = useFieldset({ props })
|
|
98
107
|
|
|
108
|
+
const screen = useScreen()
|
|
109
|
+
|
|
99
110
|
// constants
|
|
100
111
|
const hasNestedFormGenerator = inject('isFormGenerator', false)
|
|
101
112
|
|
|
@@ -162,7 +173,12 @@ const normalizedFields = computed(() => {
|
|
|
162
173
|
label: fieldsetItem.label,
|
|
163
174
|
description: fieldsetItem.description,
|
|
164
175
|
column: fieldsetItem.column,
|
|
165
|
-
|
|
176
|
+
buttonProps: fieldsetItem.buttonProps,
|
|
177
|
+
fields: { hidden: {}, visible: {} },
|
|
178
|
+
headerProps: fieldsetItem.headerProps,
|
|
179
|
+
|
|
180
|
+
// Indica que existe um fieldset para que o QasHeader possa ser renderizado
|
|
181
|
+
__isFieldset: true
|
|
166
182
|
}
|
|
167
183
|
|
|
168
184
|
fieldsetItem.fields.forEach(fieldName => {
|
|
@@ -181,13 +197,31 @@ const normalizedFields = computed(() => {
|
|
|
181
197
|
return fields
|
|
182
198
|
})
|
|
183
199
|
|
|
184
|
-
|
|
200
|
+
const fieldContainerClasses = computed(() => {
|
|
201
|
+
return [
|
|
202
|
+
...classes.value,
|
|
203
|
+
{
|
|
204
|
+
col: !screen.isSmall
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
// functions
|
|
185
210
|
function getFieldType ({ type }) {
|
|
186
211
|
return type === 'hidden' ? 'hidden' : 'visible'
|
|
187
212
|
}
|
|
188
213
|
|
|
189
|
-
function
|
|
190
|
-
return
|
|
214
|
+
function getHeaderProps (fieldsetItem) {
|
|
215
|
+
return {
|
|
216
|
+
description: fieldsetItem.description,
|
|
217
|
+
|
|
218
|
+
labelProps: {
|
|
219
|
+
...fieldsetItem.headerProps?.labelProps,
|
|
220
|
+
...(fieldsetItem.label && { label: fieldsetItem.label })
|
|
221
|
+
},
|
|
222
|
+
|
|
223
|
+
...fieldsetItem.headerProps
|
|
224
|
+
}
|
|
191
225
|
}
|
|
192
226
|
|
|
193
227
|
function isFieldDisabled ({ disable }) {
|
|
@@ -201,6 +235,10 @@ function updateModelValue ({ key, value }) {
|
|
|
201
235
|
emit('update:modelValue', models)
|
|
202
236
|
}
|
|
203
237
|
|
|
238
|
+
function hasButtonProps ({ buttonProps = {} }) {
|
|
239
|
+
return !!Object.keys(buttonProps).length
|
|
240
|
+
}
|
|
241
|
+
|
|
204
242
|
// composables
|
|
205
243
|
function useFieldset ({ props }) {
|
|
206
244
|
const fieldsetClasses = computed(() => {
|
|
@@ -97,6 +97,9 @@ slots:
|
|
|
97
97
|
default: {}
|
|
98
98
|
type: Object
|
|
99
99
|
|
|
100
|
+
'legend-bottom-[nome-da-chave]':
|
|
101
|
+
desc: Acessa o slot da seção abaixo do conteúdo do form de um fieldset específico.
|
|
102
|
+
|
|
100
103
|
events:
|
|
101
104
|
'@update:model-value -> function(value)':
|
|
102
105
|
desc: Dispara quando o model-value altera, também usado para v-model.
|