@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,6 +1,6 @@
1
1
  {
2
2
  "name": "@itfin/components",
3
- "version": "2.0.9",
3
+ "version": "2.0.10",
4
4
  "author": "Vitalii Savchuk <esvit666@gmail.com>",
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -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
- <itf-text-field
5
- style="width: 300px"
6
- small
7
- :placeholder="searchPlaceholder"
8
- prepend-icon="search"
9
- :delay-input="250"
10
- clearable
11
- :value="filterValue.query"
12
- @input="(e) => onFilterChange({ type: 'text', name: 'query' }, { value: e })"
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="showFilters = !showFilters">
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
- for (const item of this.filters) {
136
- if (item.type === 'period') {
137
- filter[item.name] = payload.from ? this.formatValue(item, { value: [payload.from, payload.to] }) : { isDefault: true, ...item.options.defaultValue };
138
- filterValue.from = payload.from;
139
- filterValue.to = payload.to;
140
- } else {
141
- filter[item.name] = payload[item.name] ? this.formatValue(item, { value: payload[item.name] }) : { isDefault: true, ...item.options.defaultValue };
142
- filterValue[item.name] = payload[item.name];
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
  }
@@ -28,6 +28,7 @@
28
28
  }
29
29
  .item-toggle {
30
30
  width: 1.5rem;
31
+ min-width: 1.5rem;
31
32
  display: flex;
32
33
  align-items: center;
33
34
  }
@@ -130,6 +130,7 @@ body[data-theme="dark"] {
130
130
  }
131
131
  .last-sticky-column {
132
132
  position: relative;
133
+ border-right: 0 none !important;
133
134
  &:after {
134
135
  content: "";
135
136
  position: absolute;