@itfin/components 2.0.46 → 2.0.48
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
CHANGED
|
@@ -20,17 +20,25 @@
|
|
|
20
20
|
</div>
|
|
21
21
|
</div>
|
|
22
22
|
<div class="facets-list">
|
|
23
|
-
<div v-for="(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
23
|
+
<div v-for="(group, g) of groupedList">
|
|
24
|
+
<div v-if="group.group" class="dropdown-item ps-1 d-flex align-items-center"
|
|
25
|
+
:class="{'active': isGroupSelected(group.items)}" @click="groupSelected(!isGroupSelected(group.items), group.items)">
|
|
26
|
+
<span class="facet-name text-dark d-flex align-items-center">
|
|
27
|
+
<itf-checkbox ungrouped :value="isGroupSelected(group.items)" @input="groupSelected($event, group.items)" class="m-0" />
|
|
28
|
+
<div class="w-100 text-truncate">{{ group.group }}</div>
|
|
29
|
+
</span>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div v-for="(val, n) of group.items" :key="n" class="dropdown-item ps-1" :class="{'active': val.isSelected, 'ps-4': group.group}" @click="onFilterClick(val)">
|
|
33
|
+
<span class="facet-name text-dark d-flex align-items-center">
|
|
34
|
+
<itf-checkbox ungrouped :value="val.isSelected" class="m-0" />
|
|
35
|
+
<div class="w-100 text-truncate">{{ val.label }} <span v-if="val.description" class="small"><br/>{{ val.description }}</span></div>
|
|
36
|
+
</span>
|
|
37
|
+
<span v-if="val.count" class="facet-stat">
|
|
38
|
+
{{ val.count }}
|
|
39
|
+
<span class="facet-bar"><span :style="{'--bar-width': `${getPercent(val)}%`}" class="facet-bar-progress" /></span>
|
|
40
|
+
</span>
|
|
41
|
+
</div>
|
|
34
42
|
</div>
|
|
35
43
|
</div>
|
|
36
44
|
|
|
@@ -115,10 +123,8 @@
|
|
|
115
123
|
<script>
|
|
116
124
|
import uniq from 'lodash/uniq';
|
|
117
125
|
import sortBy from 'lodash/sortBy';
|
|
118
|
-
import groupBy from 'lodash/groupBy';
|
|
119
126
|
import { Vue, Prop, Model, Component } from 'vue-property-decorator';
|
|
120
127
|
import itfTextField from '../text-field/TextField.vue';
|
|
121
|
-
import itfIcon from '../icon/Icon';
|
|
122
128
|
import itfButton from '../button/Button';
|
|
123
129
|
import itfCheckbox from '../checkbox/Checkbox.vue';
|
|
124
130
|
|
|
@@ -126,7 +132,6 @@ export default @Component({
|
|
|
126
132
|
name: 'FilterFacetsList',
|
|
127
133
|
components: {
|
|
128
134
|
itfCheckbox,
|
|
129
|
-
itfIcon,
|
|
130
135
|
itfButton,
|
|
131
136
|
itfTextField
|
|
132
137
|
}
|
|
@@ -136,7 +141,6 @@ class FilterFacetsList extends Vue {
|
|
|
136
141
|
@Prop() items;
|
|
137
142
|
@Prop() item;
|
|
138
143
|
@Prop() total;
|
|
139
|
-
@Prop() options;
|
|
140
144
|
@Prop({ type: Number, default: 5 }) limit;
|
|
141
145
|
@Prop(Boolean) multiple;
|
|
142
146
|
@Prop(Boolean) showAll;
|
|
@@ -150,44 +154,6 @@ class FilterFacetsList extends Vue {
|
|
|
150
154
|
this.showMore = !this.showMore;
|
|
151
155
|
}
|
|
152
156
|
|
|
153
|
-
get groupIcon() {
|
|
154
|
-
return this.options?.groupIcon;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
get flatList() {
|
|
158
|
-
return treeToFlat(this.items || []);
|
|
159
|
-
|
|
160
|
-
function getIdsDeep(items, mapFunc) {
|
|
161
|
-
return (items ?? []).reduce((acc, item) => {
|
|
162
|
-
const id = mapFunc(item);
|
|
163
|
-
if (id) {
|
|
164
|
-
acc.push(id);
|
|
165
|
-
}
|
|
166
|
-
if (item.items && item.items.length) {
|
|
167
|
-
acc.push(...getIdsDeep(item.items, mapFunc));
|
|
168
|
-
}
|
|
169
|
-
return acc;
|
|
170
|
-
}, []);
|
|
171
|
-
}
|
|
172
|
-
function treeToFlat(items, level = 0) {
|
|
173
|
-
return (items ?? []).reduce((acc, item) => {
|
|
174
|
-
acc.push({
|
|
175
|
-
...item,
|
|
176
|
-
level,
|
|
177
|
-
ids: [item.isGroup ? `g:${item.value}` : item.value].concat(
|
|
178
|
-
getIdsDeep(item.items, (item) => item.isGroup ? `g:${item.value}` : item.value)
|
|
179
|
-
)
|
|
180
|
-
.filter(Boolean),
|
|
181
|
-
});
|
|
182
|
-
if (item.items && item.items.length) {
|
|
183
|
-
// acc.push({ ...item, group: item.label, level });
|
|
184
|
-
acc.push(...treeToFlat(item.items, level + 1));
|
|
185
|
-
}
|
|
186
|
-
return acc;
|
|
187
|
-
}, []);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
157
|
get hasMore() {
|
|
192
158
|
if (this.showAll) {
|
|
193
159
|
return false;
|
|
@@ -196,27 +162,26 @@ class FilterFacetsList extends Vue {
|
|
|
196
162
|
}
|
|
197
163
|
|
|
198
164
|
get hasGroups() {
|
|
199
|
-
const groups = uniq(this.
|
|
165
|
+
const groups = uniq(this.items && this.items.map(item => item.group).filter(Boolean));
|
|
200
166
|
return groups.length > 1
|
|
201
167
|
}
|
|
202
168
|
|
|
203
|
-
isGroupSelected(
|
|
204
|
-
return
|
|
169
|
+
isGroupSelected(items) {
|
|
170
|
+
return items.every(item => item.isSelected);
|
|
205
171
|
}
|
|
206
172
|
|
|
207
|
-
groupSelected(value,
|
|
173
|
+
groupSelected(value, items) {
|
|
208
174
|
let newVal = this.value ? [...Array.isArray(this.value) ? this.value : [this.value]] : [];
|
|
209
|
-
console.info(value, ids);
|
|
210
175
|
if (value) {
|
|
211
|
-
|
|
212
|
-
const itemValue = `${
|
|
176
|
+
items.forEach((item) => {
|
|
177
|
+
const itemValue = `${item.value}`;
|
|
213
178
|
if (!newVal.includes(itemValue)) {
|
|
214
179
|
newVal.push(itemValue);
|
|
215
180
|
}
|
|
216
181
|
});
|
|
217
182
|
} else {
|
|
218
|
-
|
|
219
|
-
const itemValue = `${
|
|
183
|
+
items.forEach((item) => {
|
|
184
|
+
const itemValue = `${item.value}`;
|
|
220
185
|
newVal = newVal.filter(val => val !== itemValue);
|
|
221
186
|
});
|
|
222
187
|
}
|
|
@@ -224,7 +189,7 @@ class FilterFacetsList extends Vue {
|
|
|
224
189
|
}
|
|
225
190
|
|
|
226
191
|
get visibleList() {
|
|
227
|
-
let list = this.
|
|
192
|
+
let list = this.items.map(val => {
|
|
228
193
|
const isSelected = this.multiple
|
|
229
194
|
? Array.isArray(this.value) && this.value.map(String).includes(`${val.value}`)
|
|
230
195
|
: `${this.value}` === `${val.value}`;
|
|
@@ -237,15 +202,22 @@ class FilterFacetsList extends Vue {
|
|
|
237
202
|
if (this.isShowSelected) {
|
|
238
203
|
return list.filter((val) => val.isSelected);
|
|
239
204
|
}
|
|
240
|
-
return
|
|
205
|
+
return sortBy(list, (item) => this.hasGroups ? item.group || item.label : item.label);
|
|
241
206
|
}
|
|
242
207
|
|
|
243
208
|
get groupedList() {
|
|
244
209
|
if (!this.hasGroups) {
|
|
245
|
-
return this.mappedValues;
|
|
210
|
+
return [{ items: this.mappedValues }];
|
|
246
211
|
}
|
|
247
|
-
const groups =
|
|
248
|
-
|
|
212
|
+
const groups = {};
|
|
213
|
+
this.mappedValues.forEach((item) => {
|
|
214
|
+
const group = item.group || '';
|
|
215
|
+
if (!groups[group]) {
|
|
216
|
+
groups[group] = [];
|
|
217
|
+
}
|
|
218
|
+
groups[group].push(item);
|
|
219
|
+
});
|
|
220
|
+
return Object.entries(groups).map(([group, items]) => ({ group, items }));
|
|
249
221
|
}
|
|
250
222
|
|
|
251
223
|
get mappedValues() {
|
|
@@ -261,10 +233,6 @@ class FilterFacetsList extends Vue {
|
|
|
261
233
|
}
|
|
262
234
|
|
|
263
235
|
onFilterClick(val) {
|
|
264
|
-
if (val.isGroup) {
|
|
265
|
-
this.groupSelected(!val.isSelected, val.ids);
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
236
|
const value = `${val.value}`;
|
|
269
237
|
if (!this.multiple) {
|
|
270
238
|
return this.$emit('input', `${this.value}` === value ? null : value);
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div class="px-1">
|
|
4
|
+
<div class="facets-filter-header">
|
|
5
|
+
<div v-if="title">{{title}}</div>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
<itf-text-field small v-model="query" class="mb-2" :placeholder="$t('components.filter.search')" clearable />
|
|
9
|
+
|
|
10
|
+
<div class="d-flex justify-content-between small mb-2">
|
|
11
|
+
<a v-if="isSelectedAll" href="" @click.stop.prevent="onSelectAll(false)">{{$t('components.filter.deselectAll')}}</a>
|
|
12
|
+
<a v-else href="" @click.stop.prevent="onSelectAll(true)">{{$t('components.filter.selectAll')}}</a>
|
|
13
|
+
|
|
14
|
+
<span class="text-muted" v-if="!isHasSelected" href="" @click.stop.prevent="onShowSelected(true)">{{$t('components.filter.showSelected')}}</span>
|
|
15
|
+
<a v-else-if="!isShowSelected" href="" @click.stop.prevent="onShowSelected(true)">{{$t('components.filter.showSelected')}}</a>
|
|
16
|
+
<a v-else href="" @click.stop.prevent="onShowSelected(false)">{{$t('components.filter.showAll')}}</a>
|
|
17
|
+
</div>
|
|
18
|
+
<div v-if="!mappedValues.length">
|
|
19
|
+
<div class="text-muted text-center py-4">{{ $t('components.filter.noResults') }}</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="facets-list">
|
|
23
|
+
<div v-for="(val, g) of groupedList" :key="g" :style="{paddingLeft: `${((val.level || 0) + 0.5) * 1}rem`}"
|
|
24
|
+
class="dropdown-item" :class="{'active': val.isSelected, 'active': isGroupSelected(val)}" @click="onFilterClick(val)">
|
|
25
|
+
<span class="facet-name text-dark d-flex align-items-center">
|
|
26
|
+
<itf-checkbox ungrouped :value="val.isSelected" class="m-0" />
|
|
27
|
+
<itf-icon new v-if="val.isGroup && groupIcon" :name="groupIcon" class="me-1" />
|
|
28
|
+
<div class="w-100 text-truncate">{{ val.label }} <span v-if="val.description" class="small"><br/>{{ val.description }}</span></div>
|
|
29
|
+
</span>
|
|
30
|
+
<span v-if="val.count" class="facet-stat">
|
|
31
|
+
{{ val.count }}
|
|
32
|
+
<span class="facet-bar"><span :style="{'--bar-width': `${getPercent(val)}%`}" class="facet-bar-progress" /></span>
|
|
33
|
+
</span>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<itf-button default class="mt-1" v-if="hasMore" small block @click="toggleMore">
|
|
38
|
+
<span v-if="showMore">{{ $t('components.filter.hideMore', { count: visibleList.length }) }}</span>
|
|
39
|
+
<span v-else>{{ $t('components.filter.showMore', { count: visibleList.length }) }}</span>
|
|
40
|
+
</itf-button>
|
|
41
|
+
</div>
|
|
42
|
+
</template>
|
|
43
|
+
<style lang="scss" scoped>
|
|
44
|
+
.facets-filter-header {
|
|
45
|
+
border-bottom: 1px solid var(--bs-border-color-translucent);
|
|
46
|
+
color: #A5A5A9;
|
|
47
|
+
padding: 0 0.75rem .5rem;
|
|
48
|
+
margin: 0 -.75rem .75rem;
|
|
49
|
+
}
|
|
50
|
+
.facets-list {
|
|
51
|
+
max-height: 50vh;
|
|
52
|
+
overflow: auto;
|
|
53
|
+
}
|
|
54
|
+
.dropdown-item {
|
|
55
|
+
--bs-dropdown-link-active-bg: rgba(var(--bs-primary-rgb), .25);
|
|
56
|
+
|
|
57
|
+
cursor: pointer;
|
|
58
|
+
display: inline-flex;
|
|
59
|
+
-webkit-box-align: center;
|
|
60
|
+
align-items: center;
|
|
61
|
+
-webkit-box-pack: justify;
|
|
62
|
+
justify-content: space-between;
|
|
63
|
+
position: relative;
|
|
64
|
+
box-sizing: border-box;
|
|
65
|
+
min-height: 1.75rem;
|
|
66
|
+
width: 100%;
|
|
67
|
+
font-size: 0.875rem;
|
|
68
|
+
line-height: 1.25rem;
|
|
69
|
+
font-weight: 400;
|
|
70
|
+
white-space: normal;
|
|
71
|
+
user-select: none;
|
|
72
|
+
border-radius: 0.25rem;
|
|
73
|
+
border-width: 1px;
|
|
74
|
+
border-style: solid;
|
|
75
|
+
border-color: transparent;
|
|
76
|
+
border-image: initial;
|
|
77
|
+
transition: none 0s ease 0s;
|
|
78
|
+
margin: 1px 0;
|
|
79
|
+
&.active {
|
|
80
|
+
.facet-bar-progress {
|
|
81
|
+
background-color: var(--bs-blue);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
.facet-name {
|
|
85
|
+
min-width: 0;
|
|
86
|
+
text-align: left;
|
|
87
|
+
line-height: 100%;
|
|
88
|
+
white-space: nowrap;
|
|
89
|
+
|
|
90
|
+
.itf-checkbox {
|
|
91
|
+
min-height: 1.25rem;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
.facet-stat {
|
|
95
|
+
display: flex;
|
|
96
|
+
-webkit-box-align: center;
|
|
97
|
+
align-items: center;
|
|
98
|
+
margin-left: 0.25rem;
|
|
99
|
+
}
|
|
100
|
+
.facet-bar {
|
|
101
|
+
display: inline-block;
|
|
102
|
+
margin-left: 0.5rem;
|
|
103
|
+
width: 60px;
|
|
104
|
+
}
|
|
105
|
+
.facet-bar-progress {
|
|
106
|
+
display: block;
|
|
107
|
+
width: var(--bar-width);
|
|
108
|
+
min-width: 5px;
|
|
109
|
+
height: 10px;
|
|
110
|
+
background-color: rgba(var(--bs-blue-rgb), 50%);
|
|
111
|
+
transition: width 0.3s ease 0s;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
</style>
|
|
115
|
+
<script>
|
|
116
|
+
import uniq from 'lodash/uniq';
|
|
117
|
+
import sortBy from 'lodash/sortBy';
|
|
118
|
+
import groupBy from 'lodash/groupBy';
|
|
119
|
+
import { Vue, Prop, Model, Component } from 'vue-property-decorator';
|
|
120
|
+
import itfTextField from '../text-field/TextField.vue';
|
|
121
|
+
import itfIcon from '../icon/Icon';
|
|
122
|
+
import itfButton from '../button/Button';
|
|
123
|
+
import itfCheckbox from '../checkbox/Checkbox.vue';
|
|
124
|
+
|
|
125
|
+
export default @Component({
|
|
126
|
+
name: 'FilterFacetsList',
|
|
127
|
+
components: {
|
|
128
|
+
itfCheckbox,
|
|
129
|
+
itfIcon,
|
|
130
|
+
itfButton,
|
|
131
|
+
itfTextField
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
class FilterFacetsList extends Vue {
|
|
135
|
+
@Model('input') value;
|
|
136
|
+
@Prop() items;
|
|
137
|
+
@Prop() item;
|
|
138
|
+
@Prop() total;
|
|
139
|
+
@Prop() options;
|
|
140
|
+
@Prop({ type: Number, default: 5 }) limit;
|
|
141
|
+
@Prop(Boolean) multiple;
|
|
142
|
+
@Prop(Boolean) showAll;
|
|
143
|
+
@Prop(String) title;
|
|
144
|
+
|
|
145
|
+
query = '';
|
|
146
|
+
showMore = false;
|
|
147
|
+
isShowSelected = false;
|
|
148
|
+
|
|
149
|
+
toggleMore() {
|
|
150
|
+
this.showMore = !this.showMore;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
get groupIcon() {
|
|
154
|
+
return this.options?.groupIcon;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
get flatList() {
|
|
158
|
+
return treeToFlat(this.items || []);
|
|
159
|
+
|
|
160
|
+
function getIdsDeep(items, mapFunc) {
|
|
161
|
+
return (items ?? []).reduce((acc, item) => {
|
|
162
|
+
const id = mapFunc(item);
|
|
163
|
+
if (id) {
|
|
164
|
+
acc.push(id);
|
|
165
|
+
}
|
|
166
|
+
if (item.items && item.items.length) {
|
|
167
|
+
acc.push(...getIdsDeep(item.items, mapFunc));
|
|
168
|
+
}
|
|
169
|
+
return acc;
|
|
170
|
+
}, []);
|
|
171
|
+
}
|
|
172
|
+
function treeToFlat(items, level = 0) {
|
|
173
|
+
return (items ?? []).reduce((acc, item) => {
|
|
174
|
+
acc.push({
|
|
175
|
+
...item,
|
|
176
|
+
level,
|
|
177
|
+
ids: [item.isGroup ? `g:${item.value}` : item.value].concat(
|
|
178
|
+
getIdsDeep(item.items, (item) => item.isGroup ? `g:${item.value}` : item.value)
|
|
179
|
+
)
|
|
180
|
+
.filter(Boolean),
|
|
181
|
+
});
|
|
182
|
+
if (item.items && item.items.length) {
|
|
183
|
+
// acc.push({ ...item, group: item.label, level });
|
|
184
|
+
acc.push(...treeToFlat(item.items, level + 1));
|
|
185
|
+
}
|
|
186
|
+
return acc;
|
|
187
|
+
}, []);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
get hasMore() {
|
|
192
|
+
if (this.showAll) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
return this.visibleList.length > this.limit;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
get hasGroups() {
|
|
199
|
+
const groups = uniq(this.flatList && this.flatList.map(item => item.group).filter(Boolean));
|
|
200
|
+
return groups.length > 1
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
isGroupSelected(val) {
|
|
204
|
+
return (val.ids ?? []).every(id => this.value.includes(`${id}`));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
groupSelected(value, ids) {
|
|
208
|
+
let newVal = this.value ? [...Array.isArray(this.value) ? this.value : [this.value]] : [];
|
|
209
|
+
console.info(value, ids);
|
|
210
|
+
if (value) {
|
|
211
|
+
ids.forEach((id) => {
|
|
212
|
+
const itemValue = `${id}`;
|
|
213
|
+
if (!newVal.includes(itemValue)) {
|
|
214
|
+
newVal.push(itemValue);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
} else {
|
|
218
|
+
ids.forEach((id) => {
|
|
219
|
+
const itemValue = `${id}`;
|
|
220
|
+
newVal = newVal.filter(val => val !== itemValue);
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
this.$emit('input', this.multiple ? newVal : (newVal.length > 0 ? newVal[0] : null));
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
get visibleList() {
|
|
227
|
+
let list = this.flatList.map(val => {
|
|
228
|
+
const isSelected = this.multiple
|
|
229
|
+
? Array.isArray(this.value) && this.value.map(String).includes(`${val.value}`)
|
|
230
|
+
: `${this.value}` === `${val.value}`;
|
|
231
|
+
|
|
232
|
+
return { ...val, isSelected };
|
|
233
|
+
});
|
|
234
|
+
if (this.query) {
|
|
235
|
+
list = list.filter((val) => val.label.toLowerCase().includes(this.query.toLowerCase()));
|
|
236
|
+
}
|
|
237
|
+
if (this.isShowSelected) {
|
|
238
|
+
return list.filter((val) => val.isSelected);
|
|
239
|
+
}
|
|
240
|
+
return this.hasGroups ? sortBy(list, (item) => item.group || item.label) : list;//sortBy(list, (item) => this.hasGroups ? item.group || item.label : item.label);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
get groupedList() {
|
|
244
|
+
if (!this.hasGroups) {
|
|
245
|
+
return this.mappedValues;
|
|
246
|
+
}
|
|
247
|
+
const groups = groupBy(this.mappedValues, (item) => item.group || '');
|
|
248
|
+
return Object.entries(groups).reduce((acc, [group, items]) => [...acc, { label: group, isGroup: true }, ...(items.map(item => ({ ...item, level: 1 })))], []);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
get mappedValues() {
|
|
252
|
+
const list = this.visibleList;
|
|
253
|
+
if (!this.showMore && !this.showAll) {
|
|
254
|
+
return list.slice(0, this.limit);
|
|
255
|
+
}
|
|
256
|
+
return list;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
getPercent(item) {
|
|
260
|
+
return this.total ? Math.round((item.count / this.total) * 100) : 0;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
onFilterClick(val) {
|
|
264
|
+
if (val.isGroup) {
|
|
265
|
+
this.groupSelected(!val.isSelected, val.ids);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const value = `${val.value}`;
|
|
269
|
+
if (!this.multiple) {
|
|
270
|
+
return this.$emit('input', `${this.value}` === value ? null : value);
|
|
271
|
+
}
|
|
272
|
+
const newVal = [...Array.isArray(this.value) ? [...this.value] : []].map((s) => s.toString());
|
|
273
|
+
if (newVal.includes(value)) {
|
|
274
|
+
newVal.splice(newVal.indexOf(value), 1);
|
|
275
|
+
} else {
|
|
276
|
+
newVal.push(value);
|
|
277
|
+
}
|
|
278
|
+
this.$emit('input', newVal);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
get isSelectedAll() {
|
|
282
|
+
return this.mappedValues.every(o => o.isSelected);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
onSelectAll(isSelect = false) {
|
|
286
|
+
if (isSelect) {
|
|
287
|
+
this.$emit('input', this.visibleList.map((val) => `${val.value}`));
|
|
288
|
+
} else {
|
|
289
|
+
this.$emit('input', []);
|
|
290
|
+
}
|
|
291
|
+
this.isShowSelected = false;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
get isHasSelected() {
|
|
295
|
+
return this.value && this.value.length > 0 && !this.query; // тільки коли не пошук
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
onShowSelected(isShow = false) {
|
|
299
|
+
if (!this.value.length && isShow) { // не показувати, якщо нічого не вибрано
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
this.isShowSelected = isShow;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
</script>
|