@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itfin/components",
3
- "version": "1.4.18",
3
+ "version": "1.4.20",
4
4
  "author": "Vitalii Savchuk <esvit666@gmail.com>",
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -17,13 +17,13 @@
17
17
  </div>
18
18
  </slot>
19
19
  <div class="d-flex gap-2">
20
- <itf-button v-if="showFilter" default icon class="position-relative" @click="toggleFilters" :class="{'active': showFilters}">
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
- :search="currentTab !== 'list'"
7
- :show-filter="currentTab !== 'list'"
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
- <slot v-if="currentTab === 'list'" name="list-view"></slot>
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>