@bildvitta/quasar-ui-asteroid 3.15.0-beta.10 → 3.15.0-beta.12
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/card/QasCard.vue +5 -1
- package/src/components/form-generator/QasFormGenerator.vue +5 -1
- package/src/components/form-generator/QasFormGenerator.yml +4 -1
- package/src/components/grid-generator/QasGridGenerator.vue +68 -4
- package/src/components/grid-generator/QasGridGenerator.yml +13 -1
- package/src/components/stepper/QasStepper.vue +6 -2
- package/src/components/stepper-form-view/QasStepperFormView.vue +84 -0
- package/src/components/stepper-form-view/QasStepperFormView.yml +58 -0
- package/src/composables/private/use-generator.js +22 -1
- package/src/vue-plugin.js +3 -0
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<qas-actions-menu v-if="hasActions" :list="actionsMenuProps" :use-label="false" />
|
|
12
12
|
</div>
|
|
13
13
|
|
|
14
|
-
<div class="q-my-sm">
|
|
14
|
+
<div class="q-my-sm qas-card__content">
|
|
15
15
|
<slot name="default" />
|
|
16
16
|
</div>
|
|
17
17
|
|
|
@@ -97,6 +97,10 @@ const hasFooter = computed(() => hasFooterSlot.value || hasExpansion.value)
|
|
|
97
97
|
|
|
98
98
|
<style lang="scss">
|
|
99
99
|
.qas-card {
|
|
100
|
+
&__content {
|
|
101
|
+
max-width: 100%;
|
|
102
|
+
}
|
|
103
|
+
|
|
100
104
|
&__router {
|
|
101
105
|
&:hover {
|
|
102
106
|
color: $primary;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div :class="fieldsetClasses">
|
|
3
3
|
<div v-for="(fieldsetItem, fieldsetItemKey) in normalizedFields" :key="fieldsetItemKey" class="full-width">
|
|
4
4
|
<slot v-if="fieldsetItem.label" :name="`legend-${fieldsetItemKey}`">
|
|
5
|
-
<qas-label :label="fieldsetItem.label" />
|
|
5
|
+
<qas-label :label="fieldsetItem.label" :margin="getLabelMargin(fieldsetItem)" />
|
|
6
6
|
<div v-if="fieldsetItem.description" class="q-mb-md text-body1 text-grey-8">{{ fieldsetItem.description }}</div>
|
|
7
7
|
</slot>
|
|
8
8
|
|
|
@@ -180,4 +180,8 @@ function useFieldset ({ props }) {
|
|
|
180
180
|
hasFieldset
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
|
+
|
|
184
|
+
function getLabelMargin (fieldsetItem) {
|
|
185
|
+
return fieldsetItem.description ? 'sm' : 'md'
|
|
186
|
+
}
|
|
183
187
|
</script>
|
|
@@ -8,7 +8,7 @@ props:
|
|
|
8
8
|
desc: Colunas do grid de cada campo.
|
|
9
9
|
default: col-6
|
|
10
10
|
type: [Array, String, Object]
|
|
11
|
-
examples: ["[{ sm: 6, md: 12 }]", "{ name: { sm: 6, md: 12 } }", "12"]
|
|
11
|
+
examples: ["[{ sm: 6, md: 12 }]", "{ name: { sm: 6, md: 12 } }", "12", "{ sm: 6, md: 12 }"]
|
|
12
12
|
|
|
13
13
|
disable:
|
|
14
14
|
desc: Deixa os campos desabilitados enviando a prop "disable" para cada campo.
|
|
@@ -63,6 +63,9 @@ props:
|
|
|
63
63
|
default: []
|
|
64
64
|
type: Array
|
|
65
65
|
|
|
66
|
+
use-common-columns:
|
|
67
|
+
desc: Utilizado quando passar a estrutura da prop "columns" sendo um objeto onde seus breakpoints serão replicados para todos fields.
|
|
68
|
+
|
|
66
69
|
slots:
|
|
67
70
|
'field-[nome-da-chave]':
|
|
68
71
|
desc: Acessa o slot de um campo especifico.
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="classes">
|
|
3
|
-
<div v-for="(field, key) in fieldsByResult" :key="key" :class="
|
|
3
|
+
<div v-for="(field, key) in fieldsByResult" :key="key" :class="getContainerClass({ key })">
|
|
4
4
|
<slot :field="field" :name="`field-${field.name}`">
|
|
5
5
|
<slot :field="field" name="header">
|
|
6
|
-
<header :class="
|
|
6
|
+
<header :class="headerClass" :data-cy="`grid-generator-${field.name}-field`" :title="getTitle(field, 'label')">
|
|
7
7
|
{{ field.label }}
|
|
8
8
|
</header>
|
|
9
9
|
</slot>
|
|
10
10
|
|
|
11
11
|
<slot :field="field" name="content">
|
|
12
|
-
<div :class="
|
|
12
|
+
<div :class="contentClass" :data-cy="`grid-generator-${field.name}-result`" :title="getTitle(field, 'formattedResult')">
|
|
13
13
|
{{ field.formattedResult }}
|
|
14
14
|
</div>
|
|
15
15
|
</slot>
|
|
@@ -21,12 +21,15 @@
|
|
|
21
21
|
<script setup>
|
|
22
22
|
import useGenerator, { baseProps } from '../../composables/private/use-generator'
|
|
23
23
|
import { isEmpty, humanize } from '../../helpers'
|
|
24
|
+
import { useScreen } from '../../composables'
|
|
24
25
|
import { isObject } from 'lodash-es'
|
|
25
26
|
import { ref, computed, watch } from 'vue'
|
|
26
27
|
|
|
27
28
|
// define component name
|
|
28
29
|
defineOptions({ name: 'QasGridGenerator' })
|
|
29
30
|
|
|
31
|
+
const screen = useScreen()
|
|
32
|
+
|
|
30
33
|
// props
|
|
31
34
|
const props = defineProps({
|
|
32
35
|
...baseProps,
|
|
@@ -54,16 +57,65 @@ const props = defineProps({
|
|
|
54
57
|
useEmptyResult: {
|
|
55
58
|
default: true,
|
|
56
59
|
type: Boolean
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
useEllipsis: {
|
|
63
|
+
default: true,
|
|
64
|
+
type: Boolean
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
useInline: {
|
|
68
|
+
type: Boolean
|
|
57
69
|
}
|
|
58
70
|
})
|
|
59
71
|
|
|
60
72
|
// composables
|
|
61
|
-
const { classes, getFieldClass } = useGenerator({ props })
|
|
73
|
+
const { classes: useGeneratorClasses, getFieldClass } = useGenerator({ props })
|
|
62
74
|
|
|
63
75
|
// computed
|
|
64
76
|
const hasResult = computed(() => Object.keys(props.result).length)
|
|
65
77
|
const hasFields = computed(() => Object.keys(props.fields).length)
|
|
66
78
|
|
|
79
|
+
const contentClass = computed(() => {
|
|
80
|
+
if (!props.useEllipsis || (screen.isSmall && props.useEllipsis)) return props.contentClass
|
|
81
|
+
|
|
82
|
+
if (Array.isArray(props.contentClass)) {
|
|
83
|
+
return [...props.contentClass, 'ellipsis']
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (typeof props.contentClass === 'string') {
|
|
87
|
+
return `${props.contentClass} ellipsis`
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
...props.contentClass,
|
|
92
|
+
ellipsis: true
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
const headerClass = computed(() => {
|
|
97
|
+
if (!props.useEllipsis || (screen.isSmall && props.useEllipsis)) return props.headerClass
|
|
98
|
+
|
|
99
|
+
if (Array.isArray(props.headerClass)) {
|
|
100
|
+
return [...props.headerClass, 'ellipsis']
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (typeof props.headerClass === 'string') {
|
|
104
|
+
return `${props.headerClass} ellipsis`
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
...props.headerClass,
|
|
109
|
+
ellipsis: true
|
|
110
|
+
}
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
const classes = computed(() => {
|
|
114
|
+
if (props.useInline) return 'row q-col-gutter-md'
|
|
115
|
+
|
|
116
|
+
return useGeneratorClasses.value
|
|
117
|
+
})
|
|
118
|
+
|
|
67
119
|
const fieldsByResult = ref({})
|
|
68
120
|
|
|
69
121
|
/**
|
|
@@ -122,4 +174,16 @@ function getFieldsByResult () {
|
|
|
122
174
|
function setFieldsByResult () {
|
|
123
175
|
fieldsByResult.value = getFieldsByResult()
|
|
124
176
|
}
|
|
177
|
+
|
|
178
|
+
function getContainerClass ({ key }) {
|
|
179
|
+
if (props.useInline) {
|
|
180
|
+
return 'row justify-between col-12'
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return getFieldClass({ index: key, isGridGenerator: true })
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function getTitle (field, key) {
|
|
187
|
+
return props.useEllipsis ? field[key] : ''
|
|
188
|
+
}
|
|
125
189
|
</script>
|
|
@@ -8,7 +8,7 @@ props:
|
|
|
8
8
|
desc: Colunas do grid de cada campo.
|
|
9
9
|
default: col-6
|
|
10
10
|
type: [Array, String, Object]
|
|
11
|
-
examples: ["{ name: { sm: 6, md: 12 } }", "[{ sm: 6, md: 12 }]"]
|
|
11
|
+
examples: ["{ name: { sm: 6, md: 12 } }", "[{ sm: 6, md: 12 }]", "{ sm: 6, md: 12 }"]
|
|
12
12
|
|
|
13
13
|
content-class:
|
|
14
14
|
desc: Classe de cada "div" pai referente ao resultado.
|
|
@@ -48,6 +48,18 @@ props:
|
|
|
48
48
|
default: true
|
|
49
49
|
type: Boolean
|
|
50
50
|
|
|
51
|
+
use-ellipsis:
|
|
52
|
+
desc: Adiciona a classe "ellipsis" para o elemento do conteúdo.
|
|
53
|
+
default: true
|
|
54
|
+
type: Boolean
|
|
55
|
+
|
|
56
|
+
use-inline:
|
|
57
|
+
desc: Adiciona a disposição dos campos por linha, ou seja, header e content ocupando a linha toda.
|
|
58
|
+
type: Boolean
|
|
59
|
+
|
|
60
|
+
use-common-columns:
|
|
61
|
+
desc: Usado quando precisa passar a prop "columns" como objeto sendo que será o valor comum para todos fields
|
|
62
|
+
|
|
51
63
|
slots:
|
|
52
64
|
content:
|
|
53
65
|
desc: Slot para o conteúdo (content).
|
|
@@ -22,7 +22,7 @@ const props = defineProps({
|
|
|
22
22
|
},
|
|
23
23
|
|
|
24
24
|
modelValue: {
|
|
25
|
-
type: [
|
|
25
|
+
type: [String, Number],
|
|
26
26
|
default: 0
|
|
27
27
|
},
|
|
28
28
|
|
|
@@ -39,7 +39,7 @@ const screen = useScreen()
|
|
|
39
39
|
|
|
40
40
|
const emit = defineEmits(['update:modelValue'])
|
|
41
41
|
|
|
42
|
-
defineExpose({ next, previous })
|
|
42
|
+
defineExpose({ next, previous, goTo })
|
|
43
43
|
|
|
44
44
|
const model = computed({
|
|
45
45
|
get () {
|
|
@@ -63,6 +63,10 @@ function getContext (context) {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
function goTo (step) {
|
|
67
|
+
stepper.value.goTo(step)
|
|
68
|
+
}
|
|
69
|
+
|
|
66
70
|
function next () {
|
|
67
71
|
if (props.disable) return
|
|
68
72
|
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<qas-stepper ref="stepper" v-model="model" v-bind="stepperProps">
|
|
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]">
|
|
5
|
+
<component :is="step.component" />
|
|
6
|
+
</q-step>
|
|
7
|
+
</template>
|
|
8
|
+
</qas-stepper>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script setup>
|
|
12
|
+
import { ref, provide, computed } from 'vue'
|
|
13
|
+
|
|
14
|
+
defineOptions({ name: 'QasStepperFormView' })
|
|
15
|
+
|
|
16
|
+
const props = defineProps({
|
|
17
|
+
steps: {
|
|
18
|
+
type: Array,
|
|
19
|
+
required: true
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
formViewProps: {
|
|
23
|
+
type: Object,
|
|
24
|
+
default: () => ({})
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
stepperProps: {
|
|
28
|
+
type: Object,
|
|
29
|
+
default: () => ({})
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const model = defineModel({ type: Number, default: 1 })
|
|
34
|
+
|
|
35
|
+
const values = ref({})
|
|
36
|
+
const stepPropsList = ref([])
|
|
37
|
+
const stepper = ref(null)
|
|
38
|
+
|
|
39
|
+
setStepProps({ payload: [...props.steps.map(({ stepProps }) => stepProps)] })
|
|
40
|
+
|
|
41
|
+
const defaultFormViewProps = computed(() => {
|
|
42
|
+
return {
|
|
43
|
+
useBoundary: false,
|
|
44
|
+
useNotifySuccess: false,
|
|
45
|
+
...props.formViewProps
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
function setStepProps ({ step, payload }) {
|
|
50
|
+
if (step) {
|
|
51
|
+
stepPropsList.value[step - 1] = payload
|
|
52
|
+
} else {
|
|
53
|
+
stepPropsList.value = payload
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/*
|
|
58
|
+
* - Merge do payload com objetivo de enviar o payload completo de todos steps no stepper final
|
|
59
|
+
* - É possível ir para um step especifico ou somente ir para o próximo.
|
|
60
|
+
*/
|
|
61
|
+
function nextStep ({ payload = {} }) {
|
|
62
|
+
Object.assign(values.value, payload)
|
|
63
|
+
|
|
64
|
+
stepper.value.next()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isDone (stepIndex) {
|
|
68
|
+
return model.value > stepIndex + 1
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function getStepName (stepIndex) {
|
|
72
|
+
return stepIndex + 1
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
provide('stepper', {
|
|
76
|
+
stepperModel: model,
|
|
77
|
+
formViewProps: defaultFormViewProps,
|
|
78
|
+
goTo: step => stepper.value.goTo(step),
|
|
79
|
+
next: nextStep,
|
|
80
|
+
previous: () => stepper.value.previous(),
|
|
81
|
+
setStepProps,
|
|
82
|
+
stepsValues: values
|
|
83
|
+
})
|
|
84
|
+
</script>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
type: component
|
|
2
|
+
|
|
3
|
+
meta:
|
|
4
|
+
desc: Componente para steppers de formulário.
|
|
5
|
+
|
|
6
|
+
props:
|
|
7
|
+
steps:
|
|
8
|
+
desc: Lista de step, cada item possuindo "stepProps" e "component".
|
|
9
|
+
required: true
|
|
10
|
+
type: Array
|
|
11
|
+
|
|
12
|
+
form-view-props:
|
|
13
|
+
desc: Propriedades que serão repassadas para os componentes, podendo repassar coisas que serão comúm entre as páginas, como "entity", "mode".
|
|
14
|
+
type: Object
|
|
15
|
+
|
|
16
|
+
stepper-props:
|
|
17
|
+
desc: Propriedades que serão repassadas para o QasStepper.
|
|
18
|
+
type: Object
|
|
19
|
+
|
|
20
|
+
inject:
|
|
21
|
+
stepper-model:
|
|
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
|
+
type: Number
|
|
24
|
+
|
|
25
|
+
form-view-props:
|
|
26
|
+
desc: Propriedades do QasFormView que são comuns entre todos os steppers. Possui reatividade, portanto para acessar é necessário do ".value"
|
|
27
|
+
type: Object
|
|
28
|
+
|
|
29
|
+
'goTo: (step) => void':
|
|
30
|
+
desc: Função usada para mudar o step atual.
|
|
31
|
+
params:
|
|
32
|
+
step:
|
|
33
|
+
desc: Nome do step que deseja visualizar.
|
|
34
|
+
type: Number
|
|
35
|
+
|
|
36
|
+
'next: (payload) => void':
|
|
37
|
+
desc: Avança para o próximo step.
|
|
38
|
+
params:
|
|
39
|
+
payload:
|
|
40
|
+
desc: Payload do formulário atual, que será mergeado no "stepperValues", com a intenção de guardar o payload completo para ser enviado no último step.
|
|
41
|
+
type: Object
|
|
42
|
+
|
|
43
|
+
'previous: () => void':
|
|
44
|
+
desc: Volta para o step anterior.
|
|
45
|
+
|
|
46
|
+
'setStepProps: () => void':
|
|
47
|
+
desc: Altera as propriedades de um step específico caso precise que seja alterado com base em alguma lógica atual da página.
|
|
48
|
+
params:
|
|
49
|
+
step:
|
|
50
|
+
desc: Step que deseja alterar as propriedades
|
|
51
|
+
type: Number
|
|
52
|
+
|
|
53
|
+
payload:
|
|
54
|
+
desc: Propriedades do step como "title", "prefix", "caption", entre outros.
|
|
55
|
+
|
|
56
|
+
steps-values:
|
|
57
|
+
desc: Payload com todos valores que foram mergeados através da função "next" ao decorrer dos avanços dos steps. É usado para você recuperar no último step com intenção de enviar o payload completo de todos step para a API. Possui reatividade, portanto para acessar é necessário do ".value"
|
|
58
|
+
type: Object
|
|
@@ -19,6 +19,10 @@ export const baseProps = {
|
|
|
19
19
|
default: Spacing.Lg,
|
|
20
20
|
type: [String, Boolean],
|
|
21
21
|
validator: gutterValidator
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
useCommonColumns: {
|
|
25
|
+
type: Boolean
|
|
22
26
|
}
|
|
23
27
|
}
|
|
24
28
|
|
|
@@ -86,7 +90,11 @@ export default function ({ props = {} }) {
|
|
|
86
90
|
for (const key in formattedColumns) {
|
|
87
91
|
const value = formattedColumns[key]
|
|
88
92
|
|
|
89
|
-
|
|
93
|
+
if (IRREGULAR_CLASSES.includes(value)) {
|
|
94
|
+
classes.push(value === 'col' ? profiles[key] : value)
|
|
95
|
+
} else {
|
|
96
|
+
classes.push(`${profiles[key]}-${value}`)
|
|
97
|
+
}
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
return [...classes, renamedClasses]
|
|
@@ -103,10 +111,23 @@ export default function ({ props = {} }) {
|
|
|
103
111
|
* @private
|
|
104
112
|
*/
|
|
105
113
|
function _handleColumnsByField ({ index, isGridGenerator }) {
|
|
114
|
+
/*
|
|
115
|
+
* Quando é passado o columns como um único objeto que será replicado para todos fields.
|
|
116
|
+
*/
|
|
117
|
+
if (props.useCommonColumns && Object.keys(props.columns).length) {
|
|
118
|
+
return _getBreakpoint(props.columns)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/*
|
|
122
|
+
* Quando não é passado columns, retornará o default.
|
|
123
|
+
*/
|
|
106
124
|
if (!props.columns[index]) {
|
|
107
125
|
return _getDefaultColumnClass(isGridGenerator)
|
|
108
126
|
}
|
|
109
127
|
|
|
128
|
+
/*
|
|
129
|
+
* Quando é passado um objeto por field.
|
|
130
|
+
*/
|
|
110
131
|
return _getBreakpoint(props.columns[index])
|
|
111
132
|
}
|
|
112
133
|
|
package/src/vue-plugin.js
CHANGED
|
@@ -58,6 +58,7 @@ import QasSingleView from './components/single-view/QasSingleView.vue'
|
|
|
58
58
|
import QasSortable from './components/sortable/QasSortable.vue'
|
|
59
59
|
import QasStatus from './components/status/QasStatus.vue'
|
|
60
60
|
import QasStepper from './components/stepper/QasStepper.vue'
|
|
61
|
+
import QasStepperFormView from './components/stepper-form-view/QasStepperFormView.vue'
|
|
61
62
|
import QasTableGenerator from './components/table-generator/QasTableGenerator.vue'
|
|
62
63
|
import QasTabsGenerator from './components/tabs-generator/QasTabsGenerator.vue'
|
|
63
64
|
import QasTextTruncate from './components/text-truncate/QasTextTruncate.vue'
|
|
@@ -149,6 +150,7 @@ async function install (app) {
|
|
|
149
150
|
app.component('QasSortable', QasSortable)
|
|
150
151
|
app.component('QasStatus', QasStatus)
|
|
151
152
|
app.component('QasStepper', QasStepper)
|
|
153
|
+
app.component('QasStepperFormView', QasStepperFormView)
|
|
152
154
|
app.component('QasTableGenerator', QasTableGenerator)
|
|
153
155
|
app.component('QasTabsGenerator', QasTabsGenerator)
|
|
154
156
|
app.component('QasTextTruncate', QasTextTruncate)
|
|
@@ -241,6 +243,7 @@ export {
|
|
|
241
243
|
QasSortable,
|
|
242
244
|
QasStatus,
|
|
243
245
|
QasStepper,
|
|
246
|
+
QasStepperFormView,
|
|
244
247
|
QasTableGenerator,
|
|
245
248
|
QasTabsGenerator,
|
|
246
249
|
QasTextTruncate,
|