@itfin/components 1.2.96 → 1.2.98

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.
@@ -6,22 +6,38 @@
6
6
  <div class="line"></div>
7
7
  </div>
8
8
 
9
- <div data-test="table-group-wrapper" class="table-group-wrapper" :style="`--row-count: ${isShowTable ? rows.length : 0}`">
9
+ <div data-test="table-group-wrapper" class="table-group-wrapper flex-grow-1 w-100 d-block"
10
+ :style="`--row-count: ${isShowTable ? rows.length : 0}`">
10
11
  <div class="">
11
- <div data-test="table-group" class="position-relative me-4">
12
- <div group="tablegroups" class="draggable-item" data-draggable-mirror="{&quot;xAxis&quot;:false}">
13
- <div class="table-row-template d-flex align-items-stretch" style="height: var(--group-title-height)">
12
+ <div data-test="table-group" class="position-relative">
13
+ <itf-table-header
14
+ v-if="showHeader"
15
+ :columns="visibleColumns"
16
+ @sort:columns="onColumnsSorted"
17
+ :column-resizing="columnResizing"
18
+ :column-sorting="columnSorting"
19
+ :show-add-column="showAddColumn"
20
+ :row-height="rowHeight"
21
+ @update:columns="$emit('update:columns', $event)"
22
+ @add-column="$emit('add-column', $event)"
23
+ />
24
+
25
+ <div group="tablegroups" class="draggable-item"
26
+ data-draggable-mirror="{&quot;xAxis&quot;:false}">
27
+ <div class="table-row-template d-flex align-items-stretch"
28
+ style="height: var(--group-title-height)">
14
29
  <div class="shadow-area"></div>
15
- <div class="header-wrapper drag-handle">
16
- <div class="header-content tw-sticky tw-flex tw-items-center tw-gap-5 tw-px-4">
30
+ <div class="header-wrapper" v-drag-handle>
31
+ <div class="header-content position-sticky d-flex align-items-center">
17
32
  <a href="" class="collapse-arrow" @click.prevent="toggleGroup">
18
- <itf-icon :name="isShowTable ? 'chevron_down' : 'chevron_right'" />
33
+ <itf-icon :name="isShowTable ? 'chevron_down' : 'chevron_right'"/>
19
34
  </a>
20
- <span class="d-flex align-items-center line-overflow group-header-value" data-test="group-value-group-label-value">
21
- <span title="To Do" class="badge text-decoration-none" style="background-color: #FFA2A2; color: #4C4E69;">To Do</span>
35
+ <span class="d-flex align-items-center line-overflow group-header-value"
36
+ data-test="group-value-group-label-value">
37
+ {{ title }}
22
38
  </span>
23
39
  <div data-test="table-group-item-count" class="table-group-item-count">
24
- {{rows.length}}
40
+ {{ rows.length }}
25
41
  </div>
26
42
  </div>
27
43
  </div>
@@ -29,80 +45,91 @@
29
45
  </div>
30
46
 
31
47
  <!-- Сама таблиця -->
32
- <div v-if="isShowTable" class="table-view-body">
33
- <itf-table-header :columns="columns" />
34
- <itf-table-body :rows="rows" :columns="columns">
48
+ <div v-if="isShowTable">
49
+ <itf-table-body
50
+ :rows="rows"
51
+ :columns="visibleColumns"
52
+ :row-height="rowHeight"
53
+ :show-add-column="showAddColumn">
35
54
  <template v-for="(_, name) in $slots" #[name]="slotData">
36
- <slot :name="name" v-bind="slotData || {}" />
55
+ <slot :name="name" v-bind="slotData || {}"/>
37
56
  </template>
38
57
  <template v-for="(_, name) in $scopedSlots" #[name]="slotData">
39
- <slot :name="name" v-bind="slotData || {}" />
58
+ <slot :name="name" v-bind="slotData || {}"/>
40
59
  </template>
41
60
  </itf-table-body>
42
61
  </div>
43
62
 
44
63
  <!-- Лінія додати нову -->
45
- <div v-if="isShowTable && addNewRows" class="table-row-template d-flex align-items-stretch">
64
+ <div v-if="isShowTable && addNewRows"
65
+ class="table-row-template d-flex align-items-stretch">
46
66
  <div class="shadow-area"></div>
47
- <a href="" data-test="table-add-new-item" class="d-flex align-items-center flex-grow-1 table-add-new-item">
67
+ <a href="" data-test="table-add-new-item"
68
+ class="d-flex align-items-center flex-grow-1 table-add-new-item">
48
69
  <span class="d-sticky d-flex align-items-center px-2">
49
- <itf-icon name="plus" />
70
+ <itf-icon name="plus"/>
50
71
  <span>Add new row</span>
51
72
  </span>
52
73
  </a>
53
74
  </div>
54
75
 
55
76
  <!-- Групування -->
56
- <div v-if="showGrouping"
57
- class="table-row-template d-flex align-items-stretch tw-h-[var(--table-small-row-size)] table-summary">
58
- <div class="tw-bg-light dark:tw-bg-light-invert shadow-area"></div>
59
- <div class="d-flex tw-flex-row align-items-center tw-ml-[var(--indicator-area-width)]"><span
60
- data-v-54c5481c="" data-column="0" class="tw-relative line-overflow"
61
- style="width: 400px;"><a href=""
62
- class="context-menu-toggle tw-w-full tw-text-gray dark:tw-text-gray-invert tw-text-sm tw-flex tw-pr-3 tw-flex tw-items-stretch tw-justify-end"
63
- data-v-54c5481c=""><span data-v-016abbf7=""
64
- data-test="summary-column"
65
- data-attribute-id="621b5429-3de2-4731-979f-ef0e0c974a6e"
66
- class="invisible-summary tw-flex tw-items-center tw-justify-end tw-flex-auto"><span
67
- data-v-016abbf7="" class="summary-placeholder hbox tw-items-center tw-justify-center">
68
- Summary
69
- <i data-v-016abbf7=""
70
- class="tw-ml-2 tw-text-gray dark:tw-text-gray-invert ic-arrow-down"></i></span></span>
71
- <!----></a></span><span data-v-54c5481c="" data-column="1"
72
- class="tw-relative line-overflow" style="width: 240px;"><a
73
- href=""
74
- class="context-menu-toggle tw-w-full tw-text-gray dark:tw-text-gray-invert tw-text-sm tw-flex tw-pr-3 tw-flex tw-items-stretch tw-justify-end"
75
- data-v-54c5481c=""><span data-v-016abbf7="" data-test="summary-column"
76
- data-attribute-id="afaaafd3-6f27-470c-9f85-4f0312eaefc0"
77
- class="invisible-summary tw-flex tw-items-center tw-justify-end tw-flex-auto visible-summary"><span
78
- data-v-016abbf7=""><span data-v-016abbf7="" class="summary-placeholder tw-mr-2">
79
- Earliest:
80
- </span> <span data-v-016abbf7="">
81
- Jun 28, 2023
82
- </span></span></span> <!----></a></span><span data-v-54c5481c="" data-column="2"
83
- class="tw-relative line-overflow"
84
- style="width: 240px;"><a href=""
85
- class="context-menu-toggle tw-w-full tw-text-gray dark:tw-text-gray-invert tw-text-sm tw-flex tw-pr-3 tw-flex tw-items-stretch tw-justify-end"
86
- data-v-54c5481c=""><span
87
- data-v-016abbf7="" data-test="summary-column"
88
- data-attribute-id="0c545783-9fb4-4105-9558-9b105415bb07"
89
- class="invisible-summary tw-flex tw-items-center tw-justify-end tw-flex-auto"><span
90
- data-v-016abbf7="" class="summary-placeholder hbox tw-items-center tw-justify-center">
91
- Summary
92
- <i data-v-016abbf7=""
93
- class="tw-ml-2 tw-text-gray dark:tw-text-gray-invert ic-arrow-down"></i></span></span>
94
- <!----></a></span><span data-v-54c5481c="" data-column="3"
95
- class="tw-relative line-overflow" style="width: 120px;"><a
96
- href=""
97
- class="context-menu-toggle tw-w-full tw-text-gray dark:tw-text-gray-invert tw-text-sm tw-flex tw-pr-3 tw-flex tw-items-stretch tw-justify-end"
98
- data-v-54c5481c=""><span data-v-016abbf7="" data-test="summary-column"
99
- data-attribute-id="b3935a97-9dc6-49bc-ae6b-767f3d88b86e"
100
- class="invisible-summary tw-flex tw-items-center tw-justify-end tw-flex-auto"><span
101
- data-v-016abbf7="" class="summary-placeholder hbox tw-items-center tw-justify-center">
102
- Summary
103
- <i data-v-016abbf7=""
104
- class="tw-ml-2 tw-text-gray dark:tw-text-gray-invert ic-arrow-down"></i></span></span>
105
- <!----></a></span></div>
77
+ <div v-if="showSummary" class="table-row-template d-flex align-items-stretch table-summary">
78
+ <div class="shadow-area"></div>
79
+
80
+ <div class="table-summary-columns d-flex tw-flex-row align-items-center">
81
+ <span
82
+ v-for="(column, n) in visibleColumns"
83
+ :key="n"
84
+ :data-column="n"
85
+ class="table-summary-column position-relative line-overflow"
86
+ :style="`width: ${column.width}px;`">
87
+ <itf-dropdown text>
88
+ <template #button>
89
+ <span data-test="summary-column" class="invisible-summary d-flex align-items-center justify-content-end flex-auto">
90
+ <span class="summary-placeholder align-items-center justify-content-center">
91
+ Summary
92
+ <itf-icon name="chevron_down" />
93
+ </span>
94
+ </span>
95
+ </template>
96
+
97
+ <ul class="dropdown-menu show ps-0" aria-labelledby="dropdownMenuOffset">
98
+ <li v-if="column.sortable">
99
+ <a class="dropdown-item d-flex align-items-center" href="javascript:;">
100
+ <itf-icon name="arrow_up" :size="16" class="me-1" />
101
+ Sort By Asc
102
+ </a>
103
+ </li>
104
+ <li v-if="column.sortable">
105
+ <a class="dropdown-item d-flex align-items-center" href="javascript:;">
106
+ <itf-icon name="arrow_down" :size="16" class="me-1" />
107
+ Sort By Desc
108
+ </a>
109
+ </li>
110
+ <li v-if="column.groupable">
111
+ <a class="dropdown-item d-flex align-items-center" href="javascript:;">
112
+ <itf-icon name="episodes" :size="16" class="me-1" />
113
+ Group By
114
+ </a>
115
+ </li>
116
+ <li>
117
+ <a class="dropdown-item d-flex align-items-center" href="javascript:;" @click="togglePinned(n)">
118
+ <itf-icon :name="column.pinned ? 'checkbox_checked' : 'checkbox_empty'" :size="16" class="me-1" />
119
+ <span v-if="column.pinned">Unpin Column</span>
120
+ <span v-else>Pin Column</span>
121
+ </a>
122
+ </li>
123
+ <li>
124
+ <a class="dropdown-item d-flex align-items-center" href="javascript:;" @click="hideColumn(n)">
125
+ <itf-icon name="eye_no" :size="16" class="me-1" />
126
+ Hide
127
+ </a>
128
+ </li>
129
+ </ul>
130
+ </itf-dropdown>
131
+ </span>
132
+ </div>
106
133
  </div>
107
134
  </div>
108
135
  </div>
@@ -113,9 +140,9 @@
113
140
  <style lang="scss">
114
141
  .itf-table-group {
115
142
  --group-title-height: 40px;
116
- --table-small-row-size: 36px;
117
143
  --table-row-height: 36px;
118
- --shadow-area-width: 45px;
144
+ --table-small-row-size: var(--table-row-height);
145
+ --shadow-area-width: 2px;
119
146
  --indicator-area-width: 38px;
120
147
 
121
148
  flex-direction: column;
@@ -138,7 +165,7 @@
138
165
 
139
166
  .table-group-wrapper {
140
167
  display: flex;
141
- height: calc(var(--group-title-height) + var(--table-small-row-size)*3 + var(--row-count)*var(--table-row-height));
168
+ height: calc(var(--group-title-height) + var(--table-small-row-size) * 1 + var(--row-count) * var(--table-row-height));
142
169
  }
143
170
 
144
171
  .shadow-area {
@@ -152,16 +179,18 @@
152
179
  position: -webkit-sticky;
153
180
  position: sticky;
154
181
  left: 0;
155
- background: #fff;
156
- border-right: 1px solid rgb(238, 238, 238);
182
+ background: var(--bs-body-bg);
183
+ border-right: 1px solid var(--bs-border-color);
157
184
  }
185
+
158
186
  .header-wrapper:not(.collapsed *) {
159
187
  flex-grow: 1;
160
- border-bottom-right-radius: 0!important;
161
- border-bottom-left-radius: 0!important;
188
+ border-bottom-right-radius: 0 !important;
189
+ border-bottom-left-radius: 0 !important;
162
190
  }
191
+
163
192
  .header-wrapper {
164
- background-color: rgb(218 218 218 / 1);
193
+ background-color: var(--bs-body-bg);
165
194
  left: var(--shadow-area-width);
166
195
  align-items: center;
167
196
  display: flex;
@@ -169,8 +198,12 @@
169
198
  position: sticky;
170
199
  border-radius: 0.1875rem;
171
200
  border-bottom-width: 1px;
201
+ border-bottom-style: solid;
202
+ font-weight: 500;
203
+ font-size: 1.25rem;
172
204
  border-color: rgb(238 238 238 / 1);
173
205
  }
206
+
174
207
  .header-content:not(.draggable-mirror *) {
175
208
  left: var(--shadow-area-width);
176
209
  padding-left: 0.75rem;
@@ -180,32 +213,39 @@
180
213
  position: sticky;
181
214
  display: flex;
182
215
  }
216
+
183
217
  .table-group-item-count {
184
- padding-top: 0.125rem;
185
- padding-bottom: 0.125rem;
186
- padding-left: 0.5rem;
187
- padding-right: 0.5rem;
218
+ padding: 0.125rem 0.5rem;
188
219
  background-color: rgb(250 251 252 / 1);
189
220
  border-radius: 0.1875rem;
221
+ font-weight: normal;
222
+ font-size: 1rem;
190
223
  }
224
+
191
225
  .table-view-wrapper .vue-recycle-scroller__item-wrapper {
192
226
  overflow: visible;
193
227
  }
228
+
194
229
  .vue-recycle-scroller.direction-vertical .vue-recycle-scroller__item-wrapper {
195
230
  width: 100%;
196
231
  }
232
+
197
233
  .table-view-wrapper .vue-recycle-scroller__item-wrapper {
198
234
  overflow: visible;
199
235
  }
236
+
200
237
  .vue-recycle-scroller.ready .vue-recycle-scroller__item-view {
201
238
  position: absolute;
202
239
  top: 0;
203
240
  left: 0;
204
241
  will-change: transform;
242
+ width: 100%;
205
243
  }
244
+
206
245
  .table-row-template {
207
246
  height: var(--table-small-row-size);
208
247
  }
248
+
209
249
  .table-add-new-item {
210
250
  border-right: 1px solid rgb(238 238 238 / 1);
211
251
  border-bottom: 1px solid rgb(238 238 238 / 1);
@@ -215,10 +255,32 @@
215
255
  position: sticky;
216
256
  }
217
257
  }
258
+
259
+ .table-summary {
260
+ .shadow-area {
261
+ border-right: 0;
262
+ min-width: var(--table-min-width);
263
+ }
264
+ .table-summary-columns {
265
+ padding-right: .5rem;
266
+ text-align: right;
267
+ }
268
+ .table-summary-column {
269
+ opacity: 0.05;
270
+ font-size: .85rem;
271
+ padding-right: .25rem;
272
+
273
+ &:hover {
274
+ opacity: 1;
275
+ }
276
+ }
277
+ }
218
278
  }
219
279
  </style>
220
280
  <script>
221
- import {Vue, Component, Prop, PropSync} from 'vue-property-decorator';
281
+ import sortBy from 'lodash/sortBy';
282
+ import {Vue, Component, Prop} from 'vue-property-decorator';
283
+ import itfDropdown from '../dropdown/Dropdown.vue';
222
284
  import itfButton from '../button/Button.vue';
223
285
  import itfIcon from '../icon/Icon.vue';
224
286
  import itfTableBody from './TableBody.vue';
@@ -230,17 +292,45 @@ export default @Component({
230
292
  itfButton,
231
293
  itfIcon,
232
294
  itfTableBody,
295
+ itfDropdown,
233
296
  itfTableHeader
234
297
  }
235
298
  })
236
299
  class itfTableGroup extends Vue {
237
300
  @Prop() columns;
238
301
  @Prop() rows;
302
+ @Prop() title;
239
303
  @Prop(Boolean) showGrouping;
304
+ @Prop(Boolean) showSummary;
240
305
  @Prop(Boolean) addNewRows;
306
+ @Prop(Boolean) columnSorting;
307
+ @Prop(Boolean) columnResizing;
308
+ @Prop(Boolean) showAddColumn;
309
+ @Prop(Boolean) showHeader;
310
+ @Prop({type: Number, default: 40}) rowHeight;
241
311
 
242
312
  isShowTable = true;
243
313
 
314
+ get visibleColumns() {
315
+ let list = this.columns;
316
+ list = sortBy(list, (column) => column.pinned ? 0 : 1);
317
+ let left = 47;
318
+ const pinned = list.filter((column) => column.pinned && column.visible !== false);
319
+ list = list.map((column, index) => {
320
+ const item = {...column};
321
+ item.left = (item.pinned && item.visible !== false) ? left : 0;
322
+ left = (item.pinned && item.visible !== false) ? left + column.width : left;
323
+ item.lastPinned = index === pinned.length - 1;
324
+ return item
325
+ });
326
+ return list;
327
+ }
328
+
329
+ onColumnsSorted(columns) {
330
+ this.$emit('sort:columns', columns);
331
+ this.$emit('update:columns', columns);
332
+ }
333
+
244
334
  toggleGroup() {
245
335
  this.isShowTable = !this.isShowTable;
246
336
  }