@itfin/components 1.4.18 → 1.4.20
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
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
</div>
|
|
18
18
|
</slot>
|
|
19
19
|
<div class="d-flex gap-2">
|
|
20
|
-
|
|
20
|
+
<!--itf-button v-if="showFilter" default icon class="position-relative" @click="toggleFilters" :class="{'active': showFilters}">
|
|
21
21
|
<itf-icon new name="filter" />
|
|
22
22
|
<span v-if="activeFiltersCount" class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-primary">
|
|
23
23
|
{{activeFiltersCount}}
|
|
24
24
|
<span class="visually-hidden">active filters</span>
|
|
25
25
|
</span>
|
|
26
|
-
</itf-button
|
|
26
|
+
</itf-button-->
|
|
27
27
|
<slot name="after-filter-btn"></slot>
|
|
28
28
|
</div>
|
|
29
29
|
</div>
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
<div v-loading="loading || loadingData" class="flex-grow-1 w-100 d-flex flex-column">
|
|
4
4
|
<itf-filter-panel
|
|
5
5
|
:search-placeholder="searchPlaceholder"
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
search
|
|
7
|
+
show-filter
|
|
8
8
|
class="py-2 px-3"
|
|
9
9
|
:static-filters="filters"
|
|
10
10
|
:endpoint="filtersEndpoint"
|
|
@@ -40,6 +40,15 @@
|
|
|
40
40
|
</div>
|
|
41
41
|
</a>
|
|
42
42
|
</itf-dropdown>
|
|
43
|
+
<itf-dropdown v-if="downloadEndpoint" shadow append-to-context :button-options="{ default: true, small: true }" class="h-100" autoclose="outside">
|
|
44
|
+
<template #button>
|
|
45
|
+
<itf-icon name="download"/>
|
|
46
|
+
{{ $t('export') }}
|
|
47
|
+
</template>
|
|
48
|
+
<a v-for="(item, n) in getDownloadLinks()" target="_blank" :key="n" :href="item.link" class="dropdown-item">
|
|
49
|
+
{{item.title}}
|
|
50
|
+
</a>
|
|
51
|
+
</itf-dropdown>
|
|
43
52
|
|
|
44
53
|
<slot name="before-tabs"></slot>
|
|
45
54
|
|
|
@@ -60,7 +69,11 @@
|
|
|
60
69
|
</template>
|
|
61
70
|
</itf-filter-panel>
|
|
62
71
|
|
|
63
|
-
<
|
|
72
|
+
<div v-if="currentTab === 'list'" class="position-relative flex-grow-1">
|
|
73
|
+
<div class="position-absolute" style="top: 0; left: 0; right: 0; bottom: 0; overflow: auto;">
|
|
74
|
+
<slot name="list-view" :items="items" :loading="loading"></slot>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
64
77
|
<slot v-else-if="currentTab === 'board'" name="kanban-view"></slot>
|
|
65
78
|
<slot v-else-if="currentTab === 'calendar'" name="calendar-view"></slot>
|
|
66
79
|
<slot v-else name="table-view">
|
|
@@ -130,10 +143,12 @@ import itfTableBody from "../table/TableBody.vue";
|
|
|
130
143
|
import itfIcon from "../icon/Icon.vue";
|
|
131
144
|
import itfDropdown from "../dropdown/Dropdown.vue";
|
|
132
145
|
import itfSegmentedControl from '../segmented-control/SegmentedControl.vue';
|
|
146
|
+
import itfButton from '@itfin/components/src/components/button/Button.vue';
|
|
133
147
|
|
|
134
148
|
export default @Component({
|
|
135
149
|
name: 'itfView',
|
|
136
150
|
components: {
|
|
151
|
+
itfButton,
|
|
137
152
|
itfSegmentedControl,
|
|
138
153
|
itfDropdown,
|
|
139
154
|
itfIcon,
|
|
@@ -158,6 +173,7 @@ class itfView extends Vue {
|
|
|
158
173
|
@Prop(String) filtersEndpoint;
|
|
159
174
|
@Prop(String) itemsKey;
|
|
160
175
|
@Prop({ type: String, default: null }) groupBy;
|
|
176
|
+
@Prop({ type: String, default: null }) downloadEndpoint; // префікс апі для завантаження
|
|
161
177
|
@Prop({ type: String, default: 'totals' }) totalsKey;
|
|
162
178
|
@Prop(String) panelKey;
|
|
163
179
|
@Prop(String) stateName;
|
|
@@ -185,7 +201,7 @@ class itfView extends Vue {
|
|
|
185
201
|
filter = {};
|
|
186
202
|
loadingData = false;
|
|
187
203
|
activeIds = [];
|
|
188
|
-
tableColumns =
|
|
204
|
+
tableColumns = null;
|
|
189
205
|
totals = null;
|
|
190
206
|
|
|
191
207
|
@Watch('selectedIds', { deep: true, immediate: true })
|
|
@@ -195,6 +211,28 @@ class itfView extends Vue {
|
|
|
195
211
|
}
|
|
196
212
|
}
|
|
197
213
|
|
|
214
|
+
getDownloadLinks() {
|
|
215
|
+
const state = this.$refs.table ? this.$refs.table.getTableState() : null;
|
|
216
|
+
const filter = this.filter;
|
|
217
|
+
const sorting = this.sorting;
|
|
218
|
+
const filterableColumnsNames = (state?.columns ?? []).filter(column => column.visible).map(column => column.property);
|
|
219
|
+
|
|
220
|
+
const filterWithValue = Object.fromEntries(Object.entries(filter).filter(([_, value]) => typeof value !== 'undefined'));
|
|
221
|
+
const params = {
|
|
222
|
+
...filterWithValue,
|
|
223
|
+
sort: sorting
|
|
224
|
+
};
|
|
225
|
+
if (filterableColumnsNames.length) {
|
|
226
|
+
params.columns = filterableColumnsNames.join(',')
|
|
227
|
+
}
|
|
228
|
+
const xlsQueryParams = new URLSearchParams({ ...params, format: 'xlsx' }).toString();
|
|
229
|
+
const csvQueryParams = new URLSearchParams({ ...params, format: 'csv' }).toString();
|
|
230
|
+
return [
|
|
231
|
+
{ title: 'Excel (xlsx)', link: `${this.downloadEndpoint}?${xlsQueryParams}` },
|
|
232
|
+
{ title: 'Plain text (csv)', link: `${this.downloadEndpoint}?${csvQueryParams}` },
|
|
233
|
+
];
|
|
234
|
+
}
|
|
235
|
+
|
|
198
236
|
get currentTab() {
|
|
199
237
|
return this.tab;
|
|
200
238
|
}
|
|
@@ -362,7 +400,7 @@ class itfView extends Vue {
|
|
|
362
400
|
}
|
|
363
401
|
|
|
364
402
|
getTableState() {
|
|
365
|
-
return this.$refs.table.getTableState();
|
|
403
|
+
return this.$refs.table ? this.$refs.table.getTableState() : null;
|
|
366
404
|
}
|
|
367
405
|
}
|
|
368
406
|
</script>
|