bfg-common 1.5.134 → 1.5.135

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,801 +1,801 @@
1
- <template>
2
- <div class="clone-vm">
3
- <atoms-wizard
4
- show
5
- :wizard="wizard"
6
- :selected-scheme="selectedScheme"
7
- :title="title"
8
- :localization="localization"
9
- @change-steps="onChangeSteps"
10
- @hide="onHideModal"
11
- @submit="onFinish"
12
- >
13
- <template #modalBody="{ selectedStep }">
14
- <atoms-loader v-show="!vmSettings" id="loader" />
15
- <div v-if="vmSettings" class="vm-context">
16
- <common-pages-scheduled-tasks-modals-common-new-task-form
17
- v-show="selectedStep.id === dynamicSteps.scheduledTasks"
18
- v-model="newTaskForm"
19
- :target="selectedVirtualMachine"
20
- class="new-task-form"
21
- />
22
- <common-vm-actions-common-select-name
23
- v-show="
24
- selectedStep.id === dynamicSteps.selectName ||
25
- selectedStep.id === dynamicSteps.selectNameFolder
26
- "
27
- :show="
28
- selectedStep.id === dynamicSteps.selectName ||
29
- selectedStep.id === dynamicSteps.selectNameFolder
30
- "
31
- :name-form-submit="nameFormSubmit"
32
- :project="props.project"
33
- :data-center="props.dataCenter"
34
- @submit="onChangeName(...$event)"
35
- @check-name="emits('check-name', $event)"
36
- />
37
- <common-vm-actions-common-select-compute-resource
38
- v-if="isSphere"
39
- v-show="selectedStep.id === dynamicSteps.selectComputeResource"
40
- v-model="computeResource"
41
- :compute-resource-submit="computeResourceSubmit"
42
- :data-center="vmForm.dataCenter"
43
- :compute-resource="props.computeResource"
44
- :compute-resource-tree="props.computeResourceTree"
45
- @submit="onChangeComputeResource"
46
- @select-compute-resource-tree="onSelectComputeResourceTree"
47
- @get-compute-resource-tree="
48
- emits('get-compute-resource-tree', $event)
49
- "
50
- @show-compute-resource-tree="
51
- emits('show-compute-resource-tree', $event)
52
- "
53
- @clear-compute-resource-tree="emits('clear-compute-resource-tree')"
54
- />
55
- <common-vm-actions-common-select-storage
56
- v-show="selectedStep.id === dynamicSteps.selectStorage"
57
- :storage-submit="storageSubmit"
58
- :datastore="props.datastore"
59
- :storage="vmSettings.storage"
60
- :get-datastore-table-func="props.getDatastoreTableFunc"
61
- @submit="onChangeStorage"
62
- />
63
- <common-vm-actions-common-select-options
64
- v-show="selectedStep.id === dynamicSteps.selectOptions"
65
- @change="onChangeSelectOptions"
66
- />
67
- <common-vm-actions-common-select-os
68
- v-show="selectedStep.id === dynamicSteps.selectGuestOSMachineType"
69
- v-model:machine-type="vmForm.guestMachineType"
70
- v-model:guest-os-family="vmForm.guestOsFamily"
71
- v-model:guest-os-version="vmForm.guestOsVersion"
72
- :families-options="guestOsFamilies"
73
- :versions-options="guestOsVersions"
74
- :machine-types-options="machineTypes"
75
- :error-validation-fields="props.errorValidationFields"
76
- @remove-error-by-title="emits('remove-error-by-title', $event)"
77
- />
78
- <common-vm-actions-common-customize-hardware
79
- v-show="selectedStep.id === dynamicSteps.customizeHardware"
80
- v-model:vm-name="vmName"
81
- v-model:guest-machine-type="vmSettings.guestMachineType"
82
- v-model:guest-os-family="vmSettings.guestOsFamily"
83
- v-model:guest-os-version="vmSettings.guestOsVersion"
84
- :storage="vmSettings.storage"
85
- :hard-disks-for-boot-options="virtualHardwareHardDisksLocal"
86
- :cd-dvd-drives-for-boot-options="virtualHardwareCdDvdDrivesLocal"
87
- :networks-for-boot-options="virtualHardwareNetworksLocal"
88
- :cd-dvd-drives="vmSettings.cdDvdDrives"
89
- :hard-disks="vmSettings.hardDisks"
90
- :networks="vmSettings.networks"
91
- :customize-hardware-submit="customizeHardwareSubmit"
92
- :max-cpus="vmSettings.maxCpus"
93
- :max-memory="vmSettings.maxMemory"
94
- :cpu-models="vmSettings.cpuModels"
95
- :cpu="vmSettings.cpu"
96
- :memory="vmSettings.memory"
97
- :video-card="vmSettings.videoCard"
98
- :usb-controller="vmSettings.usbController"
99
- :pci-devices="vmSettings.pciDevices"
100
- :selected-nav-item="selectedNavItem"
101
- :hard-disks-for-edit="vmSettings.hardDisks"
102
- :options="vmSettings.options"
103
- :nodes="props.nodes"
104
- :files="props.files"
105
- :networks-table="props.networksTable"
106
- :error-validation-fields="props.errorValidationFields"
107
- :vm-cpu-help-text-second="props.vmCpuHelpTextSecond"
108
- :passthrough-devices="props.passthroughDevices"
109
- :mediated-devices="props.mediatedDevices"
110
- :get-datastore-table-func="props.getDatastoreTableFunc"
111
- :datastore="props.datastore"
112
- :project="props.project"
113
- is-clone
114
- @change-boot-order="onChangeBootOrder"
115
- @send-data="onChangeCustomizeHardware"
116
- @get-storage="emits('get-storage', $event)"
117
- @get-folders-or-files="emits('get-folders-or-files', $event)"
118
- @get-active-device-child="emits('get-active-device-child', $event)"
119
- @show-datastore-child="emits('show-datastore-child', $event)"
120
- @get-networks-table="emits('get-networks-table', $event)"
121
- @get-pci-devices="emits('get-pci-devices')"
122
- />
123
- <common-ready-to-complete
124
- v-show="selectedStep.id === dynamicSteps.readyComplete"
125
- :data="props.readyCompleteTableInfo"
126
- />
127
- </div>
128
- </template>
129
- </atoms-wizard>
130
- </div>
131
- </template>
132
-
133
- <script setup lang="ts">
134
- import type {
135
- UI_I_DatastoreTableItem,
136
- UI_I_FolderOrFileTreePayload,
137
- } from '~/lib/models/store/storage/interfaces'
138
- import type { UI_I_NetworkTableItem } from '~/lib/models/store/network/interfaces'
139
- import type { API_UI_I_Error } from '~/lib/models/store/interfaces'
140
- import type { UI_I_TablePayload } from '~/lib/models/table/interfaces'
141
- import type { UI_I_FileTreeNode } from '~/components/lib/models/interfaces'
142
- import type {
143
- UI_I_ArbitraryObject,
144
- UI_I_Localization,
145
- } from '~/lib/models/interfaces'
146
- import type { UI_I_SendDataCustomizeHardware } from '~/components/common/vm/actions/common/customizeHardware/lib/models/interfaces'
147
- import type { UI_I_ErrorValidationField } from '~/lib/models/store/interfaces'
148
- import type {
149
- UI_I_SendDataCpu,
150
- UI_I_SendDataMemory,
151
- UI_I_SendDataNewCdDvdDrive,
152
- UI_I_SendDataNewHardDisk,
153
- UI_I_SendDataNewNetwork,
154
- } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/models/interfaces'
155
- import type { UI_T_SelectedNavItem } from '~/components/common/vm/actions/common/lib/models/types'
156
- import type { UI_I_TableInfoItem } from '~/components/atoms/table/info/lib/models/interfaces'
157
- import type { UI_T_ChangeBootOrder } from '~/components/common/vm/actions/lib/models/types'
158
- import type { UI_T_Project } from '~/lib/models/types'
159
- import type {
160
- UI_I_MediatedDevice,
161
- UI_I_PciDevice,
162
- UI_I_VmSettings,
163
- } from '~/lib/models/store/vm/interfaces'
164
- import type { UI_I_VmForm } from '~/components/common/vm/actions/common/lib/models/interfaces'
165
- import type {
166
- UI_I_ValidationReturn,
167
- UI_I_WizardStep,
168
- } from '~/components/atoms/wizard/lib/models/interfaces'
169
- import type { UI_I_Capabilities } from '~/components/common/vm/actions/common/lib/models/interfaces'
170
- import type { UI_I_ScheduleNewTasksForm } from '~/components/common/pages/scheduledTasks/modals/lib/models/interfaces'
171
- import type { UI_I_OptionItem } from '~/components/atoms/lib/models/interfaces'
172
- import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
173
- import {
174
- stepsSchemeInitial,
175
- stepsFunc,
176
- dynamicSteps,
177
- } from '~/components/common/vm/actions/clone/lib/config/steps'
178
- import Wizard from '~/components/atoms/wizard/lib/utils/utils'
179
- import { mapCapabilities } from '~/components/common/vm/actions/common/lib/utils/capabilities'
180
- import { scheduledTaskDefaultFormFunc } from '~/components/common/pages/scheduledTasks/modals/lib/config/createScheduledTask'
181
- import { capabilitiesFunc } from '~/components/common/vm/actions/common/lib/config/capabilities'
182
-
183
- const props = 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
- errorValidationFields: UI_I_ErrorValidationField[]
191
- readyCompleteTableInfo: UI_I_TableInfoItem[]
192
- vmCpuHelpTextSecond: string
193
- finishFunc: any
194
- getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
195
- validateSendDataFunc: any
196
- passthroughDevices: UI_I_PciDevice[]
197
- mediatedDevices: UI_I_MediatedDevice[]
198
- vmNameInWizard: string
199
- capabilities?: UI_I_Capabilities
200
- schedulerTask?: any // TODO надо interface переместить глобално
201
- selectedVirtualMachine?: UI_I_Capabilities
202
- dataCenter?: UI_I_TreeNode // для сферы
203
- computeResource?: UI_I_TreeNode // для сферы
204
- computeResourceTree?: UI_I_TreeNode[] // для сферы
205
- }>()
206
-
207
- const emits = defineEmits<{
208
- (event: 'check-name', value: [string, (error: API_UI_I_Error) => void]): void
209
- (event: 'get-storage', value: UI_I_TablePayload): void
210
- (event: 'get-folders-or-files', value: UI_I_FolderOrFileTreePayload): void
211
- (event: 'get-active-device-child', value: UI_I_FileTreeNode): void
212
- (event: 'show-datastore-child', value: UI_I_FileTreeNode): void
213
- (event: 'remove-error-by-title', value: string): void
214
- (event: 'get-networks-table', value: UI_I_TablePayload): void
215
- (event: 'get-pci-devices'): void
216
- (event: 'hide'): void
217
- (
218
- event: 'get-compute-resource-tree',
219
- value: { id: string | number; cb: () => void }
220
- ): void // для сферы
221
- (event: 'show-compute-resource-tree', value: UI_I_TreeNode): void // для сферы
222
- (event: 'select-compute-resource-tree', value: UI_I_TreeNode): void // для сферы
223
- (event: 'clear-compute-resource-tree'): void // для сферы
224
- }>()
225
-
226
- const { $recursion } = useNuxtApp()
227
-
228
- const localization = computed<UI_I_Localization>(() => useLocal())
229
-
230
- const isSphere = computed<boolean>(() => props.project === 'sphere')
231
-
232
- const isScheduledTasks = computed<boolean>(
233
- () => props.schedulerTask.isSchedulerTask
234
- )
235
-
236
- const title = computed<string>(() => {
237
- const { scheduleNewTasks, scheduleTaskEdit, cloneExistingVirtualMachine } =
238
- localization.value.common
239
-
240
- let result = cloneExistingVirtualMachine
241
- if (isScheduledTasks.value) {
242
- const schedulerMode = props.schedulerTask.editTask
243
- ? scheduleTaskEdit
244
- : scheduleNewTasks
245
-
246
- result = `${schedulerMode} (${cloneExistingVirtualMachine})`
247
- }
248
-
249
- return result
250
- })
251
-
252
- watch(
253
- () => props.capabilities,
254
- () => {
255
- if (props.capabilities) {
256
- mapCapabilities(props.capabilities)
257
- }
258
- },
259
- { deep: true, immediate: true }
260
- )
261
-
262
- const wizard: Wizard = new Wizard(
263
- stepsFunc(localization.value),
264
- stepsSchemeInitial
265
- )
266
- watch(
267
- isScheduledTasks,
268
- (newValue) => {
269
- if (newValue) {
270
- wizard.changeScheme(isSphere.value ? 12 : 4)
271
- } else {
272
- wizard.changeScheme(isSphere.value ? 8 : 0)
273
- wizard.selectStepHard(isSphere.value ? 2 : 1)
274
- }
275
- },
276
- { immediate: true }
277
- )
278
-
279
- // TODO move to common
280
- const newTaskForm = ref<UI_I_ScheduleNewTasksForm>(
281
- useDeepCopy(scheduledTaskDefaultFormFunc())
282
- )
283
- watch(
284
- newTaskForm,
285
- (newValue: UI_I_ScheduleNewTasksForm) => {
286
- if (isScheduledTasks.value) wizard.setDisabledNextButton(newValue.isValid)
287
- },
288
- { immediate: true, deep: true }
289
- )
290
-
291
- const selectedScheme = computed<number[]>(() => wizard.selectedScheme.value)
292
-
293
- const onChangeSteps = async (value: UI_I_WizardStep[]): Promise<void> => {
294
- wizard.changeSteps(value, validationFunc, validateSendData)
295
- }
296
-
297
- const validationFunc = async (
298
- value: UI_I_WizardStep[],
299
- currentStep: UI_I_WizardStep,
300
- nextStep: UI_I_WizardStep
301
- ): Promise<UI_I_ValidationReturn> => {
302
- let stepHasError = false
303
- let stepShouldStop = {
304
- ifOnCurrentStep: false,
305
- ifFromAnyStep: false,
306
- stoppageStepId: -1,
307
- }
308
-
309
- wizard.setLoader(true)
310
- if (
311
- wizard.isValidateForStep(
312
- isSphere.value ? dynamicSteps.selectNameFolder : dynamicSteps.selectName,
313
- currentStep.id,
314
- nextStep.id
315
- )
316
- ) {
317
- const nameValidation = await checkName(value)
318
-
319
- value = nameValidation.newValue
320
- stepHasError = stepHasError || nameValidation.stepHasError
321
- } else if (
322
- isSphere.value &&
323
- wizard.isValidateForStep(
324
- dynamicSteps.selectComputeResource,
325
- currentStep.id,
326
- nextStep.id
327
- )
328
- ) {
329
- const computeResourceValidation = await checkComputeResource(value)
330
-
331
- value = computeResourceValidation.newValue
332
- stepHasError = stepHasError || computeResourceValidation.stepHasError
333
- } else if (
334
- wizard.isValidateForStep(
335
- dynamicSteps.selectStorage,
336
- currentStep.id,
337
- nextStep.id
338
- )
339
- ) {
340
- const storageValidation = await checkStorage(value)
341
-
342
- value = storageValidation.newValue
343
-
344
- stepHasError = stepHasError || storageValidation.stepHasError
345
- } else if (
346
- wizard.isValidateForStep(
347
- dynamicSteps.customizeHardware,
348
- currentStep.id,
349
- nextStep.id
350
- )
351
- ) {
352
- const customizeHardwareValidation = await checkCustomizeHardware(value)
353
-
354
- value = customizeHardwareValidation.newValue
355
-
356
- stepHasError = stepHasError || customizeHardwareValidation.stepHasError
357
- }
358
- wizard.setLoader(false)
359
-
360
- return {
361
- newValue: value,
362
- stepHasError,
363
- stepShouldStop,
364
- }
365
- }
366
- const checkName = async (
367
- value: UI_I_WizardStep[]
368
- ): Promise<UI_I_ValidationReturn> => {
369
- let stepHasError = false
370
-
371
- return new Promise((resolve) => {
372
- const step = isSphere.value
373
- ? dynamicSteps.selectNameFolder
374
- : dynamicSteps.selectName
375
- nameFormSubmit.value = (isValid: boolean) => {
376
- if (!isValid) {
377
- stepHasError = wizard.setValidation(step, 'name', {
378
- fieldMessage: 'aaa',
379
- alertMessage: 'aaa',
380
- })
381
- } else if (wizard.hasMessage(step, 'name')) {
382
- value = wizard.removeValidation(step, 'name', value)
383
- }
384
-
385
- resolve({
386
- stepHasError,
387
- newValue: value,
388
- })
389
- nameFormSubmit.value = null
390
- }
391
- })
392
- }
393
- const checkComputeResource = async (
394
- value: UI_I_WizardStep[]
395
- ): Promise<UI_I_ValidationReturn> => {
396
- let stepHasError = false
397
-
398
- return new Promise((resolve) => {
399
- computeResourceSubmit.value = (isValid: boolean) => {
400
- if (!isValid) {
401
- stepHasError = wizard.setValidation(
402
- dynamicSteps.selectComputeResource,
403
- 'computeResource',
404
- {
405
- fieldMessage: 'aaa',
406
- alertMessage: 'aaa',
407
- }
408
- )
409
- } else if (
410
- wizard.hasMessage(dynamicSteps.selectComputeResource, 'computeResource')
411
- ) {
412
- value = wizard.removeValidation(
413
- dynamicSteps.selectComputeResource,
414
- 'computeResource',
415
- value
416
- )
417
- }
418
-
419
- resolve({
420
- stepHasError,
421
- newValue: value,
422
- })
423
- computeResourceSubmit.value = null
424
- }
425
- })
426
- }
427
- const checkStorage = async (
428
- value: UI_I_WizardStep[]
429
- ): Promise<UI_I_ValidationReturn> => {
430
- let stepHasError = false
431
-
432
- return new Promise((resolve) => {
433
- storageSubmit.value = (isValid: boolean) => {
434
- if (!isValid) {
435
- stepHasError = wizard.setValidation(
436
- dynamicSteps.selectStorage,
437
- 'storage',
438
- {
439
- fieldMessage: 'aaa',
440
- alertMessage: 'aaa',
441
- }
442
- )
443
- } else if (wizard.hasMessage(dynamicSteps.selectStorage, 'storage')) {
444
- value = wizard.removeValidation(
445
- dynamicSteps.selectStorage,
446
- 'storage',
447
- value
448
- )
449
- }
450
-
451
- resolve({
452
- stepHasError,
453
- newValue: value,
454
- })
455
- storageSubmit.value = null
456
- }
457
- })
458
- }
459
- const checkCustomizeHardware = async (
460
- value: UI_I_WizardStep[]
461
- ): Promise<UI_I_ValidationReturn> => {
462
- let stepHasError = false
463
-
464
- return new Promise((resolve) => {
465
- customizeHardwareSubmit.value = (isValid: boolean) => {
466
- if (!isValid) {
467
- stepHasError = wizard.setValidation(
468
- dynamicSteps.customizeHardware,
469
- 'customizeHardware',
470
- {
471
- fieldMessage: 'aaa',
472
- alertMessage: 'aaa',
473
- }
474
- )
475
- } else if (
476
- wizard.hasMessage(dynamicSteps.customizeHardware, 'customizeHardware')
477
- ) {
478
- value = wizard.removeValidation(
479
- dynamicSteps.customizeHardware,
480
- 'customizeHardware',
481
- value
482
- )
483
- }
484
-
485
- resolve({
486
- stepHasError,
487
- newValue: value,
488
- })
489
- storageSubmit.value = null
490
- }
491
- })
492
- }
493
-
494
- const vmForm = ref<UI_I_VmForm>({
495
- name: '',
496
- compatibility: '',
497
- guestMachineType: null,
498
- guestOsFamily: null,
499
- guestOsVersion: null,
500
- computeResource: null,
501
- storage: null,
502
- locationPath: '',
503
- dataCenter: null,
504
- options: [],
505
- })
506
- const onChangeName = (name: string, node: UI_I_TreeNode): void => {
507
- vmForm.value.name = name
508
- if (isSphere.value) {
509
- vmForm.value.locationPath = node.id
510
- vmForm.value.dataCenter = $recursion.findParentByValue(
511
- node,
512
- 'datacenter',
513
- 'type',
514
- 'parent'
515
- )
516
- }
517
- }
518
- const onChangeStorage = (storage: UI_I_DatastoreTableItem | null): void => {
519
- if (!storage) return
520
-
521
- vmForm.value.storage = storage
522
- }
523
- const onChangeSelectOptions = (options: string[]): void => {
524
- vmForm.value.options = options
525
- if (
526
- options.includes('customize-os') &&
527
- options.includes('customize-hardware')
528
- ) {
529
- let procuratorSchame = isScheduledTasks.value ? 7 : 3
530
- let sphereSchame = isScheduledTasks.value ? 15 : 11
531
- wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
532
- } else if (options.includes('customize-os')) {
533
- let procuratorSchame = isScheduledTasks.value ? 5 : 1
534
- let sphereSchame = isScheduledTasks.value ? 13 : 9
535
- wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
536
- } else if (options.includes('customize-hardware')) {
537
- let procuratorSchame = isScheduledTasks.value ? 6 : 2
538
- let sphereSchame = isScheduledTasks.value ? 14 : 10
539
- wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
540
- } else {
541
- let procuratorSchame = isScheduledTasks.value ? 4 : 0
542
- let sphereSchame = isScheduledTasks.value ? 12 : 8
543
- wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
544
- }
545
-
546
- // Change power on by default
547
- isPowerOnByDefault.value = options.includes('power-on')
548
- }
549
- const customizeHardware = ref<UI_I_SendDataCustomizeHardware | null>(null)
550
- const onChangeCustomizeHardware = (
551
- data: UI_I_SendDataCustomizeHardware
552
- ): void => {
553
- customizeHardware.value = data
554
- }
555
-
556
- const virtualHardwareHardDisksLocal = computed<
557
- UI_I_SendDataNewHardDisk[] | null
558
- >(() => customizeHardware.value?.virtualHardware?.hardDisks || null)
559
- const virtualHardwareNetworksLocal = computed<UI_I_SendDataNewNetwork[] | null>(
560
- () => customizeHardware.value?.virtualHardware?.networks || null
561
- )
562
- const virtualHardwareCdDvdDrivesLocal = computed<
563
- UI_I_SendDataNewCdDvdDrive[] | null
564
- >(() => customizeHardware.value?.virtualHardware?.cdDvdDrives || null)
565
-
566
- const virtualHardwareCpu = computed<UI_I_SendDataCpu | null>(
567
- () => customizeHardware.value?.virtualHardware?.cpu || null
568
- )
569
- const virtualHardwareMemory = computed<UI_I_SendDataMemory | null>(
570
- () => customizeHardware.value?.virtualHardware?.memory || null
571
- )
572
- const virtualHardwareHardDisks = ref<UI_I_SendDataNewHardDisk[] | null>(null)
573
- const virtualHardwareCdDvdDrives = ref<UI_I_SendDataNewCdDvdDrive[] | null>(
574
- null
575
- )
576
- const virtualHardwareNetworks = ref<UI_I_SendDataNewNetwork[] | null>(null)
577
- const onChangeBootOrder = (data: UI_T_ChangeBootOrder): void => {
578
- virtualHardwareHardDisks.value = data[0]
579
- virtualHardwareCdDvdDrives.value = data[1]
580
- virtualHardwareNetworks.value = data[2]
581
- }
582
-
583
- const isPowerOnByDefault = ref<boolean>(false)
584
-
585
- watch(
586
- () => props.vmNameInWizard,
587
- (newValue) => {
588
- vmForm.value.name = newValue
589
- }
590
- )
591
-
592
- const validateSendData = async (
593
- value: UI_I_WizardStep[]
594
- ): Promise<UI_I_ValidationReturn> => {
595
- wizard.setLoader(true)
596
- let stepHasError = false
597
-
598
- const data = await props.validateSendDataFunc(
599
- vmForm.value,
600
- virtualHardwareCpu.value,
601
- virtualHardwareMemory.value,
602
- customizeHardware.value,
603
- virtualHardwareNetworks.value,
604
- virtualHardwareHardDisks.value,
605
- virtualHardwareCdDvdDrives.value,
606
- isPowerOnByDefault.value,
607
- localization.value,
608
- vmForm.value.locationPath, // для сферы
609
- computeResourcePath.value // для сферы
610
- )
611
-
612
- wizard.setLoader(false)
613
- if (data) {
614
- stepHasError = true
615
- selectedNavItem.value = data[0]
616
- }
617
-
618
- return {
619
- stepHasError,
620
- newValue: value,
621
- }
622
- }
623
- const onFinish = (): void => {
624
- wizard.setLoader(false)
625
- props
626
- .finishFunc(
627
- vmForm.value,
628
- virtualHardwareCpu.value,
629
- virtualHardwareMemory.value,
630
- customizeHardware.value,
631
- virtualHardwareNetworks.value,
632
- virtualHardwareHardDisks.value,
633
- virtualHardwareCdDvdDrives.value,
634
- isPowerOnByDefault.value,
635
- localization.value,
636
- vmForm.value.locationPath, // для сферы
637
- computeResourcePath.value, // для сферы
638
- false,
639
- newTaskForm.value,
640
- props.schedulerTask
641
- )
642
- .then(() => {
643
- onHideModal()
644
- wizard.setLoader(false)
645
- })
646
- }
647
-
648
- const selectedNavItem = ref<UI_T_SelectedNavItem>(0)
649
-
650
- const nameFormSubmit = ref<null | Function>(null)
651
- const computeResourceSubmit = ref<null | Function>(null)
652
- const storageSubmit = ref<null | Function>(null)
653
- const customizeHardwareSubmit = ref<null | Function>(null)
654
-
655
- const vmSettings = computed<UI_I_VmSettings | null>(() => props.vmSettings)
656
- const vmName = ref<string>(vmSettings.value?.name || '')
657
-
658
- const guestOsFamilies = ref<UI_I_OptionItem[]>(
659
- capabilitiesFunc().guestOsFamilies
660
- )
661
- const guestOsVersions = ref<UI_I_ArbitraryObject<UI_I_OptionItem[]>>(
662
- capabilitiesFunc().guestOsVersions
663
- )
664
- const machineTypes = ref<UI_I_OptionItem[]>(capabilitiesFunc().machineTypes)
665
-
666
- const computeResource = ref<UI_I_TreeNode | null>(null)
667
- const onChangeComputeResource = (node: UI_I_TreeNode): void => {
668
- computeResource.value = node
669
- }
670
- // // Для сферы
671
- const computeResourcePath = ref<string>('')
672
- const onSelectComputeResourceTree = (node: UI_I_TreeNode): void => {
673
- emits('select-compute-resource-tree', node)
674
- computeResourcePath.value = node.id
675
- }
676
-
677
- watch(vmSettings, (newValue) => {
678
- vmName.value = newValue?.name || ''
679
-
680
- if (newValue?.guestOsFamily)
681
- vmForm.value.guestOsFamily = newValue.guestOsFamily
682
- if (newValue?.guestMachineType)
683
- vmForm.value.guestMachineType = newValue.guestMachineType
684
- if (newValue?.guestOsVersion)
685
- vmForm.value.guestOsVersion = newValue.guestOsVersion
686
-
687
- if (newValue?.compatibility)
688
- vmForm.value.compatibility = newValue.compatibility
689
- })
690
-
691
- const onHideModal = (): void => {
692
- emits('hide')
693
- }
694
- </script>
695
-
696
- <style scoped lang="scss">
697
- :deep(.has-solid.close-icon.clr-icon) {
698
- width: 20px;
699
- top: 0;
700
- }
701
- .vm-context {
702
- padding: 16px 15px 10px 10px;
703
- height: 100%;
704
- display: flex;
705
- flex-direction: column;
706
-
707
- .context-title-wrap {
708
- padding-bottom: 3px;
709
- border-bottom: 1px solid #a6a6a6;
710
-
711
- h4 {
712
- font-weight: 700;
713
- font-size: 13px;
714
- color: var(--vm-context-title);
715
- }
716
- p {
717
- font-weight: 400;
718
- font-size: 13px;
719
- color: var(--vm-context-sub-title);
720
- }
721
- }
722
-
723
- .finish-block {
724
- padding: 18px 24px 24px 24px;
725
-
726
- .add-hosts-ready-to-complete-mt-12 {
727
- margin-top: 12px;
728
-
729
- .add-hosts-ready-to-complete-bold {
730
- line-height: 18px;
731
- font-weight: 700;
732
- }
733
- }
734
- }
735
-
736
- .vm-hardware-version {
737
- align-self: flex-end;
738
- margin-top: auto;
739
- }
740
- }
741
-
742
- :deep(.modal .modal-dialog .modal-content .modal-footer) {
743
- flex: unset;
744
- height: unset;
745
- min-height: unset;
746
- }
747
- :deep(.wizard-modal-titlebar h3) {
748
- color: #000;
749
- font-size: 24px;
750
- font-weight: 200;
751
- line-height: 27px;
752
- margin: 0;
753
- padding: 0;
754
- }
755
- :deep(.clr-wizard-stepnav-item) {
756
- padding-left: 0;
757
- }
758
- :deep(.clr-wizard-stepnav
759
- .clr-wizard-stepnav-item
760
- button
761
- .clr-wizard-stepnav-link-title) {
762
- width: 189px;
763
- font-weight: 700;
764
- font-size: 13px;
765
- }
766
-
767
- #vm-wizard-notification {
768
- h3 {
769
- color: var(--global-font-color7);
770
- margin-top: 6px;
771
- }
772
- p {
773
- color: var(--global-font-color6);
774
- line-height: 16px;
775
- }
776
- }
777
-
778
- .power-on-by-default-wrap {
779
- display: flex;
780
- align-items: center;
781
-
782
- input {
783
- margin-right: 6px;
784
- }
785
- }
786
-
787
- .new-task-form {
788
- padding: 0 25px 0 5px;
789
- }
790
- </style>
791
-
792
- <style>
793
- :root {
794
- --vm-context-title: #333;
795
- --vm-context-sub-title: #000;
796
- }
797
- :root.dark-theme {
798
- --vm-context-title: #adbbc4;
799
- --vm-context-sub-title: #adbbc4;
800
- }
801
- </style>
1
+ <template>
2
+ <div class="clone-vm">
3
+ <atoms-wizard
4
+ show
5
+ :wizard="wizard"
6
+ :selected-scheme="selectedScheme"
7
+ :title="title"
8
+ :localization="localization"
9
+ @change-steps="onChangeSteps"
10
+ @hide="onHideModal"
11
+ @submit="onFinish"
12
+ >
13
+ <template #modalBody="{ selectedStep }">
14
+ <atoms-loader v-show="!vmSettings" id="loader" />
15
+ <div v-if="vmSettings" class="vm-context">
16
+ <common-pages-scheduled-tasks-modals-common-new-task-form
17
+ v-show="selectedStep.id === dynamicSteps.scheduledTasks"
18
+ v-model="newTaskForm"
19
+ :target="selectedVirtualMachine"
20
+ class="new-task-form"
21
+ />
22
+ <common-vm-actions-common-select-name
23
+ v-show="
24
+ selectedStep.id === dynamicSteps.selectName ||
25
+ selectedStep.id === dynamicSteps.selectNameFolder
26
+ "
27
+ :show="
28
+ selectedStep.id === dynamicSteps.selectName ||
29
+ selectedStep.id === dynamicSteps.selectNameFolder
30
+ "
31
+ :name-form-submit="nameFormSubmit"
32
+ :project="props.project"
33
+ :data-center="props.dataCenter"
34
+ @submit="onChangeName(...$event)"
35
+ @check-name="emits('check-name', $event)"
36
+ />
37
+ <common-vm-actions-common-select-compute-resource
38
+ v-if="isSphere"
39
+ v-show="selectedStep.id === dynamicSteps.selectComputeResource"
40
+ v-model="computeResource"
41
+ :compute-resource-submit="computeResourceSubmit"
42
+ :data-center="vmForm.dataCenter"
43
+ :compute-resource="props.computeResource"
44
+ :compute-resource-tree="props.computeResourceTree"
45
+ @submit="onChangeComputeResource"
46
+ @select-compute-resource-tree="onSelectComputeResourceTree"
47
+ @get-compute-resource-tree="
48
+ emits('get-compute-resource-tree', $event)
49
+ "
50
+ @show-compute-resource-tree="
51
+ emits('show-compute-resource-tree', $event)
52
+ "
53
+ @clear-compute-resource-tree="emits('clear-compute-resource-tree')"
54
+ />
55
+ <common-vm-actions-common-select-storage
56
+ v-show="selectedStep.id === dynamicSteps.selectStorage"
57
+ :storage-submit="storageSubmit"
58
+ :datastore="props.datastore"
59
+ :storage="vmSettings.storage"
60
+ :get-datastore-table-func="props.getDatastoreTableFunc"
61
+ @submit="onChangeStorage"
62
+ />
63
+ <common-vm-actions-common-select-options
64
+ v-show="selectedStep.id === dynamicSteps.selectOptions"
65
+ @change="onChangeSelectOptions"
66
+ />
67
+ <common-vm-actions-common-select-os
68
+ v-show="selectedStep.id === dynamicSteps.selectGuestOSMachineType"
69
+ v-model:machine-type="vmForm.guestMachineType"
70
+ v-model:guest-os-family="vmForm.guestOsFamily"
71
+ v-model:guest-os-version="vmForm.guestOsVersion"
72
+ :families-options="guestOsFamilies"
73
+ :versions-options="guestOsVersions"
74
+ :machine-types-options="machineTypes"
75
+ :error-validation-fields="props.errorValidationFields"
76
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
77
+ />
78
+ <common-vm-actions-common-customize-hardware
79
+ v-show="selectedStep.id === dynamicSteps.customizeHardware"
80
+ v-model:vm-name="vmName"
81
+ v-model:guest-machine-type="vmSettings.guestMachineType"
82
+ v-model:guest-os-family="vmSettings.guestOsFamily"
83
+ v-model:guest-os-version="vmSettings.guestOsVersion"
84
+ :storage="vmSettings.storage"
85
+ :hard-disks-for-boot-options="virtualHardwareHardDisksLocal"
86
+ :cd-dvd-drives-for-boot-options="virtualHardwareCdDvdDrivesLocal"
87
+ :networks-for-boot-options="virtualHardwareNetworksLocal"
88
+ :cd-dvd-drives="vmSettings.cdDvdDrives"
89
+ :hard-disks="vmSettings.hardDisks"
90
+ :networks="vmSettings.networks"
91
+ :customize-hardware-submit="customizeHardwareSubmit"
92
+ :max-cpus="vmSettings.maxCpus"
93
+ :max-memory="vmSettings.maxMemory"
94
+ :cpu-models="vmSettings.cpuModels"
95
+ :cpu="vmSettings.cpu"
96
+ :memory="vmSettings.memory"
97
+ :video-card="vmSettings.videoCard"
98
+ :usb-controller="vmSettings.usbController"
99
+ :pci-devices="vmSettings.pciDevices"
100
+ :selected-nav-item="selectedNavItem"
101
+ :hard-disks-for-edit="vmSettings.hardDisks"
102
+ :options="vmSettings.options"
103
+ :nodes="props.nodes"
104
+ :files="props.files"
105
+ :networks-table="props.networksTable"
106
+ :error-validation-fields="props.errorValidationFields"
107
+ :vm-cpu-help-text-second="props.vmCpuHelpTextSecond"
108
+ :passthrough-devices="props.passthroughDevices"
109
+ :mediated-devices="props.mediatedDevices"
110
+ :get-datastore-table-func="props.getDatastoreTableFunc"
111
+ :datastore="props.datastore"
112
+ :project="props.project"
113
+ is-clone
114
+ @change-boot-order="onChangeBootOrder"
115
+ @send-data="onChangeCustomizeHardware"
116
+ @get-storage="emits('get-storage', $event)"
117
+ @get-folders-or-files="emits('get-folders-or-files', $event)"
118
+ @get-active-device-child="emits('get-active-device-child', $event)"
119
+ @show-datastore-child="emits('show-datastore-child', $event)"
120
+ @get-networks-table="emits('get-networks-table', $event)"
121
+ @get-pci-devices="emits('get-pci-devices')"
122
+ />
123
+ <common-ready-to-complete
124
+ v-show="selectedStep.id === dynamicSteps.readyComplete"
125
+ :data="props.readyCompleteTableInfo"
126
+ />
127
+ </div>
128
+ </template>
129
+ </atoms-wizard>
130
+ </div>
131
+ </template>
132
+
133
+ <script setup lang="ts">
134
+ import type {
135
+ UI_I_DatastoreTableItem,
136
+ UI_I_FolderOrFileTreePayload,
137
+ } from '~/lib/models/store/storage/interfaces'
138
+ import type { UI_I_NetworkTableItem } from '~/lib/models/store/network/interfaces'
139
+ import type { API_UI_I_Error } from '~/lib/models/store/interfaces'
140
+ import type { UI_I_TablePayload } from '~/lib/models/table/interfaces'
141
+ import type { UI_I_FileTreeNode } from '~/components/lib/models/interfaces'
142
+ import type {
143
+ UI_I_ArbitraryObject,
144
+ UI_I_Localization,
145
+ } from '~/lib/models/interfaces'
146
+ import type { UI_I_SendDataCustomizeHardware } from '~/components/common/vm/actions/common/customizeHardware/lib/models/interfaces'
147
+ import type { UI_I_ErrorValidationField } from '~/lib/models/store/interfaces'
148
+ import type {
149
+ UI_I_SendDataCpu,
150
+ UI_I_SendDataMemory,
151
+ UI_I_SendDataNewCdDvdDrive,
152
+ UI_I_SendDataNewHardDisk,
153
+ UI_I_SendDataNewNetwork,
154
+ } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/models/interfaces'
155
+ import type { UI_T_SelectedNavItem } from '~/components/common/vm/actions/common/lib/models/types'
156
+ import type { UI_I_TableInfoItem } from '~/components/atoms/table/info/lib/models/interfaces'
157
+ import type { UI_T_ChangeBootOrder } from '~/components/common/vm/actions/lib/models/types'
158
+ import type { UI_T_Project } from '~/lib/models/types'
159
+ import type {
160
+ UI_I_MediatedDevice,
161
+ UI_I_PciDevice,
162
+ UI_I_VmSettings,
163
+ } from '~/lib/models/store/vm/interfaces'
164
+ import type {
165
+ UI_I_VmForm,
166
+ } from '~/components/common/vm/actions/common/lib/models/interfaces'
167
+ import type {
168
+ UI_I_ValidationReturn,
169
+ UI_I_WizardStep,
170
+ } from '~/components/atoms/wizard/lib/models/interfaces'
171
+ import type { UI_I_Capabilities } from '~/components/common/vm/actions/common/lib/models/interfaces'
172
+ import type { UI_I_ScheduleNewTasksForm } from '~/components/common/pages/scheduledTasks/modals/lib/models/interfaces'
173
+ import type { UI_I_OptionItem } from '~/components/atoms/lib/models/interfaces'
174
+ import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
175
+ import {
176
+ stepsSchemeInitial,
177
+ stepsFunc,
178
+ dynamicSteps,
179
+ } from '~/components/common/vm/actions/clone/lib/config/steps'
180
+ import Wizard from '~/components/atoms/wizard/lib/utils/utils'
181
+ import { mapCapabilities } from '~/components/common/vm/actions/common/lib/utils/capabilities'
182
+ import { scheduledTaskDefaultFormFunc } from '~/components/common/pages/scheduledTasks/modals/lib/config/createScheduledTask'
183
+ import { capabilities } from '~/components/common/vm/actions/common/lib/config/capabilities'
184
+
185
+ const props = defineProps<{
186
+ project: UI_T_Project
187
+ vmSettings: UI_I_VmSettings | null
188
+ nodes: UI_I_FileTreeNode[]
189
+ files: UI_I_FileTreeNode[]
190
+ networksTable: UI_I_NetworkTableItem[]
191
+ datastore: UI_I_DatastoreTableItem[]
192
+ errorValidationFields: UI_I_ErrorValidationField[]
193
+ readyCompleteTableInfo: UI_I_TableInfoItem[]
194
+ vmCpuHelpTextSecond: string
195
+ finishFunc: any
196
+ getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
197
+ validateSendDataFunc: any
198
+ passthroughDevices: UI_I_PciDevice[]
199
+ mediatedDevices: UI_I_MediatedDevice[]
200
+ vmNameInWizard: string
201
+ capabilities?: UI_I_Capabilities
202
+ schedulerTask?: any // TODO надо interface переместить глобално
203
+ selectedVirtualMachine?: UI_I_Capabilities
204
+ dataCenter?: UI_I_TreeNode // для сферы
205
+ computeResource?: UI_I_TreeNode // для сферы
206
+ computeResourceTree?: UI_I_TreeNode[] // для сферы
207
+ }>()
208
+
209
+ const emits = defineEmits<{
210
+ (event: 'check-name', value: [string, (error: API_UI_I_Error) => void]): void
211
+ (event: 'get-storage', value: UI_I_TablePayload): void
212
+ (event: 'get-folders-or-files', value: UI_I_FolderOrFileTreePayload): void
213
+ (event: 'get-active-device-child', value: UI_I_FileTreeNode): void
214
+ (event: 'show-datastore-child', value: UI_I_FileTreeNode): void
215
+ (event: 'remove-error-by-title', value: string): void
216
+ (event: 'get-networks-table', value: UI_I_TablePayload): void
217
+ (event: 'get-pci-devices'): void
218
+ (event: 'hide'): void
219
+ (
220
+ event: 'get-compute-resource-tree',
221
+ value: { id: string | number; cb: () => void }
222
+ ): void // для сферы
223
+ (event: 'show-compute-resource-tree', value: UI_I_TreeNode): void // для сферы
224
+ (event: 'select-compute-resource-tree', value: UI_I_TreeNode): void // для сферы
225
+ (event: 'clear-compute-resource-tree'): void // для сферы
226
+ }>()
227
+
228
+ const { $recursion } = useNuxtApp()
229
+
230
+ const localization = computed<UI_I_Localization>(() => useLocal())
231
+
232
+ const isSphere = computed<boolean>(() => props.project === 'sphere')
233
+
234
+ const isScheduledTasks = computed<boolean>(
235
+ () => props.schedulerTask.isSchedulerTask
236
+ )
237
+
238
+ const title = computed<string>(() => {
239
+ const { scheduleNewTasks, scheduleTaskEdit, cloneExistingVirtualMachine } =
240
+ localization.value.common
241
+
242
+ let result = cloneExistingVirtualMachine
243
+ if (isScheduledTasks.value) {
244
+ const schedulerMode = props.schedulerTask.editTask
245
+ ? scheduleTaskEdit
246
+ : scheduleNewTasks
247
+
248
+ result = `${schedulerMode} (${cloneExistingVirtualMachine})`
249
+ }
250
+
251
+ return result
252
+ })
253
+
254
+ watch(
255
+ () => props.capabilities,
256
+ () => {
257
+ if (props.capabilities) {
258
+ mapCapabilities(props.capabilities)
259
+ }
260
+ },
261
+ { deep: true, immediate: true }
262
+ )
263
+
264
+ const wizard: Wizard = new Wizard(
265
+ stepsFunc(localization.value),
266
+ stepsSchemeInitial
267
+ )
268
+ watch(
269
+ isScheduledTasks,
270
+ (newValue) => {
271
+ if (newValue) {
272
+ wizard.changeScheme(isSphere.value ? 12 : 4)
273
+ } else {
274
+ wizard.changeScheme(isSphere.value ? 8 : 0)
275
+ wizard.selectStepHard(isSphere.value ? 2 : 1)
276
+ }
277
+ },
278
+ { immediate: true }
279
+ )
280
+
281
+ // TODO move to common
282
+ const newTaskForm = ref<UI_I_ScheduleNewTasksForm>(
283
+ useDeepCopy(scheduledTaskDefaultFormFunc())
284
+ )
285
+ watch(
286
+ newTaskForm,
287
+ (newValue: UI_I_ScheduleNewTasksForm) => {
288
+ if (isScheduledTasks.value) wizard.setDisabledNextButton(newValue.isValid)
289
+ },
290
+ { immediate: true, deep: true }
291
+ )
292
+
293
+ const selectedScheme = computed<number[]>(() => wizard.selectedScheme.value)
294
+
295
+ const onChangeSteps = async (value: UI_I_WizardStep[]): Promise<void> => {
296
+ wizard.changeSteps(value, validationFunc, validateSendData)
297
+ }
298
+
299
+ const validationFunc = async (
300
+ value: UI_I_WizardStep[],
301
+ currentStep: UI_I_WizardStep,
302
+ nextStep: UI_I_WizardStep
303
+ ): Promise<UI_I_ValidationReturn> => {
304
+ let stepHasError = false
305
+ let stepShouldStop = {
306
+ ifOnCurrentStep: false,
307
+ ifFromAnyStep: false,
308
+ stoppageStepId: -1,
309
+ }
310
+
311
+ wizard.setLoader(true)
312
+ if (
313
+ wizard.isValidateForStep(
314
+ isSphere.value ? dynamicSteps.selectNameFolder : dynamicSteps.selectName,
315
+ currentStep.id,
316
+ nextStep.id
317
+ )
318
+ ) {
319
+ const nameValidation = await checkName(value)
320
+
321
+ value = nameValidation.newValue
322
+ stepHasError = stepHasError || nameValidation.stepHasError
323
+ } else if (
324
+ isSphere.value &&
325
+ wizard.isValidateForStep(
326
+ dynamicSteps.selectComputeResource,
327
+ currentStep.id,
328
+ nextStep.id
329
+ )
330
+ ) {
331
+ const computeResourceValidation = await checkComputeResource(value)
332
+
333
+ value = computeResourceValidation.newValue
334
+ stepHasError = stepHasError || computeResourceValidation.stepHasError
335
+ } else if (
336
+ wizard.isValidateForStep(
337
+ dynamicSteps.selectStorage,
338
+ currentStep.id,
339
+ nextStep.id
340
+ )
341
+ ) {
342
+ const storageValidation = await checkStorage(value)
343
+
344
+ value = storageValidation.newValue
345
+
346
+ stepHasError = stepHasError || storageValidation.stepHasError
347
+ } else if (
348
+ wizard.isValidateForStep(
349
+ dynamicSteps.customizeHardware,
350
+ currentStep.id,
351
+ nextStep.id
352
+ )
353
+ ) {
354
+ const customizeHardwareValidation = await checkCustomizeHardware(value)
355
+
356
+ value = customizeHardwareValidation.newValue
357
+
358
+ stepHasError = stepHasError || customizeHardwareValidation.stepHasError
359
+ }
360
+ wizard.setLoader(false)
361
+
362
+ return {
363
+ newValue: value,
364
+ stepHasError,
365
+ stepShouldStop,
366
+ }
367
+ }
368
+ const checkName = async (
369
+ value: UI_I_WizardStep[]
370
+ ): Promise<UI_I_ValidationReturn> => {
371
+ let stepHasError = false
372
+
373
+ return new Promise((resolve) => {
374
+ const step = isSphere.value
375
+ ? dynamicSteps.selectNameFolder
376
+ : dynamicSteps.selectName
377
+ nameFormSubmit.value = (isValid: boolean) => {
378
+ if (!isValid) {
379
+ stepHasError = wizard.setValidation(step, 'name', {
380
+ fieldMessage: 'aaa',
381
+ alertMessage: 'aaa',
382
+ })
383
+ } else if (wizard.hasMessage(step, 'name')) {
384
+ value = wizard.removeValidation(step, 'name', value)
385
+ }
386
+
387
+ resolve({
388
+ stepHasError,
389
+ newValue: value,
390
+ })
391
+ nameFormSubmit.value = null
392
+ }
393
+ })
394
+ }
395
+ const checkComputeResource = async (
396
+ value: UI_I_WizardStep[]
397
+ ): Promise<UI_I_ValidationReturn> => {
398
+ let stepHasError = false
399
+
400
+ return new Promise((resolve) => {
401
+ computeResourceSubmit.value = (isValid: boolean) => {
402
+ if (!isValid) {
403
+ stepHasError = wizard.setValidation(
404
+ dynamicSteps.selectComputeResource,
405
+ 'computeResource',
406
+ {
407
+ fieldMessage: 'aaa',
408
+ alertMessage: 'aaa',
409
+ }
410
+ )
411
+ } else if (
412
+ wizard.hasMessage(dynamicSteps.selectComputeResource, 'computeResource')
413
+ ) {
414
+ value = wizard.removeValidation(
415
+ dynamicSteps.selectComputeResource,
416
+ 'computeResource',
417
+ value
418
+ )
419
+ }
420
+
421
+ resolve({
422
+ stepHasError,
423
+ newValue: value,
424
+ })
425
+ computeResourceSubmit.value = null
426
+ }
427
+ })
428
+ }
429
+ const checkStorage = async (
430
+ value: UI_I_WizardStep[]
431
+ ): Promise<UI_I_ValidationReturn> => {
432
+ let stepHasError = false
433
+
434
+ return new Promise((resolve) => {
435
+ storageSubmit.value = (isValid: boolean) => {
436
+ if (!isValid) {
437
+ stepHasError = wizard.setValidation(
438
+ dynamicSteps.selectStorage,
439
+ 'storage',
440
+ {
441
+ fieldMessage: 'aaa',
442
+ alertMessage: 'aaa',
443
+ }
444
+ )
445
+ } else if (wizard.hasMessage(dynamicSteps.selectStorage, 'storage')) {
446
+ value = wizard.removeValidation(
447
+ dynamicSteps.selectStorage,
448
+ 'storage',
449
+ value
450
+ )
451
+ }
452
+
453
+ resolve({
454
+ stepHasError,
455
+ newValue: value,
456
+ })
457
+ storageSubmit.value = null
458
+ }
459
+ })
460
+ }
461
+ const checkCustomizeHardware = async (
462
+ value: UI_I_WizardStep[]
463
+ ): Promise<UI_I_ValidationReturn> => {
464
+ let stepHasError = false
465
+
466
+ return new Promise((resolve) => {
467
+ customizeHardwareSubmit.value = (isValid: boolean) => {
468
+ if (!isValid) {
469
+ stepHasError = wizard.setValidation(
470
+ dynamicSteps.customizeHardware,
471
+ 'customizeHardware',
472
+ {
473
+ fieldMessage: 'aaa',
474
+ alertMessage: 'aaa',
475
+ }
476
+ )
477
+ } else if (
478
+ wizard.hasMessage(dynamicSteps.customizeHardware, 'customizeHardware')
479
+ ) {
480
+ value = wizard.removeValidation(
481
+ dynamicSteps.customizeHardware,
482
+ 'customizeHardware',
483
+ value
484
+ )
485
+ }
486
+
487
+ resolve({
488
+ stepHasError,
489
+ newValue: value,
490
+ })
491
+ storageSubmit.value = null
492
+ }
493
+ })
494
+ }
495
+
496
+ const vmForm = ref<UI_I_VmForm>({
497
+ name: '',
498
+ compatibility: '',
499
+ guestMachineType: null,
500
+ guestOsFamily: null,
501
+ guestOsVersion: null,
502
+ computeResource: null,
503
+ storage: null,
504
+ locationPath: '',
505
+ dataCenter: null,
506
+ options: [],
507
+ })
508
+ const onChangeName = (name: string, node: UI_I_TreeNode): void => {
509
+ vmForm.value.name = name
510
+ if (isSphere.value) {
511
+ vmForm.value.locationPath = node.id
512
+ vmForm.value.dataCenter = $recursion.findParentByValue(
513
+ node,
514
+ 'datacenter',
515
+ 'type',
516
+ 'parent'
517
+ )
518
+ }
519
+ }
520
+ const onChangeStorage = (storage: UI_I_DatastoreTableItem | null): void => {
521
+ if (!storage) return
522
+
523
+ vmForm.value.storage = storage
524
+ }
525
+ const onChangeSelectOptions = (options: string[]): void => {
526
+ vmForm.value.options = options
527
+ if (
528
+ options.includes('customize-os') &&
529
+ options.includes('customize-hardware')
530
+ ) {
531
+ let procuratorSchame = isScheduledTasks.value ? 7 : 3
532
+ let sphereSchame = isScheduledTasks.value ? 15 : 11
533
+ wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
534
+ } else if (options.includes('customize-os')) {
535
+ let procuratorSchame = isScheduledTasks.value ? 5 : 1
536
+ let sphereSchame = isScheduledTasks.value ? 13 : 9
537
+ wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
538
+ } else if (options.includes('customize-hardware')) {
539
+ let procuratorSchame = isScheduledTasks.value ? 6 : 2
540
+ let sphereSchame = isScheduledTasks.value ? 14 : 10
541
+ wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
542
+ } else {
543
+ let procuratorSchame = isScheduledTasks.value ? 4 : 0
544
+ let sphereSchame = isScheduledTasks.value ? 12 : 8
545
+ wizard.changeScheme(isSphere.value ? sphereSchame : procuratorSchame)
546
+ }
547
+
548
+ // Change power on by default
549
+ isPowerOnByDefault.value = options.includes('power-on')
550
+ }
551
+ const customizeHardware = ref<UI_I_SendDataCustomizeHardware | null>(null)
552
+ const onChangeCustomizeHardware = (
553
+ data: UI_I_SendDataCustomizeHardware
554
+ ): void => {
555
+ customizeHardware.value = data
556
+ }
557
+
558
+ const virtualHardwareHardDisksLocal = computed<
559
+ UI_I_SendDataNewHardDisk[] | null
560
+ >(() => customizeHardware.value?.virtualHardware?.hardDisks || null)
561
+ const virtualHardwareNetworksLocal = computed<UI_I_SendDataNewNetwork[] | null>(
562
+ () => customizeHardware.value?.virtualHardware?.networks || null
563
+ )
564
+ const virtualHardwareCdDvdDrivesLocal = computed<
565
+ UI_I_SendDataNewCdDvdDrive[] | null
566
+ >(() => customizeHardware.value?.virtualHardware?.cdDvdDrives || null)
567
+
568
+ const virtualHardwareCpu = computed<UI_I_SendDataCpu | null>(
569
+ () => customizeHardware.value?.virtualHardware?.cpu || null
570
+ )
571
+ const virtualHardwareMemory = computed<UI_I_SendDataMemory | null>(
572
+ () => customizeHardware.value?.virtualHardware?.memory || null
573
+ )
574
+ const virtualHardwareHardDisks = ref<UI_I_SendDataNewHardDisk[] | null>(null)
575
+ const virtualHardwareCdDvdDrives = ref<UI_I_SendDataNewCdDvdDrive[] | null>(
576
+ null
577
+ )
578
+ const virtualHardwareNetworks = ref<UI_I_SendDataNewNetwork[] | null>(null)
579
+ const onChangeBootOrder = (data: UI_T_ChangeBootOrder): void => {
580
+ virtualHardwareHardDisks.value = data[0]
581
+ virtualHardwareCdDvdDrives.value = data[1]
582
+ virtualHardwareNetworks.value = data[2]
583
+ }
584
+
585
+ const isPowerOnByDefault = ref<boolean>(false)
586
+
587
+ watch(
588
+ () => props.vmNameInWizard,
589
+ (newValue) => {
590
+ vmForm.value.name = newValue
591
+ }
592
+ )
593
+
594
+ const validateSendData = async (
595
+ value: UI_I_WizardStep[]
596
+ ): Promise<UI_I_ValidationReturn> => {
597
+ wizard.setLoader(true)
598
+ let stepHasError = false
599
+
600
+ const data = await props.validateSendDataFunc(
601
+ vmForm.value,
602
+ virtualHardwareCpu.value,
603
+ virtualHardwareMemory.value,
604
+ customizeHardware.value,
605
+ virtualHardwareNetworks.value,
606
+ virtualHardwareHardDisks.value,
607
+ virtualHardwareCdDvdDrives.value,
608
+ isPowerOnByDefault.value,
609
+ localization.value,
610
+ vmForm.value.locationPath, // для сферы
611
+ computeResourcePath.value // для сферы
612
+ )
613
+
614
+ wizard.setLoader(false)
615
+ if (data) {
616
+ stepHasError = true
617
+ selectedNavItem.value = data[0]
618
+ }
619
+
620
+ return {
621
+ stepHasError,
622
+ newValue: value,
623
+ }
624
+ }
625
+ const onFinish = (): void => {
626
+ wizard.setLoader(false)
627
+ props
628
+ .finishFunc(
629
+ vmForm.value,
630
+ virtualHardwareCpu.value,
631
+ virtualHardwareMemory.value,
632
+ customizeHardware.value,
633
+ virtualHardwareNetworks.value,
634
+ virtualHardwareHardDisks.value,
635
+ virtualHardwareCdDvdDrives.value,
636
+ isPowerOnByDefault.value,
637
+ localization.value,
638
+ vmForm.value.locationPath, // для сферы
639
+ computeResourcePath.value, // для сферы
640
+ false,
641
+ newTaskForm.value,
642
+ props.schedulerTask
643
+ )
644
+ .then(() => {
645
+ onHideModal()
646
+ wizard.setLoader(false)
647
+ })
648
+ }
649
+
650
+ const selectedNavItem = ref<UI_T_SelectedNavItem>(0)
651
+
652
+ const nameFormSubmit = ref<null | Function>(null)
653
+ const computeResourceSubmit = ref<null | Function>(null)
654
+ const storageSubmit = ref<null | Function>(null)
655
+ const customizeHardwareSubmit = ref<null | Function>(null)
656
+
657
+ const vmSettings = computed<UI_I_VmSettings | null>(() => props.vmSettings)
658
+ const vmName = ref<string>(vmSettings.value?.name || '')
659
+
660
+ const guestOsFamilies = ref<UI_I_OptionItem[]>(capabilities.guestOsFamilies)
661
+ const guestOsVersions = ref<UI_I_ArbitraryObject<UI_I_OptionItem[]>>(
662
+ capabilities.guestOsVersions
663
+ )
664
+ const machineTypes = ref<UI_I_OptionItem[]>(capabilities.machineTypes)
665
+
666
+ const computeResource = ref<UI_I_TreeNode | null>(null)
667
+ const onChangeComputeResource = (node: UI_I_TreeNode): void => {
668
+ computeResource.value = node
669
+ }
670
+ // // Для сферы
671
+ const computeResourcePath = ref<string>('')
672
+ const onSelectComputeResourceTree = (node: UI_I_TreeNode): void => {
673
+ emits('select-compute-resource-tree', node)
674
+ computeResourcePath.value = node.id
675
+ }
676
+
677
+ watch(vmSettings, (newValue) => {
678
+ vmName.value = newValue?.name || ''
679
+
680
+ if (newValue?.guestOsFamily)
681
+ vmForm.value.guestOsFamily = newValue.guestOsFamily
682
+ if (newValue?.guestMachineType)
683
+ vmForm.value.guestMachineType = newValue.guestMachineType
684
+ if (newValue?.guestOsVersion)
685
+ vmForm.value.guestOsVersion = newValue.guestOsVersion
686
+
687
+ if (newValue?.compatibility)
688
+ vmForm.value.compatibility = newValue.compatibility
689
+ })
690
+
691
+ const onHideModal = (): void => {
692
+ emits('hide')
693
+ }
694
+ </script>
695
+
696
+ <style scoped lang="scss">
697
+ :deep(.has-solid.close-icon.clr-icon) {
698
+ width: 20px;
699
+ top: 0;
700
+ }
701
+ .vm-context {
702
+ padding: 16px 15px 10px 10px;
703
+ height: 100%;
704
+ display: flex;
705
+ flex-direction: column;
706
+
707
+ .context-title-wrap {
708
+ padding-bottom: 3px;
709
+ border-bottom: 1px solid #a6a6a6;
710
+
711
+ h4 {
712
+ font-weight: 700;
713
+ font-size: 13px;
714
+ color: var(--vm-context-title);
715
+ }
716
+ p {
717
+ font-weight: 400;
718
+ font-size: 13px;
719
+ color: var(--vm-context-sub-title);
720
+ }
721
+ }
722
+
723
+ .finish-block {
724
+ padding: 18px 24px 24px 24px;
725
+
726
+ .add-hosts-ready-to-complete-mt-12 {
727
+ margin-top: 12px;
728
+
729
+ .add-hosts-ready-to-complete-bold {
730
+ line-height: 18px;
731
+ font-weight: 700;
732
+ }
733
+ }
734
+ }
735
+
736
+ .vm-hardware-version {
737
+ align-self: flex-end;
738
+ margin-top: auto;
739
+ }
740
+ }
741
+
742
+ :deep(.modal .modal-dialog .modal-content .modal-footer) {
743
+ flex: unset;
744
+ height: unset;
745
+ min-height: unset;
746
+ }
747
+ :deep(.wizard-modal-titlebar h3) {
748
+ color: #000;
749
+ font-size: 24px;
750
+ font-weight: 200;
751
+ line-height: 27px;
752
+ margin: 0;
753
+ padding: 0;
754
+ }
755
+ :deep(.clr-wizard-stepnav-item) {
756
+ padding-left: 0;
757
+ }
758
+ :deep(.clr-wizard-stepnav
759
+ .clr-wizard-stepnav-item
760
+ button
761
+ .clr-wizard-stepnav-link-title) {
762
+ width: 189px;
763
+ font-weight: 700;
764
+ font-size: 13px;
765
+ }
766
+
767
+ #vm-wizard-notification {
768
+ h3 {
769
+ color: var(--global-font-color7);
770
+ margin-top: 6px;
771
+ }
772
+ p {
773
+ color: var(--global-font-color6);
774
+ line-height: 16px;
775
+ }
776
+ }
777
+
778
+ .power-on-by-default-wrap {
779
+ display: flex;
780
+ align-items: center;
781
+
782
+ input {
783
+ margin-right: 6px;
784
+ }
785
+ }
786
+
787
+ .new-task-form {
788
+ padding: 0 25px 0 5px;
789
+ }
790
+ </style>
791
+
792
+ <style>
793
+ :root {
794
+ --vm-context-title: #333;
795
+ --vm-context-sub-title: #000;
796
+ }
797
+ :root.dark-theme {
798
+ --vm-context-title: #adbbc4;
799
+ --vm-context-sub-title: #adbbc4;
800
+ }
801
+ </style>