bfg-common 1.5.548 → 1.5.550

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 (158) 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/components/atoms/TheIcon3.vue +50 -50
  7. package/components/atoms/collapse/CollapseNav.vue +170 -170
  8. package/components/atoms/perPage/PerPage.vue +58 -58
  9. package/components/atoms/table/dataGrid/DataGrid.vue +1718 -1718
  10. package/components/atoms/table/dataGrid/DataGridPagination.vue +97 -97
  11. package/components/atoms/table/dataGrid/lib/config/settingsTable.ts +94 -94
  12. package/components/atoms/table/dataGrid/lib/utils/export.ts +16 -16
  13. package/components/common/backup/storage/actions/add/Add.vue +251 -251
  14. package/components/common/backup/storage/actions/add/lib/utils.ts +51 -51
  15. package/components/common/browse/blocks/contents/filesNew/Skeleton.vue +18 -18
  16. package/components/common/diagramMain/modals/lib/config/portModal.ts +251 -251
  17. package/components/common/diagramMain/modals/lib/config/vCenterModal.ts +48 -48
  18. package/components/common/diagramMain/port/Port.vue +580 -580
  19. package/components/common/layout/theHeader/helpMenu/About.vue +79 -79
  20. package/components/common/layout/theHeader/helpMenu/aboutOld/AboutOld.vue +79 -79
  21. package/components/common/pages/backups/DetailView.vue +52 -52
  22. package/components/common/pages/backups/lib/models/interfaces.ts +36 -36
  23. package/components/common/pages/backups/modals/Modals.vue +243 -243
  24. package/components/common/pages/backups/modals/createBackup/New.vue +2 -8
  25. package/components/common/pages/backups/modals/createBackup/configuration/maxBandwidth/lib/config/options.ts +6 -6
  26. package/components/common/pages/backups/modals/createBackup/lib/config/readyToCompleteOptions.ts +69 -69
  27. package/components/common/pages/backups/modals/lib/config/restore.ts +115 -115
  28. package/components/common/pages/backups/modals/lib/models/interfaces.ts +186 -186
  29. package/components/common/pages/backups/modals/restore/Restore.vue +5 -9
  30. package/components/common/pages/backups/modals/restore/RestoreNew.vue +3 -12
  31. package/components/common/pages/backups/modals/restore/RestoreOld.vue +18 -6
  32. package/components/common/pages/backups/modals/restore/name/lib/models/interfaces.ts +6 -6
  33. package/components/common/pages/home/lib/models/interfaces.ts +48 -48
  34. package/components/common/pages/home/widgets/hosts/Hosts.vue +27 -27
  35. package/components/common/pages/home/widgets/hosts/lib/config/items.ts +23 -23
  36. package/components/common/pages/home/widgets/vms/VmsOld.vue +35 -35
  37. package/components/common/pages/home/widgets/vms/lib/config/items.ts +19 -19
  38. package/components/common/pages/scheduledTasks/lib/utils/utils.ts +84 -84
  39. package/components/common/readyToComplete/ReadyToComplete.vue +17 -17
  40. package/components/common/select/radio/RadioGroup.vue +137 -137
  41. package/components/common/spiceConsole/Drawer.vue +420 -420
  42. package/components/common/spiceConsole/SpiceConsole.vue +184 -184
  43. package/components/common/spiceConsole/lib/models/interfaces.ts +5 -5
  44. package/components/common/tools/Actions.vue +207 -207
  45. package/components/common/treeView/TreeView.vue +52 -52
  46. package/components/common/vm/actions/add/Add.vue +877 -950
  47. package/components/common/vm/actions/add/New.vue +652 -690
  48. package/components/common/vm/actions/add/Old.vue +363 -402
  49. package/components/common/vm/actions/add/lib/config/steps.ts +347 -347
  50. package/components/common/vm/actions/clone/Clone.vue +809 -809
  51. package/components/common/vm/actions/clone/new/New.vue +457 -457
  52. package/components/common/vm/actions/clone/old/Old.vue +378 -378
  53. package/components/common/vm/actions/common/customizeHardware/CustomizeHardware.vue +243 -308
  54. package/components/common/vm/actions/common/customizeHardware/CustomizeHardwareNew.vue +328 -373
  55. package/components/common/vm/actions/common/customizeHardware/CustomizeHardwareOld.vue +161 -205
  56. package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardware.vue +694 -728
  57. package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardwareNew.vue +512 -523
  58. package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardwareOld.vue +328 -339
  59. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/Cpu.vue +348 -368
  60. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/CpuNew.vue +241 -248
  61. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/CpuOld.vue +184 -189
  62. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/Shares.vue +140 -140
  63. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/lib/config/options.ts +28 -28
  64. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/Memory.vue +300 -313
  65. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/MemoryNew.vue +158 -158
  66. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/MemoryOld.vue +155 -155
  67. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +427 -427
  68. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/location/Location.vue +154 -154
  69. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddress.vue +119 -119
  70. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIo.vue +31 -31
  71. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newUsbController/NewUsbController.vue +47 -58
  72. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newUsbController/NewUsbControllerNew.vue +68 -65
  73. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newUsbController/NewUsbControllerOld.vue +64 -61
  74. package/components/common/vm/actions/common/customizeHardware/virtualHardware/other/Other.vue +16 -16
  75. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCard.vue +140 -162
  76. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCardNew.vue +6 -5
  77. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCardOld.vue +6 -5
  78. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/lib/config/options.ts +4 -4
  79. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/numberDisplays/NumberDisplays.vue +53 -53
  80. package/components/common/vm/actions/common/customizeHardware/vmoptions/Vmoptions.vue +76 -163
  81. package/components/common/vm/actions/common/customizeHardware/vmoptions/VmoptionsNew.vue +87 -138
  82. package/components/common/vm/actions/common/customizeHardware/vmoptions/VmoptionsOld.vue +71 -120
  83. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/BootOptions.vue +46 -110
  84. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/BootOptionsNew.vue +65 -85
  85. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/BootOptionsOld.vue +70 -91
  86. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/delay/Delay.vue +32 -32
  87. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/firmware/Firmware.vue +60 -60
  88. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/Order.vue +156 -174
  89. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/OrderNew.vue +109 -74
  90. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/OrderOld.vue +104 -66
  91. package/components/common/vm/actions/common/customizeHardware/vmoptions/generalOptions/GeneralOptions.vue +86 -101
  92. package/components/common/vm/actions/common/customizeHardware/vmoptions/generalOptions/GeneralOptionsNew.vue +163 -173
  93. package/components/common/vm/actions/common/customizeHardware/vmoptions/generalOptions/GeneralOptionsOld.vue +162 -170
  94. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/New.vue +142 -148
  95. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/Old.vue +135 -141
  96. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/RemoteConsoleOptions.vue +74 -178
  97. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/Keymap.vue +32 -32
  98. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/{KeymapNew.vue → New.vue} +45 -45
  99. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/{KeymapOld.vue → Old.vue} +47 -47
  100. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/Password.vue +102 -103
  101. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirection.vue +28 -28
  102. package/components/common/vm/actions/common/customizeHardware/vmoptions/tools/Tools.vue +26 -49
  103. package/components/common/vm/actions/common/lib/models/interfaces.ts +189 -157
  104. package/components/common/vm/actions/common/select/compatibility/Old.vue +107 -107
  105. package/components/common/vm/actions/common/select/createType/CreateType.vue +38 -38
  106. package/components/common/vm/actions/common/select/createType/lib/models/interfaces.ts +5 -5
  107. package/components/common/vm/actions/common/select/os/Old.vue +152 -152
  108. package/components/common/vm/actions/common/select/os/Os.vue +139 -139
  109. package/components/common/vm/actions/common/select/storage/Old.vue +125 -125
  110. package/components/common/vm/actions/common/select/storage/Storage.vue +178 -178
  111. package/components/common/vm/actions/common/select/storage/new/New.vue +311 -311
  112. package/components/common/vm/actions/common/select/storage/new/lib/models/interfaces.ts +5 -5
  113. package/components/common/vm/actions/common/select/storage/new/lib/utils/utils.ts +21 -21
  114. package/components/common/vm/actions/common/select/template/old/Old.vue +50 -50
  115. package/components/common/vm/actions/editSettings/new/Skeleton.vue +88 -88
  116. package/components/common/vm/actions/lib/models/interfaces.ts +15 -40
  117. package/components/common/vm/actions/lib/utils.ts +244 -239
  118. package/components/common/vm/actions/register/Register.vue +352 -352
  119. package/components/common/vm/actions/register/lib/config/steps.ts +86 -86
  120. package/components/common/wizards/common/compatibility/Compatibility.vue +35 -35
  121. package/components/common/wizards/common/compatibility/New.vue +99 -99
  122. package/components/common/wizards/common/compatibility/Old.vue +53 -53
  123. package/components/common/wizards/common/steps/computeResource/ComputeResource.vue +86 -86
  124. package/components/common/wizards/common/steps/computeResource/New.vue +93 -93
  125. package/components/common/wizards/common/steps/computeResource/Old.vue +103 -103
  126. package/components/common/wizards/common/steps/name/Name.vue +178 -178
  127. package/components/common/wizards/common/steps/name/New.vue +221 -221
  128. package/components/common/wizards/common/steps/name/Old.vue +121 -121
  129. package/components/common/wizards/common/steps/name/lib/models/interfaces.ts +4 -4
  130. package/components/common/wizards/common/steps/name/location/Location.vue +85 -85
  131. package/components/common/wizards/common/steps/name/location/New.vue +40 -40
  132. package/components/common/wizards/datastore/add/Add.vue +228 -228
  133. package/components/common/wizards/datastore/add/lib/utils.ts +85 -85
  134. package/components/common/wizards/datastore/add/steps/typeMode/lib/config/typeOptions.ts +43 -43
  135. package/components/common/wizards/vm/migrate/select/computeResource/ComputeResource.vue +205 -205
  136. package/components/common/wizards/vm/migrate/select/network/Network.vue +103 -103
  137. package/composables/useAppVersion.ts +21 -21
  138. package/composables/useLocal.ts +6 -6
  139. package/composables/useLocalCommon.ts +39 -39
  140. package/package.json +1 -3
  141. package/plugins/console.ts +21 -21
  142. package/plugins/date.ts +233 -233
  143. package/plugins/mouse.ts +21 -21
  144. package/plugins/panelStates.ts +70 -70
  145. package/plugins/text.ts +59 -59
  146. package/public/spice-console/application/clientgui.js +854 -854
  147. package/public/spice-console/application/packetfactory.js +211 -211
  148. package/public/spice-console/application/virtualmouse.js +147 -147
  149. package/public/spice-console/lib/images/bitmap.js +203 -203
  150. package/public/spice-console/network/spicechannel.js +440 -440
  151. package/public/spice-console/process/cursorprocess.js +121 -121
  152. package/public/spice-console/process/inputprocess.js +227 -227
  153. package/public/spice-console/process/mainprocess.js +210 -210
  154. package/public/spice-console/run.js +210 -210
  155. package/store/main/mutations.ts +7 -7
  156. package/store/main/state.ts +7 -7
  157. /package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/{PasswordNew.vue → New.vue} +0 -0
  158. /package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/{PasswordOld.vue → Old.vue} +0 -0
@@ -1,728 +1,694 @@
1
- <template>
2
- <common-vm-actions-common-customize-hardware-virtual-hardware-new
3
- v-if="isNewView"
4
- v-model:cpu-invalid="cpuInvalid"
5
- v-model:memory-invalid="memoryInvalid"
6
- v-model:video-card-invalid="videoCardInvalid"
7
- :nodes="props.nodes"
8
- :files="props.files"
9
- :is-edit="props.isEdit"
10
- :storage="props.storage"
11
- :project="props.project"
12
- :max-cpus="props.maxCpus"
13
- :max-memory="props.maxMemory"
14
- :cpu-models="props.cpuModels"
15
- :datastore="props.datastore"
16
- :is-datastore-loading="props.isDatastoreLoading"
17
- :networks-type="networksType"
18
- :networks-table="props.networksTable"
19
- :dropdown-items="dropdownItems"
20
- :hard-disks-type="hardDisksType"
21
- :networks-index="networksIndex"
22
- :hard-disks-index="hardDisksIndex"
23
- :pci-devices-type="pciDevicesType"
24
- :is-show-file-modal="isShowFileModal"
25
- :pci-devices-index="pciDevicesIndex"
26
- :cd-dvd-drives-type="cdDvdDrivesType"
27
- :cd-dvd-drives-index="cdDvdDrivesIndex"
28
- :error-validation-fields="errorValidationFields"
29
- :get-datastore-table-func="getDatastoreTableFunc"
30
- :cpu="cpu"
31
- :state="state"
32
- :memory="memory"
33
- :networks="networksLocal"
34
- :hard-disks="hardDisksLocal"
35
- :video-card="videoCard"
36
- :pci-devices="pciDevicesLocal"
37
- :cd-dvd-drives="cdDvdDrivesLocal"
38
- :usb-controller="usbController"
39
- :guest-machine-type="guestMachineType"
40
- :passthrough-devices="passthroughDevices"
41
- :mediated-devices="mediatedDevices"
42
- :vm-cpu-help-text-second="vmCpuHelpTextSecond"
43
- :compute-resource="props.computeResource"
44
- :compatibility-info="props.compatibilityInfo"
45
- @add-device="onAddDevice"
46
- @get-storage="emits('get-storage', $event)"
47
- @remove-network="onRemoveNetwork"
48
- @hide-file-modal="isShowFileModal = false"
49
- @remove-hard-disk="onRemoveHardDisk(...$event)"
50
- @remove-pci-device="onRemovePciDevice"
51
- @get-networks-table="emits('get-networks-table', $event)"
52
- @add-exist-hard-disk="onAddExistHardDisk"
53
- @roll-back-hard-disk="onRollBackHardDisk"
54
- @set-invalid-network="onSetInvalidNetwork(...$event)"
55
- @remove-cd-dvd-drive="onRemoveCdDvdDrive(...$event)"
56
- @show-datastore-child="emits('show-datastore-child', $event)"
57
- @get-folders-or-files="emits('get-folders-or-files', $event)"
58
- @send-data-cpu-method="onSendDataCpuMethod"
59
- @set-invalid-hard-disk="onSetInvalidHardDisk(...$event)"
60
- @remove-error-by-title="emits('remove-error-by-title', $event)"
61
- @roll-back-cd-dvd-drive="onRollBackCdDvdDrive"
62
- @set-invalid-pci-device="onSetInvalidPciDevice(...$event)"
63
- @get-active-device-child="emits('get-active-device-child', $event)"
64
- @send-data-memory-method="onSendDataMemoryMethod"
65
- @send-data-video-card-method="onSendDataVideoCardMethod"
66
- @send-data-new-network-method="sendDataNewNetworkMethod(...$event)"
67
- @send-data-pci-devices-method="onSendDataPciDevicesMethod(...$event)"
68
- @send-data-new-hard-disk-method="onSendDataNewHardDiskMethod(...$event)"
69
- @send-data-new-cd-dvd-drive-method="sendDataNewCdDvdDriveMethod(...$event)"
70
- @send-data-new-usb-controller-method="onSendDataNewUsbControllerMethod"
71
- />
72
- <common-vm-actions-common-customize-hardware-virtual-hardware-old
73
- v-else
74
- v-model:cpu-invalid="cpuInvalid"
75
- v-model:memory-invalid="memoryInvalid"
76
- v-model:video-card-invalid="videoCardInvalid"
77
- :nodes="props.nodes"
78
- :files="props.files"
79
- :is-edit="props.isEdit"
80
- :storage="props.storage"
81
- :project="props.project"
82
- :max-cpus="props.maxCpus"
83
- :max-memory="props.maxMemory"
84
- :cpu-models="props.cpuModels"
85
- :datastore="props.datastore"
86
- :is-datastore-loading="props.isDatastoreLoading"
87
- :networks-type="networksType"
88
- :networks-table="props.networksTable"
89
- :dropdown-items="dropdownItems"
90
- :hard-disks-type="hardDisksType"
91
- :networks-index="networksIndex"
92
- :hard-disks-index="hardDisksIndex"
93
- :pci-devices-type="pciDevicesType"
94
- :is-show-file-modal="isShowFileModal"
95
- :pci-devices-index="pciDevicesIndex"
96
- :cd-dvd-drives-type="cdDvdDrivesType"
97
- :cd-dvd-drives-index="cdDvdDrivesIndex"
98
- :error-validation-fields="errorValidationFields"
99
- :get-datastore-table-func="getDatastoreTableFunc"
100
- :cpu="cpu"
101
- :state="state"
102
- :memory="memory"
103
- :networks="networksLocal"
104
- :hard-disks="hardDisksLocal"
105
- :video-card="videoCard"
106
- :pci-devices="pciDevicesLocal"
107
- :cd-dvd-drives="cdDvdDrivesLocal"
108
- :usb-controller="usbController"
109
- :guest-machine-type="guestMachineType"
110
- :passthrough-devices="passthroughDevices"
111
- :mediated-devices="mediatedDevices"
112
- :vm-cpu-help-text-second="vmCpuHelpTextSecond"
113
- :compute-resource="props.computeResource"
114
- @add-device="onAddDevice"
115
- @get-storage="emits('get-storage', $event)"
116
- @remove-network="onRemoveNetwork"
117
- @hide-file-modal="isShowFileModal = false"
118
- @remove-hard-disk="onRemoveHardDisk(...$event)"
119
- @remove-pci-device="onRemovePciDevice"
120
- @get-networks-table="emits('get-networks-table', $event)"
121
- @add-exist-hard-disk="onAddExistHardDisk"
122
- @roll-back-hard-disk="onRollBackHardDisk"
123
- @set-invalid-network="onSetInvalidNetwork(...$event)"
124
- @remove-cd-dvd-drive="onRemoveCdDvdDrive(...$event)"
125
- @show-datastore-child="emits('show-datastore-child', $event)"
126
- @get-folders-or-files="emits('get-folders-or-files', $event)"
127
- @send-data-cpu-method="onSendDataCpuMethod"
128
- @set-invalid-hard-disk="onSetInvalidHardDisk(...$event)"
129
- @remove-error-by-title="emits('remove-error-by-title', $event)"
130
- @roll-back-cd-dvd-drive="onRollBackCdDvdDrive"
131
- @set-invalid-pci-device="onSetInvalidPciDevice(...$event)"
132
- @get-active-device-child="emits('get-active-device-child', $event)"
133
- @send-data-memory-method="onSendDataMemoryMethod"
134
- @send-data-video-card-method="onSendDataVideoCardMethod"
135
- @send-data-new-network-method="sendDataNewNetworkMethod(...$event)"
136
- @send-data-pci-devices-method="onSendDataPciDevicesMethod(...$event)"
137
- @send-data-new-hard-disk-method="onSendDataNewHardDiskMethod(...$event)"
138
- @send-data-new-cd-dvd-drive-method="sendDataNewCdDvdDriveMethod(...$event)"
139
- @send-data-new-usb-controller-method="onSendDataNewUsbControllerMethod"
140
- />
141
- </template>
142
-
143
- <script setup lang="ts">
144
- import type { UI_T_Project } from '~/lib/models/types'
145
- import type { UI_I_DatastoreTableItem } from '~/lib/models/store/storage/interfaces'
146
- import type { UI_I_NetworkTableItem } from '~/lib/models/store/network/interfaces'
147
- import type { UI_I_TablePayload } from '~/lib/models/table/interfaces'
148
- import type { UI_I_FolderOrFileTreePayload } from '~/lib/models/store/storage/interfaces'
149
- import type { UI_I_FileTreeNode } from '~/components/lib/models/interfaces'
150
- import type {
151
- UI_I_SendDataCpu,
152
- UI_I_SendDataMemory,
153
- UI_I_SendDataNewHardDisk,
154
- UI_I_SendDataNewNetwork,
155
- UI_I_SendDataVideoCard,
156
- UI_I_InvalidKeys,
157
- UI_I_SendDataVirtualHardware,
158
- UI_I_SendDataNewCdDvdDrive,
159
- // UI_I_HardDisk,
160
- UI_I_SendDataNewPciDevice,
161
- } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/models/interfaces'
162
- import type { UI_I_ErrorValidationField } from '~/lib/models/store/interfaces'
163
- import type {
164
- UI_T_HardDiskType,
165
- UI_T_NetworkType,
166
- UI_T_CdDvdType,
167
- } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/models/types'
168
- import type { UI_I_OptionItem } from '~/components/atoms/lib/models/interfaces'
169
- import type {
170
- UI_I_DropdownTreeItem,
171
- UI_I_DropdownTreeItemChild,
172
- } from '~/components/atoms/dropdown/tree/lib/models/interfaces'
173
- import type { UI_I_Localization } from '~/lib/models/interfaces'
174
- import type {
175
- API_UI_I_VmEditCpu,
176
- API_UI_I_VmEditMemory,
177
- UI_I_MediatedDevice,
178
- UI_I_PciDevice,
179
- } from '~/lib/models/store/vm/interfaces'
180
- import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
181
- import { dropdownItemsFunc } from './lib/config/dropdownItems'
182
-
183
- const props = withDefaults(
184
- defineProps<{
185
- storage: UI_I_DatastoreTableItem | null
186
- cpuModels: UI_I_OptionItem[]
187
- maxCpus: number
188
- maxMemory: number
189
- isEdit: boolean
190
- isClone: boolean
191
- errorValidationFields: UI_I_ErrorValidationField<string>[]
192
- nodes: UI_I_FileTreeNode[]
193
- files: UI_I_FileTreeNode[]
194
- networksTable: UI_I_NetworkTableItem[]
195
- getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
196
- datastore: UI_I_DatastoreTableItem[]
197
- isDatastoreLoading: boolean
198
- project: UI_T_Project
199
- state?: string | number
200
- cpu?: API_UI_I_VmEditCpu
201
- memory?: API_UI_I_VmEditMemory
202
- vmCpuHelpTextSecond?: string
203
- hardDisks?: UI_I_SendDataNewHardDisk[] | null
204
- cdDvdDrives?: UI_I_SendDataNewCdDvdDrive[] | null
205
- networks?: UI_I_SendDataNewNetwork[] | null
206
- videoCard?: UI_I_SendDataVideoCard
207
- usbController?: string
208
- pciDevices?: UI_I_SendDataNewPciDevice[]
209
- passthroughDevices?: UI_I_PciDevice[]
210
- mediatedDevices?: UI_I_MediatedDevice[]
211
- guestMachineType?: UI_I_OptionItem | null
212
- computeResource?: UI_I_TreeNode | null
213
- compatibilityInfo?: string
214
- }>(),
215
- {
216
- state: undefined,
217
- cpu: undefined,
218
- memory: undefined,
219
- vmCpuHelpTextSecond: undefined,
220
- hardDisks: undefined,
221
- cdDvdDrives: undefined,
222
- networks: undefined,
223
- videoCard: undefined,
224
- usbController: undefined,
225
- pciDevices: undefined,
226
- passthroughDevices: undefined,
227
- mediatedDevices: undefined,
228
- guestMachineType: undefined,
229
- computeResource: undefined,
230
- compatibilityInfo: undefined,
231
- }
232
- )
233
- const emits = defineEmits<{
234
- (event: 'send-data', value: UI_I_SendDataVirtualHardware): void
235
- (event: 'invalid', value: string[]): void
236
- (event: 'get-storage', value: UI_I_TablePayload): void
237
- (event: 'get-folders-or-files', value: UI_I_FolderOrFileTreePayload): void
238
- (event: 'get-active-device-child', value: UI_I_FileTreeNode): void
239
- (event: 'show-datastore-child', value: UI_I_FileTreeNode): void
240
- (event: 'remove-error-by-title', value: string): void
241
- (event: 'get-networks-table', value: UI_I_TablePayload): void
242
- (event: 'get-pci-devices'): void
243
- }>()
244
-
245
- const { $store, $binary }: any = useNuxtApp()
246
- const isNewView = computed<boolean>(() => $store.getters['main/getIsNewView'])
247
-
248
- const localization = computed<UI_I_Localization>(() => useLocal())
249
-
250
- const dropdownItems = computed<UI_I_DropdownTreeItem[]>(() =>
251
- dropdownItemsFunc(
252
- localization.value,
253
- props.state,
254
- props.passthroughDevices,
255
- props.mediatedDevices
256
- )
257
- )
258
-
259
- const hardDisksIndex = ref<number[]>([0])
260
- const hardDisksType = ref<UI_T_HardDiskType[]>(['new'])
261
- const hardDisksLocal = ref<UI_I_SendDataNewHardDisk[]>([
262
- {
263
- create: true,
264
- size: 90,
265
- source: '',
266
- boot_order: -1,
267
- },
268
- ])
269
- watch(
270
- () => props.hardDisks,
271
- (newValue) => {
272
- if ((!props.isEdit && !props.isClone) || !newValue) return
273
-
274
- const count = newValue?.length || 0
275
- hardDisksIndex.value = [...Array(count).keys()]
276
- hardDisksLocal.value = newValue
277
- if (props.isEdit) {
278
- hardDisksType.value = Array(count).fill('edit')
279
- } else if (props.isClone) {
280
- hardDisksType.value = Array(count).fill('clone')
281
- hardDisksLocal.value = newValue.map((hardDisk) => {
282
- hardDisk.create = true
283
- return hardDisk
284
- })
285
- }
286
- },
287
- { immediate: true }
288
- )
289
-
290
- const addHardDisk = (
291
- create = true,
292
- size = 90,
293
- source = '',
294
- type: UI_T_HardDiskType = 'new',
295
- provisioned_type?: number // При добавлении существующей
296
- ): void => {
297
- const newIndex = (hardDisksIndex.value.at(-1) ?? -1) + 1
298
- hardDisksIndex.value.push(newIndex)
299
- hardDisksType.value.push(type)
300
-
301
- let provisionType = 'thick'
302
- if (provisioned_type === 1) provisionType = 'thin'
303
-
304
- hardDisksLocal.value.push({
305
- create,
306
- size,
307
- source,
308
- attach: true,
309
- boot_order: 0, // Убираем галочку
310
- provision_type: provisionType,
311
- })
312
- sendData()
313
- }
314
- const onAddExistHardDisk = (file: UI_I_FileTreeNode): void => {
315
- addHardDisk(
316
- false,
317
- $binary.bToGb(file.size),
318
- file.path,
319
- 'exist',
320
- file.provisioned_type
321
- )
322
- }
323
- const onRemoveHardDisk = (
324
- index: number,
325
- hardDisk: UI_I_SendDataNewHardDisk
326
- ): void => {
327
- const removeIndex = hardDisksIndex.value.indexOf(index)
328
-
329
- if (!hardDisk.create && !hardDisk.attach) {
330
- hardDisksType.value = hardDisksType.value.map((item, key) => {
331
- if (key === removeIndex) return 'removed'
332
- return item
333
- })
334
- sendData()
335
- return
336
- }
337
-
338
- hardDisksIndex.value = hardDisksIndex.value.filter((item) => item !== index)
339
- hardDisksType.value = hardDisksType.value.filter(
340
- (_item, key) => key !== removeIndex
341
- )
342
-
343
- hardDisksLocal.value = hardDisksLocal.value.filter(
344
- (_hardDisk, key: number) => {
345
- return removeIndex !== key
346
- }
347
- )
348
-
349
- delete newHardDiskInvalidKeys.value[index]
350
- delete sendDataNewHardDisk.value[index]
351
- sendData()
352
- }
353
- const onRollBackHardDisk = (index: number): void => {
354
- const removeIndex = hardDisksIndex.value.indexOf(index)
355
- hardDisksType.value = hardDisksType.value.map((item, key) => {
356
- if (key === removeIndex) return 'edit'
357
- return item
358
- })
359
- }
360
-
361
- const defaultNetwork = {
362
- network: '',
363
- net_bridge: '',
364
- mac: '',
365
- target: '',
366
- model: '',
367
- boot_order: -1,
368
- }
369
- const networksLocal = ref<UI_I_SendDataNewNetwork[]>([
370
- useDeepCopy(defaultNetwork),
371
- ])
372
- const networksType = ref<UI_T_NetworkType[]>(['new'])
373
- const networksIndex = ref<number[]>([0])
374
- watch(
375
- () => props.networks,
376
- (newValue) => {
377
- if (!props.isEdit && !props.isClone) return
378
- if (!newValue) {
379
- networksLocal.value = []
380
- networksType.value = []
381
- networksIndex.value = []
382
- return
383
- }
384
-
385
- // networksLocal.value = newValue
386
- // networksType.value = Array(newValue.length).fill('edit')
387
- const count = newValue?.length || 0
388
- networksIndex.value = [...Array(count).keys()]
389
- networksLocal.value = newValue
390
- if (props.isEdit) {
391
- networksType.value = Array(count).fill('edit')
392
- } else if (props.isClone) {
393
- networksType.value = Array(count).fill('clone')
394
- }
395
- },
396
- { immediate: true }
397
- )
398
- const addNetwork = (): void => {
399
- const index = (networksIndex.value.at(-1) ?? -1) + 1
400
- networksIndex.value.push(index)
401
- networksType.value.push('new')
402
-
403
- networksLocal.value.push({
404
- ...useDeepCopy(defaultNetwork),
405
- boot_order: 0, // Убираем галочку
406
- })
407
- }
408
- const onRemoveNetwork = (index: number): void => {
409
- const removeIndex = networksIndex.value.indexOf(index)
410
- networksIndex.value = networksIndex.value.filter((item) => item !== index)
411
- networksType.value = networksType.value.filter(
412
- (_item, key) => key !== removeIndex
413
- )
414
- networksLocal.value = networksLocal.value.filter(
415
- (_network, key: number) => removeIndex !== key
416
- )
417
-
418
- delete newNetworkInvalidKeys.value[index]
419
- delete sendDataNewNetwork.value[index]
420
- sendData()
421
- }
422
-
423
- const defaultCdDvdDriver: UI_I_SendDataNewCdDvdDrive = {
424
- create: false,
425
- attach: false,
426
- source: '',
427
- bus: '',
428
- device_type: 'cdrom',
429
- boot_order: -1,
430
- }
431
- const cdDvdDrivesLocal = ref<UI_I_SendDataNewCdDvdDrive[]>([
432
- useDeepCopy(defaultCdDvdDriver),
433
- ])
434
- const cdDvdDrivesIndex = ref<number[]>([0])
435
- const cdDvdDrivesType = ref<UI_T_CdDvdType[]>(['new'])
436
- watch(
437
- () => props.cdDvdDrives,
438
- (newValue) => {
439
- if ((!props.isEdit && !props.isClone) || !newValue) return
440
-
441
- // cdDvdDrivesLocal.value = newValue
442
- // cdDvdDrivesType.value = Array(newValue.length).fill('edit')
443
- const count = newValue?.length || 0
444
- cdDvdDrivesIndex.value = [...Array(count).keys()]
445
- cdDvdDrivesLocal.value = newValue
446
- if (props.isEdit) {
447
- cdDvdDrivesType.value = Array(count).fill('edit')
448
- } else if (props.isClone) {
449
- cdDvdDrivesType.value = Array(count).fill('new')
450
- }
451
- },
452
- { immediate: true }
453
- )
454
- const addCdDvdDrive = (): void => {
455
- const value = (cdDvdDrivesIndex.value.at(-1) ?? -1) + 1
456
- cdDvdDrivesIndex.value.push(value)
457
- cdDvdDrivesType.value.push('new')
458
- cdDvdDrivesLocal.value.push({
459
- ...useDeepCopy(defaultCdDvdDriver),
460
- attach: true,
461
- boot_order: 0, // Убираем галочку
462
- })
463
- }
464
- const onRemoveCdDvdDrive = (
465
- index: number,
466
- cdDvdDrive: UI_I_SendDataNewCdDvdDrive
467
- ): void => {
468
- const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
469
-
470
- // if (!cdDvdDrive.create && !cdDvdDrive.attach) {
471
- if (cdDvdDrivesType.value[index] === 'edit' && !cdDvdDrive.attach) {
472
- cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
473
- if (key === removeIndex) return 'removed'
474
- return item
475
- })
476
- sendData()
477
- return
478
- }
479
-
480
- cdDvdDrivesIndex.value = cdDvdDrivesIndex.value.filter(
481
- (cdDvdDrive) => cdDvdDrive !== index
482
- )
483
- cdDvdDrivesType.value = cdDvdDrivesType.value.filter(
484
- (_item, key) => key !== index
485
- )
486
- cdDvdDrivesLocal.value = cdDvdDrivesLocal.value.filter(
487
- (_cdDvdDrive, key: number) => removeIndex !== key
488
- )
489
-
490
- delete sendDataNewCdDvdDrive.value[index]
491
- sendData()
492
- }
493
- const onRollBackCdDvdDrive = (index: number): void => {
494
- const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
495
- cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
496
- if (key === removeIndex) return 'edit'
497
- return item
498
- })
499
- }
500
-
501
- const defaultPciDevice: UI_I_SendDataNewPciDevice = {
502
- address: '',
503
- vendor_name: '',
504
- class_name: '',
505
- device_name: '',
506
- }
507
- const pciDevicesIndex = ref<number[]>([0])
508
- const pciDevicesType = ref<('new' | 'edit' | 'removed')[]>(['new'])
509
- const pciDevicesLocal = ref<UI_I_SendDataNewPciDevice[]>([])
510
- watch(
511
- () => props.pciDevices,
512
- (newValue) => {
513
- if ((!props.isEdit && !props.isClone) || !newValue) return
514
-
515
- const count = newValue?.length || 0
516
- pciDevicesIndex.value = [...Array(count).keys()]
517
- pciDevicesLocal.value = newValue || []
518
- if (props.isEdit) {
519
- pciDevicesType.value = Array(count).fill('edit')
520
- } else if (props.isClone) {
521
- pciDevicesType.value = Array(count).fill('new')
522
- }
523
- },
524
- { immediate: true }
525
- )
526
-
527
- const addPciDevice = (): void => {
528
- const newIndex = (pciDevicesIndex.value.at(-1) ?? -1) + 1
529
- pciDevicesIndex.value.push(newIndex)
530
- pciDevicesType.value.push('new')
531
-
532
- pciDevicesLocal.value.push(useDeepCopy(defaultPciDevice))
533
- }
534
- const onRemovePciDevice = (index: number): void => {
535
- const removeIndex = pciDevicesIndex.value.indexOf(index)
536
- pciDevicesIndex.value = pciDevicesIndex.value.filter((item) => item !== index)
537
- pciDevicesType.value = pciDevicesType.value.filter(
538
- (_item, key) => key !== removeIndex
539
- )
540
-
541
- pciDevicesLocal.value = pciDevicesLocal.value.filter(
542
- (_pciDevice, key: number) => {
543
- return removeIndex !== key
544
- }
545
- )
546
-
547
- delete newPciDeviceInvalidKeys.value[index]
548
- delete sendDataNewPciDevices.value[index]
549
- sendData()
550
- }
551
-
552
- const isShowFileModal = ref<boolean>(false)
553
- const onAddDevice = (item: UI_I_DropdownTreeItemChild): void => {
554
- switch (item.value) {
555
- case 1:
556
- addHardDisk()
557
- break
558
- case 2:
559
- isShowFileModal.value = true
560
- break
561
- case 5:
562
- addCdDvdDrive()
563
- break
564
- case 10:
565
- addPciDevice()
566
- break
567
- case 14:
568
- addNetwork()
569
- break
570
- }
571
- }
572
-
573
- const cpuInvalid = ref<boolean>(false)
574
- const sendDataCpu = ref<UI_I_SendDataCpu | null>(null)
575
- const onSendDataCpuMethod = (data: UI_I_SendDataCpu): void => {
576
- sendDataCpu.value = data
577
- sendData()
578
- }
579
- const sendDataMemory = ref<UI_I_SendDataMemory | null>(null)
580
- const onSendDataMemoryMethod = (data: UI_I_SendDataMemory): void => {
581
- sendDataMemory.value = data
582
- sendData()
583
- }
584
- const sendDataNewHardDisk = ref<UI_I_SendDataNewHardDisk[]>([])
585
- const onSendDataNewHardDiskMethod = (
586
- data: UI_I_SendDataNewHardDisk,
587
- index: number
588
- ): void => {
589
- sendDataNewHardDisk.value[index] = data
590
- sendData()
591
- }
592
- const sendDataNewNetwork = ref<UI_I_SendDataNewNetwork[]>([])
593
- const sendDataNewNetworkMethod = (
594
- data: UI_I_SendDataNewNetwork,
595
- index: number
596
- ): void => {
597
- sendDataNewNetwork.value[index] = data
598
- sendData()
599
- }
600
- const sendDataNewCdDvdDrive = ref<UI_I_SendDataNewCdDvdDrive[]>([])
601
- const sendDataNewCdDvdDriveMethod = (
602
- data: UI_I_SendDataNewCdDvdDrive,
603
- index: number
604
- ): void => {
605
- sendDataNewCdDvdDrive.value[index] = data
606
- sendData()
607
- }
608
- const sendDataNewUsbController = ref<string | null>(null)
609
- const onSendDataNewUsbControllerMethod = (data: string): void => {
610
- sendDataNewUsbController.value = data
611
- sendData()
612
- }
613
- const sendDataNewPciDevices = ref<UI_I_SendDataNewPciDevice[]>([])
614
- const onSendDataPciDevicesMethod = (
615
- data: UI_I_SendDataNewPciDevice,
616
- index: number
617
- ): void => {
618
- sendDataNewPciDevices.value[index] = data
619
- sendData()
620
- }
621
- const sendDataVideoCard = ref<UI_I_SendDataVideoCard | null>(null)
622
- const onSendDataVideoCardMethod = (data: UI_I_SendDataVideoCard): void => {
623
- sendDataVideoCard.value = data
624
- sendData()
625
- }
626
-
627
- const sendData = (): void => {
628
- const cpu = sendDataCpu.value
629
- const memory = sendDataMemory.value
630
- const hardDisks = sendDataNewHardDisk.value.flat(2)
631
- const networks = sendDataNewNetwork.value.flat(2)
632
- const cdDvdDrives = sendDataNewCdDvdDrive.value.flat(2)
633
- const pciDevices = sendDataNewPciDevices.value.flat()
634
- const usbController = sendDataNewUsbController.value
635
- const videoCard = sendDataVideoCard.value
636
-
637
- const sendData: UI_I_SendDataVirtualHardware = {
638
- cpu,
639
- memory,
640
- usbController,
641
- pciDevices,
642
- networks,
643
- hardDisks,
644
- cdDvdDrives,
645
- videoCard,
646
- }
647
- emits('send-data', sendData)
648
- }
649
-
650
- const onSetInvalidHardDisk = (invalid: boolean, index: number): void => {
651
- newHardDiskInvalidKeys.value[index] = invalid
652
- }
653
-
654
- const onSetInvalidNetwork = (invalid: boolean, key: number): void => {
655
- newNetworkInvalidKeys.value[key] = invalid
656
- }
657
-
658
- const onSetInvalidPciDevice = (invalid: boolean, key: number): void => {
659
- newPciDeviceInvalidKeys.value[key] = invalid
660
- }
661
-
662
- const memoryInvalid = ref<boolean>(false)
663
- const videoCardInvalid = ref<boolean>(false)
664
- const newHardDiskInvalidKeys = ref<UI_I_InvalidKeys>({})
665
- const newNetworkInvalidKeys = ref<UI_I_InvalidKeys>({})
666
- const newPciDeviceInvalidKeys = ref<UI_I_InvalidKeys>({})
667
-
668
- watch(
669
- [
670
- cpuInvalid,
671
- memoryInvalid,
672
- newHardDiskInvalidKeys,
673
- newNetworkInvalidKeys,
674
- newPciDeviceInvalidKeys,
675
- videoCardInvalid,
676
- ],
677
- () => {
678
- const cpu = cpuInvalid.value ? localization.value.common.cpu : ''
679
- const memory = memoryInvalid.value ? localization.value.common.memory : ''
680
- const videoCard = videoCardInvalid.value
681
- ? localization.value.common.videoCard
682
- : ''
683
- let newHardDisk = ''
684
- Object.keys(newHardDiskInvalidKeys.value).forEach((key) => {
685
- if (!newHardDiskInvalidKeys.value[+key]) {
686
- return
687
- }
688
-
689
- newHardDisk +=
690
- (newHardDisk ? ', ' : '') +
691
- localization.value.common.newHardDisk +
692
- ' ' +
693
- (+key + 1)
694
- })
695
- let newNetwork = ''
696
- Object.keys(newNetworkInvalidKeys.value).forEach((key) => {
697
- if (!newNetworkInvalidKeys.value[+key]) {
698
- return
699
- }
700
-
701
- newNetwork +=
702
- (newNetwork ? ', ' : '') +
703
- localization.value.common.newNetwork +
704
- ' ' +
705
- (+key + 1)
706
- })
707
- // let pciDevice = ''
708
- // Object.keys(newPciDeviceInvalidKeys.value).forEach((key) => {
709
- // if (!newPciDeviceInvalidKeys.value[+key]) {
710
- // return
711
- // }
712
- //
713
- // pciDevice +=
714
- // (pciDevice ? ', ' : '') +
715
- // localization.value.common.pciDevice +
716
- // ' ' +
717
- // (+key + 1)
718
- // })
719
-
720
- emits('invalid', [cpu, memory, newHardDisk, newNetwork, videoCard])
721
- },
722
- { deep: true }
723
- )
724
-
725
- emits('get-pci-devices')
726
- </script>
727
-
728
- <style scoped lang="scss"></style>
1
+ <template>
2
+ <common-vm-actions-common-customize-hardware-virtual-hardware-new
3
+ v-if="isNewView"
4
+ v-model="model"
5
+ v-model:cpu-invalid="cpuInvalid"
6
+ v-model:memory-invalid="memoryInvalid"
7
+ v-model:video-card-invalid="videoCardInvalid"
8
+ :nodes="props.nodes"
9
+ :files="props.files"
10
+ :is-edit="props.isEdit"
11
+ :storage="props.storage"
12
+ :project="props.project"
13
+ :max-memory="props.maxMemory"
14
+ :cpu-models="props.cpuModels"
15
+ :datastore="props.datastore"
16
+ :is-datastore-loading="props.isDatastoreLoading"
17
+ :networks-type="networksType"
18
+ :networks-table="props.networksTable"
19
+ :dropdown-items="dropdownItems"
20
+ :hard-disks-type="hardDisksType"
21
+ :networks-index="networksIndex"
22
+ :hard-disks-index="hardDisksIndex"
23
+ :pci-devices-type="pciDevicesType"
24
+ :is-show-file-modal="isShowFileModal"
25
+ :pci-devices-index="pciDevicesIndex"
26
+ :cd-dvd-drives-type="cdDvdDrivesType"
27
+ :cd-dvd-drives-index="cdDvdDrivesIndex"
28
+ :error-validation-fields="errorValidationFields"
29
+ :get-datastore-table-func="getDatastoreTableFunc"
30
+ :state="state"
31
+ :networks="networksLocal"
32
+ :hard-disks="hardDisksLocal"
33
+ :video-card="videoCard"
34
+ :pci-devices="pciDevicesLocal"
35
+ :cd-dvd-drives="cdDvdDrivesLocal"
36
+ :guest-machine-type="guestMachineType"
37
+ :passthrough-devices="passthroughDevices"
38
+ :mediated-devices="mediatedDevices"
39
+ :vm-cpu-help-text-second="vmCpuHelpTextSecond"
40
+ :compute-resource="props.computeResource"
41
+ :compatibility-info="props.compatibilityInfo"
42
+ @add-device="onAddDevice"
43
+ @get-storage="emits('get-storage', $event)"
44
+ @remove-network="onRemoveNetwork"
45
+ @hide-file-modal="isShowFileModal = false"
46
+ @remove-hard-disk="onRemoveHardDisk(...$event)"
47
+ @remove-pci-device="onRemovePciDevice"
48
+ @get-networks-table="emits('get-networks-table', $event)"
49
+ @add-exist-hard-disk="onAddExistHardDisk"
50
+ @roll-back-hard-disk="onRollBackHardDisk"
51
+ @set-invalid-network="onSetInvalidNetwork(...$event)"
52
+ @remove-cd-dvd-drive="onRemoveCdDvdDrive(...$event)"
53
+ @show-datastore-child="emits('show-datastore-child', $event)"
54
+ @get-folders-or-files="emits('get-folders-or-files', $event)"
55
+ @set-invalid-hard-disk="onSetInvalidHardDisk(...$event)"
56
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
57
+ @roll-back-cd-dvd-drive="onRollBackCdDvdDrive"
58
+ @set-invalid-pci-device="onSetInvalidPciDevice(...$event)"
59
+ @get-active-device-child="emits('get-active-device-child', $event)"
60
+ @send-data-new-network-method="sendDataNewNetworkMethod(...$event)"
61
+ @send-data-pci-devices-method="onSendDataPciDevicesMethod(...$event)"
62
+ @send-data-new-hard-disk-method="onSendDataNewHardDiskMethod(...$event)"
63
+ @send-data-new-cd-dvd-drive-method="sendDataNewCdDvdDriveMethod(...$event)"
64
+ />
65
+ <common-vm-actions-common-customize-hardware-virtual-hardware-old
66
+ v-else
67
+ v-model="model"
68
+ v-model:cpu-invalid="cpuInvalid"
69
+ v-model:memory-invalid="memoryInvalid"
70
+ v-model:video-card-invalid="videoCardInvalid"
71
+ :nodes="props.nodes"
72
+ :files="props.files"
73
+ :is-edit="props.isEdit"
74
+ :storage="props.storage"
75
+ :project="props.project"
76
+ :max-memory="props.maxMemory"
77
+ :cpu-models="props.cpuModels"
78
+ :datastore="props.datastore"
79
+ :is-datastore-loading="props.isDatastoreLoading"
80
+ :networks-type="networksType"
81
+ :networks-table="props.networksTable"
82
+ :dropdown-items="dropdownItems"
83
+ :hard-disks-type="hardDisksType"
84
+ :networks-index="networksIndex"
85
+ :hard-disks-index="hardDisksIndex"
86
+ :pci-devices-type="pciDevicesType"
87
+ :is-show-file-modal="isShowFileModal"
88
+ :pci-devices-index="pciDevicesIndex"
89
+ :cd-dvd-drives-type="cdDvdDrivesType"
90
+ :cd-dvd-drives-index="cdDvdDrivesIndex"
91
+ :error-validation-fields="errorValidationFields"
92
+ :get-datastore-table-func="getDatastoreTableFunc"
93
+ :state="state"
94
+ :networks="networksLocal"
95
+ :hard-disks="hardDisksLocal"
96
+ :video-card="videoCard"
97
+ :pci-devices="pciDevicesLocal"
98
+ :cd-dvd-drives="cdDvdDrivesLocal"
99
+ :guest-machine-type="guestMachineType"
100
+ :passthrough-devices="passthroughDevices"
101
+ :mediated-devices="mediatedDevices"
102
+ :vm-cpu-help-text-second="vmCpuHelpTextSecond"
103
+ :compute-resource="props.computeResource"
104
+ @add-device="onAddDevice"
105
+ @get-storage="emits('get-storage', $event)"
106
+ @remove-network="onRemoveNetwork"
107
+ @hide-file-modal="isShowFileModal = false"
108
+ @remove-hard-disk="onRemoveHardDisk(...$event)"
109
+ @remove-pci-device="onRemovePciDevice"
110
+ @get-networks-table="emits('get-networks-table', $event)"
111
+ @add-exist-hard-disk="onAddExistHardDisk"
112
+ @roll-back-hard-disk="onRollBackHardDisk"
113
+ @set-invalid-network="onSetInvalidNetwork(...$event)"
114
+ @remove-cd-dvd-drive="onRemoveCdDvdDrive(...$event)"
115
+ @show-datastore-child="emits('show-datastore-child', $event)"
116
+ @get-folders-or-files="emits('get-folders-or-files', $event)"
117
+ @set-invalid-hard-disk="onSetInvalidHardDisk(...$event)"
118
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
119
+ @roll-back-cd-dvd-drive="onRollBackCdDvdDrive"
120
+ @set-invalid-pci-device="onSetInvalidPciDevice(...$event)"
121
+ @get-active-device-child="emits('get-active-device-child', $event)"
122
+ @send-data-new-network-method="sendDataNewNetworkMethod(...$event)"
123
+ @send-data-pci-devices-method="onSendDataPciDevicesMethod(...$event)"
124
+ @send-data-new-hard-disk-method="onSendDataNewHardDiskMethod(...$event)"
125
+ @send-data-new-cd-dvd-drive-method="sendDataNewCdDvdDriveMethod(...$event)"
126
+ />
127
+ </template>
128
+
129
+ <script setup lang="ts">
130
+ import type { UI_T_Project } from '~/lib/models/types'
131
+ import type { UI_I_DatastoreTableItem } from '~/lib/models/store/storage/interfaces'
132
+ import type { UI_I_NetworkTableItem } from '~/lib/models/store/network/interfaces'
133
+ import type { UI_I_TablePayload } from '~/lib/models/table/interfaces'
134
+ import type { UI_I_FolderOrFileTreePayload } from '~/lib/models/store/storage/interfaces'
135
+ import type { UI_I_FileTreeNode } from '~/components/lib/models/interfaces'
136
+ import type {
137
+ UI_I_SendDataNewHardDisk,
138
+ UI_I_SendDataNewNetwork,
139
+ UI_I_SendDataVideoCard,
140
+ UI_I_InvalidKeys,
141
+ UI_I_SendDataNewCdDvdDrive,
142
+ // UI_I_HardDisk,
143
+ UI_I_SendDataNewPciDevice,
144
+ } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/models/interfaces'
145
+ import type { UI_I_ErrorValidationField } from '~/lib/models/store/interfaces'
146
+ import type {
147
+ UI_T_HardDiskType,
148
+ UI_T_NetworkType,
149
+ UI_T_CdDvdType,
150
+ } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/models/types'
151
+ import type { UI_I_OptionItem } from '~/components/atoms/lib/models/interfaces'
152
+ import type {
153
+ UI_I_DropdownTreeItem,
154
+ UI_I_DropdownTreeItemChild,
155
+ } from '~/components/atoms/dropdown/tree/lib/models/interfaces'
156
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
157
+ import type {
158
+ UI_I_MediatedDevice,
159
+ UI_I_PciDevice,
160
+ } from '~/lib/models/store/vm/interfaces'
161
+ import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
162
+ import type { UI_I_CreateVmData } from '~/components/common/vm/actions/common/lib/models/interfaces'
163
+ import { dropdownItemsFunc } from './lib/config/dropdownItems'
164
+
165
+ const model = defineModel<UI_I_CreateVmData>({ required: true })
166
+
167
+ const props = withDefaults(
168
+ defineProps<{
169
+ storage: UI_I_DatastoreTableItem | null
170
+ cpuModels: UI_I_OptionItem[]
171
+ maxMemory: number
172
+ isEdit: boolean
173
+ isClone: boolean
174
+ errorValidationFields: UI_I_ErrorValidationField[]
175
+ nodes: UI_I_FileTreeNode[]
176
+ files: UI_I_FileTreeNode[]
177
+ networksTable: UI_I_NetworkTableItem[]
178
+ getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
179
+ datastore: UI_I_DatastoreTableItem[]
180
+ isDatastoreLoading: boolean
181
+ project: UI_T_Project
182
+ state?: string | number
183
+ vmCpuHelpTextSecond?: string
184
+ hardDisks?: UI_I_SendDataNewHardDisk[] | null
185
+ cdDvdDrives?: UI_I_SendDataNewCdDvdDrive[] | null
186
+ networks?: UI_I_SendDataNewNetwork[] | null
187
+ videoCard?: UI_I_SendDataVideoCard
188
+ pciDevices?: UI_I_SendDataNewPciDevice[]
189
+ passthroughDevices?: UI_I_PciDevice[]
190
+ mediatedDevices?: UI_I_MediatedDevice[]
191
+ guestMachineType?: UI_I_OptionItem | null
192
+ computeResource?: UI_I_TreeNode | null
193
+ compatibilityInfo?: string
194
+ }>(),
195
+ {
196
+ state: undefined,
197
+ vmCpuHelpTextSecond: undefined,
198
+ hardDisks: undefined,
199
+ cdDvdDrives: undefined,
200
+ networks: undefined,
201
+ videoCard: undefined,
202
+ pciDevices: undefined,
203
+ passthroughDevices: undefined,
204
+ mediatedDevices: undefined,
205
+ guestMachineType: undefined,
206
+ computeResource: undefined,
207
+ compatibilityInfo: undefined,
208
+ }
209
+ )
210
+ const emits = defineEmits<{
211
+ (event: 'invalid', value: string[]): void
212
+ (event: 'get-storage', value: UI_I_TablePayload): void
213
+ (event: 'get-folders-or-files', value: UI_I_FolderOrFileTreePayload): void
214
+ (event: 'get-active-device-child', value: UI_I_FileTreeNode): void
215
+ (event: 'show-datastore-child', value: UI_I_FileTreeNode): void
216
+ (event: 'remove-error-by-title', value: string): void
217
+ (event: 'get-networks-table', value: UI_I_TablePayload): void
218
+ (event: 'get-pci-devices'): void
219
+ }>()
220
+
221
+ const { $store, $binary }: any = useNuxtApp()
222
+ const isNewView = computed<boolean>(() => $store.getters['main/getIsNewView'])
223
+
224
+ const localization = computed<UI_I_Localization>(() => useLocal())
225
+
226
+ const dropdownItems = computed<UI_I_DropdownTreeItem[]>(() =>
227
+ dropdownItemsFunc(
228
+ localization.value,
229
+ props.state,
230
+ props.passthroughDevices,
231
+ props.mediatedDevices
232
+ )
233
+ )
234
+
235
+ const hardDisksIndex = ref<number[]>([0])
236
+ const hardDisksType = ref<UI_T_HardDiskType[]>(['new'])
237
+ const hardDisksLocal = ref<UI_I_SendDataNewHardDisk[]>([
238
+ {
239
+ create: true,
240
+ size: 90,
241
+ source: '',
242
+ boot_order: -1,
243
+ },
244
+ ])
245
+ watch(
246
+ () => props.hardDisks,
247
+ (newValue) => {
248
+ if ((!props.isEdit && !props.isClone) || !newValue) return
249
+
250
+ const count = newValue?.length || 0
251
+ hardDisksIndex.value = [...Array(count).keys()]
252
+ hardDisksLocal.value = newValue
253
+ if (props.isEdit) {
254
+ hardDisksType.value = Array(count).fill('edit')
255
+ } else if (props.isClone) {
256
+ hardDisksType.value = Array(count).fill('clone')
257
+ hardDisksLocal.value = newValue.map((hardDisk) => {
258
+ hardDisk.create = true
259
+ return hardDisk
260
+ })
261
+ }
262
+ },
263
+ { immediate: true }
264
+ )
265
+
266
+ const addHardDisk = (
267
+ create = true,
268
+ size = 90,
269
+ source = '',
270
+ type: UI_T_HardDiskType = 'new',
271
+ provisioned_type?: number // При добавлении существующей
272
+ ): void => {
273
+ const newIndex = (hardDisksIndex.value.at(-1) ?? -1) + 1
274
+ hardDisksIndex.value.push(newIndex)
275
+ hardDisksType.value.push(type)
276
+
277
+ let provisionType = 'thick'
278
+ if (provisioned_type === 1) provisionType = 'thin'
279
+
280
+ model.value.disk_devices = [
281
+ ...model.value.disk_devices.filter((disk) => disk.device_type !== 'cdrom'),
282
+ {
283
+ create,
284
+ size,
285
+ source,
286
+ attach: true,
287
+ boot_order: 0, // Убираем галочку
288
+ provision_type: provisionType,
289
+ },
290
+ ...model.value.disk_devices.filter((disk) => disk.device_type === 'cdrom'),
291
+ ]
292
+ hardDisksLocal.value.push({
293
+ create,
294
+ size,
295
+ source,
296
+ attach: true,
297
+ boot_order: 0, // Убираем галочку
298
+ provision_type: provisionType,
299
+ })
300
+ }
301
+ const onAddExistHardDisk = (file: UI_I_FileTreeNode): void => {
302
+ addHardDisk(
303
+ false,
304
+ $binary.bToGb(file.size),
305
+ file.path,
306
+ 'exist',
307
+ file.provisioned_type
308
+ )
309
+ }
310
+ const onRemoveHardDisk = (
311
+ index: number,
312
+ hardDisk: UI_I_SendDataNewHardDisk
313
+ ): void => {
314
+ const removeIndex = hardDisksIndex.value.indexOf(index)
315
+
316
+ if (!hardDisk.create && !hardDisk.attach) {
317
+ hardDisksType.value = hardDisksType.value.map((item, key) => {
318
+ if (key === removeIndex) return 'removed'
319
+ return item
320
+ })
321
+ return
322
+ }
323
+
324
+ hardDisksIndex.value = hardDisksIndex.value.filter((item) => item !== index)
325
+ hardDisksType.value = hardDisksType.value.filter(
326
+ (_item, key) => key !== removeIndex
327
+ )
328
+
329
+ model.value.disk_devices = model.value.disk_devices.filter(
330
+ (_hardDisk, key: number) => {
331
+ return removeIndex !== key
332
+ }
333
+ )
334
+ hardDisksLocal.value = hardDisksLocal.value.filter(
335
+ (_hardDisk, key: number) => {
336
+ return removeIndex !== key
337
+ }
338
+ )
339
+
340
+ delete newHardDiskInvalidKeys.value[index]
341
+ }
342
+ const onRollBackHardDisk = (index: number): void => {
343
+ const removeIndex = hardDisksIndex.value.indexOf(index)
344
+ hardDisksType.value = hardDisksType.value.map((item, key) => {
345
+ if (key === removeIndex) return 'edit'
346
+ return item
347
+ })
348
+ }
349
+
350
+ const defaultNetwork = {
351
+ network: '',
352
+ net_bridge: '',
353
+ mac: '',
354
+ target: '',
355
+ model: '',
356
+ boot_order: -1,
357
+ }
358
+ const networksLocal = ref<UI_I_SendDataNewNetwork[]>([
359
+ useDeepCopy(defaultNetwork),
360
+ ])
361
+ const networksType = ref<UI_T_NetworkType[]>(['new'])
362
+ const networksIndex = ref<number[]>([0])
363
+ watch(
364
+ () => props.networks,
365
+ (newValue) => {
366
+ if (!props.isEdit && !props.isClone) return
367
+ if (!newValue) {
368
+ networksLocal.value = []
369
+ networksType.value = []
370
+ networksIndex.value = []
371
+ return
372
+ }
373
+
374
+ // networksLocal.value = newValue
375
+ // networksType.value = Array(newValue.length).fill('edit')
376
+ const count = newValue?.length || 0
377
+ networksIndex.value = [...Array(count).keys()]
378
+ networksLocal.value = newValue
379
+ if (props.isEdit) {
380
+ networksType.value = Array(count).fill('edit')
381
+ } else if (props.isClone) {
382
+ networksType.value = Array(count).fill('clone')
383
+ }
384
+ },
385
+ { immediate: true }
386
+ )
387
+ const addNetwork = (): void => {
388
+ const index = (networksIndex.value.at(-1) ?? -1) + 1
389
+ networksIndex.value.push(index)
390
+ networksType.value.push('new')
391
+
392
+ model.value.network_devices.push({
393
+ ...useDeepCopy(defaultNetwork),
394
+ boot_order: 0, // Убираем галочку
395
+ })
396
+ networksLocal.value.push({
397
+ ...useDeepCopy(defaultNetwork),
398
+ boot_order: 0, // Убираем галочку
399
+ })
400
+ }
401
+ const onRemoveNetwork = (index: number): void => {
402
+ const removeIndex = networksIndex.value.indexOf(index)
403
+ networksIndex.value = networksIndex.value.filter((item) => item !== index)
404
+ networksType.value = networksType.value.filter(
405
+ (_item, key) => key !== removeIndex
406
+ )
407
+ model.value.network_devices = model.value.network_devices.filter(
408
+ (_network, key: number) => removeIndex !== key
409
+ )
410
+ networksLocal.value = networksLocal.value.filter(
411
+ (_network, key: number) => removeIndex !== key
412
+ )
413
+
414
+ delete newNetworkInvalidKeys.value[index]
415
+ }
416
+
417
+ const defaultCdDvdDriver: UI_I_SendDataNewCdDvdDrive = {
418
+ create: false,
419
+ attach: false,
420
+ source: '',
421
+ bus: '',
422
+ device_type: 'cdrom',
423
+ boot_order: -1,
424
+ }
425
+ const cdDvdDrivesLocal = ref<UI_I_SendDataNewCdDvdDrive[]>([
426
+ useDeepCopy(defaultCdDvdDriver),
427
+ ])
428
+ const cdDvdDrivesIndex = ref<number[]>([0])
429
+ const cdDvdDrivesType = ref<UI_T_CdDvdType[]>(['new'])
430
+ watch(
431
+ () => props.cdDvdDrives,
432
+ (newValue) => {
433
+ if ((!props.isEdit && !props.isClone) || !newValue) return
434
+
435
+ // cdDvdDrivesLocal.value = newValue
436
+ // cdDvdDrivesType.value = Array(newValue.length).fill('edit')
437
+ const count = newValue?.length || 0
438
+ cdDvdDrivesIndex.value = [...Array(count).keys()]
439
+ cdDvdDrivesLocal.value = newValue
440
+ if (props.isEdit) {
441
+ cdDvdDrivesType.value = Array(count).fill('edit')
442
+ } else if (props.isClone) {
443
+ cdDvdDrivesType.value = Array(count).fill('new')
444
+ }
445
+ },
446
+ { immediate: true }
447
+ )
448
+ const addCdDvdDrive = (): void => {
449
+ const value = (cdDvdDrivesIndex.value.at(-1) ?? -1) + 1
450
+ cdDvdDrivesIndex.value.push(value)
451
+ cdDvdDrivesType.value.push('new')
452
+ model.value.disk_devices.push({
453
+ ...useDeepCopy(defaultCdDvdDriver),
454
+ attach: true,
455
+ boot_order: 0, // Убираем галочку
456
+ })
457
+ cdDvdDrivesLocal.value.push({
458
+ ...useDeepCopy(defaultCdDvdDriver),
459
+ attach: true,
460
+ boot_order: 0, // Убираем галочку
461
+ })
462
+ }
463
+ const onRemoveCdDvdDrive = (
464
+ index: number,
465
+ cdDvdDrive: UI_I_SendDataNewCdDvdDrive
466
+ ): void => {
467
+ const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
468
+
469
+ // if (!cdDvdDrive.create && !cdDvdDrive.attach) {
470
+ if (cdDvdDrivesType.value[index] === 'edit' && !cdDvdDrive.attach) {
471
+ cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
472
+ if (key === removeIndex) return 'removed'
473
+ return item
474
+ })
475
+ return
476
+ }
477
+
478
+ cdDvdDrivesIndex.value = cdDvdDrivesIndex.value.filter(
479
+ (cdDvdDrive) => cdDvdDrive !== index
480
+ )
481
+ cdDvdDrivesType.value = cdDvdDrivesType.value.filter(
482
+ (_item, key) => key !== index
483
+ )
484
+ model.value.disk_devices = model.value.disk_devices.filter(
485
+ (_cdDvdDrive, key: number) => removeIndex !== key
486
+ )
487
+ cdDvdDrivesLocal.value = cdDvdDrivesLocal.value.filter(
488
+ (_cdDvdDrive, key: number) => removeIndex !== key
489
+ )
490
+ }
491
+ const onRollBackCdDvdDrive = (index: number): void => {
492
+ const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
493
+ cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
494
+ if (key === removeIndex) return 'edit'
495
+ return item
496
+ })
497
+ }
498
+
499
+ const defaultPciDevice: UI_I_SendDataNewPciDevice = {
500
+ address: '',
501
+ vendor_name: '',
502
+ class_name: '',
503
+ device_name: '',
504
+ }
505
+ const pciDevicesIndex = ref<number[]>([0])
506
+ const pciDevicesType = ref<('new' | 'edit' | 'removed')[]>(['new'])
507
+ const pciDevicesLocal = ref<UI_I_SendDataNewPciDevice[]>([])
508
+ watch(
509
+ () => props.pciDevices,
510
+ (newValue) => {
511
+ if ((!props.isEdit && !props.isClone) || !newValue) return
512
+
513
+ const count = newValue?.length || 0
514
+ pciDevicesIndex.value = [...Array(count).keys()]
515
+ pciDevicesLocal.value = newValue || []
516
+ if (props.isEdit) {
517
+ pciDevicesType.value = Array(count).fill('edit')
518
+ } else if (props.isClone) {
519
+ pciDevicesType.value = Array(count).fill('new')
520
+ }
521
+ },
522
+ { immediate: true }
523
+ )
524
+
525
+ const addPciDevice = (): void => {
526
+ const newIndex = (pciDevicesIndex.value.at(-1) ?? -1) + 1
527
+ pciDevicesIndex.value.push(newIndex)
528
+ pciDevicesType.value.push('new')
529
+
530
+ pciDevicesLocal.value.push(useDeepCopy(defaultPciDevice))
531
+ model.value.passthrough_pci_devices.push(useDeepCopy(defaultPciDevice))
532
+ }
533
+ const onRemovePciDevice = (index: number): void => {
534
+ const removeIndex = pciDevicesIndex.value.indexOf(index)
535
+ pciDevicesIndex.value = pciDevicesIndex.value.filter((item) => item !== index)
536
+ pciDevicesType.value = pciDevicesType.value.filter(
537
+ (_item, key) => key !== removeIndex
538
+ )
539
+
540
+ model.value.passthrough_pci_devices = model.value.passthrough_pci_devices.filter(
541
+ (_pciDevice, key: number) => {
542
+ return removeIndex !== key
543
+ }
544
+ )
545
+ pciDevicesLocal.value = pciDevicesLocal.value.filter(
546
+ (_pciDevice, key: number) => {
547
+ return removeIndex !== key
548
+ }
549
+ )
550
+
551
+ delete newPciDeviceInvalidKeys.value[index]
552
+ }
553
+
554
+ const isShowFileModal = ref<boolean>(false)
555
+ const onAddDevice = (item: UI_I_DropdownTreeItemChild): void => {
556
+ switch (item.value) {
557
+ case 1:
558
+ addHardDisk()
559
+ break
560
+ case 2:
561
+ isShowFileModal.value = true
562
+ break
563
+ case 5:
564
+ addCdDvdDrive()
565
+ break
566
+ case 10:
567
+ addPciDevice()
568
+ break
569
+ case 14:
570
+ addNetwork()
571
+ break
572
+ }
573
+ }
574
+
575
+ const cpuInvalid = ref<boolean>(false)
576
+ const onSendDataNewHardDiskMethod = (
577
+ data: UI_I_SendDataNewHardDisk,
578
+ index: number
579
+ ): void => {
580
+ model.value.disk_devices[index] = {
581
+ ...data,
582
+ boot_order: model.value.disk_devices[index]?.boot_order || 0,
583
+ }
584
+ }
585
+ const sendDataNewNetworkMethod = (
586
+ data: UI_I_SendDataNewNetwork,
587
+ index: number
588
+ ): void => {
589
+ model.value.network_devices[index] = {
590
+ ...data,
591
+ boot_order: model.value.network_devices[index]?.boot_order || 0,
592
+ }
593
+ }
594
+ const sendDataNewCdDvdDriveMethod = (
595
+ data: UI_I_SendDataNewCdDvdDrive,
596
+ index: number
597
+ ): void => {
598
+ const cdromIndexStart = model.value.disk_devices.findIndex(
599
+ (disk) => disk.device_type === 'cdrom'
600
+ )
601
+ model.value.disk_devices[cdromIndexStart + index] = {
602
+ ...data,
603
+ boot_order:
604
+ model.value.disk_devices[cdromIndexStart + index]?.boot_order || 0,
605
+ }
606
+ }
607
+ const onSendDataPciDevicesMethod = (
608
+ data: UI_I_SendDataNewPciDevice,
609
+ index: number
610
+ ): void => {
611
+ model.value.passthrough_pci_devices[index] = {
612
+ ...data,
613
+ }
614
+ }
615
+
616
+ const onSetInvalidHardDisk = (invalid: boolean, index: number): void => {
617
+ newHardDiskInvalidKeys.value[index] = invalid
618
+ }
619
+
620
+ const onSetInvalidNetwork = (invalid: boolean, key: number): void => {
621
+ newNetworkInvalidKeys.value[key] = invalid
622
+ }
623
+
624
+ const onSetInvalidPciDevice = (invalid: boolean, key: number): void => {
625
+ newPciDeviceInvalidKeys.value[key] = invalid
626
+ }
627
+
628
+ const memoryInvalid = ref<boolean>(false)
629
+ const videoCardInvalid = ref<boolean>(false)
630
+ const newHardDiskInvalidKeys = ref<UI_I_InvalidKeys>({})
631
+ const newNetworkInvalidKeys = ref<UI_I_InvalidKeys>({})
632
+ const newPciDeviceInvalidKeys = ref<UI_I_InvalidKeys>({})
633
+
634
+ watch(
635
+ [
636
+ cpuInvalid,
637
+ memoryInvalid,
638
+ newHardDiskInvalidKeys,
639
+ newNetworkInvalidKeys,
640
+ newPciDeviceInvalidKeys,
641
+ videoCardInvalid,
642
+ ],
643
+ () => {
644
+ const cpu = cpuInvalid.value ? localization.value.common.cpu : ''
645
+ const memory = memoryInvalid.value ? localization.value.common.memory : ''
646
+ const videoCard = videoCardInvalid.value
647
+ ? localization.value.common.videoCard
648
+ : ''
649
+ let newHardDisk = ''
650
+ Object.keys(newHardDiskInvalidKeys.value).forEach((key) => {
651
+ if (!newHardDiskInvalidKeys.value[+key]) {
652
+ return
653
+ }
654
+
655
+ newHardDisk +=
656
+ (newHardDisk ? ', ' : '') +
657
+ localization.value.common.newHardDisk +
658
+ ' ' +
659
+ (+key + 1)
660
+ })
661
+ let newNetwork = ''
662
+ Object.keys(newNetworkInvalidKeys.value).forEach((key) => {
663
+ if (!newNetworkInvalidKeys.value[+key]) {
664
+ return
665
+ }
666
+
667
+ newNetwork +=
668
+ (newNetwork ? ', ' : '') +
669
+ localization.value.common.newNetwork +
670
+ ' ' +
671
+ (+key + 1)
672
+ })
673
+ // let pciDevice = ''
674
+ // Object.keys(newPciDeviceInvalidKeys.value).forEach((key) => {
675
+ // if (!newPciDeviceInvalidKeys.value[+key]) {
676
+ // return
677
+ // }
678
+ //
679
+ // pciDevice +=
680
+ // (pciDevice ? ', ' : '') +
681
+ // localization.value.common.pciDevice +
682
+ // ' ' +
683
+ // (+key + 1)
684
+ // })
685
+
686
+ emits('invalid', [cpu, memory, newHardDisk, newNetwork, videoCard])
687
+ },
688
+ { deep: true }
689
+ )
690
+
691
+ emits('get-pci-devices')
692
+ </script>
693
+
694
+ <style scoped lang="scss"></style>