@itfin/components 2.0.9 → 2.0.10
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
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="itf-filter-panel d-flex flex-column gap-3 align-items-start">
|
|
3
3
|
<div v-if="search" class="d-flex gap-2 justify-content-between w-100">
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
<slot name="search">
|
|
5
|
+
<itf-text-field
|
|
6
|
+
style="width: 300px"
|
|
7
|
+
small
|
|
8
|
+
:placeholder="searchPlaceholder"
|
|
9
|
+
prepend-icon="search"
|
|
10
|
+
:delay-input="250"
|
|
11
|
+
clearable
|
|
12
|
+
:value="filterValue.query"
|
|
13
|
+
@input="(e) => onFilterChange({ type: 'text', name: 'query' }, { value: e })"
|
|
14
|
+
/>
|
|
15
|
+
</slot>
|
|
14
16
|
<div class="d-flex gap-2">
|
|
15
|
-
<itf-button default icon class="position-relative" @click="
|
|
17
|
+
<itf-button default icon class="position-relative" @click="toggleFilters">
|
|
16
18
|
<itf-icon new name="filter" />
|
|
17
19
|
<span v-if="activeFiltersCount" class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-primary">
|
|
18
20
|
{{activeFiltersCount}}
|
|
@@ -89,6 +91,7 @@ class FilterPanel extends Vue {
|
|
|
89
91
|
@Prop({ type: Array }) staticFilters;
|
|
90
92
|
@Prop({ type: String }) endpoint;
|
|
91
93
|
@Prop() panel;
|
|
94
|
+
@Prop(String) stateName;
|
|
92
95
|
@Prop(Boolean) search;
|
|
93
96
|
@Prop(Boolean) mini;
|
|
94
97
|
@Prop({ type: String, default: function() { return this.$t('components.filter.search'); } }) searchPlaceholder;
|
|
@@ -101,16 +104,25 @@ class FilterPanel extends Vue {
|
|
|
101
104
|
|
|
102
105
|
get visibleFilters() {
|
|
103
106
|
if (this.mini) {
|
|
104
|
-
return this.filters.slice(0, 2);
|
|
107
|
+
return this.filters.filter(f => !f.options?.hidden).slice(0, 2);
|
|
105
108
|
}
|
|
106
|
-
return this.filters;
|
|
109
|
+
return this.filters.filter(f => !f.options?.hidden);
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
get resetFilters() {
|
|
110
113
|
return this.filters.filter(f => !this.visibleFilters.find(vf => vf.name === f.name));
|
|
111
114
|
}
|
|
112
115
|
|
|
116
|
+
get localstorageKey() {
|
|
117
|
+
return `filter-panel-${this.stateName}-filters`;
|
|
118
|
+
}
|
|
119
|
+
|
|
113
120
|
async mounted() {
|
|
121
|
+
if (this.stateName) {
|
|
122
|
+
const item = localStorage.getItem(this.localstorageKey);
|
|
123
|
+
this.showFilters = item ? JSON.parse(item) : this.showFilters;
|
|
124
|
+
}
|
|
125
|
+
|
|
114
126
|
this.filters = this.staticFilters ?? [];
|
|
115
127
|
if (this.endpoint) {
|
|
116
128
|
this.loading = true;
|
|
@@ -128,18 +140,27 @@ class FilterPanel extends Vue {
|
|
|
128
140
|
}
|
|
129
141
|
}
|
|
130
142
|
|
|
143
|
+
toggleFilters() {
|
|
144
|
+
this.showFilters = !this.showFilters;
|
|
145
|
+
if (this.stateName) {
|
|
146
|
+
localStorage.setItem(this.localstorageKey, this.showFilters);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
131
150
|
loadFiltersValue() {
|
|
132
151
|
const payload = this.panel ? this.panel.getPayload() : {};
|
|
133
152
|
const filter = {};
|
|
134
153
|
const filterValue = {};
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
154
|
+
if (this.filters) {
|
|
155
|
+
for (const item of this.filters) {
|
|
156
|
+
if (item.type === 'period') {
|
|
157
|
+
filter[item.name] = payload.from ? this.formatValue(item, { value: [payload.from, payload.to] }) : { isDefault: true, ...item.options.defaultValue };
|
|
158
|
+
filterValue.from = payload.from;
|
|
159
|
+
filterValue.to = payload.to;
|
|
160
|
+
} else {
|
|
161
|
+
filter[item.name] = payload[item.name] ? this.formatValue(item, { value: payload[item.name] }) : { isDefault: true, ...item.options.defaultValue };
|
|
162
|
+
filterValue[item.name] = payload[item.name];
|
|
163
|
+
}
|
|
143
164
|
}
|
|
144
165
|
}
|
|
145
166
|
if (this.search) {
|
|
@@ -187,7 +208,7 @@ class FilterPanel extends Vue {
|
|
|
187
208
|
}
|
|
188
209
|
|
|
189
210
|
get activeFiltersCount() {
|
|
190
|
-
return Object.values(this.filter).filter(facet => !facet.isDefault).length;
|
|
211
|
+
return Object.values(this.filter).filter(facet => !facet.isDefault && !facet.hidden).length;
|
|
191
212
|
}
|
|
192
213
|
|
|
193
214
|
formatValue(facet, value) {
|
|
@@ -250,6 +271,7 @@ class FilterPanel extends Vue {
|
|
|
250
271
|
value.value = value.value.length ? value.value : undefined;
|
|
251
272
|
value.isDefault = !value.value;
|
|
252
273
|
}
|
|
274
|
+
value.hidden = facet.options?.hidden ?? false;
|
|
253
275
|
return value;
|
|
254
276
|
}
|
|
255
277
|
}
|