bfg-common 1.1.63 → 1.1.64

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 (92) hide show
  1. package/assets/localization/local_be.json +1 -1
  2. package/assets/localization/local_hy.json +1 -1
  3. package/assets/localization/local_kk.json +1 -1
  4. package/assets/localization/local_ru.json +1 -1
  5. package/components/atoms/alert/Notification.vue +167 -167
  6. package/components/atoms/autocomplete/Autocomplete.vue +236 -236
  7. package/components/atoms/datepicker/Datepicker.vue +612 -612
  8. package/components/atoms/list/SelectList.vue +62 -62
  9. package/components/atoms/nav/NavBar.vue +116 -116
  10. package/components/atoms/nav/VerticalNavBar.vue +89 -89
  11. package/components/atoms/notificationBar/NotificationBar.vue +175 -175
  12. package/components/atoms/perPage/PerPage.vue +52 -52
  13. package/components/atoms/popup/SimplePopup.vue +90 -90
  14. package/components/atoms/step/VerticalStep.vue +104 -104
  15. package/components/atoms/switch/Switch.vue +107 -107
  16. package/components/atoms/table/dataGrid/DataGridColumnSwitch.vue +206 -206
  17. package/components/atoms/table/dataGrid/DataGridPage.vue +189 -189
  18. package/components/atoms/tabs/Tabs.vue +189 -189
  19. package/components/atoms/tooltip/Signpost.vue +224 -224
  20. package/components/common/adapterManager/AddAdapterWarningModal.vue +82 -82
  21. package/components/common/adapterManager/NoActiveAdaptersModal.vue +62 -62
  22. package/components/common/adapterManager/NoConnectedActiveAdaptersModal.vue +62 -62
  23. package/components/common/browse/Browse.vue +182 -182
  24. package/components/common/browse/blocks/Title.vue +66 -66
  25. package/components/common/diagramMain/Diagram.vue +186 -186
  26. package/components/common/diagramMain/DiagramMain.vue +986 -986
  27. package/components/common/diagramMain/adapter/AdapterItem.vue +227 -227
  28. package/components/common/diagramMain/adapter/AdapterItems.vue +57 -57
  29. package/components/common/diagramMain/modals/editSettings/tabs/port/IpvFourSettings.vue +339 -339
  30. package/components/common/diagramMain/modals/editSettings/tabs/port/PortProperties.vue +202 -202
  31. package/components/common/diagramMain/modals/remove/RemoveModal.vue +226 -226
  32. package/components/common/diagramMain/network/Contents.vue +238 -238
  33. package/components/common/feedback/Buttons.vue +232 -232
  34. package/components/common/feedback/Message.vue +468 -468
  35. package/components/common/feedback/VisitPortal.vue +54 -54
  36. package/components/common/graph/Graph.vue +18 -20
  37. package/components/common/help/navbar/left/Left.vue +159 -159
  38. package/components/common/help/navbar/left/utils/constructAccordion.ts +27 -27
  39. package/components/common/mainNavigationPanel/MainNavigationPanel.vue +359 -359
  40. package/components/common/modals/Rename.vue +165 -165
  41. package/components/common/monitor/advanced/Advanced.vue +3 -33
  42. package/components/common/monitor/advanced/GraphView.vue +4 -4
  43. package/components/common/monitor/advanced/table/Table.vue +5 -5
  44. package/components/common/monitor/advanced/tools/Tools.vue +27 -91
  45. package/components/common/monitor/advanced/tools/chartOptionsModal/ChartOptionsModal.vue +17 -101
  46. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/Counters.vue +7 -25
  47. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/table/config/utils.ts +0 -55
  48. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/table/models/interfaces.ts +1 -1
  49. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/timespan/Timespan.vue +3 -32
  50. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/timespan/form/Form.vue +8 -25
  51. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/timespan/object/Object.vue +19 -41
  52. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/timespan/object/models/interfaces.ts +1 -1
  53. package/components/common/monitor/advanced/tools/config/advancedToolbar.ts +38 -50
  54. package/components/common/monitor/config/getValidDateByOption.ts +6 -105
  55. package/components/common/monitor/overview/filters/Filters.vue +6 -6
  56. package/components/common/monitor/overview/filters/customIntervalModal/CustomIntervalModal.vue +8 -8
  57. package/components/common/monitor/overview/filters/customIntervalModal/config/dateChecker.ts +1 -1
  58. package/components/common/perPage/PerPage.vue +51 -51
  59. package/components/common/recursionTree/RecursionTree.vue +201 -201
  60. package/components/common/vm/actions/add/customizeHardware/virtualHardware/VirtualHardware.vue +641 -642
  61. package/components/common/vm/actions/add/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDrive.vue +245 -274
  62. package/components/common/vm/actions/add/customizeHardware/virtualHardware/cpu/Cpu.vue +375 -375
  63. package/components/common/vm/actions/add/customizeHardware/virtualHardware/limit/Limit.vue +234 -234
  64. package/components/common/vm/actions/add/customizeHardware/virtualHardware/limit/config/options.ts +28 -28
  65. package/components/common/vm/actions/add/customizeHardware/virtualHardware/memory/Memory.vue +316 -316
  66. package/components/common/vm/actions/add/customizeHardware/virtualHardware/memory/config/memoryOptions.ts +35 -35
  67. package/components/common/vm/actions/add/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +447 -447
  68. package/components/common/vm/actions/add/customizeHardware/virtualHardware/newNetwork/NewNetwork.vue +1 -1
  69. package/components/common/vm/actions/add/customizeHardware/virtualHardware/reservation/Reservation.vue +235 -235
  70. package/components/common/vm/actions/add/customizeHardware/vmoptions/bootOptions/order/Order.vue +203 -195
  71. package/components/common/vm/actions/add/select/storage/config/config.ts +154 -154
  72. package/components/common/wizards/datastore/add/nfs/configuration/Configuration.vue +373 -373
  73. package/components/common/wizards/datastore/add/nfs/configuration/serversList/ServersList.vue +123 -123
  74. package/components/common/wizards/datastore/add/nfs/kerberosAuthentication/KerberosAuthentication.vue +54 -54
  75. package/components/common/wizards/datastore/add/sharedStorm/deviceSelection/hostTable/HostTable.vue +131 -131
  76. package/components/common/wizards/datastore/add/sharedStorm/partitionConfiguration/PartitionConfiguration.vue +230 -230
  77. package/models/store/interfaces.ts +37 -37
  78. package/models/store/storage/interfaces.ts +32 -32
  79. package/models/store/types.ts +32 -32
  80. package/modules/fixContentBuild/utils/methods.ts +114 -114
  81. package/package.json +1 -1
  82. package/public/spice-console/application/codec.js +257 -257
  83. package/public/spice-console/lib/rasterEngine.js +907 -907
  84. package/public/spice-console/network/spicechannel.js +369 -369
  85. package/public/spice-console-minify/lib/decoder/dixie.min.js +4 -4
  86. package/public/spice-console-minify/lib/jgestures.min.js +24 -24
  87. package/public/spice-console-minify/lib/jquery-2.0.3.min.js +24 -24
  88. package/public/spice-console-minify/lib/jquery-mousewheel.min.js +11 -11
  89. package/public/spice-console-minify/lib/jquery-visibility.min.js +1 -1
  90. package/public/spice-console-minify/lib/lodash.4.0.0.min.js +5 -5
  91. package/utils/contentBuild.ts +34 -34
  92. package/components/common/monitor/advanced/tools/utils/countCores.ts +0 -7
@@ -1,642 +1,641 @@
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: false,
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({
376
- ...useDeepCopy(defaultCdDvdDriver),
377
- create: true,
378
- attach: true,
379
- })
380
- }
381
- const onRemoveCdDvdDrive = (
382
- index: number,
383
- cdDvdDrive: UI_I_SendDataNewCdDvdDrive
384
- ): void => {
385
- const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
386
-
387
- if (!cdDvdDrive.create && !cdDvdDrive.attach) {
388
- cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
389
- if (key === removeIndex) return 'removed'
390
- return item
391
- })
392
- sendData()
393
- return
394
- }
395
-
396
- cdDvdDrivesIndex.value = cdDvdDrivesIndex.value.filter(
397
- (cdDvdDrive) => cdDvdDrive !== index
398
- )
399
- cdDvdDrivesType.value = cdDvdDrivesType.value.filter(
400
- (_item, key) => key !== index
401
- )
402
- cdDvdDrives.value = cdDvdDrives.value.filter(
403
- (_cdDvdDrive, key: number) => removeIndex !== key
404
- )
405
-
406
- delete sendDataNewCdDvdDrive.value[index]
407
- sendData()
408
- }
409
- const onRollBackCdDvdDrive = (index: number): void => {
410
- const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
411
- cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
412
- if (key === removeIndex) return 'edit'
413
- return item
414
- })
415
- }
416
-
417
- const defaultPciDevice: UI_I_PciDevice = {
418
- id: '',
419
- vendor_name: '',
420
- class_name: 'cdrom',
421
- device_name: 'cdrom',
422
- }
423
- const pciDevicesIndex = ref<number[]>([0])
424
- const pciDevicesType = ref<('new' | 'edit')[]>(['new'])
425
- const pciDevices = ref<UI_I_PciDevice[]>([])
426
- watch(
427
- () => props.pciDevices,
428
- (newValue) => {
429
- if (!props.isEdit) return
430
-
431
- const count = newValue?.length || 0
432
- pciDevicesIndex.value = [...Array(count).keys()]
433
- pciDevicesType.value = Array(count).fill('edit')
434
- pciDevices.value = newValue || []
435
- },
436
- { immediate: true }
437
- )
438
-
439
- const addPciDevice = (): void => {
440
- const newIndex = (pciDevicesIndex.value.at(-1) ?? -1) + 1
441
- pciDevicesIndex.value.push(newIndex)
442
- pciDevicesType.value.push('new')
443
-
444
- pciDevices.value.push(useDeepCopy(defaultPciDevice))
445
- }
446
- const onRemovePciDevice = (index: number): void => {
447
- const removeIndex = pciDevicesIndex.value.indexOf(index)
448
- pciDevicesIndex.value = pciDevicesIndex.value.filter((item) => item !== index)
449
- pciDevicesType.value = pciDevicesType.value.filter(
450
- (_item, key) => key !== removeIndex
451
- )
452
-
453
- pciDevices.value = pciDevices.value.filter((_pciDevice, key: number) => {
454
- return removeIndex !== key
455
- })
456
-
457
- delete newPciDeviceInvalidKeys.value[index]
458
- delete sendDataNewPciDevices.value[index]
459
- sendData()
460
- }
461
-
462
- const isShowFileModal = ref<boolean>(false)
463
- const onAddDevice = (item: UI_I_DropdownTreeItemChild): void => {
464
- switch (item.value) {
465
- case 1:
466
- addHardDisk()
467
- break
468
- case 2:
469
- isShowFileModal.value = true
470
- break
471
- case 5:
472
- addCdDvdDrive()
473
- break
474
- case 10:
475
- addPciDevice()
476
- break
477
- case 14:
478
- addNetwork()
479
- break
480
- }
481
- }
482
-
483
- const cpuInvalid = ref<boolean>(false)
484
- const sendDataCpu = ref<UI_I_SendDataCpu | null>(null)
485
- const onSendDataCpuMethod = (data: UI_I_SendDataCpu): void => {
486
- sendDataCpu.value = data
487
- sendData()
488
- }
489
- const sendDataMemory = ref<UI_I_SendDataMemory | null>(null)
490
- const onSendDataMemoryMethod = (data: UI_I_SendDataMemory): void => {
491
- sendDataMemory.value = data
492
- sendData()
493
- }
494
- const sendDataNewHardDisk = ref<UI_I_SendDataNewHardDisk[]>([])
495
- const onSendDataNewHardDiskMethod = (
496
- data: UI_I_SendDataNewHardDisk,
497
- index: number
498
- ): void => {
499
- sendDataNewHardDisk.value[index] = data
500
- sendData()
501
- }
502
- const sendDataNewNetwork = ref<UI_I_SendDataNewNetwork[]>([])
503
- const sendDataNewNetworkMethod = (
504
- data: UI_I_SendDataNewNetwork,
505
- index: number
506
- ): void => {
507
- sendDataNewNetwork.value[index] = data
508
- sendData()
509
- }
510
- const sendDataNewCdDvdDrive = ref<UI_I_SendDataNewCdDvdDrive[]>([])
511
- const sendDataNewCdDvdDriveMethod = (
512
- data: UI_I_SendDataNewCdDvdDrive,
513
- index: number
514
- ): void => {
515
- sendDataNewCdDvdDrive.value[index] = data
516
- sendData()
517
- }
518
- const sendDataNewUsbController = ref<string | null>(null)
519
- const onSendDataNewUsbControllerMethod = (data: string): void => {
520
- sendDataNewUsbController.value = data
521
- sendData()
522
- }
523
- const sendDataNewPciDevices = ref<UI_I_SendDataNewPciDevice[]>([])
524
- const onSendDataPciDevicesMethod = (
525
- data: UI_I_SendDataNewPciDevice,
526
- index: number
527
- ): void => {
528
- sendDataNewPciDevices.value[index] = data
529
- sendData()
530
- }
531
- const sendDataVideoCard = ref<UI_I_SendDataVideoCard | null>(null)
532
- const onSendDataVideoCardMethod = (data: UI_I_SendDataVideoCard): void => {
533
- sendDataVideoCard.value = data
534
- sendData()
535
- }
536
-
537
- const sendData = (): void => {
538
- const cpu = sendDataCpu.value
539
- const memory = sendDataMemory.value
540
- const hardDisks = sendDataNewHardDisk.value.flat(2)
541
- const networks = sendDataNewNetwork.value.flat(2)
542
- const cdDvdDrives = sendDataNewCdDvdDrive.value.flat(2)
543
- const pciDevices = sendDataNewPciDevices.value.flat()
544
- const usbController = sendDataNewUsbController.value
545
- const videoCard = sendDataVideoCard.value
546
-
547
- const sendData: UI_I_SendDataVirtualHardware = {
548
- cpu,
549
- memory,
550
- usbController,
551
- pciDevices,
552
- networks,
553
- hardDisks,
554
- cdDvdDrives,
555
- videoCard,
556
- }
557
- emits('send-data', sendData)
558
- }
559
-
560
- const onSetInvalidHardDisk = (invalid: boolean, index: number): void => {
561
- newHardDiskInvalidKeys.value[index] = invalid
562
- }
563
-
564
- const onSetInvalidNetwork = (invalid: boolean, key: number): void => {
565
- newNetworkInvalidKeys.value[key] = invalid
566
- }
567
-
568
- const onSetInvalidPciDevice = (invalid: boolean, key: number): void => {
569
- newPciDeviceInvalidKeys.value[key] = invalid
570
- }
571
-
572
- const memoryInvalid = ref<boolean>(false)
573
- const videoCardInvalid = ref<boolean>(false)
574
- const newHardDiskInvalidKeys = ref<UI_I_InvalidKeys>({})
575
- const newNetworkInvalidKeys = ref<UI_I_InvalidKeys>({})
576
- const newPciDeviceInvalidKeys = ref<UI_I_InvalidKeys>({})
577
-
578
- watch(
579
- [
580
- cpuInvalid,
581
- memoryInvalid,
582
- newHardDiskInvalidKeys,
583
- newNetworkInvalidKeys,
584
- newPciDeviceInvalidKeys,
585
- videoCardInvalid,
586
- ],
587
- () => {
588
- const cpu = cpuInvalid.value ? localization.value.cpu : ''
589
- const memory = memoryInvalid.value ? localization.value.memory : ''
590
- const videoCard = videoCardInvalid.value ? localization.value.videoCard : ''
591
- let newHardDisk = ''
592
- Object.keys(newHardDiskInvalidKeys.value).forEach((key) => {
593
- if (!newHardDiskInvalidKeys.value[+key]) {
594
- return
595
- }
596
-
597
- newHardDisk +=
598
- (newHardDisk ? ', ' : '') +
599
- localization.value.newHardDisk +
600
- ' ' +
601
- (+key + 1)
602
- })
603
- let newNetwork = ''
604
- Object.keys(newNetworkInvalidKeys.value).forEach((key) => {
605
- if (!newNetworkInvalidKeys.value[+key]) {
606
- return
607
- }
608
-
609
- newNetwork +=
610
- (newNetwork ? ', ' : '') +
611
- localization.value.newNetwork +
612
- ' ' +
613
- (+key + 1)
614
- })
615
- // let pciDevice = ''
616
- // Object.keys(newPciDeviceInvalidKeys.value).forEach((key) => {
617
- // if (!newPciDeviceInvalidKeys.value[+key]) {
618
- // return
619
- // }
620
- //
621
- // pciDevice +=
622
- // (pciDevice ? ', ' : '') +
623
- // localization.value.pciDevice +
624
- // ' ' +
625
- // (+key + 1)
626
- // })
627
-
628
- emits('invalid', [cpu, memory, newHardDisk, newNetwork, videoCard])
629
- },
630
- { deep: true }
631
- )
632
-
633
- emits('get-pci-devices')
634
- </script>
635
-
636
- <style scoped lang="scss">
637
- .virtual-hardware {
638
- .content-dropdown {
639
- width: 200px;
640
- }
641
- }
642
- </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: false,
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({
376
+ ...useDeepCopy(defaultCdDvdDriver),
377
+ attach: true,
378
+ })
379
+ }
380
+ const onRemoveCdDvdDrive = (
381
+ index: number,
382
+ cdDvdDrive: UI_I_SendDataNewCdDvdDrive
383
+ ): void => {
384
+ const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
385
+
386
+ if (!cdDvdDrive.create && !cdDvdDrive.attach) {
387
+ cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
388
+ if (key === removeIndex) return 'removed'
389
+ return item
390
+ })
391
+ sendData()
392
+ return
393
+ }
394
+
395
+ cdDvdDrivesIndex.value = cdDvdDrivesIndex.value.filter(
396
+ (cdDvdDrive) => cdDvdDrive !== index
397
+ )
398
+ cdDvdDrivesType.value = cdDvdDrivesType.value.filter(
399
+ (_item, key) => key !== index
400
+ )
401
+ cdDvdDrives.value = cdDvdDrives.value.filter(
402
+ (_cdDvdDrive, key: number) => removeIndex !== key
403
+ )
404
+
405
+ delete sendDataNewCdDvdDrive.value[index]
406
+ sendData()
407
+ }
408
+ const onRollBackCdDvdDrive = (index: number): void => {
409
+ const removeIndex = cdDvdDrivesIndex.value.indexOf(index)
410
+ cdDvdDrivesType.value = cdDvdDrivesType.value.map((item, key) => {
411
+ if (key === removeIndex) return 'edit'
412
+ return item
413
+ })
414
+ }
415
+
416
+ const defaultPciDevice: UI_I_PciDevice = {
417
+ id: '',
418
+ vendor_name: '',
419
+ class_name: 'cdrom',
420
+ device_name: 'cdrom',
421
+ }
422
+ const pciDevicesIndex = ref<number[]>([0])
423
+ const pciDevicesType = ref<('new' | 'edit')[]>(['new'])
424
+ const pciDevices = ref<UI_I_PciDevice[]>([])
425
+ watch(
426
+ () => props.pciDevices,
427
+ (newValue) => {
428
+ if (!props.isEdit) return
429
+
430
+ const count = newValue?.length || 0
431
+ pciDevicesIndex.value = [...Array(count).keys()]
432
+ pciDevicesType.value = Array(count).fill('edit')
433
+ pciDevices.value = newValue || []
434
+ },
435
+ { immediate: true }
436
+ )
437
+
438
+ const addPciDevice = (): void => {
439
+ const newIndex = (pciDevicesIndex.value.at(-1) ?? -1) + 1
440
+ pciDevicesIndex.value.push(newIndex)
441
+ pciDevicesType.value.push('new')
442
+
443
+ pciDevices.value.push(useDeepCopy(defaultPciDevice))
444
+ }
445
+ const onRemovePciDevice = (index: number): void => {
446
+ const removeIndex = pciDevicesIndex.value.indexOf(index)
447
+ pciDevicesIndex.value = pciDevicesIndex.value.filter((item) => item !== index)
448
+ pciDevicesType.value = pciDevicesType.value.filter(
449
+ (_item, key) => key !== removeIndex
450
+ )
451
+
452
+ pciDevices.value = pciDevices.value.filter((_pciDevice, key: number) => {
453
+ return removeIndex !== key
454
+ })
455
+
456
+ delete newPciDeviceInvalidKeys.value[index]
457
+ delete sendDataNewPciDevices.value[index]
458
+ sendData()
459
+ }
460
+
461
+ const isShowFileModal = ref<boolean>(false)
462
+ const onAddDevice = (item: UI_I_DropdownTreeItemChild): void => {
463
+ switch (item.value) {
464
+ case 1:
465
+ addHardDisk()
466
+ break
467
+ case 2:
468
+ isShowFileModal.value = true
469
+ break
470
+ case 5:
471
+ addCdDvdDrive()
472
+ break
473
+ case 10:
474
+ addPciDevice()
475
+ break
476
+ case 14:
477
+ addNetwork()
478
+ break
479
+ }
480
+ }
481
+
482
+ const cpuInvalid = ref<boolean>(false)
483
+ const sendDataCpu = ref<UI_I_SendDataCpu | null>(null)
484
+ const onSendDataCpuMethod = (data: UI_I_SendDataCpu): void => {
485
+ sendDataCpu.value = data
486
+ sendData()
487
+ }
488
+ const sendDataMemory = ref<UI_I_SendDataMemory | null>(null)
489
+ const onSendDataMemoryMethod = (data: UI_I_SendDataMemory): void => {
490
+ sendDataMemory.value = data
491
+ sendData()
492
+ }
493
+ const sendDataNewHardDisk = ref<UI_I_SendDataNewHardDisk[]>([])
494
+ const onSendDataNewHardDiskMethod = (
495
+ data: UI_I_SendDataNewHardDisk,
496
+ index: number
497
+ ): void => {
498
+ sendDataNewHardDisk.value[index] = data
499
+ sendData()
500
+ }
501
+ const sendDataNewNetwork = ref<UI_I_SendDataNewNetwork[]>([])
502
+ const sendDataNewNetworkMethod = (
503
+ data: UI_I_SendDataNewNetwork,
504
+ index: number
505
+ ): void => {
506
+ sendDataNewNetwork.value[index] = data
507
+ sendData()
508
+ }
509
+ const sendDataNewCdDvdDrive = ref<UI_I_SendDataNewCdDvdDrive[]>([])
510
+ const sendDataNewCdDvdDriveMethod = (
511
+ data: UI_I_SendDataNewCdDvdDrive,
512
+ index: number
513
+ ): void => {
514
+ sendDataNewCdDvdDrive.value[index] = data
515
+ sendData()
516
+ }
517
+ const sendDataNewUsbController = ref<string | null>(null)
518
+ const onSendDataNewUsbControllerMethod = (data: string): void => {
519
+ sendDataNewUsbController.value = data
520
+ sendData()
521
+ }
522
+ const sendDataNewPciDevices = ref<UI_I_SendDataNewPciDevice[]>([])
523
+ const onSendDataPciDevicesMethod = (
524
+ data: UI_I_SendDataNewPciDevice,
525
+ index: number
526
+ ): void => {
527
+ sendDataNewPciDevices.value[index] = data
528
+ sendData()
529
+ }
530
+ const sendDataVideoCard = ref<UI_I_SendDataVideoCard | null>(null)
531
+ const onSendDataVideoCardMethod = (data: UI_I_SendDataVideoCard): void => {
532
+ sendDataVideoCard.value = data
533
+ sendData()
534
+ }
535
+
536
+ const sendData = (): void => {
537
+ const cpu = sendDataCpu.value
538
+ const memory = sendDataMemory.value
539
+ const hardDisks = sendDataNewHardDisk.value.flat(2)
540
+ const networks = sendDataNewNetwork.value.flat(2)
541
+ const cdDvdDrives = sendDataNewCdDvdDrive.value.flat(2)
542
+ const pciDevices = sendDataNewPciDevices.value.flat()
543
+ const usbController = sendDataNewUsbController.value
544
+ const videoCard = sendDataVideoCard.value
545
+
546
+ const sendData: UI_I_SendDataVirtualHardware = {
547
+ cpu,
548
+ memory,
549
+ usbController,
550
+ pciDevices,
551
+ networks,
552
+ hardDisks,
553
+ cdDvdDrives,
554
+ videoCard,
555
+ }
556
+ emits('send-data', sendData)
557
+ }
558
+
559
+ const onSetInvalidHardDisk = (invalid: boolean, index: number): void => {
560
+ newHardDiskInvalidKeys.value[index] = invalid
561
+ }
562
+
563
+ const onSetInvalidNetwork = (invalid: boolean, key: number): void => {
564
+ newNetworkInvalidKeys.value[key] = invalid
565
+ }
566
+
567
+ const onSetInvalidPciDevice = (invalid: boolean, key: number): void => {
568
+ newPciDeviceInvalidKeys.value[key] = invalid
569
+ }
570
+
571
+ const memoryInvalid = ref<boolean>(false)
572
+ const videoCardInvalid = ref<boolean>(false)
573
+ const newHardDiskInvalidKeys = ref<UI_I_InvalidKeys>({})
574
+ const newNetworkInvalidKeys = ref<UI_I_InvalidKeys>({})
575
+ const newPciDeviceInvalidKeys = ref<UI_I_InvalidKeys>({})
576
+
577
+ watch(
578
+ [
579
+ cpuInvalid,
580
+ memoryInvalid,
581
+ newHardDiskInvalidKeys,
582
+ newNetworkInvalidKeys,
583
+ newPciDeviceInvalidKeys,
584
+ videoCardInvalid,
585
+ ],
586
+ () => {
587
+ const cpu = cpuInvalid.value ? localization.value.cpu : ''
588
+ const memory = memoryInvalid.value ? localization.value.memory : ''
589
+ const videoCard = videoCardInvalid.value ? localization.value.videoCard : ''
590
+ let newHardDisk = ''
591
+ Object.keys(newHardDiskInvalidKeys.value).forEach((key) => {
592
+ if (!newHardDiskInvalidKeys.value[+key]) {
593
+ return
594
+ }
595
+
596
+ newHardDisk +=
597
+ (newHardDisk ? ', ' : '') +
598
+ localization.value.newHardDisk +
599
+ ' ' +
600
+ (+key + 1)
601
+ })
602
+ let newNetwork = ''
603
+ Object.keys(newNetworkInvalidKeys.value).forEach((key) => {
604
+ if (!newNetworkInvalidKeys.value[+key]) {
605
+ return
606
+ }
607
+
608
+ newNetwork +=
609
+ (newNetwork ? ', ' : '') +
610
+ localization.value.newNetwork +
611
+ ' ' +
612
+ (+key + 1)
613
+ })
614
+ // let pciDevice = ''
615
+ // Object.keys(newPciDeviceInvalidKeys.value).forEach((key) => {
616
+ // if (!newPciDeviceInvalidKeys.value[+key]) {
617
+ // return
618
+ // }
619
+ //
620
+ // pciDevice +=
621
+ // (pciDevice ? ', ' : '') +
622
+ // localization.value.pciDevice +
623
+ // ' ' +
624
+ // (+key + 1)
625
+ // })
626
+
627
+ emits('invalid', [cpu, memory, newHardDisk, newNetwork, videoCard])
628
+ },
629
+ { deep: true }
630
+ )
631
+
632
+ emits('get-pci-devices')
633
+ </script>
634
+
635
+ <style scoped lang="scss">
636
+ .virtual-hardware {
637
+ .content-dropdown {
638
+ width: 200px;
639
+ }
640
+ }
641
+ </style>