@itfin/components 1.3.99 → 1.4.0

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 (151) 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 +141 -44
  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-eye-close.vue +4 -0
  30. package/src/components/icon/components/nomi-eye-open.vue +4 -0
  31. package/src/components/icon/components/nomi-eye.vue +4 -0
  32. package/src/components/icon/components/nomi-filter.vue +4 -0
  33. package/src/components/icon/components/nomi-help.vue +5 -0
  34. package/src/components/icon/components/nomi-hide.vue +4 -0
  35. package/src/components/icon/components/nomi-logout.vue +5 -0
  36. package/src/components/icon/components/nomi-money.vue +4 -0
  37. package/src/components/icon/components/nomi-move-left.vue +4 -0
  38. package/src/components/icon/components/nomi-move-right.vue +4 -0
  39. package/src/components/icon/components/nomi-pen.vue +5 -0
  40. package/src/components/icon/components/nomi-person.vue +5 -0
  41. package/src/components/icon/components/nomi-pin.vue +7 -0
  42. package/src/components/icon/components/nomi-project.vue +4 -0
  43. package/src/components/icon/components/nomi-recurrence.vue +2 -0
  44. package/src/components/icon/components/nomi-repeat.vue +7 -0
  45. package/src/components/icon/components/nomi-report.vue +4 -0
  46. package/src/components/icon/components/nomi-scissors.vue +4 -0
  47. package/src/components/icon/components/nomi-settings.vue +4 -0
  48. package/src/components/icon/components/nomi-sort-asc.vue +7 -0
  49. package/src/components/icon/components/nomi-sort-desc.vue +7 -0
  50. package/src/components/icon/components/nomi-table-view.vue +4 -0
  51. package/src/components/icon/components/nomi-tag.vue +4 -0
  52. package/src/components/icon/components/nomi-target.vue +4 -0
  53. package/src/components/icon/components/nomi-text.vue +6 -0
  54. package/src/components/icon/components/nomi-transactions.vue +8 -0
  55. package/src/components/icon/components/nomi-trash.vue +4 -0
  56. package/src/components/icon/components/nomi-unpin.vue +7 -0
  57. package/src/components/icon/components/nomi-user.vue +5 -0
  58. package/src/components/icon/convert-icons.js +11 -0
  59. package/src/components/icon/icons.js +332 -286
  60. package/src/components/icon/new-icons/ai.svg +5 -0
  61. package/src/components/icon/new-icons/arrow-down.svg +3 -0
  62. package/src/components/icon/new-icons/arrow-right-top.svg +3 -0
  63. package/src/components/icon/new-icons/arrow-up.svg +3 -0
  64. package/src/components/icon/new-icons/arrow_down.svg +3 -0
  65. package/src/components/icon/new-icons/arrow_up.svg +3 -0
  66. package/src/components/icon/new-icons/arrows.svg +6 -0
  67. package/src/components/icon/new-icons/calendar-alt.svg +3 -0
  68. package/src/components/icon/new-icons/calendar-alt2.svg +3 -0
  69. package/src/components/icon/new-icons/calendar.svg +10 -0
  70. package/src/components/icon/new-icons/card.svg +3 -0
  71. package/src/components/icon/new-icons/clear.svg +3 -0
  72. package/src/components/icon/new-icons/close.svg +4 -0
  73. package/src/components/icon/new-icons/counterparty.svg +3 -0
  74. package/src/components/icon/new-icons/dashboard.svg +3 -0
  75. package/src/components/icon/new-icons/expand.svg +6 -0
  76. package/src/components/icon/new-icons/eye-close.svg +3 -0
  77. package/src/components/icon/new-icons/eye-open.svg +3 -0
  78. package/src/components/icon/new-icons/eye.svg +3 -0
  79. package/src/components/icon/new-icons/filter.svg +3 -0
  80. package/src/components/icon/new-icons/help.svg +4 -0
  81. package/src/components/icon/new-icons/hide.svg +3 -0
  82. package/src/components/icon/new-icons/logout.svg +4 -0
  83. package/src/components/icon/new-icons/money.svg +3 -0
  84. package/src/components/icon/new-icons/move-left.svg +3 -0
  85. package/src/components/icon/new-icons/move-right.svg +3 -0
  86. package/src/components/icon/new-icons/pen.svg +4 -0
  87. package/src/components/icon/new-icons/person.svg +4 -0
  88. package/src/components/icon/new-icons/pin.svg +6 -0
  89. package/src/components/icon/new-icons/project.svg +3 -0
  90. package/src/components/icon/new-icons/recurrence.svg +1 -0
  91. package/src/components/icon/new-icons/repeat.svg +6 -0
  92. package/src/components/icon/new-icons/report.svg +3 -0
  93. package/src/components/icon/new-icons/scissors.svg +3 -0
  94. package/src/components/icon/new-icons/settings.svg +3 -0
  95. package/src/components/icon/new-icons/sort-asc.svg +6 -0
  96. package/src/components/icon/new-icons/sort-desc.svg +6 -0
  97. package/src/components/icon/new-icons/table-view.svg +3 -0
  98. package/src/components/icon/new-icons/tag.svg +3 -0
  99. package/src/components/icon/new-icons/target.svg +3 -0
  100. package/src/components/icon/new-icons/text.svg +5 -0
  101. package/src/components/icon/new-icons/transactions.svg +7 -0
  102. package/src/components/icon/new-icons/trash.svg +3 -0
  103. package/src/components/icon/new-icons/unpin.svg +6 -0
  104. package/src/components/icon/new-icons/user.svg +4 -0
  105. package/src/components/modal/DeleteConfirmModal.vue +0 -2
  106. package/src/components/modal/ItemEditor.vue +1 -5
  107. package/src/components/pagination/Pagination.vue +3 -2
  108. package/src/components/pagination/Pagination2.vue +179 -0
  109. package/src/components/panels/Panel.vue +23 -7
  110. package/src/components/panels/PanelItemEdit.vue +62 -0
  111. package/src/components/panels/PanelLink.vue +26 -6
  112. package/src/components/panels/PanelList.vue +27 -26
  113. package/src/components/panels/helpers.spec.ts +27 -0
  114. package/src/components/panels/helpers.ts +37 -0
  115. package/src/components/popover/NoticePopout.vue +1 -1
  116. package/src/components/select/Select.vue +1 -1
  117. package/src/components/sortable/draggable.js +2 -1
  118. package/src/components/table/Table2.vue +35 -8
  119. package/src/components/table/TableBody.vue +10 -18
  120. package/src/components/table/TableGroup.vue +30 -14
  121. package/src/components/table/TableHeader.vue +122 -73
  122. package/src/components/table/TableRowToggle.vue +51 -0
  123. package/src/components/table/TableRows.vue +20 -29
  124. package/src/components/table/index.stories.js +22 -200
  125. package/src/components/table/table2.scss +237 -68
  126. package/src/components/text-field/MoneyField.vue +23 -21
  127. package/src/components/text-field/TextField.vue +12 -8
  128. package/src/components/tree/TreeEditor.vue +615 -0
  129. package/src/components/view/View.vue +244 -0
  130. package/src/components/view/index.stories.js +588 -0
  131. package/src/helpers/formatters.js +14 -1
  132. package/src/helpers/tree/cdbl.js +32 -0
  133. package/src/helpers/tree/cint.js +43 -0
  134. package/src/helpers/tree/domDrag.js +911 -0
  135. package/src/helpers/tree/domFinds.js +20 -0
  136. package/src/helpers/tree/domGetPointFromEvent.js +53 -0
  137. package/src/helpers/tree/domIsClientXYIn.js +65 -0
  138. package/src/helpers/tree/domRemove.js +50 -0
  139. package/src/helpers/tree/evem.js +27 -0
  140. package/src/helpers/tree/genID.js +56 -0
  141. package/src/helpers/tree/isEle.js +28 -0
  142. package/src/helpers/tree/isestr.js +35 -0
  143. package/src/helpers/tree/isint.js +40 -0
  144. package/src/helpers/tree/isnbr.js +24 -0
  145. package/src/helpers/tree/isnum.js +38 -0
  146. package/src/helpers/tree/ispint.js +41 -0
  147. package/src/helpers/tree/isstr.js +27 -0
  148. package/src/helpers/tree.js +30 -0
  149. package/src/helpers/vuetifyColor.js +136 -0
  150. package/src/locales/en.js +17 -0
  151. package/src/locales/uk.js +17 -0
@@ -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>
@@ -42,7 +42,6 @@
42
42
  :rows="rows"
43
43
  :schema="schema"
44
44
  :editable="editable"
45
- :sort-as-string="sortAsString"
46
45
  :no-column-menu="noColumnMenu"
47
46
  :no-select-all="noSelectAll"
48
47
  :selected-ids="selectedIds"
@@ -50,6 +49,7 @@
50
49
  :sorting.sync="_sorting"
51
50
  @update:selectedIds="$emit('update:selectedIds', $event)"
52
51
  @update:columns="$emit('update:columns', $event)"
52
+ @filter="$emit('filter', $event)"
53
53
  @add-column="$emit('add-column', $event)"
54
54
  />
55
55
  </div>
@@ -61,6 +61,7 @@
61
61
  @row-click="$emit('row-click', $event)"
62
62
  :id-property="idProperty"
63
63
  :subrows-property="subrowsProperty"
64
+ :divider-property="dividerProperty"
64
65
  :rows="rows"
65
66
  :editable="editable"
66
67
  :currency="currency"
@@ -112,7 +113,7 @@
112
113
  :key="n"
113
114
  :data-column="n"
114
115
  class="position-relative line-overflow px-1"
115
- :style="column.grow ? `min-width: ${column.minWidth}px; flex-grow: 1;` : `width: ${column.width}px; max-width: ${column.width}px;`">
116
+ :style="`width: ${column.width}px; max-width: ${column.width}px;`">
116
117
  <itf-dropdown append-to-context text right @open="persistSummary = true" @close="persistSummary = false" autoclose="outside">
117
118
  <template #button>
118
119
  <span data-test="summary-column" class="invisible-summary d-flex align-items-center justify-content-end flex-auto">
@@ -154,7 +155,7 @@
154
155
 
155
156
  &.no-indicator {
156
157
  .shadow-area + .table-view-header-value, .table-item-inner {
157
- border-left: 1px solid var(--itf-table-border-color);
158
+ border-left: var(--itf-table-border-base-width) solid var(--itf-table-border-color);
158
159
  }
159
160
  }
160
161
 
@@ -230,7 +231,7 @@
230
231
  border-radius: 0;
231
232
  }
232
233
  &:hover {
233
- background: var(--itf-table-hover-bg);
234
+ //background: var(--itf-table-hover-bg); // видно, що група не на всю ширину коли є нижній скролінг
234
235
  }
235
236
  }
236
237
 
@@ -239,7 +240,7 @@
239
240
  }
240
241
  .header-content:not(.draggable-mirror *) {
241
242
  left: var(--shadow-area-width);
242
- padding-left: 0.75rem;
243
+ //padding-left: 0.75rem;
243
244
  padding-right: 0.75rem;
244
245
  gap: 1rem;
245
246
  align-items: center;
@@ -264,15 +265,18 @@
264
265
  }
265
266
 
266
267
  .table-add-new-item {
267
- border-right: 1px solid var(--itf-table-border-color);
268
- border-bottom: 1px solid var(--itf-table-border-color);
268
+ border-right:var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
269
+ border-left:var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
270
+ border-bottom: var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
269
271
  outline: none;
272
+ border-bottom-left-radius: var(--itf-table-table-border-radius);
273
+ border-bottom-right-radius: var(--itf-table-table-border-radius);
270
274
 
271
275
  & > span {
272
276
  left: var(--shadow-area-width);
273
277
  position: sticky;
274
278
  padding-left: var(--shadow-area-width);
275
- border-left: 1px solid var(--itf-table-border-color);
279
+ //border-left: var(--itf-table-border-base-width) solid var(--itf-table-border-base-color);
276
280
  height: 100%;
277
281
  }
278
282
  &:hover, &:active {
@@ -281,9 +285,20 @@
281
285
  }
282
286
 
283
287
  .sticky-group {
288
+ top: 0px;
284
289
  position: sticky;
285
- top: 0;
286
290
  z-index: 10;
291
+
292
+ & > .draggable-item {
293
+ margin-bottom: 8px;
294
+ }
295
+ .collapse-arrow {
296
+ padding: 0;
297
+
298
+ &:after {
299
+ display: none;
300
+ }
301
+ }
287
302
  }
288
303
  .table-summary {
289
304
  .shadow-area {
@@ -344,6 +359,7 @@ class itfTableGroup extends Vue {
344
359
  @Prop() title;
345
360
  @Prop() idProperty;
346
361
  @Prop() subrowsProperty;
362
+ @Prop() dividerProperty;
347
363
  @Prop() currency;
348
364
  @Prop() currencies;
349
365
  @Prop() active;
@@ -362,8 +378,8 @@ class itfTableGroup extends Vue {
362
378
  @Prop(Boolean) expandedAll;
363
379
  @Prop(Boolean) striped;
364
380
  @Prop(Boolean) stickyHeader;
365
- @Prop(Boolean) sortAsString;
366
381
  @Prop() indicatorWidth;
382
+ @Prop() shadowWidth;
367
383
  @Prop() cssProperty;
368
384
  @PropSync('sorting') _sorting;
369
385
  @Prop({ type: String, default: null }) indicatorType;
@@ -377,7 +393,7 @@ class itfTableGroup extends Vue {
377
393
  get visibleColumns() {
378
394
  let list = this.columns;
379
395
  list = sortBy(list, (column) => column.index);
380
- let left = 12 + (this.indicatorType === 'none' ? 1 : Number(this.indicatorWidth)); // sum of first 2 cells
396
+ let left = Number(this.shadowWidth) + (this.indicatorType === 'none' ? 1 : Math.max(Number(this.indicatorWidth), 16)); // sum of first 2 cells
381
397
  const pinned = list.filter((column) => column.pinned && column.visible !== false);
382
398
  list = list.map((column, index) => {
383
399
  const item = {...column};
@@ -15,9 +15,9 @@
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, 'flex-grow-1': column.grow, [`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
- :style="column.grow ? `left: ${column.left}px; flex-grow: 1` : `width: ${column.width}px; max-width: ${column.width}px; left: ${column.left}px;`">
20
+ :style="`width: ${column.width}px; max-width: ${column.width}px; left: ${column.left}px;`">
21
21
  <!-- Не треба видаляти колонки, бо вони потрібні для збереження ширини -->
22
22
  <div v-if="visibleHeader" accept-group="tablecolumns"
23
23
  class="table-view-header-space"
@@ -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')"
@@ -82,47 +139,10 @@
82
139
  v-dropzone="{payload:{ last: true }}">
83
140
  <div class="table-view-header-dropzone"></div>
84
141
  </div>
85
- <div v-if="visibleHeader && columnResizing && !column.grow" ref="resizeHandle" class="resize-handle"></div>
142
+ <div v-if="visibleHeader && columnResizing" ref="resizeHandle" class="resize-handle"></div>
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;
@@ -174,7 +194,6 @@ class itfTableHeader extends Vue {
174
194
  @Prop(Boolean) noColumnMenu;
175
195
  @Prop(Boolean) noSelectAll;
176
196
  @Prop(Boolean) editable;
177
- @Prop(Boolean) sortAsString;
178
197
  @Prop() idProperty;
179
198
  @Prop() indicatorType;
180
199
 
@@ -192,7 +211,7 @@ class itfTableHeader extends Vue {
192
211
  if (typeof this._sorting === 'string'){
193
212
  return this._sorting[0] === '-' ? {[this._sorting.substring(1)]: 'desc'} : {[this._sorting]: 'asc'};
194
213
  } else {
195
- return this._sorting;
214
+ return this._sorting ?? {};
196
215
  }
197
216
  }
198
217
 
@@ -239,6 +258,26 @@ class itfTableHeader extends Vue {
239
258
  return this.sortedColumns.findIndex((column) => column.lastPinned);
240
259
  }
241
260
 
261
+ canMoveColumn(direction, column) {
262
+ if (!this.columnSorting) {
263
+ return false;
264
+ }
265
+ const index = this.sortedColumns.findIndex((c) => c === column);
266
+ return (index + direction >= 0 && index + direction < this.sortedColumns.length);
267
+ }
268
+
269
+ moveColumn(direction, column) {
270
+ const index = this.sortedColumns.findIndex((c) => c === column);
271
+ const newIndex = index + direction;
272
+ if (newIndex < 0 || newIndex >= this.sortedColumns.length) {
273
+ return;
274
+ }
275
+ const newValue = [...this.sortedColumns];
276
+ newValue.splice(index, 1);
277
+ newValue.splice(newIndex, 0, column);
278
+ this.$emit('update:columns', newValue);
279
+ }
280
+
242
281
  reorderColumns({ detail }) {
243
282
  const { index: fromIndex } = detail.draggablePayload;
244
283
  const { index: toIndex, last } = detail.dropzonePayload;
@@ -302,15 +341,27 @@ class itfTableHeader extends Vue {
302
341
  const delta = event.pageX - startX;
303
342
  newWidth = Math.max(columnWidth + delta, 50);
304
343
  columns.forEach((column) => {
305
- if (!this.sortedColumns[index].grow) {
306
- column.style.width = `${newWidth}px`;
307
- column.style['max-width'] = `${newWidth}px`;
344
+ const { maxWidth, minWidth } = this.sortedColumns[index];
345
+ if (minWidth && newWidth < minWidth) {
346
+ newWidth = minWidth;
347
+ }
348
+ if (maxWidth && newWidth > maxWidth) {
349
+ newWidth = maxWidth;
308
350
  }
351
+ column.style.width = `${newWidth}px`;
352
+ column.style['max-width'] = `${newWidth}px`;
309
353
  });
310
354
  };
311
355
  const mouseUpHandler = () => {
312
356
  document.removeEventListener('mousemove', mouseMoveHandler);
313
357
  document.removeEventListener('mouseup', mouseUpHandler);
358
+ const { minWidth, maxWidth } = this.sortedColumns[index];
359
+ if (minWidth && newWidth < minWidth) {
360
+ newWidth = minWidth;
361
+ }
362
+ if (maxWidth && newWidth > maxWidth) {
363
+ newWidth = maxWidth;
364
+ }
314
365
  this.changeColumn(index, { width: newWidth });
315
366
  };
316
367
  document.addEventListener('mousemove', mouseMoveHandler);
@@ -360,10 +411,8 @@ class itfTableHeader extends Vue {
360
411
  }
361
412
 
362
413
  sortBy(column, order) {
363
- let sort = { [column.property]: order };
364
- if (this.sortAsString) {
365
- sort = order === 'desc' ? `-${column.property}` : column.property;
366
- }
414
+ let sort = order === 'desc' ? `-${column.property}` : column.property;
415
+ console.info(sort);
367
416
  this.$emit('update:sorting', sort);
368
417
  }
369
418
  }
@@ -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, 'flex-grow-1': column.grow, '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;