bfg-common 1.5.577 → 1.5.578

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 (61) hide show
  1. package/components/common/vm/actions/add/Add.vue +886 -960
  2. package/components/common/vm/actions/add/New.vue +16 -54
  3. package/components/common/vm/actions/add/Old.vue +16 -55
  4. package/components/common/vm/actions/add/lib/config/steps.ts +347 -347
  5. package/components/common/vm/actions/clone/Clone.vue +744 -816
  6. package/components/common/vm/actions/clone/new/New.vue +14 -50
  7. package/components/common/vm/actions/clone/old/Old.vue +16 -52
  8. package/components/common/vm/actions/common/customizeHardware/CustomizeHardware.vue +14 -81
  9. package/components/common/vm/actions/common/customizeHardware/CustomizeHardwareNew.vue +7 -56
  10. package/components/common/vm/actions/common/customizeHardware/CustomizeHardwareOld.vue +8 -56
  11. package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardware.vue +211 -206
  12. package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardwareNew.vue +225 -120
  13. package/components/common/vm/actions/common/customizeHardware/virtualHardware/VirtualHardwareOld.vue +220 -118
  14. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cdDvdDrive/CdDvdDrive.vue +66 -53
  15. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/Cpu.vue +139 -159
  16. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/CpuNew.vue +8 -15
  17. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/CpuOld.vue +8 -13
  18. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/Memory.vue +62 -75
  19. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +241 -149
  20. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDiskNew.vue +3 -4
  21. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDiskOld.vue +2 -3
  22. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/NewNetwork.vue +62 -100
  23. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newUsbController/NewUsbController.vue +6 -17
  24. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newUsbController/NewUsbControllerNew.vue +6 -3
  25. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newUsbController/NewUsbControllerOld.vue +6 -3
  26. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCard.vue +17 -39
  27. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCardNew.vue +6 -5
  28. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/VideoCardOld.vue +6 -5
  29. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/lib/config/options.ts +4 -4
  30. package/components/common/vm/actions/common/customizeHardware/vmoptions/Vmoptions.vue +6 -93
  31. package/components/common/vm/actions/common/customizeHardware/vmoptions/VmoptionsNew.vue +8 -60
  32. package/components/common/vm/actions/common/customizeHardware/vmoptions/VmoptionsOld.vue +8 -58
  33. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/BootOptions.vue +5 -69
  34. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/BootOptionsNew.vue +12 -32
  35. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/BootOptionsOld.vue +12 -33
  36. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/Order.vue +114 -132
  37. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/OrderNew.vue +41 -6
  38. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/order/OrderOld.vue +44 -6
  39. package/components/common/vm/actions/common/customizeHardware/vmoptions/generalOptions/GeneralOptions.vue +8 -23
  40. package/components/common/vm/actions/common/customizeHardware/vmoptions/generalOptions/GeneralOptionsNew.vue +21 -31
  41. package/components/common/vm/actions/common/customizeHardware/vmoptions/generalOptions/GeneralOptionsOld.vue +26 -34
  42. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/New.vue +28 -34
  43. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/Old.vue +24 -30
  44. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/RemoteConsoleOptions.vue +8 -112
  45. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/Keymap.vue +3 -3
  46. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/{KeymapNew.vue → New.vue} +6 -6
  47. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/keymap/{KeymapOld.vue → Old.vue} +5 -5
  48. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/Password.vue +6 -7
  49. package/components/common/vm/actions/common/customizeHardware/vmoptions/tools/Tools.vue +9 -27
  50. package/components/common/vm/actions/common/lib/models/interfaces.ts +58 -25
  51. package/components/common/vm/actions/common/select/options/New.vue +258 -258
  52. package/components/common/vm/actions/common/select/options/Old.vue +103 -103
  53. package/components/common/vm/actions/common/select/options/Options.vue +54 -54
  54. package/components/common/vm/actions/editSettings/EditSettings.vue +32 -90
  55. package/components/common/vm/actions/editSettings/EditSettingsOld.vue +14 -41
  56. package/components/common/vm/actions/editSettings/new/New.vue +14 -41
  57. package/components/common/vm/actions/lib/models/interfaces.ts +4 -29
  58. package/components/common/vm/actions/lib/utils.ts +64 -36
  59. package/package.json +1 -1
  60. /package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/{PasswordNew.vue → New.vue} +0 -0
  61. /package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/password/{PasswordOld.vue → Old.vue} +0 -0
@@ -1,816 +1,744 @@
1
- <template>
2
- <common-vm-actions-clone-new
3
- v-if="isNewView"
4
- v-model:vm-form="vmForm"
5
- v-model:scheduler-task-form="schedulerTaskForm"
6
- v-model:vm-name="vmName"
7
- v-model:compute-resource="vmForm.computeResource"
8
- v-model:location="location"
9
- :project="props.project"
10
- :vm-settings="vmSettings"
11
- :nodes="props.nodes"
12
- :files="props.files"
13
- :networks-table="props.networksTable"
14
- :datastore="props.datastore"
15
- :is-datastore-loading="props.isDatastoreLoading"
16
- :error-validation-fields="props.errorValidationFields"
17
- :ready-complete-table-info="props.readyCompleteTableInfo"
18
- :vm-cpu-help-text-second="props.vmCpuHelpTextSecond"
19
- :get-datastore-table-func="props.getDatastoreTableFunc"
20
- :passthrough-devices="props.passthroughDevices"
21
- :mediated-devices="props.mediatedDevices"
22
- :name-request-url="props.nameRequestUrl"
23
- :selected-virtual-machine="props.selectedVirtualMachine"
24
- :is-new-vm-from-template="props.isNewVmFromTemplate"
25
- :compute-resource-tree="props.computeResourceTree"
26
- :location-nodes="props.locationNodes"
27
- :wizard="wizard"
28
- :selected-scheme="selectedScheme"
29
- :title="title"
30
- :name-form-submit="nameFormSubmit"
31
- :storage-submit="storageSubmit"
32
- :customize-hardware-submit="customizeHardwareSubmit"
33
- :selected-nav-item="selectedNavItem"
34
- :allowed-location-kinds="allowedLocationKinds"
35
- :is-sphere="isSphere"
36
- :location-description="locationDescription"
37
- :name-test-ids="nameTestIds"
38
- :virtual-hardware-hard-disks-local="virtualHardwareHardDisksLocal"
39
- :virtual-hardware-networks-local="virtualHardwareNetworksLocal"
40
- :virtual-hardware-cd-dvd-drives-local="virtualHardwareCdDvdDrivesLocal"
41
- :guest-os-families="guestOsFamilies"
42
- :guest-os-versions="guestOsVersions"
43
- :machine-types="machineTypes"
44
- :dynamic-steps="dynamicSteps"
45
- :is-loading-compute-tree="isLoadingComputeTree"
46
- :compute-resource-alert="computeResourceAlert"
47
- :compatibility-text="compatibilityText"
48
- @get-folders-or-files="emits('get-folders-or-files', $event)"
49
- @change-name="onChangeName"
50
- @change-storage="onChangeStorage"
51
- @change-select-options="onChangeSelectOptions"
52
- @change-clone-count="cloneCount = $event"
53
- @change-boot-order="onChangeBootOrder"
54
- @change-customize-hardware="onChangeCustomizeHardware"
55
- @get-storage="emits('get-storage', $event)"
56
- @get-active-device-child="emits('get-active-device-child', $event)"
57
- @show-datastore-child="emits('show-datastore-child', $event)"
58
- @remove-error-by-title="emits('remove-error-by-title', $event)"
59
- @get-networks-table="emits('get-networks-table', $event)"
60
- @get-pci-devices="emits('get-pci-devices')"
61
- @change-steps="onChangeSteps"
62
- @hide="onHideModal"
63
- @finish="onFinish"
64
- />
65
- <common-vm-actions-clone-old
66
- v-else
67
- v-model:vm-form="vmForm"
68
- v-model:scheduler-task-form="schedulerTaskForm"
69
- v-model:vm-name="vmName"
70
- v-model:compute-resource="vmForm.computeResource"
71
- v-model:location="location"
72
- :project="props.project"
73
- :vm-settings="vmSettings"
74
- :nodes="props.nodes"
75
- :files="props.files"
76
- :networks-table="props.networksTable"
77
- :datastore="props.datastore"
78
- :is-datastore-loading="props.isDatastoreLoading"
79
- :error-validation-fields="props.errorValidationFields"
80
- :ready-complete-table-info="props.readyCompleteTableInfo"
81
- :vm-cpu-help-text-second="props.vmCpuHelpTextSecond"
82
- :get-datastore-table-func="props.getDatastoreTableFunc"
83
- :passthrough-devices="props.passthroughDevices"
84
- :mediated-devices="props.mediatedDevices"
85
- :name-request-url="props.nameRequestUrl"
86
- :selected-virtual-machine="props.selectedVirtualMachine"
87
- :is-new-vm-from-template="props.isNewVmFromTemplate"
88
- :compute-resource-tree="props.computeResourceTree"
89
- :location-nodes="props.locationNodes"
90
- :wizard="wizard"
91
- :selected-scheme="selectedScheme"
92
- :title="title"
93
- :name-form-submit="nameFormSubmit"
94
- :storage-submit="storageSubmit"
95
- :customize-hardware-submit="customizeHardwareSubmit"
96
- :selected-nav-item="selectedNavItem"
97
- :is-loading="isLoading"
98
- :allowed-location-kinds="allowedLocationKinds"
99
- :is-sphere="isSphere"
100
- :location-description="locationDescription"
101
- :name-test-ids="nameTestIds"
102
- :virtual-hardware-hard-disks-local="virtualHardwareHardDisksLocal"
103
- :virtual-hardware-networks-local="virtualHardwareNetworksLocal"
104
- :virtual-hardware-cd-dvd-drives-local="virtualHardwareCdDvdDrivesLocal"
105
- :guest-os-families="guestOsFamilies"
106
- :guest-os-versions="guestOsVersions"
107
- :machine-types="machineTypes"
108
- :dynamic-steps="dynamicSteps"
109
- :is-loading-compute-tree="isLoadingComputeTree"
110
- :compute-resource-alert="computeResourceAlert"
111
- :compatibility-text="compatibilityText"
112
- @get-folders-or-files="emits('get-folders-or-files', $event)"
113
- @change-name="onChangeName"
114
- @change-storage="onChangeStorage"
115
- @change-select-options="onChangeSelectOptions"
116
- @change-clone-count="cloneCount = $event"
117
- @change-boot-order="onChangeBootOrder"
118
- @change-customize-hardware="onChangeCustomizeHardware"
119
- @get-storage="emits('get-storage', $event)"
120
- @get-active-device-child="emits('get-active-device-child', $event)"
121
- @show-datastore-child="emits('show-datastore-child', $event)"
122
- @remove-error-by-title="emits('remove-error-by-title', $event)"
123
- @get-networks-table="emits('get-networks-table', $event)"
124
- @get-pci-devices="emits('get-pci-devices')"
125
- @change-steps="onChangeSteps"
126
- @hide="onHideModal"
127
- @finish="onFinish"
128
- />
129
- </template>
130
-
131
- <script setup lang="ts">
132
- import type {
133
- UI_I_ValidationReturn,
134
- UI_I_WizardStep,
135
- } from '~/node_modules/bfg-uikit/components/ui/wizard/lib/models/interfaces'
136
- import Wizard from '~/node_modules/bfg-uikit/components/ui/wizard/lib/utils/utils'
137
- import type {
138
- UI_I_DatastoreTableItem,
139
- UI_I_FolderOrFileTreePayload,
140
- } from '~/lib/models/store/storage/interfaces'
141
- import type { UI_I_NetworkTableItem } from '~/lib/models/store/network/interfaces'
142
- import type { UI_I_TablePayload } from '~/lib/models/table/interfaces'
143
- import type { UI_I_FileTreeNode } from '~/components/lib/models/interfaces'
144
- import type {
145
- UI_I_ArbitraryObject,
146
- UI_I_Localization,
147
- } from '~/lib/models/interfaces'
148
- import type { UI_I_SendDataCustomizeHardware } from '~/components/common/vm/actions/common/customizeHardware/lib/models/interfaces'
149
- import type { UI_I_ErrorValidationField } from '~/lib/models/store/interfaces'
150
- import type {
151
- UI_I_SendDataCpu,
152
- UI_I_SendDataMemory,
153
- UI_I_SendDataNewCdDvdDrive,
154
- UI_I_SendDataNewHardDisk,
155
- UI_I_SendDataNewNetwork,
156
- } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/models/interfaces'
157
- import type { UI_T_SelectedNavItem } from '~/components/common/vm/actions/common/lib/models/types'
158
- import type { UI_I_TableInfoItem } from '~/components/atoms/table/info/lib/models/interfaces'
159
- import type { UI_T_ChangeBootOrder } from '~/components/common/vm/actions/lib/models/types'
160
- import type { UI_T_Project } from '~/lib/models/types'
161
- import type {
162
- UI_I_MediatedDevice,
163
- UI_I_PciDevice,
164
- UI_I_VmSettings,
165
- } from '~/lib/models/store/vm/interfaces'
166
- import type { UI_I_VmForm } from '~/components/common/vm/actions/common/lib/models/interfaces'
167
- import type { UI_I_Capabilities } from '~/components/common/vm/actions/common/lib/models/interfaces'
168
- import type { UI_I_ScheduleNewTasksForm } from '~/components/common/pages/scheduledTasks/modals/lib/models/interfaces'
169
- import type { UI_I_OptionItem } from '~/components/atoms/lib/models/interfaces'
170
- import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
171
- import type { UI_I_NameTestIds } from '~/components/common/wizards/common/steps/name/lib/models/interfaces'
172
- import type { UI_T_CompatibilityStatus } from '~/components/common/wizards/common/compatibility/lib/models/types'
173
- import {
174
- stepsSchemeInitial,
175
- stepsFunc,
176
- dynamicSteps,
177
- } from '~/components/common/vm/actions/clone/lib/config/steps'
178
- import { mapCapabilities } from '~/components/common/vm/actions/common/lib/utils/capabilities'
179
- import { scheduledTaskDefaultFormFunc } from '~/components/common/pages/scheduledTasks/modals/lib/config/createScheduledTask'
180
- import { capabilities } from '~/components/common/vm/actions/common/lib/config/capabilities'
181
-
182
- const props = withDefaults(
183
- defineProps<{
184
- project: UI_T_Project
185
- vmSettings: UI_I_VmSettings | null
186
- nodes: UI_I_FileTreeNode[]
187
- files: UI_I_FileTreeNode[]
188
- networksTable: UI_I_NetworkTableItem[]
189
- datastore: UI_I_DatastoreTableItem[]
190
- isDatastoreLoading: boolean
191
- errorValidationFields: UI_I_ErrorValidationField[]
192
- readyCompleteTableInfo: UI_I_TableInfoItem[]
193
- vmCpuHelpTextSecond: string
194
- finishFunc: any
195
- getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
196
- validateSendDataFunc: any
197
- passthroughDevices: UI_I_PciDevice[]
198
- mediatedDevices: UI_I_MediatedDevice[]
199
- vmNameInWizard: string
200
- nameRequestUrl: string
201
- capabilities?: UI_I_Capabilities
202
- schedulerTask?: any // TODO надо interface переместить глобално
203
- selectedVirtualMachine?: string
204
- isNewVmFromTemplate?: boolean
205
- dataCenter?: UI_I_TreeNode | null // для сферы
206
- computeResource?: UI_I_TreeNode // для сферы
207
- computeResourceTree?: UI_I_TreeNode[] // для сферы
208
- locationNodes?: UI_I_TreeNode[] // для сферы
209
- }>(),
210
- {
211
- capabilities: undefined,
212
- schedulerTask: undefined,
213
- selectedVirtualMachine: '',
214
- isNewVmFromTemplate: undefined,
215
- dataCenter: null,
216
- computeResource: null,
217
- computeResourceTree: undefined,
218
- locationNodes: () => [],
219
- }
220
- )
221
-
222
- const emits = defineEmits<{
223
- (event: 'get-storage', value: UI_I_TablePayload): void
224
- (event: 'get-folders-or-files', value: UI_I_FolderOrFileTreePayload): void
225
- (event: 'get-active-device-child', value: UI_I_FileTreeNode): void
226
- (event: 'show-datastore-child', value: UI_I_FileTreeNode): void
227
- (event: 'remove-error-by-title', value: string): void
228
- (event: 'get-networks-table', value: UI_I_TablePayload): void
229
- (event: 'get-pci-devices'): void
230
- (event: 'hide'): void
231
- (
232
- event: 'get-compute-resource-tree',
233
- value: { id: string | number; cb: () => void }
234
- ): void // для сферы
235
- (event: 'select-compute-resource-tree', value: UI_I_TreeNode): void // для сферы
236
- }>()
237
-
238
- const { $store, $recursion } = useNuxtApp()
239
-
240
- const isNewView = computed<boolean>(() => $store.getters['main/getIsNewView'])
241
-
242
- const localization = computed<UI_I_Localization>(() => useLocal())
243
-
244
- const isSphere = computed<boolean>(() => props.project === 'sphere')
245
-
246
- const location = ref<UI_I_TreeNode | null>(props.dataCenter) // для сферы
247
-
248
- const isScheduledTasks = computed<boolean>(
249
- () => props.schedulerTask?.isSchedulerTask
250
- )
251
-
252
- const title = computed<string>(() => {
253
- const { scheduleNewTasks, scheduleTaskEdit, cloneExistingVirtualMachine } =
254
- localization.value.common
255
-
256
- let result = cloneExistingVirtualMachine
257
- if (isScheduledTasks.value) {
258
- const schedulerMode = props.schedulerTask.editTask
259
- ? scheduleTaskEdit
260
- : scheduleNewTasks
261
-
262
- result = `${schedulerMode} (${cloneExistingVirtualMachine})`
263
- }
264
-
265
- if (props.isNewVmFromTemplate) {
266
- result = localization.value.vmWizard.deployFromTemplate
267
- }
268
-
269
- return result
270
- })
271
-
272
- watch(
273
- () => props.capabilities,
274
- () => {
275
- if (props.capabilities) {
276
- mapCapabilities(props.capabilities)
277
- }
278
- },
279
- { deep: true, immediate: true }
280
- )
281
-
282
- const wizard: Wizard = new Wizard(
283
- stepsFunc(localization.value),
284
- stepsSchemeInitial
285
- )
286
-
287
- const selectedScheme = computed<number[]>(() => wizard.selectedScheme.value)
288
-
289
- watch(
290
- isScheduledTasks,
291
- (newValue: boolean) => {
292
- if (newValue) {
293
- wizard.changeScheme(isSphere.value ? 12 : 4)
294
- } else {
295
- wizard.changeScheme(isSphere.value ? 8 : 0)
296
- wizard.selectStepHard(isSphere.value ? 2 : 1)
297
- }
298
- },
299
- { immediate: true }
300
- )
301
-
302
- const allowedLocationKinds = ref<number[]>([3, 7]) // TODO use from config
303
- const locationDescription = computed<string>(
304
- () => localization.value.common.selectLocationVirtualMachine
305
- )
306
-
307
- const nameTestIds = ref<UI_I_NameTestIds>({
308
- name: 'virtual-machine-name',
309
- helpIcon: 'show-vm-name-help-icon',
310
- })
311
-
312
- const schedulerTaskForm = ref<UI_I_ScheduleNewTasksForm>(
313
- useDeepCopy(scheduledTaskDefaultFormFunc())
314
- )
315
- watch(
316
- props.schedulerTask,
317
- (newValue) => {
318
- if (!newValue?.isSchedulerTask) return
319
- schedulerTaskForm.value = newValue.data
320
- },
321
- { immediate: true, deep: true }
322
- )
323
- watch(
324
- schedulerTaskForm,
325
- (newValue: UI_I_ScheduleNewTasksForm) => {
326
- if (isScheduledTasks.value) wizard.setDisabledNextButton(newValue.isValid)
327
- },
328
- { immediate: true, deep: true }
329
- )
330
-
331
- const onChangeSteps = async (value: UI_I_WizardStep[]): Promise<void> => {
332
- wizard.changeSteps(value, validationFunc, validateSendData)
333
- }
334
-
335
- const validationFunc = async (
336
- value: UI_I_WizardStep[],
337
- currentStep: UI_I_WizardStep,
338
- nextStep: UI_I_WizardStep
339
- ): Promise<UI_I_ValidationReturn> => {
340
- let stepHasError = false
341
- let stepShouldStop = {
342
- ifOnCurrentStep: false,
343
- ifFromAnyStep: false,
344
- stoppageStepId: -1,
345
- }
346
-
347
- wizard.setLoader(true)
348
- if (
349
- wizard.isValidateForStep(
350
- isSphere.value ? dynamicSteps.selectNameFolder : dynamicSteps.selectName,
351
- currentStep.id,
352
- nextStep.id
353
- )
354
- ) {
355
- const nameValidation = await checkName(value)
356
-
357
- value = nameValidation.newValue
358
- stepHasError = stepHasError || nameValidation.stepHasError
359
- } else if (
360
- isSphere.value &&
361
- wizard.isValidateForStep(
362
- dynamicSteps.selectComputeResource,
363
- currentStep.id,
364
- nextStep.id
365
- )
366
- ) {
367
- const computeResourceValidation = await checkComputeResource(value)
368
-
369
- value = computeResourceValidation.newValue
370
- stepHasError = stepHasError || computeResourceValidation.stepHasError
371
- } else if (
372
- wizard.isValidateForStep(
373
- dynamicSteps.selectStorage,
374
- currentStep.id,
375
- nextStep.id
376
- )
377
- ) {
378
- const storageValidation = await checkStorage(value)
379
-
380
- value = storageValidation.newValue
381
-
382
- stepHasError = stepHasError || storageValidation.stepHasError
383
- } else if (
384
- wizard.isValidateForStep(
385
- dynamicSteps.customizeHardware,
386
- currentStep.id,
387
- nextStep.id
388
- )
389
- ) {
390
- const customizeHardwareValidation = await checkCustomizeHardware(value)
391
-
392
- value = customizeHardwareValidation.newValue
393
-
394
- stepHasError = stepHasError || customizeHardwareValidation.stepHasError
395
- }
396
- wizard.setLoader(false)
397
-
398
- return {
399
- newValue: value,
400
- stepHasError,
401
- stepShouldStop,
402
- }
403
- }
404
- const checkName = async (
405
- value: UI_I_WizardStep[]
406
- ): Promise<UI_I_ValidationReturn> => {
407
- let stepHasError = false
408
-
409
- return new Promise((resolve) => {
410
- const step = isSphere.value
411
- ? dynamicSteps.selectNameFolder
412
- : dynamicSteps.selectName
413
- nameFormSubmit.value = (isValid: boolean) => {
414
- if (!isValid) {
415
- stepHasError = wizard.setValidation(step, 'name', {
416
- fieldMessage: 'aaa',
417
- alertMessage: 'aaa',
418
- })
419
- } else if (wizard.hasMessage(step, 'name')) {
420
- value = wizard.removeValidation(step, 'name', value)
421
- }
422
-
423
- resolve({
424
- stepHasError,
425
- newValue: value,
426
- })
427
- nameFormSubmit.value = null
428
- }
429
- })
430
- }
431
- const compatibilityText = computed<[UI_T_CompatibilityStatus, string]>(() => {
432
- const { computeResource } = vmForm.value
433
-
434
- if (!computeResource)
435
- return [
436
- 'none',
437
- localization.value.vmWizard.noDestinationComputeResourceSelected,
438
- ]
439
-
440
- let res: [UI_T_CompatibilityStatus, string] = [
441
- 'success',
442
- localization.value.common.compatibilityChecksSucceeded,
443
- ]
444
-
445
- if (!['cluster', 'host', 'resource_pool'].includes(computeResource?.type)) {
446
- res = [
447
- 'error',
448
- localization.value.common.selectValidClusterOrHostDestination,
449
- ]
450
- }
451
- if (computeResource?.type === 'cluster') {
452
- const hasHost = !!computeResource.nodes.length
453
- if (!hasHost) {
454
- res = ['error', localization.value.common.clusterNotContainAnyHosts]
455
- }
456
- }
457
-
458
- if (computeResource?.type === 'host') {
459
- if (computeResource.state === 'Error') {
460
- // TODO check Maintenance Mode
461
- res = [
462
- 'error',
463
- localization.value.common.selectedHostDisconnectedMaintenanceMode,
464
- ]
465
- }
466
- }
467
-
468
- return res
469
- })
470
- const computeResourceAlert = ref<string[]>([])
471
- const checkComputeResource = (
472
- value: UI_I_WizardStep[]
473
- ): UI_I_ValidationReturn => {
474
- let stepHasError = false
475
-
476
- const { computeResource } = vmForm.value
477
-
478
- if (
479
- !computeResource ||
480
- // compatibilityText.value[0] !== 1 ||
481
- computeResource.type === 'datacenter' ||
482
- computeResource.type === 'folder' ||
483
- (computeResource.type === 'cluster' && !computeResource.nodes.length)
484
- ) {
485
- computeResourceAlert.value = [
486
- localization.value.common.specifyValidClusterOrHostDestination,
487
- ]
488
- stepHasError = wizard.setValidation(
489
- dynamicSteps.selectComputeResource,
490
- 'computeResource',
491
- {
492
- fieldMessage: 'aaa',
493
- alertMessage: 'aaa',
494
- }
495
- )
496
- } else {
497
- computeResourceAlert.value = []
498
- if (
499
- wizard.hasMessage(dynamicSteps.selectComputeResource, 'computeResource')
500
- ) {
501
- value = wizard.removeValidation(
502
- dynamicSteps.selectComputeResource,
503
- 'computeResource',
504
- value
505
- )
506
- }
507
- }
508
-
509
- return {
510
- stepHasError,
511
- newValue: value,
512
- }
513
- }
514
- const checkStorage = async (
515
- value: UI_I_WizardStep[]
516
- ): Promise<UI_I_ValidationReturn> => {
517
- let stepHasError = false
518
-
519
- return new Promise((resolve) => {
520
- storageSubmit.value = (isValid: boolean) => {
521
- if (!isValid) {
522
- stepHasError = wizard.setValidation(
523
- dynamicSteps.selectStorage,
524
- 'storage',
525
- {
526
- fieldMessage: 'aaa',
527
- alertMessage: 'aaa',
528
- }
529
- )
530
- } else if (wizard.hasMessage(dynamicSteps.selectStorage, 'storage')) {
531
- value = wizard.removeValidation(
532
- dynamicSteps.selectStorage,
533
- 'storage',
534
- value
535
- )
536
- }
537
-
538
- resolve({
539
- stepHasError,
540
- newValue: value,
541
- })
542
- storageSubmit.value = null
543
- }
544
- })
545
- }
546
- const checkCustomizeHardware = async (
547
- value: UI_I_WizardStep[]
548
- ): Promise<UI_I_ValidationReturn> => {
549
- let stepHasError = false
550
-
551
- return new Promise((resolve) => {
552
- customizeHardwareSubmit.value = (isValid: boolean) => {
553
- if (!isValid) {
554
- stepHasError = wizard.setValidation(
555
- dynamicSteps.customizeHardware,
556
- 'customizeHardware',
557
- {
558
- fieldMessage: 'aaa',
559
- alertMessage: 'aaa',
560
- }
561
- )
562
- } else if (
563
- wizard.hasMessage(dynamicSteps.customizeHardware, 'customizeHardware')
564
- ) {
565
- value = wizard.removeValidation(
566
- dynamicSteps.customizeHardware,
567
- 'customizeHardware',
568
- value
569
- )
570
- }
571
-
572
- resolve({
573
- stepHasError,
574
- newValue: value,
575
- })
576
- storageSubmit.value = null
577
- }
578
- })
579
- }
580
-
581
- const vmForm = ref<UI_I_VmForm>({
582
- name: '',
583
- compatibility: '',
584
- guestMachineType: null,
585
- guestOsFamily: null,
586
- guestOsVersion: null,
587
- computeResource: props.computeResource,
588
- storage: null,
589
- locationPath: '',
590
- dataCenter: null,
591
- options: [],
592
- })
593
-
594
- const isLoadingComputeTree = ref<boolean>(false)
595
- const onChangeName = (data: [string, UI_I_TreeNode | null]): void => {
596
- const [name, node] = data
597
-
598
- vmForm.value.name = name
599
- if (isSphere.value) {
600
- vmForm.value.locationPath = node.id
601
- vmForm.value.dataCenter = $recursion.findParentByValue(
602
- node,
603
- 'datacenter',
604
- 'type',
605
- 'parent'
606
- )
607
- isLoadingComputeTree.value = true
608
- emits('get-compute-resource-tree', {
609
- id: node.id,
610
- cb: () => {
611
- isLoadingComputeTree.value = false
612
- },
613
- })
614
- }
615
- }
616
- const onChangeStorage = (storage: UI_I_DatastoreTableItem | null): void => {
617
- if (!storage) return
618
-
619
- vmForm.value.storage = storage
620
- }
621
- const onChangeSelectOptions = (options: string[]): void => {
622
- vmForm.value.options = options
623
- if (
624
- options.includes('customize-os') &&
625
- options.includes('customize-hardware')
626
- ) {
627
- let procuratorSchame = isScheduledTasks.value ? 7 : 3
628
- let sphereSchame = isScheduledTasks.value ? 15 : 11
629
- wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
630
- } else if (options.includes('customize-os')) {
631
- let procuratorSchame = isScheduledTasks.value ? 5 : 1
632
- let sphereSchame = isScheduledTasks.value ? 13 : 9
633
- wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
634
- } else if (options.includes('customize-hardware')) {
635
- let procuratorSchame = isScheduledTasks.value ? 6 : 2
636
- let sphereSchame = isScheduledTasks.value ? 14 : 10
637
- wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
638
- } else {
639
- let procuratorSchame = isScheduledTasks.value ? 4 : 0
640
- let sphereSchame = isScheduledTasks.value ? 12 : 8
641
- wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
642
- }
643
-
644
- // Change power on by default
645
- isPowerOnByDefault.value = options.includes('power-on')
646
- isCreateLinkedClone.value = options.includes('create-linked-clone')
647
- }
648
- const cloneCount = ref<number>(1)
649
- const customizeHardware = ref<UI_I_SendDataCustomizeHardware | null>(null)
650
- const onChangeCustomizeHardware = (
651
- data: UI_I_SendDataCustomizeHardware
652
- ): void => {
653
- customizeHardware.value = data
654
- }
655
-
656
- const virtualHardwareHardDisksLocal = computed<
657
- UI_I_SendDataNewHardDisk[] | null
658
- >(() => customizeHardware.value?.virtualHardware?.hardDisks || null)
659
- const virtualHardwareNetworksLocal = computed<UI_I_SendDataNewNetwork[] | null>(
660
- () => customizeHardware.value?.virtualHardware?.networks || null
661
- )
662
- const virtualHardwareCdDvdDrivesLocal = computed<
663
- UI_I_SendDataNewCdDvdDrive[] | null
664
- >(() => customizeHardware.value?.virtualHardware?.cdDvdDrives || null)
665
-
666
- const virtualHardwareCpu = computed<UI_I_SendDataCpu | null>(
667
- () => customizeHardware.value?.virtualHardware?.cpu || null
668
- )
669
- const virtualHardwareMemory = computed<UI_I_SendDataMemory | null>(
670
- () => customizeHardware.value?.virtualHardware?.memory || null
671
- )
672
- const virtualHardwareHardDisks = ref<UI_I_SendDataNewHardDisk[] | null>(null)
673
- const virtualHardwareCdDvdDrives = ref<UI_I_SendDataNewCdDvdDrive[] | null>(
674
- null
675
- )
676
- const virtualHardwareNetworks = ref<UI_I_SendDataNewNetwork[] | null>(null)
677
- const onChangeBootOrder = (data: UI_T_ChangeBootOrder): void => {
678
- virtualHardwareHardDisks.value = data[0]
679
- virtualHardwareCdDvdDrives.value = data[1]
680
- virtualHardwareNetworks.value = data[2]
681
- }
682
-
683
- const isPowerOnByDefault = ref<boolean>(false)
684
- const isCreateLinkedClone = ref<boolean>(false)
685
-
686
- watch(
687
- () => props.vmNameInWizard,
688
- (newValue) => {
689
- vmForm.value.name = newValue
690
- }
691
- )
692
-
693
- const validateSendData = async (
694
- value: UI_I_WizardStep[]
695
- ): Promise<UI_I_ValidationReturn> => {
696
- wizard.setLoader(true)
697
- let stepHasError = false
698
-
699
- const data = await props.validateSendDataFunc(
700
- vmForm.value,
701
- virtualHardwareCpu.value,
702
- virtualHardwareMemory.value,
703
- customizeHardware.value,
704
- virtualHardwareNetworks.value,
705
- virtualHardwareHardDisks.value,
706
- virtualHardwareCdDvdDrives.value,
707
- isPowerOnByDefault.value,
708
- localization.value,
709
- vmForm.value.locationPath, // для сферы
710
- // computeResourcePath.value // для сферы
711
- vmSettings.value.host_id // для сферы // TODO rollback
712
- )
713
-
714
- wizard.setLoader(false)
715
- if (data) {
716
- stepHasError = true
717
- selectedNavItem.value = data[0]
718
- }
719
-
720
- return {
721
- stepHasError,
722
- newValue: value,
723
- }
724
- }
725
-
726
- const isLoading = ref<boolean>(false)
727
- const onFinish = (): void => {
728
- isLoading.value = true
729
- wizard.setLoader(false)
730
- props
731
- .finishFunc(
732
- vmForm.value,
733
- virtualHardwareCpu.value,
734
- virtualHardwareMemory.value,
735
- customizeHardware.value,
736
- virtualHardwareNetworks.value,
737
- virtualHardwareHardDisks.value,
738
- virtualHardwareCdDvdDrives.value,
739
- isPowerOnByDefault.value,
740
- localization.value,
741
- vmForm.value.locationPath, // для сферы
742
- // computeResourcePath.value, // для сферы
743
- vmSettings.value.host_id, // для сферы // TODO rollback
744
- false,
745
- schedulerTaskForm.value,
746
- props.schedulerTask,
747
- isCreateLinkedClone.value,
748
- cloneCount.value
749
- )
750
- .then(() => {
751
- isLoading.value = false
752
- onHideModal()
753
- wizard.setLoader(false)
754
- })
755
- }
756
-
757
- const selectedNavItem = ref<UI_T_SelectedNavItem>(0)
758
-
759
- const nameFormSubmit = ref<null | Function>(null)
760
- const storageSubmit = ref<null | Function>(null)
761
- const customizeHardwareSubmit = ref<null | Function>(null)
762
-
763
- const vmSettings = computed<UI_I_VmSettings | null>(() => props.vmSettings)
764
- const vmName = ref<string>(vmSettings.value?.name || '')
765
-
766
- const guestOsFamilies = ref<UI_I_OptionItem[]>(
767
- capabilities.value.guestOsFamilies
768
- )
769
- const guestOsVersions = ref<UI_I_ArbitraryObject<UI_I_OptionItem[]>>(
770
- capabilities.value.guestOsVersions
771
- )
772
- const machineTypes = ref<UI_I_OptionItem[]>(capabilities.value.machineTypes)
773
-
774
- // Для сферы
775
- const computeResourcePath = ref<string>('')
776
- const onSelectComputeResourceTree = (node: UI_I_TreeNode): void => {
777
- emits('select-compute-resource-tree', node)
778
- computeResourcePath.value = String(node.id)
779
- }
780
- watch(
781
- () => vmForm.value.computeResource,
782
- (newValue, oldValue) => {
783
- if (newValue && newValue.id !== oldValue?.id) {
784
- onSelectComputeResourceTree(newValue)
785
- }
786
- },
787
- { deep: true, immediate: true }
788
- )
789
-
790
- watch(vmSettings, (newValue) => {
791
- vmName.value = newValue?.name || ''
792
-
793
- if (newValue?.guestOsFamily)
794
- vmForm.value.guestOsFamily = newValue.guestOsFamily
795
- if (newValue?.guestMachineType)
796
- vmForm.value.guestMachineType = newValue.guestMachineType
797
- if (newValue?.guestOsVersion)
798
- vmForm.value.guestOsVersion = newValue.guestOsVersion
799
-
800
- if (newValue?.compatibility)
801
- vmForm.value.compatibility = newValue.compatibility
802
-
803
- if (newValue?.storage) {
804
- const datastore = props.datastore.find(
805
- (item) => item.id === newValue.storage.id
806
- )
807
- if (datastore) vmForm.value.storage = datastore
808
- }
809
- })
810
-
811
- const onHideModal = (): void => {
812
- emits('hide')
813
- }
814
- </script>
815
-
816
- <style scoped lang="scss"></style>
1
+ <template>
2
+ <common-vm-actions-clone-new
3
+ v-if="isNewView"
4
+ v-model="model"
5
+ v-model:scheduler-task-form="schedulerTaskForm"
6
+ v-model:compute-resource="vmForm.computeResource"
7
+ v-model:location="location"
8
+ :project="props.project"
9
+ :nodes="props.nodes"
10
+ :files="props.files"
11
+ :networks-table="props.networksTable"
12
+ :datastore="props.datastore"
13
+ :is-datastore-loading="props.isDatastoreLoading"
14
+ :error-validation-fields="props.errorValidationFields"
15
+ :ready-complete-table-info="props.readyCompleteTableInfo"
16
+ :vm-cpu-help-text-second="props.vmCpuHelpTextSecond"
17
+ :get-datastore-table-func="props.getDatastoreTableFunc"
18
+ :passthrough-devices="props.passthroughDevices"
19
+ :mediated-devices="props.mediatedDevices"
20
+ :name-request-url="props.nameRequestUrl"
21
+ :selected-virtual-machine="props.selectedVirtualMachine"
22
+ :is-new-vm-from-template="props.isNewVmFromTemplate"
23
+ :compute-resource-tree="props.computeResourceTree"
24
+ :location-nodes="props.locationNodes"
25
+ :wizard="wizard"
26
+ :selected-scheme="selectedScheme"
27
+ :title="title"
28
+ :name-form-submit="nameFormSubmit"
29
+ :storage-submit="storageSubmit"
30
+ :customize-hardware-submit="customizeHardwareSubmit"
31
+ :selected-nav-item="selectedNavItem"
32
+ :allowed-location-kinds="allowedLocationKinds"
33
+ :is-sphere="isSphere"
34
+ :location-description="locationDescription"
35
+ :name-test-ids="nameTestIds"
36
+ :guest-os-families="guestOsFamilies"
37
+ :guest-os-versions="guestOsVersions"
38
+ :machine-types="machineTypes"
39
+ :dynamic-steps="dynamicSteps"
40
+ :is-loading-compute-tree="isLoadingComputeTree"
41
+ :compute-resource-alert="computeResourceAlert"
42
+ :compatibility-text="compatibilityText"
43
+ :max-memory="maxMemory"
44
+ :cpu-models="cpuModels"
45
+ @get-folders-or-files="emits('get-folders-or-files', $event)"
46
+ @change-name="onChangeName"
47
+ @change-storage="onChangeStorage"
48
+ @change-select-options="onChangeSelectOptions"
49
+ @change-clone-count="cloneCount = $event"
50
+ @get-storage="emits('get-storage', $event)"
51
+ @get-active-device-child="emits('get-active-device-child', $event)"
52
+ @show-datastore-child="emits('show-datastore-child', $event)"
53
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
54
+ @get-networks-table="emits('get-networks-table', $event)"
55
+ @get-pci-devices="emits('get-pci-devices')"
56
+ @change-steps="onChangeSteps"
57
+ @hide="onHideModal"
58
+ @finish="onFinish"
59
+ />
60
+ <common-vm-actions-clone-old
61
+ v-else
62
+ v-model="model"
63
+ v-model:scheduler-task-form="schedulerTaskForm"
64
+ v-model:compute-resource="vmForm.computeResource"
65
+ v-model:location="location"
66
+ :project="props.project"
67
+ :nodes="props.nodes"
68
+ :files="props.files"
69
+ :networks-table="props.networksTable"
70
+ :datastore="props.datastore"
71
+ :is-datastore-loading="props.isDatastoreLoading"
72
+ :error-validation-fields="props.errorValidationFields"
73
+ :ready-complete-table-info="props.readyCompleteTableInfo"
74
+ :vm-cpu-help-text-second="props.vmCpuHelpTextSecond"
75
+ :get-datastore-table-func="props.getDatastoreTableFunc"
76
+ :passthrough-devices="props.passthroughDevices"
77
+ :mediated-devices="props.mediatedDevices"
78
+ :name-request-url="props.nameRequestUrl"
79
+ :selected-virtual-machine="props.selectedVirtualMachine"
80
+ :is-new-vm-from-template="props.isNewVmFromTemplate"
81
+ :compute-resource-tree="props.computeResourceTree"
82
+ :location-nodes="props.locationNodes"
83
+ :wizard="wizard"
84
+ :selected-scheme="selectedScheme"
85
+ :title="title"
86
+ :name-form-submit="nameFormSubmit"
87
+ :storage-submit="storageSubmit"
88
+ :customize-hardware-submit="customizeHardwareSubmit"
89
+ :selected-nav-item="selectedNavItem"
90
+ :is-loading="isLoading"
91
+ :allowed-location-kinds="allowedLocationKinds"
92
+ :is-sphere="isSphere"
93
+ :location-description="locationDescription"
94
+ :name-test-ids="nameTestIds"
95
+ :guest-os-families="guestOsFamilies"
96
+ :guest-os-versions="guestOsVersions"
97
+ :machine-types="machineTypes"
98
+ :dynamic-steps="dynamicSteps"
99
+ :is-loading-compute-tree="isLoadingComputeTree"
100
+ :compute-resource-alert="computeResourceAlert"
101
+ :compatibility-text="compatibilityText"
102
+ :max-memory="maxMemory"
103
+ :cpu-models="cpuModels"
104
+ @get-folders-or-files="emits('get-folders-or-files', $event)"
105
+ @change-name="onChangeName"
106
+ @change-storage="onChangeStorage"
107
+ @change-select-options="onChangeSelectOptions"
108
+ @change-clone-count="cloneCount = $event"
109
+ @get-storage="emits('get-storage', $event)"
110
+ @get-active-device-child="emits('get-active-device-child', $event)"
111
+ @show-datastore-child="emits('show-datastore-child', $event)"
112
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
113
+ @get-networks-table="emits('get-networks-table', $event)"
114
+ @get-pci-devices="emits('get-pci-devices')"
115
+ @change-steps="onChangeSteps"
116
+ @hide="onHideModal"
117
+ @finish="onFinish"
118
+ />
119
+ </template>
120
+
121
+ <script setup lang="ts">
122
+ import type {
123
+ UI_I_ValidationReturn,
124
+ UI_I_WizardStep,
125
+ } from '~/node_modules/bfg-uikit/components/ui/wizard/lib/models/interfaces'
126
+ import Wizard from '~/node_modules/bfg-uikit/components/ui/wizard/lib/utils/utils'
127
+ import type {
128
+ UI_I_DatastoreTableItem,
129
+ UI_I_FolderOrFileTreePayload,
130
+ } from '~/lib/models/store/storage/interfaces'
131
+ import type { UI_I_NetworkTableItem } from '~/lib/models/store/network/interfaces'
132
+ import type { UI_I_TablePayload } from '~/lib/models/table/interfaces'
133
+ import type { UI_I_FileTreeNode } from '~/components/lib/models/interfaces'
134
+ import type {
135
+ UI_I_ArbitraryObject,
136
+ UI_I_Localization,
137
+ } from '~/lib/models/interfaces'
138
+ import type { UI_I_ErrorValidationField } from '~/lib/models/store/interfaces'
139
+ import type { UI_T_SelectedNavItem } from '~/components/common/vm/actions/common/lib/models/types'
140
+ import type { UI_I_TableInfoItem } from '~/components/atoms/table/info/lib/models/interfaces'
141
+ import type { UI_T_Project } from '~/lib/models/types'
142
+ import type {
143
+ UI_I_MediatedDevice,
144
+ UI_I_PciDevice,
145
+ } from '~/lib/models/store/vm/interfaces'
146
+ import type {UI_I_CreateVmData, UI_I_VmForm} from '~/components/common/vm/actions/common/lib/models/interfaces'
147
+ import type { UI_I_Capabilities } from '~/components/common/vm/actions/common/lib/models/interfaces'
148
+ import type { UI_I_ScheduleNewTasksForm } from '~/components/common/pages/scheduledTasks/modals/lib/models/interfaces'
149
+ import type { UI_I_OptionItem } from '~/components/atoms/lib/models/interfaces'
150
+ import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
151
+ import type { UI_I_NameTestIds } from '~/components/common/wizards/common/steps/name/lib/models/interfaces'
152
+ import type { UI_T_CompatibilityStatus } from '~/components/common/wizards/common/compatibility/lib/models/types'
153
+ import {
154
+ stepsSchemeInitial,
155
+ stepsFunc,
156
+ dynamicSteps,
157
+ } from '~/components/common/vm/actions/clone/lib/config/steps'
158
+ import { mapCapabilities } from '~/components/common/vm/actions/common/lib/utils/capabilities'
159
+ import { scheduledTaskDefaultFormFunc } from '~/components/common/pages/scheduledTasks/modals/lib/config/createScheduledTask'
160
+ import { capabilities } from '~/components/common/vm/actions/common/lib/config/capabilities'
161
+
162
+ const model = defineModel<UI_I_CreateVmData>({ required: true })
163
+
164
+ const props = withDefaults(
165
+ defineProps<{
166
+ project: UI_T_Project
167
+ nodes: UI_I_FileTreeNode[]
168
+ files: UI_I_FileTreeNode[]
169
+ networksTable: UI_I_NetworkTableItem[]
170
+ datastore: UI_I_DatastoreTableItem[]
171
+ isDatastoreLoading: boolean
172
+ errorValidationFields: UI_I_ErrorValidationField[]
173
+ readyCompleteTableInfo: UI_I_TableInfoItem[]
174
+ vmCpuHelpTextSecond: string
175
+ finishFunc: any
176
+ getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
177
+ validateSendDataFunc: any
178
+ passthroughDevices: UI_I_PciDevice[]
179
+ mediatedDevices: UI_I_MediatedDevice[]
180
+ vmNameInWizard: string
181
+ nameRequestUrl: string
182
+ capabilities?: UI_I_Capabilities
183
+ schedulerTask?: any // TODO надо interface переместить глобално
184
+ selectedVirtualMachine?: string
185
+ isNewVmFromTemplate?: boolean
186
+ dataCenter?: UI_I_TreeNode | null // для сферы
187
+ computeResource?: UI_I_TreeNode // для сферы
188
+ computeResourceTree?: UI_I_TreeNode[] // для сферы
189
+ locationNodes?: UI_I_TreeNode[] // для сферы
190
+ }>(),
191
+ {
192
+ capabilities: undefined,
193
+ schedulerTask: undefined,
194
+ selectedVirtualMachine: '',
195
+ isNewVmFromTemplate: undefined,
196
+ dataCenter: null,
197
+ computeResource: null,
198
+ computeResourceTree: undefined,
199
+ locationNodes: () => [],
200
+ }
201
+ )
202
+
203
+ const emits = defineEmits<{
204
+ (event: 'get-storage', value: UI_I_TablePayload): void
205
+ (event: 'get-folders-or-files', value: UI_I_FolderOrFileTreePayload): void
206
+ (event: 'get-active-device-child', value: UI_I_FileTreeNode): void
207
+ (event: 'show-datastore-child', value: UI_I_FileTreeNode): void
208
+ (event: 'remove-error-by-title', value: string): void
209
+ (event: 'get-networks-table', value: UI_I_TablePayload): void
210
+ (event: 'get-pci-devices'): void
211
+ (event: 'hide'): void
212
+ (
213
+ event: 'get-compute-resource-tree',
214
+ value: { id: string | number; cb: () => void }
215
+ ): void // для сферы
216
+ (event: 'select-compute-resource-tree', value: UI_I_TreeNode): void // для сферы
217
+ }>()
218
+
219
+ const { $store, $recursion } = useNuxtApp()
220
+
221
+ const isNewView = computed<boolean>(() => $store.getters['main/getIsNewView'])
222
+
223
+ const localization = computed<UI_I_Localization>(() => useLocal())
224
+
225
+ const isSphere = computed<boolean>(() => props.project === 'sphere')
226
+
227
+ const location = ref<UI_I_TreeNode | null>(props.dataCenter) // для сферы
228
+
229
+ const isScheduledTasks = computed<boolean>(
230
+ () => props.schedulerTask?.isSchedulerTask
231
+ )
232
+
233
+ const title = computed<string>(() => {
234
+ const { scheduleNewTasks, scheduleTaskEdit, cloneExistingVirtualMachine } =
235
+ localization.value.common
236
+
237
+ let result = cloneExistingVirtualMachine
238
+ if (isScheduledTasks.value) {
239
+ const schedulerMode = props.schedulerTask.editTask
240
+ ? scheduleTaskEdit
241
+ : scheduleNewTasks
242
+
243
+ result = `${schedulerMode} (${cloneExistingVirtualMachine})`
244
+ }
245
+
246
+ if (props.isNewVmFromTemplate) {
247
+ result = localization.value.vmWizard.deployFromTemplate
248
+ }
249
+
250
+ return result
251
+ })
252
+
253
+ watch(
254
+ () => props.capabilities,
255
+ () => {
256
+ if (props.capabilities) {
257
+ mapCapabilities(props.capabilities)
258
+ }
259
+ },
260
+ { deep: true, immediate: true }
261
+ )
262
+
263
+ const cpuModels = ref<UI_I_OptionItem[]>(capabilities.value.cpuModels)
264
+ const maxMemory = ref<number>(capabilities.value.maxMemory)
265
+
266
+ const wizard: Wizard = new Wizard(
267
+ stepsFunc(localization.value),
268
+ stepsSchemeInitial
269
+ )
270
+
271
+ const selectedScheme = computed<number[]>(() => wizard.selectedScheme.value)
272
+
273
+ watch(
274
+ isScheduledTasks,
275
+ (newValue: boolean) => {
276
+ if (newValue) {
277
+ wizard.changeScheme(isSphere.value ? 12 : 4)
278
+ } else {
279
+ wizard.changeScheme(isSphere.value ? 8 : 0)
280
+ wizard.selectStepHard(isSphere.value ? 2 : 1)
281
+ }
282
+ },
283
+ { immediate: true }
284
+ )
285
+
286
+ const allowedLocationKinds = ref<number[]>([3, 7]) // TODO use from config
287
+ const locationDescription = computed<string>(
288
+ () => localization.value.common.selectLocationVirtualMachine
289
+ )
290
+
291
+ const nameTestIds = ref<UI_I_NameTestIds>({
292
+ name: 'virtual-machine-name',
293
+ helpIcon: 'show-vm-name-help-icon',
294
+ })
295
+
296
+ const schedulerTaskForm = ref<UI_I_ScheduleNewTasksForm>(
297
+ useDeepCopy(scheduledTaskDefaultFormFunc())
298
+ )
299
+ watch(
300
+ props.schedulerTask,
301
+ (newValue) => {
302
+ if (!newValue?.isSchedulerTask) return
303
+ schedulerTaskForm.value = newValue.data
304
+ },
305
+ { immediate: true, deep: true }
306
+ )
307
+ watch(
308
+ schedulerTaskForm,
309
+ (newValue: UI_I_ScheduleNewTasksForm) => {
310
+ if (isScheduledTasks.value) wizard.setDisabledNextButton(newValue.isValid)
311
+ },
312
+ { immediate: true, deep: true }
313
+ )
314
+
315
+ const onChangeSteps = async (value: UI_I_WizardStep[]): Promise<void> => {
316
+ wizard.changeSteps(value, validationFunc, validateSendData)
317
+ }
318
+
319
+ const validationFunc = async (
320
+ value: UI_I_WizardStep[],
321
+ currentStep: UI_I_WizardStep,
322
+ nextStep: UI_I_WizardStep
323
+ ): Promise<UI_I_ValidationReturn> => {
324
+ let stepHasError = false
325
+ let stepShouldStop = {
326
+ ifOnCurrentStep: false,
327
+ ifFromAnyStep: false,
328
+ stoppageStepId: -1,
329
+ }
330
+
331
+ wizard.setLoader(true)
332
+ if (
333
+ wizard.isValidateForStep(
334
+ isSphere.value ? dynamicSteps.selectNameFolder : dynamicSteps.selectName,
335
+ currentStep.id,
336
+ nextStep.id
337
+ )
338
+ ) {
339
+ const nameValidation = await checkName(value)
340
+
341
+ value = nameValidation.newValue
342
+ stepHasError = stepHasError || nameValidation.stepHasError
343
+ } else if (
344
+ isSphere.value &&
345
+ wizard.isValidateForStep(
346
+ dynamicSteps.selectComputeResource,
347
+ currentStep.id,
348
+ nextStep.id
349
+ )
350
+ ) {
351
+ const computeResourceValidation = await checkComputeResource(value)
352
+
353
+ value = computeResourceValidation.newValue
354
+ stepHasError = stepHasError || computeResourceValidation.stepHasError
355
+ } else if (
356
+ wizard.isValidateForStep(
357
+ dynamicSteps.selectStorage,
358
+ currentStep.id,
359
+ nextStep.id
360
+ )
361
+ ) {
362
+ const storageValidation = await checkStorage(value)
363
+
364
+ value = storageValidation.newValue
365
+
366
+ stepHasError = stepHasError || storageValidation.stepHasError
367
+ } else if (
368
+ wizard.isValidateForStep(
369
+ dynamicSteps.customizeHardware,
370
+ currentStep.id,
371
+ nextStep.id
372
+ )
373
+ ) {
374
+ const customizeHardwareValidation = await checkCustomizeHardware(value)
375
+
376
+ value = customizeHardwareValidation.newValue
377
+
378
+ stepHasError = stepHasError || customizeHardwareValidation.stepHasError
379
+ }
380
+ wizard.setLoader(false)
381
+
382
+ return {
383
+ newValue: value,
384
+ stepHasError,
385
+ stepShouldStop,
386
+ }
387
+ }
388
+ const checkName = async (
389
+ value: UI_I_WizardStep[]
390
+ ): Promise<UI_I_ValidationReturn> => {
391
+ let stepHasError = false
392
+
393
+ return new Promise((resolve) => {
394
+ const step = isSphere.value
395
+ ? dynamicSteps.selectNameFolder
396
+ : dynamicSteps.selectName
397
+ nameFormSubmit.value = (isValid: boolean) => {
398
+ if (!isValid) {
399
+ stepHasError = wizard.setValidation(step, 'name', {
400
+ fieldMessage: 'aaa',
401
+ alertMessage: 'aaa',
402
+ })
403
+ } else if (wizard.hasMessage(step, 'name')) {
404
+ value = wizard.removeValidation(step, 'name', value)
405
+ }
406
+
407
+ resolve({
408
+ stepHasError,
409
+ newValue: value,
410
+ })
411
+ nameFormSubmit.value = null
412
+ }
413
+ })
414
+ }
415
+ const compatibilityText = computed<[UI_T_CompatibilityStatus, string]>(() => {
416
+ const { computeResource } = vmForm.value
417
+
418
+ if (!computeResource)
419
+ return [
420
+ 'none',
421
+ localization.value.vmWizard.noDestinationComputeResourceSelected,
422
+ ]
423
+
424
+ let res: [UI_T_CompatibilityStatus, string] = [
425
+ 'success',
426
+ localization.value.common.compatibilityChecksSucceeded,
427
+ ]
428
+
429
+ if (!['cluster', 'host', 'resource_pool'].includes(computeResource?.type)) {
430
+ res = [
431
+ 'error',
432
+ localization.value.common.selectValidClusterOrHostDestination,
433
+ ]
434
+ }
435
+ if (computeResource?.type === 'cluster') {
436
+ const hasHost = !!computeResource.nodes.length
437
+ if (!hasHost) {
438
+ res = ['error', localization.value.common.clusterNotContainAnyHosts]
439
+ }
440
+ }
441
+
442
+ if (computeResource?.type === 'host') {
443
+ if (computeResource.state === 'Error') {
444
+ // TODO check Maintenance Mode
445
+ res = [
446
+ 'error',
447
+ localization.value.common.selectedHostDisconnectedMaintenanceMode,
448
+ ]
449
+ }
450
+ }
451
+
452
+ return res
453
+ })
454
+ const computeResourceAlert = ref<string[]>([])
455
+ const checkComputeResource = (
456
+ value: UI_I_WizardStep[]
457
+ ): UI_I_ValidationReturn => {
458
+ let stepHasError = false
459
+
460
+ const { computeResource } = vmForm.value
461
+
462
+ if (
463
+ !computeResource ||
464
+ // compatibilityText.value[0] !== 1 ||
465
+ computeResource.type === 'datacenter' ||
466
+ computeResource.type === 'folder' ||
467
+ (computeResource.type === 'cluster' && !computeResource.nodes.length)
468
+ ) {
469
+ computeResourceAlert.value = [
470
+ localization.value.common.specifyValidClusterOrHostDestination,
471
+ ]
472
+ stepHasError = wizard.setValidation(
473
+ dynamicSteps.selectComputeResource,
474
+ 'computeResource',
475
+ {
476
+ fieldMessage: 'aaa',
477
+ alertMessage: 'aaa',
478
+ }
479
+ )
480
+ } else {
481
+ computeResourceAlert.value = []
482
+ if (
483
+ wizard.hasMessage(dynamicSteps.selectComputeResource, 'computeResource')
484
+ ) {
485
+ value = wizard.removeValidation(
486
+ dynamicSteps.selectComputeResource,
487
+ 'computeResource',
488
+ value
489
+ )
490
+ }
491
+ }
492
+
493
+ return {
494
+ stepHasError,
495
+ newValue: value,
496
+ }
497
+ }
498
+ const checkStorage = async (
499
+ value: UI_I_WizardStep[]
500
+ ): Promise<UI_I_ValidationReturn> => {
501
+ let stepHasError = false
502
+
503
+ return new Promise((resolve) => {
504
+ storageSubmit.value = (isValid: boolean) => {
505
+ if (!isValid) {
506
+ stepHasError = wizard.setValidation(
507
+ dynamicSteps.selectStorage,
508
+ 'storage',
509
+ {
510
+ fieldMessage: 'aaa',
511
+ alertMessage: 'aaa',
512
+ }
513
+ )
514
+ } else if (wizard.hasMessage(dynamicSteps.selectStorage, 'storage')) {
515
+ value = wizard.removeValidation(
516
+ dynamicSteps.selectStorage,
517
+ 'storage',
518
+ value
519
+ )
520
+ }
521
+
522
+ resolve({
523
+ stepHasError,
524
+ newValue: value,
525
+ })
526
+ storageSubmit.value = null
527
+ }
528
+ })
529
+ }
530
+ const checkCustomizeHardware = async (
531
+ value: UI_I_WizardStep[]
532
+ ): Promise<UI_I_ValidationReturn> => {
533
+ let stepHasError = false
534
+
535
+ return new Promise((resolve) => {
536
+ customizeHardwareSubmit.value = (isValid: boolean) => {
537
+ if (!isValid) {
538
+ stepHasError = wizard.setValidation(
539
+ dynamicSteps.customizeHardware,
540
+ 'customizeHardware',
541
+ {
542
+ fieldMessage: 'aaa',
543
+ alertMessage: 'aaa',
544
+ }
545
+ )
546
+ } else if (
547
+ wizard.hasMessage(dynamicSteps.customizeHardware, 'customizeHardware')
548
+ ) {
549
+ value = wizard.removeValidation(
550
+ dynamicSteps.customizeHardware,
551
+ 'customizeHardware',
552
+ value
553
+ )
554
+ }
555
+
556
+ resolve({
557
+ stepHasError,
558
+ newValue: value,
559
+ })
560
+ storageSubmit.value = null
561
+ }
562
+ })
563
+ }
564
+
565
+ const vmForm = ref<UI_I_VmForm>({
566
+ locationPath: '',
567
+ dataCenter: null,
568
+ })
569
+
570
+ const isLoadingComputeTree = ref<boolean>(false)
571
+ const onChangeName = (data: [string, UI_I_TreeNode | null]): void => {
572
+ const [_name, node] = data
573
+ // vmForm.value.name = name
574
+ if (isSphere.value) {
575
+ vmForm.value.locationPath = node.id
576
+ vmForm.value.dataCenter = $recursion.findParentByValue(
577
+ node,
578
+ 'datacenter',
579
+ 'type',
580
+ 'parent'
581
+ )
582
+ isLoadingComputeTree.value = true
583
+ emits('get-compute-resource-tree', {
584
+ id: node.id,
585
+ cb: () => {
586
+ isLoadingComputeTree.value = false
587
+ },
588
+ })
589
+ }
590
+ }
591
+ const onChangeStorage = (storage: UI_I_DatastoreTableItem | null): void => {
592
+ if (!storage) return
593
+
594
+ // vmForm.value.storage = storage
595
+ model.value.storage = storage
596
+ }
597
+ const onChangeSelectOptions = (options: string[]): void => {
598
+ // vmForm.value.options = options
599
+ if (
600
+ options.includes('customize-os') &&
601
+ options.includes('customize-hardware')
602
+ ) {
603
+ let procuratorSchame = isScheduledTasks.value ? 7 : 3
604
+ let sphereSchame = isScheduledTasks.value ? 15 : 11
605
+ wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
606
+ } else if (options.includes('customize-os')) {
607
+ let procuratorSchame = isScheduledTasks.value ? 5 : 1
608
+ let sphereSchame = isScheduledTasks.value ? 13 : 9
609
+ wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
610
+ } else if (options.includes('customize-hardware')) {
611
+ let procuratorSchame = isScheduledTasks.value ? 6 : 2
612
+ let sphereSchame = isScheduledTasks.value ? 14 : 10
613
+ wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
614
+ } else {
615
+ let procuratorSchame = isScheduledTasks.value ? 4 : 0
616
+ let sphereSchame = isScheduledTasks.value ? 12 : 8
617
+ wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
618
+ }
619
+
620
+ // Change power on by default
621
+ isPowerOnByDefault.value = options.includes('power-on')
622
+ isCreateLinkedClone.value = options.includes('create-linked-clone')
623
+ }
624
+ const isPowerOnByDefault = ref<boolean>(false)
625
+ const isCreateLinkedClone = ref<boolean>(false)
626
+ const cloneCount = ref<number>(0)
627
+
628
+ watch(
629
+ () => props.vmNameInWizard,
630
+ (newValue) => {
631
+ // vmForm.value.name = newValue
632
+ model.value.name = newValue
633
+ }
634
+ )
635
+
636
+ const validateSendData = async (
637
+ value: UI_I_WizardStep[]
638
+ ): Promise<UI_I_ValidationReturn> => {
639
+ wizard.setLoader(true)
640
+ let stepHasError = false
641
+
642
+ const data = await props.validateSendDataFunc(
643
+ model.value,
644
+ isPowerOnByDefault.value,
645
+ localization.value,
646
+ vmForm.value.locationPath, // для сферы
647
+ // computeResourcePath.value // для сферы
648
+ model.value.host_id // для сферы // TODO rollback
649
+ )
650
+
651
+ wizard.setLoader(false)
652
+ if (data) {
653
+ stepHasError = true
654
+ selectedNavItem.value = data[0]
655
+ }
656
+
657
+ return {
658
+ stepHasError,
659
+ newValue: value,
660
+ }
661
+ }
662
+
663
+ const isLoading = ref<boolean>(false)
664
+ const onFinish = (): void => {
665
+ isLoading.value = true
666
+ wizard.setLoader(false)
667
+ props
668
+ .finishFunc(
669
+ model.value,
670
+ isPowerOnByDefault.value,
671
+ localization.value,
672
+ vmForm.value.locationPath, // для сферы
673
+ // computeResourcePath.value, // для сферы
674
+ model.value.host_id, // для сферы // TODO rollback
675
+ false,
676
+ schedulerTaskForm.value,
677
+ props.schedulerTask,
678
+ isCreateLinkedClone.value,
679
+ cloneCount.value
680
+ )
681
+ .then(() => {
682
+ isLoading.value = false
683
+ onHideModal()
684
+ wizard.setLoader(false)
685
+ })
686
+ }
687
+
688
+ const selectedNavItem = ref<UI_T_SelectedNavItem>(0)
689
+
690
+ const nameFormSubmit = ref<null | Function>(null)
691
+ const storageSubmit = ref<null | Function>(null)
692
+ const customizeHardwareSubmit = ref<null | Function>(null)
693
+
694
+ const guestOsFamilies = ref<UI_I_OptionItem[]>(
695
+ capabilities.value.guestOsFamilies
696
+ )
697
+ const guestOsVersions = ref<UI_I_ArbitraryObject<UI_I_OptionItem[]>>(
698
+ capabilities.value.guestOsVersions
699
+ )
700
+ const machineTypes = ref<UI_I_OptionItem[]>(capabilities.value.machineTypes)
701
+
702
+ // Для сферы
703
+ const computeResourcePath = ref<string>('')
704
+ const onSelectComputeResourceTree = (node: UI_I_TreeNode): void => {
705
+ emits('select-compute-resource-tree', node)
706
+ computeResourcePath.value = String(node.id)
707
+ }
708
+ watch(
709
+ () => vmForm.value.computeResource,
710
+ (newValue, oldValue) => {
711
+ if (newValue && newValue.id !== oldValue?.id) {
712
+ onSelectComputeResourceTree(newValue)
713
+ }
714
+ },
715
+ { deep: true, immediate: true }
716
+ )
717
+
718
+ // watch(vmSettings, (newValue) => {
719
+ // vmName.value = newValue?.name || ''
720
+ //
721
+ // if (newValue?.guestOsFamily)
722
+ // vmForm.value.guestOsFamily = newValue.guestOsFamily
723
+ // if (newValue?.guestMachineType)
724
+ // vmForm.value.guestMachineType = newValue.guestMachineType
725
+ // if (newValue?.guestOsVersion)
726
+ // vmForm.value.guestOsVersion = newValue.guestOsVersion
727
+ //
728
+ // if (newValue?.compatibility)
729
+ // vmForm.value.compatibility = newValue.compatibility
730
+ //
731
+ // if (newValue?.storage) {
732
+ // const datastore = props.datastore.find(
733
+ // (item) => item.id === newValue.storage.id
734
+ // )
735
+ // if (datastore) vmForm.value.storage = datastore
736
+ // }
737
+ // })
738
+
739
+ const onHideModal = (): void => {
740
+ emits('hide')
741
+ }
742
+ </script>
743
+
744
+ <style scoped lang="scss"></style>