bfg-common 1.1.56 → 1.1.57

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.
@@ -1,631 +1,638 @@
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
- @remove="onRemoveNetwork(networksIndex[key])"
62
- @send-data="sendDataNewNetworkMethod($event, networksIndex[key])"
63
- @invalid="onSetInvalidNetwork($event, networksIndex[key])"
64
- @remove-error-by-title="emits('remove-error-by-title', $event)"
65
- @get-networks-table="emits('get-networks-table', $event)"
66
- />
67
- <common-vm-actions-add-customize-hardware-virtual-hardware-cd-dvd-drive
68
- v-for="(item, key) in cdDvdDrives"
69
- :key="cdDvdDrivesIndex[key]"
70
- :index="cdDvdDrivesIndex[key]"
71
- :hard-disks-count="hardDisks.length"
72
- :type="cdDvdDrivesType[key]"
73
- :cd-dvd-drive="item"
74
- :nodes="props.nodes"
75
- :files="props.files"
76
- :error-validation-fields="props.errorValidationFields"
77
- :is-edit="props.isEdit"
78
- :state="props.state"
79
- @remove-error-by-title="emits('remove-error-by-title', $event)"
80
- @get-storage="emits('get-storage', $event)"
81
- @get-folders-or-files="emits('get-folders-or-files', $event)"
82
- @get-active-device-child="emits('get-active-device-child', $event)"
83
- @show-datastore-child="emits('show-datastore-child', $event)"
84
- @remove="onRemoveCdDvdDrive(cdDvdDrivesIndex[key], item)"
85
- @roll-back="onRollBackCdDvdDrive(cdDvdDrivesIndex[key])"
86
- @send-data="
87
- sendDataNewCdDvdDriveMethod($event, cdDvdDrivesIndex[key])
88
- "
89
- />
90
- <common-vm-actions-add-customize-hardware-virtual-hardware-new-usb-controller
91
- :usb-controller="props.usbController"
92
- :is-edit="props.isEdit"
93
- @send-data="onSendDataNewUsbControllerMethod"
94
- />
95
- <template v-if="props.passthroughDevices">
96
- <common-vm-actions-add-customize-hardware-virtual-hardware-new-pci-device
97
- v-for="(item, key) in pciDevices"
98
- :key="pciDevicesIndex[key]"
99
- :index="pciDevicesIndex[key]"
100
- :pci-device="item"
101
- :error-validation-fields="props.errorValidationFields"
102
- :passthrough-devices="props.passthroughDevices"
103
- :type="pciDevicesType[key]"
104
- @remove="onRemovePciDevice(pciDevicesIndex[key])"
105
- @send-data="
106
- onSendDataPciDevicesMethod($event, pciDevicesIndex[key])
107
- "
108
- @invalid="onSetInvalidPciDevice($event, pciDevicesIndex[key])"
109
- @remove-error-by-title="emits('remove-error-by-title', $event)"
110
- />
111
- </template>
112
- <common-vm-actions-add-customize-hardware-virtual-hardware-video-card
113
- :is-edit="props.isEdit"
114
- :video-card="props.videoCard"
115
- :error-validation-fields="props.errorValidationFields"
116
- @send-data="onSendDataVideoCardMethod"
117
- @invalid="videoCardInvalid = $event"
118
- @remove-error-by-title="emits('remove-error-by-title', $event)"
119
- />
120
- <common-vm-actions-add-customize-hardware-virtual-hardware-other />
121
- </div>
122
- </div>
123
-
124
- <Teleport to="body">
125
- <common-vm-actions-add-customize-hardware-virtual-hardware-browse-view
126
- v-if="isShowFileModal"
127
- :show="isShowFileModal"
128
- :nodes="props.nodes"
129
- :files="props.files"
130
- @submit="onAddExistHardDisk"
131
- @get-storage="emits('get-storage', $event)"
132
- @get-folders-or-files="emits('get-folders-or-files', $event)"
133
- @get-active-device-child="emits('get-active-device-child', $event)"
134
- @show-datastore-child="emits('show-datastore-child', $event)"
135
- @hide="isShowFileModal = false"
136
- />
137
- </Teleport>
138
- </div>
139
- </template>
140
-
141
- <script setup lang="ts">
142
- import { UI_I_DatastoreTableItem } from '~/models/store/storage/interfaces'
143
- import { UI_I_NetworkTableItem } from '~/models/store/network/interfaces'
144
- import { UI_I_TablePayload } from '~/models/store/interfaces'
145
- import { UI_I_FolderOrFileTreePayload } from '~/models/store/storage/interfaces'
146
- import { UI_I_FileTreeNode } from '~/components/models/interfaces'
147
- import {
148
- UI_I_SendDataCpu,
149
- UI_I_SendDataMemory,
150
- UI_I_SendDataNewHardDisk,
151
- UI_I_SendDataNewNetwork,
152
- UI_I_SendDataVideoCard,
153
- UI_I_InvalidKeys,
154
- UI_I_SendDataVirtualHardware,
155
- UI_I_SendDataNewCdDvdDrive,
156
- UI_I_HardDisk,
157
- UI_I_PciDevice,
158
- UI_I_SendDataNewPciDevice,
159
- } from '~/components/common/vm/actions/add/customizeHardware/virtualHardware/models/interfaces'
160
- import { UI_I_ErrorValidationField } from '~/models/store/interfaces'
161
- import {
162
- UI_T_HardDiskType,
163
- UI_T_NetworkType,
164
- UI_T_CdDvdType,
165
- } from '~/components/common/vm/actions/add/customizeHardware/virtualHardware/models/types'
166
- import { UI_I_OptionItem } from '~/components/atoms/models/interfaces'
167
- import {
168
- UI_I_DropdownTreeItem,
169
- UI_I_DropdownTreeItemChild,
170
- } from '~/components/atoms/dropdown/tree/models/interfaces'
171
- import { UI_I_Localization } from '~/models/interfaces'
172
- import { UI_I_ConfigurePciDevicesTable } from '~/models/store/host/interfaces'
173
- import {
174
- API_UI_I_VmEditCpu,
175
- API_UI_I_VmEditMemory,
176
- } from '~/models/store/vm/interfaces'
177
- import { dropdownItemsFunc } from './config/dropdownItems'
178
-
179
- const props = defineProps<{
180
- storage: UI_I_DatastoreTableItem | null
181
- cpuModels: UI_I_OptionItem[]
182
- vmName: string
183
- maxCpus: number
184
- maxMemory: number
185
- isEdit: boolean
186
- errorValidationFields: UI_I_ErrorValidationField<string>[]
187
- nodes: UI_I_FileTreeNode[]
188
- files: UI_I_FileTreeNode[]
189
- networksTable: UI_I_NetworkTableItem[]
190
- getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
191
- datastore: UI_I_DatastoreTableItem[]
192
- state?: string
193
- cpu?: API_UI_I_VmEditCpu
194
- memory?: API_UI_I_VmEditMemory
195
- vmCpuHelpTextSecond?: string
196
- hardDisks?: UI_I_SendDataNewHardDisk[] | null
197
- cdDvdDrives?: UI_I_SendDataNewCdDvdDrive[] | null
198
- networks?: UI_I_SendDataNewNetwork[] | null
199
- videoCard?: UI_I_SendDataVideoCard
200
- usbController?: string
201
- pciDevices?: UI_I_PciDevice[]
202
- passthroughDevices?: UI_I_ConfigurePciDevicesTable | null
203
- }>()
204
- const emits = defineEmits<{
205
- (event: 'send-data', value: UI_I_SendDataVirtualHardware): void
206
- (event: 'invalid', value: string[]): void
207
- (event: 'get-storage', value: UI_I_TablePayload): void
208
- (event: 'get-folders-or-files', value: UI_I_FolderOrFileTreePayload): void
209
- (event: 'get-active-device-child', value: UI_I_FileTreeNode): void
210
- (event: 'show-datastore-child', value: UI_I_FileTreeNode): void
211
- (event: 'remove-error-by-title', value: string): void
212
- (event: 'get-networks-table', value: UI_I_TablePayload): void
213
- (event: 'get-pci-devices'): void
214
- }>()
215
-
216
- const localization = computed<UI_I_Localization>(() => useLocal())
217
- const { $binary } = useNuxtApp()
218
-
219
- const dropdownItems = computed<UI_I_DropdownTreeItem[]>(() =>
220
- dropdownItemsFunc(localization.value)
221
- )
222
-
223
- const hardDisksIndex = ref<number[]>([0])
224
- const hardDisksType = ref<UI_T_HardDiskType[]>(['new'])
225
- const hardDisks = ref<UI_I_SendDataNewHardDisk[]>([
226
- {
227
- create: true,
228
- size: 90,
229
- source: '',
230
- },
231
- ])
232
- watch(
233
- () => props.hardDisks,
234
- (newValue) => {
235
- if (!props.isEdit || !newValue) return
236
-
237
- const count = newValue?.length || 0
238
- hardDisksIndex.value = [...Array(count).keys()]
239
- hardDisksType.value = Array(count).fill('edit')
240
- hardDisks.value = newValue
241
- },
242
- { immediate: true }
243
- )
244
-
245
- const addHardDisk = (
246
- create = true,
247
- size = 90,
248
- source = '',
249
- type: UI_T_HardDiskType = 'new'
250
- ): void => {
251
- const newIndex = (hardDisksIndex.value.at(-1) ?? -1) + 1
252
- hardDisksIndex.value.push(newIndex)
253
- hardDisksType.value.push(type)
254
-
255
- hardDisks.value.push({ create, size, source, attach: props.isEdit })
256
- sendData()
257
- }
258
- const onAddExistHardDisk = (hardDisk: UI_I_HardDisk): void => {
259
- addHardDisk(false, $binary.bToGb(hardDisk.size), hardDisk.path, 'exist')
260
- }
261
- const onRemoveHardDisk = (index: number, hardDisk: UI_I_SendDataNewHardDisk): void => {
262
- const removeIndex = hardDisksIndex.value.indexOf(index)
263
-
264
- if (!hardDisk.create && !hardDisk.attach) {
265
- hardDisksType.value = hardDisksType.value.map((item, key) => {
266
- if (key === removeIndex) return 'removed'
267
- return item
268
- })
269
- sendData()
270
- return
271
- }
272
-
273
- hardDisksIndex.value = hardDisksIndex.value.filter((item) => item !== index)
274
- hardDisksType.value = hardDisksType.value.filter(
275
- (_item, key) => key !== removeIndex
276
- )
277
-
278
- hardDisks.value = hardDisks.value.filter((_hardDisk, key: number) => {
279
- return removeIndex !== key
280
- })
281
-
282
- delete newHardDiskInvalidKeys.value[index]
283
- delete sendDataNewHardDisk.value[index]
284
- sendData()
285
- }
286
- const onRollBackHardDisk = (index: number): void => {
287
- const removeIndex = hardDisksIndex.value.indexOf(index)
288
- hardDisksType.value = hardDisksType.value.map((item, key) => {
289
- if (key === removeIndex) return 'edit'
290
- return item
291
- })
292
- }
293
-
294
- const defaultNetwork = {
295
- network: '',
296
- net_bridge: '',
297
- mac: '',
298
- target: '',
299
- model: '',
300
- boot_order: -1,
301
- }
302
- const networks = ref<UI_I_SendDataNewNetwork[]>([useDeepCopy(defaultNetwork)])
303
- const networksType = ref<UI_T_NetworkType[]>(['new'])
304
- const networksIndex = ref<number[]>([0])
305
- watch(
306
- () => props.networks,
307
- (newValue) => {
308
- if (!props.isEdit || !newValue) return
309
-
310
- // networks.value = newValue
311
- // networksType.value = Array(newValue.length).fill('edit')
312
- const count = newValue?.length || 0
313
- networksIndex.value = [...Array(count).keys()]
314
- networksType.value = Array(count).fill('edit')
315
- networks.value = newValue
316
- },
317
- { immediate: true }
318
- )
319
- const addNetwork = (): void => {
320
- const index = (networksIndex.value.at(-1) || 0) + 1
321
- networksIndex.value.push(index)
322
- networksType.value.push('new')
323
-
324
- networks.value.push(useDeepCopy(defaultNetwork))
325
- }
326
- const onRemoveNetwork = (index: number): void => {
327
- const removeIndex = networksIndex.value.indexOf(index)
328
- networksIndex.value = networksIndex.value.filter((item) => item !== index)
329
- networksType.value = networksType.value.filter(
330
- (_item, key) => key !== removeIndex
331
- )
332
- networks.value = networks.value.filter(
333
- (_network, key: number) => removeIndex !== key
334
- )
335
-
336
- delete newNetworkInvalidKeys.value[index]
337
- delete sendDataNewNetwork.value[index]
338
- sendData()
339
- }
340
-
341
- const defaultCdDvdDriver: UI_I_SendDataNewCdDvdDrive = {
342
- create: true,
343
- source: '',
344
- bus: '',
345
- device_type: 'cdrom',
346
- boot_order: -1,
347
- }
348
- const cdDvdDrives = ref<UI_I_SendDataNewCdDvdDrive[]>([
349
- useDeepCopy(defaultCdDvdDriver),
350
- ])
351
- const cdDvdDrivesIndex = ref<number[]>([0])
352
- const cdDvdDrivesType = ref<UI_T_CdDvdType[]>(['new'])
353
- watch(
354
- () => props.cdDvdDrives,
355
- (newValue) => {
356
- if (!props.isEdit || !newValue) return
357
-
358
- // cdDvdDrives.value = newValue
359
- // cdDvdDrivesType.value = Array(newValue.length).fill('edit')
360
- const count = newValue?.length || 0
361
- cdDvdDrivesIndex.value = [...Array(count).keys()]
362
- cdDvdDrivesType.value = Array(count).fill('edit')
363
- cdDvdDrives.value = newValue
364
- },
365
- { immediate: true }
366
- )
367
- const addCdDvdDrive = (): void => {
368
- const value = (cdDvdDrivesIndex.value.at(-1) || 0) + 1
369
- cdDvdDrivesIndex.value.push(value)
370
- cdDvdDrivesType.value.push('new')
371
- cdDvdDrives.value.push(useDeepCopy(defaultCdDvdDriver))
372
- }
373
- const onRemoveCdDvdDrive = (index: number, cdDvdDrive: UI_I_SendDataNewCdDvdDrive): void => {
374
- const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
375
-
376
- if (!cdDvdDrive.create && !cdDvdDrive.attach) {
377
- cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
378
- if (key === removeIndex) return 'removed'
379
- return item
380
- })
381
- sendData()
382
- return
383
- }
384
-
385
- cdDvdDrivesIndex.value = cdDvdDrivesIndex.value.filter(
386
- (cdDvdDrive) => cdDvdDrive !== index
387
- )
388
- cdDvdDrivesType.value = cdDvdDrivesType.value.filter(
389
- (_item, key) => key !== index
390
- )
391
- cdDvdDrives.value = cdDvdDrives.value.filter(
392
- (_cdDvdDrive, key: number) => removeIndex !== key
393
- )
394
-
395
- delete sendDataNewCdDvdDrive.value[index]
396
- sendData()
397
- }
398
- const onRollBackCdDvdDrive = (index: number): void => {
399
- const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
400
- cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
401
- if (key === removeIndex) return 'edit'
402
- return item
403
- })
404
- }
405
-
406
- const defaultPciDevice: UI_I_PciDevice = {
407
- id: '',
408
- vendor_name: '',
409
- class_name: 'cdrom',
410
- device_name: 'cdrom',
411
- }
412
- const pciDevicesIndex = ref<number[]>([0])
413
- const pciDevicesType = ref<('new' | 'edit')[]>(['new'])
414
- const pciDevices = ref<UI_I_PciDevice[]>([])
415
- watch(
416
- () => props.pciDevices,
417
- (newValue) => {
418
- if (!props.isEdit) return
419
-
420
- const count = newValue?.length || 0
421
- pciDevicesIndex.value = [...Array(count).keys()]
422
- pciDevicesType.value = Array(count).fill('edit')
423
- pciDevices.value = newValue || []
424
- },
425
- { immediate: true }
426
- )
427
-
428
- const addPciDevice = (): void => {
429
- const newIndex = (pciDevicesIndex.value.at(-1) ?? -1) + 1
430
- pciDevicesIndex.value.push(newIndex)
431
- pciDevicesType.value.push('new')
432
-
433
- pciDevices.value.push(useDeepCopy(defaultPciDevice))
434
- }
435
- const onRemovePciDevice = (index: number): void => {
436
- const removeIndex = pciDevicesIndex.value.indexOf(index)
437
- pciDevicesIndex.value = pciDevicesIndex.value.filter((item) => item !== index)
438
- pciDevicesType.value = pciDevicesType.value.filter(
439
- (_item, key) => key !== removeIndex
440
- )
441
-
442
- pciDevices.value = pciDevices.value.filter((_pciDevice, key: number) => {
443
- return removeIndex !== key
444
- })
445
-
446
- delete newPciDeviceInvalidKeys.value[index]
447
- delete sendDataNewPciDevices.value[index]
448
- sendData()
449
- }
450
-
451
- const isShowFileModal = ref<boolean>(false)
452
- const onAddDevice = (item: UI_I_DropdownTreeItemChild): void => {
453
- switch (item.value) {
454
- case 1:
455
- addHardDisk()
456
- break
457
- case 2:
458
- isShowFileModal.value = true
459
- break
460
- case 5:
461
- addCdDvdDrive()
462
- break
463
- case 10:
464
- addPciDevice()
465
- break
466
- case 14:
467
- addNetwork()
468
- break
469
- }
470
- }
471
-
472
- const cpuInvalid = ref<boolean>(false)
473
- const sendDataCpu = ref<UI_I_SendDataCpu | null>(null)
474
- const onSendDataCpuMethod = (data: UI_I_SendDataCpu): void => {
475
- sendDataCpu.value = data
476
- sendData()
477
- }
478
- const sendDataMemory = ref<UI_I_SendDataMemory | null>(null)
479
- const onSendDataMemoryMethod = (data: UI_I_SendDataMemory): void => {
480
- sendDataMemory.value = data
481
- sendData()
482
- }
483
- const sendDataNewHardDisk = ref<UI_I_SendDataNewHardDisk[]>([])
484
- const onSendDataNewHardDiskMethod = (
485
- data: UI_I_SendDataNewHardDisk,
486
- index: number
487
- ): void => {
488
- sendDataNewHardDisk.value[index] = data
489
- sendData()
490
- }
491
- const sendDataNewNetwork = ref<UI_I_SendDataNewNetwork[]>([])
492
- const sendDataNewNetworkMethod = (
493
- data: UI_I_SendDataNewNetwork,
494
- index: number
495
- ): void => {
496
- sendDataNewNetwork.value[index] = data
497
- sendData()
498
- }
499
- const sendDataNewCdDvdDrive = ref<UI_I_SendDataNewCdDvdDrive[]>([])
500
- const sendDataNewCdDvdDriveMethod = (
501
- data: UI_I_SendDataNewCdDvdDrive,
502
- index: number
503
- ): void => {
504
- sendDataNewCdDvdDrive.value[index] = data
505
- sendData()
506
- }
507
- const sendDataNewUsbController = ref<string | null>(null)
508
- const onSendDataNewUsbControllerMethod = (data: string): void => {
509
- sendDataNewUsbController.value = data
510
- sendData()
511
- }
512
- const sendDataNewPciDevices = ref<UI_I_SendDataNewPciDevice[]>([])
513
- const onSendDataPciDevicesMethod = (
514
- data: UI_I_SendDataNewPciDevice,
515
- index: number
516
- ): void => {
517
- sendDataNewPciDevices.value[index] = data
518
- sendData()
519
- }
520
- const sendDataVideoCard = ref<UI_I_SendDataVideoCard | null>(null)
521
- const onSendDataVideoCardMethod = (data: UI_I_SendDataVideoCard): void => {
522
- sendDataVideoCard.value = data
523
- sendData()
524
- }
525
-
526
- const sendData = (): void => {
527
- const cpu = sendDataCpu.value
528
- const memory = sendDataMemory.value
529
- const hardDisks = sendDataNewHardDisk.value.flat(2)
530
- const networks = sendDataNewNetwork.value.flat(2)
531
- const cdDvdDrives = sendDataNewCdDvdDrive.value.flat(2)
532
- const pciDevices = sendDataNewPciDevices.value.flat()
533
- const usbController = sendDataNewUsbController.value
534
- const videoCard = sendDataVideoCard.value
535
-
536
- const sendData: UI_I_SendDataVirtualHardware = {
537
- cpu,
538
- memory,
539
- usbController,
540
- pciDevices,
541
- networks,
542
- hardDisks,
543
- cdDvdDrives,
544
- videoCard,
545
- }
546
- emits('send-data', sendData)
547
- }
548
-
549
- const onSetInvalidHardDisk = (invalid: boolean, index: number): void => {
550
- newHardDiskInvalidKeys.value[index] = invalid
551
- }
552
-
553
- const onSetInvalidNetwork = (invalid: boolean, key: number): void => {
554
- newNetworkInvalidKeys.value[key] = invalid
555
- }
556
-
557
- const onSetInvalidPciDevice = (invalid: boolean, key: number): void => {
558
- newPciDeviceInvalidKeys.value[key] = invalid
559
- }
560
-
561
- const memoryInvalid = ref<boolean>(false)
562
- const videoCardInvalid = ref<boolean>(false)
563
- const newHardDiskInvalidKeys = ref<UI_I_InvalidKeys>({})
564
- const newNetworkInvalidKeys = ref<UI_I_InvalidKeys>({})
565
- const newPciDeviceInvalidKeys = ref<UI_I_InvalidKeys>({})
566
-
567
- watch(
568
- [
569
- cpuInvalid,
570
- memoryInvalid,
571
- newHardDiskInvalidKeys,
572
- newNetworkInvalidKeys,
573
- newPciDeviceInvalidKeys,
574
- videoCardInvalid,
575
- ],
576
- () => {
577
- const cpu = cpuInvalid.value ? localization.value.cpu : ''
578
- const memory = memoryInvalid.value ? localization.value.memory : ''
579
- const videoCard = videoCardInvalid.value ? localization.value.videoCard : ''
580
- let newHardDisk = ''
581
- Object.keys(newHardDiskInvalidKeys.value).forEach((key) => {
582
- if (!newHardDiskInvalidKeys.value[+key]) {
583
- return
584
- }
585
-
586
- newHardDisk +=
587
- (newHardDisk ? ', ' : '') +
588
- localization.value.newHardDisk +
589
- ' ' +
590
- (+key + 1)
591
- })
592
- let newNetwork = ''
593
- Object.keys(newNetworkInvalidKeys.value).forEach((key) => {
594
- if (!newNetworkInvalidKeys.value[+key]) {
595
- return
596
- }
597
-
598
- newNetwork +=
599
- (newNetwork ? ', ' : '') +
600
- localization.value.newNetwork +
601
- ' ' +
602
- (+key + 1)
603
- })
604
- // let pciDevice = ''
605
- // Object.keys(newPciDeviceInvalidKeys.value).forEach((key) => {
606
- // if (!newPciDeviceInvalidKeys.value[+key]) {
607
- // return
608
- // }
609
- //
610
- // pciDevice +=
611
- // (pciDevice ? ', ' : '') +
612
- // localization.value.pciDevice +
613
- // ' ' +
614
- // (+key + 1)
615
- // })
616
-
617
- emits('invalid', [cpu, memory, newHardDisk, newNetwork, videoCard])
618
- },
619
- { deep: true }
620
- )
621
-
622
- emits('get-pci-devices')
623
- </script>
624
-
625
- <style scoped lang="scss">
626
- .virtual-hardware {
627
- .content-dropdown {
628
- width: 200px;
629
- }
630
- }
631
- </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
+ @remove="onRemoveNetwork(networksIndex[key])"
62
+ @send-data="sendDataNewNetworkMethod($event, networksIndex[key])"
63
+ @invalid="onSetInvalidNetwork($event, networksIndex[key])"
64
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
65
+ @get-networks-table="emits('get-networks-table', $event)"
66
+ />
67
+ <common-vm-actions-add-customize-hardware-virtual-hardware-cd-dvd-drive
68
+ v-for="(item, key) in cdDvdDrives"
69
+ :key="cdDvdDrivesIndex[key]"
70
+ :index="cdDvdDrivesIndex[key]"
71
+ :hard-disks-count="hardDisks.length"
72
+ :type="cdDvdDrivesType[key]"
73
+ :cd-dvd-drive="item"
74
+ :nodes="props.nodes"
75
+ :files="props.files"
76
+ :error-validation-fields="props.errorValidationFields"
77
+ :is-edit="props.isEdit"
78
+ :state="props.state"
79
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
80
+ @get-storage="emits('get-storage', $event)"
81
+ @get-folders-or-files="emits('get-folders-or-files', $event)"
82
+ @get-active-device-child="emits('get-active-device-child', $event)"
83
+ @show-datastore-child="emits('show-datastore-child', $event)"
84
+ @remove="onRemoveCdDvdDrive(cdDvdDrivesIndex[key], item)"
85
+ @roll-back="onRollBackCdDvdDrive(cdDvdDrivesIndex[key])"
86
+ @send-data="
87
+ sendDataNewCdDvdDriveMethod($event, cdDvdDrivesIndex[key])
88
+ "
89
+ />
90
+ <common-vm-actions-add-customize-hardware-virtual-hardware-new-usb-controller
91
+ :usb-controller="props.usbController"
92
+ :is-edit="props.isEdit"
93
+ @send-data="onSendDataNewUsbControllerMethod"
94
+ />
95
+ <template v-if="props.passthroughDevices">
96
+ <common-vm-actions-add-customize-hardware-virtual-hardware-new-pci-device
97
+ v-for="(item, key) in pciDevices"
98
+ :key="pciDevicesIndex[key]"
99
+ :index="pciDevicesIndex[key]"
100
+ :pci-device="item"
101
+ :error-validation-fields="props.errorValidationFields"
102
+ :passthrough-devices="props.passthroughDevices"
103
+ :type="pciDevicesType[key]"
104
+ @remove="onRemovePciDevice(pciDevicesIndex[key])"
105
+ @send-data="
106
+ onSendDataPciDevicesMethod($event, pciDevicesIndex[key])
107
+ "
108
+ @invalid="onSetInvalidPciDevice($event, pciDevicesIndex[key])"
109
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
110
+ />
111
+ </template>
112
+ <common-vm-actions-add-customize-hardware-virtual-hardware-video-card
113
+ :is-edit="props.isEdit"
114
+ :video-card="props.videoCard"
115
+ :error-validation-fields="props.errorValidationFields"
116
+ @send-data="onSendDataVideoCardMethod"
117
+ @invalid="videoCardInvalid = $event"
118
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
119
+ />
120
+ <common-vm-actions-add-customize-hardware-virtual-hardware-other />
121
+ </div>
122
+ </div>
123
+
124
+ <Teleport to="body">
125
+ <common-vm-actions-add-customize-hardware-virtual-hardware-browse-view
126
+ v-if="isShowFileModal"
127
+ :show="isShowFileModal"
128
+ :nodes="props.nodes"
129
+ :files="props.files"
130
+ @submit="onAddExistHardDisk"
131
+ @get-storage="emits('get-storage', $event)"
132
+ @get-folders-or-files="emits('get-folders-or-files', $event)"
133
+ @get-active-device-child="emits('get-active-device-child', $event)"
134
+ @show-datastore-child="emits('show-datastore-child', $event)"
135
+ @hide="isShowFileModal = false"
136
+ />
137
+ </Teleport>
138
+ </div>
139
+ </template>
140
+
141
+ <script setup lang="ts">
142
+ import { UI_I_DatastoreTableItem } from '~/models/store/storage/interfaces'
143
+ import { UI_I_NetworkTableItem } from '~/models/store/network/interfaces'
144
+ import { UI_I_TablePayload } from '~/models/store/interfaces'
145
+ import { UI_I_FolderOrFileTreePayload } from '~/models/store/storage/interfaces'
146
+ import { UI_I_FileTreeNode } from '~/components/models/interfaces'
147
+ import {
148
+ UI_I_SendDataCpu,
149
+ UI_I_SendDataMemory,
150
+ UI_I_SendDataNewHardDisk,
151
+ UI_I_SendDataNewNetwork,
152
+ UI_I_SendDataVideoCard,
153
+ UI_I_InvalidKeys,
154
+ UI_I_SendDataVirtualHardware,
155
+ UI_I_SendDataNewCdDvdDrive,
156
+ UI_I_HardDisk,
157
+ UI_I_PciDevice,
158
+ UI_I_SendDataNewPciDevice,
159
+ } from '~/components/common/vm/actions/add/customizeHardware/virtualHardware/models/interfaces'
160
+ import { UI_I_ErrorValidationField } from '~/models/store/interfaces'
161
+ import {
162
+ UI_T_HardDiskType,
163
+ UI_T_NetworkType,
164
+ UI_T_CdDvdType,
165
+ } from '~/components/common/vm/actions/add/customizeHardware/virtualHardware/models/types'
166
+ import { UI_I_OptionItem } from '~/components/atoms/models/interfaces'
167
+ import {
168
+ UI_I_DropdownTreeItem,
169
+ UI_I_DropdownTreeItemChild,
170
+ } from '~/components/atoms/dropdown/tree/models/interfaces'
171
+ import { UI_I_Localization } from '~/models/interfaces'
172
+ import { UI_I_ConfigurePciDevicesTable } from '~/models/store/host/interfaces'
173
+ import {
174
+ API_UI_I_VmEditCpu,
175
+ API_UI_I_VmEditMemory,
176
+ } from '~/models/store/vm/interfaces'
177
+ import { dropdownItemsFunc } from './config/dropdownItems'
178
+
179
+ const props = defineProps<{
180
+ storage: UI_I_DatastoreTableItem | null
181
+ cpuModels: UI_I_OptionItem[]
182
+ vmName: string
183
+ maxCpus: number
184
+ maxMemory: number
185
+ isEdit: boolean
186
+ errorValidationFields: UI_I_ErrorValidationField<string>[]
187
+ nodes: UI_I_FileTreeNode[]
188
+ files: UI_I_FileTreeNode[]
189
+ networksTable: UI_I_NetworkTableItem[]
190
+ getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
191
+ datastore: UI_I_DatastoreTableItem[]
192
+ state?: string
193
+ cpu?: API_UI_I_VmEditCpu
194
+ memory?: API_UI_I_VmEditMemory
195
+ vmCpuHelpTextSecond?: string
196
+ hardDisks?: UI_I_SendDataNewHardDisk[] | null
197
+ cdDvdDrives?: UI_I_SendDataNewCdDvdDrive[] | null
198
+ networks?: UI_I_SendDataNewNetwork[] | null
199
+ videoCard?: UI_I_SendDataVideoCard
200
+ usbController?: string
201
+ pciDevices?: UI_I_PciDevice[]
202
+ passthroughDevices?: UI_I_ConfigurePciDevicesTable | null
203
+ }>()
204
+ const emits = defineEmits<{
205
+ (event: 'send-data', value: UI_I_SendDataVirtualHardware): void
206
+ (event: 'invalid', value: string[]): void
207
+ (event: 'get-storage', value: UI_I_TablePayload): void
208
+ (event: 'get-folders-or-files', value: UI_I_FolderOrFileTreePayload): void
209
+ (event: 'get-active-device-child', value: UI_I_FileTreeNode): void
210
+ (event: 'show-datastore-child', value: UI_I_FileTreeNode): void
211
+ (event: 'remove-error-by-title', value: string): void
212
+ (event: 'get-networks-table', value: UI_I_TablePayload): void
213
+ (event: 'get-pci-devices'): void
214
+ }>()
215
+
216
+ const localization = computed<UI_I_Localization>(() => useLocal())
217
+ const { $binary } = useNuxtApp()
218
+
219
+ const dropdownItems = computed<UI_I_DropdownTreeItem[]>(() =>
220
+ dropdownItemsFunc(localization.value)
221
+ )
222
+
223
+ const hardDisksIndex = ref<number[]>([0])
224
+ const hardDisksType = ref<UI_T_HardDiskType[]>(['new'])
225
+ const hardDisks = ref<UI_I_SendDataNewHardDisk[]>([
226
+ {
227
+ create: true,
228
+ size: 90,
229
+ source: '',
230
+ },
231
+ ])
232
+ watch(
233
+ () => props.hardDisks,
234
+ (newValue) => {
235
+ if (!props.isEdit || !newValue) return
236
+
237
+ const count = newValue?.length || 0
238
+ hardDisksIndex.value = [...Array(count).keys()]
239
+ hardDisksType.value = Array(count).fill('edit')
240
+ hardDisks.value = newValue
241
+ },
242
+ { immediate: true }
243
+ )
244
+
245
+ const addHardDisk = (
246
+ create = true,
247
+ size = 90,
248
+ source = '',
249
+ type: UI_T_HardDiskType = 'new'
250
+ ): void => {
251
+ const newIndex = (hardDisksIndex.value.at(-1) ?? -1) + 1
252
+ hardDisksIndex.value.push(newIndex)
253
+ hardDisksType.value.push(type)
254
+
255
+ hardDisks.value.push({ create, size, source, attach: true })
256
+ sendData()
257
+ }
258
+ const onAddExistHardDisk = (hardDisk: UI_I_HardDisk): void => {
259
+ addHardDisk(false, $binary.bToGb(hardDisk.size), hardDisk.path, 'exist')
260
+ }
261
+ const onRemoveHardDisk = (
262
+ index: number,
263
+ hardDisk: UI_I_SendDataNewHardDisk
264
+ ): void => {
265
+ const removeIndex = hardDisksIndex.value.indexOf(index)
266
+
267
+ if (!hardDisk.create && !hardDisk.attach) {
268
+ hardDisksType.value = hardDisksType.value.map((item, key) => {
269
+ if (key === removeIndex) return 'removed'
270
+ return item
271
+ })
272
+ sendData()
273
+ return
274
+ }
275
+
276
+ hardDisksIndex.value = hardDisksIndex.value.filter((item) => item !== index)
277
+ hardDisksType.value = hardDisksType.value.filter(
278
+ (_item, key) => key !== removeIndex
279
+ )
280
+
281
+ hardDisks.value = hardDisks.value.filter((_hardDisk, key: number) => {
282
+ return removeIndex !== key
283
+ })
284
+
285
+ delete newHardDiskInvalidKeys.value[index]
286
+ delete sendDataNewHardDisk.value[index]
287
+ sendData()
288
+ }
289
+ const onRollBackHardDisk = (index: number): void => {
290
+ const removeIndex = hardDisksIndex.value.indexOf(index)
291
+ hardDisksType.value = hardDisksType.value.map((item, key) => {
292
+ if (key === removeIndex) return 'edit'
293
+ return item
294
+ })
295
+ }
296
+
297
+ const defaultNetwork = {
298
+ network: '',
299
+ net_bridge: '',
300
+ mac: '',
301
+ target: '',
302
+ model: '',
303
+ boot_order: -1,
304
+ }
305
+ const networks = ref<UI_I_SendDataNewNetwork[]>([useDeepCopy(defaultNetwork)])
306
+ const networksType = ref<UI_T_NetworkType[]>(['new'])
307
+ const networksIndex = ref<number[]>([0])
308
+ watch(
309
+ () => props.networks,
310
+ (newValue) => {
311
+ if (!props.isEdit || !newValue) return
312
+
313
+ // networks.value = newValue
314
+ // networksType.value = Array(newValue.length).fill('edit')
315
+ const count = newValue?.length || 0
316
+ networksIndex.value = [...Array(count).keys()]
317
+ networksType.value = Array(count).fill('edit')
318
+ networks.value = newValue
319
+ },
320
+ { immediate: true }
321
+ )
322
+ const addNetwork = (): void => {
323
+ const index = (networksIndex.value.at(-1) || 0) + 1
324
+ networksIndex.value.push(index)
325
+ networksType.value.push('new')
326
+
327
+ networks.value.push(useDeepCopy(defaultNetwork))
328
+ }
329
+ const onRemoveNetwork = (index: number): void => {
330
+ const removeIndex = networksIndex.value.indexOf(index)
331
+ networksIndex.value = networksIndex.value.filter((item) => item !== index)
332
+ networksType.value = networksType.value.filter(
333
+ (_item, key) => key !== removeIndex
334
+ )
335
+ networks.value = networks.value.filter(
336
+ (_network, key: number) => removeIndex !== key
337
+ )
338
+
339
+ delete newNetworkInvalidKeys.value[index]
340
+ delete sendDataNewNetwork.value[index]
341
+ sendData()
342
+ }
343
+
344
+ const defaultCdDvdDriver: UI_I_SendDataNewCdDvdDrive = {
345
+ create: true,
346
+ attach: false,
347
+ source: '',
348
+ bus: '',
349
+ device_type: 'cdrom',
350
+ boot_order: -1,
351
+ }
352
+ const cdDvdDrives = ref<UI_I_SendDataNewCdDvdDrive[]>([
353
+ useDeepCopy(defaultCdDvdDriver),
354
+ ])
355
+ const cdDvdDrivesIndex = ref<number[]>([0])
356
+ const cdDvdDrivesType = ref<UI_T_CdDvdType[]>(['new'])
357
+ watch(
358
+ () => props.cdDvdDrives,
359
+ (newValue) => {
360
+ if (!props.isEdit || !newValue) return
361
+
362
+ // cdDvdDrives.value = newValue
363
+ // cdDvdDrivesType.value = Array(newValue.length).fill('edit')
364
+ const count = newValue?.length || 0
365
+ cdDvdDrivesIndex.value = [...Array(count).keys()]
366
+ cdDvdDrivesType.value = Array(count).fill('edit')
367
+ cdDvdDrives.value = newValue
368
+ },
369
+ { immediate: true }
370
+ )
371
+ const addCdDvdDrive = (): void => {
372
+ const value = (cdDvdDrivesIndex.value.at(-1) || 0) + 1
373
+ cdDvdDrivesIndex.value.push(value)
374
+ cdDvdDrivesType.value.push('new')
375
+ cdDvdDrives.value.push({ ...useDeepCopy(defaultCdDvdDriver), attach: true })
376
+ }
377
+ const onRemoveCdDvdDrive = (
378
+ index: number,
379
+ cdDvdDrive: UI_I_SendDataNewCdDvdDrive
380
+ ): void => {
381
+ const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
382
+
383
+ if (!cdDvdDrive.create && !cdDvdDrive.attach) {
384
+ cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
385
+ if (key === removeIndex) return 'removed'
386
+ return item
387
+ })
388
+ sendData()
389
+ return
390
+ }
391
+
392
+ cdDvdDrivesIndex.value = cdDvdDrivesIndex.value.filter(
393
+ (cdDvdDrive) => cdDvdDrive !== index
394
+ )
395
+ cdDvdDrivesType.value = cdDvdDrivesType.value.filter(
396
+ (_item, key) => key !== index
397
+ )
398
+ cdDvdDrives.value = cdDvdDrives.value.filter(
399
+ (_cdDvdDrive, key: number) => removeIndex !== key
400
+ )
401
+
402
+ delete sendDataNewCdDvdDrive.value[index]
403
+ sendData()
404
+ }
405
+ const onRollBackCdDvdDrive = (index: number): void => {
406
+ const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
407
+ cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
408
+ if (key === removeIndex) return 'edit'
409
+ return item
410
+ })
411
+ }
412
+
413
+ const defaultPciDevice: UI_I_PciDevice = {
414
+ id: '',
415
+ vendor_name: '',
416
+ class_name: 'cdrom',
417
+ device_name: 'cdrom',
418
+ }
419
+ const pciDevicesIndex = ref<number[]>([0])
420
+ const pciDevicesType = ref<('new' | 'edit')[]>(['new'])
421
+ const pciDevices = ref<UI_I_PciDevice[]>([])
422
+ watch(
423
+ () => props.pciDevices,
424
+ (newValue) => {
425
+ if (!props.isEdit) return
426
+
427
+ const count = newValue?.length || 0
428
+ pciDevicesIndex.value = [...Array(count).keys()]
429
+ pciDevicesType.value = Array(count).fill('edit')
430
+ pciDevices.value = newValue || []
431
+ },
432
+ { immediate: true }
433
+ )
434
+
435
+ const addPciDevice = (): void => {
436
+ const newIndex = (pciDevicesIndex.value.at(-1) ?? -1) + 1
437
+ pciDevicesIndex.value.push(newIndex)
438
+ pciDevicesType.value.push('new')
439
+
440
+ pciDevices.value.push(useDeepCopy(defaultPciDevice))
441
+ }
442
+ const onRemovePciDevice = (index: number): void => {
443
+ const removeIndex = pciDevicesIndex.value.indexOf(index)
444
+ pciDevicesIndex.value = pciDevicesIndex.value.filter((item) => item !== index)
445
+ pciDevicesType.value = pciDevicesType.value.filter(
446
+ (_item, key) => key !== removeIndex
447
+ )
448
+
449
+ pciDevices.value = pciDevices.value.filter((_pciDevice, key: number) => {
450
+ return removeIndex !== key
451
+ })
452
+
453
+ delete newPciDeviceInvalidKeys.value[index]
454
+ delete sendDataNewPciDevices.value[index]
455
+ sendData()
456
+ }
457
+
458
+ const isShowFileModal = ref<boolean>(false)
459
+ const onAddDevice = (item: UI_I_DropdownTreeItemChild): void => {
460
+ switch (item.value) {
461
+ case 1:
462
+ addHardDisk()
463
+ break
464
+ case 2:
465
+ isShowFileModal.value = true
466
+ break
467
+ case 5:
468
+ addCdDvdDrive()
469
+ break
470
+ case 10:
471
+ addPciDevice()
472
+ break
473
+ case 14:
474
+ addNetwork()
475
+ break
476
+ }
477
+ }
478
+
479
+ const cpuInvalid = ref<boolean>(false)
480
+ const sendDataCpu = ref<UI_I_SendDataCpu | null>(null)
481
+ const onSendDataCpuMethod = (data: UI_I_SendDataCpu): void => {
482
+ sendDataCpu.value = data
483
+ sendData()
484
+ }
485
+ const sendDataMemory = ref<UI_I_SendDataMemory | null>(null)
486
+ const onSendDataMemoryMethod = (data: UI_I_SendDataMemory): void => {
487
+ sendDataMemory.value = data
488
+ sendData()
489
+ }
490
+ const sendDataNewHardDisk = ref<UI_I_SendDataNewHardDisk[]>([])
491
+ const onSendDataNewHardDiskMethod = (
492
+ data: UI_I_SendDataNewHardDisk,
493
+ index: number
494
+ ): void => {
495
+ sendDataNewHardDisk.value[index] = data
496
+ sendData()
497
+ }
498
+ const sendDataNewNetwork = ref<UI_I_SendDataNewNetwork[]>([])
499
+ const sendDataNewNetworkMethod = (
500
+ data: UI_I_SendDataNewNetwork,
501
+ index: number
502
+ ): void => {
503
+ sendDataNewNetwork.value[index] = data
504
+ sendData()
505
+ }
506
+ const sendDataNewCdDvdDrive = ref<UI_I_SendDataNewCdDvdDrive[]>([])
507
+ const sendDataNewCdDvdDriveMethod = (
508
+ data: UI_I_SendDataNewCdDvdDrive,
509
+ index: number
510
+ ): void => {
511
+ sendDataNewCdDvdDrive.value[index] = data
512
+ sendData()
513
+ }
514
+ const sendDataNewUsbController = ref<string | null>(null)
515
+ const onSendDataNewUsbControllerMethod = (data: string): void => {
516
+ sendDataNewUsbController.value = data
517
+ sendData()
518
+ }
519
+ const sendDataNewPciDevices = ref<UI_I_SendDataNewPciDevice[]>([])
520
+ const onSendDataPciDevicesMethod = (
521
+ data: UI_I_SendDataNewPciDevice,
522
+ index: number
523
+ ): void => {
524
+ sendDataNewPciDevices.value[index] = data
525
+ sendData()
526
+ }
527
+ const sendDataVideoCard = ref<UI_I_SendDataVideoCard | null>(null)
528
+ const onSendDataVideoCardMethod = (data: UI_I_SendDataVideoCard): void => {
529
+ sendDataVideoCard.value = data
530
+ sendData()
531
+ }
532
+
533
+ const sendData = (): void => {
534
+ const cpu = sendDataCpu.value
535
+ const memory = sendDataMemory.value
536
+ const hardDisks = sendDataNewHardDisk.value.flat(2)
537
+ const networks = sendDataNewNetwork.value.flat(2)
538
+ const cdDvdDrives = sendDataNewCdDvdDrive.value.flat(2)
539
+ const pciDevices = sendDataNewPciDevices.value.flat()
540
+ const usbController = sendDataNewUsbController.value
541
+ const videoCard = sendDataVideoCard.value
542
+
543
+ const sendData: UI_I_SendDataVirtualHardware = {
544
+ cpu,
545
+ memory,
546
+ usbController,
547
+ pciDevices,
548
+ networks,
549
+ hardDisks,
550
+ cdDvdDrives,
551
+ videoCard,
552
+ }
553
+ emits('send-data', sendData)
554
+ }
555
+
556
+ const onSetInvalidHardDisk = (invalid: boolean, index: number): void => {
557
+ newHardDiskInvalidKeys.value[index] = invalid
558
+ }
559
+
560
+ const onSetInvalidNetwork = (invalid: boolean, key: number): void => {
561
+ newNetworkInvalidKeys.value[key] = invalid
562
+ }
563
+
564
+ const onSetInvalidPciDevice = (invalid: boolean, key: number): void => {
565
+ newPciDeviceInvalidKeys.value[key] = invalid
566
+ }
567
+
568
+ const memoryInvalid = ref<boolean>(false)
569
+ const videoCardInvalid = ref<boolean>(false)
570
+ const newHardDiskInvalidKeys = ref<UI_I_InvalidKeys>({})
571
+ const newNetworkInvalidKeys = ref<UI_I_InvalidKeys>({})
572
+ const newPciDeviceInvalidKeys = ref<UI_I_InvalidKeys>({})
573
+
574
+ watch(
575
+ [
576
+ cpuInvalid,
577
+ memoryInvalid,
578
+ newHardDiskInvalidKeys,
579
+ newNetworkInvalidKeys,
580
+ newPciDeviceInvalidKeys,
581
+ videoCardInvalid,
582
+ ],
583
+ () => {
584
+ const cpu = cpuInvalid.value ? localization.value.cpu : ''
585
+ const memory = memoryInvalid.value ? localization.value.memory : ''
586
+ const videoCard = videoCardInvalid.value ? localization.value.videoCard : ''
587
+ let newHardDisk = ''
588
+ Object.keys(newHardDiskInvalidKeys.value).forEach((key) => {
589
+ if (!newHardDiskInvalidKeys.value[+key]) {
590
+ return
591
+ }
592
+
593
+ newHardDisk +=
594
+ (newHardDisk ? ', ' : '') +
595
+ localization.value.newHardDisk +
596
+ ' ' +
597
+ (+key + 1)
598
+ })
599
+ let newNetwork = ''
600
+ Object.keys(newNetworkInvalidKeys.value).forEach((key) => {
601
+ if (!newNetworkInvalidKeys.value[+key]) {
602
+ return
603
+ }
604
+
605
+ newNetwork +=
606
+ (newNetwork ? ', ' : '') +
607
+ localization.value.newNetwork +
608
+ ' ' +
609
+ (+key + 1)
610
+ })
611
+ // let pciDevice = ''
612
+ // Object.keys(newPciDeviceInvalidKeys.value).forEach((key) => {
613
+ // if (!newPciDeviceInvalidKeys.value[+key]) {
614
+ // return
615
+ // }
616
+ //
617
+ // pciDevice +=
618
+ // (pciDevice ? ', ' : '') +
619
+ // localization.value.pciDevice +
620
+ // ' ' +
621
+ // (+key + 1)
622
+ // })
623
+
624
+ emits('invalid', [cpu, memory, newHardDisk, newNetwork, videoCard])
625
+ },
626
+ { deep: true }
627
+ )
628
+
629
+ emits('get-pci-devices')
630
+ </script>
631
+
632
+ <style scoped lang="scss">
633
+ .virtual-hardware {
634
+ .content-dropdown {
635
+ width: 200px;
636
+ }
637
+ }
638
+ </style>
@@ -37,7 +37,7 @@ export const constructDiskDevicesFunc = (
37
37
  io: disk.io ?? '',
38
38
  limit_iops: disk.limit_iops ?? 0,
39
39
  discard: disk.discard ?? '',
40
- attach: disk.attach ?? true,
40
+ attach: disk.attach ?? false,
41
41
  detach: disk.detach ?? false,
42
42
  remove: disk.remove ?? false,
43
43
  create: disk.create ?? true,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bfg-common",
3
3
  "private": false,
4
- "version": "1.1.56",
4
+ "version": "1.1.57",
5
5
  "scripts": {
6
6
  "build": "nuxt build",
7
7
  "dev": "nuxt dev --port=3002",