@itfin/components 1.4.8 → 1.4.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
|
@@ -29,6 +29,14 @@
|
|
|
29
29
|
@input="onFilterChange({ value: $event })"
|
|
30
30
|
/>
|
|
31
31
|
</template>
|
|
32
|
+
<template v-else-if="type === 'period-selector'">
|
|
33
|
+
<itf-period-picker
|
|
34
|
+
style="margin: -.5rem"
|
|
35
|
+
:value="value.value"
|
|
36
|
+
value-format="yyyy-MM-dd"
|
|
37
|
+
@input="onFilterChange({ value: $event })"
|
|
38
|
+
/>
|
|
39
|
+
</template>
|
|
32
40
|
<template v-else-if="type === 'date'">
|
|
33
41
|
<itf-date-picker-inline
|
|
34
42
|
style="margin: -.5rem"
|
|
@@ -146,6 +154,7 @@ import itfButton from '../button/Button';
|
|
|
146
154
|
import itfDropdown from '../dropdown/Dropdown.vue';
|
|
147
155
|
import itfDatePickerInline from '../datepicker/DatePickerInline.vue';
|
|
148
156
|
import itfDateRangePickerInline from '../datepicker/DateRangePickerInline.vue';
|
|
157
|
+
import itfPeriodPicker from '../datepicker/PeriodPicker.vue'
|
|
149
158
|
import itfTextField from '../text-field/TextField.vue';
|
|
150
159
|
import FilterFacetsList from './FilterFacetsList';
|
|
151
160
|
import FilterAmountRange from './FilterAmountRange.vue';
|
|
@@ -157,6 +166,7 @@ export default @Component({
|
|
|
157
166
|
itfDropdown,
|
|
158
167
|
itfDatePickerInline,
|
|
159
168
|
itfDateRangePickerInline,
|
|
169
|
+
itfPeriodPicker,
|
|
160
170
|
itfTextField,
|
|
161
171
|
FilterFacetsList,
|
|
162
172
|
FilterAmountRange
|
|
@@ -120,6 +120,8 @@ class FilterPanel extends Vue {
|
|
|
120
120
|
loading = false;
|
|
121
121
|
showFilters = true;
|
|
122
122
|
|
|
123
|
+
periodFilters = ['period', 'period-selector'];
|
|
124
|
+
|
|
123
125
|
get visibleFilters() {
|
|
124
126
|
if (this.mini) {
|
|
125
127
|
return sortBy(this.filters, (f) => this.filter[f.name].isDefault).filter(f => !f.options?.hidden).slice(0, 2);
|
|
@@ -173,7 +175,7 @@ class FilterPanel extends Vue {
|
|
|
173
175
|
const filterValue = {};
|
|
174
176
|
if (this.filters) {
|
|
175
177
|
for (const item of this.filters) {
|
|
176
|
-
if (item.type
|
|
178
|
+
if (this.periodFilters.includes(item.type)) {
|
|
177
179
|
filter[item.name] = payload.from ? this.formatValue(item, { value: [payload.from, payload.to] }) : { isDefault: true, ...item.options.defaultValue };
|
|
178
180
|
filterValue.from = payload.from;
|
|
179
181
|
filterValue.to = payload.to;
|
|
@@ -205,7 +207,7 @@ class FilterPanel extends Vue {
|
|
|
205
207
|
|
|
206
208
|
onFilterChange(facet, value) {
|
|
207
209
|
this.filter[facet.name] = this.formatValue(facet, value);
|
|
208
|
-
if (facet.type
|
|
210
|
+
if (this.periodFilters.includes(facet.type)) {
|
|
209
211
|
this.filterValue.from = this.filter[facet.name].isDefault ? undefined : value.value[0];
|
|
210
212
|
this.filterValue.to = this.filter[facet.name].isDefault ? undefined : value.value[1];
|
|
211
213
|
} else {
|
|
@@ -236,7 +238,7 @@ class FilterPanel extends Vue {
|
|
|
236
238
|
}
|
|
237
239
|
|
|
238
240
|
formatValue(facet, value) {
|
|
239
|
-
if (facet.type
|
|
241
|
+
if (this.periodFilters.includes(facet.type)) {
|
|
240
242
|
if (value.value) {
|
|
241
243
|
let from = DateTime.fromFormat(value.value[0], 'yyyy-MM-dd');
|
|
242
244
|
let to = DateTime.fromFormat(value.value[1], 'yyyy-MM-dd');
|
|
@@ -249,7 +249,8 @@ class itfTable2 extends Vue {
|
|
|
249
249
|
@Watch('selectedIds')
|
|
250
250
|
onSelectedIdsUpdate(selectedIds) {
|
|
251
251
|
this.state.selectedIds = selectedIds;
|
|
252
|
-
|
|
252
|
+
// метод saveTableState не зберігає selectedIds в localStorage, не впевнений що він тут треба
|
|
253
|
+
// this.saveTableState();
|
|
253
254
|
}
|
|
254
255
|
|
|
255
256
|
onColumnsUpdate(columns) {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
:search="currentTab !== 'list'"
|
|
7
7
|
:show-filter="currentTab !== 'list'"
|
|
8
8
|
class="py-2 px-3"
|
|
9
|
+
:static-filters="filters"
|
|
9
10
|
:endpoint="filtersEndpoint"
|
|
10
11
|
:panel="panel"
|
|
11
12
|
v-model="filter"
|
|
@@ -41,11 +42,12 @@
|
|
|
41
42
|
</itf-dropdown>
|
|
42
43
|
|
|
43
44
|
<itf-segmented-control
|
|
44
|
-
v-if="tabs.length"
|
|
45
|
+
v-if="tabs.length > 1"
|
|
45
46
|
class="small"
|
|
46
|
-
|
|
47
|
+
:value="currentTab"
|
|
47
48
|
item-key="value"
|
|
48
49
|
:items="tabs"
|
|
50
|
+
@input="updateTabs"
|
|
49
51
|
>
|
|
50
52
|
<template #item="{ item }">
|
|
51
53
|
<div class="d-flex align-items-center">
|
|
@@ -75,6 +77,7 @@
|
|
|
75
77
|
class="permanent-checkboxes"
|
|
76
78
|
:state-name="stateName"
|
|
77
79
|
id-property="id"
|
|
80
|
+
:sort-as-string="sortAsString"
|
|
78
81
|
:rows="items"
|
|
79
82
|
:schema="tableSchema"
|
|
80
83
|
:sorting="sorting"
|
|
@@ -114,7 +117,7 @@
|
|
|
114
117
|
|
|
115
118
|
</template>
|
|
116
119
|
<script>
|
|
117
|
-
import {
|
|
120
|
+
import {Vue, ModelSync, Component, Prop, Inject, PropSync, Watch} from 'vue-property-decorator';
|
|
118
121
|
import loading from '../../directives/loading';
|
|
119
122
|
import itfTable from '../table/Table2.vue';
|
|
120
123
|
import itfFilterPanel from '../filter/FilterPanel.vue';
|
|
@@ -144,10 +147,7 @@ class itfView extends Vue {
|
|
|
144
147
|
|
|
145
148
|
@Prop({ type: Boolean }) loading;
|
|
146
149
|
@Prop({ type: Array }) filters;
|
|
147
|
-
// @Prop({ type: Object, required: true }) schema;
|
|
148
150
|
@Prop({ type: Object }) schema;
|
|
149
|
-
// @Prop({ default: 20 }) size;
|
|
150
|
-
// @Prop({ default: 1 }) page;
|
|
151
151
|
@Prop(String) defaultSorting;
|
|
152
152
|
@Prop(String) endpoint;
|
|
153
153
|
@Prop(String) filtersEndpoint;
|
|
@@ -155,7 +155,7 @@ class itfView extends Vue {
|
|
|
155
155
|
@Prop(String) panelKey;
|
|
156
156
|
@Prop(String) stateName;
|
|
157
157
|
@Prop({ type: String, default: 'checkbox' }) indicatorType;
|
|
158
|
-
@Prop({ type: String, default: '
|
|
158
|
+
@Prop({ type: String, default: 'list' }) tab;
|
|
159
159
|
@Prop({ type: String, default () { return this.$t('components.table.search'); } }) searchPlaceholder;
|
|
160
160
|
@Prop() panel;
|
|
161
161
|
@Prop(Boolean) showActions;
|
|
@@ -163,7 +163,10 @@ class itfView extends Vue {
|
|
|
163
163
|
@Prop(Boolean) listViewEnabled;
|
|
164
164
|
@Prop(Boolean) kanbanViewEnabled;
|
|
165
165
|
@Prop(Boolean) calendarViewEnabled;
|
|
166
|
-
@Prop(Boolean) tableViewEnabled;
|
|
166
|
+
@Prop({ type: Boolean, default: true }) tableViewEnabled;
|
|
167
|
+
@Prop(Boolean) sortAsString;
|
|
168
|
+
@Prop(Boolean) oldFormat;
|
|
169
|
+
@Prop({type: Function, default: null }) onSplitSlectedIds // якщо потрібно розділяти вибрані рядки в таблиці на дві групи
|
|
167
170
|
|
|
168
171
|
page = 1;
|
|
169
172
|
total = 0;
|
|
@@ -173,15 +176,18 @@ class itfView extends Vue {
|
|
|
173
176
|
filter = {};
|
|
174
177
|
loadingData = false;
|
|
175
178
|
activeIds = [];
|
|
176
|
-
tableColumns =
|
|
179
|
+
tableColumns = undefined;
|
|
177
180
|
_currentTab = null;
|
|
178
181
|
|
|
179
|
-
|
|
180
|
-
|
|
182
|
+
@Watch('selectedIds', { deep: true, immediate: true })
|
|
183
|
+
updateSelectedIds() {
|
|
184
|
+
if(this.onSplitSlectedIds && this.items.length && this.selectedIds.length) {
|
|
185
|
+
this.onSplitSlectedIds(this.selectedIds, this.items);
|
|
186
|
+
}
|
|
181
187
|
}
|
|
182
188
|
|
|
183
|
-
|
|
184
|
-
this
|
|
189
|
+
get currentTab() {
|
|
190
|
+
return this.tab;
|
|
185
191
|
}
|
|
186
192
|
|
|
187
193
|
get tabs() {
|
|
@@ -202,7 +208,6 @@ class itfView extends Vue {
|
|
|
202
208
|
}
|
|
203
209
|
|
|
204
210
|
get tableSchema() {
|
|
205
|
-
// return this.tableColumns || this.schema;
|
|
206
211
|
if (this.tableColumns) {
|
|
207
212
|
return {
|
|
208
213
|
properties: this.tableColumns
|
|
@@ -215,13 +220,12 @@ class itfView extends Vue {
|
|
|
215
220
|
}
|
|
216
221
|
|
|
217
222
|
created() {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
this.sorting = this.defaultSorting;
|
|
223
|
+
const defaultSize = localStorage.getItem('sizePerPage') ?? 20;
|
|
224
|
+
|
|
225
|
+
const { page, size, sorting } = this.panel.getPayload() ?? {};
|
|
226
|
+
this.page = page ?? 1;
|
|
227
|
+
this.size = size ?? defaultSize;
|
|
228
|
+
this.sorting = sorting ?? this.defaultSorting;
|
|
225
229
|
}
|
|
226
230
|
|
|
227
231
|
mounted() {
|
|
@@ -241,19 +245,32 @@ class itfView extends Vue {
|
|
|
241
245
|
this.$emit('load', this.filter);
|
|
242
246
|
this.loadingData = true;
|
|
243
247
|
await this.$try(async () => {
|
|
244
|
-
|
|
245
|
-
|
|
248
|
+
let filter = this.filter;
|
|
249
|
+
if (this.oldFormat) {
|
|
250
|
+
filter = Object.keys(filter).reduce((acc, key) => {
|
|
251
|
+
acc[`filter[${key}]`] = filter[key];
|
|
252
|
+
return acc;
|
|
253
|
+
}, {})
|
|
254
|
+
}
|
|
255
|
+
const { data, headers } = await this.$axios.get(this.endpoint, {
|
|
246
256
|
params: {
|
|
247
|
-
...
|
|
257
|
+
...filter,
|
|
248
258
|
page: this.page,
|
|
249
259
|
size: this.size,
|
|
250
260
|
sort: this.sorting
|
|
251
261
|
}
|
|
252
262
|
});
|
|
253
|
-
this.
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
263
|
+
if (this.oldFormat) {
|
|
264
|
+
this.items = data;
|
|
265
|
+
this.page = Number(headers['x-page'] ?? 1);
|
|
266
|
+
this.total = Number(headers['x-count'] ?? 0);
|
|
267
|
+
this.size = Number(headers['x-size'] ?? 20);
|
|
268
|
+
} else {
|
|
269
|
+
this.items = data[this.itemsKey];
|
|
270
|
+
this.page = data.meta.page;
|
|
271
|
+
this.total = data.meta.total;
|
|
272
|
+
this.size = data.meta.size;
|
|
273
|
+
}
|
|
257
274
|
});
|
|
258
275
|
this.loadingData = false;
|
|
259
276
|
this.$emit('loaded', this.filter);
|
|
@@ -278,6 +295,7 @@ class itfView extends Vue {
|
|
|
278
295
|
|
|
279
296
|
updatePage (val) {
|
|
280
297
|
this.page = val;
|
|
298
|
+
this.selectedIds = [];
|
|
281
299
|
this.setPanelPayload({ page: val });
|
|
282
300
|
this.loadData();
|
|
283
301
|
}
|
|
@@ -285,32 +303,38 @@ class itfView extends Vue {
|
|
|
285
303
|
updateSizePerPage (val) {
|
|
286
304
|
this.page = 1;
|
|
287
305
|
this.size = val;
|
|
306
|
+
this.selectedIds = [];
|
|
288
307
|
this.setPanelPayload({ page: 1, size: val });
|
|
289
308
|
this.loadData();
|
|
290
309
|
localStorage.setItem('sizePerPage', val);
|
|
291
310
|
}
|
|
292
311
|
|
|
312
|
+
updateTabs(val) {
|
|
313
|
+
this.setPanelPayload({ tab: val });
|
|
314
|
+
}
|
|
315
|
+
|
|
293
316
|
setPanelPayload(payload) {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
317
|
+
this.panel.setPayload(assignWithoutUndefined(this.panel.getPayload(), payload));
|
|
318
|
+
|
|
319
|
+
function assignWithoutUndefined(...sources) {
|
|
320
|
+
const target = {};
|
|
321
|
+
sources.forEach(source => {
|
|
322
|
+
if (source && typeof source === 'object') {
|
|
323
|
+
Object.entries(source).forEach(([key, value]) => {
|
|
324
|
+
if (value !== undefined) {
|
|
325
|
+
target[key] = value;
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
return target;
|
|
331
|
+
}
|
|
309
332
|
}
|
|
310
333
|
|
|
311
334
|
onFilterSet(filter) {
|
|
312
335
|
this.page = 1;
|
|
313
|
-
|
|
336
|
+
this.selectedIds = [];
|
|
337
|
+
this.setPanelPayload({ ...filter, page: 1 });
|
|
314
338
|
this.loadData();
|
|
315
339
|
}
|
|
316
340
|
|