@bildvitta/quasar-ui-asteroid 3.13.0-beta.5 → 3.13.0-beta.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bildvitta/quasar-ui-asteroid",
3
3
  "description": "Asteroid",
4
- "version": "3.13.0-beta.5",
4
+ "version": "3.13.0-beta.7",
5
5
  "author": "Bild & Vitta <systemteam@bild.com.br>",
6
6
  "license": "MIT",
7
7
  "main": "dist/asteroid.cjs.min.js",
@@ -17,7 +17,7 @@
17
17
  <div class="ellipsis qas-app-user__menu-name">{{ userName }}</div>
18
18
  <div class="ellipsis">{{ user.email }}</div>
19
19
 
20
- <qas-select v-if="hasCompaniesSelect" v-model="companiesModel" class="q-my-md" v-bind="defaultCompanyProps" @update:model-value="setCompanies" />
20
+ <qas-select v-if="hasCompaniesSelect" v-model="companiesModel" class="q-my-md" v-bind="defaultCompanyProps" data-cy="app-user-companies-select" @update:model-value="setCompanies" />
21
21
 
22
22
  <q-list class="q-mt-md">
23
23
  <q-item v-close-popup :active="false" class="qas-app-user__menu-item" clickable :to="user.to">
@@ -103,7 +103,6 @@ export default {
103
103
  computed: {
104
104
  defaultCompanyProps () {
105
105
  return {
106
- dataCy: 'app-user-companies-select',
107
106
  loading: this.loading,
108
107
 
109
108
  ...this.companyProps,
@@ -42,3 +42,12 @@ props:
42
42
  events:
43
43
  '@sign-out -> function()':
44
44
  desc: Dispara quando o botão de "sair" é clicado.
45
+
46
+ selectors:
47
+ app-user:
48
+ desc: Seletor do componente.
49
+ examples: ['data-cy="app-user"']
50
+
51
+ app-user-companies-select:
52
+ desc: Seletor do select de vínculos de empresas.
53
+ examples: ['data-cy="app-user-companies-select"']
@@ -1,12 +1,12 @@
1
1
  <template>
2
- <q-dialog ref="dialog" class="qas-dialog" :persistent="persistent" v-bind="dialogProps" @update:model-value="updateModelValue">
2
+ <q-dialog ref="dialog" class="qas-dialog" data-cy="dialog" :persistent="persistent" v-bind="dialogProps" @update:model-value="updateModelValue">
3
3
  <div class="bg-white q-pa-lg" :style="style">
4
4
  <header v-if="hasHeader" class="q-mb-lg">
5
5
  <slot name="header">
6
6
  <div class="items-center justify-between row">
7
- <h5 class="text-grey-9 text-h5">{{ card.title }}</h5>
7
+ <h5 class="text-grey-9 text-h5" data-cy="dialog-title">{{ card.title }}</h5>
8
8
 
9
- <qas-btn v-if="isInfoDialog" v-close-popup color="grey-9" icon="sym_r_close" variant="tertiary" />
9
+ <qas-btn v-if="isInfoDialog" v-close-popup color="grey-9" data-cy="dialog-close-btn" icon="sym_r_close" variant="tertiary" />
10
10
  </div>
11
11
  </slot>
12
12
  </header>
@@ -14,18 +14,18 @@
14
14
  <section class="text-body1 text-grey-8">
15
15
  <component :is="componentTag" ref="form" v-bind="componentProps">
16
16
  <slot name="description">
17
- <component :is="descriptionComponentTag">{{ card.description }}</component>
17
+ <component :is="descriptionComponentTag" data-cy="dialog-description">{{ card.description }}</component>
18
18
  </slot>
19
19
 
20
20
  <div v-if="!isInfoDialog">
21
21
  <slot name="actions">
22
22
  <qas-actions v-bind="formattedActionsProps">
23
23
  <template v-if="hasOk" #primary>
24
- <qas-btn v-close-popup="!useForm" class="full-width" variant="primary" v-bind="defaultOk" />
24
+ <qas-btn v-close-popup="!useForm" class="full-width" data-cy="dialog-ok-btn" variant="primary" v-bind="defaultOk" />
25
25
  </template>
26
26
 
27
27
  <template v-if="hasCancel" #secondary>
28
- <qas-btn v-close-popup class="full-width" v-bind="defaultCancel" variant="secondary" />
28
+ <qas-btn v-close-popup class="full-width" data-cy="dialog-cancel-btn" v-bind="defaultCancel" variant="secondary" />
29
29
  </template>
30
30
  </qas-actions>
31
31
  </slot>
@@ -90,3 +90,28 @@ events:
90
90
  '@ok: -> function ()':
91
91
  desc: Dispara toda vez que é clicado no botão "ok" ou quando useForm for true e o for clicado "enter" estando com foco em algum input (evento de submit).
92
92
 
93
+ selectors:
94
+ dialog:
95
+ desc: Seletor do componente.
96
+ examples: ['data-cy="dialog"']
97
+
98
+ dialog-cancel-btn:
99
+ desc: Seletor do botão de cancelar do componente.
100
+ examples: ['data-cy="dialog-cancel-btn"']
101
+
102
+ dialog-close-btn:
103
+ desc: Seletor do botão de fechar do componente.
104
+ examples: ['data-cy="dialog-close-btn"']
105
+
106
+ dialog-description:
107
+ desc: Seletor da descrição do componente.
108
+ examples: ['data-cy="dialog-description"']
109
+
110
+ dialog-ok-btn:
111
+ desc: Seletor do botão de confirmar do componente.
112
+ examples: ['data-cy="dialog-ok-btn"']
113
+
114
+ dialog-title:
115
+ desc: Seletor do título do componente.
116
+ examples: ['data-cy="dialog-title"']
117
+
@@ -29,3 +29,8 @@ events:
29
29
  value:
30
30
  desc: Novo valor do model.
31
31
  type: [Object, Array, String, Number, Boolean]
32
+
33
+ selectors:
34
+ '[fieldName]':
35
+ desc: Seletor criado a partir da propriedade "name" do campo.
36
+ examples: ['data-cy="email"', 'data-cy="phone"', 'data-cy="password"']
@@ -141,3 +141,24 @@ events:
141
141
  value:
142
142
  desc: Retorna todos os filtros realizados.
143
143
  type: Object
144
+
145
+ selectors:
146
+ filters-btn:
147
+ desc: Seletor do botão de filtro.
148
+ examples: ['data-cy="filters-btn"']
149
+
150
+ filters-clear-btn:
151
+ desc: Seletor do botão de limpar do filtro.
152
+ examples: ['data-cy="filters-clear-btn"']
153
+
154
+ 'filters-[optionText]-chip':
155
+ desc: Seletor do chip de acordo com o texto da opção selecionada.
156
+ examples: ['data-cy="filters-Ativo-chip"']
157
+
158
+ 'filters-[fieldName]-field':
159
+ desc: Seletor criado a partir da propriedade "name" do campo.
160
+ examples: ['data-cy="filters-email-field"', 'data-cy="filters-phone-field"', 'data-cy="filters-password-field"']
161
+
162
+ filters-submit-btn:
163
+ desc: Seletor do botão de submit do filtro.
164
+ examples: ['data-cy="filters-submit-btn"']
@@ -10,11 +10,11 @@
10
10
  <slot v-if="useActions" name="actions">
11
11
  <qas-actions>
12
12
  <template v-if="useSubmitButton" #primary>
13
- <qas-btn class="qas-form-view__btn" :data-cy="`btnSave-${entity}`" :disable="disable" :label="submitButtonLabel" :loading="isSubmitting" type="submit" variant="primary" />
13
+ <qas-btn class="qas-form-view__btn" :data-cy="`form-view-submit-btn-${entity}`" :disable="disable" :label="submitButtonLabel" :loading="isSubmitting" type="submit" variant="primary" />
14
14
  </template>
15
15
 
16
16
  <template v-if="hasCancelButton" #secondary>
17
- <qas-btn v-close-popup class="qas-form-view__btn" :data-cy="`btnCancel-${entity}`" :disable="isSubmitting" :label="cancelButtonLabel" type="button" variant="secondary" @click="cancel" />
17
+ <qas-btn v-close-popup class="qas-form-view__btn" :data-cy="`form-view-cancel-btn-${entity}`" :disable="isSubmitting" :label="cancelButtonLabel" type="button" variant="secondary" @click="cancel" />
18
18
  </template>
19
19
  </qas-actions>
20
20
  </slot>
@@ -57,6 +57,11 @@ export default {
57
57
  mixins: [viewMixin],
58
58
 
59
59
  props: {
60
+ beforeSubmit: {
61
+ default: null,
62
+ type: Function
63
+ },
64
+
60
65
  cancelButtonLabel: {
61
66
  default: 'Voltar',
62
67
  type: String
@@ -125,14 +130,14 @@ export default {
125
130
  type: Boolean
126
131
  },
127
132
 
133
+ useNotifySuccess: {
134
+ type: Boolean,
135
+ default: true
136
+ },
137
+
128
138
  useSubmitButton: {
129
139
  default: true,
130
140
  type: Boolean
131
- },
132
-
133
- beforeSubmit: {
134
- default: null,
135
- type: Function
136
141
  }
137
142
  },
138
143
 
@@ -447,7 +452,9 @@ export default {
447
452
  `QasFormView - submit -> resposta da action ${this.entity}/${this.mode}`, [response]
448
453
  )
449
454
 
450
- NotifySuccess(response.data.status.text || this.defaultNotifyMessages.success)
455
+ if (this.useNotifySuccess) {
456
+ NotifySuccess(response.data.status.text || this.defaultNotifyMessages.success)
457
+ }
451
458
  } catch (error) {
452
459
  const errors = error?.response?.data?.errors
453
460
  const message = error?.response?.data?.status?.text
@@ -138,6 +138,11 @@ props:
138
138
  default: true
139
139
  type: Boolean
140
140
 
141
+ use-notify-success:
142
+ desc: Controla se vai ter ou não notificação de sucesso ao finalizar o submit.
143
+ default: true
144
+ type: Boolean
145
+
141
146
  use-submit-button:
142
147
  desc: Controla se vai ter ou não botão de submit.
143
148
  default: true
@@ -235,4 +240,11 @@ events:
235
240
  desc: Retorna todos os dados "cru" respondido na exceção do submit.
236
241
  type: Object
237
242
 
243
+ selectors:
244
+ 'form-view-cancel-btn-[entity]':
245
+ desc: Seletor do botão de cancelar.
246
+ examples: ['data-cy="form-view-cancel-btn-users"']
238
247
 
248
+ 'form-view-submit-btn-[entity]':
249
+ desc: Seletor do botão de salvar.
250
+ examples: ['data-cy="form-view-submit-btn-users"']
@@ -169,3 +169,20 @@ events:
169
169
  desc: Index da imagem que seria deletada.
170
170
  default: []
171
171
  type: Array
172
+
173
+ selectors:
174
+ gallery-btn-show-more:
175
+ desc: Seletor do botão "mostrar mais".
176
+ examples: ['data-cy="gallery-btn-show-more"']
177
+
178
+ gallery-carousel:
179
+ desc: Seletor do carousel.
180
+ examples: ['data-cy="gallery-carousel"']
181
+
182
+ 'gallery-carousel-slide-[index]':
183
+ desc: Seletor pelo index do slide do carousel.
184
+ examples: ['data-cy="gallery-carousel-slide-0"', 'data-cy="gallery-carousel-slide-1"']
185
+
186
+ 'gallery-image-[index]':
187
+ desc: Seletor pelo index da imagem da galeria.
188
+ examples: ['data-cy="gallery-image-0"', 'data-cy="gallery-image-1"']
@@ -20,7 +20,21 @@
20
20
  <slot name="image">
21
21
  <q-img class="rounded-borders" height="100%" :src="card.url" v-bind="imageProps">
22
22
  <template #error>
23
- <slot name="image-error" />
23
+ <div :class="errorClasses">
24
+ <div class="text-center">
25
+ <slot name="image-error-icon">
26
+ <div v-if="errorIcon">
27
+ <q-icon :name="errorIcon" size="sm" />
28
+ </div>
29
+ </slot>
30
+
31
+ <slot name="image-error">
32
+ <div>
33
+ {{ errorMessage }}
34
+ </div>
35
+ </slot>
36
+ </div>
37
+ </div>
24
38
  </template>
25
39
  </q-img>
26
40
  </slot>
@@ -53,6 +67,16 @@ export default {
53
67
  type: Boolean
54
68
  },
55
69
 
70
+ errorIcon: {
71
+ type: String,
72
+ default: ''
73
+ },
74
+
75
+ errorMessage: {
76
+ type: String,
77
+ default: ''
78
+ },
79
+
56
80
  gridGeneratorProps: {
57
81
  type: Object,
58
82
  default: () => ({})
@@ -108,6 +132,19 @@ export default {
108
132
  'text-grey-9': !this.disable,
109
133
  'q-mb-md': this.hasActions || this.card.name
110
134
  }
135
+ },
136
+
137
+ errorClasses () {
138
+ return [
139
+ 'bg-grey-4',
140
+ 'flex',
141
+ 'full-height',
142
+ 'full-width',
143
+ 'items-center',
144
+ 'justify-center',
145
+ 'text-grey-9',
146
+ 'text-subtitle2'
147
+ ]
111
148
  }
112
149
  }
113
150
  }
@@ -9,6 +9,16 @@ props:
9
9
  default: {}
10
10
  type: Object
11
11
 
12
+ error-icon:
13
+ desc: Ícone que aparecerá quando uma imagem falhar ao carregar.
14
+ default: ''
15
+ type: String
16
+
17
+ error-message:
18
+ desc: Texto que aparecerá quando uma imagem falhar ao carregar.
19
+ default: ''
20
+ type: String
21
+
12
22
  card:
13
23
  desc: Informações do card, como name (nome) e url.
14
24
  default: {}
@@ -41,6 +51,9 @@ slots:
41
51
  image-error:
42
52
  desc: Slot para acessar o conteúdo da imagem quando existe algum erro com a imagem.
43
53
 
54
+ image-error-icon:
55
+ desc: Slot para acessar o conteúdo de ícone quando existe algum erro com a imagem.
56
+
44
57
  header:
45
58
  desc: Slot para acessar o conteúdo do cabeçalho.
46
59
 
@@ -73,3 +73,11 @@ slots:
73
73
  default: {}
74
74
  type: Object
75
75
 
76
+ selectors:
77
+ 'grid-generator-[fieldName]-field':
78
+ desc: Seletor do título do campo.
79
+ examples: ['data-cy="grid-generator-email-field"', 'data-cy="grid-generator-name-field"']
80
+
81
+ 'grid-generator-[fieldName]-result':
82
+ desc: Seletor do conteúdo do campo.
83
+ examples: ['data-cy="grid-generator-email-result"', 'data-cy="grid-generator-name-result"']
@@ -40,4 +40,9 @@ events:
40
40
  params:
41
41
  value:
42
42
  desc: Novo valor do model.
43
- type: String
43
+ type: String
44
+
45
+ selectors:
46
+ search-input:
47
+ desc: Seletor do campo de pesquisa.
48
+ examples: ['data-cy="search-input"']
@@ -116,7 +116,7 @@ export default {
116
116
  },
117
117
 
118
118
  galleryCardProps: {
119
- type: Object,
119
+ type: [Object, Function],
120
120
  default: () => ({})
121
121
  },
122
122
 
@@ -1,28 +1,6 @@
1
1
  <template>
2
2
  <div>
3
3
  <qas-gallery-card v-bind="defaultGalleryCardProps">
4
- <!-- este template é para quando existe um erro carregar uma imagem de um arquivo como PDF, DOCX. -->
5
- <template #image-error>
6
- <div class="text-uppercase" :class="errorClasses">
7
- {{ fileType }}
8
- </div>
9
- </template>
10
-
11
- <!-- este template é para quando existe um erro ao fazer um UPLOAD! -->
12
- <template v-if="hasError" #image>
13
- <div :class="errorClasses">
14
- <div class="q-pa-sm text-center">
15
- <div>
16
- <q-icon name="sym_r_cancel" size="sm" />
17
- </div>
18
-
19
- <div class="q-mt-sm">
20
- Falha ao carregar arquivo.
21
- </div>
22
- </div>
23
- </div>
24
- </template>
25
-
26
4
  <template v-if="hasGenerator" #bottom>
27
5
  <div>
28
6
  <qas-grid-generator v-if="hasGridGenerator" v-bind="defaultGridGeneratorProps" />
@@ -80,7 +58,7 @@ export default {
80
58
  },
81
59
 
82
60
  galleryCardProps: {
83
- type: Object,
61
+ type: [Object, Function],
84
62
  default: () => ({})
85
63
  },
86
64
 
@@ -112,7 +90,8 @@ export default {
112
90
  data () {
113
91
  return {
114
92
  dialogValues: {},
115
- showDialog: false
93
+ showDialog: false,
94
+ hasErrorOnUploadedFile: false
116
95
  }
117
96
  },
118
97
 
@@ -136,21 +115,67 @@ export default {
136
115
  }
137
116
  },
138
117
 
118
+ normalizedCardGalleryProps () {
119
+ const isFunction = typeof this.galleryCardProps === 'function'
120
+
121
+ const functionPayload = {
122
+ hasError: this.hasErrorOnUploadedFile,
123
+ file: this.file
124
+ }
125
+
126
+ return (isFunction ? this.galleryCardProps(functionPayload) : this.galleryCardProps) || {}
127
+ },
128
+
139
129
  defaultGalleryCardProps () {
140
- const { list, buttonProps, ...actionsMenuProps } = this.galleryCardProps.actionsMenuProps || {}
130
+ const {
131
+ list,
132
+ imageProps,
133
+
134
+ buttonProps: btnProps,
135
+ errorMessage: error,
136
+ errorIcon: icon,
137
+
138
+ ...actionsMenuProps
139
+ } = this.normalizedCardGalleryProps
140
+
141
+ /**
142
+ * Quando hasError for "true", significa que é falha ao enviar o arquivo ao servidor (upload), e nestes casos:
143
+ *
144
+ * buttonProps: deve sempre ser possível excluir a imagem, por isso o disable do botão é "false".
145
+ * errorMessage: o label do erro deve ser "Falha ao carregar arquivo."
146
+ * errorIcon: o ícone do erro deve ser "sym_r_cancel".
147
+ */
148
+ const buttonProps = this.hasError ? { ...btnProps, disable: false } : btnProps
149
+ const errorMessage = this.hasError ? 'Falha ao carregar arquivo.' : error || this.fileType
150
+ const errorIcon = this.hasError ? 'sym_r_cancel' : icon
141
151
 
142
152
  return {
143
- ...this.galleryCardProps,
144
153
  disable: this.hasError,
145
154
 
155
+ ...this.normalizedCardGalleryProps,
156
+
157
+ errorIcon,
158
+ errorMessage,
159
+
160
+ imageProps: {
161
+ ...imageProps,
162
+
163
+ // callback para sinalizar que houve erro em arquivos já upados.
164
+ onError: () => {
165
+ this.hasErrorOnUploadedFile = true
166
+
167
+ this.galleryCardProps.imageProps?.onError?.()
168
+ }
169
+ },
170
+
146
171
  actionsMenuProps: {
172
+ ...actionsMenuProps,
173
+
147
174
  buttonProps: {
148
175
  disable: false,
149
176
  ...buttonProps
150
177
  },
151
178
 
152
- ...actionsMenuProps,
153
-
154
179
  list: {
155
180
  ...(
156
181
  this.hasEditButton &&
@@ -216,21 +241,8 @@ export default {
216
241
  }
217
242
  },
218
243
 
219
- errorClasses () {
220
- return [
221
- 'bg-grey-4',
222
- 'flex',
223
- 'full-height',
224
- 'full-width',
225
- 'items-center',
226
- 'justify-center',
227
- 'text-grey-9',
228
- 'text-subtitle2'
229
- ]
230
- },
231
-
232
244
  fileName () {
233
- return this.url.split('/').pop()
245
+ return this.url ? this.url.split('/').pop() : ''
234
246
  },
235
247
 
236
248
  fileType () {
@@ -259,6 +271,7 @@ export default {
259
271
 
260
272
  hasFormFields () {
261
273
  const { fields } = this.defaultFormGeneratorProps
274
+
262
275
  return !!Object.keys(fields).length
263
276
  },
264
277
 
@@ -288,7 +301,19 @@ export default {
288
301
  },
289
302
 
290
303
  normalizedModelValue () {
291
- return this.useObjectModel && !this.hasError ? this.currentModelValue : this.file
304
+ return (
305
+ this.useObjectModel && !this.hasError
306
+ ? this.currentModelValue
307
+
308
+ /**
309
+ * Quando da erro ao enviar, a url não é enviada no model, desta forma para aparecer a imagem
310
+ * de "Falha ao enviar arquivo." é necessário que a "url" exista, então é criada uma url fake.
311
+ *
312
+ * Obs: esta URL fake é usada apenas para aparecer a imagem de "Falha ao enviar arquivo."
313
+ * e não é adicionada ao model.
314
+ */
315
+ : { url: this.url || 'error-on-upload-file', ...this.file }
316
+ )
292
317
  },
293
318
 
294
319
  url () {