bfg-common 1.5.43 → 1.5.45

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 (185) hide show
  1. package/CODE_STYLE.md +109 -109
  2. package/assets/img/icons/icons-sprite-dark-3.svg +227 -227
  3. package/assets/img/icons/icons-sprite-dark-5.svg +488 -488
  4. package/assets/img/icons/icons-sprite-light-3.svg +227 -227
  5. package/assets/img/icons/icons-sprite-light-5.svg +488 -488
  6. package/assets/scss/common/normalize.scss +339 -339
  7. package/components/atoms/TheIcon3.vue +50 -50
  8. package/components/atoms/collapse/CollapseNav.vue +165 -165
  9. package/components/atoms/dropdown/dropdown/Dropdown.vue +168 -168
  10. package/components/atoms/modal/bySteps/BySteps.vue +253 -253
  11. package/components/atoms/perPage/PerPage.vue +58 -58
  12. package/components/atoms/stack/StackBlock.vue +185 -185
  13. package/components/atoms/table/dataGrid/DataGrid.vue +1 -1
  14. package/components/atoms/table/dataGrid/DataGridColumnSwitch.vue +222 -222
  15. package/components/atoms/table/dataGrid/lib/config/settingsTable.ts +94 -94
  16. package/components/atoms/table/dataGrid/lib/utils/export.ts +16 -16
  17. package/components/atoms/tabs/VerticalTabs.vue +105 -105
  18. package/components/atoms/tooltip/Signpost.vue +227 -227
  19. package/components/common/accordion/Recursion.vue +222 -222
  20. package/components/common/browse/BrowseNew.vue +237 -237
  21. package/components/common/browse/BrowseOld.vue +217 -217
  22. package/components/common/browse/blocks/contents/Files.vue +37 -37
  23. package/components/common/browse/blocks/contents/FilesOld.vue +72 -72
  24. package/components/common/browse/blocks/contents/filesNew/FilesNew.vue +96 -96
  25. package/components/common/browse/blocks/contents/filesNew/Skeleton.vue +18 -18
  26. package/components/common/context/Context.vue +111 -111
  27. package/components/common/context/lib/models/interfaces.ts +31 -31
  28. package/components/common/context/recursion/Recursion.vue +87 -87
  29. package/components/common/context/recursion/RecursionNew.vue +238 -238
  30. package/components/common/context/recursion/RecursionOld.vue +228 -228
  31. package/components/common/details/DetailsItem.vue +109 -109
  32. package/components/common/diagramMain/DiagramMain.vue +897 -897
  33. package/components/common/diagramMain/Header.vue +214 -214
  34. package/components/common/layout/theHeader/helpMenu/About.vue +82 -82
  35. package/components/common/layout/theHeader/helpMenu/aboutNew/AboutNew.vue +103 -103
  36. package/components/common/layout/theHeader/userMenu/modals/preferences/view/ViewOld.vue +112 -112
  37. package/components/common/mainNavigationPanel/MainNavigationPanelNew.vue +336 -336
  38. package/components/common/mainNavigationPanel/MainNavigationPanelOld.vue +311 -311
  39. package/components/common/modals/unsavedChanges/UnsavedChanges.vue +56 -56
  40. package/components/common/monitor/overview/OverviewOld.vue +139 -139
  41. package/components/common/pages/home/StatusContent.vue +49 -49
  42. package/components/common/pages/home/headline/Headline.vue +45 -45
  43. package/components/common/pages/home/headline/HeadlineOld.vue +42 -42
  44. package/components/common/pages/home/lib/models/interfaces.ts +48 -48
  45. package/components/common/pages/home/widgets/Widgets.vue +49 -49
  46. package/components/common/pages/home/widgets/WidgetsNew.vue +86 -86
  47. package/components/common/pages/home/widgets/WidgetsOld.vue +34 -34
  48. package/components/common/pages/home/widgets/hosts/Hosts.vue +27 -27
  49. package/components/common/pages/home/widgets/hosts/lib/config/items.ts +23 -23
  50. package/components/common/pages/home/widgets/vms/Vms.vue +26 -26
  51. package/components/common/pages/home/widgets/vms/VmsOld.vue +35 -35
  52. package/components/common/pages/home/widgets/vms/lib/config/items.ts +19 -19
  53. package/components/common/pages/licensing/Licensing.vue +128 -0
  54. package/components/common/pages/licensing/lib/models/interfaces.ts +22 -0
  55. package/components/common/pages/licensing/lib/utils/validation.ts +29 -0
  56. package/components/common/pages/licensing/listView/ListView.vue +50 -0
  57. package/components/common/pages/licensing/listView/lib/config/list.ts +57 -0
  58. package/components/common/pages/licensing/listView/lib/models/interfaces.ts +5 -0
  59. package/components/common/pages/licensing/modals/assign/Assign.vue +247 -0
  60. package/components/common/pages/licensing/modals/assign/lib/config/tabsPannel.ts +17 -0
  61. package/components/common/pages/licensing/modals/assign/lib/models/interfaces.ts +5 -0
  62. package/components/common/pages/licensing/modals/assign/lib/utils/error.ts +25 -0
  63. package/components/common/pages/licensing/modals/assign/new/New.vue +216 -0
  64. package/components/common/pages/licensing/modals/assign/tableView/TableView.vue +193 -0
  65. package/components/common/pages/licensing/modals/assign/tableView/lib/config/table.ts +100 -0
  66. package/components/common/pages/licensing/modals/assign/tableView/lib/config/tableKeys.ts +10 -0
  67. package/components/common/pages/licensing/modals/assign/tableView/lib/models/interfaces.ts +9 -0
  68. package/components/common/pages/licensing/modals/assign/tableView/lib/models/types.ts +8 -0
  69. package/components/common/pages/packages/Packages.vue +208 -208
  70. package/components/common/pages/shortcuts/block/BlockNew.vue +96 -96
  71. package/components/common/pages/shortcuts/block/BlockOld.vue +68 -68
  72. package/components/common/portlets/customAttributes/Portlet.vue +667 -667
  73. package/components/common/portlets/tag/Portlet.vue +433 -433
  74. package/components/common/recursionTree/RecursionTree.vue +223 -223
  75. package/components/common/select/button/ButtonDropdown.vue +108 -108
  76. package/components/common/spiceConsole/Drawer.vue +370 -370
  77. package/components/common/spiceConsole/lib/models/interfaces.ts +5 -5
  78. package/components/common/split/horizontal/HorizontalNew.vue +376 -376
  79. package/components/common/split/horizontal/HorizontalOld.vue +337 -337
  80. package/components/common/split/vertical/Vertical.vue +160 -160
  81. package/components/common/tools/Actions.vue +188 -188
  82. package/components/common/vm/actions/add/Add.vue +774 -774
  83. package/components/common/vm/actions/add/lib/config/steps.ts +247 -247
  84. package/components/common/vm/actions/clone/Clone.vue +798 -798
  85. package/components/common/vm/actions/clone/lib/config/steps.ts +291 -291
  86. package/components/common/vm/actions/clone/toTemplate/ToTemplate.vue +634 -634
  87. package/components/common/vm/actions/clone/toTemplate/lib/config/steps.ts +116 -116
  88. package/components/common/vm/actions/common/customizeHardware/CustomizeHardware.vue +275 -275
  89. package/components/common/vm/actions/common/customizeHardware/CustomizeHardwareNew.vue +274 -274
  90. package/components/common/vm/actions/common/customizeHardware/CustomizeHardwareOld.vue +177 -177
  91. package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardware.vue +698 -698
  92. package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardwareNew.vue +410 -410
  93. package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardwareOld.vue +319 -319
  94. package/components/common/vm/actions/common/customizeHardware/virtualHardware/browseView/BrowseView.vue +219 -219
  95. package/components/common/vm/actions/common/customizeHardware/virtualHardware/bus/Bus.vue +99 -99
  96. package/components/common/vm/actions/common/customizeHardware/virtualHardware/bus/BusNew.vue +117 -117
  97. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDrive.vue +232 -232
  98. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDriveNew.vue +164 -164
  99. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDriveOld.vue +168 -168
  100. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/Media.vue +25 -25
  101. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/MediaNew.vue +70 -70
  102. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/media/MediaOld.vue +50 -50
  103. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/Cpu.vue +338 -338
  104. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/Shares.vue +140 -140
  105. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/lib/config/options.ts +28 -28
  106. package/components/common/vm/actions/common/customizeHardware/virtualHardware/limit/Limit.vue +220 -220
  107. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +368 -368
  108. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDiskNew.vue +232 -232
  109. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDiskOld.vue +250 -250
  110. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/mode/ModeOld.vue +56 -56
  111. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/sharing/SharingNew.vue +44 -44
  112. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/NewNetwork.vue +286 -286
  113. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/NewNetworkNew.vue +124 -124
  114. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/location/LocationOld.vue +134 -134
  115. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/location/new/New.vue +63 -63
  116. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/location/new/table/lib/config/config.ts +95 -95
  117. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddress.vue +119 -119
  118. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddressNew.vue +69 -69
  119. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddressOld.vue +83 -83
  120. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/NewPciDevice.vue +205 -205
  121. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/directPathIo/DirectPathIoNew.vue +66 -66
  122. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/directPathIo/DirectPathIoOld.vue +62 -62
  123. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIo.vue +31 -31
  124. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIoNew.vue +84 -84
  125. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIoOld.vue +76 -76
  126. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/Note.vue +15 -15
  127. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/NoteNew.vue +42 -42
  128. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/note/NoteOld.vue +30 -30
  129. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/nvidiaGrid/NvidiaGrid.vue +41 -41
  130. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/nvidiaGrid/NvidiaGridNew.vue +81 -81
  131. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/nvidiaGrid/NvidiaGridOld.vue +84 -84
  132. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newUsbController/NewUsbControllerNew.vue +56 -56
  133. package/components/common/vm/actions/common/customizeHardware/virtualHardware/other/Other.vue +16 -16
  134. package/components/common/vm/actions/common/customizeHardware/virtualHardware/other/OtherNew.vue +30 -30
  135. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCardNew.vue +104 -104
  136. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCardOld.vue +112 -112
  137. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/totalVideoMemory/TotalVideoMemoryNew.vue +54 -54
  138. package/components/common/vm/actions/common/customizeHardware/vmoptions/Vmoptions.vue +145 -145
  139. package/components/common/vm/actions/common/customizeHardware/vmoptions/VmoptionsNew.vue +102 -102
  140. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/BootOptionsNew.vue +75 -75
  141. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/delay/Delay.vue +26 -26
  142. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/firmware/Firmware.vue +57 -57
  143. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/firmware/FirmwareNew.vue +42 -42
  144. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/menu/MenuNew.vue +25 -25
  145. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/Order.vue +171 -171
  146. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/OrderNew.vue +50 -50
  147. package/components/common/vm/actions/common/customizeHardware/vmoptions/generalOptions/GeneralOptionsNew.vue +141 -141
  148. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/New.vue +140 -140
  149. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/copyPaste/CopyPasteNew.vue +30 -30
  150. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/fileTransfer/FileTransferNew.vue +30 -30
  151. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/folderSharing/FolderSharingNew.vue +30 -30
  152. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/Keymap.vue +32 -32
  153. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/KeymapNew.vue +39 -39
  154. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/Password.vue +103 -103
  155. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/PasswordNew.vue +102 -102
  156. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/PasswordOld.vue +94 -94
  157. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirection.vue +28 -28
  158. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirectionNew.vue +38 -38
  159. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirectionOld.vue +44 -44
  160. package/components/common/vm/actions/common/lib/utils/capabilities.ts +52 -52
  161. package/components/common/vm/actions/common/select/createType/CreateType.vue +74 -74
  162. package/components/common/vm/actions/common/select/storage/Storage.vue +130 -130
  163. package/components/common/vm/actions/common/select/storage/StorageOld.vue +129 -129
  164. package/components/common/vm/actions/common/select/template/Template.vue +65 -65
  165. package/components/common/vm/actions/common/select/template/TemplateTreeView.vue +88 -88
  166. package/components/common/vm/actions/editSettings/new/Skeleton.vue +88 -88
  167. package/components/common/wizards/datastore/add/lib/config/steps.ts +138 -138
  168. package/components/common/wizards/datastore/add/nfs/accessibility/Accessibility.vue +60 -60
  169. package/components/common/wizards/datastore/add/readyComplete/ReadyComplete.vue +92 -92
  170. package/components/common/wizards/network/add/steps/SelectConnectionType.vue +105 -105
  171. package/components/common/wizards/vm/migrate/lib/config/constructDataReady.ts +220 -220
  172. package/components/common/wizards/vm/migrate/select/network/Network.vue +103 -103
  173. package/components/common/wizards/vm/migrate/select/network/table/network/Network.vue +150 -150
  174. package/components/common/wizards/vm/migrate/select/network/table/network/lib/config/advancedTable.ts +91 -91
  175. package/components/common/wizards/vm/migrate/select/priority/Priority.vue +43 -43
  176. package/composables/productNameLocal.ts +30 -30
  177. package/composables/useAppVersion.ts +21 -21
  178. package/package.json +1 -1
  179. package/plugins/date.ts +233 -233
  180. package/plugins/directives.ts +24 -24
  181. package/public/spice-console/lib/images/bitmap.js +203 -203
  182. package/public/spice-console/network/spicechannel.js +383 -383
  183. package/store/main/mutations.ts +7 -7
  184. package/store/main/state.ts +7 -7
  185. package/store/tasks/mappers/recentTasks.ts +64 -64
@@ -1,667 +1,667 @@
1
- <template>
2
- <div>
3
- <ui-portlet
4
- class="attributes"
5
- test-id="attributes-portlet"
6
- :title="portletTitle"
7
- :dragged="props.dragged"
8
- :dragged-any="props.draggedAny"
9
- :is-open="props.isOpen"
10
- :portlet-id="props.portletId"
11
- :is-loading="props.isLoading"
12
- @toggle="onTogglePortlet"
13
- >
14
- <template #portletBody="{ isLoadingBody }">
15
- <ui-data-table
16
- test-id="attributes-portlet-table"
17
- :data="data"
18
- :options="attributeTableHeaderOptions"
19
- server-off
20
- :default-layout="false"
21
- size="sm"
22
- :loading="isLoadingBody"
23
- :skeleton="skeletonData"
24
- >
25
- <template #notFound>
26
- <div
27
- v-if="!allRowsCount"
28
- class="add-new-attribute-button-container"
29
- >
30
- <ui-button
31
- v-development="true"
32
- test-id="add-new-attribute-button"
33
- variant="text"
34
- is-without-height
35
- is-without-sizes
36
- :disabled="hasEditRow"
37
- @click="onAddNew"
38
- >
39
- {{ localization.zabbix.addNew }}...
40
- </ui-button>
41
- </div>
42
- </template>
43
- <!-- :loading="loading"-->
44
- <template #icon="{ item }">
45
- <div v-if="item.data.type === 'options'" class="actions-container">
46
- <span
47
- v-development="true"
48
- :id="`actions-attributes-${item.data.row}`"
49
- :class="[
50
- 'icon-container',
51
- {
52
- selected: isShow[`action-attributes-${item.data.row}`],
53
- },
54
- ]"
55
- @click="onShowActions(item.data.row)"
56
- >
57
- <ui-icon :name="item.data.icon" width="16" height="16" />
58
- </span>
59
- <ui-popup-window
60
- v-model="isShow[`action-attributes-${item.data.row}`]"
61
- :elem-id="`actions-attributes-${item.data.row}`"
62
- width="fit-content"
63
- left
64
- bottom
65
- >
66
- <div class="actions-dropdown-container">
67
- <div
68
- :class="['action', { disabled: hasEditRow }]"
69
- data-id="edit-attribute-action"
70
- @click="onEditAttribute(item.data.row)"
71
- >
72
- <!-- @click="onShowDetails(item.data.row)"-->
73
- <ui-icon name="edit" width="16" height="16" />
74
- <span>{{ localization.common.edit }}</span>
75
- </div>
76
- <div
77
- class="action-remove"
78
- data-id="delete-attribute-action"
79
- @click="onShowRemoveDialog(item.data.row)"
80
- >
81
- <ui-icon name="delete" width="16" height="16" />
82
- <span>{{ localization.common.delete }}</span>
83
- </div>
84
- </div>
85
- </ui-popup-window>
86
- </div>
87
- <template v-if="item.data.type === 'attribute'">
88
- <input
89
- v-model="editData.attribute"
90
- data-id="attribute-name-input"
91
- :class="[
92
- 'table-input',
93
- {
94
- 'table-input-error':
95
- validationData.attribute && isShowValidation,
96
- },
97
- ]"
98
- :placeholder="localization.common[item.data.type]"
99
- type="text"
100
- @click.prevent.stop
101
- />
102
- </template>
103
-
104
- <template v-else-if="item.data.type === 'value'">
105
- <input
106
- v-model="editData.value"
107
- :class="[
108
- 'table-input',
109
- {
110
- 'table-input-error':
111
- validationData.value && isShowValidation,
112
- },
113
- ]"
114
- :placeholder="localization.common[item.data.type]"
115
- type="text"
116
- data-id="attribute-value-input"
117
- @click.prevent.stop
118
- />
119
- </template>
120
- <template v-else-if="item.data.type === 'type'">
121
- <div class="category-select">
122
- <ui-select
123
- v-model="editData.type"
124
- :items="selectItems"
125
- :placeholder="localization.common.chooseCategory"
126
- width="165px"
127
- select-width="100%"
128
- :show-text="true"
129
- :error="validationData.type && isShowValidation"
130
- :disabled="isEditRow"
131
- size="sm"
132
- test-id="attribute-type-select"
133
- />
134
- </div>
135
- </template>
136
- <template v-else-if="item.data.type === 'actions'">
137
- <div class="edit-actions-container">
138
- <span
139
- class="hide-row"
140
- data-id="hide-create-attribute-row"
141
- @click.prevent.stop="onHideEditRow"
142
- >
143
- <ui-icon name="close" width="16" height="16" />
144
- </span>
145
- <span
146
- class="create-row"
147
- data-id="create-attribute-accept"
148
- @click.prevent.stop="onAddAttribute"
149
- >
150
- <ui-icon name="status-check" width="16" height="16" />
151
- </span>
152
- </div>
153
- </template>
154
- </template>
155
- </ui-data-table>
156
- </template>
157
- <template #portletFooter="{ isLoadingFooter }">
158
- <div class="footer">
159
- <ui-button
160
- v-if="!isLoadingFooter"
161
- v-development="true"
162
- test-id="add-new-attribute-button"
163
- variant="text"
164
- is-without-height
165
- is-without-sizes
166
- :disabled="hasEditRow"
167
- @click="onAddNew"
168
- >
169
- {{ localization.zabbix.addNew }}...
170
- </ui-button>
171
- <ui-portlet-skeleton-footer v-else />
172
- </div>
173
- </template>
174
- </ui-portlet>
175
-
176
- <ui-popup
177
- v-if="isShowRemoveDialog"
178
- test-id="remove-attribute-dialog"
179
- icon-name="info-status"
180
- :texts="removeAttributeDialogTexts"
181
- :message="removeAttributeMessage"
182
- :title="localization.zabbix.deleteConfirmation"
183
- @hide="onHideRemoveDialog"
184
- @submit="onRemoveAttribute"
185
- />
186
- </div>
187
- </template>
188
-
189
- <script setup lang="ts">
190
- import type {
191
- UI_I_DataTable,
192
- UI_I_DataTableHeader,
193
- UI_I_DataTableBody,
194
- } from '~/node_modules/bfg-uikit/components/ui/dataTable/models/interfaces'
195
- import type { UI_I_Dropdown } from '~/node_modules/bfg-uikit/components/ui/dropdown/models/interfaces'
196
- import type { UI_I_ModalTexts } from '~/node_modules/bfg-uikit/components/ui/modal/models/interfaces'
197
- import type {
198
- UI_I_Localization,
199
- UI_I_ArbitraryObject,
200
- } from '~/lib/models/interfaces'
201
- import type { UI_I_NewAttributeData } from '~/components/common/portlets/customAttributes/lib/models/interfaces'
202
- import {
203
- attributeTableHeaderOptions,
204
- attributeTableHeaderDataFunc,
205
- createRow,
206
- makeNewAttributeCreateActionRowFunc,
207
- availableTypesFunc,
208
- skeletonData,
209
- } from '~/components/common/portlets/customAttributes/lib/config/config'
210
-
211
- const props = defineProps<{
212
- portletId: string
213
- dragged?: boolean
214
- isOpen?: boolean
215
- draggedAny?: boolean
216
- selectedItemName: string
217
- type: UI_I_Dropdown
218
- bodyItems: UI_I_DataTableBody[]
219
- isLoading: boolean
220
- }>()
221
-
222
- const localization = computed<UI_I_Localization>(() => useLocal())
223
-
224
- const portletTitle = computed<string>(() => {
225
- const count = allRowsCount.value
226
- ? ` (${isEditRow.value ? allRowsCount.value + 1 : allRowsCount.value})`
227
- : ''
228
-
229
- return localization.value.common.customAttributes + count
230
- })
231
-
232
- const isShow = ref<UI_I_ArbitraryObject<boolean>>({})
233
-
234
- const onShowActions = (id: number): void => {
235
- isShow.value[`action-attributes-${id}`] =
236
- !isShow.value[`action-attributes-${id}`]
237
- }
238
-
239
- const attributesHeadItems = computed<UI_I_DataTableHeader[]>(() =>
240
- attributeTableHeaderDataFunc(localization.value)
241
- )
242
-
243
- const attributesBodyItems = ref<UI_I_DataTableBody[]>([])
244
-
245
- const allRowsCount = computed<number>(
246
- () =>
247
- attributesBodyItems.value.filter(
248
- (row: UI_I_DataTableBody) => !row.actionRow
249
- ).length
250
- )
251
-
252
- const hasEditRow = computed<boolean>(
253
- () => !!attributesBodyItems.value.find((row) => row.actionRow)
254
- )
255
-
256
- const selectedType = computed<UI_I_Dropdown>(() => ({
257
- text: props.type.text,
258
- value: props.type.value,
259
- selected: true,
260
- }))
261
-
262
- const editData = ref<UI_I_NewAttributeData>({
263
- attribute: '',
264
- value: '',
265
- type: selectedType.value.text,
266
- })
267
-
268
- const resetFields = (): void => {
269
- editData.value = {
270
- attribute: '',
271
- value: '',
272
- type: selectedType.value.text,
273
- }
274
- }
275
-
276
- const isShowValidation = ref<boolean>(false)
277
- const validationData = computed<{
278
- attribute: boolean
279
- value: boolean
280
- type: boolean
281
- }>(() => ({
282
- attribute: !editData.value.attribute.trim(),
283
- value: !editData.value.value.trim(),
284
- type: !editData.value.type.trim(),
285
- }))
286
-
287
- watch(
288
- validationData,
289
- (newValue: { attribute: boolean; value: boolean; type: boolean }) => {
290
- !newValue.attribute &&
291
- !newValue.value &&
292
- !newValue.type &&
293
- (isShowValidation.value = false)
294
- },
295
- { deep: true }
296
- )
297
-
298
- const onAddAttribute = (): void => {
299
- if (
300
- validationData.value.attribute ||
301
- validationData.value.value ||
302
- validationData.value.type
303
- ) {
304
- isShowValidation.value = true
305
- return
306
- }
307
-
308
- if (isEditRow.value && editRowData.value) {
309
- const editedRowData = createRow(editRowData.value.row, editData.value)
310
-
311
- attributesBodyItems.value = attributesBodyItems.value.map((row) =>
312
- row.row === editRowData.value?.row ? editedRowData : row
313
- )
314
-
315
- emits('edit-attribute', editedRowData)
316
- isShow.value[`action-attributes-${editRowData.value?.row}`] = false
317
- editRowData.value = undefined
318
- isEditRow.value = false
319
- } else {
320
- const withoutEditRowData = attributesBodyItems.value.filter(
321
- (row) => !row.actionRow
322
- )
323
-
324
- const rowsIds = withoutEditRowData.map((row) => row.row).sort()
325
- let lastId = rowsIds[rowsIds.length - 1]
326
- lastId = lastId === undefined ? -1 : lastId
327
-
328
- const addedRowData = createRow(lastId + 1, editData.value)
329
-
330
- attributesBodyItems.value.push(addedRowData)
331
- emits('add-attribute', addedRowData)
332
- attributesBodyItems.value = attributesBodyItems.value.filter(
333
- (row) => !row.actionRow
334
- )
335
- }
336
-
337
- resetFields()
338
- }
339
-
340
- const onHideEditRow = (): void => {
341
- if (isEditRow.value && editRowData.value) {
342
- attributesBodyItems.value = attributesBodyItems.value.map((row) =>
343
- row.row === editRowData.value?.row ? editRowData.value : row
344
- )
345
- isShow.value[`action-attributes-${editRowData.value?.row}`] = false
346
- editRowData.value = undefined
347
- isEditRow.value = false
348
- } else {
349
- attributesBodyItems.value = attributesBodyItems.value.filter(
350
- (row) => !row.actionRow
351
- )
352
- }
353
- resetFields()
354
- }
355
-
356
- watch(
357
- () => props.bodyItems,
358
- (newValue: UI_I_DataTableBody[]) => {
359
- attributesBodyItems.value = newValue
360
- },
361
- { deep: true, immediate: true }
362
- )
363
-
364
- const data = computed<UI_I_DataTable>(() => ({
365
- id: 'attributes',
366
- selectedRows: [],
367
- isAllSelected: false,
368
- title: '',
369
- subTitle: '',
370
- header: attributesHeadItems.value,
371
- body: attributesBodyItems.value,
372
- }))
373
-
374
- const selectItems = ref<UI_I_Dropdown[]>(
375
- useDeepCopy(availableTypesFunc(selectedType.value))
376
- )
377
-
378
- const onAddNew = (): void => {
379
- const rowsIds = attributesBodyItems.value.map((row) => row.row).sort()
380
- let lastId = rowsIds[rowsIds.length - 1]
381
- lastId = lastId === undefined ? -1 : lastId
382
-
383
- attributesBodyItems.value.push(
384
- makeNewAttributeCreateActionRowFunc(lastId + 1)
385
- )
386
- }
387
-
388
- const removeAttributeDialogTexts = computed<UI_I_ModalTexts>(() => ({
389
- button1: localization.value.common.cancel,
390
- button2: localization.value.common.delete,
391
- }))
392
-
393
- const isShowRemoveDialog = ref<boolean>(false)
394
-
395
- const onHideRemoveDialog = (): void => {
396
- isShowRemoveDialog.value = false
397
- }
398
-
399
- const attributeIdForRemove = ref<number>(0)
400
- const attributeNameForRemove = computed<string>(
401
- () =>
402
- (attributesBodyItems.value.find(
403
- (row: UI_I_DataTableBody) => row.row === attributeIdForRemove.value
404
- )?.data[0]?.text || '') as string
405
- )
406
- const removeAttributeMessage = computed<string>(() =>
407
- localization.value.common.removeAttributeDialog
408
- .replace?.('{attributeName}', attributeNameForRemove.value)
409
- .replace('{selectedItemName}', props.selectedItemName)
410
- )
411
- const onShowRemoveDialog = (id: number): void => {
412
- attributeIdForRemove.value = id
413
- isShowRemoveDialog.value = true
414
- }
415
- const onRemoveAttribute = (): void => {
416
- onHideRemoveDialog()
417
-
418
- const removeItem = attributesBodyItems.value.find(
419
- (row) => row.row === attributeIdForRemove.value
420
- )
421
- if (!removeItem) return
422
-
423
- emits('remove-attribute', removeItem)
424
- attributesBodyItems.value = attributesBodyItems.value.filter(
425
- (row) => row.row !== attributeIdForRemove.value
426
- )
427
- }
428
-
429
- const isEditRow = ref<boolean>(false)
430
- const editRowData = ref<UI_I_DataTableBody | undefined>(undefined)
431
- const onEditAttribute = (id: number): void => {
432
- editRowData.value = useDeepCopy(
433
- attributesBodyItems.value.find((row) => row.row === id)
434
- )
435
-
436
- if (!editRowData.value) return
437
- isEditRow.value = true
438
-
439
- editData.value = {
440
- attribute: editRowData.value.data[0].text,
441
- value: editRowData.value.data[1].text,
442
- type: editRowData.value.data[2].text,
443
- }
444
-
445
- attributesBodyItems.value = attributesBodyItems.value.map((row) =>
446
- row.row === id ? makeNewAttributeCreateActionRowFunc(id) : row
447
- )
448
- }
449
-
450
- const emits = defineEmits<{
451
- (event: 'toggle-portlet', id: string): void
452
- (event: 'remove-attribute', value: UI_I_DataTableBody): void
453
- (event: 'add-attribute', value: UI_I_DataTableBody): void
454
- (event: 'edit-attribute', value: UI_I_DataTableBody): void
455
- }>()
456
-
457
- const onTogglePortlet = (id: string): void => {
458
- emits('toggle-portlet', id)
459
- }
460
- </script>
461
-
462
- <style>
463
- :root {
464
- --separator-color: #e9ebed;
465
- --input-border: #d3d6da;
466
- --portlet-input-color: #4d5d69;
467
- --input-caret-color: #000000;
468
- --input-bg-common: #ffffff;
469
- --hide-row-icon: #4d5d69;
470
- --hide-row-icon-hover: #213444;
471
- --create-row-icon: #008fd6;
472
- --create-row-icon-hover: #0081c1;
473
- }
474
- :root.dark-theme {
475
- --separator-color: #e9ebed1f;
476
- --input-border: #e9ebed3d;
477
- --portlet-input-color: #d3d6da;
478
- --input-caret-color: #ffffff;
479
- --input-bg-common: transparent;
480
- --hide-row-icon: #e9eaec;
481
- --hide-row-icon-hover: #ffffff;
482
- --create-row-icon: #2ba2de;
483
- --create-row-icon-hover: #008fd6;
484
- }
485
- </style>
486
-
487
- <style scoped lang="scss">
488
- .icon-container {
489
- width: 16px;
490
- height: 16px;
491
- display: block;
492
- cursor: pointer;
493
- color: var(--table-actions-icon);
494
-
495
- &:hover,
496
- &.selected {
497
- color: var(--table-actions-icon-hover);
498
- }
499
- }
500
-
501
- .action-remove {
502
- display: flex;
503
- align-items: center;
504
- column-gap: 8px;
505
-
506
- height: 32px;
507
- border-radius: 4px;
508
- padding: 8px;
509
- color: var(--table-actions-remove);
510
- cursor: pointer;
511
-
512
- font-size: 13px;
513
- font-weight: 500;
514
- line-height: 15.73px;
515
-
516
- &:hover {
517
- background: var(--table-actions-bg-hover);
518
- }
519
- }
520
-
521
- .action {
522
- display: flex;
523
- align-items: center;
524
- column-gap: 8px;
525
-
526
- height: 32px;
527
- border-radius: 4px;
528
- padding: 8px;
529
- color: var(--table-actions-view);
530
- margin-bottom: 8px;
531
- cursor: pointer;
532
-
533
- font-size: 13px;
534
- font-weight: 500;
535
- line-height: 15.73px;
536
-
537
- &.disabled {
538
- user-select: none;
539
- pointer-events: none;
540
- opacity: 0.3;
541
- cursor: not-allowed;
542
- }
543
-
544
- &:hover {
545
- background: var(--table-actions-bg-hover);
546
- }
547
- }
548
-
549
- .footer {
550
- padding: 0 16px 8px;
551
-
552
- :deep(button.ui-btn) {
553
- line-height: 16px;
554
- margin-bottom: 11px;
555
- margin-left: 6px;
556
- width: fit-content;
557
- }
558
- }
559
-
560
- .table-input {
561
- height: 28px;
562
- background-color: var(--input-bg-common);
563
- border: 1px solid var(--input-border);
564
- font-size: 12px;
565
- font-weight: 500;
566
- line-height: 14.52px;
567
- border-radius: 6px;
568
- width: 100%;
569
- padding: 6px 8px;
570
- caret-color: var(--input-caret-color);
571
- color: var(--portlet-input-color);
572
-
573
- &::placeholder {
574
- color: #9da6ad;
575
- }
576
-
577
- &:focus,
578
- &:focus-visible {
579
- border: 1px solid #008fd6;
580
- outline: none;
581
- }
582
-
583
- &.table-input-error {
584
- border-color: #ea3223;
585
- }
586
- }
587
-
588
- .category-select {
589
- width: 100%;
590
-
591
- :deep(.ui-select-toggle-button) {
592
- height: 28px;
593
- background-color: var(--input-bg-common);
594
-
595
- &:disabled {
596
- background: var(--select-bg-disabled);
597
- color: var(--select-color-disabled);
598
- cursor: default;
599
-
600
- .ui-arrow-icon {
601
- color: var(--select-color-disabled);
602
- }
603
-
604
- :deep(.content-icon) {
605
- opacity: 40%;
606
- }
607
- }
608
- }
609
-
610
- :deep(.ui-placeholder) {
611
- font-size: 12px;
612
- }
613
-
614
- :deep(.ui-dropdown) {
615
- max-height: 250px;
616
- overflow-y: auto;
617
-
618
- .ui-dropdown-menu-item {
619
- height: 28px;
620
- margin-bottom: 4px;
621
- .ui-item-text {
622
- font-size: 12px;
623
- }
624
- }
625
- }
626
- }
627
-
628
- .hide-row {
629
- cursor: pointer;
630
- line-height: 16px;
631
- color: var(--hide-row-icon);
632
-
633
- &:hover {
634
- color: var(--hide-row-icon-hover);
635
- }
636
- }
637
-
638
- .create-row {
639
- cursor: pointer;
640
- line-height: 16px;
641
- color: var(--create-row-icon);
642
-
643
- &:hover {
644
- color: var(--create-row-icon-hover);
645
- }
646
- }
647
-
648
- .add-new-attribute-button-container {
649
- margin-top: 12px;
650
- }
651
-
652
- .actions-container {
653
- display: flex;
654
- justify-content: flex-end;
655
- width: 100%;
656
- }
657
-
658
- .actions-dropdown-container {
659
- padding: 8px;
660
- }
661
-
662
- .edit-actions-container {
663
- display: flex;
664
- align-items: center;
665
- column-gap: 12px;
666
- }
667
- </style>
1
+ <template>
2
+ <div>
3
+ <ui-portlet
4
+ class="attributes"
5
+ test-id="attributes-portlet"
6
+ :title="portletTitle"
7
+ :dragged="props.dragged"
8
+ :dragged-any="props.draggedAny"
9
+ :is-open="props.isOpen"
10
+ :portlet-id="props.portletId"
11
+ :is-loading="props.isLoading"
12
+ @toggle="onTogglePortlet"
13
+ >
14
+ <template #portletBody="{ isLoadingBody }">
15
+ <ui-data-table
16
+ test-id="attributes-portlet-table"
17
+ :data="data"
18
+ :options="attributeTableHeaderOptions"
19
+ server-off
20
+ :default-layout="false"
21
+ size="sm"
22
+ :loading="isLoadingBody"
23
+ :skeleton="skeletonData"
24
+ >
25
+ <template #notFound>
26
+ <div
27
+ v-if="!allRowsCount"
28
+ class="add-new-attribute-button-container"
29
+ >
30
+ <ui-button
31
+ v-development="true"
32
+ test-id="add-new-attribute-button"
33
+ variant="text"
34
+ is-without-height
35
+ is-without-sizes
36
+ :disabled="hasEditRow"
37
+ @click="onAddNew"
38
+ >
39
+ {{ localization.zabbix.addNew }}...
40
+ </ui-button>
41
+ </div>
42
+ </template>
43
+ <!-- :loading="loading"-->
44
+ <template #icon="{ item }">
45
+ <div v-if="item.data.type === 'options'" class="actions-container">
46
+ <span
47
+ v-development="true"
48
+ :id="`actions-attributes-${item.data.row}`"
49
+ :class="[
50
+ 'icon-container',
51
+ {
52
+ selected: isShow[`action-attributes-${item.data.row}`],
53
+ },
54
+ ]"
55
+ @click="onShowActions(item.data.row)"
56
+ >
57
+ <ui-icon :name="item.data.icon" width="16" height="16" />
58
+ </span>
59
+ <ui-popup-window
60
+ v-model="isShow[`action-attributes-${item.data.row}`]"
61
+ :elem-id="`actions-attributes-${item.data.row}`"
62
+ width="fit-content"
63
+ left
64
+ bottom
65
+ >
66
+ <div class="actions-dropdown-container">
67
+ <div
68
+ :class="['action', { disabled: hasEditRow }]"
69
+ data-id="edit-attribute-action"
70
+ @click="onEditAttribute(item.data.row)"
71
+ >
72
+ <!-- @click="onShowDetails(item.data.row)"-->
73
+ <ui-icon name="edit" width="16" height="16" />
74
+ <span>{{ localization.common.edit }}</span>
75
+ </div>
76
+ <div
77
+ class="action-remove"
78
+ data-id="delete-attribute-action"
79
+ @click="onShowRemoveDialog(item.data.row)"
80
+ >
81
+ <ui-icon name="delete" width="16" height="16" />
82
+ <span>{{ localization.common.delete }}</span>
83
+ </div>
84
+ </div>
85
+ </ui-popup-window>
86
+ </div>
87
+ <template v-if="item.data.type === 'attribute'">
88
+ <input
89
+ v-model="editData.attribute"
90
+ data-id="attribute-name-input"
91
+ :class="[
92
+ 'table-input',
93
+ {
94
+ 'table-input-error':
95
+ validationData.attribute && isShowValidation,
96
+ },
97
+ ]"
98
+ :placeholder="localization.common[item.data.type]"
99
+ type="text"
100
+ @click.prevent.stop
101
+ />
102
+ </template>
103
+
104
+ <template v-else-if="item.data.type === 'value'">
105
+ <input
106
+ v-model="editData.value"
107
+ :class="[
108
+ 'table-input',
109
+ {
110
+ 'table-input-error':
111
+ validationData.value && isShowValidation,
112
+ },
113
+ ]"
114
+ :placeholder="localization.common[item.data.type]"
115
+ type="text"
116
+ data-id="attribute-value-input"
117
+ @click.prevent.stop
118
+ />
119
+ </template>
120
+ <template v-else-if="item.data.type === 'type'">
121
+ <div class="category-select">
122
+ <ui-select
123
+ v-model="editData.type"
124
+ :items="selectItems"
125
+ :placeholder="localization.common.chooseCategory"
126
+ width="165px"
127
+ select-width="100%"
128
+ :show-text="true"
129
+ :error="validationData.type && isShowValidation"
130
+ :disabled="isEditRow"
131
+ size="sm"
132
+ test-id="attribute-type-select"
133
+ />
134
+ </div>
135
+ </template>
136
+ <template v-else-if="item.data.type === 'actions'">
137
+ <div class="edit-actions-container">
138
+ <span
139
+ class="hide-row"
140
+ data-id="hide-create-attribute-row"
141
+ @click.prevent.stop="onHideEditRow"
142
+ >
143
+ <ui-icon name="close" width="16" height="16" />
144
+ </span>
145
+ <span
146
+ class="create-row"
147
+ data-id="create-attribute-accept"
148
+ @click.prevent.stop="onAddAttribute"
149
+ >
150
+ <ui-icon name="status-check" width="16" height="16" />
151
+ </span>
152
+ </div>
153
+ </template>
154
+ </template>
155
+ </ui-data-table>
156
+ </template>
157
+ <template #portletFooter="{ isLoadingFooter }">
158
+ <div class="footer">
159
+ <ui-button
160
+ v-if="!isLoadingFooter"
161
+ v-development="true"
162
+ test-id="add-new-attribute-button"
163
+ variant="text"
164
+ is-without-height
165
+ is-without-sizes
166
+ :disabled="hasEditRow"
167
+ @click="onAddNew"
168
+ >
169
+ {{ localization.zabbix.addNew }}...
170
+ </ui-button>
171
+ <ui-portlet-skeleton-footer v-else />
172
+ </div>
173
+ </template>
174
+ </ui-portlet>
175
+
176
+ <ui-popup
177
+ v-if="isShowRemoveDialog"
178
+ test-id="remove-attribute-dialog"
179
+ icon-name="info-status"
180
+ :texts="removeAttributeDialogTexts"
181
+ :message="removeAttributeMessage"
182
+ :title="localization.zabbix.deleteConfirmation"
183
+ @hide="onHideRemoveDialog"
184
+ @submit="onRemoveAttribute"
185
+ />
186
+ </div>
187
+ </template>
188
+
189
+ <script setup lang="ts">
190
+ import type {
191
+ UI_I_DataTable,
192
+ UI_I_DataTableHeader,
193
+ UI_I_DataTableBody,
194
+ } from '~/node_modules/bfg-uikit/components/ui/dataTable/models/interfaces'
195
+ import type { UI_I_Dropdown } from '~/node_modules/bfg-uikit/components/ui/dropdown/models/interfaces'
196
+ import type { UI_I_ModalTexts } from '~/node_modules/bfg-uikit/components/ui/modal/models/interfaces'
197
+ import type {
198
+ UI_I_Localization,
199
+ UI_I_ArbitraryObject,
200
+ } from '~/lib/models/interfaces'
201
+ import type { UI_I_NewAttributeData } from '~/components/common/portlets/customAttributes/lib/models/interfaces'
202
+ import {
203
+ attributeTableHeaderOptions,
204
+ attributeTableHeaderDataFunc,
205
+ createRow,
206
+ makeNewAttributeCreateActionRowFunc,
207
+ availableTypesFunc,
208
+ skeletonData,
209
+ } from '~/components/common/portlets/customAttributes/lib/config/config'
210
+
211
+ const props = defineProps<{
212
+ portletId: string
213
+ dragged?: boolean
214
+ isOpen?: boolean
215
+ draggedAny?: boolean
216
+ selectedItemName: string
217
+ type: UI_I_Dropdown
218
+ bodyItems: UI_I_DataTableBody[]
219
+ isLoading: boolean
220
+ }>()
221
+
222
+ const localization = computed<UI_I_Localization>(() => useLocal())
223
+
224
+ const portletTitle = computed<string>(() => {
225
+ const count = allRowsCount.value
226
+ ? ` (${isEditRow.value ? allRowsCount.value + 1 : allRowsCount.value})`
227
+ : ''
228
+
229
+ return localization.value.common.customAttributes + count
230
+ })
231
+
232
+ const isShow = ref<UI_I_ArbitraryObject<boolean>>({})
233
+
234
+ const onShowActions = (id: number): void => {
235
+ isShow.value[`action-attributes-${id}`] =
236
+ !isShow.value[`action-attributes-${id}`]
237
+ }
238
+
239
+ const attributesHeadItems = computed<UI_I_DataTableHeader[]>(() =>
240
+ attributeTableHeaderDataFunc(localization.value)
241
+ )
242
+
243
+ const attributesBodyItems = ref<UI_I_DataTableBody[]>([])
244
+
245
+ const allRowsCount = computed<number>(
246
+ () =>
247
+ attributesBodyItems.value.filter(
248
+ (row: UI_I_DataTableBody) => !row.actionRow
249
+ ).length
250
+ )
251
+
252
+ const hasEditRow = computed<boolean>(
253
+ () => !!attributesBodyItems.value.find((row) => row.actionRow)
254
+ )
255
+
256
+ const selectedType = computed<UI_I_Dropdown>(() => ({
257
+ text: props.type.text,
258
+ value: props.type.value,
259
+ selected: true,
260
+ }))
261
+
262
+ const editData = ref<UI_I_NewAttributeData>({
263
+ attribute: '',
264
+ value: '',
265
+ type: selectedType.value.text,
266
+ })
267
+
268
+ const resetFields = (): void => {
269
+ editData.value = {
270
+ attribute: '',
271
+ value: '',
272
+ type: selectedType.value.text,
273
+ }
274
+ }
275
+
276
+ const isShowValidation = ref<boolean>(false)
277
+ const validationData = computed<{
278
+ attribute: boolean
279
+ value: boolean
280
+ type: boolean
281
+ }>(() => ({
282
+ attribute: !editData.value.attribute.trim(),
283
+ value: !editData.value.value.trim(),
284
+ type: !editData.value.type.trim(),
285
+ }))
286
+
287
+ watch(
288
+ validationData,
289
+ (newValue: { attribute: boolean; value: boolean; type: boolean }) => {
290
+ !newValue.attribute &&
291
+ !newValue.value &&
292
+ !newValue.type &&
293
+ (isShowValidation.value = false)
294
+ },
295
+ { deep: true }
296
+ )
297
+
298
+ const onAddAttribute = (): void => {
299
+ if (
300
+ validationData.value.attribute ||
301
+ validationData.value.value ||
302
+ validationData.value.type
303
+ ) {
304
+ isShowValidation.value = true
305
+ return
306
+ }
307
+
308
+ if (isEditRow.value && editRowData.value) {
309
+ const editedRowData = createRow(editRowData.value.row, editData.value)
310
+
311
+ attributesBodyItems.value = attributesBodyItems.value.map((row) =>
312
+ row.row === editRowData.value?.row ? editedRowData : row
313
+ )
314
+
315
+ emits('edit-attribute', editedRowData)
316
+ isShow.value[`action-attributes-${editRowData.value?.row}`] = false
317
+ editRowData.value = undefined
318
+ isEditRow.value = false
319
+ } else {
320
+ const withoutEditRowData = attributesBodyItems.value.filter(
321
+ (row) => !row.actionRow
322
+ )
323
+
324
+ const rowsIds = withoutEditRowData.map((row) => row.row).sort()
325
+ let lastId = rowsIds[rowsIds.length - 1]
326
+ lastId = lastId === undefined ? -1 : lastId
327
+
328
+ const addedRowData = createRow(lastId + 1, editData.value)
329
+
330
+ attributesBodyItems.value.push(addedRowData)
331
+ emits('add-attribute', addedRowData)
332
+ attributesBodyItems.value = attributesBodyItems.value.filter(
333
+ (row) => !row.actionRow
334
+ )
335
+ }
336
+
337
+ resetFields()
338
+ }
339
+
340
+ const onHideEditRow = (): void => {
341
+ if (isEditRow.value && editRowData.value) {
342
+ attributesBodyItems.value = attributesBodyItems.value.map((row) =>
343
+ row.row === editRowData.value?.row ? editRowData.value : row
344
+ )
345
+ isShow.value[`action-attributes-${editRowData.value?.row}`] = false
346
+ editRowData.value = undefined
347
+ isEditRow.value = false
348
+ } else {
349
+ attributesBodyItems.value = attributesBodyItems.value.filter(
350
+ (row) => !row.actionRow
351
+ )
352
+ }
353
+ resetFields()
354
+ }
355
+
356
+ watch(
357
+ () => props.bodyItems,
358
+ (newValue: UI_I_DataTableBody[]) => {
359
+ attributesBodyItems.value = newValue
360
+ },
361
+ { deep: true, immediate: true }
362
+ )
363
+
364
+ const data = computed<UI_I_DataTable>(() => ({
365
+ id: 'attributes',
366
+ selectedRows: [],
367
+ isAllSelected: false,
368
+ title: '',
369
+ subTitle: '',
370
+ header: attributesHeadItems.value,
371
+ body: attributesBodyItems.value,
372
+ }))
373
+
374
+ const selectItems = ref<UI_I_Dropdown[]>(
375
+ useDeepCopy(availableTypesFunc(selectedType.value))
376
+ )
377
+
378
+ const onAddNew = (): void => {
379
+ const rowsIds = attributesBodyItems.value.map((row) => row.row).sort()
380
+ let lastId = rowsIds[rowsIds.length - 1]
381
+ lastId = lastId === undefined ? -1 : lastId
382
+
383
+ attributesBodyItems.value.push(
384
+ makeNewAttributeCreateActionRowFunc(lastId + 1)
385
+ )
386
+ }
387
+
388
+ const removeAttributeDialogTexts = computed<UI_I_ModalTexts>(() => ({
389
+ button1: localization.value.common.cancel,
390
+ button2: localization.value.common.delete,
391
+ }))
392
+
393
+ const isShowRemoveDialog = ref<boolean>(false)
394
+
395
+ const onHideRemoveDialog = (): void => {
396
+ isShowRemoveDialog.value = false
397
+ }
398
+
399
+ const attributeIdForRemove = ref<number>(0)
400
+ const attributeNameForRemove = computed<string>(
401
+ () =>
402
+ (attributesBodyItems.value.find(
403
+ (row: UI_I_DataTableBody) => row.row === attributeIdForRemove.value
404
+ )?.data[0]?.text || '') as string
405
+ )
406
+ const removeAttributeMessage = computed<string>(() =>
407
+ localization.value.common.removeAttributeDialog
408
+ .replace?.('{attributeName}', attributeNameForRemove.value)
409
+ .replace('{selectedItemName}', props.selectedItemName)
410
+ )
411
+ const onShowRemoveDialog = (id: number): void => {
412
+ attributeIdForRemove.value = id
413
+ isShowRemoveDialog.value = true
414
+ }
415
+ const onRemoveAttribute = (): void => {
416
+ onHideRemoveDialog()
417
+
418
+ const removeItem = attributesBodyItems.value.find(
419
+ (row) => row.row === attributeIdForRemove.value
420
+ )
421
+ if (!removeItem) return
422
+
423
+ emits('remove-attribute', removeItem)
424
+ attributesBodyItems.value = attributesBodyItems.value.filter(
425
+ (row) => row.row !== attributeIdForRemove.value
426
+ )
427
+ }
428
+
429
+ const isEditRow = ref<boolean>(false)
430
+ const editRowData = ref<UI_I_DataTableBody | undefined>(undefined)
431
+ const onEditAttribute = (id: number): void => {
432
+ editRowData.value = useDeepCopy(
433
+ attributesBodyItems.value.find((row) => row.row === id)
434
+ )
435
+
436
+ if (!editRowData.value) return
437
+ isEditRow.value = true
438
+
439
+ editData.value = {
440
+ attribute: editRowData.value.data[0].text,
441
+ value: editRowData.value.data[1].text,
442
+ type: editRowData.value.data[2].text,
443
+ }
444
+
445
+ attributesBodyItems.value = attributesBodyItems.value.map((row) =>
446
+ row.row === id ? makeNewAttributeCreateActionRowFunc(id) : row
447
+ )
448
+ }
449
+
450
+ const emits = defineEmits<{
451
+ (event: 'toggle-portlet', id: string): void
452
+ (event: 'remove-attribute', value: UI_I_DataTableBody): void
453
+ (event: 'add-attribute', value: UI_I_DataTableBody): void
454
+ (event: 'edit-attribute', value: UI_I_DataTableBody): void
455
+ }>()
456
+
457
+ const onTogglePortlet = (id: string): void => {
458
+ emits('toggle-portlet', id)
459
+ }
460
+ </script>
461
+
462
+ <style>
463
+ :root {
464
+ --separator-color: #e9ebed;
465
+ --input-border: #d3d6da;
466
+ --portlet-input-color: #4d5d69;
467
+ --input-caret-color: #000000;
468
+ --input-bg-common: #ffffff;
469
+ --hide-row-icon: #4d5d69;
470
+ --hide-row-icon-hover: #213444;
471
+ --create-row-icon: #008fd6;
472
+ --create-row-icon-hover: #0081c1;
473
+ }
474
+ :root.dark-theme {
475
+ --separator-color: #e9ebed1f;
476
+ --input-border: #e9ebed3d;
477
+ --portlet-input-color: #d3d6da;
478
+ --input-caret-color: #ffffff;
479
+ --input-bg-common: transparent;
480
+ --hide-row-icon: #e9eaec;
481
+ --hide-row-icon-hover: #ffffff;
482
+ --create-row-icon: #2ba2de;
483
+ --create-row-icon-hover: #008fd6;
484
+ }
485
+ </style>
486
+
487
+ <style scoped lang="scss">
488
+ .icon-container {
489
+ width: 16px;
490
+ height: 16px;
491
+ display: block;
492
+ cursor: pointer;
493
+ color: var(--table-actions-icon);
494
+
495
+ &:hover,
496
+ &.selected {
497
+ color: var(--table-actions-icon-hover);
498
+ }
499
+ }
500
+
501
+ .action-remove {
502
+ display: flex;
503
+ align-items: center;
504
+ column-gap: 8px;
505
+
506
+ height: 32px;
507
+ border-radius: 4px;
508
+ padding: 8px;
509
+ color: var(--table-actions-remove);
510
+ cursor: pointer;
511
+
512
+ font-size: 13px;
513
+ font-weight: 500;
514
+ line-height: 15.73px;
515
+
516
+ &:hover {
517
+ background: var(--table-actions-bg-hover);
518
+ }
519
+ }
520
+
521
+ .action {
522
+ display: flex;
523
+ align-items: center;
524
+ column-gap: 8px;
525
+
526
+ height: 32px;
527
+ border-radius: 4px;
528
+ padding: 8px;
529
+ color: var(--table-actions-view);
530
+ margin-bottom: 8px;
531
+ cursor: pointer;
532
+
533
+ font-size: 13px;
534
+ font-weight: 500;
535
+ line-height: 15.73px;
536
+
537
+ &.disabled {
538
+ user-select: none;
539
+ pointer-events: none;
540
+ opacity: 0.3;
541
+ cursor: not-allowed;
542
+ }
543
+
544
+ &:hover {
545
+ background: var(--table-actions-bg-hover);
546
+ }
547
+ }
548
+
549
+ .footer {
550
+ padding: 0 16px 8px;
551
+
552
+ :deep(button.ui-btn) {
553
+ line-height: 16px;
554
+ margin-bottom: 11px;
555
+ margin-left: 6px;
556
+ width: fit-content;
557
+ }
558
+ }
559
+
560
+ .table-input {
561
+ height: 28px;
562
+ background-color: var(--input-bg-common);
563
+ border: 1px solid var(--input-border);
564
+ font-size: 12px;
565
+ font-weight: 500;
566
+ line-height: 14.52px;
567
+ border-radius: 6px;
568
+ width: 100%;
569
+ padding: 6px 8px;
570
+ caret-color: var(--input-caret-color);
571
+ color: var(--portlet-input-color);
572
+
573
+ &::placeholder {
574
+ color: #9da6ad;
575
+ }
576
+
577
+ &:focus,
578
+ &:focus-visible {
579
+ border: 1px solid #008fd6;
580
+ outline: none;
581
+ }
582
+
583
+ &.table-input-error {
584
+ border-color: #ea3223;
585
+ }
586
+ }
587
+
588
+ .category-select {
589
+ width: 100%;
590
+
591
+ :deep(.ui-select-toggle-button) {
592
+ height: 28px;
593
+ background-color: var(--input-bg-common);
594
+
595
+ &:disabled {
596
+ background: var(--select-bg-disabled);
597
+ color: var(--select-color-disabled);
598
+ cursor: default;
599
+
600
+ .ui-arrow-icon {
601
+ color: var(--select-color-disabled);
602
+ }
603
+
604
+ :deep(.content-icon) {
605
+ opacity: 40%;
606
+ }
607
+ }
608
+ }
609
+
610
+ :deep(.ui-placeholder) {
611
+ font-size: 12px;
612
+ }
613
+
614
+ :deep(.ui-dropdown) {
615
+ max-height: 250px;
616
+ overflow-y: auto;
617
+
618
+ .ui-dropdown-menu-item {
619
+ height: 28px;
620
+ margin-bottom: 4px;
621
+ .ui-item-text {
622
+ font-size: 12px;
623
+ }
624
+ }
625
+ }
626
+ }
627
+
628
+ .hide-row {
629
+ cursor: pointer;
630
+ line-height: 16px;
631
+ color: var(--hide-row-icon);
632
+
633
+ &:hover {
634
+ color: var(--hide-row-icon-hover);
635
+ }
636
+ }
637
+
638
+ .create-row {
639
+ cursor: pointer;
640
+ line-height: 16px;
641
+ color: var(--create-row-icon);
642
+
643
+ &:hover {
644
+ color: var(--create-row-icon-hover);
645
+ }
646
+ }
647
+
648
+ .add-new-attribute-button-container {
649
+ margin-top: 12px;
650
+ }
651
+
652
+ .actions-container {
653
+ display: flex;
654
+ justify-content: flex-end;
655
+ width: 100%;
656
+ }
657
+
658
+ .actions-dropdown-container {
659
+ padding: 8px;
660
+ }
661
+
662
+ .edit-actions-container {
663
+ display: flex;
664
+ align-items: center;
665
+ column-gap: 12px;
666
+ }
667
+ </style>