@itfin/components 1.3.56 → 1.3.58

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.3.56",
3
+ "version": "1.3.58",
4
4
  "author": "Vitalii Savchuk <esvit666@gmail.com>",
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -53,7 +53,7 @@ import { DateTime } from 'luxon';
53
53
  import tippy from 'tippy.js';
54
54
  import itfIcon from '../icon/Icon';
55
55
  import itfDatePickerInline from './DatePickerInline.vue';
56
- import itfButton from "@/components/button/Button.vue";
56
+ import itfButton from "../button/Button.vue";
57
57
 
58
58
  export default @Component({
59
59
  name: 'itfMonthPicker',
@@ -1,40 +1,70 @@
1
1
  <template>
2
2
 
3
- <nav aria-label="Page navigation example">
4
- <ul class="pagination itf-pagination px-3">
5
- <li
6
- v-for="(page, n) in pagesArr"
7
- :key="n"
8
- class="page-item"
9
- :class="{'active': page.current, 'disabled': !page.active && !page.current }"
3
+ <nav aria-label="Page navigation example" class="d-flex justify-content-between align-items-center">
4
+ <div class="d-flex gap-2 align-items-center">
5
+ <ul class="pagination itf-pagination ps-3 mb-0">
6
+ <li
7
+ v-for="(page, n) in pagesArr"
8
+ :key="n"
9
+ class="page-item"
10
+ :class="{'active': page.current, 'disabled': !page.active && !page.current }"
11
+ >
12
+ <a v-if="page.type === 'prev'" href="" class="page-link" :aria-label="$t('components.pagination.previous')" @click.prevent="onPage(page.number)">
13
+ <itf-icon name="chevron_left" aria-hidden="true" />
14
+ <span class="sr-only">{{$t('components.pagination.previous')}}</span>
15
+ </a>
16
+ <a v-else-if="page.type === 'first'" class="page-link" href="" @click.prevent="onPage(page.number)">{{page.number}}</a>
17
+ <a v-else-if="page.type === 'page'" class="page-link" href="" @click.prevent="onPage(page.number)">{{page.number}}</a>
18
+ <a v-else-if="page.type === 'last'" class="page-link" href="" @click.prevent="onPage(page.number)">{{page.number}}</a>
19
+ <span v-else-if="page.type === 'more'" class="page-link">&hellip;</span>
20
+ <a v-if="page.type === 'next'" href="" class="page-link" :aria-label="$t('components.pagination.previous')" @click.prevent="onPage(page.number)">
21
+ <span class="sr-only">{{$t('components.pagination.next')}}</span>
22
+ <itf-icon name="chevron_right" aria-hidden="true" />
23
+ </a>
24
+ </li>
25
+ </ul>
26
+ <!--div>
27
+ 1-25 of {{length}} items
28
+ </div-->
29
+ </div>
30
+
31
+ <div class="d-flex gap-2 align-items-center">
32
+ <span>{{$t('components.pagination.itemsPerPage')}}</span>
33
+ <itf-dropdown
34
+ toggle
35
+ :button-options="{ secondary: true, small: true }"
36
+ v-if="showSize"
37
+ class="itf-pagination-select"
38
+ :value="size"
10
39
  >
11
- <a v-if="page.type === 'prev'" href="" class="page-link" aria-label="Previous" @click.prevent="onPage(page.number)">
12
- <itf-icon name="chevron_left" aria-hidden="true" />
13
- <span class="sr-only">Previous</span>
14
- </a>
15
- <a v-else-if="page.type === 'first'" class="page-link" href="" @click.prevent="onPage(page.number)">{{page.number}}</a>
16
- <a v-else-if="page.type === 'page'" class="page-link" href="" @click.prevent="onPage(page.number)">{{page.number}}</a>
17
- <a v-else-if="page.type === 'last'" class="page-link" href="" @click.prevent="onPage(page.number)">{{page.number}}</a>
18
- <span v-else-if="page.type === 'more'" class="page-link">&hellip;</span>
19
- <a v-if="page.type === 'next'" href="" class="page-link" aria-label="Next" @click.prevent="onPage(page.number)">
20
- <span class="sr-only">Next</span>
21
- <itf-icon name="chevron_right" aria-hidden="true" />
22
- </a>
23
- </li>
24
- </ul>
40
+ <template #button>
41
+ <span>{{size}}</span>
42
+ </template>
43
+ <div class="dropdown-item" v-for="option in perPageOptions" :key="option.value" @click="onPerPage(option.value)">
44
+ {{option.title}}
45
+ </div>
46
+ </itf-dropdown>
47
+ </div>
25
48
  </nav>
26
49
 
27
50
  </template>
28
51
  <script>
29
52
  import { Vue, Component, Model, Prop } from 'vue-property-decorator';
30
53
  import itfIcon from '../icon/Icon.vue';
54
+ import itfDropdown from "../dropdown/Dropdown.vue";
31
55
 
32
56
  const MIN_PAGES_BLOCKS = 2;
33
57
  const MAX_PAGES_BLOCKS = 6;
58
+ const PER_PAGE_OPTIONS = [
59
+ { title: '20', value: 20 },
60
+ { title: '50', value: 50 },
61
+ { title: '100', value: 100 }
62
+ ];
34
63
 
35
64
  export default @Component({
36
65
  name: 'itfPagination',
37
66
  components: {
67
+ itfDropdown,
38
68
  itfIcon
39
69
  }
40
70
  })
@@ -45,11 +75,17 @@ class itfPagination extends Vue {
45
75
  @Prop({ type: [String, Number] }) pages;
46
76
  @Prop({ type: [String, Number], default: MIN_PAGES_BLOCKS }) minBlocks;
47
77
  @Prop({ type: [String, Number], default: MAX_PAGES_BLOCKS }) maxBlocks;
78
+ @Prop({type: Array, default: () => PER_PAGE_OPTIONS}) perPageOptions;
79
+ @Prop(Boolean) showSize;
48
80
 
49
81
  onPage(page) {
50
82
  this.$emit('input', page);
51
83
  }
52
84
 
85
+ onPerPage(size) {
86
+ this.$emit('per-page', size);
87
+ }
88
+
53
89
  get pagesArr () {
54
90
  const pageSize = Number(this.size);
55
91
  const totalItems = Number(this.length);
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
 
3
- <div class="itf-table2 scrollable scrollable-x" :class="{'permanent-checkboxes': selectedIds.length}">
3
+ <div class="itf-table2 scrollable scrollable-x" :class="{'table-striped': striped, 'table-absolute': absolute, 'permanent-checkboxes': selectedIds.length}" :style="{ '--indicator-area-width': `${indicatorType === 'none' ? 1 : indicatorWidth}px` }">
4
4
  <itf-checkbox-group v-model="selectedIds">
5
5
  <template v-for="(group, index) in groups">
6
6
  <div class="table-view-body">
@@ -30,6 +30,11 @@
30
30
  :subrows-property="subrowsProperty"
31
31
  :indicator-type="indicatorType"
32
32
  :expanded-all="expandedAll"
33
+ :indicatorWidth="indicatorWidth"
34
+ :striped="striped"
35
+ :expanded-ids="expandedIds"
36
+ :css-property="cssProperty"
37
+ @update:expanded-ids="$emit('update:expanded-ids', $event)"
33
38
  @new="$emit('new', $event)"
34
39
  @add-column="$emit('add-column', $event)"
35
40
  >
@@ -47,7 +52,7 @@
47
52
 
48
53
  </template>
49
54
  <script>
50
- import { Vue, Component, Prop, Watch, ModelSync } from 'vue-property-decorator';
55
+ import { Vue, Component, Prop, Watch, ModelSync, PropSync } from 'vue-property-decorator';
51
56
  import itfCheckboxGroup from '../checkbox/CheckboxGroup.vue';
52
57
  import itfButton from '../button/Button.vue';
53
58
  import itfIcon from '../icon/Icon.vue';
@@ -73,11 +78,14 @@ class itfTable2 extends Vue {
73
78
  @Prop({ required: true, type: Array }) rows;
74
79
  @Prop({ type: String, default: null }) groupBy;
75
80
  @Prop({ type: String, default: null }) idProperty;
81
+ @Prop({ type: String, default: null }) cssProperty;
76
82
  @Prop({ type: String, default: null }) subrowsProperty;
83
+ @Prop({ default: 45 }) indicatorWidth;
77
84
  @Prop({ type: String, default: null, validator: (val) => ['order', 'checkbox', 'toggle', 'property'].includes(val) }) indicatorType;
78
85
  @Prop({ type: String, default: null }) stateName; // save state to storage
79
86
  @Prop({ type: Object, default: () => ({}) }) schema;
80
87
  @ModelSync('value', 'input', { type: Array, default: () => ([]) }) selectedIds;
88
+ @Prop({ type: Array, default: () => [] }) expandedIds;
81
89
  @Prop() currency;
82
90
  @Prop() currencies;
83
91
  @Prop(Boolean) addNewRows;
@@ -91,6 +99,8 @@ class itfTable2 extends Vue {
91
99
  @Prop(Boolean) noSelectAll;
92
100
  @Prop(Boolean) editable;
93
101
  @Prop(Boolean) expandedAll;
102
+ @Prop(Boolean) striped;
103
+ @Prop(Boolean) absolute;
94
104
 
95
105
  state = {
96
106
  selectedIds: [],
@@ -14,7 +14,10 @@
14
14
  :currencies="currencies"
15
15
  :indicatorType="indicatorType"
16
16
  :expanded-ids="expandedIds"
17
+ :striped="striped"
17
18
  :expanded-all="expandedAll"
19
+ :css-property="cssProperty"
20
+ @update:expanded-ids="$emit('update:expanded-ids', $event)"
18
21
  @row-click="$emit('row-click', $event)"
19
22
  @update="$emit('update', $event)"
20
23
  @toggle="onToggle"
@@ -164,7 +167,7 @@
164
167
  }
165
168
  </style>
166
169
  <script>
167
- import { Vue, Component, Prop } from 'vue-property-decorator';
170
+ import { Vue, Component, Prop, PropSync } from 'vue-property-decorator';
168
171
  import itfTableRows from './TableRows.vue';
169
172
 
170
173
  export default @Component({
@@ -182,17 +185,18 @@ class itfTableBody extends Vue {
182
185
  @Prop(Boolean) noSelectAll;
183
186
  @Prop(Boolean) editable;
184
187
  @Prop(Boolean) expandedAll;
188
+ @Prop(Boolean) striped;
185
189
  @Prop() selectedIds;
186
190
  @Prop() currency;
187
191
  @Prop() currencies;
192
+ @Prop() cssProperty;
188
193
  @Prop({ type: String, default: null }) indicatorType;
189
-
190
- expandedIds = [];
194
+ @Prop() expandedIds;
191
195
 
192
196
  onToggle(item) {
193
- this.expandedIds = this.expandedIds.includes(item[this.idProperty])
197
+ this.$emit('update:expanded-ids', this.expandedIds.includes(item[this.idProperty])
194
198
  ? this.expandedIds.filter((id) => id !== item[this.idProperty])
195
- : [...this.expandedIds, item[this.idProperty]];
199
+ : [...this.expandedIds, item[this.idProperty]]);
196
200
  }
197
201
  }
198
202
  </script>
@@ -43,6 +43,7 @@
43
43
  :no-column-menu="noColumnMenu"
44
44
  :no-select-all="noSelectAll"
45
45
  :selected-ids="selectedIds"
46
+ :indicatorType="indicatorType"
46
47
  @update:selectedIds="$emit('update:selectedIds', $event)"
47
48
  @update:columns="$emit('update:columns', $event)"
48
49
  @add-column="$emit('add-column', $event)"
@@ -65,7 +66,12 @@
65
66
  :selected-ids="selectedIds"
66
67
  :indicatorType="indicatorType"
67
68
  :expanded-all="expandedAll"
68
- :show-add-column="showAddColumn">
69
+ :striped="striped"
70
+ :show-add-column="showAddColumn"
71
+ :expanded-ids="expandedIds"
72
+ :css-property="cssProperty"
73
+ @update:expanded-ids="$emit('update:expanded-ids', $event)"
74
+ >
69
75
  <template v-for="(_, name) in $slots" #[name]="slotData">
70
76
  <slot :name="name" v-bind="slotData || {}"/>
71
77
  </template>
@@ -295,7 +301,7 @@ import get from 'lodash/get';
295
301
  import sortBy from 'lodash/sortBy';
296
302
  import uniq from "lodash/uniq";
297
303
  import { round } from "../../helpers/formatters";
298
- import {Vue, Component, Prop, Watch} from 'vue-property-decorator';
304
+ import {Vue, Component, Prop, Watch, PropSync} from 'vue-property-decorator';
299
305
  import itfDropdown from '../dropdown/Dropdown.vue';
300
306
  import itfButton from '../button/Button.vue';
301
307
  import itfIcon from '../icon/Icon.vue';
@@ -338,9 +344,13 @@ class itfTableGroup extends Vue {
338
344
  @Prop(Boolean) noSelectAll;
339
345
  @Prop(Boolean) editable;
340
346
  @Prop(Boolean) expandedAll;
347
+ @Prop(Boolean) striped;
348
+ @Prop() indicatorWidth;
349
+ @Prop() cssProperty;
341
350
  @Prop({ type: String, default: null }) indicatorType;
342
351
  @Prop({type: String, default: function() { return this.$t('components.table.new'); } }) newLabel;
343
352
  @Prop({type: Object, default: () => ({})}) schema;
353
+ @Prop() expandedIds;
344
354
 
345
355
  isShowTable = true;
346
356
  persistSummary = false;
@@ -348,7 +358,7 @@ class itfTableGroup extends Vue {
348
358
  get visibleColumns() {
349
359
  let list = this.columns;
350
360
  list = sortBy(list, (column) => column.index);
351
- let left = 57; // sum of first 2 cells
361
+ let left = 12 + (this.indicatorType === 'none' ? 1 : Number(this.indicatorWidth)); // sum of first 2 cells
352
362
  const pinned = list.filter((column) => column.pinned && column.visible !== false);
353
363
  list = list.map((column, index) => {
354
364
  const item = {...column};
@@ -357,7 +367,6 @@ class itfTableGroup extends Vue {
357
367
  item.lastPinned = index === pinned.length - 1;
358
368
  return item
359
369
  });
360
- console.info(list);
361
370
  return list;
362
371
  }
363
372
 
@@ -5,7 +5,7 @@
5
5
  <div accept-group="items" class="table-view-body-space" v-dropzone="{ payload: 0 }"></div>
6
6
  <div class="shadow-area"></div>
7
7
  <div class="table-view-header-value reserved sticky">
8
- <itf-checkbox v-if="visibleHeader && !noSelectAll" ungrouped value="all" v-model="selectAll" ref="selectAll" />
8
+ <itf-checkbox v-if="indicatorType !== 'none' && visibleHeader && !noSelectAll" ungrouped value="all" v-model="selectAll" ref="selectAll" />
9
9
  </div>
10
10
 
11
11
  <template v-for="(column, n) in visibleAttributes">
@@ -169,6 +169,7 @@ class itfTableHeader extends Vue {
169
169
  @Prop(Boolean) noColumnMenu;
170
170
  @Prop(Boolean) noSelectAll;
171
171
  @Prop(Boolean) editable;
172
+ @Prop() indicatorType;
172
173
 
173
174
  @Watch('selectedIds')
174
175
  @Watch('rows')
@@ -6,7 +6,7 @@
6
6
  group="items"
7
7
  data-test="table-item"
8
8
  class="table-view-item grouped draggable-item"
9
- :class="{'selected': selectedIds.includes(item[idProperty])}"
9
+ :class="{'selected': selectedIds.includes(item[idProperty]), [cssProperty && item[cssProperty]]: !!item[cssProperty]}"
10
10
  >
11
11
  <div class="table-row-template">
12
12
  <div accept-group="items" class="table-view-body-space"></div>
@@ -27,13 +27,15 @@
27
27
  <a href="" @click.prevent.stop="$emit('toggle', item)" v-else-if="indicatorType === 'toggle'">
28
28
  <template v-if="subrowsProperty && item[subrowsProperty] && item[subrowsProperty].length">
29
29
  <template v-if="item[subrowsProperty] && item[subrowsProperty].length && !isExpanded(item)">
30
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-right-fill" viewBox="0 0 16 16">
31
- <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
30
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plus-square" viewBox="0 0 16 16">
31
+ <path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/>
32
+ <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4"/>
32
33
  </svg>
33
34
  </template>
34
35
  <template v-else>
35
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-down-fill" viewBox="0 0 16 16">
36
- <path d="M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z"/>
36
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-dash-square" viewBox="0 0 16 16">
37
+ <path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/>
38
+ <path d="M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8"/>
37
39
  </svg>
38
40
  </template>
39
41
  </template>
@@ -100,6 +102,7 @@
100
102
  :level="level + 1"
101
103
  :expanded-ids="expandedIds"
102
104
  :expanded-all="expandedAll"
105
+ :css-property="cssProperty"
103
106
  @toggle="$emit('toggle', $event)"
104
107
  >
105
108
  <template v-for="(_, name) in $slots" #[name]="slotData">
@@ -149,12 +152,14 @@ class itfTableRows extends Vue {
149
152
  @Prop(Boolean) noSelectAll;
150
153
  @Prop(Boolean) editable;
151
154
  @Prop(Boolean) expandedAll;
155
+ @Prop(Boolean) striped;
152
156
  @Prop() selectedIds;
153
157
  @Prop() expandedIds;
154
158
  @Prop() currency;
155
159
  @Prop() currencies;
160
+ @Prop() cssProperty;
156
161
  @Prop({ type: Number, default: 0 }) level;
157
- @Prop({ type: String, default: null, validator: (val) => ['order', 'checkbox', 'toggle', 'property'].includes(val) }) indicatorType;
162
+ @Prop({ type: String, default: null, validator: (val) => ['none', 'order', 'checkbox', 'toggle', 'property'].includes(val) }) indicatorType;
158
163
 
159
164
  getValue(item, column) {
160
165
  return get(item, column.property);
@@ -183,7 +188,6 @@ class itfTableRows extends Vue {
183
188
 
184
189
  isExpanded(item) {
185
190
  const isExpanded = this.expandedIds.includes(item[this.idProperty]);
186
- console.info(isExpanded, this.expandedAll)
187
191
  return this.expandedAll ? !isExpanded : isExpanded;
188
192
  }
189
193
  }
@@ -2,15 +2,18 @@
2
2
  --itf-table-border-color: #e1e1e1;
3
3
  --itf-table-header-bg: #f8f8f8;
4
4
  --itf-table-selected-bg: #f0f0f0;
5
+ --itf-table-alt-bg: #f9f9f9;
6
+ //--itf-table-border-color: #e1e1e1;
7
+ //--itf-table-header-bg: #f9faf5;
8
+ //--itf-table-selected-bg: #cbd6f4;
9
+ --itf-table-header-bg: #f8f8f8;
5
10
  --itf-table-border-color: #dbddd1;
6
- --itf-table-header-bg: #f9faf5;
7
11
  --itf-table-hover-header-bg: var(--bs-tertiary-bg);
8
12
  --itf-table-hover-bg: #f2f2f2;
9
13
  --itf-table-bg: var(--bs-body-bg);
10
14
  --itf-table-min-width: 45px;
11
15
  --itf-table-input-border-color: #aaaba6;
12
16
  --itf-table-input-focus-border-color: #0028aa;
13
- --itf-table-selected-bg: #cbd6f4;
14
17
  --itf-table-header-subtitle-color: #aeafaa;
15
18
  --itf-table-summary-text: var(--bs-tertiary-color);
16
19
 
@@ -40,6 +43,18 @@ body[data-theme="dark"] {
40
43
  overflow-x: scroll;
41
44
  padding-right: 4px;
42
45
  }
46
+ &.table-absolute {
47
+ position: absolute;
48
+ left: 0;
49
+ top: 0;
50
+ right: 0;
51
+ bottom: 0;
52
+ }
53
+ &.table-striped {
54
+ .table-view-item:nth-child(odd) {
55
+ --itf-table2-row-bg: var(--itf-table-alt-bg);
56
+ }
57
+ }
43
58
 
44
59
  &__header {
45
60
  background-color: var(--itf-table-header-bg);
@@ -205,11 +220,8 @@ body[data-theme="dark"] {
205
220
 
206
221
  background-color: var(--itf-table2-row-bg);
207
222
 
208
- &.selected {
209
- --itf-table2-row-bg: var(--itf-table-selected-bg);
210
- }
211
- &:hover {
212
- --itf-table2-row-bg: var(--itf-table-selected-bg);
223
+ &.selected, &:hover {
224
+ --itf-table2-row-bg: var(--itf-table-selected-bg) !important;
213
225
  }
214
226
 
215
227
  .indicator {
package/src/locales/en.js CHANGED
@@ -120,5 +120,10 @@ module.exports = {
120
120
  calculateCountNotEmpty: 'Count not empty',
121
121
  calculatePercentEmpty: 'Percent empty',
122
122
  calculatePercentNotEmpty: 'Percent not empty',
123
+ },
124
+ pagination: {
125
+ itemsPerPage: 'Items per page',
126
+ previous: 'Previous',
127
+ next: 'Next'
123
128
  }
124
129
  };
package/src/locales/uk.js CHANGED
@@ -97,6 +97,11 @@ module.exports = {
97
97
  copyToClipboard: {
98
98
  copyingToClipboardWasSuccessful: 'Скопійовано в буфер',
99
99
  },
100
+ pagination: {
101
+ itemsPerPage: 'К-ть на сторінці',
102
+ previous: 'Попередня',
103
+ next: 'Наступна',
104
+ },
100
105
  table: {
101
106
  new: 'Додати',
102
107
  noResults: 'Немає записів',