@itfin/components 1.3.100 → 1.4.1
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 +1 -1
- package/src/components/button/Button.vue +4 -2
- package/src/components/card/BentoCard.vue +70 -19
- package/src/components/card/BentoGrid.vue +21 -8
- package/src/components/filter/FilterAmountRange.vue +50 -42
- package/src/components/filter/FilterBadge.vue +27 -22
- package/src/components/filter/FilterFacetsList.vue +21 -17
- package/src/components/filter/FilterPanel.vue +143 -45
- package/src/components/filter/index.stories.js +0 -2
- package/src/components/form/Label.vue +19 -2
- package/src/components/icon/Icon.vue +4 -2
- package/src/components/icon/components/fi_fingerprint.vue +4 -0
- package/src/components/icon/components/nomi-ai.vue +6 -0
- package/src/components/icon/components/nomi-arrow-down.vue +4 -0
- package/src/components/icon/components/nomi-arrow-right-top.vue +4 -0
- package/src/components/icon/components/nomi-arrow-up.vue +4 -0
- package/src/components/icon/components/nomi-arrow_down.vue +4 -0
- package/src/components/icon/components/nomi-arrow_up.vue +4 -0
- package/src/components/icon/components/nomi-arrows.vue +7 -0
- package/src/components/icon/components/nomi-calendar-alt.vue +4 -0
- package/src/components/icon/components/nomi-calendar-alt2.vue +4 -0
- package/src/components/icon/components/nomi-calendar.vue +11 -0
- package/src/components/icon/components/nomi-card.vue +4 -0
- package/src/components/icon/components/nomi-clear.vue +4 -0
- package/src/components/icon/components/nomi-close.vue +5 -0
- package/src/components/icon/components/nomi-counterparty.vue +4 -0
- package/src/components/icon/components/nomi-dashboard.vue +4 -0
- package/src/components/icon/components/nomi-expand.vue +7 -0
- package/src/components/icon/components/nomi-export.vue +4 -0
- package/src/components/icon/components/nomi-eye-close.vue +4 -0
- package/src/components/icon/components/nomi-eye-open.vue +4 -0
- package/src/components/icon/components/nomi-eye.vue +4 -0
- package/src/components/icon/components/nomi-filter.vue +4 -0
- package/src/components/icon/components/nomi-help.vue +5 -0
- package/src/components/icon/components/nomi-hide.vue +4 -0
- package/src/components/icon/components/nomi-lock.vue +4 -0
- package/src/components/icon/components/nomi-logout.vue +5 -0
- package/src/components/icon/components/nomi-money.vue +4 -0
- package/src/components/icon/components/nomi-move-left.vue +4 -0
- package/src/components/icon/components/nomi-move-right.vue +4 -0
- package/src/components/icon/components/nomi-pen.vue +5 -0
- package/src/components/icon/components/nomi-person.vue +5 -0
- package/src/components/icon/components/nomi-pin.vue +7 -0
- package/src/components/icon/components/nomi-project.vue +4 -0
- package/src/components/icon/components/nomi-recurrence.vue +2 -0
- package/src/components/icon/components/nomi-repeat.vue +7 -0
- package/src/components/icon/components/nomi-report.vue +4 -0
- package/src/components/icon/components/nomi-scissors.vue +4 -0
- package/src/components/icon/components/nomi-settings.vue +4 -0
- package/src/components/icon/components/nomi-sort-asc.vue +7 -0
- package/src/components/icon/components/nomi-sort-desc.vue +7 -0
- package/src/components/icon/components/nomi-table-view.vue +4 -0
- package/src/components/icon/components/nomi-tag.vue +4 -0
- package/src/components/icon/components/nomi-target.vue +4 -0
- package/src/components/icon/components/nomi-text.vue +6 -0
- package/src/components/icon/components/nomi-transactions.vue +8 -0
- package/src/components/icon/components/nomi-trash.vue +4 -0
- package/src/components/icon/components/nomi-unpin.vue +7 -0
- package/src/components/icon/components/nomi-user.vue +5 -0
- package/src/components/icon/convert-icons.js +11 -0
- package/src/components/icon/icons.js +332 -286
- package/src/components/icon/new-icons/ai.svg +5 -0
- package/src/components/icon/new-icons/arrow-down.svg +3 -0
- package/src/components/icon/new-icons/arrow-right-top.svg +3 -0
- package/src/components/icon/new-icons/arrow-up.svg +3 -0
- package/src/components/icon/new-icons/arrow_down.svg +3 -0
- package/src/components/icon/new-icons/arrow_up.svg +3 -0
- package/src/components/icon/new-icons/arrows.svg +6 -0
- package/src/components/icon/new-icons/calendar-alt.svg +3 -0
- package/src/components/icon/new-icons/calendar-alt2.svg +3 -0
- package/src/components/icon/new-icons/calendar.svg +10 -0
- package/src/components/icon/new-icons/card.svg +3 -0
- package/src/components/icon/new-icons/clear.svg +3 -0
- package/src/components/icon/new-icons/close.svg +4 -0
- package/src/components/icon/new-icons/counterparty.svg +3 -0
- package/src/components/icon/new-icons/dashboard.svg +3 -0
- package/src/components/icon/new-icons/expand.svg +6 -0
- package/src/components/icon/new-icons/eye-close.svg +3 -0
- package/src/components/icon/new-icons/eye-open.svg +3 -0
- package/src/components/icon/new-icons/eye.svg +3 -0
- package/src/components/icon/new-icons/filter.svg +3 -0
- package/src/components/icon/new-icons/help.svg +4 -0
- package/src/components/icon/new-icons/hide.svg +3 -0
- package/src/components/icon/new-icons/logout.svg +4 -0
- package/src/components/icon/new-icons/money.svg +3 -0
- package/src/components/icon/new-icons/move-left.svg +3 -0
- package/src/components/icon/new-icons/move-right.svg +3 -0
- package/src/components/icon/new-icons/pen.svg +4 -0
- package/src/components/icon/new-icons/person.svg +4 -0
- package/src/components/icon/new-icons/pin.svg +6 -0
- package/src/components/icon/new-icons/project.svg +3 -0
- package/src/components/icon/new-icons/recurrence.svg +1 -0
- package/src/components/icon/new-icons/repeat.svg +6 -0
- package/src/components/icon/new-icons/report.svg +3 -0
- package/src/components/icon/new-icons/scissors.svg +3 -0
- package/src/components/icon/new-icons/settings.svg +3 -0
- package/src/components/icon/new-icons/sort-asc.svg +6 -0
- package/src/components/icon/new-icons/sort-desc.svg +6 -0
- package/src/components/icon/new-icons/table-view.svg +3 -0
- package/src/components/icon/new-icons/tag.svg +3 -0
- package/src/components/icon/new-icons/target.svg +3 -0
- package/src/components/icon/new-icons/text.svg +5 -0
- package/src/components/icon/new-icons/transactions.svg +7 -0
- package/src/components/icon/new-icons/trash.svg +3 -0
- package/src/components/icon/new-icons/unpin.svg +6 -0
- package/src/components/icon/new-icons/user.svg +4 -0
- package/src/components/modal/DeleteConfirmModal.vue +0 -2
- package/src/components/modal/ItemEditor.vue +1 -5
- package/src/components/pagination/Pagination.vue +3 -2
- package/src/components/pagination/Pagination2.vue +179 -0
- package/src/components/panels/Panel.vue +23 -7
- package/src/components/panels/PanelItemEdit.vue +62 -0
- package/src/components/panels/PanelLink.vue +26 -6
- package/src/components/panels/PanelList.vue +27 -26
- package/src/components/panels/helpers.spec.ts +27 -0
- package/src/components/panels/helpers.ts +37 -0
- package/src/components/popover/NoticePopout.vue +1 -1
- package/src/components/select/Select.vue +1 -1
- package/src/components/sortable/draggable.js +2 -1
- package/src/components/table/Table2.vue +37 -8
- package/src/components/table/TableBody.vue +10 -18
- package/src/components/table/TableGroup.vue +31 -12
- package/src/components/table/TableHeader.vue +118 -64
- package/src/components/table/TableRowToggle.vue +51 -0
- package/src/components/table/TableRows.vue +20 -29
- package/src/components/table/index.stories.js +22 -200
- package/src/components/table/table2.scss +237 -68
- package/src/components/text-field/MoneyField.vue +23 -21
- package/src/components/tree/TreeEditor.vue +615 -0
- package/src/components/view/View.vue +265 -0
- package/src/components/view/index.stories.js +588 -0
- package/src/helpers/formatters.js +14 -1
- package/src/helpers/tree/cdbl.js +32 -0
- package/src/helpers/tree/cint.js +43 -0
- package/src/helpers/tree/domDrag.js +911 -0
- package/src/helpers/tree/domFinds.js +20 -0
- package/src/helpers/tree/domGetPointFromEvent.js +53 -0
- package/src/helpers/tree/domIsClientXYIn.js +65 -0
- package/src/helpers/tree/domRemove.js +50 -0
- package/src/helpers/tree/evem.js +27 -0
- package/src/helpers/tree/genID.js +56 -0
- package/src/helpers/tree/isEle.js +28 -0
- package/src/helpers/tree/isestr.js +35 -0
- package/src/helpers/tree/isint.js +40 -0
- package/src/helpers/tree/isnbr.js +24 -0
- package/src/helpers/tree/isnum.js +38 -0
- package/src/helpers/tree/ispint.js +41 -0
- package/src/helpers/tree/isstr.js +27 -0
- package/src/helpers/tree.js +30 -0
- package/src/helpers/vuetifyColor.js +136 -0
- package/src/locales/en.js +17 -0
- package/src/locales/uk.js +17 -0
- package/src/components/table/TableRow.vue +0 -221
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
<div class="shadow-area"></div>
|
|
18
18
|
<div class="header-wrapper" :class="{'header-additional-column': showAddColumn}" @click.prevent="toggleGroup">
|
|
19
19
|
<a class="header-content position-sticky d-flex align-items-center">
|
|
20
|
-
<
|
|
20
|
+
<itf-button squircle icon small secondary class="collapse-arrow">
|
|
21
21
|
<itf-icon :name="isShowTable ? 'chevron_down' : 'chevron_right'"/>
|
|
22
|
-
</
|
|
23
|
-
<span class="d-flex align-items-center line-overflow group-header-value"
|
|
22
|
+
</itf-button>
|
|
23
|
+
<span class="d-flex align-items-center line-overflow group-header-value text-primary"
|
|
24
24
|
data-test="group-value-group-label-value">
|
|
25
25
|
<slot name="group-title" :rows="rows" :title="title">{{ title }}</slot>
|
|
26
26
|
</span>
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
:show-add-column="showAddColumn"
|
|
40
40
|
:show-actions="showActions"
|
|
41
41
|
:id-property="idProperty"
|
|
42
|
+
:sort-as-string="sortAsString"
|
|
42
43
|
:rows="rows"
|
|
43
44
|
:schema="schema"
|
|
44
45
|
:editable="editable"
|
|
45
|
-
:sort-as-string="sortAsString"
|
|
46
46
|
:no-column-menu="noColumnMenu"
|
|
47
47
|
:no-select-all="noSelectAll"
|
|
48
48
|
:selected-ids="selectedIds"
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
:sorting.sync="_sorting"
|
|
51
51
|
@update:selectedIds="$emit('update:selectedIds', $event)"
|
|
52
52
|
@update:columns="$emit('update:columns', $event)"
|
|
53
|
+
@filter="$emit('filter', $event)"
|
|
53
54
|
@add-column="$emit('add-column', $event)"
|
|
54
55
|
/>
|
|
55
56
|
</div>
|
|
@@ -61,10 +62,12 @@
|
|
|
61
62
|
@row-click="$emit('row-click', $event)"
|
|
62
63
|
:id-property="idProperty"
|
|
63
64
|
:subrows-property="subrowsProperty"
|
|
65
|
+
:divider-property="dividerProperty"
|
|
64
66
|
:rows="rows"
|
|
65
67
|
:editable="editable"
|
|
66
68
|
:currency="currency"
|
|
67
69
|
:currencies="currencies"
|
|
70
|
+
:sort-as-string="sortAsString"
|
|
68
71
|
:columns="visibleColumns"
|
|
69
72
|
:no-select-all="noSelectAll"
|
|
70
73
|
:selected-ids="selectedIds"
|
|
@@ -154,7 +157,7 @@
|
|
|
154
157
|
|
|
155
158
|
&.no-indicator {
|
|
156
159
|
.shadow-area + .table-view-header-value, .table-item-inner {
|
|
157
|
-
border-left:
|
|
160
|
+
border-left: var(--itf-table-border-base-width) solid var(--itf-table-border-color);
|
|
158
161
|
}
|
|
159
162
|
}
|
|
160
163
|
|
|
@@ -230,7 +233,7 @@
|
|
|
230
233
|
border-radius: 0;
|
|
231
234
|
}
|
|
232
235
|
&:hover {
|
|
233
|
-
background: var(--itf-table-hover-bg);
|
|
236
|
+
//background: var(--itf-table-hover-bg); // видно, що група не на всю ширину коли є нижній скролінг
|
|
234
237
|
}
|
|
235
238
|
}
|
|
236
239
|
|
|
@@ -239,7 +242,7 @@
|
|
|
239
242
|
}
|
|
240
243
|
.header-content:not(.draggable-mirror *) {
|
|
241
244
|
left: var(--shadow-area-width);
|
|
242
|
-
padding-left: 0.75rem;
|
|
245
|
+
//padding-left: 0.75rem;
|
|
243
246
|
padding-right: 0.75rem;
|
|
244
247
|
gap: 1rem;
|
|
245
248
|
align-items: center;
|
|
@@ -264,15 +267,18 @@
|
|
|
264
267
|
}
|
|
265
268
|
|
|
266
269
|
.table-add-new-item {
|
|
267
|
-
border-right:
|
|
268
|
-
border-
|
|
270
|
+
border-right:var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
|
|
271
|
+
border-left:var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
|
|
272
|
+
border-bottom: var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
|
|
269
273
|
outline: none;
|
|
274
|
+
border-bottom-left-radius: var(--itf-table-table-border-radius);
|
|
275
|
+
border-bottom-right-radius: var(--itf-table-table-border-radius);
|
|
270
276
|
|
|
271
277
|
& > span {
|
|
272
278
|
left: var(--shadow-area-width);
|
|
273
279
|
position: sticky;
|
|
274
280
|
padding-left: var(--shadow-area-width);
|
|
275
|
-
border-left:
|
|
281
|
+
//border-left: var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
|
|
276
282
|
height: 100%;
|
|
277
283
|
}
|
|
278
284
|
&:hover, &:active {
|
|
@@ -281,9 +287,20 @@
|
|
|
281
287
|
}
|
|
282
288
|
|
|
283
289
|
.sticky-group {
|
|
290
|
+
top: 0px;
|
|
284
291
|
position: sticky;
|
|
285
|
-
top: 0;
|
|
286
292
|
z-index: 10;
|
|
293
|
+
|
|
294
|
+
& > .draggable-item {
|
|
295
|
+
margin-bottom: 8px;
|
|
296
|
+
}
|
|
297
|
+
.collapse-arrow {
|
|
298
|
+
padding: 0;
|
|
299
|
+
|
|
300
|
+
&:after {
|
|
301
|
+
display: none;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
287
304
|
}
|
|
288
305
|
.table-summary {
|
|
289
306
|
.shadow-area {
|
|
@@ -344,6 +361,7 @@ class itfTableGroup extends Vue {
|
|
|
344
361
|
@Prop() title;
|
|
345
362
|
@Prop() idProperty;
|
|
346
363
|
@Prop() subrowsProperty;
|
|
364
|
+
@Prop() dividerProperty;
|
|
347
365
|
@Prop() currency;
|
|
348
366
|
@Prop() currencies;
|
|
349
367
|
@Prop() active;
|
|
@@ -364,6 +382,7 @@ class itfTableGroup extends Vue {
|
|
|
364
382
|
@Prop(Boolean) stickyHeader;
|
|
365
383
|
@Prop(Boolean) sortAsString;
|
|
366
384
|
@Prop() indicatorWidth;
|
|
385
|
+
@Prop() shadowWidth;
|
|
367
386
|
@Prop() cssProperty;
|
|
368
387
|
@PropSync('sorting') _sorting;
|
|
369
388
|
@Prop({ type: String, default: null }) indicatorType;
|
|
@@ -377,7 +396,7 @@ class itfTableGroup extends Vue {
|
|
|
377
396
|
get visibleColumns() {
|
|
378
397
|
let list = this.columns;
|
|
379
398
|
list = sortBy(list, (column) => column.index);
|
|
380
|
-
let left =
|
|
399
|
+
let left = Number(this.shadowWidth) + (this.indicatorType === 'none' ? 1 : Math.max(Number(this.indicatorWidth), 16)); // sum of first 2 cells
|
|
381
400
|
const pinned = list.filter((column) => column.pinned && column.visible !== false);
|
|
382
401
|
list = list.map((column, index) => {
|
|
383
402
|
const item = {...column};
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
data-test="table-header-column"
|
|
16
16
|
:data-column="n"
|
|
17
17
|
:data-id="column.Id"
|
|
18
|
-
:class="{'sticky': column.pinned, 'last-sticky-column': n === lastPinnedIndex, [`justify-content-${column.align || 'start'}`]: true}"
|
|
18
|
+
:class="{'sticky': column.pinned, 'active': sortColumnParams[column.property], 'last-sticky-column': n === lastPinnedIndex, [`justify-content-${column.align || 'start'}`]: true}"
|
|
19
19
|
class="table-view-header-value"
|
|
20
20
|
:style="`width: ${column.width}px; max-width: ${column.width}px; left: ${column.left}px;`">
|
|
21
21
|
<!-- Не треба видаляти колонки, бо вони потрібні для збереження ширини -->
|
|
@@ -29,30 +29,22 @@
|
|
|
29
29
|
<div v-if="visibleHeader" group="tablecolumns"
|
|
30
30
|
class="table-header"
|
|
31
31
|
@drop="reorderColumns"
|
|
32
|
-
v-drag-handle
|
|
33
32
|
v-draggable="{ handle: true, payload: { index: n, item: column }, mirror: {yAxis:false} }">
|
|
34
33
|
<itf-dropdown text append-to-body shadow ref="dropdown" class="w-100" :disabled="noColumnMenu">
|
|
35
34
|
<template #button>
|
|
36
|
-
<
|
|
37
|
-
<
|
|
38
|
-
{
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
<div class="itf-table2__header-title d-flex w-100 align-items-center" :title="getTitle(column.title)">
|
|
36
|
+
<itf-icon class="itf-table2__header-icon" new v-if="column.icon" :name="column.icon"></itf-icon>
|
|
37
|
+
<div class="flex-grow-1 w-100 itf-table2__title-container d-flex align-items-center" :class="{'justify-content-end': column.align === 'end'}">
|
|
38
|
+
<div class="itf-table2__title text-truncate">{{getTitle(column.title)}}</div>
|
|
39
|
+
<div v-if="column.prefix" class="itf-table2__subtitle text-truncate" v-text="column.prefix" />
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
<itf-icon v-if="sortColumnParams[column.property]" :name="sortColumnParams[column.property] === 'asc' ? 'sort-asc' : 'sort-desc'" new :size="20" class="ms-1" />
|
|
42
43
|
</template>
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
<a class="dropdown-item d-flex align-items-center" href="javascript:;" @click="sortBy(column, 'asc')">
|
|
46
|
-
<itf-icon name="arrow_up" :size="16" class="me-1" />
|
|
47
|
-
{{$t('components.table.sortAscending')}}
|
|
48
|
-
</a>
|
|
49
|
-
</div>
|
|
50
|
-
<div v-if="column.sortable">
|
|
51
|
-
<a class="dropdown-item d-flex align-items-center" href="javascript:;" @click="sortBy(column, 'desc')">
|
|
52
|
-
<itf-icon name="arrow_down" :size="16" class="me-1" />
|
|
53
|
-
{{$t('components.table.sortDescending')}}
|
|
54
|
-
</a>
|
|
44
|
+
<div class="dropdown-header">
|
|
45
|
+
{{$t('components.table.actions')}}
|
|
55
46
|
</div>
|
|
47
|
+
|
|
56
48
|
<div v-if="column.groupable">
|
|
57
49
|
<a class="dropdown-item d-flex align-items-center" href="javascript:;">
|
|
58
50
|
<itf-icon name="episodes" :size="16" class="me-1" />
|
|
@@ -60,19 +52,84 @@
|
|
|
60
52
|
</a>
|
|
61
53
|
</div>
|
|
62
54
|
<div>
|
|
63
|
-
<a class="dropdown-item d-flex align-items-center" href="javascript:;" @click="togglePinned(n)">
|
|
64
|
-
<itf-icon
|
|
55
|
+
<a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="togglePinned(n)">
|
|
56
|
+
<itf-icon v-if="column.pinned" name="pin" new />
|
|
57
|
+
<itf-icon v-else name="pin" new />
|
|
58
|
+
|
|
65
59
|
<span v-if="column.pinned">{{$t('components.table.unfreezeColumn')}}</span>
|
|
66
60
|
<span v-else>{{$t('components.table.freezeColumn')}}</span>
|
|
67
61
|
</a>
|
|
68
62
|
</div>
|
|
69
63
|
<div v-if="showAddColumn">
|
|
70
|
-
<a class="dropdown-item d-flex align-items-center" href="javascript:;" @click="hideColumn(n)">
|
|
71
|
-
<itf-icon name="
|
|
64
|
+
<a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="hideColumn(n)">
|
|
65
|
+
<itf-icon name="hide" new />
|
|
66
|
+
|
|
72
67
|
{{$t('components.table.hideColumn')}}
|
|
73
68
|
</a>
|
|
74
69
|
</div>
|
|
70
|
+
<div v-if="column.filtrable">
|
|
71
|
+
<a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="$emit('filter', column)">
|
|
72
|
+
<itf-icon name="filter" new />
|
|
73
|
+
|
|
74
|
+
{{$t('components.table.filter')}}
|
|
75
|
+
</a>
|
|
76
|
+
</div>
|
|
77
|
+
<div v-if="canMoveColumn(1, column)">
|
|
78
|
+
<a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="moveColumn(1, column)">
|
|
79
|
+
<itf-icon name="move-right" new />
|
|
80
|
+
|
|
81
|
+
{{$t('components.table.moveRight')}}
|
|
82
|
+
</a>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
<div v-if="canMoveColumn(-1, column)">
|
|
86
|
+
<a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="moveColumn(-1, column)">
|
|
87
|
+
<itf-icon name="move-left" new />
|
|
88
|
+
|
|
89
|
+
{{$t('components.table.moveLeft')}}
|
|
90
|
+
</a>
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
<template v-if="column.sortable">
|
|
94
|
+
<div class="dropdown-header">
|
|
95
|
+
{{$t('components.table.sorting')}}
|
|
96
|
+
</div>
|
|
97
|
+
<div>
|
|
98
|
+
<a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="sortBy(column, 'asc')">
|
|
99
|
+
<itf-icon name="sort-asc" new />
|
|
100
|
+
{{$t('components.table.sortAscending')}}
|
|
101
|
+
</a>
|
|
102
|
+
</div>
|
|
103
|
+
<div>
|
|
104
|
+
<a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="sortBy(column, 'desc')">
|
|
105
|
+
<itf-icon name="sort-desc" new />
|
|
106
|
+
{{$t('components.table.sortDescending')}}
|
|
107
|
+
</a>
|
|
108
|
+
</div>
|
|
109
|
+
</template>
|
|
75
110
|
</itf-dropdown>
|
|
111
|
+
<div v-if="columnSorting" v-drag-handle class="itf-table2__drag-column">
|
|
112
|
+
<svg width="35" height="23" viewBox="0 0 35 23" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
113
|
+
<g filter="url(#filter0_d_1081_25763)">
|
|
114
|
+
<rect x="4" y="2" width="27" height="15" rx="4" fill="#1A4A97"/>
|
|
115
|
+
<circle cx="23.5" cy="9.5" r="1.5" fill="white"/>
|
|
116
|
+
<circle cx="17.5" cy="9.5" r="1.5" fill="white"/>
|
|
117
|
+
<circle cx="11.5" cy="9.5" r="1.5" fill="white"/>
|
|
118
|
+
</g>
|
|
119
|
+
<defs>
|
|
120
|
+
<filter id="filter0_d_1081_25763" x="0" y="0" width="35" height="23" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
121
|
+
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
122
|
+
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
|
123
|
+
<feOffset dy="2"/>
|
|
124
|
+
<feGaussianBlur stdDeviation="2"/>
|
|
125
|
+
<feComposite in2="hardAlpha" operator="out"/>
|
|
126
|
+
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
|
127
|
+
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1081_25763"/>
|
|
128
|
+
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_1081_25763" result="shape"/>
|
|
129
|
+
</filter>
|
|
130
|
+
</defs>
|
|
131
|
+
</svg>
|
|
132
|
+
</div>
|
|
76
133
|
</div>
|
|
77
134
|
<div v-if="visibleHeader && n === sortedColumns.length - 1"
|
|
78
135
|
@enter="columnHighlightLast('enter')"
|
|
@@ -86,43 +143,6 @@
|
|
|
86
143
|
</div>
|
|
87
144
|
</template>
|
|
88
145
|
<div class="table-view-item-value extra flex-grow-1"></div>
|
|
89
|
-
<itf-dropdown v-if="showAddColumn && visibleHeader" ref="newDd" text append-to-context shadow autoclose="outside" class="table-header-add-column table-view-item-actions" data-test="table-header-add-column">
|
|
90
|
-
<template #button>
|
|
91
|
-
<itf-button icon small><span class="nom-gear"></span></itf-button>
|
|
92
|
-
</template>
|
|
93
|
-
|
|
94
|
-
<itf-sortable :value="sortedColumns" @input="onSortColumns">
|
|
95
|
-
<template v-for="(column, k) in sortedColumns">
|
|
96
|
-
<div :key="`column${k}`" class="d-flex align-items-center justify-content-between" :class="{'px-2 py-1': column.visible !== false}">
|
|
97
|
-
<template v-if="column.visible !== false">
|
|
98
|
-
<div class="d-flex justify-content-between flex-grow-1">
|
|
99
|
-
<div>
|
|
100
|
-
<span class="nom-grip-vertical"></span>
|
|
101
|
-
<span v-if="column.icon" :class="column.icon"></span>
|
|
102
|
-
{{getTitle(column.title)}}
|
|
103
|
-
</div>
|
|
104
|
-
<span v-if="column.pinned" class="nom-pin-fill"></span>
|
|
105
|
-
</div>
|
|
106
|
-
<a sortable-skip href="" class="text-decoration-none" @click.prevent="hideColumn(k)">
|
|
107
|
-
<span class="nom-trash"></span>
|
|
108
|
-
</a>
|
|
109
|
-
</template>
|
|
110
|
-
</div>
|
|
111
|
-
</template>
|
|
112
|
-
</itf-sortable>
|
|
113
|
-
|
|
114
|
-
<div v-if="invisibleColumns.length">
|
|
115
|
-
<div class="dropdown-header">{{$t('components.table.addColumn')}}</div>
|
|
116
|
-
<template v-for="(column, k) in invisibleColumns">
|
|
117
|
-
<a href="" @click.prevent="addColumn(column)" :key="`inv-column${k}`" class="dropdown-item d-flex align-items-center justify-content-between px-2 py-1">
|
|
118
|
-
<div>
|
|
119
|
-
<span class="nom-plus"></span>
|
|
120
|
-
{{getTitle(column.title)}}
|
|
121
|
-
</div>
|
|
122
|
-
</a>
|
|
123
|
-
</template>
|
|
124
|
-
</div>
|
|
125
|
-
</itf-dropdown>
|
|
126
146
|
|
|
127
147
|
<div class="boundary top"></div>
|
|
128
148
|
<div class="boundary right"></div>
|
|
@@ -163,7 +183,7 @@ class itfTableHeader extends Vue {
|
|
|
163
183
|
@Inject() tableEl;
|
|
164
184
|
|
|
165
185
|
@PropSync('columns', { type: Array, default: () => ([]) }) sortedColumns;
|
|
166
|
-
@PropSync('sorting'
|
|
186
|
+
@PropSync('sorting') _sorting;
|
|
167
187
|
@Prop({ type: Array, default: () => ([]) }) rows;
|
|
168
188
|
@Prop({ type: Array, default: () => ([]) }) selectedIds;
|
|
169
189
|
@Prop({ type: Object, default: () => ({}) }) schema;
|
|
@@ -192,7 +212,7 @@ class itfTableHeader extends Vue {
|
|
|
192
212
|
if (typeof this._sorting === 'string'){
|
|
193
213
|
return this._sorting[0] === '-' ? {[this._sorting.substring(1)]: 'desc'} : {[this._sorting]: 'asc'};
|
|
194
214
|
} else {
|
|
195
|
-
return this._sorting;
|
|
215
|
+
return this._sorting ?? {};
|
|
196
216
|
}
|
|
197
217
|
}
|
|
198
218
|
|
|
@@ -239,6 +259,26 @@ class itfTableHeader extends Vue {
|
|
|
239
259
|
return this.sortedColumns.findIndex((column) => column.lastPinned);
|
|
240
260
|
}
|
|
241
261
|
|
|
262
|
+
canMoveColumn(direction, column) {
|
|
263
|
+
if (!this.columnSorting) {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
const index = this.sortedColumns.findIndex((c) => c === column);
|
|
267
|
+
return (index + direction >= 0 && index + direction < this.sortedColumns.length);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
moveColumn(direction, column) {
|
|
271
|
+
const index = this.sortedColumns.findIndex((c) => c === column);
|
|
272
|
+
const newIndex = index + direction;
|
|
273
|
+
if (newIndex < 0 || newIndex >= this.sortedColumns.length) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const newValue = [...this.sortedColumns];
|
|
277
|
+
newValue.splice(index, 1);
|
|
278
|
+
newValue.splice(newIndex, 0, column);
|
|
279
|
+
this.$emit('update:columns', newValue);
|
|
280
|
+
}
|
|
281
|
+
|
|
242
282
|
reorderColumns({ detail }) {
|
|
243
283
|
const { index: fromIndex } = detail.draggablePayload;
|
|
244
284
|
const { index: toIndex, last } = detail.dropzonePayload;
|
|
@@ -302,13 +342,27 @@ class itfTableHeader extends Vue {
|
|
|
302
342
|
const delta = event.pageX - startX;
|
|
303
343
|
newWidth = Math.max(columnWidth + delta, 50);
|
|
304
344
|
columns.forEach((column) => {
|
|
305
|
-
|
|
345
|
+
const { maxWidth, minWidth } = this.sortedColumns[index];
|
|
346
|
+
if (minWidth && newWidth < minWidth) {
|
|
347
|
+
newWidth = minWidth;
|
|
348
|
+
}
|
|
349
|
+
if (maxWidth && newWidth > maxWidth) {
|
|
350
|
+
newWidth = maxWidth;
|
|
351
|
+
}
|
|
306
352
|
column.style.width = `${newWidth}px`;
|
|
353
|
+
column.style['max-width'] = `${newWidth}px`;
|
|
307
354
|
});
|
|
308
355
|
};
|
|
309
356
|
const mouseUpHandler = () => {
|
|
310
357
|
document.removeEventListener('mousemove', mouseMoveHandler);
|
|
311
358
|
document.removeEventListener('mouseup', mouseUpHandler);
|
|
359
|
+
const { minWidth, maxWidth } = this.sortedColumns[index];
|
|
360
|
+
if (minWidth && newWidth < minWidth) {
|
|
361
|
+
newWidth = minWidth;
|
|
362
|
+
}
|
|
363
|
+
if (maxWidth && newWidth > maxWidth) {
|
|
364
|
+
newWidth = maxWidth;
|
|
365
|
+
}
|
|
312
366
|
this.changeColumn(index, { width: newWidth });
|
|
313
367
|
};
|
|
314
368
|
document.addEventListener('mousemove', mouseMoveHandler);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div @click.prevent.stop="toggle" class="d-flex align-items-center flex-nowrap" :class="{'active-toggle': visible}">
|
|
4
|
+
<div class="item-toggle text-muted">
|
|
5
|
+
<template v-if="visible && expanded">
|
|
6
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
7
|
+
width="16" height="16" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
|
8
|
+
<path d="M184.7,413.1l2.1-1.8l156.5-136c5.3-4.6,8.6-11.5,8.6-19.2c0-7.7-3.4-14.6-8.6-19.2L187.1,101l-2.6-2.3
|
|
9
|
+
C182,97,179,96,175.8,96c-8.7,0-15.8,7.4-15.8,16.6h0v286.8h0c0,9.2,7.1,16.6,15.8,16.6C179.1,416,182.2,414.9,184.7,413.1z" fill="currentColor" />
|
|
10
|
+
</svg>
|
|
11
|
+
</template>
|
|
12
|
+
<template v-else-if="visible">
|
|
13
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
14
|
+
width="16" height="16" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
|
15
|
+
<path d="M98.9,184.7l1.8,2.1l136,156.5c4.6,5.3,11.5,8.6,19.2,8.6c7.7,0,14.6-3.4,19.2-8.6L411,187.1l2.3-2.6
|
|
16
|
+
c1.7-2.5,2.7-5.5,2.7-8.7c0-8.7-7.4-15.8-16.6-15.8v0H112.6v0c-9.2,0-16.6,7.1-16.6,15.8C96,179.1,97.1,182.2,98.9,184.7z" fill="currentColor" />
|
|
17
|
+
</svg>
|
|
18
|
+
</template>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<slot></slot>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
25
|
+
<style lang="scss" scoped>
|
|
26
|
+
.active-toggle {
|
|
27
|
+
cursor: pointer;
|
|
28
|
+
}
|
|
29
|
+
.item-toggle {
|
|
30
|
+
width: 1.5rem;
|
|
31
|
+
min-width: 1.5rem;
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
}
|
|
35
|
+
</style>
|
|
36
|
+
<script>
|
|
37
|
+
import { Vue, Component, Prop } from 'vue-property-decorator';
|
|
38
|
+
|
|
39
|
+
export default @Component({
|
|
40
|
+
components: {
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
class itfTableRowToggle extends Vue {
|
|
44
|
+
@Prop(Boolean) expanded;
|
|
45
|
+
@Prop(Boolean) visible;
|
|
46
|
+
|
|
47
|
+
toggle() {
|
|
48
|
+
this.$emit('toggle');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
</script>
|
|
@@ -20,29 +20,11 @@
|
|
|
20
20
|
</a>
|
|
21
21
|
</div>
|
|
22
22
|
</div>
|
|
23
|
-
<div
|
|
24
|
-
<div class="
|
|
23
|
+
<div class="indicator sticky">
|
|
24
|
+
<div v-if="indicatorType !== 'none'" class="table-view-row-count">
|
|
25
25
|
<span v-if="indicatorType === 'order'">{{ (n + 1) }}</span>
|
|
26
26
|
<span v-else-if="indicatorType === 'property'">{{ item[idProperty] }}</span>
|
|
27
|
-
<
|
|
28
|
-
<template v-if="subrowsProperty && item[subrowsProperty] && item[subrowsProperty].length">
|
|
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-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"/>
|
|
33
|
-
</svg>
|
|
34
|
-
</template>
|
|
35
|
-
<template v-else>
|
|
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"/>
|
|
39
|
-
</svg>
|
|
40
|
-
</template>
|
|
41
|
-
</template>
|
|
42
|
-
</a>
|
|
43
|
-
</div>
|
|
44
|
-
<div v-if="!noSelectAll" class="fill on-hover">
|
|
45
|
-
<itf-checkbox :value="item[idProperty]" />
|
|
27
|
+
<span v-else-if="indicatorType === 'checkbox'"><itf-checkbox :value="item[idProperty]" /></span>
|
|
46
28
|
</div>
|
|
47
29
|
</div>
|
|
48
30
|
<div accept-group="items" class="table-item-inner" @click="$emit('row-click', item)">
|
|
@@ -51,23 +33,29 @@
|
|
|
51
33
|
v-if="column.visible !== false"
|
|
52
34
|
:data-column="k"
|
|
53
35
|
:style="`width: ${column.width}px; max-width: ${column.width}px; left: ${column.left}px;`"
|
|
54
|
-
:class="{'justify-content-end': column.align === 'end', 'sticky': column.pinned, 'last-sticky-column': k === lastPinnedIndex, '
|
|
36
|
+
:class="{'justify-content-end': column.align === 'end', 'sticky': column.pinned, 'last-sticky-column': k === lastPinnedIndex, 'editable': column.editable && editable}"
|
|
55
37
|
class="table-view-item-value d-flex h-100">
|
|
56
|
-
<
|
|
38
|
+
<div class="table-view-item-value-content" :class="{'px-2': !(column.editable && editable)}">
|
|
39
|
+
<slot
|
|
40
|
+
:name="`column.${column.property}`"
|
|
41
|
+
:toggle="() => $emit('toggle', item)"
|
|
42
|
+
:hasSubitems="!!(subrowsProperty && item[subrowsProperty] && item[subrowsProperty].length)"
|
|
43
|
+
:isExpanded="!!(item[subrowsProperty] && item[subrowsProperty].length && !isExpanded(item))"
|
|
44
|
+
:level="level" :editable="column.editable && editable" :item="item" :column="column" :update="(val) => updateValue(item, val, n, column)" :value="getValue(item, column)">
|
|
57
45
|
<template v-if="column.editable && editable && (!editableProperty || item[editableProperty])">
|
|
58
46
|
<slot :name="`edit.${column.type}`" :level="level" :toggle="() => $emit('toggle', item)" :update="(val) => updateValue(item, val, n, column)" :value="getValue(item, column)" :item="item" :column="column">
|
|
59
|
-
<itf-text-field class="w-100" v-if="column.type === 'text'" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
|
|
60
|
-
<itf-text-field class="w-100" v-if="column.type === 'number'" type="number" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
|
|
47
|
+
<itf-text-field class="w-100 h-100" v-if="column.type === 'text'" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
|
|
48
|
+
<itf-text-field class="w-100 h-100" v-if="column.type === 'number'" type="number" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
|
|
61
49
|
<itf-hours-field
|
|
62
|
-
class="w-100"
|
|
50
|
+
class="w-100 h-100"
|
|
63
51
|
placeholder="00h 00m"
|
|
64
52
|
v-else-if="column.type === 'time'"
|
|
65
53
|
:hours="getValue(item, column)"
|
|
66
54
|
@update:hours="updateValue(item, $event, n, column)"
|
|
67
55
|
/>
|
|
68
|
-
<itf-textarea class="w-100" :rows="1" autogrow v-else-if="column.type === 'textarea'" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
|
|
69
|
-
<itf-money-field class="w-100" currency-disabled :currency="currency" :currencies="currencies" v-else-if="column.type === 'money'" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
|
|
70
|
-
<itf-select class="w-100" v-else-if="column.type === 'select'" :reduce="(item) => item.value" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" :options="column.options"></itf-select>
|
|
56
|
+
<itf-textarea class="w-100 h-100" :rows="1" autogrow v-else-if="column.type === 'textarea'" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
|
|
57
|
+
<itf-money-field class="w-100 h-100" currency-disabled :currency="currency" :currencies="currencies" v-else-if="column.type === 'money'" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
|
|
58
|
+
<itf-select class="w-100 h-100" v-else-if="column.type === 'select'" :reduce="(item) => item.value" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" :options="column.options"></itf-select>
|
|
71
59
|
</slot>
|
|
72
60
|
</template>
|
|
73
61
|
<div v-else class="h-100 align-items-center d-flex w-100">
|
|
@@ -76,6 +64,7 @@
|
|
|
76
64
|
</slot>
|
|
77
65
|
</div>
|
|
78
66
|
</slot>
|
|
67
|
+
</div>
|
|
79
68
|
</div>
|
|
80
69
|
</template>
|
|
81
70
|
<div class="table-view-item-value extra"></div>
|
|
@@ -120,6 +109,7 @@
|
|
|
120
109
|
</template>
|
|
121
110
|
</itf-table-rows>
|
|
122
111
|
</template>
|
|
112
|
+
<div v-if="dividerProperty && item[dividerProperty]" :key="`divider-${n}`" class="itf-table2__row-divider"></div>
|
|
123
113
|
</template>
|
|
124
114
|
</div>
|
|
125
115
|
</template>
|
|
@@ -155,6 +145,7 @@ class itfTableRows extends Vue {
|
|
|
155
145
|
@Prop() rows;
|
|
156
146
|
@Prop() idProperty;
|
|
157
147
|
@Prop() subrowsProperty;
|
|
148
|
+
@Prop() dividerProperty;
|
|
158
149
|
@Prop() active;
|
|
159
150
|
@Prop(Boolean) showAddColumn;
|
|
160
151
|
@Prop(Boolean) noSelectAll;
|