@bildvitta/quasar-ui-asteroid 3.17.0-beta.2 → 3.17.0-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/assets/sounds/nave-notification.mp3 +0 -0
- package/src/components/actions/QasActions.vue +1 -1
- package/src/components/app-menu/QasAppMenu.vue +6 -1
- package/src/components/avatar/QasAvatar.vue +7 -8
- package/src/components/board-generator/QasBoardGenerator.vue +407 -40
- package/src/components/board-generator/QasBoardGenerator.yml +53 -12
- package/src/components/btn-dropdown/QasBtnDropdown.vue +14 -1
- package/src/components/card/QasCard.vue +13 -4
- package/src/components/chart-view/QasChartView.vue +44 -20
- package/src/components/chart-view/QasChartView.yml +10 -0
- package/src/components/checkbox/QasCheckbox.vue +30 -9
- package/src/components/checkbox/QasCheckbox.yml +5 -0
- package/src/components/copy/QasCopy.vue +12 -2
- package/src/components/copy/QasCopy.yml +8 -0
- package/src/components/date-time-input/QasDateTimeInput.vue +1 -1
- package/src/components/dialog/QasDialog.vue +3 -3
- package/src/components/expansion-item/QasExpansionItem.vue +120 -34
- package/src/components/expansion-item/QasExpansionItem.yml +38 -5
- package/src/components/filters/QasFilters.vue +1 -1
- package/src/components/filters/private/PvFiltersButton.vue +1 -1
- package/src/components/form-generator/QasFormGenerator.vue +39 -27
- package/src/components/form-generator/QasFormGenerator.yml +3 -0
- package/src/components/grabbable/QasGrabbable.vue +14 -6
- package/src/components/grabbable/QasGrabbable.yml +4 -0
- package/src/components/grid-generator/QasGridGenerator.vue +67 -34
- package/src/components/grid-generator/QasGridGenerator.yml +15 -0
- package/src/components/header/QasHeader.vue +58 -12
- package/src/components/header/QasHeader.yml +5 -0
- package/src/components/infinite-scroll/QasInfiniteScroll.vue +16 -17
- package/src/components/infinite-scroll/QasInfiniteScroll.yml +7 -0
- package/src/components/list-items/QasListItems.vue +28 -4
- package/src/components/list-items/QasListItems.yml +10 -0
- package/src/components/list-view/QasListView.vue +17 -5
- package/src/components/list-view/QasListView.yml +9 -0
- package/src/components/nested-fields/QasNestedFields.vue +91 -36
- package/src/components/nested-fields/QasNestedFields.yml +23 -0
- package/src/components/radio/QasRadio.vue +24 -5
- package/src/components/radio/QasRadio.yml +6 -0
- package/src/components/select/QasSelect.vue +129 -5
- package/src/components/select/QasSelect.yml +11 -0
- package/src/components/stepper-form-view/QasStepperFormView.yml +1 -1
- package/src/components/table-generator/QasTableGenerator.vue +10 -1
- package/src/components/text-truncate/QasTextTruncate.vue +11 -4
- package/src/components/text-truncate/QasTextTruncate.yml +4 -0
- package/src/composables/private/use-generator.js +3 -9
- package/src/composables/use-notifications.js +14 -0
- package/src/css/components/field.scss +13 -6
- package/src/css/components/item.scss +5 -1
- package/src/enums/Spacing.js +33 -0
- package/src/helpers/set-scroll-on-grab.js +9 -1
|
@@ -2,24 +2,20 @@
|
|
|
2
2
|
<div :id="fieldName" class="qas-nested-fields" :data-cy="`nested-fields-${fieldName}`">
|
|
3
3
|
<component :is="containerComponent">
|
|
4
4
|
<div v-if="useSingleLabel" class="text-left">
|
|
5
|
-
<qas-label :label="fieldLabel"
|
|
5
|
+
<qas-label :label="fieldLabel" />
|
|
6
6
|
</div>
|
|
7
7
|
|
|
8
8
|
<div ref="inputContent">
|
|
9
9
|
<component :is="componentTag" v-bind="componentProps">
|
|
10
10
|
<template v-for="(row, index) in nested" :key="`row-${index}`">
|
|
11
11
|
<div v-if="!row[destroyKey]" :id="`row-${index}`" class="full-width qas-nested-fields__field-item" data-cy="nested-fields-item">
|
|
12
|
-
<header v-if="hasHeader" class="flex
|
|
13
|
-
<qas-label v-if="!useSingleLabel" :label="getRowLabel(index)" margin="none" typography="h5" />
|
|
14
|
-
|
|
15
|
-
<qas-actions-menu v-if="hasBlockActions(row)" v-bind="getActionsMenuProps(index, row)" :use-label="false" />
|
|
16
|
-
</header>
|
|
12
|
+
<qas-header v-if="hasHeader({ row })" class="flex" v-bind="getHeaderProps({ index, row })" />
|
|
17
13
|
|
|
18
14
|
<slot :errors="transformedErrors" :fields="getFields(index, row)" :index="index" :model="nested[index]" name="before-fields" :update-value="updateValuesFromInput" />
|
|
19
15
|
|
|
20
|
-
<div ref="formGenerator" class="
|
|
16
|
+
<div ref="formGenerator" :class="formGeneratorParentClasses">
|
|
21
17
|
<slot :errors="transformedErrors" :fields="getFields(index, row)" :index="index" name="fields" :update-value="updateValuesFromInput">
|
|
22
|
-
<qas-form-generator v-model="nested[index]" class="col" :columns="formColumns" :disable="isDisabledRow(row)" :errors="transformedErrors[index]" :fields="getFields(index, row)" :fields-props="getFieldsProps(index, row)" :gutter="formGutter" @update:model-value="updateValuesFromInput($event, index)">
|
|
18
|
+
<qas-form-generator v-model="nested[index]" class="col" :columns="formColumns" :common-columns="formCommonColumns" :disable="isDisabledRow(row)" :errors="transformedErrors[index]" :fields="getFields(index, row)" :fields-props="getFieldsProps(index, row)" :gutter="formGutter" @update:model-value="updateValuesFromInput($event, index)">
|
|
23
19
|
<template v-for="(slot, key) in $slots" #[key]="scope">
|
|
24
20
|
<slot v-bind="scope" :disabled="isDisabledRow(row)" :errors="transformedErrors" :index="index" :name="key" />
|
|
25
21
|
</template>
|
|
@@ -27,7 +23,7 @@
|
|
|
27
23
|
</slot>
|
|
28
24
|
|
|
29
25
|
<div v-if="hasInlineActions(row)" class="flex items-center qas-nested-fields__actions">
|
|
30
|
-
<qas-actions-menu v-bind="
|
|
26
|
+
<qas-actions-menu v-bind="getInlineActionsMenuProps(index, row)" :use-label="false" />
|
|
31
27
|
</div>
|
|
32
28
|
</div>
|
|
33
29
|
|
|
@@ -36,7 +32,7 @@
|
|
|
36
32
|
</template>
|
|
37
33
|
</component>
|
|
38
34
|
|
|
39
|
-
<div v-if="useAdd">
|
|
35
|
+
<div v-if="useAdd" :class="addButtonClass">
|
|
40
36
|
<slot :add="add" name="add-input">
|
|
41
37
|
<div v-if="showAddFirstInputButton" class="text-left">
|
|
42
38
|
<qas-btn class="q-px-sm" color="primary" data-cy="nested-fields-add-btn" :label="addFirstInputLabel" variant="tertiary" @click="add()" />
|
|
@@ -70,7 +66,7 @@ import QasInput from '../input/QasInput.vue'
|
|
|
70
66
|
import QasLabel from '../label/QasLabel.vue'
|
|
71
67
|
|
|
72
68
|
import { constructObject } from '../../helpers'
|
|
73
|
-
import { Spacing } from '../../enums/Spacing'
|
|
69
|
+
import { Spacing, SpacingWithNumber } from '../../enums/Spacing'
|
|
74
70
|
|
|
75
71
|
import { TransitionGroup } from 'vue'
|
|
76
72
|
import debug from 'debug'
|
|
@@ -167,12 +163,22 @@ export default {
|
|
|
167
163
|
default: () => []
|
|
168
164
|
},
|
|
169
165
|
|
|
166
|
+
formCommonColumns: {
|
|
167
|
+
type: [Object, String],
|
|
168
|
+
default: () => ({})
|
|
169
|
+
},
|
|
170
|
+
|
|
170
171
|
formGutter: {
|
|
171
|
-
default: Spacing.
|
|
172
|
+
default: Spacing.Md,
|
|
172
173
|
type: [String, Boolean],
|
|
173
174
|
validator: value => typeof value === 'boolean' || Object.values(Spacing).includes(value)
|
|
174
175
|
},
|
|
175
176
|
|
|
177
|
+
headerProps: {
|
|
178
|
+
type: Function,
|
|
179
|
+
default: () => {}
|
|
180
|
+
},
|
|
181
|
+
|
|
176
182
|
identifierItemKey: {
|
|
177
183
|
type: String,
|
|
178
184
|
default: 'uuid'
|
|
@@ -296,15 +302,14 @@ export default {
|
|
|
296
302
|
return this.useFirstInputButton && !this.nested.length
|
|
297
303
|
},
|
|
298
304
|
|
|
299
|
-
|
|
300
|
-
return (this.useSingleLabel && !this.useInlineActions) || !this.useSingleLabel
|
|
301
|
-
},
|
|
302
|
-
|
|
303
|
-
headerClasses () {
|
|
305
|
+
addButtonClass () {
|
|
304
306
|
return {
|
|
305
|
-
'
|
|
306
|
-
'justify-between': !this.useSingleLabel
|
|
307
|
+
'q-mt-md': !!this.nested.length
|
|
307
308
|
}
|
|
309
|
+
},
|
|
310
|
+
|
|
311
|
+
formGeneratorParentClasses () {
|
|
312
|
+
return this.useInlineActions ? 'col-12 justify-between q-col-gutter-x-md row' : 'full-width'
|
|
308
313
|
}
|
|
309
314
|
},
|
|
310
315
|
|
|
@@ -333,8 +338,8 @@ export default {
|
|
|
333
338
|
},
|
|
334
339
|
|
|
335
340
|
methods: {
|
|
336
|
-
|
|
337
|
-
if (typeof this.actionsMenuProps === 'function') {
|
|
341
|
+
getInlineActionsMenuProps (index, row) {
|
|
342
|
+
if (typeof this.actionsMenuProps === 'function' && this.useInlineActions) {
|
|
338
343
|
return this.actionsMenuProps({
|
|
339
344
|
index,
|
|
340
345
|
row,
|
|
@@ -344,7 +349,7 @@ export default {
|
|
|
344
349
|
|
|
345
350
|
return {
|
|
346
351
|
...this.actionsMenuProps,
|
|
347
|
-
list: this.getActionsMenuList(index, row)
|
|
352
|
+
list: this.getActionsMenuList(index, row, this.actionsMenuProps?.list)
|
|
348
353
|
}
|
|
349
354
|
},
|
|
350
355
|
|
|
@@ -368,11 +373,11 @@ export default {
|
|
|
368
373
|
return list
|
|
369
374
|
},
|
|
370
375
|
|
|
371
|
-
getActionsMenuList (index, row) {
|
|
376
|
+
getActionsMenuList (index, row, defaultList = {}) {
|
|
372
377
|
const list = this.getDefaultActionsMenuList(index, row)
|
|
373
378
|
|
|
374
|
-
for (const key in
|
|
375
|
-
const { handler, ...content } =
|
|
379
|
+
for (const key in defaultList) {
|
|
380
|
+
const { handler, ...content } = defaultList[key] || {}
|
|
376
381
|
|
|
377
382
|
list[key] = {
|
|
378
383
|
handler: payload => handler?.({ payload, row, index }),
|
|
@@ -456,14 +461,32 @@ export default {
|
|
|
456
461
|
|
|
457
462
|
setScroll () {
|
|
458
463
|
const elements = this.$refs.inputContent.children
|
|
464
|
+
|
|
465
|
+
// elemento de ação, e não das linhas (rows) de inputs
|
|
459
466
|
const element = elements[elements.length - 1]
|
|
467
|
+
|
|
468
|
+
// ultima linha (rows) de inputs
|
|
469
|
+
const rowsElement = elements[0]?.children
|
|
470
|
+
|
|
471
|
+
// pegamos a posição do elemento de ação
|
|
460
472
|
const { top } = element.getBoundingClientRect()
|
|
461
|
-
const pageOffset = window.pageYOffset
|
|
462
473
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
474
|
+
// pegamos a altura da ultima linha (rows) de inputs
|
|
475
|
+
const lastRowHeight = rowsElement?.[rowsElement.length - 1]?.clientHeight
|
|
476
|
+
|
|
477
|
+
// pegamos a posição da página
|
|
478
|
+
const pageOffset = window.scrollY
|
|
479
|
+
|
|
480
|
+
// 56 é a altura do header no mobile
|
|
481
|
+
const safeScrollSize = this.$qas.screen.isSmall ? 56 + SpacingWithNumber.Lg : SpacingWithNumber.Lg
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* É necessário descontar a altura da última linha (rows) de inputs para que o scroll
|
|
485
|
+
* fique no final da última linha (rows) de inputs.
|
|
486
|
+
*/
|
|
487
|
+
const scrollTop = pageOffset + top - (lastRowHeight + safeScrollSize)
|
|
488
|
+
|
|
489
|
+
window.scrollTo({ behavior: 'smooth', top: scrollTop })
|
|
467
490
|
},
|
|
468
491
|
|
|
469
492
|
async setFocus () {
|
|
@@ -507,6 +530,41 @@ export default {
|
|
|
507
530
|
|
|
508
531
|
hasInlineActions (row) {
|
|
509
532
|
return this.useInlineActions && !this.isDisabledRow(row)
|
|
533
|
+
},
|
|
534
|
+
|
|
535
|
+
hasHeader ({ row }) {
|
|
536
|
+
return this.hasBlockActions(row) || !this.useSingleLabel
|
|
537
|
+
},
|
|
538
|
+
|
|
539
|
+
getHeaderProps ({ index, row }) {
|
|
540
|
+
const hasLabel = !this.useSingleLabel
|
|
541
|
+
const hasActions = this.hasBlockActions(row)
|
|
542
|
+
|
|
543
|
+
const { labelProps, actionsMenuProps, ...payload } = this.headerProps?.({ index, row }) || {}
|
|
544
|
+
|
|
545
|
+
return {
|
|
546
|
+
...payload,
|
|
547
|
+
|
|
548
|
+
spacing: 'sm',
|
|
549
|
+
|
|
550
|
+
...(hasActions && {
|
|
551
|
+
actionsMenuProps: {
|
|
552
|
+
useLabel: false,
|
|
553
|
+
|
|
554
|
+
...actionsMenuProps,
|
|
555
|
+
|
|
556
|
+
list: this.getActionsMenuList(index, row, actionsMenuProps?.list)
|
|
557
|
+
}
|
|
558
|
+
}),
|
|
559
|
+
|
|
560
|
+
...(hasLabel && {
|
|
561
|
+
labelProps: {
|
|
562
|
+
typography: 'h5',
|
|
563
|
+
label: this.getRowLabel(index),
|
|
564
|
+
...labelProps
|
|
565
|
+
}
|
|
566
|
+
})
|
|
567
|
+
}
|
|
510
568
|
}
|
|
511
569
|
}
|
|
512
570
|
}
|
|
@@ -514,16 +572,13 @@ export default {
|
|
|
514
572
|
|
|
515
573
|
<style lang="scss">
|
|
516
574
|
.qas-nested-fields {
|
|
575
|
+
// mesmo tamanho do input
|
|
517
576
|
&__actions {
|
|
518
|
-
height:
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
&__field-item {
|
|
522
|
-
margin-bottom: var(--qas-spacing-md);
|
|
577
|
+
height: 40px;
|
|
523
578
|
}
|
|
524
579
|
|
|
525
580
|
&__field-item + &__field-item {
|
|
526
|
-
margin-top: var(--qas-spacing-
|
|
581
|
+
margin-top: var(--qas-spacing-lg);
|
|
527
582
|
}
|
|
528
583
|
}
|
|
529
584
|
</style>
|
|
@@ -74,12 +74,34 @@ props:
|
|
|
74
74
|
type: [Array, String, Object]
|
|
75
75
|
examples: ["[{ sm: 6, md: 12 }]", "{ name: { sm: 6, md: 12 } }", "12"]
|
|
76
76
|
|
|
77
|
+
form-common-columns:
|
|
78
|
+
desc: Colunas do grid comuns.
|
|
79
|
+
default: {}
|
|
80
|
+
type: [String, Object]
|
|
81
|
+
examples: ["{ col: 12, sm: 6}" , "12"]
|
|
82
|
+
|
|
77
83
|
form-gutter:
|
|
78
84
|
desc: Espaçamento entre colunas do formulário.
|
|
79
85
|
default: lg
|
|
80
86
|
type: [String, Boolean]
|
|
81
87
|
examples: [xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, false]
|
|
82
88
|
|
|
89
|
+
header-props:
|
|
90
|
+
desc: Propriedades do header do nested por linha por callback.
|
|
91
|
+
default: () => {}
|
|
92
|
+
type: Function
|
|
93
|
+
params:
|
|
94
|
+
context:
|
|
95
|
+
desc: Payload da linha (row) -> index/row.
|
|
96
|
+
type: Object
|
|
97
|
+
params:
|
|
98
|
+
index:
|
|
99
|
+
desc: Índice da linha.
|
|
100
|
+
type: Number
|
|
101
|
+
row:
|
|
102
|
+
desc: Valores contendo na linha atual.
|
|
103
|
+
type: Object
|
|
104
|
+
|
|
83
105
|
identifier-item-key:
|
|
84
106
|
desc: Define um identificador para o item. O identificador será utilizado para validar exclusão do item, por exemplo.
|
|
85
107
|
default: uuid
|
|
@@ -251,6 +273,7 @@ slots:
|
|
|
251
273
|
type: Function
|
|
252
274
|
examples: ["updateValue({ name: 'novo valor' }, 2)"]
|
|
253
275
|
|
|
276
|
+
|
|
254
277
|
events:
|
|
255
278
|
'@update:model-value -> function (value)':
|
|
256
279
|
desc: Dispara toda vez que o model é atualizado, também utilizado para v-model.
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<div>
|
|
3
|
+
<div v-if="canShowOptionGroupLabel" class="q-mb-sm text-body1">
|
|
4
|
+
{{ props.label }}
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<component :is="component.is" v-bind="component.props" />
|
|
8
|
+
</div>
|
|
3
9
|
</template>
|
|
4
10
|
|
|
5
11
|
<script setup>
|
|
@@ -10,8 +16,20 @@ defineOptions({
|
|
|
10
16
|
inheritAttrs: false
|
|
11
17
|
})
|
|
12
18
|
|
|
19
|
+
const props = defineProps({
|
|
20
|
+
label: {
|
|
21
|
+
default: '',
|
|
22
|
+
type: String
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
|
|
13
26
|
const attrs = useAttrs()
|
|
14
27
|
|
|
28
|
+
const isOptionGroup = computed(() => !!attrs.options?.length)
|
|
29
|
+
|
|
30
|
+
// Só mostra a label caso for q-option-group e tenha label vindo nas props
|
|
31
|
+
const canShowOptionGroupLabel = computed(() => isOptionGroup.value && !!props.label)
|
|
32
|
+
|
|
15
33
|
/**
|
|
16
34
|
* - quando é um grupo de opções, o componente é 'QOptionGroup', caso contrário,
|
|
17
35
|
* é 'QRadio'.
|
|
@@ -19,16 +37,17 @@ const attrs = useAttrs()
|
|
|
19
37
|
* - todos os casos é usado o dense.
|
|
20
38
|
*/
|
|
21
39
|
const component = computed(() => {
|
|
22
|
-
const isOptionGroup = !!attrs.options?.length
|
|
23
|
-
|
|
24
40
|
const { inline = true, ...payloadProps } = attrs
|
|
25
41
|
|
|
26
42
|
return {
|
|
27
|
-
is: isOptionGroup ? 'q-option-group' : 'q-radio',
|
|
43
|
+
is: isOptionGroup.value ? 'q-option-group' : 'q-radio',
|
|
44
|
+
|
|
28
45
|
props: {
|
|
29
46
|
...payloadProps,
|
|
30
47
|
|
|
31
|
-
|
|
48
|
+
label: props.label,
|
|
49
|
+
|
|
50
|
+
...(isOptionGroup.value && {
|
|
32
51
|
inline,
|
|
33
52
|
class: {
|
|
34
53
|
'q-gutter-x-md': inline,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<q-select v-model="model" v-bind="attributes" class="qas-select" :class="componentClasses" no-error-icon
|
|
3
|
-
<template v-if="
|
|
4
|
-
<q-icon name="
|
|
2
|
+
<q-select v-model="model" v-bind="attributes" class="qas-select" :class="componentClasses" no-error-icon>
|
|
3
|
+
<template v-if="hasIcon" #prepend>
|
|
4
|
+
<q-icon :name="defaultIcon" />
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<template #no-option>
|
|
@@ -30,6 +30,34 @@
|
|
|
30
30
|
</qas-badge>
|
|
31
31
|
</template>
|
|
32
32
|
|
|
33
|
+
<template v-if="useCustomOptions" #option="scope">
|
|
34
|
+
<q-item v-bind="scope.itemProps" class="qas-select__option">
|
|
35
|
+
<q-item-section>
|
|
36
|
+
<div class="items-center q-gutter-x-sm row">
|
|
37
|
+
<q-item-label>
|
|
38
|
+
{{ scope.opt.label }}
|
|
39
|
+
</q-item-label>
|
|
40
|
+
|
|
41
|
+
<div v-for="(badge, index) in getFilteredBadgeList(scope.opt)" :key="index">
|
|
42
|
+
<qas-badge v-if="hasBadge(badge)" v-bind="getBadgeProps(badge)" />
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div v-if="scope.opt.caption">
|
|
47
|
+
<div class="items-center q-col-gutter-x-sm row">
|
|
48
|
+
<q-item-label v-for="(caption, index) in getCaptionArray(scope.opt.caption)" :key="index" caption class="items-center q-mt-xs row">
|
|
49
|
+
<div>
|
|
50
|
+
{{ caption }}
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<q-separator v-if="hasSeparator({ caption: getCaptionArray(scope.opt.caption), index })" class="q-ml-sm" vertical />
|
|
54
|
+
</q-item-label>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</q-item-section>
|
|
58
|
+
</q-item>
|
|
59
|
+
</template>
|
|
60
|
+
|
|
33
61
|
<template v-for="(_, name) in $slots" #[name]="context">
|
|
34
62
|
<slot :name="name" v-bind="context || {}" />
|
|
35
63
|
</template>
|
|
@@ -49,12 +77,27 @@ export default {
|
|
|
49
77
|
|
|
50
78
|
mixins: [searchFilterMixin],
|
|
51
79
|
|
|
80
|
+
inject: {
|
|
81
|
+
isBox: { default: false },
|
|
82
|
+
isDialog: { default: false }
|
|
83
|
+
},
|
|
84
|
+
|
|
52
85
|
props: {
|
|
86
|
+
badgeProps: {
|
|
87
|
+
default: () => ({}),
|
|
88
|
+
type: Object
|
|
89
|
+
},
|
|
90
|
+
|
|
53
91
|
fuseOptions: {
|
|
54
92
|
default: () => ({}),
|
|
55
93
|
type: Object
|
|
56
94
|
},
|
|
57
95
|
|
|
96
|
+
icon: {
|
|
97
|
+
type: String,
|
|
98
|
+
default: ''
|
|
99
|
+
},
|
|
100
|
+
|
|
58
101
|
label: {
|
|
59
102
|
type: String,
|
|
60
103
|
default: ''
|
|
@@ -83,6 +126,10 @@ export default {
|
|
|
83
126
|
type: Boolean
|
|
84
127
|
},
|
|
85
128
|
|
|
129
|
+
useCustomOptions: {
|
|
130
|
+
type: Boolean
|
|
131
|
+
},
|
|
132
|
+
|
|
86
133
|
useFetchOptionsOnCreate: {
|
|
87
134
|
default: true,
|
|
88
135
|
type: Boolean
|
|
@@ -95,6 +142,10 @@ export default {
|
|
|
95
142
|
useSearch: {
|
|
96
143
|
type: Boolean,
|
|
97
144
|
default: undefined
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
useFilterMode: {
|
|
148
|
+
type: Boolean
|
|
98
149
|
}
|
|
99
150
|
},
|
|
100
151
|
|
|
@@ -113,7 +164,7 @@ export default {
|
|
|
113
164
|
clearable: this.isSearchable,
|
|
114
165
|
emitValue: true,
|
|
115
166
|
mapOptions: true,
|
|
116
|
-
outlined:
|
|
167
|
+
outlined: this.useFilterMode,
|
|
117
168
|
dense: true,
|
|
118
169
|
dropdownIcon: 'sym_r_expand_more',
|
|
119
170
|
clearIcon: 'sym_r_close',
|
|
@@ -151,6 +202,10 @@ export default {
|
|
|
151
202
|
return this.hasFuse || this.useLazyLoading
|
|
152
203
|
},
|
|
153
204
|
|
|
205
|
+
isBordered () {
|
|
206
|
+
return (this.isBox || this.isDialog) && this.useFilterMode
|
|
207
|
+
},
|
|
208
|
+
|
|
154
209
|
hasError () {
|
|
155
210
|
return this.mx_hasFetchError || this.$attrs.error
|
|
156
211
|
},
|
|
@@ -198,7 +253,13 @@ export default {
|
|
|
198
253
|
// redesign
|
|
199
254
|
componentClasses () {
|
|
200
255
|
return {
|
|
201
|
-
|
|
256
|
+
...(this.useFilterMode && {
|
|
257
|
+
'qas-select--filter rounded-borders': true,
|
|
258
|
+
'shadow-2': !this.isBordered,
|
|
259
|
+
bordered: this.isBordered
|
|
260
|
+
}),
|
|
261
|
+
|
|
262
|
+
'qas-select--has-icon': this.hasAppend || this.hasIcon,
|
|
202
263
|
'qas-select--closed': !this.isPopupContentOpen,
|
|
203
264
|
'qas-select--loading': this.hasLoading
|
|
204
265
|
}
|
|
@@ -214,6 +275,14 @@ export default {
|
|
|
214
275
|
|
|
215
276
|
hasAppend () {
|
|
216
277
|
return !!this.$slots.append
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
defaultIcon () {
|
|
281
|
+
return this.icon || 'sym_r_search'
|
|
282
|
+
},
|
|
283
|
+
|
|
284
|
+
hasIcon () {
|
|
285
|
+
return this.isSearchable || !!this.icon
|
|
217
286
|
}
|
|
218
287
|
},
|
|
219
288
|
|
|
@@ -328,6 +397,51 @@ export default {
|
|
|
328
397
|
: this.options[0]
|
|
329
398
|
|
|
330
399
|
this.$emit('update:modelValue', modelValue)
|
|
400
|
+
},
|
|
401
|
+
|
|
402
|
+
getFilteredBadgeList (payload = {}) {
|
|
403
|
+
const { label, value, disable, caption, ...rest } = payload
|
|
404
|
+
|
|
405
|
+
const badgeList = []
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Exemplo de estrutura percorrida:
|
|
409
|
+
*
|
|
410
|
+
* @example
|
|
411
|
+
* {
|
|
412
|
+
* isTester: true,
|
|
413
|
+
* isOwner: false
|
|
414
|
+
* }
|
|
415
|
+
*/
|
|
416
|
+
for (const [key, val] of Object.entries(rest)) {
|
|
417
|
+
if (key in this.badgeProps) {
|
|
418
|
+
badgeList.push({ [key]: val })
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return badgeList
|
|
423
|
+
},
|
|
424
|
+
|
|
425
|
+
getBadgeProps (badge) {
|
|
426
|
+
const model = Object.keys(badge)[0]
|
|
427
|
+
|
|
428
|
+
const isFunction = typeof this.badgeProps[model] === 'function'
|
|
429
|
+
|
|
430
|
+
return isFunction ? this.badgeProps[model](badge[model]).props : this.badgeProps[model]
|
|
431
|
+
},
|
|
432
|
+
|
|
433
|
+
hasBadge (badge) {
|
|
434
|
+
const model = Object.keys(badge)[0]
|
|
435
|
+
|
|
436
|
+
return badge[model] || this.badgeProps[model](badge[model]).show
|
|
437
|
+
},
|
|
438
|
+
|
|
439
|
+
getCaptionArray (caption) {
|
|
440
|
+
return Array.isArray(caption) ? caption : [caption]
|
|
441
|
+
},
|
|
442
|
+
|
|
443
|
+
hasSeparator ({ caption, index }) {
|
|
444
|
+
return index !== caption.length - 1
|
|
331
445
|
}
|
|
332
446
|
}
|
|
333
447
|
}
|
|
@@ -347,12 +461,22 @@ export default {
|
|
|
347
461
|
}
|
|
348
462
|
}
|
|
349
463
|
|
|
464
|
+
&--filter {
|
|
465
|
+
.q-field__control:before {
|
|
466
|
+
border: 0;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
350
470
|
&__menu {
|
|
351
471
|
.q-item {
|
|
352
472
|
font-weight: 400 !important;
|
|
353
473
|
}
|
|
354
474
|
}
|
|
355
475
|
|
|
476
|
+
&__option:hover .q-item__label--caption {
|
|
477
|
+
color: var(--q-primary);
|
|
478
|
+
}
|
|
479
|
+
|
|
356
480
|
&--closed {
|
|
357
481
|
.q-field__native span {
|
|
358
482
|
white-space: nowrap;
|
|
@@ -7,6 +7,12 @@ meta:
|
|
|
7
7
|
desc: Componente para select que implementa o "QSelect" repassando propriedades, slots e eventos.
|
|
8
8
|
|
|
9
9
|
props:
|
|
10
|
+
badge-list:
|
|
11
|
+
desc: Configuração das badges no qual cada key é um callback com o valor booleano retornado pelo back.
|
|
12
|
+
default: {}
|
|
13
|
+
examples: ["{ isTester: () => { return { color: 'grey-8', label: 'Tester', textColor: 'white' }} }"]
|
|
14
|
+
type: Object
|
|
15
|
+
|
|
10
16
|
entity:
|
|
11
17
|
desc: Entidade enviada para a action "fetchFieldOptions" (usar somente quando "useLazyLoading" estiver habilitada).
|
|
12
18
|
default: ''
|
|
@@ -29,6 +35,11 @@ props:
|
|
|
29
35
|
keys: [label, value]
|
|
30
36
|
threshold: 0.4
|
|
31
37
|
|
|
38
|
+
icon:
|
|
39
|
+
desc: Ícone da esquerda.
|
|
40
|
+
type: String
|
|
41
|
+
default: ''
|
|
42
|
+
|
|
32
43
|
label:
|
|
33
44
|
desc: Label do componente.
|
|
34
45
|
type: String
|
|
@@ -17,7 +17,7 @@ props:
|
|
|
17
17
|
desc: Propriedades que serão repassadas para o QasStepper.
|
|
18
18
|
type: Object
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
provide:
|
|
21
21
|
stepper-model:
|
|
22
22
|
desc: Model do stepper caso precise recuperar o step atual para alguma lógica. Possui reatividade, portanto para acessar é necessário do ".value"
|
|
23
23
|
type: Number
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<qas-header v-if="hasHeaderProps" v-bind="headerProps" />
|
|
5
5
|
</slot>
|
|
6
6
|
|
|
7
|
-
<q-table ref="table" class="bg-white qas-table-generator text-grey-8" v-bind="attributes">
|
|
7
|
+
<q-table v-show="hasResults" ref="table" class="bg-white qas-table-generator text-grey-8" v-bind="attributes">
|
|
8
8
|
<template v-for="(_, name) in slots" #[name]="context">
|
|
9
9
|
<slot :name="name" v-bind="context" />
|
|
10
10
|
</template>
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
</q-td>
|
|
20
20
|
</template>
|
|
21
21
|
</q-table>
|
|
22
|
+
|
|
23
|
+
<qas-empty-result-text v-if="!hasResults" />
|
|
22
24
|
</component>
|
|
23
25
|
</template>
|
|
24
26
|
|
|
@@ -130,8 +132,15 @@ export default {
|
|
|
130
132
|
return !!this.$slots['body-cell']
|
|
131
133
|
},
|
|
132
134
|
|
|
135
|
+
hasResults () {
|
|
136
|
+
return !!this.resultsByFields.length
|
|
137
|
+
},
|
|
138
|
+
|
|
133
139
|
attributes () {
|
|
134
140
|
const attributes = {
|
|
141
|
+
tableClass: {
|
|
142
|
+
'overflow-hidden-y': !this.useStickyHeader
|
|
143
|
+
},
|
|
135
144
|
class: this.tableClass,
|
|
136
145
|
columns: this.columnsByFields,
|
|
137
146
|
flat: true,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div ref="parent" :class="classes">
|
|
3
3
|
<div class="no-wrap row text-no-wrap">
|
|
4
4
|
<div ref="truncate" class="ellipsis">
|
|
5
|
-
<slot>{{
|
|
5
|
+
<slot>{{ formattedText }}</slot>
|
|
6
6
|
</div>
|
|
7
7
|
|
|
8
8
|
<qas-btn v-if="hasButton" class="q-ml-sm" :label="buttonLabel" @click.stop.prevent="toggle" />
|
|
@@ -87,6 +87,11 @@ const props = defineProps({
|
|
|
87
87
|
|
|
88
88
|
useObjectList: {
|
|
89
89
|
type: Boolean
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
emptyText: {
|
|
93
|
+
type: String,
|
|
94
|
+
default: '-'
|
|
90
95
|
}
|
|
91
96
|
})
|
|
92
97
|
|
|
@@ -119,6 +124,8 @@ useMutationObserver({ truncate, callbackFn: truncateText })
|
|
|
119
124
|
|
|
120
125
|
const classes = computed(() => [`text-${props.color}`, `text-${props.typography}`])
|
|
121
126
|
|
|
127
|
+
const formattedText = computed(() => props.list.length || props.text ? displayText.value : props.emptyText)
|
|
128
|
+
|
|
122
129
|
// composable functions
|
|
123
130
|
function useDialog ({ props, textContent }) {
|
|
124
131
|
// reactive vars
|
|
@@ -141,7 +148,7 @@ function useDialog ({ props, textContent }) {
|
|
|
141
148
|
}
|
|
142
149
|
})
|
|
143
150
|
|
|
144
|
-
//
|
|
151
|
+
// functions
|
|
145
152
|
function toggle () {
|
|
146
153
|
show.value = !show.value
|
|
147
154
|
}
|
|
@@ -163,7 +170,7 @@ function useMutationObserver ({ truncate, callbackFn = () => {} }) {
|
|
|
163
170
|
onMounted(() => observeContentChange())
|
|
164
171
|
onUnmounted(() => observer.value.disconnect())
|
|
165
172
|
|
|
166
|
-
//
|
|
173
|
+
// functions
|
|
167
174
|
function observeContentChange () {
|
|
168
175
|
const config = { childList: true, subtree: true, characterData: true }
|
|
169
176
|
|
|
@@ -190,7 +197,7 @@ function useTruncate ({ parent, props }) {
|
|
|
190
197
|
// computed
|
|
191
198
|
const isTruncated = computed(() => textWidth.value > maxPossibleWidth.value)
|
|
192
199
|
|
|
193
|
-
//
|
|
200
|
+
// functions
|
|
194
201
|
function truncateText () {
|
|
195
202
|
parent.value.style.maxWidth = '100%'
|
|
196
203
|
textWidth.value = truncate.value.clientWidth
|