@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
@@ -1,19 +1,17 @@
1
1
  <template>
2
- <div>
3
- <qas-input v-model="model" bottom-slots v-bind="$attrs" remove-error-on-type :type="type">
4
- <template #append>
5
- <q-icon class="cursor-pointer" :color="iconColor" :name="icon" @click="toggle" />
6
- </template>
7
-
8
- <template v-for="(_, name) in $slots" #[name]="context">
9
- <slot :name="name" v-bind="context || {}" />
10
- </template>
11
-
12
- <template v-if="!hideStrengthChecker" #hint>
13
- <qas-password-strength-checker v-bind="strengthCheckerProps" :password="model" />
14
- </template>
15
- </qas-input>
16
- </div>
2
+ <qas-input v-model="model" :bottom-slots="false" v-bind="$attrs" :type="type" use-remove-error-on-type>
3
+ <template #append>
4
+ <q-icon class="cursor-pointer" :color="iconColor" :name="icon" @click="toggle" />
5
+ </template>
6
+
7
+ <template v-for="(_, name) in $slots" #[name]="context">
8
+ <slot :name="name" v-bind="context || {}" />
9
+ </template>
10
+
11
+ <template v-if="useStrengthChecker" #hint>
12
+ <qas-password-strength-checker v-bind="strengthCheckerProps" :password="model" />
13
+ </template>
14
+ </qas-input>
17
15
  </template>
18
16
 
19
17
  <script>
@@ -29,8 +27,11 @@ export default {
29
27
 
30
28
  mixins: [passwordMixin],
31
29
 
30
+ inheritAttrs: false,
31
+
32
32
  props: {
33
- hideStrengthChecker: {
33
+ useStrengthChecker: {
34
+ default: true,
34
35
  type: Boolean
35
36
  },
36
37
 
@@ -7,22 +7,11 @@ mixins:
7
7
  - '@bildvitta/quasar-ui-asteroid/dist/api/QasInput.json'
8
8
  - quasar/dist/api/QInput.json
9
9
  props:
10
- use-strength-checker:
11
- desc: Controla exibição do componente `QasStrenghtChecker`.
12
- default: true
13
- type: Boolean
14
-
15
10
  icon-color:
16
11
  desc: Cor do ícone do input.
17
12
  default: primary
18
13
  type: String
19
14
 
20
- model-value:
21
- desc: Model do componente.
22
- type: String
23
- examples: [v-model="value"]
24
- model: true
25
-
26
15
  levels:
27
16
  desc: Níveis de força da senha, é um objeto de objeto.
28
17
  type: [Object, Boolean]
@@ -59,6 +48,12 @@ props:
59
48
  progress: 1
60
49
  textClass: text-positive
61
50
 
51
+ model-value:
52
+ desc: Model do componente.
53
+ type: String
54
+ examples: [v-model="value"]
55
+ model: true
56
+
62
57
  minlength:
63
58
  desc: Número mínimo de caracteres.
64
59
  default: 8
@@ -74,6 +69,11 @@ props:
74
69
  default: blue-grey-1
75
70
  type: String
76
71
 
72
+ use-strength-checker:
73
+ desc: Controla exibição do componente `QasStrengthChecker`.
74
+ default: true
75
+ type: Boolean
76
+
77
77
  use-lowercase:
78
78
  desc: Obrigatório uso de letra(s) minuscula.
79
79
  default: true
@@ -4,16 +4,6 @@ meta:
4
4
  desc: Componente para checar nível de força da senha.
5
5
 
6
6
  props:
7
- model-value:
8
- desc: Model do componente, retorna se passou ou não na validação de senha.
9
- type: Boolean
10
- examples: [v-model="value"]
11
- model: true
12
-
13
- password:
14
- desc: Senha para ser usado nas validações.
15
- type: String
16
-
17
7
  levels:
18
8
  desc: Níveis de força da senha, é um objeto de objeto.
19
9
  type: [Object, Boolean]
@@ -50,6 +40,16 @@ props:
50
40
  progress: 1
51
41
  textClass: text-positive
52
42
 
43
+ password:
44
+ desc: Senha para ser usado nas validações.
45
+ type: String
46
+
47
+ model-value:
48
+ desc: Model do componente, retorna se passou ou não na validação de senha.
49
+ type: Boolean
50
+ examples: [v-model="value"]
51
+ model: true
52
+
53
53
  minlength:
54
54
  desc: Número mínimo de caracteres.
55
55
  default: 8
@@ -13,7 +13,7 @@
13
13
  </div>
14
14
  </div>
15
15
  <slot name="grid">
16
- <qas-grid-generator class="col-lg-7 col-xs-12 items-center" :columns="columns" :fields="filterObject(fields, list)" hide-empty-result :result="result">
16
+ <qas-grid-generator class="col-lg-7 col-xs-12 items-center" :columns="columns" :fields="filterObject(fields, list)" :result="result" :use-empty-result="false">
17
17
  <template v-for="(_, name) in $slots" #[name]="context">
18
18
  <slot :name="name" v-bind="context || {}" />
19
19
  </template>
@@ -25,7 +25,6 @@
25
25
 
26
26
  <script>
27
27
  import filterObject from '../../helpers/filter-object'
28
- import screenMixin from '../../mixins/screen'
29
28
 
30
29
  import QasAvatar from '../avatar/QasAvatar.vue'
31
30
  import QasBox from '../box/QasBox.vue'
@@ -40,8 +39,6 @@ export default {
40
39
  QasGridGenerator
41
40
  },
42
41
 
43
- mixins: [screenMixin],
44
-
45
42
  props: {
46
43
  columns: {
47
44
  type: Object,
@@ -82,7 +79,7 @@ export default {
82
79
 
83
80
  computed: {
84
81
  directionClasses () {
85
- return this.mx_untilMedium ? 'col' : 'row items-center'
82
+ return this.$qas.screen.untilMedium ? 'col' : 'row items-center'
86
83
  },
87
84
 
88
85
  userAvatarImage () {
@@ -90,7 +87,7 @@ export default {
90
87
  },
91
88
 
92
89
  avatarSize () {
93
- return this.mx_isSmall ? '145px' : '188px'
90
+ return this.$qas.screen.isSmall ? '145px' : '188px'
94
91
  }
95
92
  },
96
93
 
@@ -34,16 +34,16 @@ props:
34
34
  desc: Subtitulo do cabeçalho de perfil.
35
35
  type: String
36
36
 
37
- title:
38
- desc: Título do cabeçalho de perfil.
39
- type: String
40
- required: true
41
-
42
37
  tag:
43
38
  desc: Tag do componente pai.
44
39
  default: qas-box
45
40
  type: String
46
41
 
42
+ title:
43
+ desc: Título do cabeçalho de perfil.
44
+ type: String
45
+ required: true
46
+
47
47
  slots:
48
48
  default:
49
49
  desc: Slot para acessar seção de título e subtitulo.
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <q-img :ratio="ratio" spinner-color="grey-6" :src="imageSource">
2
+ <q-img :ratio="ratio" spinner-color="grey-7" :src="imageSource">
3
3
  <template #error>
4
4
  <div class="absolute-full bg-grey-2 flex flex-center text-grey">⚠︎</div>
5
5
  </template>
@@ -7,6 +7,12 @@ meta:
7
7
  desc: Componente para exibir imagem redimensionadas, implementa o "QImg".
8
8
 
9
9
  props:
10
+ resize:
11
+ desc: Formato de ajuste.
12
+ default: cover
13
+ type: String
14
+ examples: [cover, contain, fill, inside, outside]
15
+
10
16
  size:
11
17
  desc: Tamanho da imagem.
12
18
  type: String
@@ -16,8 +22,3 @@ props:
16
22
  type: String
17
23
  examples: [bild-vitta.png]
18
24
 
19
- resize:
20
- desc: Formato de ajuste.
21
- default: cover
22
- type: String
23
- examples: [cover, contain, fill, inside, outside]
@@ -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,88 +103,162 @@ 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 () {
96
155
  return {
97
- distance: 100,
98
- location: 0,
99
- maxPatternLength: 32,
100
- minMatchCharLength: 1,
101
- shouldSort: true,
102
156
  threshold: 0.1,
103
- tokenize: true,
157
+ ignoreLocation: true,
104
158
 
105
159
  ...this.fuseOptions
106
160
  }
107
161
  },
108
162
 
109
- hasResults () {
110
- 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
111
177
  }
112
178
  },
113
179
 
114
180
  watch: {
115
181
  defaultFuseOptions (value) {
182
+ if (this.useLazyLoading) return
183
+
116
184
  this.fuse.options = { ...this.fuse.options, ...value }
117
185
  },
118
186
 
119
- hasResults (value) {
187
+ mx_hasFilteredOptions (value) {
120
188
  !value && this.$emit('empty-result')
121
189
  },
122
190
 
123
- list: {
124
- handler (value) {
125
- this.fuse = new Fuse(value, this.defaultFuseOptions)
191
+ mx_search: {
192
+ async handler (value) {
193
+ this.$emit('update:modelValue', value)
126
194
 
127
- this.setResults(this.search)
128
- this.updateResultsModel(value)
129
- },
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
+ }
130
203
 
131
- deep: true
204
+ this.filterOptionsByFuse(value)
205
+ }
132
206
  },
133
207
 
134
- search: {
208
+ modelValue: {
135
209
  handler (value) {
136
- this.setResults(value)
137
- this.$emit('update:modelValue', value)
210
+ this.mx_search = value
138
211
  },
139
212
 
140
213
  immediate: true
141
214
  },
142
215
 
143
- searchResults: {
144
- handler (value) {
145
- this.updateResultsModel(value)
216
+ mx_filteredOptions: {
217
+ handler (options) {
218
+ this.$emit('update:results', options)
146
219
  },
220
+
147
221
  immediate: true
148
222
  }
149
223
  },
150
224
 
151
225
  created () {
152
- this.search = this.modelValue
226
+ if (this.useLazyLoading) return
227
+
228
+ this.mx_filteredOptions = this.list
153
229
  this.fuse = new Fuse(this.list, this.defaultFuseOptions)
154
- this.setResults()
230
+
231
+ this.setListWatcher()
155
232
  },
156
233
 
157
234
  methods: {
158
- setResults (value) {
159
- this.searchResults = value
160
- ? this.fuse.search(value)
161
- : this.list
235
+ filterOptionsByFuse (value) {
236
+ this.mx_filteredOptions = value ? this.mx_getNormalizedFuseResults(this.fuse.search(value)) : this.list
162
237
  },
163
238
 
164
- updateResultsModel (value) {
165
- 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 })
166
262
  }
167
263
  }
168
264
  }
@@ -9,20 +9,50 @@ 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
- default: "{ distance: 100, location: 0, maxPatternLength: 32, minMatchCharLength: 1, shouldSort: true, threshold: 0.1, tokenize: true }"
15
32
  debugger: true
16
33
  type: Object
17
34
  examples: ["{ keys: ['label'] }"]
35
+ default:
36
+ ignoreLocation: true
37
+ threshold: 0.1
18
38
 
19
39
  height:
20
40
  desc: Define altura do box quando a lista não está vazia.
21
41
  default: 300px
22
42
  type: String
23
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
+
24
54
  list:
25
- 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).
26
56
  default: []
27
57
  type: String
28
58
 
@@ -32,16 +62,16 @@ props:
32
62
  examples: [v-model="search"]
33
63
  model: true
34
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
+
35
70
  placeholder:
36
71
  desc: Placeholder do campo de pesquisa.
37
72
  default: Pesquisar
38
73
  type: String
39
74
 
40
- use-empty-slot:
41
- desc: Controla o slot "empty-result".
42
- default: true
43
- type: Boolean
44
-
45
75
  results:
46
76
  desc: Model que retorna o resultado filtrado.
47
77
  default: []
@@ -49,6 +79,16 @@ props:
49
79
  examples: [v-model:results="results"]
50
80
  model: true
51
81
 
82
+ use-empty-slot:
83
+ desc: Controla o slot "empty-result".
84
+ default: true
85
+ type: Boolean
86
+
87
+ use-lazy-loading:
88
+ desc: Controla a busca pela store "fetchFieldOptions".
89
+ default: false
90
+ type: Boolean
91
+
52
92
  slots:
53
93
  default:
54
94
  desc: Acesso ao conteúdo principal, só existe caso a busca retorne algum resultado.
@@ -56,6 +96,9 @@ slots:
56
96
  empty-result:
57
97
  desc: Acesso ao conteúdo quando a busca não retorne resultado e a prop "useEmptySlot" seja "true".
58
98
 
99
+ loading:
100
+ desc: Acesso ao conteúdo do loading que contém o "<q-spinner-dots />"..
101
+
59
102
  events:
60
103
  '@empty-result -> function ()':
61
104
  desc: Dispara toda vez que a pesquisa não retorna resultado.
@@ -74,3 +117,27 @@ events:
74
117
  desc: Novo valor do v-model:results
75
118
  default: []
76
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