@bildvitta/quasar-ui-asteroid 3.0.0-beta.2 → 3.0.0-beta.20
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/dist/api/QasActionsMenu.json +15 -15
- package/dist/api/QasAppBar.json +4 -8
- package/dist/api/QasAppMenu.json +11 -7
- package/dist/api/QasBtn.json +8 -4
- package/dist/api/QasCard.json +17 -13
- package/dist/api/QasCheckboxGroup.json +8 -8
- package/dist/api/QasCopy.json +4 -4
- package/dist/api/QasDateTimeInput.json +16 -16
- package/dist/api/QasDelete.json +17 -17
- package/dist/api/QasDialog.json +24 -20
- package/dist/api/QasFilters.json +14 -14
- package/dist/api/QasFormGenerator.json +57 -26
- package/dist/api/QasFormView.json +115 -87
- package/dist/api/QasGallery.json +4 -4
- package/dist/api/QasGridGenerator.json +40 -39
- package/dist/api/QasInput.json +13 -13
- package/dist/api/QasListItems.json +18 -17
- package/dist/api/QasListView.json +67 -53
- package/dist/api/QasNestedFields.json +45 -35
- package/dist/api/QasNumericInput.json +31 -12
- package/dist/api/QasPageHeader.json +7 -7
- package/dist/api/QasPasswordInput.json +13 -13
- package/dist/api/QasPasswordStrengthChecker.json +12 -12
- package/dist/api/QasProfile.json +5 -5
- package/dist/api/QasResizer.json +11 -11
- package/dist/api/QasSearchBox.json +90 -8
- package/dist/api/QasSelect.json +92 -25
- package/dist/api/QasSelectList.json +16 -14
- package/dist/api/QasSignaturePad.json +1 -1
- package/dist/api/QasSignatureUploader.json +9 -9
- package/dist/api/QasSingleView.json +52 -43
- package/dist/api/QasSortable.json +20 -20
- package/dist/api/QasTableGenerator.json +5 -5
- package/dist/api/QasTabsGenerator.json +5 -2
- package/dist/api/QasTransfer.json +9 -9
- package/dist/api/QasUploader.json +22 -17
- package/dist/asteroid.cjs.css +1 -1
- package/dist/asteroid.cjs.js +3904 -3102
- package/dist/asteroid.cjs.min.js +2 -2
- package/dist/asteroid.esm.css +1 -1
- package/dist/asteroid.esm.js +3908 -3106
- package/dist/asteroid.esm.min.js +2 -2
- package/dist/asteroid.umd.css +1 -1
- package/dist/asteroid.umd.js +3907 -3106
- package/dist/asteroid.umd.min.js +2 -2
- package/dist/vetur/asteroid-attributes.json +387 -303
- package/dist/vetur/asteroid-tags.json +129 -108
- package/package.json +1 -1
- package/src/assets/gear.svg +27 -0
- package/src/components/actions/QasActions.vue +1 -5
- package/src/components/actions-menu/QasActionsMenu.vue +4 -10
- package/src/components/actions-menu/QasActionsMenu.yml +15 -15
- package/src/components/app-bar/QasAppBar.vue +18 -14
- package/src/components/app-bar/QasAppBar.yml +4 -8
- package/src/components/app-menu/QasAppMenu.vue +8 -7
- package/src/components/app-menu/QasAppMenu.yml +11 -7
- package/src/components/avatar/QasAvatar.vue +0 -4
- package/src/components/box/QasBox.vue +1 -1
- package/src/components/btn/QasBtn.vue +11 -15
- package/src/components/btn/QasBtn.yml +7 -3
- package/src/components/card/QasCard.vue +18 -9
- package/src/components/card/QasCard.yml +17 -13
- package/src/components/checkbox-group/QasCheckboxGroup.yml +9 -8
- package/src/components/copy/QasCopy.vue +1 -1
- package/src/components/copy/QasCopy.yml +4 -3
- package/src/components/date-time-input/QasDateTimeInput.vue +39 -41
- package/src/components/date-time-input/QasDateTimeInput.yml +16 -16
- package/src/components/delete/QasDelete.vue +15 -1
- package/src/components/delete/QasDelete.yml +15 -15
- package/src/components/dialog/QasDialog.vue +28 -9
- package/src/components/dialog/QasDialog.yml +22 -18
- package/src/components/dialog-router/QasDialogRouter.vue +1 -1
- package/src/components/field/QasField.vue +15 -14
- package/src/components/filters/QasFilters.vue +30 -13
- package/src/components/filters/QasFilters.yml +14 -14
- package/src/components/form-generator/QasFormGenerator.vue +87 -12
- package/src/components/form-generator/QasFormGenerator.yml +32 -18
- package/src/components/form-view/QasFormView.vue +142 -60
- package/src/components/form-view/QasFormView.yml +91 -67
- package/src/components/gallery/QasGallery.vue +4 -8
- package/src/components/gallery/QasGallery.yml +4 -4
- package/src/components/grid-generator/QasGridGenerator.vue +23 -7
- package/src/components/grid-generator/QasGridGenerator.yml +29 -27
- package/src/components/input/QasInput.vue +37 -21
- package/src/components/input/QasInput.yml +13 -13
- package/src/components/layout/QasLayout.vue +4 -0
- package/src/components/list-items/QasListItems.vue +16 -24
- package/src/components/list-items/QasListItems.yml +14 -15
- package/src/components/list-view/QasListView.vue +48 -20
- package/src/components/list-view/QasListView.yml +58 -46
- package/src/components/map/QasMap.vue +5 -5
- package/src/components/nested-fields/QasNestedFields.vue +29 -21
- package/src/components/nested-fields/QasNestedFields.yml +35 -28
- package/src/components/numeric-input/QasNumericInput.vue +45 -27
- package/src/components/numeric-input/QasNumericInput.yml +26 -12
- package/src/components/page-header/QasPageHeader.vue +14 -11
- package/src/components/page-header/QasPageHeader.yml +4 -4
- package/src/components/password-input/QasPasswordInput.vue +17 -16
- package/src/components/password-input/QasPasswordInput.yml +11 -11
- package/src/components/password-strength-checker/QasPasswordStrengthChecker.yml +10 -10
- package/src/components/profile/QasProfile.vue +3 -6
- package/src/components/profile/QasProfile.yml +5 -5
- package/src/components/resizer/QasResizer.vue +1 -1
- package/src/components/resizer/QasResizer.yml +6 -5
- package/src/components/search-box/QasSearchBox.vue +138 -42
- package/src/components/search-box/QasSearchBox.yml +74 -7
- package/src/components/select/QasSelect.vue +63 -53
- package/src/components/select/QasSelect.yml +68 -17
- package/src/components/select-list/QasSelectList.vue +13 -32
- package/src/components/select-list/QasSelectList.yml +13 -14
- package/src/components/signature-pad/QasSignaturePad.vue +1 -1
- package/src/components/signature-pad/QasSignaturePad.yml +1 -1
- package/src/components/signature-uploader/QasSignatureUploader.vue +13 -14
- package/src/components/signature-uploader/QasSignatureUploader.yml +9 -9
- package/src/components/single-view/QasSingleView.vue +24 -8
- package/src/components/single-view/QasSingleView.yml +45 -38
- package/src/components/sortable/QasSortable.yml +17 -17
- package/src/components/table-generator/QasTableGenerator.vue +14 -6
- package/src/components/table-generator/QasTableGenerator.yml +5 -5
- package/src/components/tabs-generator/QasTabsGenerator.vue +2 -2
- package/src/components/tabs-generator/QasTabsGenerator.yml +2 -2
- package/src/components/text-truncate/QasTextTruncate.vue +2 -5
- package/src/components/transfer/QasTransfer.vue +5 -7
- package/src/components/transfer/QasTransfer.yml +9 -9
- package/src/components/uploader/QasUploader.vue +63 -16
- package/src/components/uploader/QasUploader.yml +17 -12
- package/src/composables/index.js +1 -1
- package/src/composables/{useHistory.js → use-history.js} +0 -0
- package/src/css/components/base.scss +3 -0
- package/src/css/components/field.scss +4 -0
- package/src/css/components/index.scss +4 -0
- package/src/css/components/radio.scss +3 -0
- package/src/css/components/tabs.scss +3 -0
- package/src/css/mixins/index.scss +1 -0
- package/src/css/{set-brand.scss → mixins/set-brand.scss} +0 -0
- package/src/css/{background.scss → utils/background.scss} +0 -0
- package/src/css/{border-radius.scss → utils/border-radius.scss} +0 -0
- package/src/css/{border.scss → utils/border.scss} +0 -0
- package/src/css/{container.scss → utils/container.scss} +0 -0
- package/src/css/{fonts.scss → utils/fonts.scss} +0 -0
- package/src/css/utils/index.scss +9 -0
- package/src/css/{line-height.scss → utils/line-height.scss} +0 -0
- package/src/css/{opacity.scss → utils/opacity.scss} +0 -0
- package/src/css/{text.scss → utils/text.scss} +0 -0
- package/src/css/{unset.scss → utils/unset.scss} +0 -0
- package/src/css/variables/button.scss +3 -0
- package/src/css/variables/index.scss +3 -0
- package/src/css/variables/shadow.scss +33 -0
- package/src/css/variables/typography.scss +139 -0
- package/src/helpers/camelize-fields-name.js +15 -0
- package/src/helpers/filters.js +2 -0
- package/src/helpers/get-normalized-options.js +20 -0
- package/src/helpers/handle-process.js +13 -0
- package/src/helpers/index.js +3 -0
- package/src/index.scss +11 -12
- package/src/mixins/generator.js +10 -2
- package/src/mixins/index.js +3 -3
- package/src/mixins/search-filter.js +227 -0
- package/src/mixins/view.js +35 -13
- package/src/pages/ErrorComponent.vue +56 -0
- package/src/pages/Forbidden.vue +21 -5
- package/src/pages/NotFound.vue +21 -5
- package/src/pages/ServerError.vue +25 -0
- package/src/pages/Unauthorized.vue +28 -0
- package/src/plugins/index.js +4 -2
- package/src/plugins/logger/Logger.js +44 -0
- package/src/plugins/logger/Logger.yml +9 -0
- package/src/plugins/screen/Screen.js +5 -0
- package/src/vue-plugin.js +6 -3
- package/src/assets/logo-modular.svg +0 -1
- package/src/css/design-system.scss +0 -18
- package/src/css/shadow.scss +0 -7
- package/src/mixins/screen.js +0 -34
|
@@ -4,27 +4,46 @@ meta:
|
|
|
4
4
|
desc: Componente para criação de múltiplos campos dinâmicos a partir do componente `QasField`.
|
|
5
5
|
|
|
6
6
|
props:
|
|
7
|
+
columns:
|
|
8
|
+
desc: Colunas do grid de cada campo.
|
|
9
|
+
default: col-6
|
|
10
|
+
type: [Array, String, Object]
|
|
11
|
+
examples: ["{ name: { sm: 6, md: 12 } }", "[{ sm: 6, md: 12 }]"]
|
|
12
|
+
|
|
7
13
|
error:
|
|
8
14
|
desc: Objeto contendo propriedades contendo a mensagem de erro.
|
|
9
15
|
default: {}
|
|
10
16
|
type: Object
|
|
11
17
|
|
|
18
|
+
fields-props:
|
|
19
|
+
desc: Propriedade para repassar propriedades para cada campo individualmente.
|
|
20
|
+
default: {}
|
|
21
|
+
type: Object
|
|
22
|
+
examples: ["{ name: { dense: true, onClick: () => alert('Estou sendo clicado') } }"]
|
|
23
|
+
|
|
12
24
|
fields:
|
|
13
25
|
desc: Lista de field contendo informações necessárias para a criação do campo correspondente.
|
|
14
26
|
default: {}
|
|
15
27
|
type: Object
|
|
16
28
|
examples: ["{ email: { name: 'email', type: 'email', label: 'E-mail' } }"]
|
|
17
29
|
|
|
18
|
-
|
|
19
|
-
desc:
|
|
30
|
+
fieldset:
|
|
31
|
+
desc: Lista para agrupar elementos por rótulo (label).
|
|
20
32
|
default: {}
|
|
21
33
|
type: Object
|
|
22
|
-
examples: ["{
|
|
34
|
+
examples: ["{ personalInformation: { label: 'Informações pessoais', fields: [name, email] } }"]
|
|
23
35
|
|
|
24
|
-
|
|
25
|
-
desc:
|
|
26
|
-
default:
|
|
27
|
-
type:
|
|
36
|
+
fieldset-gutter:
|
|
37
|
+
desc: Espaçamento entre rótulos (label).
|
|
38
|
+
default: lg
|
|
39
|
+
type: [String, Boolean]
|
|
40
|
+
examples: [xs, sm, md, lg, xl, false]
|
|
41
|
+
|
|
42
|
+
gutter:
|
|
43
|
+
desc: Espaçamento entre colunas.
|
|
44
|
+
default: md
|
|
45
|
+
type: [String, Boolean]
|
|
46
|
+
examples: [xs, sm, md, lg, xl, false]
|
|
28
47
|
|
|
29
48
|
model-value:
|
|
30
49
|
desc: Model do componente, usado para o v-model.
|
|
@@ -34,17 +53,10 @@ props:
|
|
|
34
53
|
examples: [v-model="value"]
|
|
35
54
|
model: true
|
|
36
55
|
|
|
37
|
-
|
|
38
|
-
desc:
|
|
39
|
-
default:
|
|
40
|
-
type:
|
|
41
|
-
examples: ["{ name: { sm: 6, md: 12 } }", "[{ sm: 6, md: 12 }]"]
|
|
42
|
-
|
|
43
|
-
gutter:
|
|
44
|
-
desc: Espaçamento entre colunas.
|
|
45
|
-
default: md
|
|
46
|
-
type: String
|
|
47
|
-
examples: [xs, sm, md, lg, xl]
|
|
56
|
+
order:
|
|
57
|
+
desc: Altera ordem dos campos.
|
|
58
|
+
default: []
|
|
59
|
+
type: Array
|
|
48
60
|
|
|
49
61
|
slots:
|
|
50
62
|
'field-[nome-da-chave]':
|
|
@@ -54,6 +66,8 @@ slots:
|
|
|
54
66
|
desc: Payload do campo atual.
|
|
55
67
|
default: {}
|
|
56
68
|
type: Object
|
|
69
|
+
'legend-[nome-da-chave]':
|
|
70
|
+
desc: Acessa o slot de um rótulo (label).
|
|
57
71
|
|
|
58
72
|
events:
|
|
59
73
|
'@update:model-value -> function(value)':
|
|
@@ -4,16 +4,17 @@
|
|
|
4
4
|
<slot name="header" />
|
|
5
5
|
</header>
|
|
6
6
|
|
|
7
|
-
<q-form ref="form" @submit="
|
|
7
|
+
<q-form ref="form" @submit="submitHandler">
|
|
8
8
|
<slot />
|
|
9
9
|
|
|
10
|
-
<slot v-if="
|
|
10
|
+
<slot v-if="useActions" name="actions">
|
|
11
11
|
<div class="justify-end q-col-gutter-md q-my-lg row">
|
|
12
12
|
<div v-if="hasCancelButton" class="col-12 col-sm-2" :class="cancelButtonClass">
|
|
13
|
-
<qas-btn v-close-popup
|
|
13
|
+
<qas-btn v-close-popup class="full-width" :data-cy="`btnCancel-${entity}`" :disable="isCancelButtonDisabled" :label="cancelButtonLabel" outline type="button" @click="cancel" />
|
|
14
14
|
</div>
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
|
|
16
|
+
<div v-if="useSubmitButton" class="col-12 col-sm-2" :class="submitButtonClass">
|
|
17
|
+
<qas-btn class="full-width" :data-cy="`btnSave-${entity}`" :disable="disable" :label="submitButtonLabel" :loading="isSubmitting" type="submit" />
|
|
17
18
|
</div>
|
|
18
19
|
</div>
|
|
19
20
|
</slot>
|
|
@@ -42,7 +43,7 @@ import { NotifyError, NotifySuccess } from '../../plugins'
|
|
|
42
43
|
import QasBtn from '../btn/QasBtn.vue'
|
|
43
44
|
import QasDialog from '../dialog/QasDialog.vue'
|
|
44
45
|
|
|
45
|
-
import { viewMixin
|
|
46
|
+
import { viewMixin } from '../../mixins'
|
|
46
47
|
|
|
47
48
|
export default {
|
|
48
49
|
name: 'QasFormView',
|
|
@@ -52,10 +53,10 @@ export default {
|
|
|
52
53
|
QasDialog
|
|
53
54
|
},
|
|
54
55
|
|
|
55
|
-
mixins: [viewMixin
|
|
56
|
+
mixins: [viewMixin],
|
|
56
57
|
|
|
57
58
|
props: {
|
|
58
|
-
|
|
59
|
+
cancelButtonLabel: {
|
|
59
60
|
default: 'Cancelar',
|
|
60
61
|
type: String
|
|
61
62
|
},
|
|
@@ -79,16 +80,12 @@ export default {
|
|
|
79
80
|
type: String
|
|
80
81
|
},
|
|
81
82
|
|
|
82
|
-
readOnly: {
|
|
83
|
-
type: Boolean
|
|
84
|
-
},
|
|
85
|
-
|
|
86
83
|
route: {
|
|
87
84
|
default: () => ({}),
|
|
88
85
|
type: Object
|
|
89
86
|
},
|
|
90
87
|
|
|
91
|
-
|
|
88
|
+
useDialogOnUnsavedChanges: {
|
|
92
89
|
default: true,
|
|
93
90
|
type: Boolean
|
|
94
91
|
},
|
|
@@ -98,7 +95,7 @@ export default {
|
|
|
98
95
|
type: Array
|
|
99
96
|
},
|
|
100
97
|
|
|
101
|
-
|
|
98
|
+
submitButtonLabel: {
|
|
102
99
|
default: 'Salvar',
|
|
103
100
|
type: String
|
|
104
101
|
},
|
|
@@ -110,6 +107,26 @@ export default {
|
|
|
110
107
|
|
|
111
108
|
submitting: {
|
|
112
109
|
type: Boolean
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
useActions: {
|
|
113
|
+
default: true,
|
|
114
|
+
type: Boolean
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
useCancelButton: {
|
|
118
|
+
default: true,
|
|
119
|
+
type: Boolean
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
useSubmitButton: {
|
|
123
|
+
default: true,
|
|
124
|
+
type: Boolean
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
beforeSubmit: {
|
|
128
|
+
default: null,
|
|
129
|
+
type: Function
|
|
113
130
|
}
|
|
114
131
|
},
|
|
115
132
|
|
|
@@ -126,7 +143,6 @@ export default {
|
|
|
126
143
|
data () {
|
|
127
144
|
return {
|
|
128
145
|
cachedResult: {},
|
|
129
|
-
hasResult: false,
|
|
130
146
|
isSubmitting: false,
|
|
131
147
|
showDialog: false,
|
|
132
148
|
ignoreRouterGuard: false,
|
|
@@ -146,7 +162,7 @@ export default {
|
|
|
146
162
|
|
|
147
163
|
computed: {
|
|
148
164
|
cancelButtonClass () {
|
|
149
|
-
return this.
|
|
165
|
+
return this.$qas.screen.isSmall && 'order-last'
|
|
150
166
|
},
|
|
151
167
|
|
|
152
168
|
fetchURL () {
|
|
@@ -154,7 +170,7 @@ export default {
|
|
|
154
170
|
},
|
|
155
171
|
|
|
156
172
|
hasCancelButton () {
|
|
157
|
-
return !(typeof this.cancelRoute === 'boolean' && !this.cancelRoute)
|
|
173
|
+
return !(typeof this.cancelRoute === 'boolean' && !this.cancelRoute) && this.useCancelButton
|
|
158
174
|
},
|
|
159
175
|
|
|
160
176
|
id () {
|
|
@@ -173,37 +189,27 @@ export default {
|
|
|
173
189
|
return this.$route
|
|
174
190
|
},
|
|
175
191
|
|
|
176
|
-
|
|
177
|
-
return this.
|
|
192
|
+
submitButtonClass () {
|
|
193
|
+
return this.$qas.screen.isSmall && 'order-first'
|
|
178
194
|
},
|
|
179
195
|
|
|
180
196
|
isCancelButtonDisabled () {
|
|
181
197
|
return this.disable || this.isSubmitting
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
fieldsNameWithDefaultValue () {
|
|
185
|
-
return Object.keys(this.fields).filter(field => 'default' in this.fields[field])
|
|
186
198
|
}
|
|
187
199
|
},
|
|
188
200
|
|
|
189
201
|
watch: {
|
|
190
|
-
mx_fields (fields) {
|
|
191
|
-
const models = { ...this.getModelsByFields(fields), ...this.modelValue }
|
|
192
|
-
|
|
193
|
-
if (!this.hasResult && this.showDialogOnUnsavedChanges) {
|
|
194
|
-
this.cachedResult = extend(true, {}, models)
|
|
195
|
-
}
|
|
196
|
-
},
|
|
197
|
-
|
|
198
202
|
isSubmitting (value) {
|
|
199
203
|
this.$emit('update:submitting', value)
|
|
200
204
|
}
|
|
201
205
|
},
|
|
202
206
|
|
|
203
207
|
created () {
|
|
204
|
-
onBeforeRouteLeave(this.beforeRouteLeave)
|
|
208
|
+
this.useDialogOnUnsavedChanges && onBeforeRouteLeave(this.beforeRouteLeave)
|
|
209
|
+
|
|
205
210
|
window.addEventListener('delete-success', this.setIgnoreRouterGuard)
|
|
206
|
-
|
|
211
|
+
|
|
212
|
+
this.mx_fetchHandler({ form: true, id: this.id, url: this.fetchURL }, this.fetchSingle)
|
|
207
213
|
},
|
|
208
214
|
|
|
209
215
|
onUnmounted () {
|
|
@@ -212,14 +218,32 @@ export default {
|
|
|
212
218
|
|
|
213
219
|
methods: {
|
|
214
220
|
beforeRouteLeave (to, from, next) {
|
|
221
|
+
const clonedModelValue = extend(true, {}, this.modelValue)
|
|
222
|
+
const clonedCachedResult = extend(true, {}, this.cachedResult)
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Se a propriedade "useDialogOnUnsavedChanges" for false ou a variável
|
|
226
|
+
* "ignoreRouterGuard" for true, então **não** iremos checar se o usuário
|
|
227
|
+
* alterou algum campo antes de sair da pagina, senão iremos validar pela função isEqualWith
|
|
228
|
+
* e mostrar um dialog antes do usuário sair da página.
|
|
229
|
+
*/
|
|
215
230
|
if (
|
|
216
|
-
!this.
|
|
231
|
+
!this.useDialogOnUnsavedChanges ||
|
|
217
232
|
this.ignoreRouterGuard ||
|
|
218
|
-
isEqualWith(
|
|
233
|
+
isEqualWith(
|
|
234
|
+
clonedModelValue,
|
|
235
|
+
clonedCachedResult,
|
|
236
|
+
this.handleIgnoreKeysInUnsavedChanges
|
|
237
|
+
)
|
|
219
238
|
) {
|
|
220
239
|
return next()
|
|
221
240
|
}
|
|
222
241
|
|
|
242
|
+
this.$qas.logger.group(
|
|
243
|
+
'QasFormView - beforeRouteLeave -> dialog chamado, modelValue diferente do cachedResult',
|
|
244
|
+
[{ modelValue: clonedModelValue, cachedResult: clonedCachedResult }]
|
|
245
|
+
)
|
|
246
|
+
|
|
223
247
|
this.handleDialog(() => {
|
|
224
248
|
this.ignoreRouterGuard = true
|
|
225
249
|
next()
|
|
@@ -227,41 +251,64 @@ export default {
|
|
|
227
251
|
},
|
|
228
252
|
|
|
229
253
|
cancel () {
|
|
230
|
-
|
|
231
|
-
this.handleCancelRoute()
|
|
232
|
-
}
|
|
254
|
+
this.handleCancelRoute()
|
|
233
255
|
},
|
|
234
256
|
|
|
235
|
-
async
|
|
257
|
+
async fetchSingle (externalPayload = {}) {
|
|
236
258
|
this.mx_isFetching = true
|
|
237
259
|
|
|
238
260
|
try {
|
|
239
|
-
const
|
|
240
|
-
|
|
261
|
+
const payload = {
|
|
262
|
+
form: true,
|
|
263
|
+
id: this.id,
|
|
264
|
+
url: this.fetchURL,
|
|
265
|
+
...externalPayload
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
this.$qas.logger.group(
|
|
269
|
+
`QasFormView - fetchSingle -> payload do parâmetro do ${this.entity}/fetchSingle`, [payload]
|
|
241
270
|
)
|
|
242
271
|
|
|
272
|
+
const response = await this.$store.dispatch(`${this.entity}/fetchSingle`, payload)
|
|
273
|
+
|
|
243
274
|
const { errors, fields, metadata, result } = response.data
|
|
244
275
|
|
|
276
|
+
const modelValue = { ...this.getModelsByFields(fields), ...this.modelValue }
|
|
277
|
+
|
|
245
278
|
this.mx_setErrors(errors)
|
|
246
279
|
this.mx_setFields(fields)
|
|
247
280
|
this.mx_setMetadata(metadata)
|
|
248
281
|
|
|
249
282
|
this.mx_updateModels({
|
|
250
|
-
errors
|
|
283
|
+
errors,
|
|
251
284
|
fields: this.mx_fields,
|
|
252
285
|
metadata
|
|
253
286
|
})
|
|
254
287
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
288
|
+
result && Object.assign(modelValue, result)
|
|
289
|
+
|
|
290
|
+
this.$qas.logger.group(
|
|
291
|
+
`QasFormView - fetchSingle -> resposta da action ${this.entity}/fetchSingle`, [response]
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
if (this.useDialogOnUnsavedChanges) {
|
|
295
|
+
this.cachedResult = extend(true, {}, result || modelValue)
|
|
296
|
+
this.$qas.logger.group('QasFormView - fetchSingle -> cachedResult', [this.cachedResult])
|
|
259
297
|
}
|
|
260
298
|
|
|
299
|
+
this.$emit('update:modelValue', modelValue)
|
|
261
300
|
this.$emit('fetch-success', response, this.modelValue)
|
|
301
|
+
|
|
302
|
+
this.$qas.logger.group('QasFormView - fetchSingle -> modelValue', [modelValue])
|
|
262
303
|
} catch (error) {
|
|
263
304
|
this.mx_fetchError(error)
|
|
264
305
|
this.$emit('fetch-error', error)
|
|
306
|
+
|
|
307
|
+
this.$qas.logger.group(
|
|
308
|
+
`QasFormView - fetchSingle -> exceção da action ${this.entity}/fetchSingle`,
|
|
309
|
+
[error],
|
|
310
|
+
{ error: true }
|
|
311
|
+
)
|
|
265
312
|
} finally {
|
|
266
313
|
this.mx_isFetching = false
|
|
267
314
|
}
|
|
@@ -298,6 +345,7 @@ export default {
|
|
|
298
345
|
const { addRoute } = useHistory()
|
|
299
346
|
|
|
300
347
|
this.defaultDialogProps.ok.onClick = () => addRoute(this.$route)
|
|
348
|
+
|
|
301
349
|
this.defaultDialogProps.cancel.onClick = next
|
|
302
350
|
},
|
|
303
351
|
|
|
@@ -307,48 +355,76 @@ export default {
|
|
|
307
355
|
|
|
308
356
|
// ignora chaves na hora de validar quando usuário está saindo da página
|
|
309
357
|
handleIgnoreKeysInUnsavedChanges (firstValue, secondValue) {
|
|
310
|
-
|
|
311
|
-
...this.fieldsNameWithDefaultValue,
|
|
312
|
-
...this.ignoreKeysInUnsavedChanges
|
|
313
|
-
]
|
|
358
|
+
if (!this.ignoreKeysInUnsavedChanges.length) return
|
|
314
359
|
|
|
315
|
-
|
|
360
|
+
this.ignoreKeysInUnsavedChanges.forEach(key => {
|
|
361
|
+
if (!firstValue) return
|
|
316
362
|
|
|
317
|
-
toIgnore.forEach(key => {
|
|
318
363
|
delete firstValue[key]
|
|
319
364
|
delete secondValue[key]
|
|
320
365
|
})
|
|
321
366
|
},
|
|
322
367
|
|
|
323
|
-
|
|
368
|
+
/**
|
|
369
|
+
* Se existe a propriedade com callback "beforeSubmit", então o controle de quando e como chamar o método "submit"
|
|
370
|
+
* está sendo controlado fora do QasFormView, se não existir a propriedade "beforeSubmit", então o controle do método
|
|
371
|
+
* submit é feito pelo próprio QasFormView, chamado pelo evento @submit.
|
|
372
|
+
*/
|
|
373
|
+
submitHandler (event) {
|
|
324
374
|
if (event) {
|
|
325
375
|
event.preventDefault()
|
|
326
376
|
}
|
|
327
377
|
|
|
328
|
-
|
|
329
|
-
|
|
378
|
+
const hasBeforeSubmit = typeof this.beforeSubmit === 'function'
|
|
379
|
+
|
|
380
|
+
if (hasBeforeSubmit) {
|
|
381
|
+
return this.beforeSubmit({
|
|
382
|
+
payload: { id: this.id, payload: this.modelValue, url: this.url },
|
|
383
|
+
resolve: payload => this.submit(payload)
|
|
384
|
+
})
|
|
330
385
|
}
|
|
331
386
|
|
|
387
|
+
this.submit()
|
|
388
|
+
},
|
|
389
|
+
|
|
390
|
+
async submit (externalPayload = {}) {
|
|
391
|
+
if (this.disable) return null
|
|
392
|
+
|
|
332
393
|
this.isSubmitting = true
|
|
333
394
|
|
|
334
395
|
try {
|
|
335
|
-
const
|
|
336
|
-
|
|
337
|
-
|
|
396
|
+
const payload = {
|
|
397
|
+
id: this.id,
|
|
398
|
+
payload: this.modelValue,
|
|
399
|
+
url: this.url,
|
|
400
|
+
...externalPayload
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
this.$qas.logger.group(
|
|
404
|
+
`QasFormView - submit -> payload do ${this.entity}/${this.mode}`, [payload]
|
|
338
405
|
)
|
|
339
406
|
|
|
340
|
-
|
|
407
|
+
const response = await this.$store.dispatch(`${this.entity}/${this.mode}`, payload)
|
|
408
|
+
|
|
409
|
+
if (this.useDialogOnUnsavedChanges) {
|
|
341
410
|
this.cachedResult = extend(true, {}, this.modelValue)
|
|
342
411
|
}
|
|
343
412
|
|
|
344
413
|
this.mx_setErrors()
|
|
345
414
|
NotifySuccess(response.data.status.text || 'Item salvo com sucesso!')
|
|
346
415
|
this.$emit('submit-success', response, this.modelValue)
|
|
416
|
+
|
|
417
|
+
this.$qas.logger.group(
|
|
418
|
+
`QasFormView - submit -> resposta da action ${this.entity}/${this.mode}`, [response]
|
|
419
|
+
)
|
|
347
420
|
} catch (error) {
|
|
348
421
|
const errors = error?.response?.data?.errors
|
|
349
422
|
const message = error?.response?.data?.status?.text
|
|
350
423
|
const exceptionResponse = error?.response?.data?.exception
|
|
351
|
-
|
|
424
|
+
|
|
425
|
+
const exception = errors
|
|
426
|
+
? 'Existem erros de validação no formulário.'
|
|
427
|
+
: exceptionResponse || error.message
|
|
352
428
|
|
|
353
429
|
this.mx_setErrors(errors)
|
|
354
430
|
this.$emit('update:errors', this.mx_errors)
|
|
@@ -356,6 +432,12 @@ export default {
|
|
|
356
432
|
NotifyError(message || 'Ops! Erro ao salvar item.', exception)
|
|
357
433
|
|
|
358
434
|
this.$emit('submit-error', error)
|
|
435
|
+
|
|
436
|
+
this.$qas.logger.group(
|
|
437
|
+
`QasFormView - submit -> exceção da action ${this.entity}/${this.mode}`,
|
|
438
|
+
[error],
|
|
439
|
+
{ error: true }
|
|
440
|
+
)
|
|
359
441
|
} finally {
|
|
360
442
|
this.isSubmitting = false
|
|
361
443
|
}
|
|
@@ -4,7 +4,19 @@ meta:
|
|
|
4
4
|
desc: Componente para C.R.U.D. responsável pela pela criação (Create) e edição (Update).
|
|
5
5
|
|
|
6
6
|
props:
|
|
7
|
-
|
|
7
|
+
before-fetch:
|
|
8
|
+
desc: Callback para controlar como funciona o comportamento do fetch.
|
|
9
|
+
default: null
|
|
10
|
+
type: Function
|
|
11
|
+
examples: ['beforeFetch({ payload, resolve })']
|
|
12
|
+
|
|
13
|
+
before-submit:
|
|
14
|
+
desc: Callback para controlar como funciona o comportamento do submit.
|
|
15
|
+
default: null
|
|
16
|
+
type: Function
|
|
17
|
+
examples: ['beforeSubmit({ payload, resolve })']
|
|
18
|
+
|
|
19
|
+
cancel-button-label:
|
|
8
20
|
desc: Rótulo do botão "cancelar".
|
|
9
21
|
default: Cancelar
|
|
10
22
|
type: String
|
|
@@ -29,25 +41,30 @@ props:
|
|
|
29
41
|
desc: Desabilita o submit.
|
|
30
42
|
type: Boolean
|
|
31
43
|
|
|
32
|
-
|
|
33
|
-
desc:
|
|
34
|
-
|
|
44
|
+
entity:
|
|
45
|
+
desc: Entidade da store, por exemplo se tiver que trabalhar com modulo de usuários, teremos o model "users" na store, que vai ser nossa "entity".
|
|
46
|
+
required: true
|
|
35
47
|
type: String
|
|
36
|
-
examples: [create, replace, update]
|
|
37
|
-
|
|
38
|
-
read-only:
|
|
39
|
-
desc: Controla o slot de actions.
|
|
40
|
-
type: Boolean
|
|
41
48
|
|
|
42
|
-
|
|
43
|
-
desc:
|
|
49
|
+
errors:
|
|
50
|
+
desc: Model de errors, utilizado para recuperar os errors fora do template.
|
|
44
51
|
default: {}
|
|
45
52
|
type: Object
|
|
53
|
+
examples: [v-model:errors="errors"]
|
|
54
|
+
model: true
|
|
46
55
|
|
|
47
|
-
|
|
48
|
-
desc:
|
|
49
|
-
default: true
|
|
56
|
+
fetching:
|
|
57
|
+
desc: Model de fetching, utilizado para saber se o componente está fazendo fetching de dados.
|
|
50
58
|
type: Boolean
|
|
59
|
+
examples: [v-model:fetching="isFetching"]
|
|
60
|
+
model: true
|
|
61
|
+
|
|
62
|
+
fields:
|
|
63
|
+
desc: Model de fields, utilizado para recuperar os fields fora do template.
|
|
64
|
+
default: {}
|
|
65
|
+
type: Object
|
|
66
|
+
examples: [v-model:fields="fields"]
|
|
67
|
+
model: true
|
|
51
68
|
|
|
52
69
|
ignore-keys-in-unsaved-changes:
|
|
53
70
|
desc: Vamos imaginar um cenário onde você precisa alterar valores do v-model por qualquer motivo que seja, mas quando o usuário sair da tela, não pode aparecer o modal perguntando se ele quer sair ou continuar editando, por que o usuário de fato não fez nenhuma alteração nos dados, esta prop serve para você dizer quais keys dentro do v-model você quer ignorar.
|
|
@@ -55,10 +72,18 @@ props:
|
|
|
55
72
|
type: Array
|
|
56
73
|
examples: ["['isActive']"]
|
|
57
74
|
|
|
58
|
-
|
|
59
|
-
desc:
|
|
60
|
-
default:
|
|
75
|
+
metadata:
|
|
76
|
+
desc: Model de metadata, utilizado para recuperar os metadata fora do template.
|
|
77
|
+
default: {}
|
|
78
|
+
type: Object
|
|
79
|
+
examples: [v-model:metadata="metadata"]
|
|
80
|
+
model: true
|
|
81
|
+
|
|
82
|
+
mode:
|
|
83
|
+
desc: Existem 3 modos no QasFormView, para criação (create) (equivalente a um método POST no http), e edição que são 2 diferentes, replace (equivalente a um método PUT no http) e update (equivalente a um método PATCH no http).
|
|
84
|
+
default: create
|
|
61
85
|
type: String
|
|
86
|
+
examples: [create, replace, update]
|
|
62
87
|
|
|
63
88
|
model-value:
|
|
64
89
|
desc: Model do componente, controla o payload que será enviado para as actions dos modos create, replace e update.
|
|
@@ -67,66 +92,79 @@ props:
|
|
|
67
92
|
examples: [v-model="values"]
|
|
68
93
|
model: true
|
|
69
94
|
|
|
95
|
+
route:
|
|
96
|
+
desc: Você pode passar uma configuração de rota customizada.
|
|
97
|
+
default: {}
|
|
98
|
+
type: Object
|
|
99
|
+
|
|
100
|
+
submit-button-label:
|
|
101
|
+
desc: Rótulo do botão "salvar".
|
|
102
|
+
default: Salvar
|
|
103
|
+
type: String
|
|
104
|
+
|
|
70
105
|
submitting:
|
|
71
106
|
desc: Model que que mostra quando o componente está fazendo um submitting ou não.
|
|
72
107
|
type: Boolean
|
|
73
108
|
examples: [v-model:submitting="isSubmitting"]
|
|
74
109
|
model: true
|
|
75
110
|
|
|
76
|
-
entity:
|
|
77
|
-
desc: Entidade da store, por exemplo se tiver que trabalhar com modulo de usuários, teremos o model "users" na store, que vai ser nossa "entity".
|
|
78
|
-
required: true
|
|
79
|
-
type: String
|
|
80
|
-
|
|
81
|
-
dialog:
|
|
82
|
-
desc: Este componente pode ser utilizado dentro de um dialog, neste caso o componente pai não pode ser um "QPage" e sim uma "div", esta prop cuida disto.
|
|
83
|
-
type: Boolean
|
|
84
|
-
|
|
85
111
|
url:
|
|
86
112
|
desc: Envia como parâmetro para a action "fetchSingle" do modulo correspondente a "entity".
|
|
87
113
|
type: String
|
|
88
114
|
|
|
89
|
-
|
|
90
|
-
desc:
|
|
91
|
-
default:
|
|
92
|
-
type:
|
|
93
|
-
examples: [v-model:fields="fields"]
|
|
94
|
-
model: true
|
|
115
|
+
use-actions:
|
|
116
|
+
desc: Controla se vai ter ou não o slot de actions.
|
|
117
|
+
default: true
|
|
118
|
+
type: Boolean
|
|
95
119
|
|
|
96
|
-
|
|
97
|
-
desc:
|
|
98
|
-
default:
|
|
99
|
-
type:
|
|
100
|
-
examples: [v-model:errors="errors"]
|
|
101
|
-
model: true
|
|
120
|
+
use-boundary:
|
|
121
|
+
desc: Controla o limite que o FormView terá, quando é "false", a tag pai deixa de ser um "QPage" para ser uma "div" e é removido as classes "container" e "spaced", comumente utilizando quando precisa usar o QasFormView dentro de um dialog.
|
|
122
|
+
default: true
|
|
123
|
+
type: Boolean
|
|
102
124
|
|
|
103
|
-
|
|
104
|
-
desc:
|
|
105
|
-
default:
|
|
106
|
-
type:
|
|
107
|
-
examples: [v-model:metadata="metadata"]
|
|
108
|
-
model: true
|
|
125
|
+
use-cancel-button:
|
|
126
|
+
desc: Controla se vai ter ou não botão de "cancelar".
|
|
127
|
+
default: true
|
|
128
|
+
type: Boolean
|
|
109
129
|
|
|
110
|
-
|
|
111
|
-
desc:
|
|
130
|
+
use-dialog-on-unsaved-changes:
|
|
131
|
+
desc: Vamos imaginar um cenário onde o usuário entra na nossa tela de editar/criar, faz tudo o que precisa e sem querer clica no menu para ir para outra tela, caso essa prop esteja "true", vai aparece um modal perguntando se ele quer continuar editando ou ir para a tela no qual foi inicialmente redirecionado.
|
|
132
|
+
default: true
|
|
133
|
+
type: Boolean
|
|
134
|
+
|
|
135
|
+
use-submit-button:
|
|
136
|
+
desc: Controla se vai ter ou não botão de submit.
|
|
137
|
+
default: true
|
|
112
138
|
type: Boolean
|
|
113
|
-
examples: [v-model:fetching="isFetching"]
|
|
114
|
-
model: true
|
|
115
139
|
|
|
116
140
|
slots:
|
|
117
|
-
|
|
118
|
-
desc: Slot para acessar
|
|
141
|
+
actions:
|
|
142
|
+
desc: Slot para acessar a seção onde ficam os botões de ações (salvar e cancelar).
|
|
119
143
|
|
|
120
144
|
default:
|
|
121
145
|
desc: Slot para ter o conteúdo principal (dentro do main).
|
|
122
146
|
|
|
123
|
-
actions:
|
|
124
|
-
desc: Slot para acessar a seção onde ficam os botões de ações (salvar e cancelar).
|
|
125
|
-
|
|
126
147
|
footer:
|
|
127
148
|
desc: Slot para acessar o footer.
|
|
128
149
|
|
|
150
|
+
header:
|
|
151
|
+
desc: Slot para acessar o header.
|
|
152
|
+
|
|
129
153
|
events:
|
|
154
|
+
'@fetch-success -> function(value)':
|
|
155
|
+
desc: Dispara quando a action "fetchSingle" é executada com sucesso.
|
|
156
|
+
params:
|
|
157
|
+
value:
|
|
158
|
+
desc: Retorna todos os dados "cru" respondido pelo fetch.
|
|
159
|
+
type: Object
|
|
160
|
+
|
|
161
|
+
'@fetch-error -> function(value)':
|
|
162
|
+
desc: Dispara quando a action "fetchSingle" cai em uma exceção.
|
|
163
|
+
params:
|
|
164
|
+
value:
|
|
165
|
+
desc: Retorna todos os dados "cru" respondido na exceção do fetch.
|
|
166
|
+
type: Object
|
|
167
|
+
|
|
130
168
|
'@update:model-value -> function(value)':
|
|
131
169
|
desc: Dispara toda vez que o model atualiza.
|
|
132
170
|
params:
|
|
@@ -168,17 +206,3 @@ events:
|
|
|
168
206
|
value:
|
|
169
207
|
desc: Retorna se está ou não fazendo fetching de dados.
|
|
170
208
|
type: Boolean
|
|
171
|
-
|
|
172
|
-
'@fetch-success -> function(value)':
|
|
173
|
-
desc: Dispara quando a action "fetchSingle" é executada com sucesso.
|
|
174
|
-
params:
|
|
175
|
-
value:
|
|
176
|
-
desc: Retorna todos os dados "cru" respondido pelo fetch.
|
|
177
|
-
type: Object
|
|
178
|
-
|
|
179
|
-
'@fetch-error -> function(value)':
|
|
180
|
-
desc: Dispara quando a action "fetchSingle" cai em uma exceção.
|
|
181
|
-
params:
|
|
182
|
-
value:
|
|
183
|
-
desc: Retorna todos os dados "cru" respondido na exceção do fetch.
|
|
184
|
-
type: Object
|