@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itfin/components",
3
- "version": "1.4.8",
3
+ "version": "1.4.10",
4
4
  "author": "Vitalii Savchuk <esvit666@gmail.com>",
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -42,6 +42,7 @@ $border-radius: $vs-border-radius;
42
42
  margin-right: -9px;
43
43
  align-items: center;
44
44
  padding: 1px 0 0;
45
+ min-width: 33px;
45
46
 
46
47
  .itf-button {
47
48
  margin: -0.25rem 0;
@@ -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 === 'period') {
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 === 'period') {
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 === 'period') {
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
- this.saveTableState();
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
- v-model="currentTab"
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 { Vue, ModelSync, Component, Prop, Inject } from 'vue-property-decorator';
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: 'table' }) tab;
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
- get currentTab() {
180
- return this.tab;
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
- set currentTab(val) {
184
- this.$emit('update:tab', val);
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
- // const defaultSize = localStorage.getItem('sizePerPage') ?? 20;
219
- //
220
- // const { page, size, sorting } = this.panel.getPayload() ?? {};
221
- // this.page = page ?? 1;
222
- // this.size = size ?? defaultSize;
223
- // this.sorting = sorting ?? this.defaultSorting;
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
- console.info('filter', this.filter)
245
- const res = await this.$axios.$get(this.endpoint, {
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
- ...this.filter,
257
+ ...filter,
248
258
  page: this.page,
249
259
  size: this.size,
250
260
  sort: this.sorting
251
261
  }
252
262
  });
253
- this.items = res[this.itemsKey];
254
- this.page = res.meta.page;
255
- this.total = res.meta.total;
256
- this.size = res.meta.size;
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
- // this.panel.setPayload(assignWithoutUndefined(this.panel.getPayload(), payload));
295
- //
296
- // function assignWithoutUndefined(...sources) {
297
- // const target = {};
298
- // sources.forEach(source => {
299
- // if (source && typeof source === 'object') {
300
- // Object.entries(source).forEach(([key, value]) => {
301
- // if (value !== undefined) {
302
- // target[key] = value;
303
- // }
304
- // });
305
- // }
306
- // });
307
- // return target;
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
- // this.setPanelPayload({ ...filter, page: 1 });
336
+ this.selectedIds = [];
337
+ this.setPanelPayload({ ...filter, page: 1 });
314
338
  this.loadData();
315
339
  }
316
340