bfg-common 1.4.860 → 1.4.862

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 (143) hide show
  1. package/assets/scss/common/normalize.scss +361 -361
  2. package/components/atoms/TheIcon3.vue +50 -50
  3. package/components/atoms/autocomplete/Autocomplete.vue +301 -301
  4. package/components/atoms/collapse/CollapseNav.vue +164 -164
  5. package/components/atoms/dropdown/dropdown/Dropdown.vue +168 -168
  6. package/components/atoms/modal/bySteps/BySteps.vue +253 -253
  7. package/components/atoms/stack/StackBlock.vue +185 -185
  8. package/components/atoms/table/dataGrid/DataGrid.vue +1704 -1704
  9. package/components/atoms/table/dataGrid/DataGridColumnSwitch.vue +222 -222
  10. package/components/atoms/table/dataGrid/lib/config/settingsTable.ts +94 -94
  11. package/components/atoms/table/dataGrid/lib/utils/export.ts +16 -16
  12. package/components/common/browse/BrowseNew.vue +237 -237
  13. package/components/common/browse/BrowseOld.vue +217 -217
  14. package/components/common/browse/blocks/contents/Files.vue +37 -37
  15. package/components/common/browse/blocks/contents/FilesOld.vue +72 -72
  16. package/components/common/browse/blocks/contents/filesNew/FilesNew.vue +96 -96
  17. package/components/common/browse/blocks/contents/filesNew/Skeleton.vue +18 -18
  18. package/components/common/context/Context.vue +111 -111
  19. package/components/common/context/lib/models/interfaces.ts +30 -30
  20. package/components/common/context/recursion/Recursion.vue +87 -87
  21. package/components/common/context/recursion/RecursionOld.vue +227 -227
  22. package/components/common/details/DetailsItem.vue +109 -109
  23. package/components/common/graph/Graph.vue +104 -104
  24. package/components/common/layout/theHeader/helpMenu/About.vue +82 -82
  25. package/components/common/layout/theHeader/helpMenu/aboutNew/AboutNew.vue +103 -103
  26. package/components/common/modals/unsavedChanges/UnsavedChanges.vue +56 -56
  27. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/table/lib/config/utils.ts +1040 -1040
  28. package/components/common/monitor/overview/OverviewNew.vue +142 -142
  29. package/components/common/monitor/overview/OverviewOld.vue +139 -139
  30. package/components/common/monitor/overview/filters/Filters.vue +166 -166
  31. package/components/common/monitor/overview/filters/FiltersNew.vue +172 -172
  32. package/components/common/monitor/overview/filters/FiltersOld.vue +151 -151
  33. package/components/common/monitor/overview/filters/customIntervalModal/CustomIntervalModal.vue +175 -175
  34. package/components/common/monitor/overview/filters/customIntervalModal/CustomIntervalModalOld.vue +161 -161
  35. package/components/common/pages/home/StatusContent.vue +49 -49
  36. package/components/common/pages/home/headline/Headline.vue +45 -45
  37. package/components/common/pages/home/headline/HeadlineOld.vue +42 -42
  38. package/components/common/pages/home/lib/models/interfaces.ts +48 -48
  39. package/components/common/pages/home/widgets/Widgets.vue +49 -49
  40. package/components/common/pages/home/widgets/WidgetsNew.vue +86 -86
  41. package/components/common/pages/home/widgets/WidgetsOld.vue +34 -34
  42. package/components/common/pages/home/widgets/hosts/Hosts.vue +27 -27
  43. package/components/common/pages/home/widgets/hosts/lib/config/items.ts +23 -23
  44. package/components/common/pages/home/widgets/vms/Vms.vue +26 -26
  45. package/components/common/pages/home/widgets/vms/VmsOld.vue +35 -35
  46. package/components/common/pages/home/widgets/vms/lib/config/items.ts +19 -19
  47. package/components/common/pages/packages/Packages.vue +208 -208
  48. package/components/common/recursionTree/RecursionTree.vue +223 -223
  49. package/components/common/select/button/ButtonDropdown.vue +108 -108
  50. package/components/common/spiceConsole/Drawer.vue +370 -370
  51. package/components/common/spiceConsole/lib/models/interfaces.ts +5 -5
  52. package/components/common/split/horizontal/HorizontalNew.vue +376 -376
  53. package/components/common/split/horizontal/HorizontalOld.vue +337 -337
  54. package/components/common/split/vertical/Vertical.vue +160 -160
  55. package/components/common/vm/actions/add/Add.vue +621 -621
  56. package/components/common/vm/actions/clone/Clone.vue +639 -639
  57. package/components/common/vm/actions/clone/lib/config/steps.ts +129 -129
  58. package/components/common/vm/actions/common/customizeHardware/CustomizeHardware.vue +271 -271
  59. package/components/common/vm/actions/common/customizeHardware/CustomizeHardwareNew.vue +271 -271
  60. package/components/common/vm/actions/common/customizeHardware/CustomizeHardwareOld.vue +174 -174
  61. package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardware.vue +694 -694
  62. package/components/common/vm/actions/common/customizeHardware/virtualHardware/browseView/BrowseView.vue +219 -219
  63. package/components/common/vm/actions/common/customizeHardware/virtualHardware/bus/BusNew.vue +117 -117
  64. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDriveNew.vue +161 -161
  65. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDriveOld.vue +165 -165
  66. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/Media.vue +25 -25
  67. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/MediaNew.vue +70 -70
  68. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/MediaOld.vue +50 -50
  69. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/Cpu.vue +338 -338
  70. package/components/common/vm/actions/common/customizeHardware/virtualHardware/limit/Limit.vue +220 -220
  71. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +364 -364
  72. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDiskNew.vue +229 -229
  73. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDiskOld.vue +247 -247
  74. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/mode/ModeOld.vue +56 -56
  75. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/sharing/SharingNew.vue +44 -44
  76. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/NewNetwork.vue +283 -283
  77. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/NewNetworkNew.vue +124 -124
  78. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/location/LocationOld.vue +134 -134
  79. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/location/new/New.vue +63 -63
  80. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/location/new/table/lib/config/config.ts +95 -95
  81. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddress.vue +119 -119
  82. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddressNew.vue +69 -69
  83. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddressOld.vue +83 -83
  84. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/NewPciDevice.vue +205 -205
  85. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/directPathIo/DirectPathIoNew.vue +66 -66
  86. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/directPathIo/DirectPathIoOld.vue +62 -62
  87. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIo.vue +31 -31
  88. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIoNew.vue +84 -84
  89. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIoOld.vue +76 -76
  90. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/Note.vue +15 -15
  91. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/NoteNew.vue +42 -42
  92. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/NoteOld.vue +30 -30
  93. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/nvidiaGrid/NvidiaGrid.vue +41 -41
  94. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/nvidiaGrid/NvidiaGridNew.vue +81 -81
  95. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/nvidiaGrid/NvidiaGridOld.vue +84 -84
  96. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newUsbController/NewUsbControllerNew.vue +56 -56
  97. package/components/common/vm/actions/common/customizeHardware/virtualHardware/other/Other.vue +16 -16
  98. package/components/common/vm/actions/common/customizeHardware/virtualHardware/other/OtherNew.vue +30 -30
  99. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCardNew.vue +104 -104
  100. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCardOld.vue +112 -112
  101. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/totalVideoMemory/TotalVideoMemoryNew.vue +54 -54
  102. package/components/common/vm/actions/common/customizeHardware/vmoptions/Vmoptions.vue +145 -145
  103. package/components/common/vm/actions/common/customizeHardware/vmoptions/VmoptionsNew.vue +102 -102
  104. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/BootOptionsNew.vue +75 -75
  105. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/delay/Delay.vue +26 -26
  106. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/firmware/Firmware.vue +57 -57
  107. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/firmware/FirmwareNew.vue +42 -42
  108. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/menu/MenuNew.vue +25 -25
  109. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/Order.vue +171 -171
  110. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/OrderNew.vue +50 -50
  111. package/components/common/vm/actions/common/customizeHardware/vmoptions/generalOptions/GeneralOptionsNew.vue +141 -141
  112. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/New.vue +140 -140
  113. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/copyPaste/CopyPasteNew.vue +30 -30
  114. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/fileTransfer/FileTransferNew.vue +30 -30
  115. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/folderSharing/FolderSharingNew.vue +30 -30
  116. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/Keymap.vue +32 -32
  117. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/KeymapNew.vue +39 -39
  118. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/Password.vue +103 -103
  119. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/PasswordNew.vue +102 -102
  120. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/PasswordOld.vue +94 -94
  121. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirection.vue +28 -28
  122. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirectionNew.vue +38 -38
  123. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirectionOld.vue +44 -44
  124. package/components/common/vm/actions/common/select/storage/Storage.vue +130 -130
  125. package/components/common/vm/actions/common/select/storage/StorageOld.vue +129 -129
  126. package/components/common/vm/actions/editSettings/new/Skeleton.vue +88 -88
  127. package/components/common/wizards/datastore/add/lib/config/steps.ts +138 -138
  128. package/components/common/wizards/vm/migrate/Migrate.vue +302 -302
  129. package/components/common/wizards/vm/migrate/lib/config/constructDataReady.ts +220 -220
  130. package/components/common/wizards/vm/migrate/select/network/Network.vue +103 -103
  131. package/components/common/wizards/vm/migrate/select/network/table/network/Network.vue +150 -150
  132. package/components/common/wizards/vm/migrate/select/network/table/network/lib/config/advancedTable.ts +91 -91
  133. package/components/common/wizards/vm/migrate/select/priority/Priority.vue +43 -43
  134. package/composables/productNameLocal.ts +30 -30
  135. package/composables/useAppVersion.ts +21 -21
  136. package/package.json +1 -1
  137. package/plugins/date.ts +233 -233
  138. package/plugins/recursion.ts +311 -311
  139. package/public/spice-console/lib/images/bitmap.js +203 -203
  140. package/public/spice-console/network/spicechannel.js +383 -383
  141. package/store/main/mutations.ts +7 -7
  142. package/store/main/state.ts +7 -7
  143. package/store/tasks/mappers/recentTasks.ts +64 -64
@@ -1,1704 +1,1704 @@
1
- <template>
2
- <div class="relative" style="display: flex">
3
- <div
4
- :id="outerWrapper"
5
- :class="[
6
- 'datagrid-outer-wrapper',
7
- {
8
- 'datagrid-outer-wrapper-opened-info': isShowHiddenInfo,
9
- },
10
- ]"
11
- >
12
- <div class="datagrid-inner-wrapper">
13
- <div
14
- v-if="props.isMainFilter"
15
- class="main-filter-content flex-justify-end"
16
- >
17
- <atoms-the-icon class="filter-icon" name="filter" />
18
- <input
19
- :id="`${props.testId}-main-filter-input`"
20
- v-model.trim="mainFilter"
21
- :data-id="`${props.testId}-main-filter-input`"
22
- :placeholder="props.mainFilterPlaceholder"
23
- type="text"
24
- @input="emits('main-filter', mainFilter)"
25
- />
26
- </div>
27
- <div
28
- :class="[
29
- 'datagrid',
30
- {
31
- 'datagrid-opened-info': isShowHiddenInfo,
32
- },
33
- ]"
34
- >
35
- <div :id="tableWrapperId" class="datagrid-table-wrapper">
36
- <div class="datagrid-table" :data-id="props.testId">
37
- <div class="datagrid-header">
38
- <div class="datagrid-row">
39
- <div class="datagrid-row-master datagrid-row-flex">
40
- <div
41
- v-if="props.type || $slots.toggleBlock"
42
- class="datagrid-row-sticky"
43
- >
44
- <div
45
- v-if="props.type"
46
- :id="expandableCaret"
47
- class="datagrid-column datagrid-expandable-caret datagrid-fixed-column flex-align-center flex-justify-center"
48
- >
49
- <template v-if="props.type === 'checkbox'">
50
- <div
51
- class="clr-checkbox-wrapper flex-align-center flex-justify-center w-100"
52
- >
53
- <input
54
- :id="`${props.testId}-${inputId}-all`"
55
- v-model="selectedAll"
56
- :data-id="`${props.testId}-filter-all`"
57
- type="checkbox"
58
- class="checkbox-btn"
59
- :value="-1"
60
- @change="changeAll"
61
- />
62
- <label
63
- :for="`${props.testId}-${inputId}-all`"
64
- class="clr-control-label"
65
- />
66
- </div>
67
- <div class="datagrid-column-separator"></div>
68
- </template>
69
- </div>
70
- <div
71
- v-if="$slots.toggleBlock"
72
- class="datagrid-toggle-block datagrid-column datagrid-fixed-width"
73
- >
74
- <div class="datagrid-column-flex">
75
- <div class="datagrid-column-separator">
76
- <span class="clr-sr-only" />
77
- <div class="datagrid-column-resize-tracker" />
78
- </div>
79
- </div>
80
- </div>
81
- </div>
82
- <div class="datagrid-row-scrollable">
83
- <div
84
- v-for="(item, key) in headItemsPresent"
85
- :key="key"
86
- :style="{
87
- width: columnsWidth[key][0],
88
- minWidth: columnsWidth[key][1],
89
- }"
90
- class="datagrid-column datagrid-fixed-width"
91
- >
92
- <div class="datagrid-column-flex">
93
- <button
94
- :id="`${props.testId}-sort-column-${key}`"
95
- :data-id="`${item.testId}-sort-column`"
96
- :class="[
97
- 'datagrid-column-title',
98
- {
99
- 'default text-decoration-none':
100
- !item.sortColumn,
101
- },
102
- ]"
103
- @click="sortTable(item.sortColumn)"
104
- >
105
- <slot :key="key" name="th" :item="item">
106
- <span
107
- :title="item.text"
108
- :style="{
109
- width:
110
- columnsWidth[key][0]?.slice(0, -2) -
111
- (item.hasFilter ? 65 : 40) +
112
- 'px',
113
- }"
114
- class="title-column"
115
- >
116
- {{ item.text }}
117
- </span>
118
- </slot>
119
- <span
120
- v-if="item.sortColumn"
121
- class="sort-arrow-wrap"
122
- >
123
- <atoms-the-icon
124
- v-show="sortInfo[0] === item.sortColumn"
125
- :class="['sort-arrow', { down: sortInfo[1] }]"
126
- name="sort-arrow"
127
- />
128
- </span>
129
- </button>
130
- <button
131
- v-if="item.hasFilter"
132
- :id="`${props.testId}-filter-icon-${key}`"
133
- :data-id="`${item.testId}-filter-icon`"
134
- class="datagrid-filter-toggle clr-anchor clr-smart-open-close"
135
- @click="filterShow[key] = !filterShow[key]"
136
- >
137
- <atoms-the-icon
138
- v-if="filterTerm[key]"
139
- class="filter-icon"
140
- name="filter-solid"
141
- style="fill: #0079b8"
142
- />
143
- <atoms-the-icon
144
- v-else
145
- class="filter-icon"
146
- name="filter"
147
- />
148
- </button>
149
- <atoms-popup-simple-popup
150
- v-model="filterShow[key]"
151
- :test-id="`${props.testId}-filter`"
152
- top="100%"
153
- :left="key === 0 ? '0' : ''"
154
- :right="key !== 0 ? '0' : ''"
155
- >
156
- <input
157
- :id="`${props.testId}-filter-input-${key}`"
158
- v-model="filterTerm[key]"
159
- :data-id="`${item.testId}-filter-input`"
160
- type="text"
161
- @input="filtering"
162
- />
163
- </atoms-popup-simple-popup>
164
- <div
165
- v-show="
166
- !isShowHiddenInfo ||
167
- (isShowHiddenInfo && key === 0)
168
- "
169
- :class="[
170
- 'datagrid-column-separator',
171
- {
172
- 'double-arrow-separator':
173
- key === 0 && props.withInfo,
174
- },
175
- ]"
176
- @mousedown="setGrab(key, $event)"
177
- >
178
- <button
179
- :id="`${props.testId}-resize-tracker-${key}`"
180
- class="datagrid-column-handle drag-handle draggable"
181
- />
182
- <span class="clr-sr-only" />
183
- <div class="datagrid-column-resize-tracker" />
184
- </div>
185
- </div>
186
- </div>
187
- </div>
188
- </div>
189
- </div>
190
- </div>
191
-
192
- <template v-if="bodyItemsPresent.length">
193
- <div
194
- v-for="(item, key) in bodyItemsPresent"
195
- :key="item.id"
196
- :class="[
197
- 'datagrid-body-row datagrid-row animation',
198
- {
199
- 'datagrid-selected active': checkIsSelectedRow(
200
- item[0].id
201
- ),
202
- 'datagrid-selected-info':
203
- props.withInfo &&
204
- isShowHiddenInfo &&
205
- checkIsSelectedRow(item[0].id),
206
- },
207
- ]"
208
- :[props.rowAttributeIdName]="item[0].dataId"
209
- >
210
- <div>
211
- <div
212
- :data-id="`${item[0].testId}-select-row`"
213
- class="datagrid-row-master datagrid-row-flex"
214
- @click.stop="selectRowById(item[0])"
215
- >
216
- <div
217
- v-if="props.type || $slots.toggleBlock"
218
- class="datagrid-row-sticky"
219
- @click.stop
220
- >
221
- <div
222
- :id="expandableCaret"
223
- :class="[
224
- 'datagrid-expandable-caret flex-justify-center datagrid-cell',
225
- {
226
- 'datagrid-fixed-column': !props.withInfo,
227
- 'datagrid-fixed-column-without-separator':
228
- props.withInfo,
229
- },
230
- ]"
231
- >
232
- <!--TODO refactoring (duplicate)-->
233
- <div
234
- v-if="$slots.toggleBlock && !props.type"
235
- class="datagrid-cell datagrid-fixed-width"
236
- >
237
- <div
238
- v-if="item[0]?.isShowToggleIcon ?? true"
239
- class="flex-align-center"
240
- >
241
- <button
242
- :id="`${props.testId}-toggle-icon-${key}`"
243
- :data-id="`${item[0].testId}-toggle-button`"
244
- class="datagrid-expandable-caret-button reset-btn"
245
- @click="toggle(key)"
246
- >
247
- <atoms-the-icon
248
- :class="[
249
- 'datagrid-expandable-caret-icon',
250
- { toggle: toggedItems[key] },
251
- ]"
252
- name="angle"
253
- />
254
- </button>
255
- </div>
256
- </div>
257
- <slot
258
- v-if="props.type"
259
- :key="key"
260
- name="type"
261
- :item="item"
262
- >
263
- <div
264
- :class="
265
- item[0]?.disabled && 'clr-form-control-disabled'
266
- "
267
- >
268
- <div
269
- :class="`clr-${props.type}-wrapper flex-justify-center flex-align-center`"
270
- >
271
- <input
272
- :id="`${props.testId}-${inputId}-${item[0].id}`"
273
- :key="item[0].id"
274
- v-model="selectedRowLocal"
275
- :data-id="`${item[0].testId}-row-selection-input`"
276
- :type="props.type"
277
- :class="`${props.type}-btn`"
278
- :value="item[0].id"
279
- :disabled="item[0]?.disabled || false"
280
- name="selected-store"
281
- @change="
282
- changeSelectedRow($event, item[0].id)
283
- "
284
- />
285
- <label
286
- :for="`${props.testId}-${inputId}-${item[0].id}`"
287
- class="clr-control-label"
288
- />
289
- </div>
290
- </div>
291
- </slot>
292
- </div>
293
- <!--TODO refactoring (duplicate)-->
294
- <div
295
- v-if="$slots.toggleBlock && props.type"
296
- class="datagrid-cell datagrid-fixed-width"
297
- >
298
- <div class="flex-align-center">
299
- <button
300
- :id="`${props.testId}-toggle-icon-${key}`"
301
- :data-id="`${item[0].testId}-toggle-row-button`"
302
- class="datagrid-expandable-caret-button reset-btn"
303
- @click="toggle(key)"
304
- >
305
- <atoms-the-icon
306
- :class="[
307
- 'datagrid-expandable-caret-icon',
308
- { toggle: toggedItems[key] },
309
- ]"
310
- name="angle"
311
- />
312
- </button>
313
- </div>
314
- </div>
315
- </div>
316
- <div class="datagrid-row-scrollable">
317
- <div class="datagrid-scrolling-cells">
318
- <div
319
- v-for="(item2, key2) in item"
320
- v-show="
321
- !isShowHiddenInfo ||
322
- item2.key === 'col1' ||
323
- item2.key === 'icon'
324
- "
325
- :key="key2"
326
- :style="{
327
- width: columnsWidth[key2][0],
328
- minWidth: columnsWidth[key2][1],
329
- }"
330
- :class="[
331
- 'datagrid-cell datagrid-fixed-width',
332
- {
333
- 'hidden-text-triangle':
334
- isShowHiddenInfo &&
335
- item2.data?.name === 'hidden-text-triangle',
336
- },
337
- ]"
338
- >
339
- <div
340
- :class="[
341
- 'flex-align-center h-100',
342
- {
343
- 'double-arrow-width':
344
- item2.data?.name === 'doubleArrows',
345
- },
346
- ]"
347
- >
348
- <div
349
- v-if="item2.data?.name === 'doubleArrows'"
350
- :id="`show-info-${item[0].data.id}`"
351
- :data-id="`${item[0].testId}-double-arrow`"
352
- :class="[
353
- 'double-arrow-wrap',
354
- {
355
- 'arrow-selected':
356
- isShowHiddenInfo &&
357
- item2.id === props.selectedRow,
358
- },
359
- ]"
360
- @click.prevent.stop="
361
- doubleArrowClick(item2, item)
362
- "
363
- >
364
- <atoms-the-icon
365
- v-if="item2.data?.name === 'doubleArrows'"
366
- name="doubleArrows"
367
- :class="[
368
- 'double-arrow',
369
- {
370
- 'arrow-selected':
371
- isShowHiddenInfo &&
372
- item2.id === props.selectedRow,
373
- },
374
- ]"
375
- />
376
- </div>
377
- <span
378
- v-if="item2.text && item2.data?.iconClassName"
379
- class="vertical-divider"
380
- />
381
- <slot :name="item2.key" :item="item2">
382
- <span class="text-ellipsis" :title="item2.text"
383
- >{{ item2.text }}
384
- </span>
385
- </slot>
386
- </div>
387
- </div>
388
- </div>
389
- <div
390
- v-show="toggedItems[key]"
391
- class="datagrid-row-flex datagrid-row-detail datagrid-container"
392
- >
393
- <slot name="toggleBlock" :item="item" />
394
- </div>
395
- </div>
396
- </div>
397
- </div>
398
- </div>
399
- </template>
400
- <template v-else>
401
- <div class="datagrid-placeholder-container">
402
- <div class="datagrid-placeholder datagrid-empty">
403
- <div class="datagrid-placeholder-image"></div>
404
-
405
- <span>No items found</span>
406
- </div>
407
- </div>
408
- </template>
409
- </div>
410
- </div>
411
- </div>
412
-
413
- <div
414
- v-if="!hideFooter"
415
- :class="[
416
- 'datagrid-footer',
417
- {
418
- 'datagrid-footer-opened-info': isShowHiddenInfo,
419
- },
420
- ]"
421
- >
422
- <div
423
- v-if="props.type === 'checkbox' && props.selectedRow?.length"
424
- class="clr-form-control-disabled"
425
- >
426
- <div class="clr-checkbox-wrapper">
427
- <input
428
- :id="`${props.testId}-check-all`"
429
- :data-id="`${props.testId}-check-all`"
430
- type="checkbox"
431
- checked
432
- />
433
- <label class="clr-control-label">
434
- {{ props.selectedRow?.length }}
435
- </label>
436
- </div>
437
- </div>
438
- <div class="datagrid-footer-description flex-align-center">
439
- <atoms-table-data-grid-column-switch
440
- v-if="columnKeysLocal"
441
- v-model:column-keys="columnKeysLocal"
442
- :test-id="`${props.testId}-footer-description`"
443
- class="switch-icon"
444
- />
445
-
446
- <template v-if="props.isShowExport && bodyItemsPresent.length">
447
- <common-select-button-dropdown
448
- v-if="props.selectedRow?.length"
449
- :heading="localization.common.export"
450
- :items="exportItems"
451
- :test-id="`${props.testId}-export-btn`"
452
- class="properties__actions"
453
- is-top
454
- @click="onExport"
455
- />
456
- <button
457
- v-else
458
- class="export-link dropdown-toggle btn btn-sm btn-link"
459
- @click="onExportAll"
460
- >
461
- {{ localization.common.export }}
462
- </button>
463
- </template>
464
-
465
- <div v-if="$slots.action" class="datagrid-footer__action">
466
- <slot name="action" />
467
- </div>
468
- </div>
469
-
470
- <atoms-table-data-grid-pagination
471
- :test-id="props.testId"
472
- :page-size="props.pageSize"
473
- :page="props.page"
474
- :options="mergeOptions"
475
- :total-items="props.totalItems"
476
- :total-pages="props.totalPages"
477
- :hide-pagination="props.hidePagination"
478
- :hide-page-size="props.hidePageSize"
479
- :show-page-info="props.showPageInfo"
480
- :page-items-count="props.bodyItems.length"
481
- :is-show-hidden-info="isShowHiddenInfo"
482
- @change-page-size="changePageSize"
483
- @change-page="changePage"
484
- />
485
- </div>
486
-
487
- <atoms-loader
488
- v-show="props.loading"
489
- class="datagrid-spinner"
490
- :test-id="`${props.testId}-spinner`"
491
- />
492
- </div>
493
- </div>
494
- <div
495
- v-if="isShowInfo"
496
- id="hidden-features"
497
- :class="[
498
- 'hidden-features',
499
- {
500
- 'show-hidden-info': isShowHiddenInfo,
501
- },
502
- ]"
503
- >
504
- <!-- <div class="header">-->
505
- <!-- <slot name="hiddenInfoHeader" :item="showedInfoCol" />-->
506
- <!-- <button-->
507
- <!-- :id="`${props.testId}-hidden-info-toggle-icon-${showedInfoRow?.key}-${showedInfoRow?.data.name}`"-->
508
- <!-- :data-id="`${props.testId}-hidden-info-toggle-icon`"-->
509
- <!-- class="signpost-action close"-->
510
- <!-- @click="isShowHiddenInfo = false"-->
511
- <!-- >-->
512
- <!-- <atoms-the-icon class="close-icon" name="close" />-->
513
- <!-- </button>-->
514
- <!-- </div>-->
515
- <!-- <slot name="hiddenInfoBody" />-->
516
- <button
517
- :id="`${props.testId}-hidden-info-toggle-icon-${showedInfoRow?.key}-${showedInfoRow?.data.name}`"
518
- :data-id="`${props.testId}-hidden-info-toggle-icon`"
519
- class="signpost-action close"
520
- @click="isShowHiddenInfo = false"
521
- >
522
- <atoms-the-icon class="close-icon" name="close" />
523
- </button>
524
- <slot name="hiddenInfo" :item="showedInfoCol" />
525
- </div>
526
- </div>
527
- </template>
528
-
529
- <script setup lang="ts">
530
- import { isRtl } from 'bfg-uikit/lib/config/trl'
531
- import type {
532
- UI_I_HTMLSelectElement,
533
- UI_I_Localization,
534
- } from '~/lib/models/interfaces'
535
- import type {
536
- UI_I_HeadItem,
537
- UI_I_BodyItem,
538
- UI_I_ColumnKey,
539
- } from '~/components/atoms/table/dataGrid/lib/models/interfaces'
540
- import type {
541
- UI_T_ColumnKeys,
542
- UI_T_DataGridType,
543
- UI_T_SelectedRow,
544
- } from '~/components/atoms/table/dataGrid/lib/models/types'
545
- import type { UI_I_OptionItem } from '~/components/atoms/lib/models/interfaces'
546
- import type { UI_I_DropdownButtonItem } from '~/components/common/select/button/lib/models/interfaces'
547
- import { itemsPerPage } from '~/components/atoms/table/dataGrid/lib/config/itemsPerPage'
548
- import { exportItemsFunc } from '~/components/atoms/table/dataGrid/lib/config/settingsTable'
549
- import { generateCsvAndDownload } from '~/components/atoms/table/dataGrid/lib/utils/export'
550
-
551
- const props = withDefaults(
552
- defineProps<{
553
- headItems: UI_I_HeadItem[]
554
- bodyItems: UI_I_BodyItem[][]
555
- pageSize: number
556
- page: number
557
- totalItems: number
558
- totalPages: number
559
- loading?: boolean
560
- columnKeys?: UI_I_ColumnKey[]
561
- selectedRow?: UI_T_SelectedRow
562
- type?: UI_T_DataGridType
563
- itemsPerPage?: UI_I_OptionItem[]
564
- offSelectByRow?: boolean
565
- hidePageSize?: boolean
566
- showPageInfo?: boolean
567
- serverOff?: boolean
568
- fillWidth?: boolean
569
- hideFooter?: boolean
570
- hidePagination?: boolean
571
- testId?: string
572
- withInfo?: boolean
573
- rowAttributeIdName?: string
574
- isMainFilter?: boolean
575
- mainFilterPlaceholder?: string
576
- isShowExport?: boolean
577
- }>(),
578
- {
579
- columnKeys: undefined,
580
- selectedRow: undefined,
581
- type: undefined,
582
- itemsPerPage: undefined,
583
- fillWidth: true,
584
- testId: 'ui-data-grid',
585
- withInfo: false,
586
- rowAttributeIdName: 'data-id',
587
- isShowExport: false,
588
- }
589
- )
590
-
591
- const emits = defineEmits<{
592
- (event: 'update:column-keys', value: UI_T_ColumnKeys): void
593
- (event: 'update:selected-row', value: UI_T_SelectedRow): void
594
- (event: 'update:page-size', value: number): void
595
- (event: 'update:page', value: number): void
596
- (event: 'main-filter', value: string): void
597
- (event: 'filtering', value: string[][]): void
598
- (event: 'sorting', value: [string, boolean]): void
599
- (event: 'change', value: any): void
600
- (event: 'row-detail', value: number): void
601
- }>()
602
-
603
- const localization = computed<UI_I_Localization>(() => useLocal())
604
-
605
- const mainFilter = ref<string>('')
606
-
607
- const mergeOptions = computed<UI_I_OptionItem[]>(
608
- () => props.itemsPerPage || itemsPerPage
609
- )
610
-
611
- const inputId = ref<string>(`radio-input-${useUniqueId()}`)
612
-
613
- const columnKeysLocal = computed<UI_T_ColumnKeys>({
614
- get() {
615
- return props.columnKeys
616
- },
617
- set(newValue) {
618
- emits('update:column-keys', newValue)
619
- },
620
- })
621
-
622
- const selectedAll = ref<boolean>(false)
623
- const changeAll = (e: UI_I_HTMLSelectElement): void => {
624
- const newSelectedRow: (number | string)[] = []
625
- if (e.target.checked) {
626
- bodyItemsPresent.value.forEach((row) => {
627
- if (row[0]?.disabled) return
628
-
629
- newSelectedRow.push(row[0].id)
630
- })
631
- }
632
-
633
- emits('update:selected-row', newSelectedRow)
634
- }
635
-
636
- const selectedRowLocal = ref<UI_T_SelectedRow>([])
637
- const isShowHiddenInfo = ref<boolean>(false)
638
- const tableWrapperId = `table-wrapper-${useUniqueId()}`
639
- let memoryWidth = '0'
640
-
641
- const showedInfoRow = ref<UI_I_BodyItem | null>(null)
642
- const showedInfoCol = ref<UI_I_BodyItem[] | null>(null)
643
-
644
- const isShowInfo = computed(
645
- () =>
646
- showedInfoRow.value &&
647
- showedInfoRow.value.id === props.selectedRow &&
648
- !showedInfoRow.value.data?.text &&
649
- isShowHiddenInfo.value
650
- )
651
-
652
- const setShowedInfoData = (
653
- item: UI_I_BodyItem | null,
654
- items: UI_I_BodyItem[] | null,
655
- reset: boolean = false
656
- ): void => {
657
- showedInfoRow.value = item
658
- showedInfoCol.value = items
659
-
660
- reset && (isShowHiddenInfo.value = false)
661
- item && selectRowById(item)
662
- reset && (isShowHiddenInfo.value = true)
663
- }
664
-
665
- const doubleArrowClick = (
666
- item: UI_I_BodyItem,
667
- items: UI_I_BodyItem[]
668
- ): void => {
669
- if (!isShowHiddenInfo.value) {
670
- setShowedInfoData(item, items)
671
- } else {
672
- if (showedInfoRow.value?.id !== item.id) {
673
- setShowedInfoData(item, items, true)
674
-
675
- return
676
- } else {
677
- setShowedInfoData(null, null)
678
- }
679
- }
680
-
681
- isShowHiddenInfo.value = !isShowHiddenInfo.value
682
- }
683
-
684
- watch(
685
- () => props.selectedRow,
686
- (newValue) => {
687
- if (newValue === undefined) return
688
-
689
- if (Array.isArray(newValue) && !newValue.length) selectedAll.value = false
690
-
691
- selectedRowLocal.value = newValue
692
- },
693
- { immediate: true }
694
- )
695
- const selectRowById = (item: UI_I_BodyItem): void => {
696
- const { id, disabled } = item
697
-
698
- if (props.offSelectByRow || isShowHiddenInfo.value || disabled) return
699
-
700
- if (props.type === 'checkbox' && Array.isArray(selectedRowLocal.value)) {
701
- const has = selectedRowLocal.value.includes(id)
702
- if (has) {
703
- selectedRowLocal.value = selectedRowLocal.value.filter(
704
- (rowId: string | number) => rowId !== id
705
- )
706
- } else {
707
- selectedRowLocal.value.push(id)
708
- }
709
-
710
- emits('change', selectedRowLocal.value)
711
- emits('update:selected-row', selectedRowLocal.value)
712
-
713
- changeSelectedAll(!has)
714
- return
715
- }
716
-
717
- emits('change', id)
718
- emits('update:selected-row', id)
719
- }
720
- const changeSelectedRow = (
721
- e: UI_I_HTMLSelectElement,
722
- id: number | string
723
- ): void => {
724
- if (props.type === 'checkbox' && Array.isArray(selectedRowLocal.value)) {
725
- const newSelectedRow = [...selectedRowLocal.value]
726
- emits('change', newSelectedRow)
727
- emits('update:selected-row', newSelectedRow)
728
-
729
- changeSelectedAll(e.target.checked)
730
- return
731
- }
732
-
733
- emits('change', id)
734
- emits('update:selected-row', id)
735
- }
736
- const changeSelectedAll = (checked: boolean): void => {
737
- if (props.type === 'checkbox' && Array.isArray(selectedRowLocal.value)) {
738
- const newSelectedRow = [...selectedRowLocal.value]
739
-
740
- if (!checked) {
741
- selectedAll.value = false
742
- } else if (newSelectedRow.length === bodyItemsPresent.value.length) {
743
- selectedAll.value = true
744
- }
745
- }
746
- }
747
-
748
- const checkIsSelectedRow = (id: number | string): boolean => {
749
- if (props.type === 'checkbox' && Array.isArray(props.selectedRow)) {
750
- return props.selectedRow.includes(id)
751
- }
752
- return props.selectedRow === id
753
- }
754
-
755
- // Sorting
756
- const sortInfo = ref<[string, boolean]>(['', true])
757
- const sortedColumnIndex = computed<number>(() => {
758
- let index = -1
759
- headItemsPresent.value.forEach((item, key) => {
760
- if (item.sortColumn === sortInfo.value[0]) index = key
761
- })
762
-
763
- return index
764
- })
765
- const sortTable = (sortName: string): void => {
766
- if (!sortName) return
767
-
768
- emits('update:selected-row', selectedRowLocal.value)
769
-
770
- if (sortInfo.value[0] === sortName) {
771
- sortInfo.value[1] = !sortInfo.value[1]
772
-
773
- emits('sorting', sortInfo.value)
774
- return
775
- }
776
- sortInfo.value[0] = sortName
777
- sortInfo.value[1] = true
778
-
779
- emits('sorting', sortInfo.value)
780
- }
781
-
782
- // Filtering
783
- const filterShow = ref<boolean[]>([])
784
- const filterTerm = ref<string[]>([])
785
- const filtering = (): void => {
786
- const filter: string[][] = []
787
- headItemsPresent.value.forEach((item, key) => {
788
- if (filterTerm.value[key]) filter.push([item.key, filterTerm.value[key]])
789
- })
790
-
791
- emits('filtering', filter)
792
- }
793
-
794
- // Pagination
795
- const changePageSize = (value: number): void => {
796
- emits('update:page-size', value)
797
- }
798
- const changePage = (value: number): void => {
799
- emits('update:selected-row', [])
800
- emits('update:page', value)
801
- }
802
-
803
- const headItemsPresent = computed<UI_I_HeadItem[]>(() => {
804
- if (!columnKeysLocal.value) {
805
- return props.headItems
806
- }
807
-
808
- return props.headItems.filter((item, key) => {
809
- return columnKeysLocal.value?.find(
810
- (item2, key2) => item2.key === item.key && key === key2
811
- )?.show
812
- })
813
- })
814
-
815
- const bodyItemsPresent = computed<UI_I_BodyItem[][]>(() => {
816
- let items: UI_I_BodyItem[][] = props.bodyItems
817
-
818
- // Filtering by column
819
- if (columnKeysLocal.value) {
820
- items = items.map((arr) => {
821
- arr = arr.filter((item, key) => {
822
- return columnKeysLocal.value?.find(
823
- (item2, key2) => item2.key === item.key && key === key2
824
- )?.show
825
- })
826
- return arr
827
- })
828
- }
829
-
830
- if (props.serverOff) {
831
- // Sorting
832
- if (sortInfo.value[0] !== '') {
833
- items = useDeepCopy(items).sort(
834
- (a: UI_I_BodyItem[], b: UI_I_BodyItem[]) => {
835
- let first = a[sortedColumnIndex.value].text.toString().toLowerCase()
836
- let second = b[sortedColumnIndex.value].text.toString().toLowerCase()
837
-
838
- const sortValueA = a[sortedColumnIndex.value]?.data?.sortValue
839
- const sortValueB = b[sortedColumnIndex.value]?.data?.sortValue
840
- if (sortValueA || sortValueA === 0) {
841
- first = sortValueA
842
- }
843
- if (sortValueB || sortValueB === 0) {
844
- second = sortValueB
845
- }
846
-
847
- if (sortInfo.value[1]) {
848
- return first > second ? 1 : first < second ? -1 : 0
849
- } else {
850
- return first < second ? 1 : first > second ? -1 : 0
851
- }
852
- }
853
- )
854
- }
855
- // Filtering
856
- const hasFilter = headItemsPresent.value.some(
857
- (_, key) => filterTerm.value[key]
858
- )
859
- if (hasFilter) {
860
- items = items.filter((row) => {
861
- // 0 - начальное значение
862
- // 1 - найден элемент
863
- // -1 - ненайден элемент
864
- let hasItem = 0
865
- headItemsPresent.value.forEach((item, key) => {
866
- if (!filterTerm.value[key]) return
867
- const term = filterTerm.value[key].toLowerCase()
868
-
869
- row.forEach((col) => {
870
- if (
871
- col.key === item.key &&
872
- typeof col.text === 'string' &&
873
- hasItem != -1
874
- ) {
875
- hasItem = col.text.toLowerCase().includes(term) ? 1 : -1
876
- }
877
- })
878
- })
879
-
880
- return hasItem === 1
881
- })
882
- }
883
- }
884
-
885
- return items
886
- })
887
-
888
- const toggedItems = ref<boolean[]>([])
889
-
890
- const toggle = (key: number): void => {
891
- toggedItems.value[key] = !toggedItems.value[key]
892
- if (!toggedItems.value[key]) return
893
- emits('row-detail', key)
894
- }
895
-
896
- const outerWrapper = `datagrid-outer-wrapper${useUniqueId()}`
897
- const expandableCaret = `datagrid-expandable-caret${useUniqueId()}`
898
-
899
- // Resize
900
- let helper = false
901
- let setColumnWidth = (): void => {
902
- if (!helper) {
903
- columnsWidth.value = []
904
- headItemsPresent.value.forEach((item) => {
905
- columnsWidth.value.push([
906
- item.width, // width
907
- item.width, // min-width
908
- ])
909
- })
910
-
911
- helper = true
912
- setTimeout(() => setColumnWidth(), 0)
913
- return
914
- }
915
- // Не продолжаем, чтобы ширина калонок была так как заданно в headItemsPresent
916
- if (!props.fillWidth) return
917
-
918
- // PC-672
919
- // const dataGridWidth = document.getElementById(outerWrapper)?.clientWidth || 0
920
- // const leftColumnWidth =
921
- // document.getElementById(expandableCaret)?.clientWidth || 0
922
- // const bordersWidth = 2
923
- // const columnWidth =
924
- // (dataGridWidth - leftColumnWidth - bordersWidth) /
925
- // headItemsPresent.value.length
926
-
927
- headItemsPresent.value.forEach((item) => {
928
- columnsWidth.value.push([
929
- // `${columnWidth}px`, // width
930
- item.width, // width
931
- item.width, // min-width
932
- ])
933
- })
934
- }
935
- setColumnWidth = useThrottle(setColumnWidth)
936
-
937
- const columnsWidth = ref<[string, string][]>([])
938
- watch(
939
- bodyItemsPresent,
940
- (newValue: UI_I_BodyItem[][]) => {
941
- newValue.forEach(() => {
942
- toggedItems.value.push(false)
943
- })
944
- setColumnWidth()
945
- },
946
- {
947
- immediate: true,
948
- deep: true,
949
- }
950
- )
951
-
952
- watch(
953
- headItemsPresent,
954
- (newValue: UI_I_HeadItem[]) => {
955
- filterShow.value = newValue.map(() => false)
956
- filterTerm.value = newValue.map(() => '')
957
- },
958
- {
959
- immediate: true,
960
- deep: true,
961
- }
962
- )
963
-
964
- const grabColumn = ref<number>(-1)
965
- const grabStartX = ref<number>(0)
966
- const setGrab = (key: number, e: MouseEvent): void => {
967
- if (props.withInfo && key === 0) return
968
-
969
- if (!isShowHiddenInfo.value) {
970
- grabColumn.value = key
971
- const currentWidth = parseInt(columnsWidth.value[grabColumn.value][0])
972
- grabStartX.value = e.clientX - currentWidth
973
- if (isRtl.value) {
974
- grabStartX.value = e.clientX + currentWidth
975
- }
976
- }
977
- }
978
-
979
- const isDrag = ref<boolean>(false)
980
-
981
- const mouseup = (): void => {
982
- if (grabColumn.value === -1) {
983
- return
984
- }
985
-
986
- grabColumn.value = -1
987
- isDrag.value = false
988
- }
989
-
990
- let resizeObserve: ResizeObserver
991
- let mousemove = (e: MouseEvent): void => {
992
- if (grabColumn.value === -1) return
993
-
994
- e.preventDefault()
995
- isDrag.value = true
996
- resizeObserve.disconnect()
997
-
998
- const minWidth = parseInt(columnsWidth.value[grabColumn.value][1])
999
- let changeX = Math.max(e.clientX - grabStartX.value, minWidth)
1000
- if (isRtl.value) {
1001
- changeX = Math.max(grabStartX.value - e.clientX, minWidth)
1002
- }
1003
-
1004
- columnsWidth.value[grabColumn.value] = [`${changeX}px`, `${minWidth}px`]
1005
- }
1006
- mousemove = useThrottle(mousemove)
1007
-
1008
- const setResizeObserve = (): void => {
1009
- const el = document.getElementById(outerWrapper)
1010
-
1011
- if (!el) {
1012
- setTimeout(setResizeObserve, 0)
1013
- return
1014
- }
1015
-
1016
- resizeObserve = new ResizeObserver(setColumnWidth)
1017
- resizeObserve.observe(el)
1018
- }
1019
-
1020
- let resizeObserveWithInfo: ResizeObserver
1021
-
1022
- const setColumnWidthWithInfo = (ent: ResizeObserverEntry[]): void => {
1023
- if (isShowHiddenInfo.value) {
1024
- memoryWidth = columnsWidth.value[1][0]
1025
- columnsWidth.value[1][0] = `${ent[0].contentBoxSize[0].inlineSize - 86}px`
1026
- } else {
1027
- columnsWidth.value[1][0] = memoryWidth
1028
- }
1029
- }
1030
-
1031
- const setResizeObserveWithInfo = (): void => {
1032
- const el = document.querySelector('.datagrid')
1033
-
1034
- if (!el) {
1035
- setTimeout(setResizeObserveWithInfo, 0)
1036
- return
1037
- }
1038
-
1039
- resizeObserveWithInfo = new ResizeObserver(setColumnWidthWithInfo)
1040
- resizeObserveWithInfo.observe(el)
1041
- }
1042
-
1043
- // Export
1044
- const exportItems = computed<UI_I_DropdownButtonItem[]>(() =>
1045
- exportItemsFunc(
1046
- localization.value,
1047
- bodyItemsPresent.value.length || 0,
1048
- props.selectedRow?.length || 0,
1049
- props.testId || ''
1050
- )
1051
- )
1052
- const onExport = (type: '0' | '1'): void => {
1053
- switch (type) {
1054
- case '0':
1055
- onExportAll()
1056
- break
1057
- case '1':
1058
- exportSelected()
1059
- }
1060
- }
1061
- const onExportAll = (): void => {
1062
- const rows = document.querySelectorAll(
1063
- `#${tableWrapperId} .datagrid-row-scrollable`
1064
- ) as NodeListOf<HTMLElement>
1065
- generateCsvAndDownload(Array.from(rows))
1066
- }
1067
- const exportSelected = (): void => {
1068
- const header = document.querySelectorAll(
1069
- `#${tableWrapperId} .datagrid-row-scrollable`
1070
- )[0] as HTMLElement
1071
- const rows = document.querySelectorAll(
1072
- `#${tableWrapperId} .datagrid-selected`
1073
- ) as NodeListOf<HTMLElement>
1074
- generateCsvAndDownload([header, ...Array.from(rows)])
1075
- }
1076
-
1077
- onMounted(() => {
1078
- window.addEventListener('mousemove', mousemove)
1079
- window.addEventListener('mouseup', mouseup)
1080
-
1081
- if (props.withInfo) {
1082
- setResizeObserveWithInfo()
1083
- }
1084
-
1085
- setResizeObserve()
1086
- })
1087
- onUnmounted(() => {
1088
- window.removeEventListener('mouseup', mouseup)
1089
- window.removeEventListener('mousemove', mousemove)
1090
- })
1091
- </script>
1092
-
1093
- <style scoped lang="scss">
1094
- @import '~/assets/scss/common/mixins';
1095
- .datagrid-outer-wrapper {
1096
- @include flex($dir: row);
1097
- //padding-top: 12px;
1098
- flex-grow: 1;
1099
- overflow: auto;
1100
-
1101
- &.datagrid-outer-wrapper-opened-info {
1102
- width: 35%;
1103
- min-width: 195px;
1104
- }
1105
-
1106
- & * {
1107
- box-sizing: border-box;
1108
- }
1109
-
1110
- & svg {
1111
- fill: var(--table-color);
1112
- }
1113
-
1114
- .datagrid-inner-wrapper {
1115
- @include flex($dir: column);
1116
- flex-grow: 1;
1117
- overflow: auto;
1118
-
1119
- .main-filter-content {
1120
- align-items: center;
1121
-
1122
- .filter-icon {
1123
- width: 16px;
1124
- height: 16px;
1125
- margin-right: 10px;
1126
- }
1127
- }
1128
- .datagrid {
1129
- overflow: auto;
1130
- flex: 1 1 auto;
1131
- border-radius: 0.125rem 0.125rem 0 0;
1132
- background-color: var(--block-view-bg-color);
1133
- border-color: var(--global-border-color);
1134
- margin-top: 0;
1135
-
1136
- &.datagrid-opened-info {
1137
- border-radius: 0.125rem 0 0 0;
1138
- overflow-x: hidden;
1139
- }
1140
-
1141
- .datagrid-table-wrapper {
1142
- min-width: max-content;
1143
- display: flex;
1144
- flex: 1 1 auto;
1145
- min-height: 100%;
1146
-
1147
- .datagrid-table {
1148
- @include flex($dir: column);
1149
- flex: 1 1 auto;
1150
- align-content: flex-start;
1151
- position: relative;
1152
-
1153
- .datagrid-header {
1154
- position: sticky;
1155
- top: 0;
1156
- z-index: 501;
1157
- width: auto;
1158
-
1159
- .datagrid-row-scrollable {
1160
- flex-direction: row;
1161
-
1162
- .datagrid-column-separator {
1163
- user-select: none;
1164
-
1165
- &::after {
1166
- cursor: col-resize;
1167
- }
1168
- &.double-arrow-separator .datagrid-column-handle {
1169
- cursor: unset;
1170
- }
1171
- &.double-arrow-separator::after {
1172
- cursor: unset;
1173
- }
1174
- }
1175
- }
1176
-
1177
- .datagrid-row {
1178
- color: var(--table-color);
1179
- background-color: var(--block-view-bg-color);
1180
-
1181
- &.datagrid-selected {
1182
- background-color: var(--row-selected-bg-color);
1183
- border-bottom: 1px solid var(--global-border-color);
1184
-
1185
- & :deep(*) {
1186
- color: var(--table-active-color);
1187
- }
1188
- }
1189
-
1190
- .datagrid-column {
1191
- background-color: var(--block-view-bg-color);
1192
- border-bottom: 1px solid var(--global-border-color);
1193
- padding: 6px 12px 5px;
1194
- position: relative;
1195
- //flex: 1 1 auto;
1196
-
1197
- &:last-child {
1198
- flex: 1 1 auto;
1199
- }
1200
-
1201
- &.datagrid-toggle-block {
1202
- width: 38px;
1203
- min-width: 38px;
1204
-
1205
- &::after {
1206
- content: '';
1207
- width: 0.05rem;
1208
- height: calc(100% - 0.5rem);
1209
- position: absolute;
1210
- right: 0;
1211
- top: 0.25rem;
1212
- background-color: var(--global-border-color);
1213
- }
1214
-
1215
- .datagrid-column-separator {
1216
- cursor: default;
1217
-
1218
- &::after {
1219
- cursor: default;
1220
- }
1221
- }
1222
- }
1223
- }
1224
-
1225
- .datagrid-column-title {
1226
- align-self: auto;
1227
- color: var(--table-color);
1228
- background-color: var(--block-view-bg-color);
1229
- border-bottom-color: var(--global-border-color);
1230
- font-size: 11px;
1231
- @include flex($align: center);
1232
- display: flex;
1233
- flex-direction: row;
1234
- justify-content: flex-start;
1235
- align-items: center;
1236
- //line-height: 24px;
1237
- line-height: normal;
1238
-
1239
- .title-column {
1240
- font-weight: bold;
1241
- font-size: 11px;
1242
- overflow: hidden;
1243
- text-wrap: none;
1244
- text-overflow: ellipsis;
1245
- }
1246
-
1247
- .sort-arrow-wrap {
1248
- margin-left: auto;
1249
- height: 14px;
1250
- width: 14px;
1251
- min-height: 14px;
1252
- min-width: 14px;
1253
- vertical-align: middle;
1254
-
1255
- .sort-arrow {
1256
- &.down {
1257
- transform: rotate(180deg);
1258
- }
1259
- }
1260
- }
1261
- .title-icon {
1262
- width: 24px;
1263
- height: 24px;
1264
- }
1265
- }
1266
-
1267
- .datagrid-filter-toggle {
1268
- background: unset;
1269
- margin-top: -4px;
1270
- align-self: center;
1271
-
1272
- .filter-icon {
1273
- width: 16px;
1274
- height: 16px;
1275
- }
1276
- }
1277
- }
1278
- }
1279
-
1280
- .datagrid-placeholder-container {
1281
- .datagrid-placeholder.datagrid-empty {
1282
- background: var(--block-view-bg-color);
1283
- }
1284
- span {
1285
- font-size: 16px;
1286
- color: var(--global-font-color4);
1287
- }
1288
- }
1289
-
1290
- .datagrid-row {
1291
- width: 100%;
1292
- min-width: max-content;
1293
- border-top: none;
1294
- color: var(--table-color);
1295
- background-color: var(--block-view-bg-color);
1296
- border-bottom: 1px solid var(--global-border-color);
1297
-
1298
- &.datagrid-selected {
1299
- & :deep(*) {
1300
- color: var(--table-active-color);
1301
- }
1302
-
1303
- .datagrid-cell {
1304
- background-color: var(--row-selected-bg-color);
1305
- border-bottom: 1px solid var(--global-border-color);
1306
- position: relative;
1307
- line-height: 1rem;
1308
- }
1309
-
1310
- .datagrid-row-detail {
1311
- background-color: var(--row-selected-bg-color);
1312
- border-bottom: 1px solid var(--global-border-color);
1313
- }
1314
- }
1315
-
1316
- .datagrid-cell {
1317
- min-width: 38px;
1318
- min-height: 28px;
1319
- padding: 2px 12px 3px 12px;
1320
- position: relative;
1321
-
1322
- &:has(.double-arrow-wrap) {
1323
- padding-left: 4px;
1324
- }
1325
-
1326
- &:has(.double-arrow-wrap)::after {
1327
- content: '';
1328
- width: 0.5px;
1329
- height: calc(100% - 6px);
1330
- position: absolute;
1331
- right: 2px;
1332
- top: 3px;
1333
- background-color: var(--global-border-color);
1334
- }
1335
-
1336
- &:last-child {
1337
- flex: 1 1 auto;
1338
- }
1339
-
1340
- button {
1341
- height: 0.9rem;
1342
- width: 0.9rem;
1343
-
1344
- .arrow-icon {
1345
- width: 16px;
1346
- height: 16px;
1347
- transform: rotate(90deg);
1348
- }
1349
- }
1350
-
1351
- .datagrid-cell-icon {
1352
- display: inline-block;
1353
- width: 16px;
1354
- height: 16px;
1355
- }
1356
-
1357
- .datagrid-expandable-caret-button {
1358
- cursor: pointer;
1359
- width: 100%;
1360
-
1361
- .datagrid-expandable-caret-icon {
1362
- width: 16px;
1363
- height: 16px;
1364
- transform: rotate(90deg);
1365
- fill: var(--table-caret-color);
1366
-
1367
- &.toggle {
1368
- transform: rotate(180deg);
1369
- }
1370
- }
1371
- }
1372
- }
1373
-
1374
- &.datagrid-selected-info {
1375
- width: 100%;
1376
- min-width: max-content;
1377
- border-top: none;
1378
- color: var(--table-color);
1379
- background-color: var(--block-view-bg-color);
1380
-
1381
- .datagrid-cell {
1382
- position: relative;
1383
-
1384
- &.hidden-text-triangle::after {
1385
- content: '';
1386
- position: absolute;
1387
- transform: rotate(225deg);
1388
- border-bottom: 15px solid transparent;
1389
- border-right: 15px solid var(--global-bg-color);
1390
- bottom: 26%;
1391
- right: -16px;
1392
- z-index: 1000;
1393
- }
1394
-
1395
- &.hidden-text-triangle::before {
1396
- content: '';
1397
- transform: rotate(-135deg);
1398
- position: absolute;
1399
- border-bottom: 16px solid transparent;
1400
- border-right: 16px solid var(--global-border-color);
1401
- bottom: 23%;
1402
- right: -17px;
1403
- z-index: 999;
1404
- }
1405
- }
1406
- }
1407
- }
1408
-
1409
- .datagrid-row-sticky {
1410
- @include flex($w: nowrap);
1411
- position: sticky;
1412
- left: 0;
1413
- z-index: 500;
1414
- background-color: var(--block-view-bg-color);
1415
-
1416
- .datagrid-column {
1417
- color: var(--table-color);
1418
- background-color: var(--block-view-bg-color);
1419
- border-bottom-color: var(--global-border-color);
1420
- text-align: left;
1421
- display: flex;
1422
- flex: 1 1 auto;
1423
- vertical-align: top;
1424
- border: none;
1425
-
1426
- &.datagrid-expandable-caret {
1427
- .datagrid-column-separator {
1428
- display: block;
1429
-
1430
- &::after {
1431
- top: 0;
1432
- height: 18px;
1433
- }
1434
- }
1435
-
1436
- .radio-btn {
1437
- width: 16px;
1438
- height: 16px;
1439
- }
1440
- }
1441
-
1442
- .datagrid-column-separator {
1443
- position: relative;
1444
- //left: 0.6rem;
1445
- flex: 0 0 auto;
1446
- width: 0.05rem;
1447
- order: 100;
1448
- margin-left: auto;
1449
- height: 100%;
1450
- }
1451
- }
1452
-
1453
- .datagrid-fixed-column-without-separator {
1454
- background-color: var(--block-view-bg-color);
1455
-
1456
- &::after {
1457
- background-color: transparent;
1458
- }
1459
- }
1460
-
1461
- .datagrid-fixed-column {
1462
- background-color: var(--block-view-bg-color);
1463
-
1464
- //&::after {
1465
- // content: '';
1466
- // width: 0.05rem;
1467
- // height: calc(100% - 0.5rem);
1468
- // position: absolute;
1469
- // right: 0;
1470
- // top: 0.25rem;
1471
- // background-color: var(--global-border-color);
1472
- //}
1473
-
1474
- .clr-form-control-disabled {
1475
- .clr-checkbox-wrapper {
1476
- label {
1477
- cursor: not-allowed;
1478
- }
1479
- }
1480
- }
1481
- }
1482
-
1483
- .datagrid-fixed-width {
1484
- &::after {
1485
- content: '';
1486
- width: 0.05rem;
1487
- height: calc(100% - 0.5rem);
1488
- position: absolute;
1489
- right: 0;
1490
- top: 0.25rem;
1491
- background-color: var(--global-border-color);
1492
- }
1493
- }
1494
- }
1495
-
1496
- .datagrid-row-scrollable {
1497
- @include flex($ff: row nowrap);
1498
- flex: 1 1 auto;
1499
-
1500
- .datagrid-scrolling-cells {
1501
- @include flex($ff: row nowrap);
1502
- flex: 1 1 auto;
1503
- }
1504
- }
1505
- .datagrid-body-row {
1506
- .datagrid-row-scrollable {
1507
- @include flex($ff: column nowrap);
1508
-
1509
- .datagrid-row-detail {
1510
- flex: 1;
1511
- }
1512
- }
1513
-
1514
- &:not(.datagrid-selected):hover {
1515
- border-bottom: 1px solid var(--table-hover-row-border-color);
1516
- background-color: var(--table-hover-row-background-color);
1517
- color: var(--table-hover-row-color);
1518
-
1519
- .datagrid-fixed-column {
1520
- background-color: var(--table-hover-row-background-color);
1521
- }
1522
- .datagrid-cell {
1523
- background-color: var(--table-hover-row-background-color);
1524
- }
1525
- }
1526
- }
1527
- }
1528
- }
1529
- }
1530
-
1531
- .datagrid-footer {
1532
- flex: 0 0 auto;
1533
- @include flex($ff: row nowrap, $just: space-between, $align: stretch);
1534
- font-size: 0.55rem;
1535
- background-color: var(--block-view-bg-color);
1536
- border: 0.05rem solid var(--global-border-color);
1537
- border-top: none;
1538
- border-radius: 0 0 0.15rem 0.15rem;
1539
- padding: 0 0.6rem;
1540
- height: 28px;
1541
-
1542
- &.datagrid-footer-opened-info {
1543
- border-radius: 0 0 0 0.15rem;
1544
- flex-direction: row-reverse;
1545
- }
1546
-
1547
- .clr-form-control-disabled {
1548
- opacity: 1;
1549
-
1550
- .clr-checkbox-wrapper {
1551
- label {
1552
- color: #8c8c8c;
1553
- margin-right: 9px;
1554
- padding-left: 22px;
1555
- &:before {
1556
- position: absolute;
1557
- top: 4px;
1558
- left: 0;
1559
- content: '';
1560
- display: inline-block;
1561
- height: 16px;
1562
- width: 16px;
1563
- border: none;
1564
- border-radius: 3px;
1565
- background-color: var(--table-checkbox-color);
1566
- }
1567
-
1568
- &:after {
1569
- position: absolute;
1570
- content: '';
1571
- display: inline-block;
1572
- height: 5px;
1573
- width: 8px;
1574
- border-left: 2px solid #fff;
1575
- border-bottom: 2px solid #fff;
1576
- top: 4px;
1577
- left: 4px;
1578
- transform: translateY(4px) rotate(-45deg);
1579
- }
1580
- }
1581
- }
1582
- }
1583
- }
1584
-
1585
- .datagrid-spinner {
1586
- top: 0.6rem;
1587
- height: calc(100% - 0.6rem);
1588
- }
1589
-
1590
- .datagrid-footer-description {
1591
- flex: 1 1 auto;
1592
-
1593
- :deep(svg) {
1594
- fill: var(--table-switch-color);
1595
- }
1596
- }
1597
-
1598
- .clr-radio-wrapper,
1599
- .clr-checkbox-wrapper {
1600
- height: 18px;
1601
- }
1602
-
1603
- .clr-radio-wrapper label,
1604
- .clr-checkbox-wrapper label {
1605
- padding-left: 16px;
1606
- }
1607
- }
1608
- }
1609
- //.vertical-divider {
1610
- // width: 1px;
1611
- // height: 22px;
1612
- // background: #bbb;
1613
- // margin: 2px 2px 0 -5px;
1614
- //}
1615
-
1616
- .hidden-features {
1617
- padding: 9px 14px;
1618
- background-color: var(--global-bg-color);
1619
- color: var(--global-font-color2);
1620
- border: 1px solid var(--global-border-color);
1621
- border-left: none;
1622
- overflow-y: auto;
1623
- overflow-x: hidden;
1624
- width: 65%;
1625
-
1626
- //.header {
1627
- // display: flex;
1628
- // align-items: center;
1629
- // justify-content: space-between;
1630
- // background-color: inherit;
1631
- //
1632
- // h3 {
1633
- // font-size: 1rem;
1634
- // color: var(--global-font-color2) !important;
1635
- // line-height: 1.7rem;
1636
- // }
1637
- button {
1638
- position: absolute;
1639
- top: 24px;
1640
- right: 24px;
1641
- line-height: 24px;
1642
-
1643
- .close-icon {
1644
- //margin-left: 10px;
1645
- width: 24px;
1646
- height: 24px;
1647
- }
1648
- }
1649
- //}
1650
- }
1651
- .double-arrow-width {
1652
- width: 25px;
1653
- }
1654
- .double-arrow-wrap {
1655
- width: 30px;
1656
- height: 20px;
1657
- padding-top: 1px;
1658
- padding-left: 5px;
1659
- cursor: pointer;
1660
- background-color: transparent;
1661
-
1662
- .double-arrow {
1663
- background-color: transparent;
1664
- transform: rotate(90deg);
1665
- width: 16px;
1666
- height: 16px;
1667
- }
1668
-
1669
- .double-arrow.arrow-selected {
1670
- transform: rotate(-90deg) !important;
1671
- background-color: #0079b8;
1672
- }
1673
- }
1674
- .double-arrow-wrap.arrow-selected {
1675
- background-color: #0079b8;
1676
- border-radius: 3px;
1677
- }
1678
- </style>
1679
-
1680
- <style>
1681
- :root {
1682
- --table-color: #565656;
1683
- --table-active-color: #fff;
1684
- --table-checkbox-color: #454545;
1685
- --table-caret-color: #454545;
1686
- --table-switch-color: #575757;
1687
- --table-hover-row-border-color: #666;
1688
- --table-hover-row-background-color: #e8e8e8;
1689
- --table-hover-row-color: #454545;
1690
- --table-spinner-bg-color: #ffffff99;
1691
- }
1692
-
1693
- :root.dark-theme {
1694
- --table-color: #fff;
1695
- --table-active-color: #565656;
1696
- --table-checkbox-color: #49aeda;
1697
- --table-caret-color: #ffffff;
1698
- --table-switch-color: #b3b3b3;
1699
- --table-hover-row-border-color: #fff;
1700
- --table-hover-row-background-color: #324f61;
1701
- --table-hover-row-color: #e9ecef;
1702
- --table-spinner-bg-color: rgba(0, 0, 0, 0.5);
1703
- }
1704
- </style>
1
+ <template>
2
+ <div class="relative" style="display: flex">
3
+ <div
4
+ :id="outerWrapper"
5
+ :class="[
6
+ 'datagrid-outer-wrapper',
7
+ {
8
+ 'datagrid-outer-wrapper-opened-info': isShowHiddenInfo,
9
+ },
10
+ ]"
11
+ >
12
+ <div class="datagrid-inner-wrapper">
13
+ <div
14
+ v-if="props.isMainFilter"
15
+ class="main-filter-content flex-justify-end"
16
+ >
17
+ <atoms-the-icon class="filter-icon" name="filter" />
18
+ <input
19
+ :id="`${props.testId}-main-filter-input`"
20
+ v-model.trim="mainFilter"
21
+ :data-id="`${props.testId}-main-filter-input`"
22
+ :placeholder="props.mainFilterPlaceholder"
23
+ type="text"
24
+ @input="emits('main-filter', mainFilter)"
25
+ />
26
+ </div>
27
+ <div
28
+ :class="[
29
+ 'datagrid',
30
+ {
31
+ 'datagrid-opened-info': isShowHiddenInfo,
32
+ },
33
+ ]"
34
+ >
35
+ <div :id="tableWrapperId" class="datagrid-table-wrapper">
36
+ <div class="datagrid-table" :data-id="props.testId">
37
+ <div class="datagrid-header">
38
+ <div class="datagrid-row">
39
+ <div class="datagrid-row-master datagrid-row-flex">
40
+ <div
41
+ v-if="props.type || $slots.toggleBlock"
42
+ class="datagrid-row-sticky"
43
+ >
44
+ <div
45
+ v-if="props.type"
46
+ :id="expandableCaret"
47
+ class="datagrid-column datagrid-expandable-caret datagrid-fixed-column flex-align-center flex-justify-center"
48
+ >
49
+ <template v-if="props.type === 'checkbox'">
50
+ <div
51
+ class="clr-checkbox-wrapper flex-align-center flex-justify-center w-100"
52
+ >
53
+ <input
54
+ :id="`${props.testId}-${inputId}-all`"
55
+ v-model="selectedAll"
56
+ :data-id="`${props.testId}-filter-all`"
57
+ type="checkbox"
58
+ class="checkbox-btn"
59
+ :value="-1"
60
+ @change="changeAll"
61
+ />
62
+ <label
63
+ :for="`${props.testId}-${inputId}-all`"
64
+ class="clr-control-label"
65
+ />
66
+ </div>
67
+ <div class="datagrid-column-separator"></div>
68
+ </template>
69
+ </div>
70
+ <div
71
+ v-if="$slots.toggleBlock"
72
+ class="datagrid-toggle-block datagrid-column datagrid-fixed-width"
73
+ >
74
+ <div class="datagrid-column-flex">
75
+ <div class="datagrid-column-separator">
76
+ <span class="clr-sr-only" />
77
+ <div class="datagrid-column-resize-tracker" />
78
+ </div>
79
+ </div>
80
+ </div>
81
+ </div>
82
+ <div class="datagrid-row-scrollable">
83
+ <div
84
+ v-for="(item, key) in headItemsPresent"
85
+ :key="key"
86
+ :style="{
87
+ width: columnsWidth[key][0],
88
+ minWidth: columnsWidth[key][1],
89
+ }"
90
+ class="datagrid-column datagrid-fixed-width"
91
+ >
92
+ <div class="datagrid-column-flex">
93
+ <button
94
+ :id="`${props.testId}-sort-column-${key}`"
95
+ :data-id="`${item.testId}-sort-column`"
96
+ :class="[
97
+ 'datagrid-column-title',
98
+ {
99
+ 'default text-decoration-none':
100
+ !item.sortColumn,
101
+ },
102
+ ]"
103
+ @click="sortTable(item.sortColumn)"
104
+ >
105
+ <slot :key="key" name="th" :item="item">
106
+ <span
107
+ :title="item.text"
108
+ :style="{
109
+ width:
110
+ columnsWidth[key][0]?.slice(0, -2) -
111
+ (item.hasFilter ? 65 : 40) +
112
+ 'px',
113
+ }"
114
+ class="title-column"
115
+ >
116
+ {{ item.text }}
117
+ </span>
118
+ </slot>
119
+ <span
120
+ v-if="item.sortColumn"
121
+ class="sort-arrow-wrap"
122
+ >
123
+ <atoms-the-icon
124
+ v-show="sortInfo[0] === item.sortColumn"
125
+ :class="['sort-arrow', { down: sortInfo[1] }]"
126
+ name="sort-arrow"
127
+ />
128
+ </span>
129
+ </button>
130
+ <button
131
+ v-if="item.hasFilter"
132
+ :id="`${props.testId}-filter-icon-${key}`"
133
+ :data-id="`${item.testId}-filter-icon`"
134
+ class="datagrid-filter-toggle clr-anchor clr-smart-open-close"
135
+ @click="filterShow[key] = !filterShow[key]"
136
+ >
137
+ <atoms-the-icon
138
+ v-if="filterTerm[key]"
139
+ class="filter-icon"
140
+ name="filter-solid"
141
+ style="fill: #0079b8"
142
+ />
143
+ <atoms-the-icon
144
+ v-else
145
+ class="filter-icon"
146
+ name="filter"
147
+ />
148
+ </button>
149
+ <atoms-popup-simple-popup
150
+ v-model="filterShow[key]"
151
+ :test-id="`${props.testId}-filter`"
152
+ top="100%"
153
+ :left="key === 0 ? '0' : ''"
154
+ :right="key !== 0 ? '0' : ''"
155
+ >
156
+ <input
157
+ :id="`${props.testId}-filter-input-${key}`"
158
+ v-model="filterTerm[key]"
159
+ :data-id="`${item.testId}-filter-input`"
160
+ type="text"
161
+ @input="filtering"
162
+ />
163
+ </atoms-popup-simple-popup>
164
+ <div
165
+ v-show="
166
+ !isShowHiddenInfo ||
167
+ (isShowHiddenInfo && key === 0)
168
+ "
169
+ :class="[
170
+ 'datagrid-column-separator',
171
+ {
172
+ 'double-arrow-separator':
173
+ key === 0 && props.withInfo,
174
+ },
175
+ ]"
176
+ @mousedown="setGrab(key, $event)"
177
+ >
178
+ <button
179
+ :id="`${props.testId}-resize-tracker-${key}`"
180
+ class="datagrid-column-handle drag-handle draggable"
181
+ />
182
+ <span class="clr-sr-only" />
183
+ <div class="datagrid-column-resize-tracker" />
184
+ </div>
185
+ </div>
186
+ </div>
187
+ </div>
188
+ </div>
189
+ </div>
190
+ </div>
191
+
192
+ <template v-if="bodyItemsPresent.length">
193
+ <div
194
+ v-for="(item, key) in bodyItemsPresent"
195
+ :key="item.id"
196
+ :class="[
197
+ 'datagrid-body-row datagrid-row animation',
198
+ {
199
+ 'datagrid-selected active': checkIsSelectedRow(
200
+ item[0].id
201
+ ),
202
+ 'datagrid-selected-info':
203
+ props.withInfo &&
204
+ isShowHiddenInfo &&
205
+ checkIsSelectedRow(item[0].id),
206
+ },
207
+ ]"
208
+ :[props.rowAttributeIdName]="item[0].dataId"
209
+ >
210
+ <div>
211
+ <div
212
+ :data-id="`${item[0].testId}-select-row`"
213
+ class="datagrid-row-master datagrid-row-flex"
214
+ @click.stop="selectRowById(item[0])"
215
+ >
216
+ <div
217
+ v-if="props.type || $slots.toggleBlock"
218
+ class="datagrid-row-sticky"
219
+ @click.stop
220
+ >
221
+ <div
222
+ :id="expandableCaret"
223
+ :class="[
224
+ 'datagrid-expandable-caret flex-justify-center datagrid-cell',
225
+ {
226
+ 'datagrid-fixed-column': !props.withInfo,
227
+ 'datagrid-fixed-column-without-separator':
228
+ props.withInfo,
229
+ },
230
+ ]"
231
+ >
232
+ <!--TODO refactoring (duplicate)-->
233
+ <div
234
+ v-if="$slots.toggleBlock && !props.type"
235
+ class="datagrid-cell datagrid-fixed-width"
236
+ >
237
+ <div
238
+ v-if="item[0]?.isShowToggleIcon ?? true"
239
+ class="flex-align-center"
240
+ >
241
+ <button
242
+ :id="`${props.testId}-toggle-icon-${key}`"
243
+ :data-id="`${item[0].testId}-toggle-button`"
244
+ class="datagrid-expandable-caret-button reset-btn"
245
+ @click="toggle(key)"
246
+ >
247
+ <atoms-the-icon
248
+ :class="[
249
+ 'datagrid-expandable-caret-icon',
250
+ { toggle: toggedItems[key] },
251
+ ]"
252
+ name="angle"
253
+ />
254
+ </button>
255
+ </div>
256
+ </div>
257
+ <slot
258
+ v-if="props.type"
259
+ :key="key"
260
+ name="type"
261
+ :item="item"
262
+ >
263
+ <div
264
+ :class="
265
+ item[0]?.disabled && 'clr-form-control-disabled'
266
+ "
267
+ >
268
+ <div
269
+ :class="`clr-${props.type}-wrapper flex-justify-center flex-align-center`"
270
+ >
271
+ <input
272
+ :id="`${props.testId}-${inputId}-${item[0].id}`"
273
+ :key="item[0].id"
274
+ v-model="selectedRowLocal"
275
+ :data-id="`${item[0].testId}-row-selection-input`"
276
+ :type="props.type"
277
+ :class="`${props.type}-btn`"
278
+ :value="item[0].id"
279
+ :disabled="item[0]?.disabled || false"
280
+ name="selected-store"
281
+ @change="
282
+ changeSelectedRow($event, item[0].id)
283
+ "
284
+ />
285
+ <label
286
+ :for="`${props.testId}-${inputId}-${item[0].id}`"
287
+ class="clr-control-label"
288
+ />
289
+ </div>
290
+ </div>
291
+ </slot>
292
+ </div>
293
+ <!--TODO refactoring (duplicate)-->
294
+ <div
295
+ v-if="$slots.toggleBlock && props.type"
296
+ class="datagrid-cell datagrid-fixed-width"
297
+ >
298
+ <div class="flex-align-center">
299
+ <button
300
+ :id="`${props.testId}-toggle-icon-${key}`"
301
+ :data-id="`${item[0].testId}-toggle-row-button`"
302
+ class="datagrid-expandable-caret-button reset-btn"
303
+ @click="toggle(key)"
304
+ >
305
+ <atoms-the-icon
306
+ :class="[
307
+ 'datagrid-expandable-caret-icon',
308
+ { toggle: toggedItems[key] },
309
+ ]"
310
+ name="angle"
311
+ />
312
+ </button>
313
+ </div>
314
+ </div>
315
+ </div>
316
+ <div class="datagrid-row-scrollable">
317
+ <div class="datagrid-scrolling-cells">
318
+ <div
319
+ v-for="(item2, key2) in item"
320
+ v-show="
321
+ !isShowHiddenInfo ||
322
+ item2.key === 'col1' ||
323
+ item2.key === 'icon'
324
+ "
325
+ :key="key2"
326
+ :style="{
327
+ width: columnsWidth[key2][0],
328
+ minWidth: columnsWidth[key2][1],
329
+ }"
330
+ :class="[
331
+ 'datagrid-cell datagrid-fixed-width',
332
+ {
333
+ 'hidden-text-triangle':
334
+ isShowHiddenInfo &&
335
+ item2.data?.name === 'hidden-text-triangle',
336
+ },
337
+ ]"
338
+ >
339
+ <div
340
+ :class="[
341
+ 'flex-align-center h-100',
342
+ {
343
+ 'double-arrow-width':
344
+ item2.data?.name === 'doubleArrows',
345
+ },
346
+ ]"
347
+ >
348
+ <div
349
+ v-if="item2.data?.name === 'doubleArrows'"
350
+ :id="`show-info-${item[0].data.id}`"
351
+ :data-id="`${item[0].testId}-double-arrow`"
352
+ :class="[
353
+ 'double-arrow-wrap',
354
+ {
355
+ 'arrow-selected':
356
+ isShowHiddenInfo &&
357
+ item2.id === props.selectedRow,
358
+ },
359
+ ]"
360
+ @click.prevent.stop="
361
+ doubleArrowClick(item2, item)
362
+ "
363
+ >
364
+ <atoms-the-icon
365
+ v-if="item2.data?.name === 'doubleArrows'"
366
+ name="doubleArrows"
367
+ :class="[
368
+ 'double-arrow',
369
+ {
370
+ 'arrow-selected':
371
+ isShowHiddenInfo &&
372
+ item2.id === props.selectedRow,
373
+ },
374
+ ]"
375
+ />
376
+ </div>
377
+ <span
378
+ v-if="item2.text && item2.data?.iconClassName"
379
+ class="vertical-divider"
380
+ />
381
+ <slot :name="item2.key" :item="item2">
382
+ <span class="text-ellipsis" :title="item2.text"
383
+ >{{ item2.text }}
384
+ </span>
385
+ </slot>
386
+ </div>
387
+ </div>
388
+ </div>
389
+ <div
390
+ v-show="toggedItems[key]"
391
+ class="datagrid-row-flex datagrid-row-detail datagrid-container"
392
+ >
393
+ <slot name="toggleBlock" :item="item" />
394
+ </div>
395
+ </div>
396
+ </div>
397
+ </div>
398
+ </div>
399
+ </template>
400
+ <template v-else>
401
+ <div class="datagrid-placeholder-container">
402
+ <div class="datagrid-placeholder datagrid-empty">
403
+ <div class="datagrid-placeholder-image"></div>
404
+
405
+ <span>No items found</span>
406
+ </div>
407
+ </div>
408
+ </template>
409
+ </div>
410
+ </div>
411
+ </div>
412
+
413
+ <div
414
+ v-if="!hideFooter"
415
+ :class="[
416
+ 'datagrid-footer',
417
+ {
418
+ 'datagrid-footer-opened-info': isShowHiddenInfo,
419
+ },
420
+ ]"
421
+ >
422
+ <div
423
+ v-if="props.type === 'checkbox' && props.selectedRow?.length"
424
+ class="clr-form-control-disabled"
425
+ >
426
+ <div class="clr-checkbox-wrapper">
427
+ <input
428
+ :id="`${props.testId}-check-all`"
429
+ :data-id="`${props.testId}-check-all`"
430
+ type="checkbox"
431
+ checked
432
+ />
433
+ <label class="clr-control-label">
434
+ {{ props.selectedRow?.length }}
435
+ </label>
436
+ </div>
437
+ </div>
438
+ <div class="datagrid-footer-description flex-align-center">
439
+ <atoms-table-data-grid-column-switch
440
+ v-if="columnKeysLocal"
441
+ v-model:column-keys="columnKeysLocal"
442
+ :test-id="`${props.testId}-footer-description`"
443
+ class="switch-icon"
444
+ />
445
+
446
+ <template v-if="props.isShowExport && bodyItemsPresent.length">
447
+ <common-select-button-dropdown
448
+ v-if="props.selectedRow?.length"
449
+ :heading="localization.common.export"
450
+ :items="exportItems"
451
+ :test-id="`${props.testId}-export-btn`"
452
+ class="properties__actions"
453
+ is-top
454
+ @click="onExport"
455
+ />
456
+ <button
457
+ v-else
458
+ class="export-link dropdown-toggle btn btn-sm btn-link"
459
+ @click="onExportAll"
460
+ >
461
+ {{ localization.common.export }}
462
+ </button>
463
+ </template>
464
+
465
+ <div v-if="$slots.action" class="datagrid-footer__action">
466
+ <slot name="action" />
467
+ </div>
468
+ </div>
469
+
470
+ <atoms-table-data-grid-pagination
471
+ :test-id="props.testId"
472
+ :page-size="props.pageSize"
473
+ :page="props.page"
474
+ :options="mergeOptions"
475
+ :total-items="props.totalItems"
476
+ :total-pages="props.totalPages"
477
+ :hide-pagination="props.hidePagination"
478
+ :hide-page-size="props.hidePageSize"
479
+ :show-page-info="props.showPageInfo"
480
+ :page-items-count="props.bodyItems.length"
481
+ :is-show-hidden-info="isShowHiddenInfo"
482
+ @change-page-size="changePageSize"
483
+ @change-page="changePage"
484
+ />
485
+ </div>
486
+
487
+ <atoms-loader
488
+ v-show="props.loading"
489
+ class="datagrid-spinner"
490
+ :test-id="`${props.testId}-spinner`"
491
+ />
492
+ </div>
493
+ </div>
494
+ <div
495
+ v-if="isShowInfo"
496
+ id="hidden-features"
497
+ :class="[
498
+ 'hidden-features',
499
+ {
500
+ 'show-hidden-info': isShowHiddenInfo,
501
+ },
502
+ ]"
503
+ >
504
+ <!-- <div class="header">-->
505
+ <!-- <slot name="hiddenInfoHeader" :item="showedInfoCol" />-->
506
+ <!-- <button-->
507
+ <!-- :id="`${props.testId}-hidden-info-toggle-icon-${showedInfoRow?.key}-${showedInfoRow?.data.name}`"-->
508
+ <!-- :data-id="`${props.testId}-hidden-info-toggle-icon`"-->
509
+ <!-- class="signpost-action close"-->
510
+ <!-- @click="isShowHiddenInfo = false"-->
511
+ <!-- >-->
512
+ <!-- <atoms-the-icon class="close-icon" name="close" />-->
513
+ <!-- </button>-->
514
+ <!-- </div>-->
515
+ <!-- <slot name="hiddenInfoBody" />-->
516
+ <button
517
+ :id="`${props.testId}-hidden-info-toggle-icon-${showedInfoRow?.key}-${showedInfoRow?.data.name}`"
518
+ :data-id="`${props.testId}-hidden-info-toggle-icon`"
519
+ class="signpost-action close"
520
+ @click="isShowHiddenInfo = false"
521
+ >
522
+ <atoms-the-icon class="close-icon" name="close" />
523
+ </button>
524
+ <slot name="hiddenInfo" :item="showedInfoCol" />
525
+ </div>
526
+ </div>
527
+ </template>
528
+
529
+ <script setup lang="ts">
530
+ import { isRtl } from 'bfg-uikit/lib/config/trl'
531
+ import type {
532
+ UI_I_HTMLSelectElement,
533
+ UI_I_Localization,
534
+ } from '~/lib/models/interfaces'
535
+ import type {
536
+ UI_I_HeadItem,
537
+ UI_I_BodyItem,
538
+ UI_I_ColumnKey,
539
+ } from '~/components/atoms/table/dataGrid/lib/models/interfaces'
540
+ import type {
541
+ UI_T_ColumnKeys,
542
+ UI_T_DataGridType,
543
+ UI_T_SelectedRow,
544
+ } from '~/components/atoms/table/dataGrid/lib/models/types'
545
+ import type { UI_I_OptionItem } from '~/components/atoms/lib/models/interfaces'
546
+ import type { UI_I_DropdownButtonItem } from '~/components/common/select/button/lib/models/interfaces'
547
+ import { itemsPerPage } from '~/components/atoms/table/dataGrid/lib/config/itemsPerPage'
548
+ import { exportItemsFunc } from '~/components/atoms/table/dataGrid/lib/config/settingsTable'
549
+ import { generateCsvAndDownload } from '~/components/atoms/table/dataGrid/lib/utils/export'
550
+
551
+ const props = withDefaults(
552
+ defineProps<{
553
+ headItems: UI_I_HeadItem[]
554
+ bodyItems: UI_I_BodyItem[][]
555
+ pageSize: number
556
+ page: number
557
+ totalItems: number
558
+ totalPages: number
559
+ loading?: boolean
560
+ columnKeys?: UI_I_ColumnKey[]
561
+ selectedRow?: UI_T_SelectedRow
562
+ type?: UI_T_DataGridType
563
+ itemsPerPage?: UI_I_OptionItem[]
564
+ offSelectByRow?: boolean
565
+ hidePageSize?: boolean
566
+ showPageInfo?: boolean
567
+ serverOff?: boolean
568
+ fillWidth?: boolean
569
+ hideFooter?: boolean
570
+ hidePagination?: boolean
571
+ testId?: string
572
+ withInfo?: boolean
573
+ rowAttributeIdName?: string
574
+ isMainFilter?: boolean
575
+ mainFilterPlaceholder?: string
576
+ isShowExport?: boolean
577
+ }>(),
578
+ {
579
+ columnKeys: undefined,
580
+ selectedRow: undefined,
581
+ type: undefined,
582
+ itemsPerPage: undefined,
583
+ fillWidth: true,
584
+ testId: 'ui-data-grid',
585
+ withInfo: false,
586
+ rowAttributeIdName: 'data-id',
587
+ isShowExport: false,
588
+ }
589
+ )
590
+
591
+ const emits = defineEmits<{
592
+ (event: 'update:column-keys', value: UI_T_ColumnKeys): void
593
+ (event: 'update:selected-row', value: UI_T_SelectedRow): void
594
+ (event: 'update:page-size', value: number): void
595
+ (event: 'update:page', value: number): void
596
+ (event: 'main-filter', value: string): void
597
+ (event: 'filtering', value: string[][]): void
598
+ (event: 'sorting', value: [string, boolean]): void
599
+ (event: 'change', value: any): void
600
+ (event: 'row-detail', value: number): void
601
+ }>()
602
+
603
+ const localization = computed<UI_I_Localization>(() => useLocal())
604
+
605
+ const mainFilter = ref<string>('')
606
+
607
+ const mergeOptions = computed<UI_I_OptionItem[]>(
608
+ () => props.itemsPerPage || itemsPerPage
609
+ )
610
+
611
+ const inputId = ref<string>(`radio-input-${useUniqueId()}`)
612
+
613
+ const columnKeysLocal = computed<UI_T_ColumnKeys>({
614
+ get() {
615
+ return props.columnKeys
616
+ },
617
+ set(newValue) {
618
+ emits('update:column-keys', newValue)
619
+ },
620
+ })
621
+
622
+ const selectedAll = ref<boolean>(false)
623
+ const changeAll = (e: UI_I_HTMLSelectElement): void => {
624
+ const newSelectedRow: (number | string)[] = []
625
+ if (e.target.checked) {
626
+ bodyItemsPresent.value.forEach((row) => {
627
+ if (row[0]?.disabled) return
628
+
629
+ newSelectedRow.push(row[0].id)
630
+ })
631
+ }
632
+
633
+ emits('update:selected-row', newSelectedRow)
634
+ }
635
+
636
+ const selectedRowLocal = ref<UI_T_SelectedRow>([])
637
+ const isShowHiddenInfo = ref<boolean>(false)
638
+ const tableWrapperId = `table-wrapper-${useUniqueId()}`
639
+ let memoryWidth = '0'
640
+
641
+ const showedInfoRow = ref<UI_I_BodyItem | null>(null)
642
+ const showedInfoCol = ref<UI_I_BodyItem[] | null>(null)
643
+
644
+ const isShowInfo = computed(
645
+ () =>
646
+ showedInfoRow.value &&
647
+ showedInfoRow.value.id === props.selectedRow &&
648
+ !showedInfoRow.value.data?.text &&
649
+ isShowHiddenInfo.value
650
+ )
651
+
652
+ const setShowedInfoData = (
653
+ item: UI_I_BodyItem | null,
654
+ items: UI_I_BodyItem[] | null,
655
+ reset: boolean = false
656
+ ): void => {
657
+ showedInfoRow.value = item
658
+ showedInfoCol.value = items
659
+
660
+ reset && (isShowHiddenInfo.value = false)
661
+ item && selectRowById(item)
662
+ reset && (isShowHiddenInfo.value = true)
663
+ }
664
+
665
+ const doubleArrowClick = (
666
+ item: UI_I_BodyItem,
667
+ items: UI_I_BodyItem[]
668
+ ): void => {
669
+ if (!isShowHiddenInfo.value) {
670
+ setShowedInfoData(item, items)
671
+ } else {
672
+ if (showedInfoRow.value?.id !== item.id) {
673
+ setShowedInfoData(item, items, true)
674
+
675
+ return
676
+ } else {
677
+ setShowedInfoData(null, null)
678
+ }
679
+ }
680
+
681
+ isShowHiddenInfo.value = !isShowHiddenInfo.value
682
+ }
683
+
684
+ watch(
685
+ () => props.selectedRow,
686
+ (newValue) => {
687
+ if (newValue === undefined) return
688
+
689
+ if (Array.isArray(newValue) && !newValue.length) selectedAll.value = false
690
+
691
+ selectedRowLocal.value = newValue
692
+ },
693
+ { immediate: true }
694
+ )
695
+ const selectRowById = (item: UI_I_BodyItem): void => {
696
+ const { id, disabled } = item
697
+
698
+ if (props.offSelectByRow || isShowHiddenInfo.value || disabled) return
699
+
700
+ if (props.type === 'checkbox' && Array.isArray(selectedRowLocal.value)) {
701
+ const has = selectedRowLocal.value.includes(id)
702
+ if (has) {
703
+ selectedRowLocal.value = selectedRowLocal.value.filter(
704
+ (rowId: string | number) => rowId !== id
705
+ )
706
+ } else {
707
+ selectedRowLocal.value.push(id)
708
+ }
709
+
710
+ emits('change', selectedRowLocal.value)
711
+ emits('update:selected-row', selectedRowLocal.value)
712
+
713
+ changeSelectedAll(!has)
714
+ return
715
+ }
716
+
717
+ emits('change', id)
718
+ emits('update:selected-row', id)
719
+ }
720
+ const changeSelectedRow = (
721
+ e: UI_I_HTMLSelectElement,
722
+ id: number | string
723
+ ): void => {
724
+ if (props.type === 'checkbox' && Array.isArray(selectedRowLocal.value)) {
725
+ const newSelectedRow = [...selectedRowLocal.value]
726
+ emits('change', newSelectedRow)
727
+ emits('update:selected-row', newSelectedRow)
728
+
729
+ changeSelectedAll(e.target.checked)
730
+ return
731
+ }
732
+
733
+ emits('change', id)
734
+ emits('update:selected-row', id)
735
+ }
736
+ const changeSelectedAll = (checked: boolean): void => {
737
+ if (props.type === 'checkbox' && Array.isArray(selectedRowLocal.value)) {
738
+ const newSelectedRow = [...selectedRowLocal.value]
739
+
740
+ if (!checked) {
741
+ selectedAll.value = false
742
+ } else if (newSelectedRow.length === bodyItemsPresent.value.length) {
743
+ selectedAll.value = true
744
+ }
745
+ }
746
+ }
747
+
748
+ const checkIsSelectedRow = (id: number | string): boolean => {
749
+ if (props.type === 'checkbox' && Array.isArray(props.selectedRow)) {
750
+ return props.selectedRow.includes(id)
751
+ }
752
+ return props.selectedRow === id
753
+ }
754
+
755
+ // Sorting
756
+ const sortInfo = ref<[string, boolean]>(['', true])
757
+ const sortedColumnIndex = computed<number>(() => {
758
+ let index = -1
759
+ headItemsPresent.value.forEach((item, key) => {
760
+ if (item.sortColumn === sortInfo.value[0]) index = key
761
+ })
762
+
763
+ return index
764
+ })
765
+ const sortTable = (sortName: string): void => {
766
+ if (!sortName) return
767
+
768
+ emits('update:selected-row', selectedRowLocal.value)
769
+
770
+ if (sortInfo.value[0] === sortName) {
771
+ sortInfo.value[1] = !sortInfo.value[1]
772
+
773
+ emits('sorting', sortInfo.value)
774
+ return
775
+ }
776
+ sortInfo.value[0] = sortName
777
+ sortInfo.value[1] = true
778
+
779
+ emits('sorting', sortInfo.value)
780
+ }
781
+
782
+ // Filtering
783
+ const filterShow = ref<boolean[]>([])
784
+ const filterTerm = ref<string[]>([])
785
+ const filtering = (): void => {
786
+ const filter: string[][] = []
787
+ headItemsPresent.value.forEach((item, key) => {
788
+ if (filterTerm.value[key]) filter.push([item.key, filterTerm.value[key]])
789
+ })
790
+
791
+ emits('filtering', filter)
792
+ }
793
+
794
+ // Pagination
795
+ const changePageSize = (value: number): void => {
796
+ emits('update:page-size', value)
797
+ }
798
+ const changePage = (value: number): void => {
799
+ emits('update:selected-row', [])
800
+ emits('update:page', value)
801
+ }
802
+
803
+ const headItemsPresent = computed<UI_I_HeadItem[]>(() => {
804
+ if (!columnKeysLocal.value) {
805
+ return props.headItems
806
+ }
807
+
808
+ return props.headItems.filter((item, key) => {
809
+ return columnKeysLocal.value?.find(
810
+ (item2, key2) => item2.key === item.key && key === key2
811
+ )?.show
812
+ })
813
+ })
814
+
815
+ const bodyItemsPresent = computed<UI_I_BodyItem[][]>(() => {
816
+ let items: UI_I_BodyItem[][] = props.bodyItems
817
+
818
+ // Filtering by column
819
+ if (columnKeysLocal.value) {
820
+ items = items.map((arr) => {
821
+ arr = arr.filter((item, key) => {
822
+ return columnKeysLocal.value?.find(
823
+ (item2, key2) => item2.key === item.key && key === key2
824
+ )?.show
825
+ })
826
+ return arr
827
+ })
828
+ }
829
+
830
+ if (props.serverOff) {
831
+ // Sorting
832
+ if (sortInfo.value[0] !== '') {
833
+ items = useDeepCopy(items).sort(
834
+ (a: UI_I_BodyItem[], b: UI_I_BodyItem[]) => {
835
+ let first = a[sortedColumnIndex.value].text.toString().toLowerCase()
836
+ let second = b[sortedColumnIndex.value].text.toString().toLowerCase()
837
+
838
+ const sortValueA = a[sortedColumnIndex.value]?.data?.sortValue
839
+ const sortValueB = b[sortedColumnIndex.value]?.data?.sortValue
840
+ if (sortValueA || sortValueA === 0) {
841
+ first = sortValueA
842
+ }
843
+ if (sortValueB || sortValueB === 0) {
844
+ second = sortValueB
845
+ }
846
+
847
+ if (sortInfo.value[1]) {
848
+ return first > second ? 1 : first < second ? -1 : 0
849
+ } else {
850
+ return first < second ? 1 : first > second ? -1 : 0
851
+ }
852
+ }
853
+ )
854
+ }
855
+ // Filtering
856
+ const hasFilter = headItemsPresent.value.some(
857
+ (_, key) => filterTerm.value[key]
858
+ )
859
+ if (hasFilter) {
860
+ items = items.filter((row) => {
861
+ // 0 - начальное значение
862
+ // 1 - найден элемент
863
+ // -1 - ненайден элемент
864
+ let hasItem = 0
865
+ headItemsPresent.value.forEach((item, key) => {
866
+ if (!filterTerm.value[key]) return
867
+ const term = filterTerm.value[key].toLowerCase()
868
+
869
+ row.forEach((col) => {
870
+ if (
871
+ col.key === item.key &&
872
+ typeof col.text === 'string' &&
873
+ hasItem != -1
874
+ ) {
875
+ hasItem = col.text.toLowerCase().includes(term) ? 1 : -1
876
+ }
877
+ })
878
+ })
879
+
880
+ return hasItem === 1
881
+ })
882
+ }
883
+ }
884
+
885
+ return items
886
+ })
887
+
888
+ const toggedItems = ref<boolean[]>([])
889
+
890
+ const toggle = (key: number): void => {
891
+ toggedItems.value[key] = !toggedItems.value[key]
892
+ if (!toggedItems.value[key]) return
893
+ emits('row-detail', key)
894
+ }
895
+
896
+ const outerWrapper = `datagrid-outer-wrapper${useUniqueId()}`
897
+ const expandableCaret = `datagrid-expandable-caret${useUniqueId()}`
898
+
899
+ // Resize
900
+ let helper = false
901
+ let setColumnWidth = (): void => {
902
+ if (!helper) {
903
+ columnsWidth.value = []
904
+ headItemsPresent.value.forEach((item) => {
905
+ columnsWidth.value.push([
906
+ item.width, // width
907
+ item.width, // min-width
908
+ ])
909
+ })
910
+
911
+ helper = true
912
+ setTimeout(() => setColumnWidth(), 0)
913
+ return
914
+ }
915
+ // Не продолжаем, чтобы ширина калонок была так как заданно в headItemsPresent
916
+ if (!props.fillWidth) return
917
+
918
+ // PC-672
919
+ // const dataGridWidth = document.getElementById(outerWrapper)?.clientWidth || 0
920
+ // const leftColumnWidth =
921
+ // document.getElementById(expandableCaret)?.clientWidth || 0
922
+ // const bordersWidth = 2
923
+ // const columnWidth =
924
+ // (dataGridWidth - leftColumnWidth - bordersWidth) /
925
+ // headItemsPresent.value.length
926
+
927
+ headItemsPresent.value.forEach((item) => {
928
+ columnsWidth.value.push([
929
+ // `${columnWidth}px`, // width
930
+ item.width, // width
931
+ item.width, // min-width
932
+ ])
933
+ })
934
+ }
935
+ setColumnWidth = useThrottle(setColumnWidth)
936
+
937
+ const columnsWidth = ref<[string, string][]>([])
938
+ watch(
939
+ bodyItemsPresent,
940
+ (newValue: UI_I_BodyItem[][]) => {
941
+ newValue.forEach(() => {
942
+ toggedItems.value.push(false)
943
+ })
944
+ setColumnWidth()
945
+ },
946
+ {
947
+ immediate: true,
948
+ deep: true,
949
+ }
950
+ )
951
+
952
+ watch(
953
+ headItemsPresent,
954
+ (newValue: UI_I_HeadItem[]) => {
955
+ filterShow.value = newValue.map(() => false)
956
+ filterTerm.value = newValue.map(() => '')
957
+ },
958
+ {
959
+ immediate: true,
960
+ deep: true,
961
+ }
962
+ )
963
+
964
+ const grabColumn = ref<number>(-1)
965
+ const grabStartX = ref<number>(0)
966
+ const setGrab = (key: number, e: MouseEvent): void => {
967
+ if (props.withInfo && key === 0) return
968
+
969
+ if (!isShowHiddenInfo.value) {
970
+ grabColumn.value = key
971
+ const currentWidth = parseInt(columnsWidth.value[grabColumn.value][0])
972
+ grabStartX.value = e.clientX - currentWidth
973
+ if (isRtl.value) {
974
+ grabStartX.value = e.clientX + currentWidth
975
+ }
976
+ }
977
+ }
978
+
979
+ const isDrag = ref<boolean>(false)
980
+
981
+ const mouseup = (): void => {
982
+ if (grabColumn.value === -1) {
983
+ return
984
+ }
985
+
986
+ grabColumn.value = -1
987
+ isDrag.value = false
988
+ }
989
+
990
+ let resizeObserve: ResizeObserver
991
+ let mousemove = (e: MouseEvent): void => {
992
+ if (grabColumn.value === -1) return
993
+
994
+ e.preventDefault()
995
+ isDrag.value = true
996
+ resizeObserve.disconnect()
997
+
998
+ const minWidth = parseInt(columnsWidth.value[grabColumn.value][1])
999
+ let changeX = Math.max(e.clientX - grabStartX.value, minWidth)
1000
+ if (isRtl.value) {
1001
+ changeX = Math.max(grabStartX.value - e.clientX, minWidth)
1002
+ }
1003
+
1004
+ columnsWidth.value[grabColumn.value] = [`${changeX}px`, `${minWidth}px`]
1005
+ }
1006
+ mousemove = useThrottle(mousemove)
1007
+
1008
+ const setResizeObserve = (): void => {
1009
+ const el = document.getElementById(outerWrapper)
1010
+
1011
+ if (!el) {
1012
+ setTimeout(setResizeObserve, 0)
1013
+ return
1014
+ }
1015
+
1016
+ resizeObserve = new ResizeObserver(setColumnWidth)
1017
+ resizeObserve.observe(el)
1018
+ }
1019
+
1020
+ let resizeObserveWithInfo: ResizeObserver
1021
+
1022
+ const setColumnWidthWithInfo = (ent: ResizeObserverEntry[]): void => {
1023
+ if (isShowHiddenInfo.value) {
1024
+ memoryWidth = columnsWidth.value[1][0]
1025
+ columnsWidth.value[1][0] = `${ent[0].contentBoxSize[0].inlineSize - 86}px`
1026
+ } else {
1027
+ columnsWidth.value[1][0] = memoryWidth
1028
+ }
1029
+ }
1030
+
1031
+ const setResizeObserveWithInfo = (): void => {
1032
+ const el = document.querySelector('.datagrid')
1033
+
1034
+ if (!el) {
1035
+ setTimeout(setResizeObserveWithInfo, 0)
1036
+ return
1037
+ }
1038
+
1039
+ resizeObserveWithInfo = new ResizeObserver(setColumnWidthWithInfo)
1040
+ resizeObserveWithInfo.observe(el)
1041
+ }
1042
+
1043
+ // Export
1044
+ const exportItems = computed<UI_I_DropdownButtonItem[]>(() =>
1045
+ exportItemsFunc(
1046
+ localization.value,
1047
+ bodyItemsPresent.value.length || 0,
1048
+ props.selectedRow?.length || 0,
1049
+ props.testId || ''
1050
+ )
1051
+ )
1052
+ const onExport = (type: '0' | '1'): void => {
1053
+ switch (type) {
1054
+ case '0':
1055
+ onExportAll()
1056
+ break
1057
+ case '1':
1058
+ exportSelected()
1059
+ }
1060
+ }
1061
+ const onExportAll = (): void => {
1062
+ const rows = document.querySelectorAll(
1063
+ `#${tableWrapperId} .datagrid-row-scrollable`
1064
+ ) as NodeListOf<HTMLElement>
1065
+ generateCsvAndDownload(Array.from(rows))
1066
+ }
1067
+ const exportSelected = (): void => {
1068
+ const header = document.querySelectorAll(
1069
+ `#${tableWrapperId} .datagrid-row-scrollable`
1070
+ )[0] as HTMLElement
1071
+ const rows = document.querySelectorAll(
1072
+ `#${tableWrapperId} .datagrid-selected`
1073
+ ) as NodeListOf<HTMLElement>
1074
+ generateCsvAndDownload([header, ...Array.from(rows)])
1075
+ }
1076
+
1077
+ onMounted(() => {
1078
+ window.addEventListener('mousemove', mousemove)
1079
+ window.addEventListener('mouseup', mouseup)
1080
+
1081
+ if (props.withInfo) {
1082
+ setResizeObserveWithInfo()
1083
+ }
1084
+
1085
+ setResizeObserve()
1086
+ })
1087
+ onUnmounted(() => {
1088
+ window.removeEventListener('mouseup', mouseup)
1089
+ window.removeEventListener('mousemove', mousemove)
1090
+ })
1091
+ </script>
1092
+
1093
+ <style scoped lang="scss">
1094
+ @import '~/assets/scss/common/mixins';
1095
+ .datagrid-outer-wrapper {
1096
+ @include flex($dir: row);
1097
+ //padding-top: 12px;
1098
+ flex-grow: 1;
1099
+ overflow: auto;
1100
+
1101
+ &.datagrid-outer-wrapper-opened-info {
1102
+ width: 35%;
1103
+ min-width: 195px;
1104
+ }
1105
+
1106
+ & * {
1107
+ box-sizing: border-box;
1108
+ }
1109
+
1110
+ & svg {
1111
+ fill: var(--table-color);
1112
+ }
1113
+
1114
+ .datagrid-inner-wrapper {
1115
+ @include flex($dir: column);
1116
+ flex-grow: 1;
1117
+ overflow: auto;
1118
+
1119
+ .main-filter-content {
1120
+ align-items: center;
1121
+
1122
+ .filter-icon {
1123
+ width: 16px;
1124
+ height: 16px;
1125
+ margin-right: 10px;
1126
+ }
1127
+ }
1128
+ .datagrid {
1129
+ overflow: auto;
1130
+ flex: 1 1 auto;
1131
+ border-radius: 0.125rem 0.125rem 0 0;
1132
+ background-color: var(--block-view-bg-color);
1133
+ border-color: var(--global-border-color);
1134
+ margin-top: 0;
1135
+
1136
+ &.datagrid-opened-info {
1137
+ border-radius: 0.125rem 0 0 0;
1138
+ overflow-x: hidden;
1139
+ }
1140
+
1141
+ .datagrid-table-wrapper {
1142
+ min-width: max-content;
1143
+ display: flex;
1144
+ flex: 1 1 auto;
1145
+ min-height: 100%;
1146
+
1147
+ .datagrid-table {
1148
+ @include flex($dir: column);
1149
+ flex: 1 1 auto;
1150
+ align-content: flex-start;
1151
+ position: relative;
1152
+
1153
+ .datagrid-header {
1154
+ position: sticky;
1155
+ top: 0;
1156
+ z-index: 501;
1157
+ width: auto;
1158
+
1159
+ .datagrid-row-scrollable {
1160
+ flex-direction: row;
1161
+
1162
+ .datagrid-column-separator {
1163
+ user-select: none;
1164
+
1165
+ &::after {
1166
+ cursor: col-resize;
1167
+ }
1168
+ &.double-arrow-separator .datagrid-column-handle {
1169
+ cursor: unset;
1170
+ }
1171
+ &.double-arrow-separator::after {
1172
+ cursor: unset;
1173
+ }
1174
+ }
1175
+ }
1176
+
1177
+ .datagrid-row {
1178
+ color: var(--table-color);
1179
+ background-color: var(--block-view-bg-color);
1180
+
1181
+ &.datagrid-selected {
1182
+ background-color: var(--row-selected-bg-color);
1183
+ border-bottom: 1px solid var(--global-border-color);
1184
+
1185
+ & :deep(*) {
1186
+ color: var(--table-active-color);
1187
+ }
1188
+ }
1189
+
1190
+ .datagrid-column {
1191
+ background-color: var(--block-view-bg-color);
1192
+ border-bottom: 1px solid var(--global-border-color);
1193
+ padding: 6px 12px 5px;
1194
+ position: relative;
1195
+ //flex: 1 1 auto;
1196
+
1197
+ &:last-child {
1198
+ flex: 1 1 auto;
1199
+ }
1200
+
1201
+ &.datagrid-toggle-block {
1202
+ width: 38px;
1203
+ min-width: 38px;
1204
+
1205
+ &::after {
1206
+ content: '';
1207
+ width: 0.05rem;
1208
+ height: calc(100% - 0.5rem);
1209
+ position: absolute;
1210
+ right: 0;
1211
+ top: 0.25rem;
1212
+ background-color: var(--global-border-color);
1213
+ }
1214
+
1215
+ .datagrid-column-separator {
1216
+ cursor: default;
1217
+
1218
+ &::after {
1219
+ cursor: default;
1220
+ }
1221
+ }
1222
+ }
1223
+ }
1224
+
1225
+ .datagrid-column-title {
1226
+ align-self: auto;
1227
+ color: var(--table-color);
1228
+ background-color: var(--block-view-bg-color);
1229
+ border-bottom-color: var(--global-border-color);
1230
+ font-size: 11px;
1231
+ @include flex($align: center);
1232
+ display: flex;
1233
+ flex-direction: row;
1234
+ justify-content: flex-start;
1235
+ align-items: center;
1236
+ //line-height: 24px;
1237
+ line-height: normal;
1238
+
1239
+ .title-column {
1240
+ font-weight: bold;
1241
+ font-size: 11px;
1242
+ overflow: hidden;
1243
+ text-wrap: none;
1244
+ text-overflow: ellipsis;
1245
+ }
1246
+
1247
+ .sort-arrow-wrap {
1248
+ margin-left: auto;
1249
+ height: 14px;
1250
+ width: 14px;
1251
+ min-height: 14px;
1252
+ min-width: 14px;
1253
+ vertical-align: middle;
1254
+
1255
+ .sort-arrow {
1256
+ &.down {
1257
+ transform: rotate(180deg);
1258
+ }
1259
+ }
1260
+ }
1261
+ .title-icon {
1262
+ width: 24px;
1263
+ height: 24px;
1264
+ }
1265
+ }
1266
+
1267
+ .datagrid-filter-toggle {
1268
+ background: unset;
1269
+ margin-top: -4px;
1270
+ align-self: center;
1271
+
1272
+ .filter-icon {
1273
+ width: 16px;
1274
+ height: 16px;
1275
+ }
1276
+ }
1277
+ }
1278
+ }
1279
+
1280
+ .datagrid-placeholder-container {
1281
+ .datagrid-placeholder.datagrid-empty {
1282
+ background: var(--block-view-bg-color);
1283
+ }
1284
+ span {
1285
+ font-size: 16px;
1286
+ color: var(--global-font-color4);
1287
+ }
1288
+ }
1289
+
1290
+ .datagrid-row {
1291
+ width: 100%;
1292
+ min-width: max-content;
1293
+ border-top: none;
1294
+ color: var(--table-color);
1295
+ background-color: var(--block-view-bg-color);
1296
+ border-bottom: 1px solid var(--global-border-color);
1297
+
1298
+ &.datagrid-selected {
1299
+ & :deep(*) {
1300
+ color: var(--table-active-color);
1301
+ }
1302
+
1303
+ .datagrid-cell {
1304
+ background-color: var(--row-selected-bg-color);
1305
+ border-bottom: 1px solid var(--global-border-color);
1306
+ position: relative;
1307
+ line-height: 1rem;
1308
+ }
1309
+
1310
+ .datagrid-row-detail {
1311
+ background-color: var(--row-selected-bg-color);
1312
+ border-bottom: 1px solid var(--global-border-color);
1313
+ }
1314
+ }
1315
+
1316
+ .datagrid-cell {
1317
+ min-width: 38px;
1318
+ min-height: 28px;
1319
+ padding: 2px 12px 3px 12px;
1320
+ position: relative;
1321
+
1322
+ &:has(.double-arrow-wrap) {
1323
+ padding-left: 4px;
1324
+ }
1325
+
1326
+ &:has(.double-arrow-wrap)::after {
1327
+ content: '';
1328
+ width: 0.5px;
1329
+ height: calc(100% - 6px);
1330
+ position: absolute;
1331
+ right: 2px;
1332
+ top: 3px;
1333
+ background-color: var(--global-border-color);
1334
+ }
1335
+
1336
+ &:last-child {
1337
+ flex: 1 1 auto;
1338
+ }
1339
+
1340
+ button {
1341
+ height: 0.9rem;
1342
+ width: 0.9rem;
1343
+
1344
+ .arrow-icon {
1345
+ width: 16px;
1346
+ height: 16px;
1347
+ transform: rotate(90deg);
1348
+ }
1349
+ }
1350
+
1351
+ .datagrid-cell-icon {
1352
+ display: inline-block;
1353
+ width: 16px;
1354
+ height: 16px;
1355
+ }
1356
+
1357
+ .datagrid-expandable-caret-button {
1358
+ cursor: pointer;
1359
+ width: 100%;
1360
+
1361
+ .datagrid-expandable-caret-icon {
1362
+ width: 16px;
1363
+ height: 16px;
1364
+ transform: rotate(90deg);
1365
+ fill: var(--table-caret-color);
1366
+
1367
+ &.toggle {
1368
+ transform: rotate(180deg);
1369
+ }
1370
+ }
1371
+ }
1372
+ }
1373
+
1374
+ &.datagrid-selected-info {
1375
+ width: 100%;
1376
+ min-width: max-content;
1377
+ border-top: none;
1378
+ color: var(--table-color);
1379
+ background-color: var(--block-view-bg-color);
1380
+
1381
+ .datagrid-cell {
1382
+ position: relative;
1383
+
1384
+ &.hidden-text-triangle::after {
1385
+ content: '';
1386
+ position: absolute;
1387
+ transform: rotate(225deg);
1388
+ border-bottom: 15px solid transparent;
1389
+ border-right: 15px solid var(--global-bg-color);
1390
+ bottom: 26%;
1391
+ right: -16px;
1392
+ z-index: 1000;
1393
+ }
1394
+
1395
+ &.hidden-text-triangle::before {
1396
+ content: '';
1397
+ transform: rotate(-135deg);
1398
+ position: absolute;
1399
+ border-bottom: 16px solid transparent;
1400
+ border-right: 16px solid var(--global-border-color);
1401
+ bottom: 23%;
1402
+ right: -17px;
1403
+ z-index: 999;
1404
+ }
1405
+ }
1406
+ }
1407
+ }
1408
+
1409
+ .datagrid-row-sticky {
1410
+ @include flex($w: nowrap);
1411
+ position: sticky;
1412
+ left: 0;
1413
+ z-index: 500;
1414
+ background-color: var(--block-view-bg-color);
1415
+
1416
+ .datagrid-column {
1417
+ color: var(--table-color);
1418
+ background-color: var(--block-view-bg-color);
1419
+ border-bottom-color: var(--global-border-color);
1420
+ text-align: left;
1421
+ display: flex;
1422
+ flex: 1 1 auto;
1423
+ vertical-align: top;
1424
+ border: none;
1425
+
1426
+ &.datagrid-expandable-caret {
1427
+ .datagrid-column-separator {
1428
+ display: block;
1429
+
1430
+ &::after {
1431
+ top: 0;
1432
+ height: 18px;
1433
+ }
1434
+ }
1435
+
1436
+ .radio-btn {
1437
+ width: 16px;
1438
+ height: 16px;
1439
+ }
1440
+ }
1441
+
1442
+ .datagrid-column-separator {
1443
+ position: relative;
1444
+ //left: 0.6rem;
1445
+ flex: 0 0 auto;
1446
+ width: 0.05rem;
1447
+ order: 100;
1448
+ margin-left: auto;
1449
+ height: 100%;
1450
+ }
1451
+ }
1452
+
1453
+ .datagrid-fixed-column-without-separator {
1454
+ background-color: var(--block-view-bg-color);
1455
+
1456
+ &::after {
1457
+ background-color: transparent;
1458
+ }
1459
+ }
1460
+
1461
+ .datagrid-fixed-column {
1462
+ background-color: var(--block-view-bg-color);
1463
+
1464
+ //&::after {
1465
+ // content: '';
1466
+ // width: 0.05rem;
1467
+ // height: calc(100% - 0.5rem);
1468
+ // position: absolute;
1469
+ // right: 0;
1470
+ // top: 0.25rem;
1471
+ // background-color: var(--global-border-color);
1472
+ //}
1473
+
1474
+ .clr-form-control-disabled {
1475
+ .clr-checkbox-wrapper {
1476
+ label {
1477
+ cursor: not-allowed;
1478
+ }
1479
+ }
1480
+ }
1481
+ }
1482
+
1483
+ .datagrid-fixed-width {
1484
+ &::after {
1485
+ content: '';
1486
+ width: 0.05rem;
1487
+ height: calc(100% - 0.5rem);
1488
+ position: absolute;
1489
+ right: 0;
1490
+ top: 0.25rem;
1491
+ background-color: var(--global-border-color);
1492
+ }
1493
+ }
1494
+ }
1495
+
1496
+ .datagrid-row-scrollable {
1497
+ @include flex($ff: row nowrap);
1498
+ flex: 1 1 auto;
1499
+
1500
+ .datagrid-scrolling-cells {
1501
+ @include flex($ff: row nowrap);
1502
+ flex: 1 1 auto;
1503
+ }
1504
+ }
1505
+ .datagrid-body-row {
1506
+ .datagrid-row-scrollable {
1507
+ @include flex($ff: column nowrap);
1508
+
1509
+ .datagrid-row-detail {
1510
+ flex: 1;
1511
+ }
1512
+ }
1513
+
1514
+ &:not(.datagrid-selected):hover {
1515
+ border-bottom: 1px solid var(--table-hover-row-border-color);
1516
+ background-color: var(--table-hover-row-background-color);
1517
+ color: var(--table-hover-row-color);
1518
+
1519
+ .datagrid-fixed-column {
1520
+ background-color: var(--table-hover-row-background-color);
1521
+ }
1522
+ .datagrid-cell {
1523
+ background-color: var(--table-hover-row-background-color);
1524
+ }
1525
+ }
1526
+ }
1527
+ }
1528
+ }
1529
+ }
1530
+
1531
+ .datagrid-footer {
1532
+ flex: 0 0 auto;
1533
+ @include flex($ff: row nowrap, $just: space-between, $align: stretch);
1534
+ font-size: 0.55rem;
1535
+ background-color: var(--block-view-bg-color);
1536
+ border: 0.05rem solid var(--global-border-color);
1537
+ border-top: none;
1538
+ border-radius: 0 0 0.15rem 0.15rem;
1539
+ padding: 0 0.6rem;
1540
+ height: 28px;
1541
+
1542
+ &.datagrid-footer-opened-info {
1543
+ border-radius: 0 0 0 0.15rem;
1544
+ flex-direction: row-reverse;
1545
+ }
1546
+
1547
+ .clr-form-control-disabled {
1548
+ opacity: 1;
1549
+
1550
+ .clr-checkbox-wrapper {
1551
+ label {
1552
+ color: #8c8c8c;
1553
+ margin-right: 9px;
1554
+ padding-left: 22px;
1555
+ &:before {
1556
+ position: absolute;
1557
+ top: 4px;
1558
+ left: 0;
1559
+ content: '';
1560
+ display: inline-block;
1561
+ height: 16px;
1562
+ width: 16px;
1563
+ border: none;
1564
+ border-radius: 3px;
1565
+ background-color: var(--table-checkbox-color);
1566
+ }
1567
+
1568
+ &:after {
1569
+ position: absolute;
1570
+ content: '';
1571
+ display: inline-block;
1572
+ height: 5px;
1573
+ width: 8px;
1574
+ border-left: 2px solid #fff;
1575
+ border-bottom: 2px solid #fff;
1576
+ top: 4px;
1577
+ left: 4px;
1578
+ transform: translateY(4px) rotate(-45deg);
1579
+ }
1580
+ }
1581
+ }
1582
+ }
1583
+ }
1584
+
1585
+ .datagrid-spinner {
1586
+ top: 0.6rem;
1587
+ height: calc(100% - 0.6rem);
1588
+ }
1589
+
1590
+ .datagrid-footer-description {
1591
+ flex: 1 1 auto;
1592
+
1593
+ :deep(svg) {
1594
+ fill: var(--table-switch-color);
1595
+ }
1596
+ }
1597
+
1598
+ .clr-radio-wrapper,
1599
+ .clr-checkbox-wrapper {
1600
+ height: 18px;
1601
+ }
1602
+
1603
+ .clr-radio-wrapper label,
1604
+ .clr-checkbox-wrapper label {
1605
+ padding-left: 16px;
1606
+ }
1607
+ }
1608
+ }
1609
+ //.vertical-divider {
1610
+ // width: 1px;
1611
+ // height: 22px;
1612
+ // background: #bbb;
1613
+ // margin: 2px 2px 0 -5px;
1614
+ //}
1615
+
1616
+ .hidden-features {
1617
+ padding: 9px 14px;
1618
+ background-color: var(--global-bg-color);
1619
+ color: var(--global-font-color2);
1620
+ border: 1px solid var(--global-border-color);
1621
+ border-left: none;
1622
+ overflow-y: auto;
1623
+ overflow-x: hidden;
1624
+ width: 65%;
1625
+
1626
+ //.header {
1627
+ // display: flex;
1628
+ // align-items: center;
1629
+ // justify-content: space-between;
1630
+ // background-color: inherit;
1631
+ //
1632
+ // h3 {
1633
+ // font-size: 1rem;
1634
+ // color: var(--global-font-color2) !important;
1635
+ // line-height: 1.7rem;
1636
+ // }
1637
+ button {
1638
+ position: absolute;
1639
+ top: 24px;
1640
+ right: 24px;
1641
+ line-height: 24px;
1642
+
1643
+ .close-icon {
1644
+ //margin-left: 10px;
1645
+ width: 24px;
1646
+ height: 24px;
1647
+ }
1648
+ }
1649
+ //}
1650
+ }
1651
+ .double-arrow-width {
1652
+ width: 25px;
1653
+ }
1654
+ .double-arrow-wrap {
1655
+ width: 30px;
1656
+ height: 20px;
1657
+ padding-top: 1px;
1658
+ padding-left: 5px;
1659
+ cursor: pointer;
1660
+ background-color: transparent;
1661
+
1662
+ .double-arrow {
1663
+ background-color: transparent;
1664
+ transform: rotate(90deg);
1665
+ width: 16px;
1666
+ height: 16px;
1667
+ }
1668
+
1669
+ .double-arrow.arrow-selected {
1670
+ transform: rotate(-90deg) !important;
1671
+ background-color: #0079b8;
1672
+ }
1673
+ }
1674
+ .double-arrow-wrap.arrow-selected {
1675
+ background-color: #0079b8;
1676
+ border-radius: 3px;
1677
+ }
1678
+ </style>
1679
+
1680
+ <style>
1681
+ :root {
1682
+ --table-color: #565656;
1683
+ --table-active-color: #fff;
1684
+ --table-checkbox-color: #454545;
1685
+ --table-caret-color: #454545;
1686
+ --table-switch-color: #575757;
1687
+ --table-hover-row-border-color: #666;
1688
+ --table-hover-row-background-color: #e8e8e8;
1689
+ --table-hover-row-color: #454545;
1690
+ --table-spinner-bg-color: #ffffff99;
1691
+ }
1692
+
1693
+ :root.dark-theme {
1694
+ --table-color: #fff;
1695
+ --table-active-color: #565656;
1696
+ --table-checkbox-color: #49aeda;
1697
+ --table-caret-color: #ffffff;
1698
+ --table-switch-color: #b3b3b3;
1699
+ --table-hover-row-border-color: #fff;
1700
+ --table-hover-row-background-color: #324f61;
1701
+ --table-hover-row-color: #e9ecef;
1702
+ --table-spinner-bg-color: rgba(0, 0, 0, 0.5);
1703
+ }
1704
+ </style>