@bildvitta/quasar-ui-asteroid 3.0.0-beta.9 → 3.0.0

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 (102) hide show
  1. package/dist/api/QasAppBar.json +0 -4
  2. package/dist/api/QasBtn.json +2 -1
  3. package/dist/api/QasCard.json +13 -9
  4. package/dist/api/QasDateTimeInput.json +12 -12
  5. package/dist/api/QasDialog.json +6 -2
  6. package/dist/api/QasFilters.json +4 -4
  7. package/dist/api/QasFormGenerator.json +33 -2
  8. package/dist/api/QasFormView.json +26 -9
  9. package/dist/api/QasGridGenerator.json +5 -4
  10. package/dist/api/QasInput.json +1 -1
  11. package/dist/api/QasListItems.json +18 -17
  12. package/dist/api/QasListView.json +21 -7
  13. package/dist/api/QasNestedFields.json +13 -3
  14. package/dist/api/QasNumericInput.json +10 -10
  15. package/dist/api/QasPasswordInput.json +1 -1
  16. package/dist/api/QasSearchBox.json +80 -1
  17. package/dist/api/QasSelect.json +79 -6
  18. package/dist/api/QasSelectList.json +16 -14
  19. package/dist/api/QasSignaturePad.json +1 -1
  20. package/dist/api/QasSingleView.json +13 -4
  21. package/dist/api/QasTabsGenerator.json +5 -2
  22. package/dist/api/QasUploader.json +5 -0
  23. package/dist/asteroid.cjs.css +1 -1
  24. package/dist/asteroid.cjs.js +1463 -663
  25. package/dist/asteroid.cjs.min.js +2 -2
  26. package/dist/asteroid.esm.css +1 -1
  27. package/dist/asteroid.esm.js +1466 -666
  28. package/dist/asteroid.esm.min.js +2 -2
  29. package/dist/asteroid.umd.css +1 -1
  30. package/dist/asteroid.umd.js +1466 -667
  31. package/dist/asteroid.umd.min.js +2 -2
  32. package/dist/vetur/asteroid-attributes.json +162 -94
  33. package/dist/vetur/asteroid-tags.json +54 -37
  34. package/package.json +1 -1
  35. package/src/components/actions-menu/QasActionsMenu.vue +2 -8
  36. package/src/components/app-bar/QasAppBar.vue +16 -12
  37. package/src/components/app-bar/QasAppBar.yml +0 -4
  38. package/src/components/avatar/QasAvatar.vue +0 -4
  39. package/src/components/btn/QasBtn.vue +5 -8
  40. package/src/components/btn/QasBtn.yml +2 -1
  41. package/src/components/card/QasCard.vue +18 -9
  42. package/src/components/card/QasCard.yml +13 -9
  43. package/src/components/date-time-input/QasDateTimeInput.vue +39 -41
  44. package/src/components/date-time-input/QasDateTimeInput.yml +11 -12
  45. package/src/components/delete/QasDelete.vue +15 -1
  46. package/src/components/dialog/QasDialog.vue +26 -3
  47. package/src/components/dialog/QasDialog.yml +6 -3
  48. package/src/components/dialog-router/QasDialogRouter.vue +1 -1
  49. package/src/components/field/QasField.vue +15 -14
  50. package/src/components/filters/QasFilters.vue +27 -10
  51. package/src/components/filters/QasFilters.yml +4 -4
  52. package/src/components/form-generator/QasFormGenerator.vue +87 -12
  53. package/src/components/form-generator/QasFormGenerator.yml +16 -2
  54. package/src/components/form-view/QasFormView.vue +99 -39
  55. package/src/components/form-view/QasFormView.yml +22 -9
  56. package/src/components/grid-generator/QasGridGenerator.vue +23 -7
  57. package/src/components/grid-generator/QasGridGenerator.yml +5 -4
  58. package/src/components/input/QasInput.vue +37 -21
  59. package/src/components/input/QasInput.yml +1 -1
  60. package/src/components/layout/QasLayout.vue +4 -0
  61. package/src/components/list-items/QasListItems.vue +15 -23
  62. package/src/components/list-items/QasListItems.yml +14 -15
  63. package/src/components/list-view/QasListView.vue +45 -24
  64. package/src/components/list-view/QasListView.yml +19 -7
  65. package/src/components/map/QasMap.vue +5 -5
  66. package/src/components/nested-fields/QasNestedFields.vue +29 -21
  67. package/src/components/nested-fields/QasNestedFields.yml +9 -3
  68. package/src/components/numeric-input/QasNumericInput.vue +14 -14
  69. package/src/components/numeric-input/QasNumericInput.yml +10 -10
  70. package/src/components/page-header/QasPageHeader.vue +14 -11
  71. package/src/components/password-input/QasPasswordInput.vue +17 -16
  72. package/src/components/password-input/QasPasswordInput.yml +1 -1
  73. package/src/components/profile/QasProfile.vue +1 -1
  74. package/src/components/search-box/QasSearchBox.vue +137 -36
  75. package/src/components/search-box/QasSearchBox.yml +66 -1
  76. package/src/components/select/QasSelect.vue +62 -46
  77. package/src/components/select/QasSelect.yml +63 -6
  78. package/src/components/select-list/QasSelectList.vue +11 -27
  79. package/src/components/select-list/QasSelectList.yml +13 -14
  80. package/src/components/signature-pad/QasSignaturePad.yml +1 -1
  81. package/src/components/signature-uploader/QasSignatureUploader.vue +7 -5
  82. package/src/components/single-view/QasSingleView.vue +22 -6
  83. package/src/components/single-view/QasSingleView.yml +11 -4
  84. package/src/components/table-generator/QasTableGenerator.vue +11 -1
  85. package/src/components/tabs-generator/QasTabsGenerator.vue +2 -2
  86. package/src/components/tabs-generator/QasTabsGenerator.yml +2 -2
  87. package/src/components/text-truncate/QasTextTruncate.vue +1 -1
  88. package/src/components/uploader/QasUploader.vue +62 -15
  89. package/src/components/uploader/QasUploader.yml +5 -0
  90. package/src/helpers/camelize-fields-name.js +15 -0
  91. package/src/helpers/filters.js +2 -0
  92. package/src/helpers/get-normalized-options.js +20 -0
  93. package/src/helpers/handle-process.js +13 -0
  94. package/src/helpers/index.js +3 -0
  95. package/src/mixins/generator.js +10 -2
  96. package/src/mixins/index.js +2 -0
  97. package/src/mixins/search-filter.js +227 -0
  98. package/src/mixins/view.js +32 -12
  99. package/src/plugins/index.js +4 -2
  100. package/src/plugins/logger/Logger.js +44 -0
  101. package/src/plugins/logger/Logger.yml +9 -0
  102. package/src/vue-plugin.js +6 -3
@@ -6,7 +6,7 @@
6
6
  <slot v-bind="slotData" :item="result" name="item">
7
7
  <slot name="item-section" :result="result">
8
8
  <q-item-section class="items-start text-bold">
9
- <div :class="labelClass" @click="redirectRoute(result)">{{ result.label }}</div>
9
+ <div :class="labelClass" @click="onClickLabel({ item: result, index })">{{ result.label }}</div>
10
10
  </q-item-section>
11
11
  </slot>
12
12
 
@@ -56,26 +56,16 @@ export default {
56
56
  default: () => []
57
57
  },
58
58
 
59
- to: {
60
- default: () => ({}),
61
- type: Object
62
- },
63
-
64
- redirectKey: {
65
- default: 'uuid',
66
- type: String
67
- },
68
-
69
- paramKey: {
70
- default: 'id',
71
- type: String
59
+ useClickableLabel: {
60
+ type: Boolean
72
61
  }
73
62
  },
74
63
 
75
64
  emits: [
76
65
  'added',
77
- 'update:modelValue',
78
- 'removed'
66
+ 'click-label',
67
+ 'removed',
68
+ 'update:modelValue'
79
69
  ],
80
70
 
81
71
  data () {
@@ -87,12 +77,8 @@ export default {
87
77
  },
88
78
 
89
79
  computed: {
90
- isRedirectEnabled () {
91
- return Object.keys(this.to).length
92
- },
93
-
94
80
  labelClass () {
95
- return this.isRedirectEnabled ? 'cursor-pointer' : ''
81
+ return this.useClickableLabel && 'cursor-pointer'
96
82
  },
97
83
 
98
84
  slotData () {
@@ -121,6 +107,7 @@ export default {
121
107
  this.values = [...value]
122
108
  },
123
109
 
110
+ deep: true,
124
111
  immediate: true
125
112
  }
126
113
  },
@@ -142,7 +129,7 @@ export default {
142
129
 
143
130
  return {
144
131
  dense: this.$qas.screen.isSmall,
145
- hideLabelOnSmallScreen: true,
132
+ useLabelOnSmallScreen: false,
146
133
  icon: !this.$qas.screen.isSmall ? undefined : isSelected ? 'o_close' : 'o_add',
147
134
  label: isSelected ? 'Remover' : 'Adicionar',
148
135
  outline: isSelected,
@@ -167,11 +154,8 @@ export default {
167
154
  })
168
155
  },
169
156
 
170
- redirectRoute (item) {
171
- return this.isRedirectEnabled && this.$router.push({
172
- params: { [this.paramKey]: item[this.redirectKey] },
173
- ...this.to
174
- })
157
+ onClickLabel ({ item, index }) {
158
+ this.useClickableLabel && this.$emit('click-label', { item, index })
175
159
  },
176
160
 
177
161
  remove (item) {
@@ -28,20 +28,9 @@ props:
28
28
  examples: [v-model="value"]
29
29
  model: true
30
30
 
31
- param-key:
32
- desc: Controla qual parâmetro será enviado para rota.
33
- default: id
34
- type: String
35
-
36
- redirect-key:
37
- desc: Controla qual propriedade será a chave primaria para fazer o redirecionamento.
38
- default: uuid
39
- type: String
40
-
41
- to:
42
- desc: 'Configuração do vue-router para enviar no $route.push({ ...to, params: {...} }).'
43
- default: Pesquisar
44
- type: String
31
+ use-clickable-label:
32
+ desc: Habilita "cursor-pointer" no label e evento "click-label".
33
+ type: Boolean
45
34
 
46
35
  slots:
47
36
  item:
@@ -98,6 +87,16 @@ events:
98
87
  desc: Item adicionado
99
88
  type: String
100
89
 
90
+ '@click-label -> function ({ item, index })':
91
+ desc: Dispara toda vez que o label do item é clicado **SE** a propriedade "useClickableLabel" for "true".
92
+ params:
93
+ item:
94
+ desc: Item clicado
95
+ type: Object
96
+ index:
97
+ desc: Posição do item
98
+ type: Number
99
+
101
100
  '@removed -> function (item, index)':
102
101
  desc: Dispara toda vez que um item é removido do v-model.
103
102
  params:
@@ -15,7 +15,7 @@ props:
15
15
  default: {}
16
16
  type: Object
17
17
 
18
- signature_options:
18
+ signature-options:
19
19
  desc: Opções da biblioteca signature_pad (https://github.com/szimek/signature_pad#options).
20
20
  default: {}
21
21
  type: Object
@@ -7,10 +7,10 @@
7
7
  <div v-if="uploadLabel" class="q-uploader__title">{{ uploadLabel }}</div>
8
8
  </div>
9
9
 
10
- <q-btn v-if="!readonly" dense flat icon="o_add" round @click="openDialog" />
10
+ <qas-btn v-if="!readonly" color="white" dense flat icon="o_add" round @click="openDialog" />
11
11
 
12
- <q-btn ref="forceUpload" class="hidden" @click="upload(scope)" />
13
- <q-btn ref="buttonCleanFiles" class="hidden" @click="scope.removeUploadedFiles" />
12
+ <qas-btn ref="forceUpload" class="hidden" @click="upload(scope)" />
13
+ <qas-btn ref="buttonCleanFiles" class="hidden" @click="scope.removeUploadedFiles" />
14
14
  </div>
15
15
  </template>
16
16
  </qas-uploader>
@@ -27,14 +27,15 @@
27
27
  </template>
28
28
 
29
29
  <template #actions>
30
- <q-btn class="full-width" color="primary" :disable="isEmpty" label="Salvar" no-caps @click="getSignatureData" />
31
- <q-btn class="full-width q-mt-sm" color="primary" flat label="Cancelar" no-caps @click="closeSignature" />
30
+ <qas-btn class="full-width" color="primary" :disable="isEmpty" label="Salvar" no-caps @click="getSignatureData" />
31
+ <qas-btn class="full-width q-mt-sm" color="primary" flat label="Cancelar" no-caps @click="closeSignature" />
32
32
  </template>
33
33
  </qas-dialog>
34
34
  </div>
35
35
  </template>
36
36
 
37
37
  <script>
38
+ import QasBtn from '../btn/QasBtn.vue'
38
39
  import QasDialog from '../dialog/QasDialog.vue'
39
40
  import QasUploader from '../uploader/QasUploader.vue'
40
41
  import QasSignaturePad from '../signature-pad/QasSignaturePad.vue'
@@ -45,6 +46,7 @@ export default {
45
46
  name: 'QasSignatureUploader',
46
47
 
47
48
  components: {
49
+ QasBtn,
48
50
  QasDialog,
49
51
  QasUploader,
50
52
  QasSignaturePad
@@ -66,7 +66,9 @@ export default {
66
66
 
67
67
  watch: {
68
68
  $route (to, from) {
69
- to.name === from.name && this.fetchSingle()
69
+ if (to.name === from.name) {
70
+ this.mx_fetchHandler({ id: this.id, url: this.url }, this.fetchSingle)
71
+ }
70
72
  },
71
73
 
72
74
  resultModel (value) {
@@ -75,19 +77,23 @@ export default {
75
77
  },
76
78
 
77
79
  created () {
78
- this.fetchSingle()
80
+ this.mx_fetchHandler({ id: this.id, url: this.url }, this.fetchSingle)
79
81
  },
80
82
 
81
83
  methods: {
82
- async fetchSingle (params = {}) {
84
+ async fetchSingle (externalPayload = {}) {
83
85
  this.mx_isFetching = true
84
86
 
85
87
  try {
86
- const response = await this.$store.dispatch(
87
- `${this.entity}/fetchSingle`,
88
- { id: this.id, url: this.url, params }
88
+ const payload = { id: this.id, url: this.url, ...externalPayload }
89
+
90
+ this.$qas.logger.group(
91
+ `QasSingleView - fetchSingle -> payload do parâmetro do ${this.entity}/fetchSingle`,
92
+ [payload]
89
93
  )
90
94
 
95
+ const response = await this.$store.dispatch(`${this.entity}/fetchSingle`, payload)
96
+
91
97
  const { errors, fields, metadata } = response.data
92
98
 
93
99
  this.mx_setErrors(errors)
@@ -100,10 +106,20 @@ export default {
100
106
  metadata: this.mx_metadata
101
107
  })
102
108
 
109
+ this.$qas.logger.group(
110
+ `QasSingleView - fetchSingle -> resposta da action ${this.entity}/fetchSingle`, [response]
111
+ )
112
+
103
113
  this.$emit('fetch-success', response)
104
114
  } catch (error) {
105
115
  this.mx_fetchError(error)
106
116
  this.$emit('fetch-error', error)
117
+
118
+ this.$qas.logger.group(
119
+ `QasSingleView - fetchSingle -> exceção da action ${this.entity}/fetchSingle`,
120
+ [error],
121
+ { error: true }
122
+ )
107
123
  } finally {
108
124
  this.mx_isFetching = false
109
125
  }
@@ -4,15 +4,17 @@ meta:
4
4
  desc: Componente para C.R.U.D. responsável pela visualização (Read) ou conhecido também como "show".
5
5
 
6
6
  props:
7
+ before-fetch:
8
+ desc: Callback para controlar como funciona o comportamento do fetchSingle.
9
+ default: null
10
+ type: Function
11
+ examples: ['beforeFetch({ payload, resolve, done })']
12
+
7
13
  custom-id:
8
14
  desc: Por padrão, o componente vai pegar o "id" que vem como parâmetro na url, caso queira que o id seja diferente da url, use esta prop.
9
15
  type: String
10
16
  examples: ['my-custom-id']
11
17
 
12
- dialog:
13
- 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.
14
- type: Boolean
15
-
16
18
  entity:
17
19
  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".
18
20
  required: true
@@ -55,6 +57,11 @@ props:
55
57
  desc: Envia como parâmetro para a action "fetchSingle" do modulo correspondente a "entity".
56
58
  type: String
57
59
 
60
+ use-boundary:
61
+ 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.
62
+ default: true
63
+ type: Boolean
64
+
58
65
  slots:
59
66
  default:
60
67
  desc: 'Slot para ter o conteúdo principal (dentro do main).'
@@ -101,6 +101,8 @@ export default {
101
101
  columnByField(this.fields[index])
102
102
  }
103
103
 
104
+ this.$qas.logger.group('QasTableGenerator - Automatic columns', [columns])
105
+
104
106
  return columns
105
107
  }
106
108
 
@@ -113,6 +115,8 @@ export default {
113
115
  }
114
116
  })
115
117
 
118
+ this.$qas.logger.group('QasTableGenerator - columns', [columns])
119
+
116
120
  return columns
117
121
  },
118
122
 
@@ -129,9 +133,11 @@ export default {
129
133
  },
130
134
 
131
135
  resultsByFields () {
136
+ if (!Object.keys(this.fields).length) return []
137
+
132
138
  const results = extend(true, [], this.results)
133
139
 
134
- return results.map((result, index) => {
140
+ const mappedResults = results.map((result, index) => {
135
141
  for (const key in result) {
136
142
  result.default = this.results[index]
137
143
  result[key] = humanize(this.fields[key], result[key]) || this.emptyResultText
@@ -139,6 +145,10 @@ export default {
139
145
 
140
146
  return result
141
147
  })
148
+
149
+ this.$qas.logger.group('QasTableGenerator - resultsByFields', [mappedResults])
150
+
151
+ return mappedResults
142
152
  },
143
153
 
144
154
  rowsPerPage () {
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <q-tabs v-model="model" :active-color="activeColor" :indicator-color="indicatorColor" outside-arrows>
3
3
  <slot v-for="(tab, key) in formattedTabs" :item="tab" :name="`tab-${tab.value}`">
4
- <q-tab :key="key" v-bind="tab" :class="tabClass" :label="tab.label" :name="key">
4
+ <q-tab :key="key" v-bind="tab" :class="tabClass" :label="tab.label" :name="tab.value">
5
5
  <slot :item="tab" :name="`tab-after-${tab.value}`">
6
6
  <q-badge v-if="counters[key]" :label="counters[key]" v-bind="defaultCounterProps" />
7
7
  </slot>
@@ -50,7 +50,7 @@ export default {
50
50
  tabs: {
51
51
  default: () => ({}),
52
52
  required: true,
53
- type: Object
53
+ type: [Object, Array]
54
54
  }
55
55
  },
56
56
 
@@ -38,9 +38,9 @@ props:
38
38
  type: String
39
39
 
40
40
  tabs:
41
- desc: Objeto contendo todas as tabs a serem geradas.
41
+ desc: Objeto ou Array contendo todas as tabs a serem geradas.
42
42
  default: {}
43
- type: Object
43
+ type: [Object, Array]
44
44
  examples: ["{ tab1: 'tab1', tab2: 'tab2' }"]
45
45
 
46
46
  slots:
@@ -81,7 +81,7 @@ export default {
81
81
  return {
82
82
  cancel: false,
83
83
  ok: false,
84
- useCloseIcon: true,
84
+ useCloseButton: true,
85
85
  ...this.dialogProps,
86
86
  card: {
87
87
  title: this.dialogTitle,
@@ -15,7 +15,7 @@
15
15
 
16
16
  <qas-btn v-if="showAddFile" ref="buttonUpload" color="white" dense flat icon="o_add" round @click="$refs.hiddenInput.click()" />
17
17
 
18
- <input ref="hiddenInput" class="qas-uploader__input" :multiple="isMultiple" type="file">
18
+ <input ref="hiddenInput" :accept="attributes.accept" class="qas-uploader__input" :multiple="isMultiple" type="file">
19
19
 
20
20
  <qas-btn ref="buttonCleanFiles" class="hidden" color="white" @click="scope.removeUploadedFiles" />
21
21
  <qas-btn v-if="scope.canUpload" color="white" dense flat icon="o_cloud_upload" round @click="scope.upload" />
@@ -28,7 +28,7 @@
28
28
  <slot name="list" :scope="scope">
29
29
  <div class="col-12 q-col-gutter-md row">
30
30
  <div v-for="(file, index) in getFilesList(scope.files, scope)" :key="index" class="row" :class="itemClass">
31
- <qas-avatar class="q-mr-sm" color="contrast-primary" icon="o_attach_file" :image="file.image" rounded :text-color="getColorFileIcon(file)" />
31
+ <qas-avatar class="q-mr-sm" color="contrast-primary" icon="o_attach_file" :image="file.url" rounded :text-color="getColorFileIcon(file)" />
32
32
 
33
33
  <div class="col items-center no-wrap row">
34
34
  <div class="column no-wrap" :class="{ col: isMultiple }">
@@ -131,6 +131,10 @@ export default {
131
131
 
132
132
  uploading: {
133
133
  type: Boolean
134
+ },
135
+
136
+ useObjectModel: {
137
+ type: Boolean
134
138
  }
135
139
  },
136
140
 
@@ -244,12 +248,19 @@ export default {
244
248
  uploaded (response) {
245
249
  const fullPath = response.xhr.responseURL.split('?').shift()
246
250
 
247
- this.$emit(
248
- 'update:modelValue',
249
- this.isMultiple ? [...this.modelValue, fullPath] : fullPath || ''
250
- )
251
+ const objectValue = {
252
+ format: response.files[0].type,
253
+ url: fullPath,
254
+ name: response.files[0].name
255
+ }
256
+
257
+ const model = this.useObjectModel ? objectValue : fullPath
258
+
259
+ this.$emit('update:modelValue', this.isMultiple ? [...this.modelValue, model] : model || '')
251
260
 
252
261
  this.updateUploading(false)
262
+
263
+ this.$qas.logger.group('QasUploader - uploaded', [this.modelValue])
253
264
  },
254
265
 
255
266
  async fetchCredentials (filename) {
@@ -260,6 +271,12 @@ export default {
260
271
  entity: this.entity,
261
272
  filename
262
273
  })
274
+
275
+ this.$qas.logger.group(
276
+ 'QasUploader - fetchCredentials -> resposta de /upload-credentials/',
277
+ [data]
278
+ )
279
+
263
280
  return data
264
281
  } finally {
265
282
  this.isFetching = false
@@ -278,8 +295,16 @@ export default {
278
295
  }
279
296
 
280
297
  const clonedValue = extend(true, [], this.modelValue)
281
- const numberIndex = this.modelValue.findIndex(file => this.getFileName(file) === index)
298
+ const numberIndex = this.modelValue.findIndex(file => {
299
+ if (this.useObjectModel) {
300
+ return file.uuid === index || file.url.includes(index)
301
+ }
302
+
303
+ return this.getFileName(file) === index
304
+ })
305
+
282
306
  clonedValue.splice(numberIndex, 1)
307
+
283
308
  this.$emit('update:modelValue', clonedValue)
284
309
  },
285
310
 
@@ -288,12 +313,10 @@ export default {
288
313
  },
289
314
 
290
315
  getFilesList (uploadedFiles) {
291
- const pathsList = Array.isArray(this.modelValue) ? this.modelValue : (this.modelValue ? [this.modelValue] : [])
292
-
293
316
  uploadedFiles = uploadedFiles.map((file, indexToDelete) => {
294
317
  return {
295
318
  isUploaded: true,
296
- image: file.xhr ? file.xhr.responseURL.split('?').shift() : '',
319
+ url: file.xhr ? file.xhr.responseURL.split('?').shift() : '',
297
320
  name: file.name,
298
321
  progressLabel: file.__progressLabel,
299
322
  sizeLabel: file.__sizeLabel,
@@ -302,11 +325,20 @@ export default {
302
325
  }
303
326
  })
304
327
 
328
+ const pathsList = Array.isArray(this.modelValue)
329
+ ? this.modelValue
330
+ : (this.modelValue ? [this.modelValue] : [])
331
+
305
332
  const mergedList = [...pathsList, ...uploadedFiles]
306
333
 
307
334
  const files = {}
308
335
 
309
336
  mergedList.forEach(file => {
337
+ if (this.useObjectModel && file.uuid) {
338
+ files[file.uuid] = file
339
+ return
340
+ }
341
+
310
342
  if (file.isFailed) {
311
343
  files[file.name] = file
312
344
  return
@@ -314,16 +346,18 @@ export default {
314
346
 
315
347
  if (typeof file === 'string') {
316
348
  const fileName = this.getFileName(file)
317
- files[fileName] = { image: file, isUploaded: false, name: fileName }
349
+ files[fileName] = { url: file, isUploaded: false, name: fileName }
318
350
  return
319
351
  }
320
352
 
321
- if (file.image) {
322
- const fileName = this.getFileName(file.image)
353
+ if (file.url) {
354
+ const fileName = this.getFileName(file.url)
323
355
  files[fileName] = file
324
356
  }
325
357
  })
326
358
 
359
+ this.$qas.logger.group('QasUploader - getFilesList', [files])
360
+
327
361
  return files
328
362
  },
329
363
 
@@ -343,6 +377,8 @@ export default {
343
377
  const filesList = Array.from(this.hiddenInputElement.files)
344
378
  const processedFiles = []
345
379
 
380
+ this.$refs.hiddenInput.value = ''
381
+
346
382
  filesList.forEach(file => processedFiles.push(this.resizeImage(file)))
347
383
  this.uploader.addFiles(await Promise.all(processedFiles))
348
384
  },
@@ -362,7 +398,14 @@ export default {
362
398
  // Retorna largura e altura da original da imagem
363
399
  const { width, height } = await getImageSize(image)
364
400
 
365
- if (width <= this.sizeLimit) return file
401
+ if (width <= this.sizeLimit) {
402
+ this.$qas.logger.info(`
403
+ QasUploader - resizeImage -> Tamanho da imagem menor que o tamanho limite,
404
+ sendo assim, não faz o resize
405
+ `)
406
+
407
+ return file
408
+ }
366
409
 
367
410
  // Retorna os novos tamanhos redimensionados
368
411
  const resizedDimensions = getResizeDimensions(this.sizeLimit, width, height)
@@ -380,7 +423,11 @@ export default {
380
423
  const resizedImage = await pica.resize(image, canvas, this.defaultPicaResizeOptions)
381
424
  const blob = await pica.toBlob(resizedImage, type, 0.90)
382
425
 
383
- return new File([blob], file.name, { type })
426
+ const newFile = new File([blob], file.name, { type })
427
+
428
+ this.$qas.logger.group('QasUploader - resizeImage -> nova imagem', [newFile])
429
+
430
+ return newFile
384
431
  } catch {
385
432
  // Caso não consiga redimensionar retorna o arquivo original
386
433
  return file
@@ -76,6 +76,11 @@ props:
76
76
  examples: [v-model:uploading="isUploading"]
77
77
  model: true
78
78
 
79
+ useObjectModel:
80
+ desc: Controla se a model retornará um array de objetos.
81
+ type: Boolean
82
+ model: true
83
+
79
84
  slots:
80
85
  header:
81
86
  desc: Acesso ao header do <q-uploader />.
@@ -0,0 +1,15 @@
1
+ import { camelize } from 'humps'
2
+
3
+ export default function camelizeFieldsName (fields) {
4
+ for (const field in fields) {
5
+ const currentField = fields[field]
6
+
7
+ currentField.name = camelize(currentField.name)
8
+
9
+ if (Object.keys(currentField.children || {}).length) {
10
+ camelizeFieldsName(currentField.children)
11
+ }
12
+ }
13
+
14
+ return fields
15
+ }
@@ -114,6 +114,8 @@ function humanize (field = {}, value) {
114
114
  case 'time': return time(value)
115
115
  case 'radio': return selectLabel(field.options, value)
116
116
  case 'percent': return formatPercent(value)
117
+ case 'money': return money(value)
118
+ case 'decimal': return decimal(value)
117
119
  default: return value
118
120
  }
119
121
  }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * param {options: object[], label: string, value: string} object
3
+ *
4
+ * @example getNormalizedOptions({
5
+ * options: [{ name: 'Test 1', uuid: '1' }, { name: 'Test 2', uuid: '2' }],
6
+ * label: 'name'
7
+ * value: 'uuid'
8
+ * }) // retorna [{ label: 'Test 1', value: '1' }, { label: 'Test 2', value: '2' }]
9
+ */
10
+ export default ({ options = [], label, value }) => {
11
+ return options.map(option => {
12
+ const { [label]: labelKey, [value]: valueKey, ...payload } = option
13
+
14
+ return {
15
+ label: option[label],
16
+ value: option[value],
17
+ ...payload
18
+ }
19
+ })
20
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @param {function} processEnv função que retorna o process.env.
3
+ * @param {string} defaultValue valor default caso não exista a process.env
4
+ *
5
+ * @example handleProcess(() => process.env.MY_ENV, 'meu-valor-default')
6
+ */
7
+ export default (processEnv = () => {}, defaultValue) => {
8
+ try {
9
+ return processEnv() || defaultValue
10
+ } catch {
11
+ return defaultValue
12
+ }
13
+ }
@@ -8,6 +8,9 @@ export { default as filterObject } from './filter-object.js'
8
8
  export { default as getGreatestCommonDivisor } from './get-greatest-common-divisor.js'
9
9
  export { default as filterObjectToArray } from './filter-object-to-array.js'
10
10
  export { default as filterListByHandle } from './filter-list-by-handle.js'
11
+ export { default as camelizeFieldsName } from './camelize-fields-name.js'
12
+ export { default as getNormalizedOptions } from './get-normalized-options.js'
13
+ export { default as handleProcess } from './handle-process.js'
11
14
 
12
15
  export * from './filters.js'
13
16
  export * from './images.js'
@@ -15,7 +15,9 @@ export default {
15
15
  gutter: {
16
16
  default: 'md',
17
17
  type: [String, Boolean],
18
- validator: value => ['xs', 'sm', 'md', 'lg', 'xl'].includes(value)
18
+ validator: value => {
19
+ return typeof value === 'boolean' || ['xs', 'sm', 'md', 'lg', 'xl'].includes(value)
20
+ }
19
21
  }
20
22
  },
21
23
 
@@ -64,7 +66,13 @@ export default {
64
66
  },
65
67
 
66
68
  mx_handleColumnsByIndex (index, isGridGenerator) {
67
- const fields = isGridGenerator ? this.fields : this.groupedFields.visible
69
+ const fields = isGridGenerator ? this.fields : {}
70
+
71
+ if (!isGridGenerator) {
72
+ for (const key in this.normalizedFields) {
73
+ Object.assign(fields, this.normalizedFields[key].fields.visible)
74
+ }
75
+ }
68
76
 
69
77
  if (!Array.isArray(fields)) {
70
78
  index = Object.keys(fields).findIndex(field => field === index)
@@ -1,6 +1,7 @@
1
1
  import contextMixin from './context.js'
2
2
  import formMixin from './form.js'
3
3
  import generatorMixin from './generator.js'
4
+ import searchFilterMixin from './search-filter.js'
4
5
  import passwordMixin from './password.js'
5
6
  import viewMixin from './view.js'
6
7
 
@@ -8,6 +9,7 @@ export {
8
9
  contextMixin,
9
10
  formMixin,
10
11
  generatorMixin,
12
+ searchFilterMixin,
11
13
  passwordMixin,
12
14
  viewMixin
13
15
  }