@itfin/components 1.4.36 → 1.5.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 (204) hide show
  1. package/package.json +17 -20
  2. package/src/ITFSettings.js +6 -0
  3. package/src/assets/scss/_css_variables.scss +2 -7
  4. package/src/assets/scss/_dark-theme.scss +2 -12
  5. package/src/assets/scss/_variables.scss +34 -9
  6. package/src/assets/scss/components/_button.scss +147 -10
  7. package/src/assets/scss/components/_checkbox.scss +9 -0
  8. package/src/assets/scss/components/_datepicker.scss +3 -3
  9. package/src/assets/scss/components/_pagination.scss +4 -1
  10. package/src/assets/scss/components/_popover.scss +22 -0
  11. package/src/assets/scss/components/_segmeneted-control.scss +19 -8
  12. package/src/assets/scss/components/_select.scss +6 -8
  13. package/src/assets/scss/components/_text-field.scss +27 -11
  14. package/src/assets/scss/components/select/_dropdown-menu.scss +1 -0
  15. package/src/assets/scss/components/select/_dropdown-toggle.scss +0 -1
  16. package/src/assets/scss/directives/tooltip.scss +10 -5
  17. package/src/assets/scss/main.scss +48 -0
  18. package/src/components/alert/AlertBanner.vue +75 -0
  19. package/src/components/app/App.vue +6 -3
  20. package/src/components/button/Button.vue +3 -1
  21. package/src/components/button/NativeButton.js +4 -0
  22. package/src/components/button/index.stories.js +2 -2
  23. package/src/components/checkbox/Checkbox.vue +2 -1
  24. package/src/components/checkbox/RadioBox.vue +13 -7
  25. package/src/components/copyToClipboard/CopyToClipboard.vue +4 -1
  26. package/src/components/customize/PropertiesList.vue +0 -2
  27. package/src/components/customize/PropertiesPopupMenu.vue +1 -1
  28. package/src/components/customize/PropertyItem.vue +6 -24
  29. package/src/components/datepicker/DatePicker.vue +3 -1
  30. package/src/components/datepicker/DatePickerInline.vue +2 -2
  31. package/src/components/datepicker/DateRangePickerInline.vue +6 -1
  32. package/src/components/dropdown/Dropdown.vue +1 -1
  33. package/src/components/dropdown/DropdownMenu.vue +1 -1
  34. package/src/components/editable/EditButton.vue +1 -1
  35. package/src/components/filter/FilterBadge.vue +20 -1
  36. package/src/components/filter/FilterFacetsList.vue +67 -13
  37. package/src/components/filter/FilterPanel.vue +8 -4
  38. package/src/components/filter/NewFilter.vue +305 -0
  39. package/src/components/form/Label.vue +5 -5
  40. package/src/components/icon/components/nomi-ai-alt.vue +5 -0
  41. package/src/components/icon/components/nomi-arrow-right.vue +4 -0
  42. package/src/components/icon/components/nomi-bell.vue +5 -0
  43. package/src/components/icon/components/nomi-calendar-payment.vue +10 -0
  44. package/src/components/icon/components/nomi-card-plus.vue +1 -0
  45. package/src/components/icon/components/nomi-cash-provider.vue +9 -0
  46. package/src/components/icon/components/nomi-cash-repeat.vue +6 -0
  47. package/src/components/icon/components/nomi-category-edit.vue +5 -0
  48. package/src/components/icon/components/nomi-chavron-up.vue +4 -0
  49. package/src/components/icon/components/nomi-chavron_down.vue +4 -0
  50. package/src/components/icon/components/nomi-chavron_up.vue +4 -0
  51. package/src/components/icon/components/nomi-chevron-up.vue +4 -0
  52. package/src/components/icon/components/nomi-exit-right.vue +4 -0
  53. package/src/components/icon/components/nomi-help.vue +2 -3
  54. package/src/components/icon/components/nomi-history.vue +7 -0
  55. package/src/components/icon/components/nomi-lock.vue +1 -1
  56. package/src/components/icon/components/nomi-pen-alt.vue +4 -0
  57. package/src/components/icon/components/nomi-project.vue +2 -2
  58. package/src/components/icon/components/nomi-refresh-off.vue +4 -0
  59. package/src/components/icon/components/nomi-refresh.vue +4 -0
  60. package/src/components/icon/components/nomi-scissors.vue +1 -1
  61. package/src/components/icon/components/nomi-start.vue +28 -0
  62. package/src/components/icon/components/nomi-table-view.vue +1 -4
  63. package/src/components/icon/components/nomi-transactions-delete.vue +5 -0
  64. package/src/components/icon/components/nomi-type-array.vue +6 -0
  65. package/src/components/icon/components/nomi-type-boolean.vue +5 -0
  66. package/src/components/icon/components/nomi-type-date.vue +4 -0
  67. package/src/components/icon/components/nomi-type-null.vue +4 -0
  68. package/src/components/icon/components/nomi-type-number.vue +4 -0
  69. package/src/components/icon/components/nomi-type-object.vue +4 -0
  70. package/src/components/icon/components/nomi-type-string.vue +4 -0
  71. package/src/components/icon/components/nomi-unarchive.vue +17 -0
  72. package/src/components/icon/components/nomi-unlink.vue +10 -0
  73. package/src/components/icon/components/nomi-user.vue +3 -3
  74. package/src/components/icon/components/nomi-warning-triangle.vue +6 -0
  75. package/src/components/icon/components/nomi-warning_triangle_filled.vue +6 -0
  76. package/src/components/icon/convert-icons.js +3 -0
  77. package/src/components/icon/icons.js +390 -312
  78. package/src/components/icon/new-icons/ai-alt.svg +4 -0
  79. package/src/components/icon/new-icons/arrow-right-alt.svg +3 -0
  80. package/src/components/icon/new-icons/arrow-right.svg +3 -0
  81. package/src/components/icon/new-icons/arrow_left.svg +3 -0
  82. package/src/components/icon/new-icons/automation.svg +4 -0
  83. package/src/components/icon/new-icons/balance.svg +3 -0
  84. package/src/components/icon/new-icons/balance_turnover.svg +4 -0
  85. package/src/components/icon/new-icons/bar-horizontal.svg +6 -0
  86. package/src/components/icon/new-icons/bell.svg +4 -0
  87. package/src/components/icon/new-icons/calendar-payment.svg +9 -0
  88. package/src/components/icon/new-icons/card-plus.svg +1 -0
  89. package/src/components/icon/new-icons/cash-provider.svg +8 -0
  90. package/src/components/icon/new-icons/cash-repeat.svg +5 -0
  91. package/src/components/icon/new-icons/cash.svg +3 -0
  92. package/src/components/icon/new-icons/cashflow.svg +3 -0
  93. package/src/components/icon/new-icons/category-edit.svg +4 -0
  94. package/src/components/icon/new-icons/category.svg +4 -0
  95. package/src/components/icon/new-icons/category_alt.svg +3 -0
  96. package/src/components/icon/new-icons/chart-bars.svg +5 -0
  97. package/src/components/icon/new-icons/chart-donut.svg +3 -0
  98. package/src/components/icon/new-icons/chart-funnel.svg +5 -0
  99. package/src/components/icon/new-icons/chart-kpi.svg +7 -0
  100. package/src/components/icon/new-icons/chart-line.svg +4 -0
  101. package/src/components/icon/new-icons/chart-lines.svg +5 -0
  102. package/src/components/icon/new-icons/check-alt.svg +3 -0
  103. package/src/components/icon/new-icons/check.svg +3 -0
  104. package/src/components/icon/new-icons/chevron-down.svg +3 -0
  105. package/src/components/icon/new-icons/chevron-left.svg +3 -0
  106. package/src/components/icon/new-icons/chevron-right.svg +3 -0
  107. package/src/components/icon/new-icons/chevron-up.svg +3 -0
  108. package/src/components/icon/new-icons/collapse.svg +6 -0
  109. package/src/components/icon/new-icons/control-panel.svg +7 -0
  110. package/src/components/icon/new-icons/credit.svg +3 -0
  111. package/src/components/icon/new-icons/currencies.svg +3 -0
  112. package/src/components/icon/new-icons/debt.svg +3 -0
  113. package/src/components/icon/new-icons/demo.svg +6 -0
  114. package/src/components/icon/new-icons/dev.svg +3 -0
  115. package/src/components/icon/new-icons/dots.svg +5 -0
  116. package/src/components/icon/new-icons/duplicate.svg +4 -0
  117. package/src/components/icon/new-icons/exit-right.svg +3 -0
  118. package/src/components/icon/new-icons/export.svg +3 -0
  119. package/src/components/icon/new-icons/file.svg +3 -0
  120. package/src/components/icon/new-icons/folder.svg +3 -0
  121. package/src/components/icon/new-icons/goods-turnover.svg +3 -0
  122. package/src/components/icon/new-icons/goods.svg +4 -0
  123. package/src/components/icon/new-icons/help-alt.svg +3 -0
  124. package/src/components/icon/new-icons/help.svg +2 -3
  125. package/src/components/icon/new-icons/history.svg +6 -0
  126. package/src/components/icon/new-icons/integration.svg +3 -0
  127. package/src/components/icon/new-icons/link.svg +5 -0
  128. package/src/components/icon/new-icons/lock.svg +1 -1
  129. package/src/components/icon/new-icons/menu.svg +5 -0
  130. package/src/components/icon/new-icons/minus.svg +3 -0
  131. package/src/components/icon/new-icons/payment_calendar.svg +3 -0
  132. package/src/components/icon/new-icons/pc.svg +3 -0
  133. package/src/components/icon/new-icons/pen-alt.svg +3 -0
  134. package/src/components/icon/new-icons/planFact.svg +4 -0
  135. package/src/components/icon/new-icons/pnl.svg +7 -0
  136. package/src/components/icon/new-icons/project.svg +2 -2
  137. package/src/components/icon/new-icons/project_alt.svg +3 -0
  138. package/src/components/icon/new-icons/project_alt2.svg +3 -0
  139. package/src/components/icon/new-icons/promo.svg +3 -0
  140. package/src/components/icon/new-icons/refresh-off.svg +3 -0
  141. package/src/components/icon/new-icons/refresh.svg +3 -0
  142. package/src/components/icon/new-icons/scissors.svg +1 -1
  143. package/src/components/icon/new-icons/segment.svg +3 -0
  144. package/src/components/icon/new-icons/start.svg +27 -0
  145. package/src/components/icon/new-icons/strongbox.svg +3 -0
  146. package/src/components/icon/new-icons/subscription.svg +3 -0
  147. package/src/components/icon/new-icons/table-view.svg +1 -4
  148. package/src/components/icon/new-icons/time.svg +3 -0
  149. package/src/components/icon/new-icons/transactions_alt.svg +6 -0
  150. package/src/components/icon/new-icons/transactions_delete.svg +4 -0
  151. package/src/components/icon/new-icons/type-array.svg +5 -0
  152. package/src/components/icon/new-icons/type-boolean.svg +4 -0
  153. package/src/components/icon/new-icons/type-date.svg +3 -0
  154. package/src/components/icon/new-icons/type-null.svg +3 -0
  155. package/src/components/icon/new-icons/type-number.svg +3 -0
  156. package/src/components/icon/new-icons/type-object.svg +3 -0
  157. package/src/components/icon/new-icons/type-string.svg +3 -0
  158. package/src/components/icon/new-icons/types.svg +6 -0
  159. package/src/components/icon/new-icons/unarchive.svg +16 -0
  160. package/src/components/icon/new-icons/unlink.svg +9 -0
  161. package/src/components/icon/new-icons/user.svg +3 -3
  162. package/src/components/icon/new-icons/user_plus.svg +10 -0
  163. package/src/components/icon/new-icons/warehouse.svg +3 -0
  164. package/src/components/icon/new-icons/warning_triangle.svg +5 -0
  165. package/src/components/icon/new-icons/warning_triangle_filled.svg +5 -0
  166. package/src/components/kanban/BoardCard.vue +1 -1
  167. package/src/components/kanban/BoardCardTimer.vue +1 -1
  168. package/src/components/modal/DeleteConfirmModal.vue +10 -6
  169. package/src/components/modal/ItemEditor.vue +1 -1
  170. package/src/components/modal/Modal.vue +1 -1
  171. package/src/components/overlay/SensitiveOverlay.vue +2 -4
  172. package/src/components/panels/Panel.vue +110 -23
  173. package/src/components/panels/PanelItemEdit.vue +8 -6
  174. package/src/components/panels/PanelList.vue +163 -40
  175. package/src/components/panels/helpers.ts +29 -11
  176. package/src/components/popover/Popover.vue +105 -22
  177. package/src/components/segmented-control/SegmentedControl.vue +9 -3
  178. package/src/components/sortable/draggable.js +1 -1
  179. package/src/components/table/Table2.vue +68 -67
  180. package/src/components/table/TableBody.vue +17 -22
  181. package/src/components/table/TableGroup.vue +40 -24
  182. package/src/components/table/TableHeader.vue +86 -81
  183. package/src/components/table/TableRowToggle.vue +1 -9
  184. package/src/components/table/TableRows.vue +49 -55
  185. package/src/components/table/mobile.js +4 -0
  186. package/src/components/table/table2.scss +34 -15
  187. package/src/components/text-field/MoneyField.vue +10 -4
  188. package/src/components/text-field/TextField.vue +17 -8
  189. package/src/components/tree/TreeEditor.vue +3 -2
  190. package/src/components/view/View.vue +73 -208
  191. package/src/directives/appendToBody.js +1 -0
  192. package/src/helpers/validators.js +9 -35
  193. package/src/helpers/validators.spec.js +11 -48
  194. package/src/locales/en.js +4 -6
  195. package/src/locales/pl.js +158 -0
  196. package/src/locales/uk.js +6 -7
  197. package/src/components/icon/components/nomi-calendar-view.vue +0 -4
  198. package/src/components/icon/components/nomi-kanban-view.vue +0 -6
  199. package/src/components/icon/components/nomi-list-view.vue +0 -7
  200. package/src/components/icon/components/nomi-table-config.vue +0 -9
  201. package/src/components/icon/new-icons/calendar-view.svg +0 -3
  202. package/src/components/icon/new-icons/kanban-view.svg +0 -5
  203. package/src/components/icon/new-icons/list-view.svg +0 -6
  204. package/src/components/icon/new-icons/table-config.svg +0 -8
@@ -4,8 +4,8 @@
4
4
  <div ref="container" class="table-row-template">
5
5
  <div accept-group="items" class="table-view-body-space" v-dropzone="{ payload: 0 }"></div>
6
6
  <div class="shadow-area"></div>
7
- <div v-if="indicatorType !== 'none'" class="table-view-header-value reserved sticky">
8
- <itf-checkbox v-if="indicatorType !== 'none' && visibleHeader && !noSelectAll" ungrouped value="all" v-model="selectAll" ref="selectAll" />
7
+ <div class="table-view-header-value reserved sticky" data-test="table-header-checkbox">
8
+ <itf-checkbox v-if="indicatorType === 'checkbox' && visibleHeader && !noSelectAll" ungrouped value="all" v-model="selectAll" ref="selectAll" />
9
9
  </div>
10
10
 
11
11
  <template v-for="(column, n) in visibleAttributes">
@@ -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, 'active': sortColumnParams[column.property], 'last-sticky-column': n === lastPinnedIndex, [`justify-content-${column.align || 'start'}`]: true}"
18
+ :class="{'sticky': column.pinned && !getIsMobileView(), 'active': sortColumnParams[column.property], 'last-sticky-column': n === lastPinnedIndex && !getIsMobileView(), [`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,87 +29,90 @@
29
29
  <div v-if="visibleHeader" group="tablecolumns"
30
30
  class="table-header"
31
31
  @drop="reorderColumns"
32
- v-draggable="{ dragHandleClass: null, handle: true, payload: { index: n, item: column }, mirror: {yAxis:false} }">
33
- <itf-dropdown text append-to-body shadow ref="dropdown" class="w-100" :disabled="noColumnMenu">
34
- <template #button>
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">
39
- {{getTitle(column.title)}}
40
- <div v-if="column.prefix" class="itf-table2__subtitle text-truncate" :class="{'text-end': column.align === 'end'}" v-text="column.prefix" />
32
+ v-draggable="{ handle: true, payload: { index: n, item: column }, mirror: {yAxis:false} }">
33
+ <div class="d-flex align-items-center gap-1">
34
+ <itf-dropdown text append-to-body shadow ref="dropdown" class="w-100" :disabled="noColumnMenu">
35
+ <template #button>
36
+ <div class="d-flex align-items-start justify-content-between">
37
+ <div class="itf-table2__header-title d-flex w-100 align-items-center" :title="getTitle(column.title)">
38
+ <itf-icon class="itf-table2__header-icon" new v-if="column.icon" :name="column.icon"></itf-icon>
39
+ <div class="flex-grow-1 w-100 itf-table2__title-container d-flex align-items-center" :class="{'justify-content-end': column.align === 'end'}">
40
+ <div class="itf-table2__title text-truncate">{{getTitle(column.title)}}</div>
41
+ <div v-if="column.prefix" class="itf-table2__subtitle text-truncate" v-text="column.prefix" />
42
+ </div>
41
43
  </div>
44
+ <itf-icon v-if="sortColumnParams[column.property]" :name="sortColumnParams[column.property] === 'asc' ? 'sort-asc' : 'sort-desc'" new :size="20" class="ms-1" />
42
45
  </div>
43
- </div>
44
- <itf-icon v-if="sortColumnParams[column.property]" :name="sortColumnParams[column.property] === 'asc' ? 'sort-asc' : 'sort-desc'" new :size="20" class="ms-1" />
45
- </template>
46
- <div class="dropdown-header">
47
- {{$t('components.table.actions')}}
48
- </div>
49
-
50
- <div v-if="column.groupable">
51
- <a class="dropdown-item d-flex align-items-center" href="javascript:;">
52
- <itf-icon name="episodes" :size="16" class="me-1" />
53
- {{$t('components.table.groupBy')}}
54
- </a>
55
- </div>
56
- <div>
57
- <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="togglePinned(n)">
58
- <itf-icon v-if="column.pinned" name="pin" new />
59
- <itf-icon v-else name="pin" new />
60
-
61
- <span v-if="column.pinned">{{$t('components.table.unfreezeColumn')}}</span>
62
- <span v-else>{{$t('components.table.freezeColumn')}}</span>
63
- </a>
64
- </div>
65
- <div v-if="showAddColumn">
66
- <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="hideColumn(n)">
67
- <itf-icon name="hide" new />
68
-
69
- {{$t('components.table.hideColumn')}}
70
- </a>
71
- </div>
72
- <div v-if="column.filtrable">
73
- <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="$emit('filter', column)">
74
- <itf-icon name="filter" new />
75
-
76
- {{$t('components.table.filter')}}
77
- </a>
78
- </div>
79
- <div v-if="canMoveColumn(1, column)">
80
- <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="moveColumn(1, column)">
81
- <itf-icon name="move-right" new />
82
-
83
- {{$t('components.table.moveRight')}}
84
- </a>
85
- </div>
86
-
87
- <div v-if="canMoveColumn(-1, column)">
88
- <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="moveColumn(-1, column)">
89
- <itf-icon name="move-left" new />
90
-
91
- {{$t('components.table.moveLeft')}}
92
- </a>
93
- </div>
94
-
95
- <template v-if="column.sortable">
46
+ </template>
96
47
  <div class="dropdown-header">
97
- {{$t('components.table.sorting')}}
48
+ {{$t('components.table.actions')}}
98
49
  </div>
99
- <div>
100
- <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="sortBy(column, 'asc')">
101
- <itf-icon name="sort-asc" new />
102
- {{$t('components.table.sortAscending')}}
50
+
51
+ <div v-if="column.groupable">
52
+ <a class="dropdown-item d-flex align-items-center" href="javascript:;">
53
+ <itf-icon name="episodes" :size="16" class="me-1" />
54
+ {{$t('components.table.groupBy')}}
103
55
  </a>
104
56
  </div>
105
57
  <div>
106
- <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="sortBy(column, 'desc')">
107
- <itf-icon name="sort-desc" new />
108
- {{$t('components.table.sortDescending')}}
58
+ <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="togglePinned(n)">
59
+ <itf-icon v-if="column.pinned" name="pin" new />
60
+ <itf-icon v-else name="pin" new />
61
+
62
+ <span v-if="column.pinned">{{$t('components.table.unfreezeColumn')}}</span>
63
+ <span v-else>{{$t('components.table.freezeColumn')}}</span>
64
+ </a>
65
+ </div>
66
+ <div v-if="showAddColumn">
67
+ <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="hideColumn(n)">
68
+ <itf-icon name="hide" new />
69
+
70
+ {{$t('components.table.hideColumn')}}
71
+ </a>
72
+ </div>
73
+ <div v-if="column.filtrable">
74
+ <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="$emit('filter', column)">
75
+ <itf-icon name="filter" new />
76
+
77
+ {{$t('components.table.filter')}}
78
+ </a>
79
+ </div>
80
+ <div v-if="canMoveColumn(1, column)">
81
+ <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="moveColumn(1, column)">
82
+ <itf-icon name="move-right" new />
83
+
84
+ {{$t('components.table.moveRight')}}
109
85
  </a>
110
86
  </div>
111
- </template>
112
- </itf-dropdown>
87
+
88
+ <div v-if="canMoveColumn(-1, column)">
89
+ <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="moveColumn(-1, column)">
90
+ <itf-icon name="move-left" new />
91
+
92
+ {{$t('components.table.moveLeft')}}
93
+ </a>
94
+ </div>
95
+
96
+ <template v-if="column.sortable">
97
+ <div class="dropdown-header">
98
+ {{$t('components.table.sorting')}}
99
+ </div>
100
+ <div>
101
+ <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="sortBy(column, 'asc')">
102
+ <itf-icon name="sort-asc" new />
103
+ {{$t('components.table.sortAscending')}}
104
+ </a>
105
+ </div>
106
+ <div>
107
+ <a class="dropdown-item d-flex align-items-center gap-1" href="javascript:;" @click="sortBy(column, 'desc')">
108
+ <itf-icon name="sort-desc" new />
109
+ {{$t('components.table.sortDescending')}}
110
+ </a>
111
+ </div>
112
+ </template>
113
+ </itf-dropdown>
114
+ <slot :name="`header.${column.property}.after`" v-bind="{ column }"></slot>
115
+ </div>
113
116
  <div v-if="columnSorting" v-drag-handle class="itf-table2__drag-column">
114
117
  <svg width="35" height="23" viewBox="0 0 35 23" fill="none" xmlns="http://www.w3.org/2000/svg">
115
118
  <g filter="url(#filter0_d_1081_25763)">
@@ -164,6 +167,7 @@ import createDraggable from '../sortable/draggable';
164
167
  import itfDropdown from '../dropdown/Dropdown.vue';
165
168
  import itfSortable from '../sortable/Sortable.vue';
166
169
  import settings from "../../ITFSettings";
170
+ import { getIsMobileView } from "./mobile";
167
171
 
168
172
  const { Node, ...draggableDirectives } = createDraggable();
169
173
 
@@ -196,7 +200,6 @@ class itfTableHeader extends Vue {
196
200
  @Prop(Boolean) noColumnMenu;
197
201
  @Prop(Boolean) noSelectAll;
198
202
  @Prop(Boolean) editable;
199
- @Prop(Boolean) sortAsString;
200
203
  @Prop() idProperty;
201
204
  @Prop() indicatorType;
202
205
 
@@ -210,6 +213,10 @@ class itfTableHeader extends Vue {
210
213
  }
211
214
  }
212
215
 
216
+ getIsMobileView() {
217
+ return getIsMobileView();
218
+ }
219
+
213
220
  get sortColumnParams() {
214
221
  if (typeof this._sorting === 'string'){
215
222
  return this._sorting[0] === '-' ? {[this._sorting.substring(1)]: 'desc'} : {[this._sorting]: 'asc'};
@@ -235,7 +242,7 @@ class itfTableHeader extends Vue {
235
242
 
236
243
  set selectAll(val) {
237
244
  if (val) {
238
- this.$emit('update:selectedIds', this.rows.map(r => r[this.idProperty]));
245
+ this.$emit('update:selectedIds', this.rows.filter(r => !r.isDisabled).map(r => r[this.idProperty]));
239
246
  } else {
240
247
  this.$emit('update:selectedIds', []);
241
248
  }
@@ -414,10 +421,8 @@ class itfTableHeader extends Vue {
414
421
  }
415
422
 
416
423
  sortBy(column, order) {
417
- let sort = { [column.property]: order };
418
- if (this.sortAsString) {
419
- sort = order === 'desc' ? `-${column.property}` : column.property;
420
- }
424
+ let sort = order === 'desc' ? `-${column.property}` : column.property;
425
+ console.info(sort);
421
426
  this.$emit('update:sorting', sort);
422
427
  }
423
428
  }
@@ -2,10 +2,7 @@
2
2
  <div>
3
3
  <div @click.prevent.stop="toggle" class="d-flex align-items-center flex-nowrap" :class="{'active-toggle': visible}">
4
4
  <div class="item-toggle text-muted">
5
- <template v-if="visible && loading">
6
- <div class="itf-spinner"></div>
7
- </template>
8
- <template v-else-if="visible && expanded">
5
+ <template v-if="visible && expanded">
9
6
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
10
7
  width="16" height="16" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
11
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
@@ -26,10 +23,6 @@
26
23
  </div>
27
24
  </template>
28
25
  <style lang="scss" scoped>
29
- .itf-spinner {
30
- width: 1rem;
31
- height: 1rem;
32
- }
33
26
  .active-toggle {
34
27
  cursor: pointer;
35
28
  }
@@ -50,7 +43,6 @@ export default @Component({
50
43
  class itfTableRowToggle extends Vue {
51
44
  @Prop(Boolean) expanded;
52
45
  @Prop(Boolean) visible;
53
- @Prop(Boolean) loading;
54
46
 
55
47
  toggle() {
56
48
  this.$emit('toggle');
@@ -6,7 +6,7 @@
6
6
  group="items"
7
7
  data-test="table-item"
8
8
  class="table-view-item grouped draggable-item"
9
- :class="{'selected': selectedIds.includes(item[idProperty]), 'active': isActive(item[idProperty]), [cssProperty && item[cssProperty]]: !!item[cssProperty]}"
9
+ :class="{'selected': selectedIds.includes(item[idProperty]), 'active': isActive(item[idProperty]), 'disabled': item.isDisabled, [cssProperty && item[cssProperty]]: !!item[cssProperty]}"
10
10
  >
11
11
  <div class="table-row-template">
12
12
  <div accept-group="items" class="table-view-body-space"></div>
@@ -24,23 +24,7 @@
24
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
- <span v-else-if="indicatorType === 'checkbox'"><itf-checkbox :value="item[idProperty]" /></span>
28
- <a href="" @click.prevent.stop="$emit('toggle', item)" v-else-if="indicatorType === 'toggle'">
29
- <template v-if="subrowsProperty && item[subrowsProperty] && item[subrowsProperty].length">
30
- <template v-if="item[subrowsProperty] && item[subrowsProperty].length && !isExpanded(item)">
31
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plus-square" viewBox="0 0 16 16">
32
- <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"/>
33
- <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"/>
34
- </svg>
35
- </template>
36
- <template v-else>
37
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-dash-square" viewBox="0 0 16 16">
38
- <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"/>
39
- <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"/>
40
- </svg>
41
- </template>
42
- </template>
43
- </a>
27
+ <span v-else-if="indicatorType === 'checkbox'"><itf-checkbox :disabled="item.isDisabled" :value="item[idProperty]" /></span>
44
28
  </div>
45
29
  </div>
46
30
  <div accept-group="items" class="table-item-inner" @click="$emit('row-click', item)">
@@ -49,37 +33,37 @@
49
33
  v-if="column.visible !== false"
50
34
  :data-column="k"
51
35
  :style="`width: ${column.width}px; max-width: ${column.width}px; left: ${column.left}px;`"
52
- :class="{'sticky': column.pinned, 'last-sticky-column': k === lastPinnedIndex, 'editable': column.editable && editable}"
36
+ :class="{[column.cssClass]: !!column.cssClass, 'justify-content-end': column.align === 'end', 'sticky': column.pinned && !getIsMobileView(), 'last-sticky-column': k === lastPinnedIndex && !getIsMobileView(), 'editable': column.editable && editable}"
53
37
  class="table-view-item-value d-flex h-100">
54
- <div class="table-view-item-value-content align-items-center" :class="{'justify-content-end': column.align === 'end', 'px-2': !(column.editable && editable)}">
55
- <slot
56
- :name="`column.${column.property}`"
57
- :toggle="() => $emit('toggle', item)"
58
- :hasSubitems="hasSubitems(item)"
59
- :isExpanded="!!(hasSubitems(item) && !isExpanded(item))"
60
- :level="level" :editable="column.editable && editable" :item="item" :column="column" :update="(val) => updateValue(item, val, n, column)" :value="getValue(item, column)">
61
- <template v-if="column.editable && editable && (!editableProperty || item[editableProperty])">
62
- <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">
63
- <itf-text-field class="w-100 h-100" v-if="column.type === 'text'" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
64
- <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)" />
65
- <itf-hours-field
66
- class="w-100 h-100"
67
- placeholder="00h 00m"
68
- v-else-if="column.type === 'time'"
69
- :hours="getValue(item, column)"
70
- @update:hours="updateValue(item, $event, n, column)"
71
- />
72
- <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)" />
73
- <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)" />
74
- <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>
75
- </slot>
76
- </template>
77
- <span v-else class="text-truncate">
78
- <slot :name="`format.${column.type}`" :toggle="() => $emit('toggle', item)" :level="level" :value="getValue(item, column)" :update="(value) => updateValue(item, value, n, column)" :item="item" :column="column">
79
- {{getValue(item, column)}}
80
- </slot>
81
- </span>
82
- </slot>
38
+ <div class="table-view-item-value-content" :class="{'px-2': !(column.editable && editable), 'py-1': (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" :updateFields="(val) => updateValues(item, val, n, column)" :update="(val) => updateValue(item, val, n, column)" :value="getValue(item, column)">
45
+ <template v-if="column.editable && editable && (!editableProperty || item[editableProperty])">
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">
47
+ <itf-text-field class="w-100" v-if="column.type === 'text'" :postfix="column.postfix" :maxlength="column.maxlength" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
48
+ <itf-text-field class="w-100" v-if="column.type === 'number'" :postfix="column.postfix" :max="column.max" :min="column.min" :step="column.step" :maxlength="column.maxlength" type="number" :value="getValue(item, column)" @input="updateValue(item, $event, n, column)" />
49
+ <itf-hours-field
50
+ class="w-100 h-100"
51
+ placeholder="00h 00m"
52
+ v-else-if="column.type === 'time'"
53
+ :hours="getValue(item, column)"
54
+ @update:hours="updateValue(item, $event, n, column)"
55
+ />
56
+ <itf-textarea class="w-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" 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" 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>
59
+ </slot>
60
+ </template>
61
+ <div v-else class="h-100 align-items-center d-flex w-100">
62
+ <slot :name="`format.${column.type}`" :toggle="() => $emit('toggle', item)" :level="level" :value="getValue(item, column)" :update="(value) => updateValue(item, value, n, column)" :item="item" :column="column">
63
+ {{getValue(item, column)}}
64
+ </slot>
65
+ </div>
66
+ </slot>
83
67
  </div>
84
68
  </div>
85
69
  </template>
@@ -102,7 +86,6 @@
102
86
  :columns="columns"
103
87
  :id-property="idProperty"
104
88
  :subrows-property="subrowsProperty"
105
- :async-subrows-property="asyncSubrowsProperty"
106
89
  :show-add-column="showAddColumn"
107
90
  :show-actions="showActions"
108
91
  :no-select-all="noSelectAll"
@@ -115,6 +98,7 @@
115
98
  :expanded-all="expandedAll"
116
99
  :css-property="cssProperty"
117
100
  :editable-property="editableProperty"
101
+ :active="active"
118
102
  @update="$emit('update', $event)"
119
103
  @toggle="$emit('toggle', $event)"
120
104
  >
@@ -142,6 +126,7 @@ import itfTextarea from '../text-field/Textarea.vue';
142
126
  import itfHoursField from '../text-field/HoursField.vue';
143
127
  import itfSelect from '../select/Select.vue';
144
128
  import itfTableBody from './TableBody.vue';
129
+ import { getIsMobileView } from "./mobile";
145
130
  // import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';
146
131
 
147
132
  export default @Component({
@@ -162,7 +147,6 @@ class itfTableRows extends Vue {
162
147
  @Prop() rows;
163
148
  @Prop() idProperty;
164
149
  @Prop() subrowsProperty;
165
- @Prop() asyncSubrowsProperty;
166
150
  @Prop() dividerProperty;
167
151
  @Prop() active;
168
152
  @Prop(Boolean) showAddColumn;
@@ -192,10 +176,8 @@ class itfTableRows extends Vue {
192
176
  return this.columns.findIndex((column) => column.lastPinned);
193
177
  }
194
178
 
195
- hasSubitems(item) {
196
- const hasFactItems = this.subrowsProperty && item[this.subrowsProperty] && item[this.subrowsProperty].length;
197
- const hasPlanItems = this.asyncSubrowsProperty && item[this.asyncSubrowsProperty] && item[this.asyncSubrowsProperty];
198
- return !!(hasFactItems || hasPlanItems);
179
+ getIsMobileView() {
180
+ return getIsMobileView();
199
181
  }
200
182
 
201
183
  updateValue(item, value, index, column) {
@@ -212,8 +194,20 @@ class itfTableRows extends Vue {
212
194
  }
213
195
  }
214
196
 
197
+ updateValues(item, values, index, column) {
198
+ const newItem = { ...item };
199
+ Object.assign(newItem, values);
200
+ this.$emit('update', {
201
+ index,
202
+ item,
203
+ inputValue: values,
204
+ value: newItem,
205
+ column
206
+ });
207
+ }
208
+
215
209
  isActive(id) {
216
- if (!this.idProperty || !this.active) {
210
+ if (!this.idProperty) {
217
211
  return false;
218
212
  }
219
213
  if (Array.isArray(this.active)) {
@@ -0,0 +1,4 @@
1
+ export
2
+ function getIsMobileView() {
3
+ return window.matchMedia('(max-width: 768px)').matches;
4
+ }
@@ -7,10 +7,10 @@
7
7
  --itf-table-alt-bg: #F9FAFB;
8
8
  --itf-table-alt-selected-bg: #eff1f3;
9
9
  --itf-table-header-bg: #f5f7f8;
10
- --itf-table-header-color: #575b63;
10
+ --itf-table-header-color: #7A818EA5;
11
11
  --itf-table-mirror-bg: #F2F4F7;
12
12
  --itf-table-border-color: transparent; //var(--itf-table-header-bg);
13
- --itf-table-header-border-color: #8E97A533;
13
+ --itf-table-header-border-color: #7A818E33;
14
14
  --itf-table-border-base-color: var(--itf-table-header-bg); // кольори границь таблиці без внутрішніх рядків
15
15
  --itf-table-border-base-width: 2px;
16
16
  --itf-table-hover-header-bg: #dfe5ef;
@@ -23,8 +23,6 @@
23
23
  --itf-table-summary-text: var(--bs-tertiary-color);
24
24
  --itf-table-table-border-radius: 1rem;
25
25
  --itf-table-header-height: 2.25rem;
26
- --itf-table-divider-bg: #F7F8FA;
27
- --itf-table-divider-border: rgba(238, 238, 238, 1);
28
26
 
29
27
  --group-title-height: 40px;
30
28
  --table-row-height: none;
@@ -45,9 +43,6 @@ body[data-theme="dark"] {
45
43
  --itf-table-selected-bg: #011534;
46
44
  --itf-table-active-bg: #022e72;
47
45
  --itf-table-summary-text: #82909d80;
48
- --itf-table-border-base-color: var(--itf-table-header-bg);
49
- --itf-table-divider-bg: #0f0f0f;
50
- --itf-table-divider-border: rgb(100, 100, 100, .1);
51
46
  }
52
47
  .itf-table2 {
53
48
  font-size: var(--itf-table-content-font-size, var(--itf-table-font-size));
@@ -65,7 +60,7 @@ body[data-theme="dark"] {
65
60
  height: 100%;
66
61
  }
67
62
  .scroller {
68
- //margin-bottom: .5rem;
63
+ margin-bottom: 12px;
69
64
  }
70
65
  .scrollable-x {
71
66
  overflow-x: scroll;
@@ -102,18 +97,34 @@ body[data-theme="dark"] {
102
97
  position: sticky;
103
98
  top: 0;
104
99
  bottom: 0;
105
- right: -5px;
100
+ right: -.5rem;
106
101
  z-index: 8;
107
- padding-right: 5px;
108
- padding-left: 5px;
109
102
  display: flex;
110
103
  align-items: center;
104
+
105
+ @media (max-width: 768px) {
106
+ position: relative;
107
+ opacity: 1;
108
+ }
111
109
  }
112
110
  .on-hover {
113
111
  opacity: 0;
112
+ width: 0;
113
+ padding: 4px .5rem;
114
+ overflow: hidden;
114
115
  pointer-events: none;
116
+ position: absolute;
117
+ right: 0;
118
+ background: linear-gradient(90deg, transparent 0, var(--itf-table2-row-bg) 10px);
119
+
120
+ @media (max-width: 768px) {
121
+ width: max-content;
122
+ opacity: 1;
123
+ position: relative;
124
+ }
115
125
  }
116
126
  .table-row-template:hover .on-hover {
127
+ width: max-content;
117
128
  opacity: 1;
118
129
  pointer-events: all;
119
130
  }
@@ -229,6 +240,9 @@ body[data-theme="dark"] {
229
240
  &:not(.draggable-container--is-dragging):hover .table-view-header-value {
230
241
  z-index: 39;
231
242
  }
243
+ &:not(.draggable-container--is-dragging):hover .sticky {
244
+ z-index: 40;
245
+ }
232
246
  &:after {
233
247
  content: "";
234
248
  position: absolute;
@@ -437,14 +451,20 @@ body[data-theme="dark"] {
437
451
  .indicator {
438
452
  border-left: var(--itf-table-border-base-width) solid var(--itf-table2-border-color);
439
453
  }
454
+
455
+ &.disabled {
456
+ .table-view-item-value {
457
+ opacity: 0.5;
458
+ }
459
+ }
440
460
  }
441
461
 
442
462
  &__row-divider {
443
- background-color: var(--itf-table-divider-bg);
463
+ background-color: #F7F8FA;
444
464
  height: 5px;
445
465
  padding: 0;
446
- border-top: 1px solid var(--itf-table-divider-border);
447
- border-bottom: 1px solid var(--itf-table-divider-border);
466
+ border-top: 1px solid rgba(238, 238, 238, 1);
467
+ border-bottom: 1px solid rgba(238, 238, 238, 1);
448
468
  }
449
469
  //&:hover, &.permanent-editable-border {
450
470
  // .table-view-item-value.editable {
@@ -457,7 +477,6 @@ body[data-theme="dark"] {
457
477
  position: relative;
458
478
  z-index: 2;
459
479
  width: 100%;
460
- display: flex;
461
480
  height: 100%;
462
481
  background: var(--itf-table2-row-bg)
463
482
  }
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="itf-money-field ph-no-capture" :class="{'currency-arrow': !currencyDisabled, 'currency-select': currencySelect}">
3
- <div :class="{'input-group h-100': noCurrencySign}" :style="`--itf-money-field-padding-left: ${noCurrencySign ? 1 : selectedCurrencySymbol.length * 0.6 + 1}rem`">
3
+ <div class="h-100" :class="{'input-group h-100': noCurrencySign}" :style="`--itf-money-field-padding-left: ${noCurrencySign ? 1 : selectedCurrencySymbol.length * 0.6 + 1}rem`">
4
4
  <span class="itf-money-field__prepend" v-if="!noCurrencySign">{{ selectedCurrencySymbol }}</span>
5
5
  <i-mask-component
6
6
  ref="input"
@@ -9,6 +9,7 @@
9
9
  :class="{ 'is-invalid': isInvalid(), 'is-valid': isSuccess() }"
10
10
  @input="setValue"
11
11
  :value="maskedValue"
12
+ :placeholder="placeholder"
12
13
  :unmask="false"
13
14
  :disabled="disabled"
14
15
  />
@@ -100,6 +101,7 @@ class itfMoneyField extends Vue {
100
101
  @Inject({ default: null }) itemLabel;
101
102
 
102
103
  @Model('input', { default: '' }) value;
104
+ @Prop({ default: '' }) placeholder;
103
105
  @Prop({ type: Object, default: null }) currency;
104
106
  @Prop({ type: Boolean, default: false }) noCurrencySign;
105
107
  @Prop({ type: Boolean, default: false }) disabled;
@@ -145,7 +147,7 @@ class itfMoneyField extends Vue {
145
147
  }
146
148
 
147
149
  onCurrencyChanged(e) {
148
- const currency = this.currenciesList.find((c) => c[this.itemKey] === parseInt(e.target.value));
150
+ const currency = this.currenciesList.find((c) => `${c[this.itemKey]}` === `${e.target.value}`);
149
151
  this.$emit('update:currency', currency)
150
152
  }
151
153
 
@@ -154,11 +156,11 @@ class itfMoneyField extends Vue {
154
156
  }
155
157
 
156
158
  get selectedCurrencySymbol() {
157
- return this.selectedCurrency ? this.selectedCurrency[this.symbolKey] : '#';
159
+ return this.selectedCurrency ? this.selectedCurrency[this.symbolKey] : '';
158
160
  }
159
161
 
160
162
  get selectedCurrencyCode() {
161
- return this.selectedCurrency ? this.selectedCurrency[this.codeKey] : '###';
163
+ return this.selectedCurrency ? this.selectedCurrency[this.codeKey] : '';
162
164
  }
163
165
 
164
166
  get currencyId() {
@@ -173,6 +175,10 @@ class itfMoneyField extends Vue {
173
175
  }
174
176
 
175
177
  setValue (val) {
178
+ if (val === '') {
179
+ this.$emit('input', '');
180
+ return;
181
+ }
176
182
  if (!isNumeric(val) || (val || '').toString().match(/\..*0$/)) { // що не видаляло останній нуль вкінці
177
183
  return;
178
184
  }