bfg-common 1.1.76 → 1.1.78

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 (82) hide show
  1. package/components/atoms/alert/Notification.vue +167 -167
  2. package/components/atoms/autocomplete/Autocomplete.vue +236 -236
  3. package/components/atoms/datepicker/Datepicker.vue +612 -612
  4. package/components/atoms/list/SelectList.vue +62 -62
  5. package/components/atoms/nav/NavBar.vue +116 -116
  6. package/components/atoms/nav/VerticalNavBar.vue +89 -89
  7. package/components/atoms/notificationBar/NotificationBar.vue +175 -175
  8. package/components/atoms/perPage/PerPage.vue +52 -52
  9. package/components/atoms/popup/SimplePopup.vue +90 -90
  10. package/components/atoms/step/VerticalStep.vue +104 -104
  11. package/components/atoms/switch/Switch.vue +107 -107
  12. package/components/atoms/table/dataGrid/DataGridColumnSwitch.vue +206 -206
  13. package/components/atoms/table/dataGrid/DataGridPage.vue +189 -189
  14. package/components/atoms/tabs/Tabs.vue +189 -189
  15. package/components/atoms/tooltip/Signpost.vue +224 -224
  16. package/components/common/adapterManager/AddAdapterWarningModal.vue +82 -82
  17. package/components/common/adapterManager/NoActiveAdaptersModal.vue +62 -62
  18. package/components/common/adapterManager/NoConnectedActiveAdaptersModal.vue +62 -62
  19. package/components/common/browse/Browse.vue +182 -182
  20. package/components/common/browse/blocks/Title.vue +66 -66
  21. package/components/common/diagramMain/Diagram.vue +186 -186
  22. package/components/common/diagramMain/DiagramMain.vue +986 -986
  23. package/components/common/diagramMain/adapter/AdapterItem.vue +227 -227
  24. package/components/common/diagramMain/adapter/AdapterItems.vue +57 -57
  25. package/components/common/diagramMain/modals/editSettings/tabs/port/IpvFourSettings.vue +339 -339
  26. package/components/common/diagramMain/modals/editSettings/tabs/port/PortProperties.vue +202 -202
  27. package/components/common/diagramMain/modals/remove/RemoveModal.vue +226 -226
  28. package/components/common/diagramMain/network/Contents.vue +238 -238
  29. package/components/common/feedback/Buttons.vue +232 -232
  30. package/components/common/feedback/Message.vue +468 -468
  31. package/components/common/feedback/VisitPortal.vue +54 -54
  32. package/components/common/help/navbar/left/Left.vue +159 -159
  33. package/components/common/help/navbar/left/utils/constructAccordion.ts +27 -27
  34. package/components/common/mainNavigationPanel/MainNavigationPanel.vue +359 -359
  35. package/components/common/modals/Rename.vue +165 -165
  36. package/components/common/monitor/advanced/Advanced.vue +214 -221
  37. package/components/common/monitor/advanced/tools/Tools.vue +422 -441
  38. package/components/common/monitor/advanced/tools/chartOptionsModal/ChartOptionsModal.vue +452 -424
  39. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/Counters.vue +93 -86
  40. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/table/Table.vue +130 -121
  41. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/table/config/utils.ts +689 -688
  42. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/timespan/Timespan.vue +76 -73
  43. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/timespan/object/Object.vue +176 -129
  44. package/components/common/monitor/advanced/tools/chartOptionsModal/models/models.ts +19 -0
  45. package/components/common/perPage/PerPage.vue +51 -51
  46. package/components/common/recursionTree/RecursionTree.vue +201 -201
  47. package/components/common/vm/actions/add/config/capabilities.ts +777 -777
  48. package/components/common/vm/actions/add/customizeHardware/virtualHardware/VirtualHardware.vue +646 -646
  49. package/components/common/vm/actions/add/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDrive.vue +246 -246
  50. package/components/common/vm/actions/add/customizeHardware/virtualHardware/cpu/Cpu.vue +375 -375
  51. package/components/common/vm/actions/add/customizeHardware/virtualHardware/limit/Limit.vue +234 -234
  52. package/components/common/vm/actions/add/customizeHardware/virtualHardware/limit/config/options.ts +28 -28
  53. package/components/common/vm/actions/add/customizeHardware/virtualHardware/memory/Memory.vue +316 -316
  54. package/components/common/vm/actions/add/customizeHardware/virtualHardware/memory/config/memoryOptions.ts +35 -35
  55. package/components/common/vm/actions/add/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +445 -445
  56. package/components/common/vm/actions/add/customizeHardware/virtualHardware/reservation/Reservation.vue +235 -235
  57. package/components/common/vm/actions/add/customizeHardware/virtualHardware/videoCard/VideoCard.vue +177 -177
  58. package/components/common/vm/actions/add/customizeHardware/vmoptions/bootOptions/order/Order.vue +197 -197
  59. package/components/common/vm/actions/add/customizeHardware/vmoptions/generalOptions/GeneralOptions.vue +180 -180
  60. package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/CopyPaste.vue +51 -51
  61. package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/keymap/Keymap.vue +55 -55
  62. package/components/common/vm/actions/add/select/storage/config/config.ts +154 -154
  63. package/components/common/wizards/datastore/add/nfs/configuration/Configuration.vue +373 -373
  64. package/components/common/wizards/datastore/add/nfs/configuration/serversList/ServersList.vue +123 -123
  65. package/components/common/wizards/datastore/add/nfs/kerberosAuthentication/KerberosAuthentication.vue +54 -54
  66. package/components/common/wizards/datastore/add/sharedStorm/deviceSelection/hostTable/HostTable.vue +131 -131
  67. package/components/common/wizards/datastore/add/sharedStorm/partitionConfiguration/PartitionConfiguration.vue +230 -230
  68. package/models/store/interfaces.ts +37 -37
  69. package/models/store/storage/interfaces.ts +32 -32
  70. package/models/store/types.ts +32 -32
  71. package/modules/fixContentBuild/utils/methods.ts +114 -114
  72. package/package.json +1 -1
  73. package/public/spice-console/application/codec.js +257 -257
  74. package/public/spice-console/lib/rasterEngine.js +907 -907
  75. package/public/spice-console/network/spicechannel.js +369 -369
  76. package/public/spice-console-minify/lib/decoder/dixie.min.js +4 -4
  77. package/public/spice-console-minify/lib/jgestures.min.js +24 -24
  78. package/public/spice-console-minify/lib/jquery-2.0.3.min.js +24 -24
  79. package/public/spice-console-minify/lib/jquery-mousewheel.min.js +11 -11
  80. package/public/spice-console-minify/lib/jquery-visibility.min.js +1 -1
  81. package/public/spice-console-minify/lib/lodash.4.0.0.min.js +5 -5
  82. package/utils/contentBuild.ts +34 -34
@@ -1,646 +1,646 @@
1
- <template>
2
- <div class="virtual-hardware">
3
- <div class="clr-row clr-justify-content-end">
4
- <atoms-dropdown-tree
5
- :title="localization.addNewDevice"
6
- :items="dropdownItems"
7
- @select="onAddDevice"
8
- />
9
- </div>
10
-
11
- <div class="clr-component">
12
- <div class="stack-view">
13
- <common-vm-actions-add-customize-hardware-virtual-hardware-cpu
14
- :max-cpus="props.maxCpus"
15
- :cpu-models="props.cpuModels"
16
- :cpu="props.cpu"
17
- :is-edit="props.isEdit"
18
- :state="props.state"
19
- :error-validation-fields="props.errorValidationFields"
20
- :vm-cpu-help-text-second="props.vmCpuHelpTextSecond"
21
- @send-data="onSendDataCpuMethod"
22
- @remove-error-by-title="emits('remove-error-by-title', $event)"
23
- @invalid="cpuInvalid = $event"
24
- />
25
- <common-vm-actions-add-customize-hardware-virtual-hardware-memory
26
- :max-memory="props.maxMemory"
27
- :is-edit="props.isEdit"
28
- :memory="props.memory"
29
- :state="props.state"
30
- :error-validation-fields="props.errorValidationFields"
31
- @send-data="onSendDataMemoryMethod"
32
- @invalid="memoryInvalid = $event"
33
- @remove-error-by-title="emits('remove-error-by-title', $event)"
34
- />
35
- <common-vm-actions-add-customize-hardware-virtual-hardware-new-hard-disk
36
- v-for="(item, key) in hardDisks"
37
- :key="hardDisksIndex[key]"
38
- :index="hardDisksIndex[key]"
39
- :type="hardDisksType[key]"
40
- :storage="props.storage"
41
- :hard-disk="item"
42
- :error-validation-fields="props.errorValidationFields"
43
- :get-datastore-table-func="props.getDatastoreTableFunc"
44
- :datastore="props.datastore"
45
- :is-edit="props.isEdit"
46
- :state="props.state"
47
- @remove="onRemoveHardDisk(hardDisksIndex[key], item)"
48
- @roll-back="onRollBackHardDisk(hardDisksIndex[key])"
49
- @send-data="onSendDataNewHardDiskMethod($event, hardDisksIndex[key])"
50
- @invalid="onSetInvalidHardDisk($event, hardDisksIndex[key])"
51
- @remove-error-by-title="emits('remove-error-by-title', $event)"
52
- />
53
- <common-vm-actions-add-customize-hardware-virtual-hardware-new-network
54
- v-for="(item, key) in networks"
55
- :key="networksIndex[key]"
56
- :index="networksIndex[key]"
57
- :type="networksType[key]"
58
- :network="item"
59
- :networks-table="props.networksTable"
60
- :error-validation-fields="props.errorValidationFields"
61
- :state="props.state"
62
- @remove="onRemoveNetwork(networksIndex[key])"
63
- @send-data="sendDataNewNetworkMethod($event, networksIndex[key])"
64
- @invalid="onSetInvalidNetwork($event, networksIndex[key])"
65
- @remove-error-by-title="emits('remove-error-by-title', $event)"
66
- @get-networks-table="emits('get-networks-table', $event)"
67
- />
68
- <common-vm-actions-add-customize-hardware-virtual-hardware-cd-dvd-drive
69
- v-for="(item, key) in cdDvdDrives"
70
- :key="cdDvdDrivesIndex[key]"
71
- :index="cdDvdDrivesIndex[key]"
72
- :hard-disks-count="hardDisks.length"
73
- :type="cdDvdDrivesType[key]"
74
- :cd-dvd-drive="item"
75
- :nodes="props.nodes"
76
- :files="props.files"
77
- :error-validation-fields="props.errorValidationFields"
78
- :is-edit="props.isEdit"
79
- :state="props.state"
80
- @remove-error-by-title="emits('remove-error-by-title', $event)"
81
- @get-storage="emits('get-storage', $event)"
82
- @get-folders-or-files="emits('get-folders-or-files', $event)"
83
- @get-active-device-child="emits('get-active-device-child', $event)"
84
- @show-datastore-child="emits('show-datastore-child', $event)"
85
- @remove="onRemoveCdDvdDrive(cdDvdDrivesIndex[key], item)"
86
- @roll-back="onRollBackCdDvdDrive(cdDvdDrivesIndex[key])"
87
- @send-data="
88
- sendDataNewCdDvdDriveMethod($event, cdDvdDrivesIndex[key])
89
- "
90
- />
91
- <common-vm-actions-add-customize-hardware-virtual-hardware-new-usb-controller
92
- :usb-controller="props.usbController"
93
- :is-edit="props.isEdit"
94
- :state="props.state"
95
- @send-data="onSendDataNewUsbControllerMethod"
96
- />
97
- <template v-if="props.passthroughDevices">
98
- <common-vm-actions-add-customize-hardware-virtual-hardware-new-pci-device
99
- v-for="(item, key) in pciDevices"
100
- :key="pciDevicesIndex[key]"
101
- :index="pciDevicesIndex[key]"
102
- :pci-device="item"
103
- :error-validation-fields="props.errorValidationFields"
104
- :passthrough-devices="props.passthroughDevices"
105
- :type="pciDevicesType[key]"
106
- @remove="onRemovePciDevice(pciDevicesIndex[key])"
107
- @send-data="
108
- onSendDataPciDevicesMethod($event, pciDevicesIndex[key])
109
- "
110
- @invalid="onSetInvalidPciDevice($event, pciDevicesIndex[key])"
111
- @remove-error-by-title="emits('remove-error-by-title', $event)"
112
- />
113
- </template>
114
- <common-vm-actions-add-customize-hardware-virtual-hardware-video-card
115
- :is-edit="props.isEdit"
116
- :video-card="props.videoCard"
117
- :error-validation-fields="props.errorValidationFields"
118
- :state="props.state"
119
- @send-data="onSendDataVideoCardMethod"
120
- @invalid="videoCardInvalid = $event"
121
- @remove-error-by-title="emits('remove-error-by-title', $event)"
122
- />
123
- <common-vm-actions-add-customize-hardware-virtual-hardware-other />
124
- </div>
125
- </div>
126
-
127
- <Teleport to="body">
128
- <common-vm-actions-add-customize-hardware-virtual-hardware-browse-view
129
- v-if="isShowFileModal"
130
- :show="isShowFileModal"
131
- :nodes="props.nodes"
132
- :files="props.files"
133
- @submit="onAddExistHardDisk"
134
- @get-storage="emits('get-storage', $event)"
135
- @get-folders-or-files="emits('get-folders-or-files', $event)"
136
- @get-active-device-child="emits('get-active-device-child', $event)"
137
- @show-datastore-child="emits('show-datastore-child', $event)"
138
- @hide="isShowFileModal = false"
139
- />
140
- </Teleport>
141
- </div>
142
- </template>
143
-
144
- <script setup lang="ts">
145
- import { UI_I_DatastoreTableItem } from '~/models/store/storage/interfaces'
146
- import { UI_I_NetworkTableItem } from '~/models/store/network/interfaces'
147
- import { UI_I_TablePayload } from '~/models/store/interfaces'
148
- import { UI_I_FolderOrFileTreePayload } from '~/models/store/storage/interfaces'
149
- import { UI_I_FileTreeNode } from '~/components/models/interfaces'
150
- import {
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_PciDevice,
161
- UI_I_SendDataNewPciDevice,
162
- } from '~/components/common/vm/actions/add/customizeHardware/virtualHardware/models/interfaces'
163
- import { UI_I_ErrorValidationField } from '~/models/store/interfaces'
164
- import {
165
- UI_T_HardDiskType,
166
- UI_T_NetworkType,
167
- UI_T_CdDvdType,
168
- } from '~/components/common/vm/actions/add/customizeHardware/virtualHardware/models/types'
169
- import { UI_I_OptionItem } from '~/components/atoms/models/interfaces'
170
- import {
171
- UI_I_DropdownTreeItem,
172
- UI_I_DropdownTreeItemChild,
173
- } from '~/components/atoms/dropdown/tree/models/interfaces'
174
- import { UI_I_Localization } from '~/models/interfaces'
175
- import { UI_I_ConfigurePciDevicesTable } from '~/models/store/host/interfaces'
176
- import {
177
- API_UI_I_VmEditCpu,
178
- API_UI_I_VmEditMemory,
179
- } from '~/models/store/vm/interfaces'
180
- import { dropdownItemsFunc } from './config/dropdownItems'
181
-
182
- const props = defineProps<{
183
- storage: UI_I_DatastoreTableItem | null
184
- cpuModels: UI_I_OptionItem[]
185
- vmName: string
186
- maxCpus: number
187
- maxMemory: number
188
- isEdit: boolean
189
- errorValidationFields: UI_I_ErrorValidationField<string>[]
190
- nodes: UI_I_FileTreeNode[]
191
- files: UI_I_FileTreeNode[]
192
- networksTable: UI_I_NetworkTableItem[]
193
- getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
194
- datastore: UI_I_DatastoreTableItem[]
195
- state?: string | number
196
- cpu?: API_UI_I_VmEditCpu
197
- memory?: API_UI_I_VmEditMemory
198
- vmCpuHelpTextSecond?: string
199
- hardDisks?: UI_I_SendDataNewHardDisk[] | null
200
- cdDvdDrives?: UI_I_SendDataNewCdDvdDrive[] | null
201
- networks?: UI_I_SendDataNewNetwork[] | null
202
- videoCard?: UI_I_SendDataVideoCard
203
- usbController?: string
204
- pciDevices?: UI_I_PciDevice[]
205
- passthroughDevices?: UI_I_ConfigurePciDevicesTable | null
206
- }>()
207
- const emits = defineEmits<{
208
- (event: 'send-data', value: UI_I_SendDataVirtualHardware): void
209
- (event: 'invalid', value: string[]): void
210
- (event: 'get-storage', value: UI_I_TablePayload): void
211
- (event: 'get-folders-or-files', value: UI_I_FolderOrFileTreePayload): void
212
- (event: 'get-active-device-child', value: UI_I_FileTreeNode): void
213
- (event: 'show-datastore-child', value: UI_I_FileTreeNode): void
214
- (event: 'remove-error-by-title', value: string): void
215
- (event: 'get-networks-table', value: UI_I_TablePayload): void
216
- (event: 'get-pci-devices'): void
217
- }>()
218
-
219
- const localization = computed<UI_I_Localization>(() => useLocal())
220
- const { $binary } = useNuxtApp()
221
-
222
- const dropdownItems = computed<UI_I_DropdownTreeItem[]>(() =>
223
- dropdownItemsFunc(localization.value)
224
- )
225
-
226
- const hardDisksIndex = ref<number[]>([0])
227
- const hardDisksType = ref<UI_T_HardDiskType[]>(['new'])
228
- const hardDisks = ref<UI_I_SendDataNewHardDisk[]>([
229
- {
230
- create: true,
231
- size: 90,
232
- source: '',
233
- boot_order: -1,
234
- },
235
- ])
236
- watch(
237
- () => props.hardDisks,
238
- (newValue) => {
239
- if (!props.isEdit || !newValue) return
240
-
241
- const count = newValue?.length || 0
242
- hardDisksIndex.value = [...Array(count).keys()]
243
- hardDisksType.value = Array(count).fill('edit')
244
- hardDisks.value = newValue
245
- },
246
- { immediate: true }
247
- )
248
-
249
- const addHardDisk = (
250
- create = true,
251
- size = 90,
252
- source = '',
253
- type: UI_T_HardDiskType = 'new'
254
- ): void => {
255
- const newIndex = (hardDisksIndex.value.at(-1) ?? -1) + 1
256
- hardDisksIndex.value.push(newIndex)
257
- hardDisksType.value.push(type)
258
-
259
- hardDisks.value.push({ create, size, source, attach: true, boot_order: -1 })
260
- sendData()
261
- }
262
- const onAddExistHardDisk = (hardDisk: UI_I_HardDisk): void => {
263
- addHardDisk(false, $binary.bToGb(hardDisk.size), hardDisk.path, 'exist')
264
- }
265
- const onRemoveHardDisk = (
266
- index: number,
267
- hardDisk: UI_I_SendDataNewHardDisk
268
- ): void => {
269
- const removeIndex = hardDisksIndex.value.indexOf(index)
270
-
271
- if (!hardDisk.create && !hardDisk.attach) {
272
- hardDisksType.value = hardDisksType.value.map((item, key) => {
273
- if (key === removeIndex) return 'removed'
274
- return item
275
- })
276
- sendData()
277
- return
278
- }
279
-
280
- hardDisksIndex.value = hardDisksIndex.value.filter((item) => item !== index)
281
- hardDisksType.value = hardDisksType.value.filter(
282
- (_item, key) => key !== removeIndex
283
- )
284
-
285
- hardDisks.value = hardDisks.value.filter((_hardDisk, key: number) => {
286
- return removeIndex !== key
287
- })
288
-
289
- delete newHardDiskInvalidKeys.value[index]
290
- delete sendDataNewHardDisk.value[index]
291
- sendData()
292
- }
293
- const onRollBackHardDisk = (index: number): void => {
294
- const removeIndex = hardDisksIndex.value.indexOf(index)
295
- hardDisksType.value = hardDisksType.value.map((item, key) => {
296
- if (key === removeIndex) return 'edit'
297
- return item
298
- })
299
- }
300
-
301
- const defaultNetwork = {
302
- network: '',
303
- net_bridge: '',
304
- mac: '',
305
- target: '',
306
- model: '',
307
- boot_order: -1,
308
- }
309
- const networks = ref<UI_I_SendDataNewNetwork[]>([useDeepCopy(defaultNetwork)])
310
- const networksType = ref<UI_T_NetworkType[]>(['new'])
311
- const networksIndex = ref<number[]>([0])
312
- watch(
313
- () => props.networks,
314
- (newValue) => {
315
- if (!props.isEdit || !newValue) return
316
-
317
- // networks.value = newValue
318
- // networksType.value = Array(newValue.length).fill('edit')
319
- const count = newValue?.length || 0
320
- networksIndex.value = [...Array(count).keys()]
321
- networksType.value = Array(count).fill('edit')
322
- networks.value = newValue
323
- },
324
- { immediate: true }
325
- )
326
- const addNetwork = (): void => {
327
- const index = (networksIndex.value.at(-1) || 0) + 1
328
- networksIndex.value.push(index)
329
- networksType.value.push('new')
330
-
331
- networks.value.push(useDeepCopy(defaultNetwork))
332
- }
333
- const onRemoveNetwork = (index: number): void => {
334
- const removeIndex = networksIndex.value.indexOf(index)
335
- networksIndex.value = networksIndex.value.filter((item) => item !== index)
336
- networksType.value = networksType.value.filter(
337
- (_item, key) => key !== removeIndex
338
- )
339
- networks.value = networks.value.filter(
340
- (_network, key: number) => removeIndex !== key
341
- )
342
-
343
- delete newNetworkInvalidKeys.value[index]
344
- delete sendDataNewNetwork.value[index]
345
- sendData()
346
- }
347
-
348
- const defaultCdDvdDriver: UI_I_SendDataNewCdDvdDrive = {
349
- create: false,
350
- attach: false,
351
- source: '',
352
- bus: '',
353
- device_type: 'cdrom',
354
- boot_order: -1,
355
- }
356
- const cdDvdDrives = ref<UI_I_SendDataNewCdDvdDrive[]>([
357
- useDeepCopy(defaultCdDvdDriver),
358
- ])
359
- const cdDvdDrivesIndex = ref<number[]>([0])
360
- const cdDvdDrivesType = ref<UI_T_CdDvdType[]>(['new'])
361
- watch(
362
- () => props.cdDvdDrives,
363
- (newValue) => {
364
- if (!props.isEdit || !newValue) return
365
-
366
- // cdDvdDrives.value = newValue
367
- // cdDvdDrivesType.value = Array(newValue.length).fill('edit')
368
- const count = newValue?.length || 0
369
- cdDvdDrivesIndex.value = [...Array(count).keys()]
370
- cdDvdDrivesType.value = Array(count).fill('edit')
371
- cdDvdDrives.value = newValue
372
- },
373
- { immediate: true }
374
- )
375
- const addCdDvdDrive = (): void => {
376
- const value = (cdDvdDrivesIndex.value.at(-1) || 0) + 1
377
- cdDvdDrivesIndex.value.push(value)
378
- cdDvdDrivesType.value.push('new')
379
- cdDvdDrives.value.push({
380
- ...useDeepCopy(defaultCdDvdDriver),
381
- attach: true,
382
- })
383
- }
384
- const onRemoveCdDvdDrive = (
385
- index: number,
386
- cdDvdDrive: UI_I_SendDataNewCdDvdDrive
387
- ): void => {
388
- const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
389
-
390
- // if (!cdDvdDrive.create && !cdDvdDrive.attach) {
391
- if (cdDvdDrivesType.value[index] === 'edit' && !cdDvdDrive.attach) {
392
- cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
393
- if (key === removeIndex) return 'removed'
394
- return item
395
- })
396
- sendData()
397
- return
398
- }
399
-
400
- cdDvdDrivesIndex.value = cdDvdDrivesIndex.value.filter(
401
- (cdDvdDrive) => cdDvdDrive !== index
402
- )
403
- cdDvdDrivesType.value = cdDvdDrivesType.value.filter(
404
- (_item, key) => key !== index
405
- )
406
- cdDvdDrives.value = cdDvdDrives.value.filter(
407
- (_cdDvdDrive, key: number) => removeIndex !== key
408
- )
409
-
410
- delete sendDataNewCdDvdDrive.value[index]
411
- sendData()
412
- }
413
- const onRollBackCdDvdDrive = (index: number): void => {
414
- const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
415
- cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
416
- if (key === removeIndex) return 'edit'
417
- return item
418
- })
419
- }
420
-
421
- const defaultPciDevice: UI_I_PciDevice = {
422
- id: '',
423
- vendor_name: '',
424
- class_name: 'cdrom',
425
- device_name: 'cdrom',
426
- }
427
- const pciDevicesIndex = ref<number[]>([0])
428
- const pciDevicesType = ref<('new' | 'edit')[]>(['new'])
429
- const pciDevices = ref<UI_I_PciDevice[]>([])
430
- watch(
431
- () => props.pciDevices,
432
- (newValue) => {
433
- if (!props.isEdit) return
434
-
435
- const count = newValue?.length || 0
436
- pciDevicesIndex.value = [...Array(count).keys()]
437
- pciDevicesType.value = Array(count).fill('edit')
438
- pciDevices.value = newValue || []
439
- },
440
- { immediate: true }
441
- )
442
-
443
- const addPciDevice = (): void => {
444
- const newIndex = (pciDevicesIndex.value.at(-1) ?? -1) + 1
445
- pciDevicesIndex.value.push(newIndex)
446
- pciDevicesType.value.push('new')
447
-
448
- pciDevices.value.push(useDeepCopy(defaultPciDevice))
449
- }
450
- const onRemovePciDevice = (index: number): void => {
451
- const removeIndex = pciDevicesIndex.value.indexOf(index)
452
- pciDevicesIndex.value = pciDevicesIndex.value.filter((item) => item !== index)
453
- pciDevicesType.value = pciDevicesType.value.filter(
454
- (_item, key) => key !== removeIndex
455
- )
456
-
457
- pciDevices.value = pciDevices.value.filter((_pciDevice, key: number) => {
458
- return removeIndex !== key
459
- })
460
-
461
- delete newPciDeviceInvalidKeys.value[index]
462
- delete sendDataNewPciDevices.value[index]
463
- sendData()
464
- }
465
-
466
- const isShowFileModal = ref<boolean>(false)
467
- const onAddDevice = (item: UI_I_DropdownTreeItemChild): void => {
468
- switch (item.value) {
469
- case 1:
470
- addHardDisk()
471
- break
472
- case 2:
473
- isShowFileModal.value = true
474
- break
475
- case 5:
476
- addCdDvdDrive()
477
- break
478
- case 10:
479
- addPciDevice()
480
- break
481
- case 14:
482
- addNetwork()
483
- break
484
- }
485
- }
486
-
487
- const cpuInvalid = ref<boolean>(false)
488
- const sendDataCpu = ref<UI_I_SendDataCpu | null>(null)
489
- const onSendDataCpuMethod = (data: UI_I_SendDataCpu): void => {
490
- sendDataCpu.value = data
491
- sendData()
492
- }
493
- const sendDataMemory = ref<UI_I_SendDataMemory | null>(null)
494
- const onSendDataMemoryMethod = (data: UI_I_SendDataMemory): void => {
495
- sendDataMemory.value = data
496
- sendData()
497
- }
498
- const sendDataNewHardDisk = ref<UI_I_SendDataNewHardDisk[]>([])
499
- const onSendDataNewHardDiskMethod = (
500
- data: UI_I_SendDataNewHardDisk,
501
- index: number
502
- ): void => {
503
- sendDataNewHardDisk.value[index] = data
504
- sendData()
505
- }
506
- const sendDataNewNetwork = ref<UI_I_SendDataNewNetwork[]>([])
507
- const sendDataNewNetworkMethod = (
508
- data: UI_I_SendDataNewNetwork,
509
- index: number
510
- ): void => {
511
- sendDataNewNetwork.value[index] = data
512
- sendData()
513
- }
514
- const sendDataNewCdDvdDrive = ref<UI_I_SendDataNewCdDvdDrive[]>([])
515
- const sendDataNewCdDvdDriveMethod = (
516
- data: UI_I_SendDataNewCdDvdDrive,
517
- index: number
518
- ): void => {
519
- sendDataNewCdDvdDrive.value[index] = data
520
- sendData()
521
- }
522
- const sendDataNewUsbController = ref<string | null>(null)
523
- const onSendDataNewUsbControllerMethod = (data: string): void => {
524
- sendDataNewUsbController.value = data
525
- sendData()
526
- }
527
- const sendDataNewPciDevices = ref<UI_I_SendDataNewPciDevice[]>([])
528
- const onSendDataPciDevicesMethod = (
529
- data: UI_I_SendDataNewPciDevice,
530
- index: number
531
- ): void => {
532
- sendDataNewPciDevices.value[index] = data
533
- sendData()
534
- }
535
- const sendDataVideoCard = ref<UI_I_SendDataVideoCard | null>(null)
536
- const onSendDataVideoCardMethod = (data: UI_I_SendDataVideoCard): void => {
537
- sendDataVideoCard.value = data
538
- sendData()
539
- }
540
-
541
- const sendData = (): void => {
542
- const cpu = sendDataCpu.value
543
- const memory = sendDataMemory.value
544
- const hardDisks = sendDataNewHardDisk.value.flat(2)
545
- const networks = sendDataNewNetwork.value.flat(2)
546
- const cdDvdDrives = sendDataNewCdDvdDrive.value.flat(2)
547
- const pciDevices = sendDataNewPciDevices.value.flat()
548
- const usbController = sendDataNewUsbController.value
549
- const videoCard = sendDataVideoCard.value
550
-
551
- const sendData: UI_I_SendDataVirtualHardware = {
552
- cpu,
553
- memory,
554
- usbController,
555
- pciDevices,
556
- networks,
557
- hardDisks,
558
- cdDvdDrives,
559
- videoCard,
560
- }
561
- emits('send-data', sendData)
562
- }
563
-
564
- const onSetInvalidHardDisk = (invalid: boolean, index: number): void => {
565
- newHardDiskInvalidKeys.value[index] = invalid
566
- }
567
-
568
- const onSetInvalidNetwork = (invalid: boolean, key: number): void => {
569
- newNetworkInvalidKeys.value[key] = invalid
570
- }
571
-
572
- const onSetInvalidPciDevice = (invalid: boolean, key: number): void => {
573
- newPciDeviceInvalidKeys.value[key] = invalid
574
- }
575
-
576
- const memoryInvalid = ref<boolean>(false)
577
- const videoCardInvalid = ref<boolean>(false)
578
- const newHardDiskInvalidKeys = ref<UI_I_InvalidKeys>({})
579
- const newNetworkInvalidKeys = ref<UI_I_InvalidKeys>({})
580
- const newPciDeviceInvalidKeys = ref<UI_I_InvalidKeys>({})
581
-
582
- watch(
583
- [
584
- cpuInvalid,
585
- memoryInvalid,
586
- newHardDiskInvalidKeys,
587
- newNetworkInvalidKeys,
588
- newPciDeviceInvalidKeys,
589
- videoCardInvalid,
590
- ],
591
- () => {
592
- const cpu = cpuInvalid.value ? localization.value.cpu : ''
593
- const memory = memoryInvalid.value ? localization.value.memory : ''
594
- const videoCard = videoCardInvalid.value ? localization.value.videoCard : ''
595
- let newHardDisk = ''
596
- Object.keys(newHardDiskInvalidKeys.value).forEach((key) => {
597
- if (!newHardDiskInvalidKeys.value[+key]) {
598
- return
599
- }
600
-
601
- newHardDisk +=
602
- (newHardDisk ? ', ' : '') +
603
- localization.value.newHardDisk +
604
- ' ' +
605
- (+key + 1)
606
- })
607
- let newNetwork = ''
608
- Object.keys(newNetworkInvalidKeys.value).forEach((key) => {
609
- if (!newNetworkInvalidKeys.value[+key]) {
610
- return
611
- }
612
-
613
- newNetwork +=
614
- (newNetwork ? ', ' : '') +
615
- localization.value.newNetwork +
616
- ' ' +
617
- (+key + 1)
618
- })
619
- // let pciDevice = ''
620
- // Object.keys(newPciDeviceInvalidKeys.value).forEach((key) => {
621
- // if (!newPciDeviceInvalidKeys.value[+key]) {
622
- // return
623
- // }
624
- //
625
- // pciDevice +=
626
- // (pciDevice ? ', ' : '') +
627
- // localization.value.pciDevice +
628
- // ' ' +
629
- // (+key + 1)
630
- // })
631
-
632
- emits('invalid', [cpu, memory, newHardDisk, newNetwork, videoCard])
633
- },
634
- { deep: true }
635
- )
636
-
637
- emits('get-pci-devices')
638
- </script>
639
-
640
- <style scoped lang="scss">
641
- .virtual-hardware {
642
- .content-dropdown {
643
- width: 200px;
644
- }
645
- }
646
- </style>
1
+ <template>
2
+ <div class="virtual-hardware">
3
+ <div class="clr-row clr-justify-content-end">
4
+ <atoms-dropdown-tree
5
+ :title="localization.addNewDevice"
6
+ :items="dropdownItems"
7
+ @select="onAddDevice"
8
+ />
9
+ </div>
10
+
11
+ <div class="clr-component">
12
+ <div class="stack-view">
13
+ <common-vm-actions-add-customize-hardware-virtual-hardware-cpu
14
+ :max-cpus="props.maxCpus"
15
+ :cpu-models="props.cpuModels"
16
+ :cpu="props.cpu"
17
+ :is-edit="props.isEdit"
18
+ :state="props.state"
19
+ :error-validation-fields="props.errorValidationFields"
20
+ :vm-cpu-help-text-second="props.vmCpuHelpTextSecond"
21
+ @send-data="onSendDataCpuMethod"
22
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
23
+ @invalid="cpuInvalid = $event"
24
+ />
25
+ <common-vm-actions-add-customize-hardware-virtual-hardware-memory
26
+ :max-memory="props.maxMemory"
27
+ :is-edit="props.isEdit"
28
+ :memory="props.memory"
29
+ :state="props.state"
30
+ :error-validation-fields="props.errorValidationFields"
31
+ @send-data="onSendDataMemoryMethod"
32
+ @invalid="memoryInvalid = $event"
33
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
34
+ />
35
+ <common-vm-actions-add-customize-hardware-virtual-hardware-new-hard-disk
36
+ v-for="(item, key) in hardDisks"
37
+ :key="hardDisksIndex[key]"
38
+ :index="hardDisksIndex[key]"
39
+ :type="hardDisksType[key]"
40
+ :storage="props.storage"
41
+ :hard-disk="item"
42
+ :error-validation-fields="props.errorValidationFields"
43
+ :get-datastore-table-func="props.getDatastoreTableFunc"
44
+ :datastore="props.datastore"
45
+ :is-edit="props.isEdit"
46
+ :state="props.state"
47
+ @remove="onRemoveHardDisk(hardDisksIndex[key], item)"
48
+ @roll-back="onRollBackHardDisk(hardDisksIndex[key])"
49
+ @send-data="onSendDataNewHardDiskMethod($event, hardDisksIndex[key])"
50
+ @invalid="onSetInvalidHardDisk($event, hardDisksIndex[key])"
51
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
52
+ />
53
+ <common-vm-actions-add-customize-hardware-virtual-hardware-new-network
54
+ v-for="(item, key) in networks"
55
+ :key="networksIndex[key]"
56
+ :index="networksIndex[key]"
57
+ :type="networksType[key]"
58
+ :network="item"
59
+ :networks-table="props.networksTable"
60
+ :error-validation-fields="props.errorValidationFields"
61
+ :state="props.state"
62
+ @remove="onRemoveNetwork(networksIndex[key])"
63
+ @send-data="sendDataNewNetworkMethod($event, networksIndex[key])"
64
+ @invalid="onSetInvalidNetwork($event, networksIndex[key])"
65
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
66
+ @get-networks-table="emits('get-networks-table', $event)"
67
+ />
68
+ <common-vm-actions-add-customize-hardware-virtual-hardware-cd-dvd-drive
69
+ v-for="(item, key) in cdDvdDrives"
70
+ :key="cdDvdDrivesIndex[key]"
71
+ :index="cdDvdDrivesIndex[key]"
72
+ :hard-disks-count="hardDisks.length"
73
+ :type="cdDvdDrivesType[key]"
74
+ :cd-dvd-drive="item"
75
+ :nodes="props.nodes"
76
+ :files="props.files"
77
+ :error-validation-fields="props.errorValidationFields"
78
+ :is-edit="props.isEdit"
79
+ :state="props.state"
80
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
81
+ @get-storage="emits('get-storage', $event)"
82
+ @get-folders-or-files="emits('get-folders-or-files', $event)"
83
+ @get-active-device-child="emits('get-active-device-child', $event)"
84
+ @show-datastore-child="emits('show-datastore-child', $event)"
85
+ @remove="onRemoveCdDvdDrive(cdDvdDrivesIndex[key], item)"
86
+ @roll-back="onRollBackCdDvdDrive(cdDvdDrivesIndex[key])"
87
+ @send-data="
88
+ sendDataNewCdDvdDriveMethod($event, cdDvdDrivesIndex[key])
89
+ "
90
+ />
91
+ <common-vm-actions-add-customize-hardware-virtual-hardware-new-usb-controller
92
+ :usb-controller="props.usbController"
93
+ :is-edit="props.isEdit"
94
+ :state="props.state"
95
+ @send-data="onSendDataNewUsbControllerMethod"
96
+ />
97
+ <template v-if="props.passthroughDevices">
98
+ <common-vm-actions-add-customize-hardware-virtual-hardware-new-pci-device
99
+ v-for="(item, key) in pciDevices"
100
+ :key="pciDevicesIndex[key]"
101
+ :index="pciDevicesIndex[key]"
102
+ :pci-device="item"
103
+ :error-validation-fields="props.errorValidationFields"
104
+ :passthrough-devices="props.passthroughDevices"
105
+ :type="pciDevicesType[key]"
106
+ @remove="onRemovePciDevice(pciDevicesIndex[key])"
107
+ @send-data="
108
+ onSendDataPciDevicesMethod($event, pciDevicesIndex[key])
109
+ "
110
+ @invalid="onSetInvalidPciDevice($event, pciDevicesIndex[key])"
111
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
112
+ />
113
+ </template>
114
+ <common-vm-actions-add-customize-hardware-virtual-hardware-video-card
115
+ :is-edit="props.isEdit"
116
+ :video-card="props.videoCard"
117
+ :error-validation-fields="props.errorValidationFields"
118
+ :state="props.state"
119
+ @send-data="onSendDataVideoCardMethod"
120
+ @invalid="videoCardInvalid = $event"
121
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
122
+ />
123
+ <common-vm-actions-add-customize-hardware-virtual-hardware-other />
124
+ </div>
125
+ </div>
126
+
127
+ <Teleport to="body">
128
+ <common-vm-actions-add-customize-hardware-virtual-hardware-browse-view
129
+ v-if="isShowFileModal"
130
+ :show="isShowFileModal"
131
+ :nodes="props.nodes"
132
+ :files="props.files"
133
+ @submit="onAddExistHardDisk"
134
+ @get-storage="emits('get-storage', $event)"
135
+ @get-folders-or-files="emits('get-folders-or-files', $event)"
136
+ @get-active-device-child="emits('get-active-device-child', $event)"
137
+ @show-datastore-child="emits('show-datastore-child', $event)"
138
+ @hide="isShowFileModal = false"
139
+ />
140
+ </Teleport>
141
+ </div>
142
+ </template>
143
+
144
+ <script setup lang="ts">
145
+ import { UI_I_DatastoreTableItem } from '~/models/store/storage/interfaces'
146
+ import { UI_I_NetworkTableItem } from '~/models/store/network/interfaces'
147
+ import { UI_I_TablePayload } from '~/models/store/interfaces'
148
+ import { UI_I_FolderOrFileTreePayload } from '~/models/store/storage/interfaces'
149
+ import { UI_I_FileTreeNode } from '~/components/models/interfaces'
150
+ import {
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_PciDevice,
161
+ UI_I_SendDataNewPciDevice,
162
+ } from '~/components/common/vm/actions/add/customizeHardware/virtualHardware/models/interfaces'
163
+ import { UI_I_ErrorValidationField } from '~/models/store/interfaces'
164
+ import {
165
+ UI_T_HardDiskType,
166
+ UI_T_NetworkType,
167
+ UI_T_CdDvdType,
168
+ } from '~/components/common/vm/actions/add/customizeHardware/virtualHardware/models/types'
169
+ import { UI_I_OptionItem } from '~/components/atoms/models/interfaces'
170
+ import {
171
+ UI_I_DropdownTreeItem,
172
+ UI_I_DropdownTreeItemChild,
173
+ } from '~/components/atoms/dropdown/tree/models/interfaces'
174
+ import { UI_I_Localization } from '~/models/interfaces'
175
+ import { UI_I_ConfigurePciDevicesTable } from '~/models/store/host/interfaces'
176
+ import {
177
+ API_UI_I_VmEditCpu,
178
+ API_UI_I_VmEditMemory,
179
+ } from '~/models/store/vm/interfaces'
180
+ import { dropdownItemsFunc } from './config/dropdownItems'
181
+
182
+ const props = defineProps<{
183
+ storage: UI_I_DatastoreTableItem | null
184
+ cpuModels: UI_I_OptionItem[]
185
+ vmName: string
186
+ maxCpus: number
187
+ maxMemory: number
188
+ isEdit: boolean
189
+ errorValidationFields: UI_I_ErrorValidationField<string>[]
190
+ nodes: UI_I_FileTreeNode[]
191
+ files: UI_I_FileTreeNode[]
192
+ networksTable: UI_I_NetworkTableItem[]
193
+ getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
194
+ datastore: UI_I_DatastoreTableItem[]
195
+ state?: string | number
196
+ cpu?: API_UI_I_VmEditCpu
197
+ memory?: API_UI_I_VmEditMemory
198
+ vmCpuHelpTextSecond?: string
199
+ hardDisks?: UI_I_SendDataNewHardDisk[] | null
200
+ cdDvdDrives?: UI_I_SendDataNewCdDvdDrive[] | null
201
+ networks?: UI_I_SendDataNewNetwork[] | null
202
+ videoCard?: UI_I_SendDataVideoCard
203
+ usbController?: string
204
+ pciDevices?: UI_I_PciDevice[]
205
+ passthroughDevices?: UI_I_ConfigurePciDevicesTable | null
206
+ }>()
207
+ const emits = defineEmits<{
208
+ (event: 'send-data', value: UI_I_SendDataVirtualHardware): void
209
+ (event: 'invalid', value: string[]): void
210
+ (event: 'get-storage', value: UI_I_TablePayload): void
211
+ (event: 'get-folders-or-files', value: UI_I_FolderOrFileTreePayload): void
212
+ (event: 'get-active-device-child', value: UI_I_FileTreeNode): void
213
+ (event: 'show-datastore-child', value: UI_I_FileTreeNode): void
214
+ (event: 'remove-error-by-title', value: string): void
215
+ (event: 'get-networks-table', value: UI_I_TablePayload): void
216
+ (event: 'get-pci-devices'): void
217
+ }>()
218
+
219
+ const localization = computed<UI_I_Localization>(() => useLocal())
220
+ const { $binary } = useNuxtApp()
221
+
222
+ const dropdownItems = computed<UI_I_DropdownTreeItem[]>(() =>
223
+ dropdownItemsFunc(localization.value)
224
+ )
225
+
226
+ const hardDisksIndex = ref<number[]>([0])
227
+ const hardDisksType = ref<UI_T_HardDiskType[]>(['new'])
228
+ const hardDisks = ref<UI_I_SendDataNewHardDisk[]>([
229
+ {
230
+ create: true,
231
+ size: 90,
232
+ source: '',
233
+ boot_order: -1,
234
+ },
235
+ ])
236
+ watch(
237
+ () => props.hardDisks,
238
+ (newValue) => {
239
+ if (!props.isEdit || !newValue) return
240
+
241
+ const count = newValue?.length || 0
242
+ hardDisksIndex.value = [...Array(count).keys()]
243
+ hardDisksType.value = Array(count).fill('edit')
244
+ hardDisks.value = newValue
245
+ },
246
+ { immediate: true }
247
+ )
248
+
249
+ const addHardDisk = (
250
+ create = true,
251
+ size = 90,
252
+ source = '',
253
+ type: UI_T_HardDiskType = 'new'
254
+ ): void => {
255
+ const newIndex = (hardDisksIndex.value.at(-1) ?? -1) + 1
256
+ hardDisksIndex.value.push(newIndex)
257
+ hardDisksType.value.push(type)
258
+
259
+ hardDisks.value.push({ create, size, source, attach: true, boot_order: -1 })
260
+ sendData()
261
+ }
262
+ const onAddExistHardDisk = (hardDisk: UI_I_HardDisk): void => {
263
+ addHardDisk(false, $binary.bToGb(hardDisk.size), hardDisk.path, 'exist')
264
+ }
265
+ const onRemoveHardDisk = (
266
+ index: number,
267
+ hardDisk: UI_I_SendDataNewHardDisk
268
+ ): void => {
269
+ const removeIndex = hardDisksIndex.value.indexOf(index)
270
+
271
+ if (!hardDisk.create && !hardDisk.attach) {
272
+ hardDisksType.value = hardDisksType.value.map((item, key) => {
273
+ if (key === removeIndex) return 'removed'
274
+ return item
275
+ })
276
+ sendData()
277
+ return
278
+ }
279
+
280
+ hardDisksIndex.value = hardDisksIndex.value.filter((item) => item !== index)
281
+ hardDisksType.value = hardDisksType.value.filter(
282
+ (_item, key) => key !== removeIndex
283
+ )
284
+
285
+ hardDisks.value = hardDisks.value.filter((_hardDisk, key: number) => {
286
+ return removeIndex !== key
287
+ })
288
+
289
+ delete newHardDiskInvalidKeys.value[index]
290
+ delete sendDataNewHardDisk.value[index]
291
+ sendData()
292
+ }
293
+ const onRollBackHardDisk = (index: number): void => {
294
+ const removeIndex = hardDisksIndex.value.indexOf(index)
295
+ hardDisksType.value = hardDisksType.value.map((item, key) => {
296
+ if (key === removeIndex) return 'edit'
297
+ return item
298
+ })
299
+ }
300
+
301
+ const defaultNetwork = {
302
+ network: '',
303
+ net_bridge: '',
304
+ mac: '',
305
+ target: '',
306
+ model: '',
307
+ boot_order: -1,
308
+ }
309
+ const networks = ref<UI_I_SendDataNewNetwork[]>([useDeepCopy(defaultNetwork)])
310
+ const networksType = ref<UI_T_NetworkType[]>(['new'])
311
+ const networksIndex = ref<number[]>([0])
312
+ watch(
313
+ () => props.networks,
314
+ (newValue) => {
315
+ if (!props.isEdit || !newValue) return
316
+
317
+ // networks.value = newValue
318
+ // networksType.value = Array(newValue.length).fill('edit')
319
+ const count = newValue?.length || 0
320
+ networksIndex.value = [...Array(count).keys()]
321
+ networksType.value = Array(count).fill('edit')
322
+ networks.value = newValue
323
+ },
324
+ { immediate: true }
325
+ )
326
+ const addNetwork = (): void => {
327
+ const index = (networksIndex.value.at(-1) || 0) + 1
328
+ networksIndex.value.push(index)
329
+ networksType.value.push('new')
330
+
331
+ networks.value.push(useDeepCopy(defaultNetwork))
332
+ }
333
+ const onRemoveNetwork = (index: number): void => {
334
+ const removeIndex = networksIndex.value.indexOf(index)
335
+ networksIndex.value = networksIndex.value.filter((item) => item !== index)
336
+ networksType.value = networksType.value.filter(
337
+ (_item, key) => key !== removeIndex
338
+ )
339
+ networks.value = networks.value.filter(
340
+ (_network, key: number) => removeIndex !== key
341
+ )
342
+
343
+ delete newNetworkInvalidKeys.value[index]
344
+ delete sendDataNewNetwork.value[index]
345
+ sendData()
346
+ }
347
+
348
+ const defaultCdDvdDriver: UI_I_SendDataNewCdDvdDrive = {
349
+ create: false,
350
+ attach: false,
351
+ source: '',
352
+ bus: '',
353
+ device_type: 'cdrom',
354
+ boot_order: -1,
355
+ }
356
+ const cdDvdDrives = ref<UI_I_SendDataNewCdDvdDrive[]>([
357
+ useDeepCopy(defaultCdDvdDriver),
358
+ ])
359
+ const cdDvdDrivesIndex = ref<number[]>([0])
360
+ const cdDvdDrivesType = ref<UI_T_CdDvdType[]>(['new'])
361
+ watch(
362
+ () => props.cdDvdDrives,
363
+ (newValue) => {
364
+ if (!props.isEdit || !newValue) return
365
+
366
+ // cdDvdDrives.value = newValue
367
+ // cdDvdDrivesType.value = Array(newValue.length).fill('edit')
368
+ const count = newValue?.length || 0
369
+ cdDvdDrivesIndex.value = [...Array(count).keys()]
370
+ cdDvdDrivesType.value = Array(count).fill('edit')
371
+ cdDvdDrives.value = newValue
372
+ },
373
+ { immediate: true }
374
+ )
375
+ const addCdDvdDrive = (): void => {
376
+ const value = (cdDvdDrivesIndex.value.at(-1) || 0) + 1
377
+ cdDvdDrivesIndex.value.push(value)
378
+ cdDvdDrivesType.value.push('new')
379
+ cdDvdDrives.value.push({
380
+ ...useDeepCopy(defaultCdDvdDriver),
381
+ attach: true,
382
+ })
383
+ }
384
+ const onRemoveCdDvdDrive = (
385
+ index: number,
386
+ cdDvdDrive: UI_I_SendDataNewCdDvdDrive
387
+ ): void => {
388
+ const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
389
+
390
+ // if (!cdDvdDrive.create && !cdDvdDrive.attach) {
391
+ if (cdDvdDrivesType.value[index] === 'edit' && !cdDvdDrive.attach) {
392
+ cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
393
+ if (key === removeIndex) return 'removed'
394
+ return item
395
+ })
396
+ sendData()
397
+ return
398
+ }
399
+
400
+ cdDvdDrivesIndex.value = cdDvdDrivesIndex.value.filter(
401
+ (cdDvdDrive) => cdDvdDrive !== index
402
+ )
403
+ cdDvdDrivesType.value = cdDvdDrivesType.value.filter(
404
+ (_item, key) => key !== index
405
+ )
406
+ cdDvdDrives.value = cdDvdDrives.value.filter(
407
+ (_cdDvdDrive, key: number) => removeIndex !== key
408
+ )
409
+
410
+ delete sendDataNewCdDvdDrive.value[index]
411
+ sendData()
412
+ }
413
+ const onRollBackCdDvdDrive = (index: number): void => {
414
+ const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
415
+ cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
416
+ if (key === removeIndex) return 'edit'
417
+ return item
418
+ })
419
+ }
420
+
421
+ const defaultPciDevice: UI_I_PciDevice = {
422
+ id: '',
423
+ vendor_name: '',
424
+ class_name: 'cdrom',
425
+ device_name: 'cdrom',
426
+ }
427
+ const pciDevicesIndex = ref<number[]>([0])
428
+ const pciDevicesType = ref<('new' | 'edit')[]>(['new'])
429
+ const pciDevices = ref<UI_I_PciDevice[]>([])
430
+ watch(
431
+ () => props.pciDevices,
432
+ (newValue) => {
433
+ if (!props.isEdit) return
434
+
435
+ const count = newValue?.length || 0
436
+ pciDevicesIndex.value = [...Array(count).keys()]
437
+ pciDevicesType.value = Array(count).fill('edit')
438
+ pciDevices.value = newValue || []
439
+ },
440
+ { immediate: true }
441
+ )
442
+
443
+ const addPciDevice = (): void => {
444
+ const newIndex = (pciDevicesIndex.value.at(-1) ?? -1) + 1
445
+ pciDevicesIndex.value.push(newIndex)
446
+ pciDevicesType.value.push('new')
447
+
448
+ pciDevices.value.push(useDeepCopy(defaultPciDevice))
449
+ }
450
+ const onRemovePciDevice = (index: number): void => {
451
+ const removeIndex = pciDevicesIndex.value.indexOf(index)
452
+ pciDevicesIndex.value = pciDevicesIndex.value.filter((item) => item !== index)
453
+ pciDevicesType.value = pciDevicesType.value.filter(
454
+ (_item, key) => key !== removeIndex
455
+ )
456
+
457
+ pciDevices.value = pciDevices.value.filter((_pciDevice, key: number) => {
458
+ return removeIndex !== key
459
+ })
460
+
461
+ delete newPciDeviceInvalidKeys.value[index]
462
+ delete sendDataNewPciDevices.value[index]
463
+ sendData()
464
+ }
465
+
466
+ const isShowFileModal = ref<boolean>(false)
467
+ const onAddDevice = (item: UI_I_DropdownTreeItemChild): void => {
468
+ switch (item.value) {
469
+ case 1:
470
+ addHardDisk()
471
+ break
472
+ case 2:
473
+ isShowFileModal.value = true
474
+ break
475
+ case 5:
476
+ addCdDvdDrive()
477
+ break
478
+ case 10:
479
+ addPciDevice()
480
+ break
481
+ case 14:
482
+ addNetwork()
483
+ break
484
+ }
485
+ }
486
+
487
+ const cpuInvalid = ref<boolean>(false)
488
+ const sendDataCpu = ref<UI_I_SendDataCpu | null>(null)
489
+ const onSendDataCpuMethod = (data: UI_I_SendDataCpu): void => {
490
+ sendDataCpu.value = data
491
+ sendData()
492
+ }
493
+ const sendDataMemory = ref<UI_I_SendDataMemory | null>(null)
494
+ const onSendDataMemoryMethod = (data: UI_I_SendDataMemory): void => {
495
+ sendDataMemory.value = data
496
+ sendData()
497
+ }
498
+ const sendDataNewHardDisk = ref<UI_I_SendDataNewHardDisk[]>([])
499
+ const onSendDataNewHardDiskMethod = (
500
+ data: UI_I_SendDataNewHardDisk,
501
+ index: number
502
+ ): void => {
503
+ sendDataNewHardDisk.value[index] = data
504
+ sendData()
505
+ }
506
+ const sendDataNewNetwork = ref<UI_I_SendDataNewNetwork[]>([])
507
+ const sendDataNewNetworkMethod = (
508
+ data: UI_I_SendDataNewNetwork,
509
+ index: number
510
+ ): void => {
511
+ sendDataNewNetwork.value[index] = data
512
+ sendData()
513
+ }
514
+ const sendDataNewCdDvdDrive = ref<UI_I_SendDataNewCdDvdDrive[]>([])
515
+ const sendDataNewCdDvdDriveMethod = (
516
+ data: UI_I_SendDataNewCdDvdDrive,
517
+ index: number
518
+ ): void => {
519
+ sendDataNewCdDvdDrive.value[index] = data
520
+ sendData()
521
+ }
522
+ const sendDataNewUsbController = ref<string | null>(null)
523
+ const onSendDataNewUsbControllerMethod = (data: string): void => {
524
+ sendDataNewUsbController.value = data
525
+ sendData()
526
+ }
527
+ const sendDataNewPciDevices = ref<UI_I_SendDataNewPciDevice[]>([])
528
+ const onSendDataPciDevicesMethod = (
529
+ data: UI_I_SendDataNewPciDevice,
530
+ index: number
531
+ ): void => {
532
+ sendDataNewPciDevices.value[index] = data
533
+ sendData()
534
+ }
535
+ const sendDataVideoCard = ref<UI_I_SendDataVideoCard | null>(null)
536
+ const onSendDataVideoCardMethod = (data: UI_I_SendDataVideoCard): void => {
537
+ sendDataVideoCard.value = data
538
+ sendData()
539
+ }
540
+
541
+ const sendData = (): void => {
542
+ const cpu = sendDataCpu.value
543
+ const memory = sendDataMemory.value
544
+ const hardDisks = sendDataNewHardDisk.value.flat(2)
545
+ const networks = sendDataNewNetwork.value.flat(2)
546
+ const cdDvdDrives = sendDataNewCdDvdDrive.value.flat(2)
547
+ const pciDevices = sendDataNewPciDevices.value.flat()
548
+ const usbController = sendDataNewUsbController.value
549
+ const videoCard = sendDataVideoCard.value
550
+
551
+ const sendData: UI_I_SendDataVirtualHardware = {
552
+ cpu,
553
+ memory,
554
+ usbController,
555
+ pciDevices,
556
+ networks,
557
+ hardDisks,
558
+ cdDvdDrives,
559
+ videoCard,
560
+ }
561
+ emits('send-data', sendData)
562
+ }
563
+
564
+ const onSetInvalidHardDisk = (invalid: boolean, index: number): void => {
565
+ newHardDiskInvalidKeys.value[index] = invalid
566
+ }
567
+
568
+ const onSetInvalidNetwork = (invalid: boolean, key: number): void => {
569
+ newNetworkInvalidKeys.value[key] = invalid
570
+ }
571
+
572
+ const onSetInvalidPciDevice = (invalid: boolean, key: number): void => {
573
+ newPciDeviceInvalidKeys.value[key] = invalid
574
+ }
575
+
576
+ const memoryInvalid = ref<boolean>(false)
577
+ const videoCardInvalid = ref<boolean>(false)
578
+ const newHardDiskInvalidKeys = ref<UI_I_InvalidKeys>({})
579
+ const newNetworkInvalidKeys = ref<UI_I_InvalidKeys>({})
580
+ const newPciDeviceInvalidKeys = ref<UI_I_InvalidKeys>({})
581
+
582
+ watch(
583
+ [
584
+ cpuInvalid,
585
+ memoryInvalid,
586
+ newHardDiskInvalidKeys,
587
+ newNetworkInvalidKeys,
588
+ newPciDeviceInvalidKeys,
589
+ videoCardInvalid,
590
+ ],
591
+ () => {
592
+ const cpu = cpuInvalid.value ? localization.value.cpu : ''
593
+ const memory = memoryInvalid.value ? localization.value.memory : ''
594
+ const videoCard = videoCardInvalid.value ? localization.value.videoCard : ''
595
+ let newHardDisk = ''
596
+ Object.keys(newHardDiskInvalidKeys.value).forEach((key) => {
597
+ if (!newHardDiskInvalidKeys.value[+key]) {
598
+ return
599
+ }
600
+
601
+ newHardDisk +=
602
+ (newHardDisk ? ', ' : '') +
603
+ localization.value.newHardDisk +
604
+ ' ' +
605
+ (+key + 1)
606
+ })
607
+ let newNetwork = ''
608
+ Object.keys(newNetworkInvalidKeys.value).forEach((key) => {
609
+ if (!newNetworkInvalidKeys.value[+key]) {
610
+ return
611
+ }
612
+
613
+ newNetwork +=
614
+ (newNetwork ? ', ' : '') +
615
+ localization.value.newNetwork +
616
+ ' ' +
617
+ (+key + 1)
618
+ })
619
+ // let pciDevice = ''
620
+ // Object.keys(newPciDeviceInvalidKeys.value).forEach((key) => {
621
+ // if (!newPciDeviceInvalidKeys.value[+key]) {
622
+ // return
623
+ // }
624
+ //
625
+ // pciDevice +=
626
+ // (pciDevice ? ', ' : '') +
627
+ // localization.value.pciDevice +
628
+ // ' ' +
629
+ // (+key + 1)
630
+ // })
631
+
632
+ emits('invalid', [cpu, memory, newHardDisk, newNetwork, videoCard])
633
+ },
634
+ { deep: true }
635
+ )
636
+
637
+ emits('get-pci-devices')
638
+ </script>
639
+
640
+ <style scoped lang="scss">
641
+ .virtual-hardware {
642
+ .content-dropdown {
643
+ width: 200px;
644
+ }
645
+ }
646
+ </style>