@bildvitta/quasar-ui-asteroid 3.17.0-beta.9 → 3.17.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 (58) hide show
  1. package/package.json +3 -2
  2. package/src/assets/sounds/nave-notification.mp3 +0 -0
  3. package/src/components/app-menu/QasAppMenu.vue +73 -15
  4. package/src/components/app-menu/QasAppMenu.yml +5 -5
  5. package/src/components/app-user/QasAppUser.vue +49 -40
  6. package/src/components/avatar/QasAvatar.vue +7 -8
  7. package/src/components/badge/QasBadge.vue +3 -29
  8. package/src/components/board-generator/QasBoardGenerator.vue +442 -40
  9. package/src/components/board-generator/QasBoardGenerator.yml +107 -12
  10. package/src/components/card/QasCard.vue +13 -4
  11. package/src/components/chart-view/QasChartView.vue +56 -3
  12. package/src/components/chart-view/QasChartView.yml +6 -0
  13. package/src/components/checkbox/QasCheckbox.vue +67 -11
  14. package/src/components/checkbox/QasCheckbox.yml +18 -0
  15. package/src/components/copy/QasCopy.vue +12 -2
  16. package/src/components/copy/QasCopy.yml +8 -0
  17. package/src/components/expansion-item/QasExpansionItem.vue +108 -76
  18. package/src/components/expansion-item/QasExpansionItem.yml +38 -10
  19. package/src/components/field/QasField.vue +1 -1
  20. package/src/components/form-generator/QasFormGenerator.vue +23 -10
  21. package/src/components/form-generator/QasFormGenerator.yml +2 -2
  22. package/src/components/grabbable/QasGrabbable.vue +14 -6
  23. package/src/components/grabbable/QasGrabbable.yml +4 -0
  24. package/src/components/grid-generator/QasGridGenerator.vue +3 -3
  25. package/src/components/grid-generator/QasGridGenerator.yml +2 -2
  26. package/src/components/grid-item/QasGridItem.vue +1 -1
  27. package/src/components/header/QasHeader.vue +11 -9
  28. package/src/components/infinite-scroll/QasInfiniteScroll.vue +16 -17
  29. package/src/components/infinite-scroll/QasInfiniteScroll.yml +7 -0
  30. package/src/components/list-view/QasListView.vue +16 -2
  31. package/src/components/list-view/QasListView.yml +9 -0
  32. package/src/components/radio/QasRadio.vue +24 -5
  33. package/src/components/radio/QasRadio.yml +6 -0
  34. package/src/components/select/QasSelect.vue +11 -2
  35. package/src/components/select/QasSelect.yml +1 -1
  36. package/src/components/select-filter/QasSelectFilter.vue +65 -0
  37. package/src/components/select-filter/QasSelectFilter.yml +36 -0
  38. package/src/components/stepper/QasStepper.vue +50 -3
  39. package/src/components/stepper-form-view/QasStepperFormView.vue +6 -4
  40. package/src/components/stepper-form-view/QasStepperFormView.yml +1 -1
  41. package/src/components/table-generator/QasTableGenerator.vue +3 -0
  42. package/src/components/text-truncate/QasTextTruncate.vue +77 -14
  43. package/src/components/text-truncate/QasTextTruncate.yml +14 -3
  44. package/src/components/uploader/QasUploader.vue +70 -24
  45. package/src/components/uploader/QasUploader.yml +15 -1
  46. package/src/components/welcome/QasWelcome.vue +8 -0
  47. package/src/components/welcome/QasWelcome.yml +3 -0
  48. package/src/composables/index.js +3 -1
  49. package/src/composables/private/index.js +1 -0
  50. package/src/composables/private/use-auth-user.js +20 -0
  51. package/src/composables/private/use-generator.js +20 -5
  52. package/src/composables/use-default-filters.js +106 -0
  53. package/src/composables/use-notifications.js +14 -0
  54. package/src/composables/use-query-cache.js +1 -1
  55. package/src/helpers/set-scroll-on-grab.js +9 -1
  56. package/src/shared/badge-config.js +29 -0
  57. package/src/vue-plugin.js +3 -0
  58. package/src/components/app-menu/private/PvAppMenuHelpChat.vue +0 -222
@@ -18,6 +18,10 @@ props:
18
18
  desc: Seta o título do dialog.
19
19
  type: String
20
20
 
21
+ empty-text:
22
+ desc: Texto a ser exibido no caso de não houver itens no "list" ou o "text" for vazio.
23
+ type: String
24
+
21
25
  max-width:
22
26
  desc: Seta o tamanho máximo do texto.
23
27
  type: Number
@@ -47,13 +51,20 @@ props:
47
51
  default: []
48
52
  type: Array
49
53
 
54
+ use-badge:
55
+ desc: Habilita badges para cada item da lista.
56
+ default: false
57
+ type: Boolean
58
+
50
59
  use-object-list:
51
60
  desc: Utiliza a propriedade "list" como array de objeto contendo label (uso junto a prop list).
61
+ default: false
52
62
  type: Boolean
53
63
 
54
- empty-text:
55
- desc: Texto a ser exibido no caso de não houver itens no "list" ou o "text" for vazio.
56
- type: String
64
+ use-wrap-badge:
65
+ desc: habilita a quebra de linha das badges quando o texto for muito grande.
66
+ default: false
67
+ type: Boolean
57
68
 
58
69
  slots:
59
70
  default:
@@ -3,18 +3,20 @@
3
3
  <q-uploader ref="uploader" auto-upload class="bg-transparent" :class="uploaderClasses" v-bind="attributes" :factory="factory" flat :max-files="maxFiles" method="PUT" @factory-failed="factoryFailed" @uploaded="uploaded" @uploading="updateUploading(true)">
4
4
  <template #header="scope">
5
5
  <slot name="header" :scope="scope">
6
- <div class="flex items-center justify-between">
7
- <div>
8
- <qas-label v-bind="labelProps" />
9
-
10
- <div v-if="errorMessage" class="q-mt-xs text-caption text-negative">
11
- {{ errorMessage }}
6
+ <qas-header class="q-mb-none" v-bind="getHeaderProps(scope)">
7
+ <template #description>
8
+ <div :class="headerDescriptionClasses">
9
+ {{ headerProps.description }}
12
10
  </div>
13
- </div>
11
+ </template>
12
+
13
+ <template v-for="(_, name) in $slots" #[getHeaderSlotName(name)]="context">
14
+ <slot :name v-bind="context" />
15
+ </template>
16
+ </qas-header>
14
17
 
15
- <div v-if="hasAddFile">
16
- <qas-btn color="primary" icon="sym_r_add" :label="addButtonLabel" :use-label-on-small-screen="false" variant="tertiary" @click="onAddButtonClick(scope)" />
17
- </div>
18
+ <div v-if="errorMessage" class="q-mt-xs text-caption text-negative">
19
+ {{ errorMessage }}
18
20
  </div>
19
21
 
20
22
  <!-- ------------------------------------ tags hidden -------------------------------------- -->
@@ -24,15 +26,13 @@
24
26
  </template>
25
27
 
26
28
  <template #list="scope">
27
- <div v-if="hasGalleryCardSection(getFilesList(scope.files, scope))" class="q-col-gutter-lg q-mt-sm row">
29
+ <div v-if="hasGalleryCardSection(getFilesList(scope.files, scope))" class="q-col-gutter-lg row">
28
30
  <div v-for="(file, key, index) in getFilesList(scope.files, scope)" :key="index" :class="columnClasses">
29
31
  <pv-uploader-gallery-card v-bind="getUploaderGalleryCardProps({ key, scope, file, index })" />
30
32
  </div>
31
33
  </div>
32
34
 
33
- <div v-else class="q-mt-lg">
34
- <qas-empty-result-text />
35
- </div>
35
+ <qas-empty-result-text v-else />
36
36
  </template>
37
37
  </q-uploader>
38
38
 
@@ -42,6 +42,7 @@
42
42
 
43
43
  <script>
44
44
  import PvUploaderGalleryCard from './private/PvUploaderGalleryCard.vue'
45
+ import QasHeader from '../header/QasHeader.vue'
45
46
 
46
47
  import { uid, extend } from 'quasar'
47
48
  import { NotifyError } from '../../plugins'
@@ -53,7 +54,8 @@ export default {
53
54
  name: 'QasUploader',
54
55
 
55
56
  components: {
56
- PvUploaderGalleryCard
57
+ PvUploaderGalleryCard,
58
+ QasHeader
57
59
  },
58
60
 
59
61
  inheritAttrs: false,
@@ -125,6 +127,11 @@ export default {
125
127
  type: Object
126
128
  },
127
129
 
130
+ headerProps: {
131
+ type: Object,
132
+ default: () => ({})
133
+ },
134
+
128
135
  label: {
129
136
  type: String,
130
137
  default: ''
@@ -199,6 +206,12 @@ export default {
199
206
  return this.$attrs
200
207
  },
201
208
 
209
+ headerDescriptionClasses () {
210
+ return {
211
+ 'text-negative': this.error
212
+ }
213
+ },
214
+
202
215
  columnClasses () {
203
216
  const irregularClasses = ['col']
204
217
  const columns = this.defaultColumns
@@ -290,15 +303,6 @@ export default {
290
303
  return this.$attrs.multiple || this.$attrs.multiple === ''
291
304
  },
292
305
 
293
- labelProps () {
294
- return {
295
- label: this.label,
296
- margin: 'none',
297
-
298
- ...(this.error && { color: 'negative' })
299
- }
300
- },
301
-
302
306
  self () {
303
307
  return this
304
308
  },
@@ -613,6 +617,48 @@ export default {
613
617
  const emptyModel = this.isMultiple ? [] : this.useObjectModel ? {} : ''
614
618
 
615
619
  this.$emit('update:modelValue', emptyModel)
620
+ },
621
+
622
+ getHeaderSlotName (name) {
623
+ return name.replace('header-', '')
624
+ },
625
+
626
+ getHeaderProps (scope) {
627
+ const { labelProps, actionsMenuProps, ...othersHeaderProps } = this.headerProps
628
+
629
+ const { list, ...othersActionsMenuProps } = actionsMenuProps || {}
630
+
631
+ return {
632
+ spacing: 'lg',
633
+
634
+ labelProps: {
635
+ label: this.label,
636
+
637
+ margin: 'none',
638
+
639
+ ...labelProps,
640
+
641
+ ...(this.error && { color: 'negative' })
642
+ },
643
+
644
+ ...(this.hasAddFile && {
645
+ actionsMenuProps: {
646
+ list: {
647
+ add: {
648
+ icon: 'sym_r_add',
649
+ label: this.addButtonLabel,
650
+ handler: () => this.onAddButtonClick(scope)
651
+ },
652
+
653
+ ...list
654
+ },
655
+
656
+ ...othersActionsMenuProps
657
+ }
658
+ }),
659
+
660
+ ...othersHeaderProps
661
+ }
616
662
  }
617
663
  }
618
664
  }
@@ -83,8 +83,13 @@ props:
83
83
  default: {}
84
84
  type: Object
85
85
 
86
+ header-props:
87
+ desc: Propriedades repassadas para o componente "QasHeader".
88
+ default: {}
89
+ type: Object
90
+
86
91
  label:
87
- desc: Label do componente, repassado para o componente "QasLabel".
92
+ desc: Label do componente.
88
93
  type: String
89
94
 
90
95
  max-files:
@@ -158,6 +163,15 @@ slots:
158
163
  default: {}
159
164
  type: Object
160
165
 
166
+ header-actions:
167
+ desc: Acessa o slot actions do "QasHeader".
168
+
169
+ header-description:
170
+ desc: Acessa o slot description do "QasHeader".
171
+
172
+ header-label:
173
+ desc: Acessa o slot label do "QasHeader".
174
+
161
175
  list:
162
176
  desc: Acesso ao conteúdo onde fica a listagem de arquivos.
163
177
  scope:
@@ -14,6 +14,10 @@
14
14
  </slot>
15
15
  </div>
16
16
 
17
+ <div v-if="hasAfterGreetingSlot" class="q-mt-lg">
18
+ <slot name="after-greeting" />
19
+ </div>
20
+
17
21
  <div v-if="hasShortcuts">
18
22
  <qas-label class="q-mt-lg" label="Atalhos" />
19
23
 
@@ -102,6 +106,10 @@ export default {
102
106
  if (time >= '12:00' && time < '18:59') return 'Boa tarde'
103
107
 
104
108
  return 'Boa noite'
109
+ },
110
+
111
+ hasAfterGreetingSlot () {
112
+ return !!this.$slots['after-greeting']
105
113
  }
106
114
  }
107
115
  }
@@ -21,3 +21,6 @@ props:
21
21
  slots:
22
22
  actions:
23
23
  desc: Slot para substituir o QasActionsMenu.
24
+
25
+ after-greeting:
26
+ desc: Slot para acessar o conteúdo depois da saudação.
@@ -1,8 +1,10 @@
1
1
  export { default as useContext } from './use-context.js'
2
+ export { default as useDefaultFilters } from './use-default-filters.js'
2
3
  export { default as useForm } from './use-form.js'
3
4
  export { default as useHistory } from './use-history.js'
5
+ export { default as useNotifications } from './use-notifications.js'
4
6
  export { default as useQueryCache } from './use-query-cache.js'
5
7
  export { default as useScreen } from './use-screen.js'
6
- export { default as useNotifications } from './use-notifications.js'
7
8
 
8
9
  export * from './use-notifications.js'
10
+ export * from './use-default-filters.js'
@@ -1,3 +1,4 @@
1
1
  export { default as useView } from './use-view'
2
2
  export { default as useGenerator } from './use-generator'
3
3
  export { default as useToggleVisibility } from './use-toggle-visibility'
4
+ export { default as useAuthUser } from './use-auth-user'
@@ -0,0 +1,20 @@
1
+ import { LocalStorage } from 'quasar'
2
+
3
+ import { computed, ref } from 'vue'
4
+
5
+ const user = ref(LocalStorage.getItem('user'))
6
+
7
+ export default function useAuthUser () {
8
+ window.addEventListener('message', ({ data }) => {
9
+ if (data.type !== 'updateUser') return
10
+
11
+ user.value = data.user
12
+ })
13
+
14
+ const hasUser = computed(() => !!user.value)
15
+
16
+ return {
17
+ user,
18
+ hasUser
19
+ }
20
+ }
@@ -1,6 +1,8 @@
1
- import { computed } from 'vue'
2
1
  import { Spacing } from '../../enums/Spacing'
3
2
  import { gutterValidator } from '../../helpers/private/gutter-validator'
3
+ import useScreen from '../use-screen'
4
+
5
+ import { computed } from 'vue'
4
6
 
5
7
  const IRREGULAR_CLASSES = ['col', 'col-auto', 'fit']
6
8
 
@@ -21,7 +23,7 @@ export const baseProps = {
21
23
  },
22
24
 
23
25
  gutter: {
24
- default: Spacing.Md,
26
+ default: undefined,
25
27
  type: [String, Boolean],
26
28
  validator: gutterValidator
27
29
  }
@@ -34,20 +36,33 @@ export const baseProps = {
34
36
  * @name useGenerator
35
37
  * @param {Object} options - Opções do componente.
36
38
  * @param {baseProps} options.props - Propriedades do componente.
39
+ * @param {boolean} options.isGrid - Propriedades do componente.
37
40
  * @returns {{
38
41
  * classes: classes,
39
42
  * getFieldClass: getFieldClass
40
43
  * }}
41
44
  */
42
- export default function ({ props = {} }) {
45
+ export default function ({ props = {}, isGrid = false }) {
46
+ const screen = useScreen()
47
+
48
+ /**
49
+ * Se a propriedade gutter não for passada, será calculada automaticamente.
50
+ * se for usado no grid e for inline, o gutter será menor.
51
+ */
52
+ const defaultGutter = computed(() => {
53
+ if (props.gutter !== undefined) return props.gutter
54
+
55
+ return isGrid && (props.useInline && !screen.isSmall) ? Spacing.Sm : Spacing.Md
56
+ })
57
+
43
58
  /**
44
59
  * @type {{ value: string[] | string }}
45
60
  */
46
61
  const classes = computed(() => {
47
62
  const classesList = ['row']
48
63
 
49
- if (props.gutter) {
50
- classesList.push(`q-col-gutter-${props.gutter}`)
64
+ if (defaultGutter.value) {
65
+ classesList.push(`q-col-gutter-${defaultGutter.value}`)
51
66
  }
52
67
 
53
68
  return classesList
@@ -0,0 +1,106 @@
1
+ import { computed, ref } from 'vue'
2
+ import { LocalStorage, is } from 'quasar'
3
+
4
+ const filterQuery = ref({})
5
+
6
+ const defaultFiltersHooks = {
7
+ defaultFiltersChange: []
8
+ }
9
+
10
+ /**
11
+ * Define os filtros padrão antes de entrar na rota.
12
+ *
13
+ * Prioridade de aplicação dos filtros:
14
+ * 1 - Se o filtro estiver salvo no estado global, então utiliza ele.
15
+ * 2 - Se o filtro já estiver na query, então utiliza ele.
16
+ * 3 - Se o filtro já estiver salvo no LocalStorage, então utiliza ele.
17
+ *
18
+ * @param {Object} to - Rota de destino.
19
+ * @param {Object} _from - Rota de origem.
20
+ * @param {Function} next - Função de redirecionamento.
21
+ * @param {Array} queryList='company' - Lista de filtros a serem aplicados.
22
+ */
23
+ export function setDefaultFiltersBeforeEnter (to, _from, next, queryList = ['company']) {
24
+ const { getDefaultFiltersFromStorage, setFilterQuery } = useDefaultFilters()
25
+
26
+ const { query } = to
27
+ const newQuery = { ...query }
28
+
29
+ // recupera os filtros padrão do LocalStorage
30
+ const defaultFiltersFromStorage = getDefaultFiltersFromStorage()
31
+
32
+ queryList.forEach(name => {
33
+ // 1. se o filtro já estiver salvo no estado, então utiliza ele
34
+ if (filterQuery.value[name]) {
35
+ newQuery[name] = filterQuery.value[name]
36
+ return
37
+ }
38
+
39
+ // 2. se o filtro já estiver na query, então utiliza ele
40
+ if (query[name]) {
41
+ setFilterQuery(query[name], name)
42
+
43
+ return
44
+ }
45
+
46
+ const storedFilter = defaultFiltersFromStorage[name]
47
+
48
+ // 3. se o filtro já estiver salvo no LocalStorage, então utiliza ele
49
+ if (storedFilter) {
50
+ setFilterQuery(storedFilter, name)
51
+ newQuery[name] = storedFilter
52
+ }
53
+ })
54
+
55
+ /**
56
+ * Verifica se houve mudanças na query antes de redirecionar, sem essa validação
57
+ * o redirecionamento ocorre mesmo que a query seja a mesma, gerando loop infinito.
58
+ */
59
+ if (!is.deepEqual(newQuery, query)) return next({ ...to, query: newQuery, replace: true })
60
+
61
+ next()
62
+ }
63
+
64
+ /**
65
+ * Este composable recupera os filtros default salvos no LocalStorage na chave 'defaultFilters'.
66
+ */
67
+ export default function useDefaultFilters () {
68
+ const hasFilterQuery = computed(() => !!Object.keys(filterQuery.value).length)
69
+
70
+ function setFilterQuery (query, name = 'company') {
71
+ filterQuery.value[name] = query
72
+ }
73
+
74
+ function getDefaultFiltersFromStorage () {
75
+ const defaultFiltersFromStorage = LocalStorage.getItem('defaultFilters') || {}
76
+
77
+ return defaultFiltersFromStorage
78
+ }
79
+
80
+ function triggerDefaultFiltersChange (newFilters, oldFilters) {
81
+ // necessário verificar se houve mudanças antes de disparar o evento para não duplicar.
82
+ if (is.deepEqual(newFilters, oldFilters)) return
83
+
84
+ defaultFiltersHooks.defaultFiltersChange.forEach(hook => hook(newFilters, oldFilters))
85
+ }
86
+
87
+ function onDefaultFiltersChange (callback) {
88
+ defaultFiltersHooks.defaultFiltersChange.push(callback)
89
+ }
90
+
91
+ function removeOnDefaultFiltersChange (callback) {
92
+ const index = defaultFiltersHooks.defaultFiltersChange.indexOf(callback)
93
+
94
+ if (~index) defaultFiltersHooks.defaultFiltersChange.splice(index, 1)
95
+ }
96
+
97
+ return {
98
+ filterQuery,
99
+ hasFilterQuery,
100
+ getDefaultFiltersFromStorage,
101
+ onDefaultFiltersChange,
102
+ removeOnDefaultFiltersChange,
103
+ setFilterQuery,
104
+ triggerDefaultFiltersChange
105
+ }
106
+ }
@@ -4,6 +4,8 @@ import hasParentByClassName from '../helpers/private/has-parent-by-class-name'
4
4
  import { Notify } from 'quasar'
5
5
  import { ref } from 'vue'
6
6
 
7
+ import naveNotificationSound from '../assets/sounds/nave-notification.mp3'
8
+
7
9
  const callbackFunctions = {
8
10
  onNotificationReceived: []
9
11
  }
@@ -63,6 +65,8 @@ export default function () {
63
65
  timeout: 30000
64
66
  })
65
67
 
68
+ sendNotificationSound()
69
+
66
70
  /**
67
71
  * Função que é chamada quando o usuário clica na notificação, se a notificação
68
72
  * tem link, então ele vai ser redirecionado para o link em uma nova aba, caso
@@ -96,6 +100,16 @@ export default function () {
96
100
  </div>
97
101
  `)
98
102
  }
103
+
104
+ /**
105
+ * Função que toca o som de notificação.
106
+ */
107
+ function sendNotificationSound () {
108
+ const audio = new Audio(naveNotificationSound)
109
+
110
+ // o áudio agora é reproduzível; reproduza-o se as permissões permitirem
111
+ audio.addEventListener('canplaythrough', audio.play)
112
+ }
99
113
  }
100
114
 
101
115
  return {
@@ -19,7 +19,7 @@ export default function () {
19
19
  }
20
20
 
21
21
  function findOne (key, filter) {
22
- return cachedFilters[key][filter]
22
+ return cachedFilters[key]?.[filter]
23
23
  }
24
24
 
25
25
  function findAll (key) {
@@ -7,10 +7,11 @@
7
7
  * onMoveFn: function({ element: HTMLElement, event: MouseEvent | TouchEvent }),
8
8
  * onScrollFn: function({ element: HTMLElement, event: Event })
9
9
  * }} options
10
+ * @param {String} cancelMouseDownTarget
10
11
  *
11
12
  * @returns {{ element: HTMLElement, destroyEvents: function }}
12
13
  */
13
- export default function (element, options = {}) {
14
+ export default function (element, options = {}, cancelMouseDownTarget) {
14
15
  let isDown = false
15
16
  let startX
16
17
  let scrollLeft
@@ -46,6 +47,13 @@ export default function (element, options = {}) {
46
47
  }
47
48
 
48
49
  function onMouseEnter (event) {
50
+ /**
51
+ * closest busca ancestral mais próximo de um elemento, ou seja, verifica se no event que recebo, tenho a classe no qual nao se deve aplicar o grab.
52
+ */
53
+ const targetElement = cancelMouseDownTarget ? event.target.closest(`.${cancelMouseDownTarget}`) : null
54
+
55
+ if (!!cancelMouseDownTarget && !!targetElement) return null
56
+
49
57
  onEnter()
50
58
 
51
59
  startX = event.pageX - element.offsetLeft
@@ -0,0 +1,29 @@
1
+ export const baseProps = {
2
+ color: {
3
+ type: String,
4
+ default: 'light-blue-2'
5
+ },
6
+
7
+ label: {
8
+ type: String,
9
+ default: ''
10
+ },
11
+
12
+ multiLine: {
13
+ type: Boolean
14
+ },
15
+
16
+ textColor: {
17
+ type: String,
18
+ default: 'black'
19
+ },
20
+
21
+ removable: {
22
+ type: Boolean
23
+ },
24
+
25
+ tabindex: {
26
+ type: [String, Number],
27
+ default: undefined
28
+ }
29
+ }
package/src/vue-plugin.js CHANGED
@@ -14,6 +14,7 @@ import QasBtnDropdown from './components/btn-dropdown/QasBtnDropdown.vue'
14
14
  import QasCard from './components/card/QasCard.vue'
15
15
  import QasCardImage from './components/card-image/QasCardImage.vue'
16
16
  import QasCheckbox from './components/checkbox/QasCheckbox.vue'
17
+ import QasSelectFilter from './components/select-filter/QasSelectFilter.vue'
17
18
  import QasCopy from './components/copy/QasCopy.vue'
18
19
  import QasDate from './components/date/QasDate.vue'
19
20
  import QasDateTimeInput from './components/date-time-input/QasDateTimeInput.vue'
@@ -112,6 +113,7 @@ async function install (app) {
112
113
  app.component('QasCard', QasCard)
113
114
  app.component('QasCardImage', QasCardImage)
114
115
  app.component('QasCheckbox', QasCheckbox)
116
+ app.component('QasSelectFilter', QasSelectFilter)
115
117
  app.component('QasCopy', QasCopy)
116
118
  app.component('QasDate', QasDate)
117
119
  app.component('QasDateTimeInput', QasDateTimeInput)
@@ -213,6 +215,7 @@ export {
213
215
  QasCard,
214
216
  QasCheckbox,
215
217
  QasCopy,
218
+ QasSelectFilter,
216
219
  QasDate,
217
220
  QasDateTimeInput,
218
221
  QasDebugger,