@bildvitta/quasar-ui-asteroid 3.11.0-beta.2 → 3.11.0-beta.4
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 +1 -1
- package/src/components/chart-view/QasChartView.vue +383 -0
- package/src/components/chart-view/QasChartView.yml +87 -0
- package/src/components/chart-view/config/charts/bar.js +45 -0
- package/src/components/chart-view/config/charts/doughnut.js +43 -0
- package/src/components/chart-view/config/charts/index.js +9 -0
- package/src/components/chart-view/config/charts/line.js +57 -0
- package/src/components/chart-view/config/defaults/colors.js +19 -0
- package/src/components/chart-view/config/defaults/font.js +5 -0
- package/src/components/chart-view/config/defaults/index.js +2 -0
- package/src/components/chart-view/config/index.js +3 -0
- package/src/components/chart-view/config/plugins/index.js +3 -0
- package/src/components/chart-view/config/plugins/legend.js +9 -0
- package/src/components/chart-view/config/plugins/tooltip.js +15 -0
- package/src/components/chart-view/config/plugins/zoom.js +31 -0
- package/src/components/header-actions/QasHeaderActions.vue +17 -1
- package/src/components/header-actions/QasHeaderActions.yml +7 -1
- package/src/components/label/QasLabel.vue +5 -4
- package/src/components/search-box/QasSearchBox.vue +48 -17
- package/src/components/search-box/QasSearchBox.yml +8 -0
- package/src/components/search-input/QasSearchInput.vue +1 -24
- package/src/components/select-list/QasSelectList.vue +76 -48
- package/src/components/select-list/QasSelectList.yml +8 -39
- package/src/components/select-list/private/PvSelectListCheckbox.vue +31 -0
- package/src/css/components/field.scss +1 -1
- package/src/css/components/item.scss +4 -0
- package/src/helpers/rules.js +2 -2
- package/src/mixins/search-filter.js +1 -1
- package/src/vue-plugin/components/chart-view-component.js +16 -0
- package/src/vue-plugin/third-party-components-initializer.js +2 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const zoomPluginConfig = {
|
|
2
|
+
limits: {
|
|
3
|
+
x: {
|
|
4
|
+
max: 'original',
|
|
5
|
+
min: 'original'
|
|
6
|
+
},
|
|
7
|
+
|
|
8
|
+
y: {
|
|
9
|
+
max: 'original',
|
|
10
|
+
min: 'original'
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
pan: {
|
|
15
|
+
enabled: true,
|
|
16
|
+
modifierKey: 'ctrl'
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
zoom: {
|
|
20
|
+
mode: 'xy',
|
|
21
|
+
|
|
22
|
+
pinch: {
|
|
23
|
+
enabled: true
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
wheel: {
|
|
27
|
+
enabled: true,
|
|
28
|
+
modifierKey: 'ctrl'
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="
|
|
2
|
+
<div class="justify-between no-wrap q-col-gutter-x-md q-mb-xl row text-body1 text-grey-8" :class="containerClass">
|
|
3
3
|
<div :class="leftClass">
|
|
4
4
|
<slot name="left">
|
|
5
5
|
{{ text }}
|
|
@@ -17,6 +17,12 @@
|
|
|
17
17
|
</template>
|
|
18
18
|
|
|
19
19
|
<script>
|
|
20
|
+
const AlignTypes = {
|
|
21
|
+
Start: 'start',
|
|
22
|
+
Center: 'center',
|
|
23
|
+
End: 'end'
|
|
24
|
+
}
|
|
25
|
+
|
|
20
26
|
export default {
|
|
21
27
|
name: 'QasHeaderActions',
|
|
22
28
|
|
|
@@ -26,6 +32,12 @@ export default {
|
|
|
26
32
|
default: () => ({})
|
|
27
33
|
},
|
|
28
34
|
|
|
35
|
+
alignColumns: {
|
|
36
|
+
default: AlignTypes.Center,
|
|
37
|
+
type: String,
|
|
38
|
+
validator: value => Object.values(AlignTypes).includes(value)
|
|
39
|
+
},
|
|
40
|
+
|
|
29
41
|
buttonProps: {
|
|
30
42
|
default: () => ({}),
|
|
31
43
|
type: Object
|
|
@@ -38,6 +50,10 @@ export default {
|
|
|
38
50
|
},
|
|
39
51
|
|
|
40
52
|
computed: {
|
|
53
|
+
containerClass () {
|
|
54
|
+
return `items-${this.alignColumns}`
|
|
55
|
+
},
|
|
56
|
+
|
|
41
57
|
hasDefaultButton () {
|
|
42
58
|
return !!Object.keys(this.buttonProps).length
|
|
43
59
|
},
|
|
@@ -9,6 +9,12 @@ props:
|
|
|
9
9
|
default: {}
|
|
10
10
|
type: Object
|
|
11
11
|
|
|
12
|
+
align-columns:
|
|
13
|
+
desc: Alinhamento vertical das colunas.
|
|
14
|
+
default: center
|
|
15
|
+
type: String
|
|
16
|
+
examples: [start, center, end]
|
|
17
|
+
|
|
12
18
|
button-props:
|
|
13
19
|
desc: Propriedades do QasBtn.
|
|
14
20
|
default: {}
|
|
@@ -23,4 +29,4 @@ slots:
|
|
|
23
29
|
desc: slot para acessar seção da esquerda (descrição).
|
|
24
30
|
|
|
25
31
|
right:
|
|
26
|
-
desc: slot para acessar seção da direita (ação).
|
|
32
|
+
desc: slot para acessar seção da direita (ação).
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="text-
|
|
2
|
+
<div class="text-h4" :class="classes">
|
|
3
3
|
<slot :label-with-suffix="labelWithSuffix">{{ labelWithSuffix }}</slot>
|
|
4
4
|
</div>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script>
|
|
8
8
|
import { addCounterSuffix } from '../../helpers'
|
|
9
|
+
import { Spacing } from '../../enums/Spacing'
|
|
9
10
|
|
|
10
11
|
export default {
|
|
11
12
|
name: 'QasLabel',
|
|
@@ -22,12 +23,12 @@ export default {
|
|
|
22
23
|
},
|
|
23
24
|
|
|
24
25
|
margin: {
|
|
25
|
-
default:
|
|
26
|
+
default: Spacing.Md,
|
|
26
27
|
type: String,
|
|
27
28
|
validator: value => {
|
|
28
|
-
const
|
|
29
|
+
const availableSpacings = Object.values(Spacing)
|
|
29
30
|
|
|
30
|
-
return
|
|
31
|
+
return availableSpacings.includes(value)
|
|
31
32
|
}
|
|
32
33
|
},
|
|
33
34
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div>
|
|
2
|
+
<div class="qas-search-box">
|
|
3
3
|
<qas-search-input v-bind="attributes" v-model="mx_search" />
|
|
4
4
|
|
|
5
|
-
<
|
|
5
|
+
<slot name="after-search" />
|
|
6
|
+
|
|
7
|
+
<div ref="scrollContainer" class="overflow-auto q-mt-md relative-position" :class="containerClasses" :style="containerStyle">
|
|
6
8
|
<component :is="component.is" v-bind="component.props" class="q-mr-sm">
|
|
7
9
|
<slot v-if="mx_hasFilteredOptions" />
|
|
8
10
|
</component>
|
|
@@ -14,11 +16,15 @@
|
|
|
14
16
|
</slot>
|
|
15
17
|
|
|
16
18
|
<slot v-if="showEmptyResult" name="empty-result">
|
|
17
|
-
<
|
|
19
|
+
<q-item class="q-px-none">
|
|
20
|
+
<q-item-section class="q-px-none">
|
|
21
|
+
<qas-empty-result-text />
|
|
22
|
+
</q-item-section>
|
|
23
|
+
</q-item>
|
|
18
24
|
</slot>
|
|
19
25
|
|
|
20
26
|
<q-inner-loading :showing="showInnerLoading">
|
|
21
|
-
<q-spinner color="grey" size="
|
|
27
|
+
<q-spinner color="grey" size="2rem" />
|
|
22
28
|
</q-inner-loading>
|
|
23
29
|
</div>
|
|
24
30
|
</div>
|
|
@@ -67,6 +73,10 @@ export default {
|
|
|
67
73
|
type: String
|
|
68
74
|
},
|
|
69
75
|
|
|
76
|
+
outlined: {
|
|
77
|
+
type: Boolean
|
|
78
|
+
},
|
|
79
|
+
|
|
70
80
|
placeholder: {
|
|
71
81
|
default: 'Pesquisar',
|
|
72
82
|
type: String
|
|
@@ -91,7 +101,9 @@ export default {
|
|
|
91
101
|
|
|
92
102
|
data () {
|
|
93
103
|
return {
|
|
94
|
-
fuse: null
|
|
104
|
+
fuse: null,
|
|
105
|
+
scrollContainer: null,
|
|
106
|
+
isInfiniteScrollDisabled: true
|
|
95
107
|
}
|
|
96
108
|
},
|
|
97
109
|
|
|
@@ -108,7 +120,7 @@ export default {
|
|
|
108
120
|
},
|
|
109
121
|
|
|
110
122
|
containerStyle () {
|
|
111
|
-
return {
|
|
123
|
+
return { maxHeight: this.containerHeight }
|
|
112
124
|
},
|
|
113
125
|
|
|
114
126
|
hasNoOptionsOnFirstFetch () {
|
|
@@ -124,8 +136,9 @@ export default {
|
|
|
124
136
|
component () {
|
|
125
137
|
const infiniteScrollProps = {
|
|
126
138
|
offset: 100,
|
|
127
|
-
scrollTarget: this
|
|
128
|
-
ref: 'infiniteScrollRef'
|
|
139
|
+
scrollTarget: this.scrollContainer,
|
|
140
|
+
ref: 'infiniteScrollRef',
|
|
141
|
+
disable: this.isInfiniteScrollDisabled
|
|
129
142
|
}
|
|
130
143
|
|
|
131
144
|
return {
|
|
@@ -137,6 +150,14 @@ export default {
|
|
|
137
150
|
}
|
|
138
151
|
},
|
|
139
152
|
|
|
153
|
+
containerClasses () {
|
|
154
|
+
return {
|
|
155
|
+
'qas-search-box__container': this.outlined,
|
|
156
|
+
'q-px-md': this.outlined,
|
|
157
|
+
'rounded-borders': this.outlined
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
|
|
140
161
|
defaultFuseOptions () {
|
|
141
162
|
return {
|
|
142
163
|
...fuseConfig,
|
|
@@ -206,6 +227,10 @@ export default {
|
|
|
206
227
|
}
|
|
207
228
|
},
|
|
208
229
|
|
|
230
|
+
mounted () {
|
|
231
|
+
this.scrollContainer = this.$refs.scrollContainer
|
|
232
|
+
},
|
|
233
|
+
|
|
209
234
|
created () {
|
|
210
235
|
this.setSearchMethod()
|
|
211
236
|
},
|
|
@@ -216,16 +241,8 @@ export default {
|
|
|
216
241
|
},
|
|
217
242
|
|
|
218
243
|
async onInfiniteScroll (_, done) {
|
|
219
|
-
// Se tiver erro no primeiro fetch, retorna o "done" na proxima.
|
|
220
244
|
if (((this.mx_hasFetchError && !this.mx_hasFilteredOptions) || this.hasNoOptionsOnFirstFetch)) return done()
|
|
221
245
|
|
|
222
|
-
const canMakeFirstFetch = this.mx_fetchCount === 0 && this.mx_hasFilteredOptions
|
|
223
|
-
|
|
224
|
-
if ((!this.mx_hasFilteredOptions || canMakeFirstFetch) && !this.mx_search) {
|
|
225
|
-
await this.mx_setFetchOptions()
|
|
226
|
-
return done()
|
|
227
|
-
}
|
|
228
|
-
|
|
229
246
|
if (this.mx_canFetchOptions()) {
|
|
230
247
|
await this.mx_loadMoreOptions()
|
|
231
248
|
return done()
|
|
@@ -255,9 +272,23 @@ export default {
|
|
|
255
272
|
this.setListWatcher()
|
|
256
273
|
},
|
|
257
274
|
|
|
258
|
-
setLazyLoading () {
|
|
275
|
+
async setLazyLoading () {
|
|
259
276
|
this.mx_setCachedOptions('list')
|
|
277
|
+
|
|
278
|
+
await this.mx_setFetchOptions()
|
|
279
|
+
|
|
280
|
+
this.isInfiniteScrollDisabled = false
|
|
260
281
|
}
|
|
261
282
|
}
|
|
262
283
|
}
|
|
263
284
|
</script>
|
|
285
|
+
|
|
286
|
+
<style lang="scss">
|
|
287
|
+
.qas-search-box {
|
|
288
|
+
&__container {
|
|
289
|
+
min-height: 48px;
|
|
290
|
+
background-color: white;
|
|
291
|
+
border: 1px solid $grey-4;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
</style>
|
|
@@ -62,6 +62,11 @@ props:
|
|
|
62
62
|
type: String
|
|
63
63
|
examples: [cities]
|
|
64
64
|
|
|
65
|
+
outlined:
|
|
66
|
+
desc: Define se a área que contém o resultado da pesquisa terá o estilo de borda arredondada com fundo branco (semelhante a um input).
|
|
67
|
+
default: false
|
|
68
|
+
type: Boolean
|
|
69
|
+
|
|
65
70
|
placeholder:
|
|
66
71
|
desc: Placeholder do campo de pesquisa.
|
|
67
72
|
default: Pesquisar
|
|
@@ -85,6 +90,9 @@ props:
|
|
|
85
90
|
type: Boolean
|
|
86
91
|
|
|
87
92
|
slots:
|
|
93
|
+
after-search:
|
|
94
|
+
desc: Acesso ao conteúdo após o input de pesquisa e antes do resultados (slot default).
|
|
95
|
+
|
|
88
96
|
default:
|
|
89
97
|
desc: Acesso ao conteúdo principal, só existe caso a busca retorne algum resultado.
|
|
90
98
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="qas-filter-input">
|
|
3
|
-
<qas-input ref="input" v-model="model" class="bg-white
|
|
3
|
+
<qas-input ref="input" v-model="model" v-bind="$attrs" class="bg-white rounded-borders-sm" data-cy="search-input" :debounce="debounce" dense hide-bottom-space input-class="ellipsis text-grey-8" type="search">
|
|
4
4
|
<template #prepend>
|
|
5
5
|
<q-icon v-if="useSearchOnType" color="grey-8" name="sym_r_search" />
|
|
6
6
|
<qas-btn v-else color="grey-9" icon="sym_r_search" variant="tertiary" @click="$emit('filter')" />
|
|
@@ -82,19 +82,6 @@ export default {
|
|
|
82
82
|
position: relative;
|
|
83
83
|
|
|
84
84
|
.q-field {
|
|
85
|
-
&::before {
|
|
86
|
-
border: 2px solid transparent;
|
|
87
|
-
border-radius: var(--qas-generic-border-radius);
|
|
88
|
-
bottom: 0;
|
|
89
|
-
content: '';
|
|
90
|
-
left: 0;
|
|
91
|
-
pointer-events: none;
|
|
92
|
-
position: absolute;
|
|
93
|
-
right: 0;
|
|
94
|
-
top: 0;
|
|
95
|
-
transition: border-color var(--qas-generic-transition);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
85
|
&--dense .q-field__prepend {
|
|
99
86
|
padding-right: var(--qas-spacing-xs);
|
|
100
87
|
}
|
|
@@ -103,16 +90,6 @@ export default {
|
|
|
103
90
|
padding-left: var(--qas-spacing-sm);
|
|
104
91
|
}
|
|
105
92
|
|
|
106
|
-
&--focused::before {
|
|
107
|
-
border-color: var(--q-primary);
|
|
108
|
-
color: var(--q-primary);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
&__control::after,
|
|
112
|
-
&__control::before {
|
|
113
|
-
display: none !important;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
93
|
&__native {
|
|
117
94
|
padding-bottom: var(--qas-spacing-sm);
|
|
118
95
|
padding-top: var(--qas-spacing-sm);
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<qas-search-box v-model:results="results" v-bind="defaultSearchBoxProps" :list="sortedList">
|
|
2
|
+
<qas-search-box ref="searchBox" v-model:results="results" v-bind="defaultSearchBoxProps" :list="sortedList">
|
|
3
|
+
<template #after-search>
|
|
4
|
+
<div class="q-mb-md q-mt-xl">
|
|
5
|
+
<span class="q-pr-sm text-body1 text-grey-8">Seleção:</span>
|
|
6
|
+
|
|
7
|
+
<qas-btn :disable="isClearSelectionDisabled" label="Limpar seleção" variant="tertiary" @click="clearSelection" />
|
|
8
|
+
</div>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
3
11
|
<template #default>
|
|
4
|
-
<q-list separator>
|
|
5
|
-
<q-item v-for="result in results" :key="result.value" class="q-px-none">
|
|
12
|
+
<q-list class="bg-white rounded-borders" separator>
|
|
13
|
+
<q-item v-for="result in results" :key="result.value" class="q-px-none" tag="label">
|
|
6
14
|
<slot v-bind="slotData" :item="result" name="item">
|
|
7
|
-
<
|
|
8
|
-
<
|
|
9
|
-
<div :class="labelClass" @click="onClickLabel({ item: result, index })">
|
|
10
|
-
{{ result.label }}
|
|
11
|
-
</div>
|
|
12
|
-
</q-item-section>
|
|
13
|
-
</slot>
|
|
14
|
-
|
|
15
|
-
<q-item-section avatar>
|
|
16
|
-
<slot :item="result" name="item-action" v-bind="slotData">
|
|
17
|
-
<qas-btn :disable="readonly" :use-label-on-small-screen="false" v-bind="getButtonProps(result)" @click="handleClick(result)" />
|
|
18
|
-
</slot>
|
|
15
|
+
<q-item-section>
|
|
16
|
+
<pv-select-list-checkbox :readonly="readonly" :result="result" :use-active="hasValueInModel(result.value)" @add="add" @remove="remove" />
|
|
19
17
|
</q-item-section>
|
|
20
18
|
</slot>
|
|
21
19
|
</q-item>
|
|
@@ -29,13 +27,17 @@ import { sortBy } from 'lodash-es'
|
|
|
29
27
|
|
|
30
28
|
import QasBtn from '../btn/QasBtn.vue'
|
|
31
29
|
import QasSearchBox from '../search-box/QasSearchBox.vue'
|
|
30
|
+
import PvSelectListCheckbox from './private/PvSelectListCheckbox.vue'
|
|
32
31
|
|
|
33
32
|
export default {
|
|
34
33
|
name: 'QasSelectList',
|
|
35
34
|
|
|
36
35
|
components: {
|
|
37
36
|
QasBtn,
|
|
38
|
-
QasSearchBox
|
|
37
|
+
QasSearchBox,
|
|
38
|
+
|
|
39
|
+
// private
|
|
40
|
+
PvSelectListCheckbox
|
|
39
41
|
},
|
|
40
42
|
|
|
41
43
|
inheritAttrs: false,
|
|
@@ -55,6 +57,11 @@ export default {
|
|
|
55
57
|
type: Boolean
|
|
56
58
|
},
|
|
57
59
|
|
|
60
|
+
emitValue: {
|
|
61
|
+
type: Boolean,
|
|
62
|
+
default: true
|
|
63
|
+
},
|
|
64
|
+
|
|
58
65
|
modelValue: {
|
|
59
66
|
type: Array,
|
|
60
67
|
default: () => []
|
|
@@ -69,20 +76,21 @@ export default {
|
|
|
69
76
|
default: () => ({})
|
|
70
77
|
},
|
|
71
78
|
|
|
72
|
-
|
|
73
|
-
type: Boolean
|
|
79
|
+
useEmitLabelValueOnly: {
|
|
80
|
+
type: Boolean,
|
|
81
|
+
default: true
|
|
74
82
|
}
|
|
75
83
|
},
|
|
76
84
|
|
|
77
85
|
emits: [
|
|
78
86
|
'added',
|
|
79
|
-
'click-label',
|
|
80
87
|
'removed',
|
|
81
88
|
'update:modelValue'
|
|
82
89
|
],
|
|
83
90
|
|
|
84
91
|
data () {
|
|
85
92
|
return {
|
|
93
|
+
searchBox: null,
|
|
86
94
|
sortedList: [],
|
|
87
95
|
values: [],
|
|
88
96
|
results: []
|
|
@@ -94,7 +102,9 @@ export default {
|
|
|
94
102
|
return {
|
|
95
103
|
fuseOptions: { keys: ['label'] },
|
|
96
104
|
|
|
97
|
-
...this.searchBoxProps
|
|
105
|
+
...this.searchBoxProps,
|
|
106
|
+
|
|
107
|
+
outlined: true
|
|
98
108
|
}
|
|
99
109
|
},
|
|
100
110
|
|
|
@@ -102,10 +112,6 @@ export default {
|
|
|
102
112
|
return this.defaultSearchBoxProps.useLazyLoading
|
|
103
113
|
},
|
|
104
114
|
|
|
105
|
-
labelClass () {
|
|
106
|
-
return this.useClickableLabel && 'cursor-pointer'
|
|
107
|
-
},
|
|
108
|
-
|
|
109
115
|
list () {
|
|
110
116
|
return this.defaultSearchBoxProps.list || []
|
|
111
117
|
},
|
|
@@ -113,10 +119,17 @@ export default {
|
|
|
113
119
|
slotData () {
|
|
114
120
|
return {
|
|
115
121
|
add: this.add,
|
|
116
|
-
handleClick: this.handleClick,
|
|
117
122
|
remove: this.remove,
|
|
118
123
|
updateModel: this.updateModel
|
|
119
124
|
}
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
isClearSelectionDisabled () {
|
|
128
|
+
return !this.modelValue.length || this.readonly || !this.results.length
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
hasSearch () {
|
|
132
|
+
return this.searchBox.mx_search
|
|
120
133
|
}
|
|
121
134
|
},
|
|
122
135
|
|
|
@@ -141,33 +154,22 @@ export default {
|
|
|
141
154
|
}
|
|
142
155
|
},
|
|
143
156
|
|
|
157
|
+
mounted () {
|
|
158
|
+
this.searchBox = this.$refs.searchBox
|
|
159
|
+
},
|
|
160
|
+
|
|
144
161
|
created () {
|
|
145
162
|
if (!this.hasLazyLoading) this.handleList()
|
|
146
163
|
},
|
|
147
164
|
|
|
148
165
|
methods: {
|
|
149
166
|
add (item) {
|
|
150
|
-
this.values.push(item
|
|
167
|
+
this.values.push(this.getNormalizedValue(item))
|
|
151
168
|
this.updateModel()
|
|
152
169
|
|
|
153
170
|
this.$emit('added', item)
|
|
154
171
|
},
|
|
155
172
|
|
|
156
|
-
getButtonProps ({ value }) {
|
|
157
|
-
const isSelected = this.values.includes(value)
|
|
158
|
-
|
|
159
|
-
return {
|
|
160
|
-
label: isSelected ? this.deleteLabel : this.addLabel,
|
|
161
|
-
variant: 'tertiary',
|
|
162
|
-
color: isSelected ? 'grey-9' : 'primary',
|
|
163
|
-
icon: isSelected ? 'sym_r_delete' : 'sym_r_add'
|
|
164
|
-
}
|
|
165
|
-
},
|
|
166
|
-
|
|
167
|
-
handleClick (item) {
|
|
168
|
-
return this.values.includes(item.value) ? this.remove(item) : this.add(item)
|
|
169
|
-
},
|
|
170
|
-
|
|
171
173
|
handleList () {
|
|
172
174
|
if (this.modelValue.length) {
|
|
173
175
|
return this.sortList()
|
|
@@ -181,12 +183,12 @@ export default {
|
|
|
181
183
|
})
|
|
182
184
|
},
|
|
183
185
|
|
|
184
|
-
onClickLabel ({ item, index }) {
|
|
185
|
-
this.useClickableLabel && this.$emit('click-label', { item, index })
|
|
186
|
-
},
|
|
187
|
-
|
|
188
186
|
remove (item) {
|
|
189
|
-
const index = this.values.findIndex(
|
|
187
|
+
const index = this.values.findIndex(itemValue => {
|
|
188
|
+
const normalizedItem = this.emitValue ? itemValue : item.value
|
|
189
|
+
|
|
190
|
+
return normalizedItem === item.value
|
|
191
|
+
})
|
|
190
192
|
|
|
191
193
|
this.values.splice(index, 1)
|
|
192
194
|
this.updateModel()
|
|
@@ -196,12 +198,38 @@ export default {
|
|
|
196
198
|
|
|
197
199
|
sortList () {
|
|
198
200
|
this.sortedList = this.deleteOnly
|
|
199
|
-
? this.list.filter(item => this.
|
|
200
|
-
: sortBy(this.list, item => !this.
|
|
201
|
+
? this.list.filter(item => this.hasValueInModel(item.value))
|
|
202
|
+
: sortBy(this.list, item => !this.hasValueInModel(item.value))
|
|
201
203
|
},
|
|
202
204
|
|
|
203
205
|
updateModel (model) {
|
|
204
206
|
this.$emit('update:modelValue', model || this.values)
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
hasValueInModel (value) {
|
|
210
|
+
return this.emitValue
|
|
211
|
+
? this.modelValue.includes(value)
|
|
212
|
+
: !!this.modelValue.find(item => item.value === value)
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
getNormalizedValue (objectValue = {}) {
|
|
216
|
+
if (this.emitValue) return objectValue.value
|
|
217
|
+
|
|
218
|
+
if (this.useEmitLabelValueOnly) {
|
|
219
|
+
const { label, value } = objectValue
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
label,
|
|
223
|
+
value
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return objectValue
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
clearSelection () {
|
|
231
|
+
this.values = []
|
|
232
|
+
this.updateModel()
|
|
205
233
|
}
|
|
206
234
|
}
|
|
207
235
|
}
|
|
@@ -21,6 +21,11 @@ props:
|
|
|
21
21
|
desc: Caso o "modelValue" tenha valor, ele remove tudo na lista que não esteja dentro do modelValue.
|
|
22
22
|
type: Boolean
|
|
23
23
|
|
|
24
|
+
emit-value:
|
|
25
|
+
desc: Quando valor é "true", transforma o model em um array de string, senão o model será um array de objeto.
|
|
26
|
+
default: true
|
|
27
|
+
type: Boolean
|
|
28
|
+
|
|
24
29
|
model-value:
|
|
25
30
|
desc: Model do componente, que será controlado tudo que foi selecionado.
|
|
26
31
|
default: []
|
|
@@ -38,8 +43,9 @@ props:
|
|
|
38
43
|
default: {}
|
|
39
44
|
type: Object
|
|
40
45
|
|
|
41
|
-
use-
|
|
42
|
-
desc:
|
|
46
|
+
use-emit-label-value-only:
|
|
47
|
+
desc: Propriedade para ser usada em conjunto com ':emitValue="false"', caso habilite essa propriedade, o model sempre será um array de objeto com label e value, se estiver desabilitado, o objeto dentro do model será o objeto inteiro, não somente label e value.
|
|
48
|
+
default: true
|
|
43
49
|
type: Boolean
|
|
44
50
|
|
|
45
51
|
slots:
|
|
@@ -54,33 +60,6 @@ slots:
|
|
|
54
60
|
desc: Função para adicionar um item ao model
|
|
55
61
|
type: Function
|
|
56
62
|
|
|
57
|
-
handleClick:
|
|
58
|
-
desc: Função que controla o model adiciona ou remove do model
|
|
59
|
-
type: Function
|
|
60
|
-
|
|
61
|
-
remove:
|
|
62
|
-
desc: Função para remover um item do model
|
|
63
|
-
type: Function
|
|
64
|
-
|
|
65
|
-
updateModel:
|
|
66
|
-
desc: Função para atualizar o v-model
|
|
67
|
-
type: Function
|
|
68
|
-
|
|
69
|
-
item-action:
|
|
70
|
-
desc: Acesso dentro do "<q-item-section avatar />".
|
|
71
|
-
scope:
|
|
72
|
-
item:
|
|
73
|
-
desc: Item atual da lista
|
|
74
|
-
type: Object
|
|
75
|
-
|
|
76
|
-
add:
|
|
77
|
-
desc: Função para adicionar um item ao model
|
|
78
|
-
type: Function
|
|
79
|
-
|
|
80
|
-
handleClick:
|
|
81
|
-
desc: Função que controla o model adiciona ou remove do model
|
|
82
|
-
type: Function
|
|
83
|
-
|
|
84
63
|
remove:
|
|
85
64
|
desc: Função para remover um item do model
|
|
86
65
|
type: Function
|
|
@@ -97,16 +76,6 @@ events:
|
|
|
97
76
|
desc: Item adicionado
|
|
98
77
|
type: String
|
|
99
78
|
|
|
100
|
-
'@click-label -> function ({ item, index })':
|
|
101
|
-
desc: Dispara toda vez que o label do item é clicado **SE** a propriedade "useClickableLabel" for "true".
|
|
102
|
-
params:
|
|
103
|
-
item:
|
|
104
|
-
desc: Item clicado
|
|
105
|
-
type: Object
|
|
106
|
-
index:
|
|
107
|
-
desc: Posição do item
|
|
108
|
-
type: Number
|
|
109
|
-
|
|
110
79
|
'@removed -> function (item, index)':
|
|
111
80
|
desc: Dispara toda vez que um item é removido do v-model.
|
|
112
81
|
params:
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<q-checkbox class="text-body1" dense :disable="props.readonly" :label="props.result.label" :model-value="props.useActive" @update:model-value="onUpdateModelValue(result)" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup>
|
|
6
|
+
defineOptions({
|
|
7
|
+
name: 'PvSelectListCheckbox'
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
const props = defineProps({
|
|
11
|
+
result: {
|
|
12
|
+
type: Object,
|
|
13
|
+
default: () => ({})
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
readonly: {
|
|
17
|
+
type: Boolean
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
useActive: {
|
|
21
|
+
type: Boolean,
|
|
22
|
+
default: false
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const emit = defineEmits(['add', 'remove'])
|
|
27
|
+
|
|
28
|
+
function onUpdateModelValue () {
|
|
29
|
+
return emit(props.useActive ? 'remove' : 'add', props.result)
|
|
30
|
+
}
|
|
31
|
+
</script>
|
package/src/helpers/rules.js
CHANGED