@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
@@ -1,42 +1,64 @@
1
1
  <template>
2
2
  <qas-box>
3
- <q-input v-model="search" clearable :disable="!list.length" outlined :placeholder="placeholder">
3
+ <qas-input v-bind="attributes" ref="search" v-model="mx_search">
4
4
  <template #append>
5
5
  <q-icon color="primary" name="o_search" />
6
6
  </template>
7
- </q-input>
7
+ </qas-input>
8
8
 
9
- <div class="overflow-auto q-mt-xs relative-position" :style="contentStyle">
10
- <slot v-if="hasResults" />
9
+ <div ref="scrollContainer" class="overflow-auto q-mt-xs relative-position" :style="containerStyle">
10
+ <component :is="component.is" v-bind="component.props">
11
+ <slot v-if="mx_hasFilteredOptions" />
12
+ </component>
11
13
 
12
- <slot v-else-if="useEmptySlot" name="empty-result">
14
+ <slot v-if="showSpinnerDots" name="loading">
15
+ <div class="flex justify-center q-pb-sm">
16
+ <q-spinner-dots color="primary" size="20px" />
17
+ </div>
18
+ </slot>
19
+
20
+ <slot v-if="showEmptyResult" name="empty-result">
13
21
  <div class="absolute-center text-center">
14
22
  <q-icon class="q-mb-sm text-center" color="primary" name="o_search" size="38px" />
15
- <div>Não resultados disponíveis.</div>
23
+ <div>{{ emptyResultText }}</div>
16
24
  </div>
17
25
  </slot>
26
+
27
+ <q-inner-loading :showing="showInnerLoading">
28
+ <q-spinner color="grey" size="3em" />
29
+ </q-inner-loading>
18
30
  </div>
19
31
  </qas-box>
20
32
  </template>
21
33
 
22
34
  <script>
35
+ import { QInfiniteScroll } from 'quasar'
23
36
  import Fuse from 'fuse.js'
24
37
 
25
38
  import QasBox from '../box/QasBox.vue'
39
+ import { searchFilterMixin } from '../../mixins'
26
40
 
27
41
  export default {
28
42
  name: 'QasSearchBox',
29
43
 
30
44
  components: {
31
- QasBox
45
+ QasBox,
46
+ QInfiniteScroll
32
47
  },
33
48
 
49
+ mixins: [searchFilterMixin],
50
+
34
51
  props: {
35
52
  emptyListHeight: {
36
53
  default: '100px',
37
54
  type: String
38
55
  },
39
56
 
57
+ emptyResultText: {
58
+ default: 'Não há resultados disponíveis.',
59
+ type: String
60
+ },
61
+
40
62
  fuseOptions: {
41
63
  default: () => ({}),
42
64
  type: Object
@@ -81,15 +103,52 @@ export default {
81
103
 
82
104
  data () {
83
105
  return {
84
- fuse: null,
85
- searchResults: this.list,
86
- search: ''
106
+ fuse: null
87
107
  }
88
108
  },
89
109
 
90
110
  computed: {
91
- contentStyle () {
92
- return { height: this.list.length ? this.height : this.emptyListHeight }
111
+ attributes () {
112
+ return {
113
+ clearable: true,
114
+ disable: this.isDisabled,
115
+ debounce: this.useLazyLoading ? 500 : 0,
116
+ outlined: true,
117
+ placeholder: this.placeholder,
118
+ hideBottomSpace: true,
119
+ error: this.mx_hasFetchError,
120
+ loading: this.mx_isFetching
121
+ }
122
+ },
123
+
124
+ containerStyle () {
125
+ return { height: this.containerHeight }
126
+ },
127
+
128
+ hasNoOptionsOnFirstFetch () {
129
+ return this.mx_fetchCount === 1 && !this.mx_hasFilteredOptions
130
+ },
131
+
132
+ containerHeight () {
133
+ const hasEmptyList = (!this.list.length && !this.useLazyLoading) || this.hasNoOptionsOnFirstFetch
134
+
135
+ return hasEmptyList ? this.emptyListHeight : this.height
136
+ },
137
+
138
+ component () {
139
+ const infiniteScrollProps = {
140
+ offset: 100,
141
+ scrollTarget: this.$refs.scrollContainer,
142
+ ref: 'infiniteScrollRef'
143
+ }
144
+
145
+ return {
146
+ is: this.useLazyLoading ? 'q-infinite-scroll' : 'div',
147
+ props: {
148
+ ...(this.useLazyLoading && infiniteScrollProps),
149
+ ...(this.useLazyLoading && { onLoad: this.onInfiniteScroll })
150
+ }
151
+ }
93
152
  },
94
153
 
95
154
  defaultFuseOptions () {
@@ -101,63 +160,105 @@ export default {
101
160
  }
102
161
  },
103
162
 
104
- hasResults () {
105
- return !!this.searchResults.length
163
+ isDisabled () {
164
+ return (!this.useLazyLoading && !this.list.length) || this.mx_isFetching || this.hasNoOptionsOnFirstFetch
165
+ },
166
+
167
+ showEmptyResult () {
168
+ return this.useEmptySlot && !this.mx_hasFilteredOptions && !this.mx_isFetching
169
+ },
170
+
171
+ showSpinnerDots () {
172
+ return this.mx_hasFilteredOptions && this.mx_isFetching
173
+ },
174
+
175
+ showInnerLoading () {
176
+ return !this.mx_hasFilteredOptions && this.mx_isFetching
106
177
  }
107
178
  },
108
179
 
109
180
  watch: {
110
181
  defaultFuseOptions (value) {
182
+ if (this.useLazyLoading) return
183
+
111
184
  this.fuse.options = { ...this.fuse.options, ...value }
112
185
  },
113
186
 
114
- hasResults (value) {
187
+ mx_hasFilteredOptions (value) {
115
188
  !value && this.$emit('empty-result')
116
189
  },
117
190
 
118
- list: {
119
- handler (value) {
120
- this.fuse = new Fuse(value, this.defaultFuseOptions)
191
+ mx_search: {
192
+ async handler (value) {
193
+ this.$emit('update:modelValue', value)
121
194
 
122
- this.setResults(this.search)
123
- this.updateResultsModel(value)
124
- },
195
+ if (this.useLazyLoading) {
196
+ await this.mx_filterOptionsByStore(value)
197
+
198
+ this.$refs.infiniteScrollRef.resume()
199
+ this.$refs.search.focus()
200
+
201
+ return
202
+ }
125
203
 
126
- deep: true
204
+ this.filterOptionsByFuse(value)
205
+ }
127
206
  },
128
207
 
129
- search: {
208
+ modelValue: {
130
209
  handler (value) {
131
- this.setResults(value)
132
- this.$emit('update:modelValue', value)
210
+ this.mx_search = value
133
211
  },
134
212
 
135
213
  immediate: true
136
214
  },
137
215
 
138
- searchResults: {
139
- handler (value) {
140
- this.updateResultsModel(value)
216
+ mx_filteredOptions: {
217
+ handler (options) {
218
+ this.$emit('update:results', options)
141
219
  },
220
+
142
221
  immediate: true
143
222
  }
144
223
  },
145
224
 
146
225
  created () {
147
- this.search = this.modelValue
226
+ if (this.useLazyLoading) return
227
+
228
+ this.mx_filteredOptions = this.list
148
229
  this.fuse = new Fuse(this.list, this.defaultFuseOptions)
149
- this.setResults()
230
+
231
+ this.setListWatcher()
150
232
  },
151
233
 
152
234
  methods: {
153
- setResults (value) {
154
- this.searchResults = value
155
- ? this.fuse.search(value)
156
- : this.list
235
+ filterOptionsByFuse (value) {
236
+ this.mx_filteredOptions = value ? this.mx_getNormalizedFuseResults(this.fuse.search(value)) : this.list
157
237
  },
158
238
 
159
- updateResultsModel (value) {
160
- this.$emit('update:results', value.map(result => result.item || result))
239
+ async onInfiniteScroll (_, done) {
240
+ // Se tiver erro no primeiro fetch, retorna o "done" na proxima.
241
+ if (((this.mx_hasFetchError && !this.mx_hasFilteredOptions) || this.hasNoOptionsOnFirstFetch)) return done()
242
+
243
+ if (!this.mx_hasFilteredOptions && !this.mx_search) {
244
+ await this.mx_setFetchOptions()
245
+ return done()
246
+ }
247
+
248
+ if (this.mx_canFetchOptions()) {
249
+ await this.mx_loadMoreOptions()
250
+ return done()
251
+ }
252
+
253
+ done(true)
254
+ },
255
+
256
+ setListWatcher () {
257
+ this.$watch('list', value => {
258
+ this.fuse = new Fuse(value, this.defaultFuseOptions)
259
+
260
+ this.filterOptionsByFuse(this.mx_search)
261
+ }, { deep: true })
161
262
  }
162
263
  }
163
264
  }
@@ -9,6 +9,24 @@ props:
9
9
  default: 100px
10
10
  type: String
11
11
 
12
+ empty-result-text:
13
+ desc: Define o texto dentro do box quando a lista está vazia.
14
+ default: Não há resultados disponíveis.
15
+ type: String
16
+
17
+ entity:
18
+ desc: Entidade enviada para a action "fetchFieldOptions" (usar somente quando "useLazyLoading" estiver habilitada).
19
+ default: ''
20
+ type: String
21
+ examples: [users]
22
+
23
+ fetching:
24
+ desc: Usado para saber quando o componente está fazendo fetching (usar somente quando "useLazyLoading" estiver habilitada).
25
+ default: false
26
+ type: Boolean
27
+ model: true
28
+ examples: [v-model:fetching="isFetching"]
29
+
12
30
  fuse-options:
13
31
  desc: Opções do Fuse.js (https://fusejs.io/api/options.html).
14
32
  debugger: true
@@ -23,8 +41,18 @@ props:
23
41
  default: 300px
24
42
  type: String
25
43
 
44
+ lazy-loading-props:
45
+ desc: Propriedades para o lazy loading (usar somente quando "useLazyLoading" estiver habilitada).
46
+ type: Object
47
+ debugger: true
48
+ default:
49
+ decamelizeFieldName: true
50
+ url: ''
51
+ params:
52
+ limit: 48
53
+
26
54
  list:
27
- desc: Lista onde ocorrerá a busca (array de objetos).
55
+ desc: Lista onde ocorrerá a busca sendo array de objetos (usar somente quando "useLazyLoading" **NÃO** estiver habilitada).
28
56
  default: []
29
57
  type: String
30
58
 
@@ -34,6 +62,11 @@ props:
34
62
  examples: [v-model="search"]
35
63
  model: true
36
64
 
65
+ name:
66
+ desc: Nome do campo a ser enviado para a action "fetchFieldOptions" (usar somente quando "useLazyLoading" estiver habilitada).
67
+ type: String
68
+ examples: [cities]
69
+
37
70
  placeholder:
38
71
  desc: Placeholder do campo de pesquisa.
39
72
  default: Pesquisar
@@ -51,6 +84,11 @@ props:
51
84
  default: true
52
85
  type: Boolean
53
86
 
87
+ use-lazy-loading:
88
+ desc: Controla a busca pela store "fetchFieldOptions".
89
+ default: false
90
+ type: Boolean
91
+
54
92
  slots:
55
93
  default:
56
94
  desc: Acesso ao conteúdo principal, só existe caso a busca retorne algum resultado.
@@ -58,6 +96,9 @@ slots:
58
96
  empty-result:
59
97
  desc: Acesso ao conteúdo quando a busca não retorne resultado e a prop "useEmptySlot" seja "true".
60
98
 
99
+ loading:
100
+ desc: Acesso ao conteúdo do loading que contém o "<q-spinner-dots />"..
101
+
61
102
  events:
62
103
  '@empty-result -> function ()':
63
104
  desc: Dispara toda vez que a pesquisa não retorna resultado.
@@ -76,3 +117,27 @@ events:
76
117
  desc: Novo valor do v-model:results
77
118
  default: []
78
119
  type: Array
120
+
121
+ '@update:fetching -> function (value)':
122
+ desc: Dispara toda vez que o campo de busca faz o fetch do lazy loading
123
+ params:
124
+ value:
125
+ desc: Novo valor do v-model:fetching
126
+ default: false
127
+ type: Boolean
128
+
129
+ '@fetch-options-success -> function (value)':
130
+ desc: Dispara toda vez que o campo de busca faz o fetch do lazy loading com sucesso.
131
+ params:
132
+ value:
133
+ desc: Valor retornado pela action "fetchFieldOptions"
134
+ default: {}
135
+ type: Object
136
+
137
+ '@fetch-options-error -> function (value)':
138
+ desc: Dispara toda vez que o campo de busca faz o fetch do lazy loading e cai em uma exceção.
139
+ params:
140
+ value:
141
+ desc: Valor retornado pela action "fetchFieldOptions"
142
+ default: {}
143
+ type: Object
@@ -1,13 +1,13 @@
1
1
  <template>
2
- <q-select v-model="model" v-bind="attributes" @filter="filterOptions">
2
+ <q-select v-model="model" v-bind="attributes">
3
3
  <template #append>
4
4
  <slot name="append">
5
- <q-icon v-if="searchable" name="o_search" />
5
+ <q-icon v-if="isSearchable" name="o_search" />
6
6
  </slot>
7
7
  </template>
8
8
 
9
9
  <template #no-option>
10
- <slot name="no-option">
10
+ <slot v-if="!mx_isFetching" name="no-option">
11
11
  <q-item>
12
12
  <q-item-section class="text-grey">
13
13
  {{ noOptionLabel }}
@@ -16,6 +16,14 @@
16
16
  </slot>
17
17
  </template>
18
18
 
19
+ <template #after-options>
20
+ <slot v-if="mx_isFetching" name="after-options">
21
+ <div class="flex justify-center q-pb-sm">
22
+ <q-spinner-dots color="primary" size="20px" />
23
+ </div>
24
+ </slot>
25
+ </template>
26
+
19
27
  <template v-for="(_, name) in $slots" #[name]="context">
20
28
  <slot :name="name" v-bind="context || {}" />
21
29
  </template>
@@ -23,11 +31,14 @@
23
31
  </template>
24
32
 
25
33
  <script>
34
+ import { searchFilterMixin } from '../../mixins'
26
35
  import Fuse from 'fuse.js'
27
36
 
28
37
  export default {
29
38
  name: 'QasSelect',
30
39
 
40
+ mixins: [searchFilterMixin],
41
+
31
42
  props: {
32
43
  fuseOptions: {
33
44
  default: () => ({}),
@@ -41,7 +52,7 @@ export default {
41
52
 
42
53
  modelValue: {
43
54
  default: () => [],
44
- type: [Array, Object, String, Number]
55
+ type: [Array, Object, String, Number, Boolean]
45
56
  },
46
57
 
47
58
  noOptionLabel: {
@@ -54,13 +65,13 @@ export default {
54
65
  type: Array
55
66
  },
56
67
 
57
- searchable: {
58
- type: Boolean
59
- },
60
-
61
68
  valueKey: {
62
69
  default: '',
63
70
  type: String
71
+ },
72
+
73
+ useSearch: {
74
+ type: Boolean
64
75
  }
65
76
  },
66
77
 
@@ -68,7 +79,6 @@ export default {
68
79
 
69
80
  data () {
70
81
  return {
71
- filteredOptions: [],
72
82
  fuse: null
73
83
  }
74
84
  },
@@ -76,15 +86,18 @@ export default {
76
86
  computed: {
77
87
  attributes () {
78
88
  return {
79
- clearable: this.searchable,
89
+ clearable: this.isSearchable,
80
90
  emitValue: true,
81
91
  mapOptions: true,
82
92
  outlined: true,
83
-
84
93
  ...this.$attrs,
85
94
 
86
- options: this.filteredOptions,
87
- useInput: this.searchable
95
+ options: this.mx_filteredOptions,
96
+ useInput: this.isSearchable,
97
+ error: this.hasError,
98
+ loading: this.hasLoading,
99
+ ...(this.useLazyLoading && { onVirtualScroll: this.mx_onVirtualScroll }),
100
+ ...(this.isSearchable && { onFilter: this.onFilter })
88
101
  }
89
102
  },
90
103
 
@@ -98,12 +111,20 @@ export default {
98
111
  }
99
112
  },
100
113
 
101
- formattedResult () {
102
- if (!this.labelKey && !this.valueKey) {
103
- return this.options
104
- }
114
+ isSearchable () {
115
+ return this.useSearch || this.useLazyLoading
116
+ },
117
+
118
+ defaultOptions () {
119
+ return this.mx_handleOptions(this.options)
120
+ },
105
121
 
106
- return this.options.map(item => this.renameKey(item))
122
+ hasError () {
123
+ return this.mx_hasFetchError || this.$attrs.error
124
+ },
125
+
126
+ hasLoading () {
127
+ return this.mx_isFetching || this.$attrs.loading
107
128
  },
108
129
 
109
130
  model: {
@@ -124,11 +145,11 @@ export default {
124
145
 
125
146
  options: {
126
147
  handler () {
127
- if (this.fuse) {
128
- this.fuse.list = this.formattedResult
129
- }
148
+ if (this.useLazyLoading && this.mx_hasFilteredOptions) return
149
+
150
+ if (this.fuse) this.setFuse()
130
151
 
131
- this.filteredOptions = this.formattedResult
152
+ this.mx_filteredOptions = this.defaultOptions
132
153
  },
133
154
 
134
155
  immediate: true
@@ -137,42 +158,37 @@ export default {
137
158
 
138
159
  created () {
139
160
  this.setFuse()
161
+ this.useLazyLoading && this.mx_setFetchOptions('')
140
162
  },
141
163
 
142
164
  methods: {
143
- filterOptions (value, update) {
144
- update(() => {
145
- if (!this.searchable) return
146
-
147
- if (value === '') {
148
- this.filteredOptions = this.formattedResult
149
- } else {
150
- const results = this.fuse.search(value)
151
- this.filteredOptions = results.map(item => item.item)
152
- }
153
- })
165
+ setFuse () {
166
+ if (this.useSearch) {
167
+ this.fuse = new Fuse(this.defaultOptions, this.defaultFuseOptions)
168
+ }
154
169
  },
155
170
 
156
- renameKey (item) {
157
- const mapKeys = {
158
- label: this.labelKey,
159
- value: this.valueKey
171
+ async onFilter (value, update) {
172
+ if (this.useLazyLoading && value !== this.mx_search) {
173
+ await this.mx_filterOptionsByStore(value)
160
174
  }
161
175
 
162
- for (const newKey in mapKeys) {
163
- if (!item.hasOwnProperty.call(newKey)) {
164
- item[newKey] = item[mapKeys[newKey]]
165
- delete item[mapKeys[newKey]]
166
- }
176
+ if (!this.useLazyLoading && this.useSearch) {
177
+ this.filterOptionsByFuse(value)
167
178
  }
168
179
 
169
- return item
180
+ update()
170
181
  },
171
182
 
172
- setFuse () {
173
- if (this.searchable) {
174
- this.fuse = new Fuse(this.options, this.defaultFuseOptions)
183
+ filterOptionsByFuse (value) {
184
+ if (value === '') {
185
+ this.mx_filteredOptions = this.defaultOptions
186
+ return
175
187
  }
188
+
189
+ const results = this.fuse.search(value)
190
+
191
+ this.mx_filteredOptions = this.mx_getNormalizedFuseResults(results)
176
192
  }
177
193
  }
178
194
  }
@@ -7,6 +7,19 @@ meta:
7
7
  desc: Componente para select que implementa o "QSelect" repassando propriedades, slots e eventos.
8
8
 
9
9
  props:
10
+ entity:
11
+ desc: Entidade enviada para a action "fetchFieldOptions" (usar somente quando "useLazyLoading" estiver habilitada).
12
+ default: ''
13
+ type: String
14
+ examples: [users]
15
+
16
+ fetching:
17
+ desc: Usado para saber quando o componente está fazendo fetching (usar somente quando "useLazyLoading" estiver habilitada).
18
+ default: false
19
+ type: Boolean
20
+ model: true
21
+ examples: [v-model:fetching="isFetching"]
22
+
10
23
  fuse-options:
11
24
  desc: Opções do Fuse.js (https://fusejs.io/api/options.html).
12
25
  type: Object
@@ -21,13 +34,28 @@ props:
21
34
  type: String
22
35
  examples: [label-key="name"]
23
36
 
37
+ lazy-loading-props:
38
+ desc: Propriedades para o lazy loading (usar somente quando "useLazyLoading" estiver habilitada).
39
+ type: Object
40
+ debugger: true
41
+ default:
42
+ decamelizeFieldName: true
43
+ url: ''
44
+ params:
45
+ limit: 48
46
+
24
47
  model-value:
25
48
  desc: Model do componente.
26
49
  default: []
27
- type: [Array, Object, String, Number]
50
+ type: [Array, Object, String, Number, Boolean]
28
51
  examples: [v-model="value"]
29
52
  model: true
30
53
 
54
+ name:
55
+ desc: Nome do campo a ser enviado para a action "fetchFieldOptions" (usar somente quando "useLazyLoading" estiver habilitada).
56
+ type: String
57
+ examples: [cities]
58
+
31
59
  no-option-label:
32
60
  desc: Rótulo padrão de quando os options estão vazios.
33
61
  default: Nenhum resultado foi encontrado.
@@ -38,19 +66,48 @@ props:
38
66
  default: []
39
67
  type: Array
40
68
 
41
- searchable:
42
- desc: Controla se vai ou não ter campo de busca no select.
43
- type: Boolean
44
-
45
69
  value-key:
46
70
  desc: O componente internamente espera receber na propriedade "options" um array de objeto contendo "label" e "value", caso o seu objeto não tenha "value" mas um "uuid" por exemplo, você pode definir esta prop "label-value" como "uuid".
47
71
  type: String
48
72
  examples: [value-key="uuid"]
49
73
 
74
+ use-search:
75
+ desc: Controla se vai ou não ter campo de busca no select.
76
+ type: Boolean
77
+
78
+ use-lazy-loading:
79
+ desc: Controla a busca pela store "fetchFieldOptions".
80
+ default: false
81
+ type: Boolean
82
+
50
83
  events:
51
84
  '@update:model-value -> function (value)':
52
85
  desc: Dispara toda vez que o model é atualizado, também utilizado para v-model.
53
86
  params:
54
87
  value:
55
88
  desc: Novo valor do v-model
56
- type: [Array, Object, String, Number]
89
+ type: [Array, Object, String, Number, Boolean]
90
+
91
+ '@update:fetching -> function (value)':
92
+ desc: Dispara toda vez que o campo de busca faz o fetch do lazy loading
93
+ params:
94
+ value:
95
+ desc: Novo valor do v-model:fetching
96
+ default: false
97
+ type: Boolean
98
+
99
+ '@fetch-options-success -> function (value)':
100
+ desc: Dispara toda vez que o campo de busca faz o fetch do lazy loading com sucesso.
101
+ params:
102
+ value:
103
+ desc: Valor retornado pela action "fetchFieldOptions"
104
+ default: {}
105
+ type: Object
106
+
107
+ '@fetch-options-error -> function (value)':
108
+ desc: Dispara toda vez que o campo de busca faz o fetch do lazy loading e cai em uma exceção.
109
+ params:
110
+ value:
111
+ desc: Valor retornado pela action "fetchFieldOptions"
112
+ default: {}
113
+ type: Object