@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.
Files changed (153) hide show
  1. package/package.json +1 -1
  2. package/src/components/button/Button.vue +4 -2
  3. package/src/components/card/BentoCard.vue +70 -19
  4. package/src/components/card/BentoGrid.vue +21 -8
  5. package/src/components/filter/FilterAmountRange.vue +50 -42
  6. package/src/components/filter/FilterBadge.vue +27 -22
  7. package/src/components/filter/FilterFacetsList.vue +21 -17
  8. package/src/components/filter/FilterPanel.vue +143 -45
  9. package/src/components/filter/index.stories.js +0 -2
  10. package/src/components/form/Label.vue +19 -2
  11. package/src/components/icon/Icon.vue +4 -2
  12. package/src/components/icon/components/fi_fingerprint.vue +4 -0
  13. package/src/components/icon/components/nomi-ai.vue +6 -0
  14. package/src/components/icon/components/nomi-arrow-down.vue +4 -0
  15. package/src/components/icon/components/nomi-arrow-right-top.vue +4 -0
  16. package/src/components/icon/components/nomi-arrow-up.vue +4 -0
  17. package/src/components/icon/components/nomi-arrow_down.vue +4 -0
  18. package/src/components/icon/components/nomi-arrow_up.vue +4 -0
  19. package/src/components/icon/components/nomi-arrows.vue +7 -0
  20. package/src/components/icon/components/nomi-calendar-alt.vue +4 -0
  21. package/src/components/icon/components/nomi-calendar-alt2.vue +4 -0
  22. package/src/components/icon/components/nomi-calendar.vue +11 -0
  23. package/src/components/icon/components/nomi-card.vue +4 -0
  24. package/src/components/icon/components/nomi-clear.vue +4 -0
  25. package/src/components/icon/components/nomi-close.vue +5 -0
  26. package/src/components/icon/components/nomi-counterparty.vue +4 -0
  27. package/src/components/icon/components/nomi-dashboard.vue +4 -0
  28. package/src/components/icon/components/nomi-expand.vue +7 -0
  29. package/src/components/icon/components/nomi-export.vue +4 -0
  30. package/src/components/icon/components/nomi-eye-close.vue +4 -0
  31. package/src/components/icon/components/nomi-eye-open.vue +4 -0
  32. package/src/components/icon/components/nomi-eye.vue +4 -0
  33. package/src/components/icon/components/nomi-filter.vue +4 -0
  34. package/src/components/icon/components/nomi-help.vue +5 -0
  35. package/src/components/icon/components/nomi-hide.vue +4 -0
  36. package/src/components/icon/components/nomi-lock.vue +4 -0
  37. package/src/components/icon/components/nomi-logout.vue +5 -0
  38. package/src/components/icon/components/nomi-money.vue +4 -0
  39. package/src/components/icon/components/nomi-move-left.vue +4 -0
  40. package/src/components/icon/components/nomi-move-right.vue +4 -0
  41. package/src/components/icon/components/nomi-pen.vue +5 -0
  42. package/src/components/icon/components/nomi-person.vue +5 -0
  43. package/src/components/icon/components/nomi-pin.vue +7 -0
  44. package/src/components/icon/components/nomi-project.vue +4 -0
  45. package/src/components/icon/components/nomi-recurrence.vue +2 -0
  46. package/src/components/icon/components/nomi-repeat.vue +7 -0
  47. package/src/components/icon/components/nomi-report.vue +4 -0
  48. package/src/components/icon/components/nomi-scissors.vue +4 -0
  49. package/src/components/icon/components/nomi-settings.vue +4 -0
  50. package/src/components/icon/components/nomi-sort-asc.vue +7 -0
  51. package/src/components/icon/components/nomi-sort-desc.vue +7 -0
  52. package/src/components/icon/components/nomi-table-view.vue +4 -0
  53. package/src/components/icon/components/nomi-tag.vue +4 -0
  54. package/src/components/icon/components/nomi-target.vue +4 -0
  55. package/src/components/icon/components/nomi-text.vue +6 -0
  56. package/src/components/icon/components/nomi-transactions.vue +8 -0
  57. package/src/components/icon/components/nomi-trash.vue +4 -0
  58. package/src/components/icon/components/nomi-unpin.vue +7 -0
  59. package/src/components/icon/components/nomi-user.vue +5 -0
  60. package/src/components/icon/convert-icons.js +11 -0
  61. package/src/components/icon/icons.js +332 -286
  62. package/src/components/icon/new-icons/ai.svg +5 -0
  63. package/src/components/icon/new-icons/arrow-down.svg +3 -0
  64. package/src/components/icon/new-icons/arrow-right-top.svg +3 -0
  65. package/src/components/icon/new-icons/arrow-up.svg +3 -0
  66. package/src/components/icon/new-icons/arrow_down.svg +3 -0
  67. package/src/components/icon/new-icons/arrow_up.svg +3 -0
  68. package/src/components/icon/new-icons/arrows.svg +6 -0
  69. package/src/components/icon/new-icons/calendar-alt.svg +3 -0
  70. package/src/components/icon/new-icons/calendar-alt2.svg +3 -0
  71. package/src/components/icon/new-icons/calendar.svg +10 -0
  72. package/src/components/icon/new-icons/card.svg +3 -0
  73. package/src/components/icon/new-icons/clear.svg +3 -0
  74. package/src/components/icon/new-icons/close.svg +4 -0
  75. package/src/components/icon/new-icons/counterparty.svg +3 -0
  76. package/src/components/icon/new-icons/dashboard.svg +3 -0
  77. package/src/components/icon/new-icons/expand.svg +6 -0
  78. package/src/components/icon/new-icons/eye-close.svg +3 -0
  79. package/src/components/icon/new-icons/eye-open.svg +3 -0
  80. package/src/components/icon/new-icons/eye.svg +3 -0
  81. package/src/components/icon/new-icons/filter.svg +3 -0
  82. package/src/components/icon/new-icons/help.svg +4 -0
  83. package/src/components/icon/new-icons/hide.svg +3 -0
  84. package/src/components/icon/new-icons/logout.svg +4 -0
  85. package/src/components/icon/new-icons/money.svg +3 -0
  86. package/src/components/icon/new-icons/move-left.svg +3 -0
  87. package/src/components/icon/new-icons/move-right.svg +3 -0
  88. package/src/components/icon/new-icons/pen.svg +4 -0
  89. package/src/components/icon/new-icons/person.svg +4 -0
  90. package/src/components/icon/new-icons/pin.svg +6 -0
  91. package/src/components/icon/new-icons/project.svg +3 -0
  92. package/src/components/icon/new-icons/recurrence.svg +1 -0
  93. package/src/components/icon/new-icons/repeat.svg +6 -0
  94. package/src/components/icon/new-icons/report.svg +3 -0
  95. package/src/components/icon/new-icons/scissors.svg +3 -0
  96. package/src/components/icon/new-icons/settings.svg +3 -0
  97. package/src/components/icon/new-icons/sort-asc.svg +6 -0
  98. package/src/components/icon/new-icons/sort-desc.svg +6 -0
  99. package/src/components/icon/new-icons/table-view.svg +3 -0
  100. package/src/components/icon/new-icons/tag.svg +3 -0
  101. package/src/components/icon/new-icons/target.svg +3 -0
  102. package/src/components/icon/new-icons/text.svg +5 -0
  103. package/src/components/icon/new-icons/transactions.svg +7 -0
  104. package/src/components/icon/new-icons/trash.svg +3 -0
  105. package/src/components/icon/new-icons/unpin.svg +6 -0
  106. package/src/components/icon/new-icons/user.svg +4 -0
  107. package/src/components/modal/DeleteConfirmModal.vue +0 -2
  108. package/src/components/modal/ItemEditor.vue +1 -5
  109. package/src/components/pagination/Pagination.vue +3 -2
  110. package/src/components/pagination/Pagination2.vue +179 -0
  111. package/src/components/panels/Panel.vue +23 -7
  112. package/src/components/panels/PanelItemEdit.vue +62 -0
  113. package/src/components/panels/PanelLink.vue +26 -6
  114. package/src/components/panels/PanelList.vue +27 -26
  115. package/src/components/panels/helpers.spec.ts +27 -0
  116. package/src/components/panels/helpers.ts +37 -0
  117. package/src/components/popover/NoticePopout.vue +1 -1
  118. package/src/components/select/Select.vue +1 -1
  119. package/src/components/sortable/draggable.js +2 -1
  120. package/src/components/table/Table2.vue +37 -8
  121. package/src/components/table/TableBody.vue +10 -18
  122. package/src/components/table/TableGroup.vue +31 -12
  123. package/src/components/table/TableHeader.vue +118 -64
  124. package/src/components/table/TableRowToggle.vue +51 -0
  125. package/src/components/table/TableRows.vue +20 -29
  126. package/src/components/table/index.stories.js +22 -200
  127. package/src/components/table/table2.scss +237 -68
  128. package/src/components/text-field/MoneyField.vue +23 -21
  129. package/src/components/tree/TreeEditor.vue +615 -0
  130. package/src/components/view/View.vue +265 -0
  131. package/src/components/view/index.stories.js +588 -0
  132. package/src/helpers/formatters.js +14 -1
  133. package/src/helpers/tree/cdbl.js +32 -0
  134. package/src/helpers/tree/cint.js +43 -0
  135. package/src/helpers/tree/domDrag.js +911 -0
  136. package/src/helpers/tree/domFinds.js +20 -0
  137. package/src/helpers/tree/domGetPointFromEvent.js +53 -0
  138. package/src/helpers/tree/domIsClientXYIn.js +65 -0
  139. package/src/helpers/tree/domRemove.js +50 -0
  140. package/src/helpers/tree/evem.js +27 -0
  141. package/src/helpers/tree/genID.js +56 -0
  142. package/src/helpers/tree/isEle.js +28 -0
  143. package/src/helpers/tree/isestr.js +35 -0
  144. package/src/helpers/tree/isint.js +40 -0
  145. package/src/helpers/tree/isnbr.js +24 -0
  146. package/src/helpers/tree/isnum.js +38 -0
  147. package/src/helpers/tree/ispint.js +41 -0
  148. package/src/helpers/tree/isstr.js +27 -0
  149. package/src/helpers/tree.js +30 -0
  150. package/src/helpers/vuetifyColor.js +136 -0
  151. package/src/locales/en.js +17 -0
  152. package/src/locales/uk.js +17 -0
  153. 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
- <span class="collapse-arrow">
20
+ <itf-button squircle icon small secondary class="collapse-arrow">
21
21
  <itf-icon :name="isShowTable ? 'chevron_down' : 'chevron_right'"/>
22
- </span>
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: 1px solid var(--itf-table-border-color);
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: 1px solid var(--itf-table-border-color);
268
- border-bottom: 1px solid var(--itf-table-border-color);
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: 1px solid var(--itf-table-border-color);
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 = 12 + (this.indicatorType === 'none' ? 1 : Number(this.indicatorWidth)); // sum of first 2 cells
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
- <span class="itf-table2__header-title text-truncate" :title="getTitle(column.title)" :class="{'ms-auto': column.align === 'end'}">
37
- <span v-if="column.icon" :class="column.icon"></span>
38
- {{getTitle(column.title)}}
39
- <div v-if="column.prefix" class="itf-table2__subtitle" v-text="column.prefix" />
40
- </span>
41
- <itf-icon v-if="sortColumnParams[column.property]" :name="sortColumnParams[column.property] === 'asc' ? 'arrow_up' : 'arrow_down'" :size="16" class="ms-1" />
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
- <div v-if="column.sortable">
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 :name="column.pinned ? 'checkbox_checked' : 'checkbox_empty'" :size="16" class="me-1" />
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="eye_no" :size="16" class="me-1" />
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', { type: Object, default: () => ({}) }) _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
- column.style['max-width'] = `${newWidth}px`;
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 v-if="indicatorType !== 'none'" class="indicator sticky">
24
- <div class="fill table-view-row-count" :class="{'on-rest': !noSelectAll}">
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
- <a href="" @click.prevent.stop="$emit('toggle', item)" v-else-if="indicatorType === 'toggle'">
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, 'px-2': !(column.editable && editable), 'editable': column.editable && editable}"
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
- <slot :name="`column.${column.property}`" :toggle="() => $emit('toggle', item)" :level="level" :editable="column.editable && editable" :item="item" :column="column" :update="(val) => updateValue(item, val, n, column)" :value="getValue(item, column)">
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;