@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.
Files changed (173) hide show
  1. package/dist/api/QasActionsMenu.json +15 -15
  2. package/dist/api/QasAppBar.json +4 -8
  3. package/dist/api/QasAppMenu.json +11 -7
  4. package/dist/api/QasBtn.json +8 -4
  5. package/dist/api/QasCard.json +17 -13
  6. package/dist/api/QasCheckboxGroup.json +8 -8
  7. package/dist/api/QasCopy.json +4 -4
  8. package/dist/api/QasDateTimeInput.json +16 -16
  9. package/dist/api/QasDelete.json +17 -17
  10. package/dist/api/QasDialog.json +24 -20
  11. package/dist/api/QasFilters.json +14 -14
  12. package/dist/api/QasFormGenerator.json +57 -26
  13. package/dist/api/QasFormView.json +115 -87
  14. package/dist/api/QasGallery.json +4 -4
  15. package/dist/api/QasGridGenerator.json +40 -39
  16. package/dist/api/QasInput.json +13 -13
  17. package/dist/api/QasListItems.json +18 -17
  18. package/dist/api/QasListView.json +67 -53
  19. package/dist/api/QasNestedFields.json +45 -35
  20. package/dist/api/QasNumericInput.json +31 -12
  21. package/dist/api/QasPageHeader.json +7 -7
  22. package/dist/api/QasPasswordInput.json +13 -13
  23. package/dist/api/QasPasswordStrengthChecker.json +12 -12
  24. package/dist/api/QasProfile.json +5 -5
  25. package/dist/api/QasResizer.json +11 -11
  26. package/dist/api/QasSearchBox.json +90 -8
  27. package/dist/api/QasSelect.json +92 -25
  28. package/dist/api/QasSelectList.json +16 -14
  29. package/dist/api/QasSignaturePad.json +1 -1
  30. package/dist/api/QasSignatureUploader.json +9 -9
  31. package/dist/api/QasSingleView.json +52 -43
  32. package/dist/api/QasSortable.json +20 -20
  33. package/dist/api/QasTableGenerator.json +5 -5
  34. package/dist/api/QasTabsGenerator.json +5 -2
  35. package/dist/api/QasTransfer.json +9 -9
  36. package/dist/api/QasUploader.json +22 -17
  37. package/dist/asteroid.cjs.css +1 -1
  38. package/dist/asteroid.cjs.js +3904 -3102
  39. package/dist/asteroid.cjs.min.js +2 -2
  40. package/dist/asteroid.esm.css +1 -1
  41. package/dist/asteroid.esm.js +3908 -3106
  42. package/dist/asteroid.esm.min.js +2 -2
  43. package/dist/asteroid.umd.css +1 -1
  44. package/dist/asteroid.umd.js +3907 -3106
  45. package/dist/asteroid.umd.min.js +2 -2
  46. package/dist/vetur/asteroid-attributes.json +387 -303
  47. package/dist/vetur/asteroid-tags.json +129 -108
  48. package/package.json +1 -1
  49. package/src/assets/gear.svg +27 -0
  50. package/src/components/actions/QasActions.vue +1 -5
  51. package/src/components/actions-menu/QasActionsMenu.vue +4 -10
  52. package/src/components/actions-menu/QasActionsMenu.yml +15 -15
  53. package/src/components/app-bar/QasAppBar.vue +18 -14
  54. package/src/components/app-bar/QasAppBar.yml +4 -8
  55. package/src/components/app-menu/QasAppMenu.vue +8 -7
  56. package/src/components/app-menu/QasAppMenu.yml +11 -7
  57. package/src/components/avatar/QasAvatar.vue +0 -4
  58. package/src/components/box/QasBox.vue +1 -1
  59. package/src/components/btn/QasBtn.vue +11 -15
  60. package/src/components/btn/QasBtn.yml +7 -3
  61. package/src/components/card/QasCard.vue +18 -9
  62. package/src/components/card/QasCard.yml +17 -13
  63. package/src/components/checkbox-group/QasCheckboxGroup.yml +9 -8
  64. package/src/components/copy/QasCopy.vue +1 -1
  65. package/src/components/copy/QasCopy.yml +4 -3
  66. package/src/components/date-time-input/QasDateTimeInput.vue +39 -41
  67. package/src/components/date-time-input/QasDateTimeInput.yml +16 -16
  68. package/src/components/delete/QasDelete.vue +15 -1
  69. package/src/components/delete/QasDelete.yml +15 -15
  70. package/src/components/dialog/QasDialog.vue +28 -9
  71. package/src/components/dialog/QasDialog.yml +22 -18
  72. package/src/components/dialog-router/QasDialogRouter.vue +1 -1
  73. package/src/components/field/QasField.vue +15 -14
  74. package/src/components/filters/QasFilters.vue +30 -13
  75. package/src/components/filters/QasFilters.yml +14 -14
  76. package/src/components/form-generator/QasFormGenerator.vue +87 -12
  77. package/src/components/form-generator/QasFormGenerator.yml +32 -18
  78. package/src/components/form-view/QasFormView.vue +142 -60
  79. package/src/components/form-view/QasFormView.yml +91 -67
  80. package/src/components/gallery/QasGallery.vue +4 -8
  81. package/src/components/gallery/QasGallery.yml +4 -4
  82. package/src/components/grid-generator/QasGridGenerator.vue +23 -7
  83. package/src/components/grid-generator/QasGridGenerator.yml +29 -27
  84. package/src/components/input/QasInput.vue +37 -21
  85. package/src/components/input/QasInput.yml +13 -13
  86. package/src/components/layout/QasLayout.vue +4 -0
  87. package/src/components/list-items/QasListItems.vue +16 -24
  88. package/src/components/list-items/QasListItems.yml +14 -15
  89. package/src/components/list-view/QasListView.vue +48 -20
  90. package/src/components/list-view/QasListView.yml +58 -46
  91. package/src/components/map/QasMap.vue +5 -5
  92. package/src/components/nested-fields/QasNestedFields.vue +29 -21
  93. package/src/components/nested-fields/QasNestedFields.yml +35 -28
  94. package/src/components/numeric-input/QasNumericInput.vue +45 -27
  95. package/src/components/numeric-input/QasNumericInput.yml +26 -12
  96. package/src/components/page-header/QasPageHeader.vue +14 -11
  97. package/src/components/page-header/QasPageHeader.yml +4 -4
  98. package/src/components/password-input/QasPasswordInput.vue +17 -16
  99. package/src/components/password-input/QasPasswordInput.yml +11 -11
  100. package/src/components/password-strength-checker/QasPasswordStrengthChecker.yml +10 -10
  101. package/src/components/profile/QasProfile.vue +3 -6
  102. package/src/components/profile/QasProfile.yml +5 -5
  103. package/src/components/resizer/QasResizer.vue +1 -1
  104. package/src/components/resizer/QasResizer.yml +6 -5
  105. package/src/components/search-box/QasSearchBox.vue +138 -42
  106. package/src/components/search-box/QasSearchBox.yml +74 -7
  107. package/src/components/select/QasSelect.vue +63 -53
  108. package/src/components/select/QasSelect.yml +68 -17
  109. package/src/components/select-list/QasSelectList.vue +13 -32
  110. package/src/components/select-list/QasSelectList.yml +13 -14
  111. package/src/components/signature-pad/QasSignaturePad.vue +1 -1
  112. package/src/components/signature-pad/QasSignaturePad.yml +1 -1
  113. package/src/components/signature-uploader/QasSignatureUploader.vue +13 -14
  114. package/src/components/signature-uploader/QasSignatureUploader.yml +9 -9
  115. package/src/components/single-view/QasSingleView.vue +24 -8
  116. package/src/components/single-view/QasSingleView.yml +45 -38
  117. package/src/components/sortable/QasSortable.yml +17 -17
  118. package/src/components/table-generator/QasTableGenerator.vue +14 -6
  119. package/src/components/table-generator/QasTableGenerator.yml +5 -5
  120. package/src/components/tabs-generator/QasTabsGenerator.vue +2 -2
  121. package/src/components/tabs-generator/QasTabsGenerator.yml +2 -2
  122. package/src/components/text-truncate/QasTextTruncate.vue +2 -5
  123. package/src/components/transfer/QasTransfer.vue +5 -7
  124. package/src/components/transfer/QasTransfer.yml +9 -9
  125. package/src/components/uploader/QasUploader.vue +63 -16
  126. package/src/components/uploader/QasUploader.yml +17 -12
  127. package/src/composables/index.js +1 -1
  128. package/src/composables/{useHistory.js → use-history.js} +0 -0
  129. package/src/css/components/base.scss +3 -0
  130. package/src/css/components/field.scss +4 -0
  131. package/src/css/components/index.scss +4 -0
  132. package/src/css/components/radio.scss +3 -0
  133. package/src/css/components/tabs.scss +3 -0
  134. package/src/css/mixins/index.scss +1 -0
  135. package/src/css/{set-brand.scss → mixins/set-brand.scss} +0 -0
  136. package/src/css/{background.scss → utils/background.scss} +0 -0
  137. package/src/css/{border-radius.scss → utils/border-radius.scss} +0 -0
  138. package/src/css/{border.scss → utils/border.scss} +0 -0
  139. package/src/css/{container.scss → utils/container.scss} +0 -0
  140. package/src/css/{fonts.scss → utils/fonts.scss} +0 -0
  141. package/src/css/utils/index.scss +9 -0
  142. package/src/css/{line-height.scss → utils/line-height.scss} +0 -0
  143. package/src/css/{opacity.scss → utils/opacity.scss} +0 -0
  144. package/src/css/{text.scss → utils/text.scss} +0 -0
  145. package/src/css/{unset.scss → utils/unset.scss} +0 -0
  146. package/src/css/variables/button.scss +3 -0
  147. package/src/css/variables/index.scss +3 -0
  148. package/src/css/variables/shadow.scss +33 -0
  149. package/src/css/variables/typography.scss +139 -0
  150. package/src/helpers/camelize-fields-name.js +15 -0
  151. package/src/helpers/filters.js +2 -0
  152. package/src/helpers/get-normalized-options.js +20 -0
  153. package/src/helpers/handle-process.js +13 -0
  154. package/src/helpers/index.js +3 -0
  155. package/src/index.scss +11 -12
  156. package/src/mixins/generator.js +10 -2
  157. package/src/mixins/index.js +3 -3
  158. package/src/mixins/search-filter.js +227 -0
  159. package/src/mixins/view.js +35 -13
  160. package/src/pages/ErrorComponent.vue +56 -0
  161. package/src/pages/Forbidden.vue +21 -5
  162. package/src/pages/NotFound.vue +21 -5
  163. package/src/pages/ServerError.vue +25 -0
  164. package/src/pages/Unauthorized.vue +28 -0
  165. package/src/plugins/index.js +4 -2
  166. package/src/plugins/logger/Logger.js +44 -0
  167. package/src/plugins/logger/Logger.yml +9 -0
  168. package/src/plugins/screen/Screen.js +5 -0
  169. package/src/vue-plugin.js +6 -3
  170. package/src/assets/logo-modular.svg +0 -1
  171. package/src/css/design-system.scss +0 -18
  172. package/src/css/shadow.scss +0 -7
  173. 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
- fields-props:
19
- desc: Propriedade para repassar propriedades para cada campo individualmente.
30
+ fieldset:
31
+ desc: Lista para agrupar elementos por rótulo (label).
20
32
  default: {}
21
33
  type: Object
22
- examples: ["{ name: { dense: true, onClick: () => alert('Estou sendo clicado') } }"]
34
+ examples: ["{ personalInformation: { label: 'Informações pessoais', fields: [name, email] } }"]
23
35
 
24
- order:
25
- desc: Altera ordem dos campos.
26
- default: []
27
- type: Array
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
- columns:
38
- desc: Colunas do grid de cada campo.
39
- default: col-6
40
- type: [Array, String, Object]
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="submit">
7
+ <q-form ref="form" @submit="submitHandler">
8
8
  <slot />
9
9
 
10
- <slot v-if="!readOnly" name="actions">
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="dialog" class="full-width" :data-cy="`btnCancel-${entity}`" :disable="isCancelButtonDisabled" :label="cancelButton" outline type="button" @click="cancel" />
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
- <div class="col-12 col-sm-2" :class="saveButtonClass">
16
- <qas-btn class="full-width" :data-cy="`btnSave-${entity}`" :disable="disable" :label="submitButton" :loading="isSubmitting" type="submit" />
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, screenMixin } from '../../mixins'
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, screenMixin],
56
+ mixins: [viewMixin],
56
57
 
57
58
  props: {
58
- cancelButton: {
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
- showDialogOnUnsavedChanges: {
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
- submitButton: {
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.mx_isSmall && 'order-last'
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
- saveButtonClass () {
177
- return this.mx_isSmall && 'order-first'
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
- this.fetch()
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.showDialogOnUnsavedChanges ||
231
+ !this.useDialogOnUnsavedChanges ||
217
232
  this.ignoreRouterGuard ||
218
- isEqualWith(this.modelValue, this.cachedResult, this.handleIgnoreKeysInUnsavedChanges)
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
- if (!this.dialog) {
231
- this.handleCancelRoute()
232
- }
254
+ this.handleCancelRoute()
233
255
  },
234
256
 
235
- async fetch (params) {
257
+ async fetchSingle (externalPayload = {}) {
236
258
  this.mx_isFetching = true
237
259
 
238
260
  try {
239
- const response = await this.$store.dispatch(
240
- `${this.entity}/fetchSingle`, { form: true, id: this.id, params, url: this.fetchURL }
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: errors,
283
+ errors,
251
284
  fields: this.mx_fields,
252
285
  metadata
253
286
  })
254
287
 
255
- if (result) {
256
- this.hasResult = true
257
- this.$emit('update:modelValue', { ...this.modelValue, ...result })
258
- this.cachedResult = this.showDialogOnUnsavedChanges && extend(true, {}, result)
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
- const toIgnore = [
311
- ...this.fieldsNameWithDefaultValue,
312
- ...this.ignoreKeysInUnsavedChanges
313
- ]
358
+ if (!this.ignoreKeysInUnsavedChanges.length) return
314
359
 
315
- if (!toIgnore.length) return
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
- async submit (event) {
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
- if (this.disable || this.readyOnly) {
329
- return null
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 response = await this.$store.dispatch(
336
- `${this.entity}/${this.mode}`,
337
- { id: this.id, payload: this.modelValue, url: this.url }
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
- if (this.showDialogOnUnsavedChanges) {
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
- const exception = errors ? 'Existem erros de validação no formulário.' : exceptionResponse || error.message
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
- cancel-button:
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
- mode:
33
- 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).
34
- default: create
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
- route:
43
- desc: Você pode passar uma configuração de rota customizada.
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
- show-dialog-on-unsaved-changes:
48
- 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.
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
- submit-button:
59
- desc: Rótulo do botão "salvar".
60
- default: Salvar
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
- fields:
90
- desc: Model de fields, utilizado para recuperar os fields fora do template.
91
- default: {}
92
- type: Object
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
- errors:
97
- desc: Model de errors, utilizado para recuperar os errors fora do template.
98
- default: {}
99
- type: Object
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
- metadata:
104
- desc: Model de metadata, utilizado para recuperar os metadata fora do template.
105
- default: {}
106
- type: Object
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
- fetching:
111
- desc: Model de fetching, utilizado para saber se o componente está fazendo fetching de dados.
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
- header:
118
- desc: Slot para acessar o header.
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