bfg-common 1.5.575 → 1.5.577

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 (121) hide show
  1. package/CODE_STYLE.md +109 -109
  2. package/assets/img/icons/icons-sprite-dark-3.svg +227 -227
  3. package/assets/img/icons/icons-sprite-dark-5.svg +488 -488
  4. package/assets/img/icons/icons-sprite-light-3.svg +227 -227
  5. package/assets/img/icons/icons-sprite-light-5.svg +488 -488
  6. package/assets/localization/local_be.json +7 -2
  7. package/assets/localization/local_en.json +7 -2
  8. package/assets/localization/local_hy.json +7 -2
  9. package/assets/localization/local_kk.json +7 -2
  10. package/assets/localization/local_ru.json +7 -2
  11. package/assets/localization/local_zh.json +7 -2
  12. package/components/atoms/TheIcon3.vue +50 -50
  13. package/components/atoms/collapse/CollapseNav.vue +170 -170
  14. package/components/atoms/perPage/PerPage.vue +58 -58
  15. package/components/atoms/table/dataGrid/DataGrid.vue +1718 -1718
  16. package/components/atoms/table/dataGrid/DataGridPagination.vue +97 -97
  17. package/components/atoms/table/dataGrid/lib/config/settingsTable.ts +94 -94
  18. package/components/atoms/table/dataGrid/lib/utils/export.ts +16 -16
  19. package/components/common/backup/storage/actions/add/Add.vue +2 -3
  20. package/components/common/backup/storage/actions/add/Old.vue +2 -3
  21. package/components/common/backup/storage/actions/add/lib/utils.ts +51 -51
  22. package/components/common/backup/storage/actions/add/steps/readyComplete/ReadyComplete.vue +45 -45
  23. package/components/common/backup/storage/actions/add/steps/readyComplete/lib/config/propertiesDetails.ts +7 -7
  24. package/components/common/browse/blocks/contents/filesNew/Skeleton.vue +18 -18
  25. package/components/common/diagramMain/modals/lib/config/portModal.ts +251 -251
  26. package/components/common/diagramMain/modals/lib/config/vCenterModal.ts +48 -48
  27. package/components/common/diagramMain/port/Port.vue +580 -580
  28. package/components/common/layout/theHeader/helpMenu/About.vue +79 -79
  29. package/components/common/layout/theHeader/helpMenu/aboutOld/AboutOld.vue +79 -79
  30. package/components/common/pages/backups/DetailView.vue +52 -52
  31. package/components/common/pages/backups/lib/models/interfaces.ts +36 -36
  32. package/components/common/pages/backups/modals/Modals.vue +243 -243
  33. package/components/common/pages/backups/modals/createBackup/configuration/maxBandwidth/lib/config/options.ts +6 -6
  34. package/components/common/pages/backups/modals/createBackup/lib/config/readyToCompleteOptions.ts +69 -69
  35. package/components/common/pages/backups/modals/lib/config/restore.ts +115 -115
  36. package/components/common/pages/backups/modals/lib/models/interfaces.ts +186 -186
  37. package/components/common/pages/backups/modals/restore/name/lib/models/interfaces.ts +6 -6
  38. package/components/common/pages/home/lib/models/interfaces.ts +48 -48
  39. package/components/common/pages/home/widgets/hosts/Hosts.vue +27 -27
  40. package/components/common/pages/home/widgets/hosts/lib/config/items.ts +23 -23
  41. package/components/common/pages/home/widgets/vms/VmsOld.vue +35 -35
  42. package/components/common/pages/home/widgets/vms/lib/config/items.ts +19 -19
  43. package/components/common/pages/scheduledTasks/lib/utils/utils.ts +84 -84
  44. package/components/common/readyToComplete/ReadyToComplete.vue +17 -17
  45. package/components/common/select/radio/RadioGroup.vue +137 -137
  46. package/components/common/spiceConsole/Drawer.vue +420 -420
  47. package/components/common/spiceConsole/SpiceConsole.vue +184 -184
  48. package/components/common/spiceConsole/lib/models/interfaces.ts +5 -5
  49. package/components/common/tools/Actions.vue +207 -207
  50. package/components/common/treeView/TreeView.vue +52 -52
  51. package/components/common/vm/actions/add/Add.vue +960 -951
  52. package/components/common/vm/actions/add/New.vue +2 -0
  53. package/components/common/vm/actions/add/Old.vue +2 -0
  54. package/components/common/vm/actions/add/lib/config/steps.ts +347 -347
  55. package/components/common/vm/actions/clone/Clone.vue +816 -809
  56. package/components/common/vm/actions/clone/new/New.vue +2 -0
  57. package/components/common/vm/actions/clone/old/Old.vue +2 -0
  58. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/Shares.vue +140 -140
  59. package/components/common/vm/actions/common/customizeHardware/virtualHardware/cpu/shares/lib/config/options.ts +28 -28
  60. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/MemoryNew.vue +158 -158
  61. package/components/common/vm/actions/common/customizeHardware/virtualHardware/memory/MemoryOld.vue +155 -155
  62. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/location/Location.vue +154 -154
  63. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newNetwork/macAddress/MacAddress.vue +119 -119
  64. package/components/common/vm/actions/common/customizeHardware/virtualHardware/newPciDevice/dynamicDirectPathIo/DynamicDirectPathIo.vue +31 -31
  65. package/components/common/vm/actions/common/customizeHardware/virtualHardware/other/Other.vue +16 -16
  66. package/components/common/vm/actions/common/customizeHardware/virtualHardware/videoCard/numberDisplays/NumberDisplays.vue +53 -53
  67. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/delay/Delay.vue +32 -32
  68. package/components/common/vm/actions/common/customizeHardware/vmoptions/bootOptions/firmware/Firmware.vue +60 -60
  69. package/components/common/vm/actions/common/customizeHardware/vmoptions/remoteConsoleOptions/usbRedirection/UsbRedirection.vue +28 -28
  70. package/components/common/vm/actions/common/select/compatibility/Old.vue +107 -107
  71. package/components/common/vm/actions/common/select/createType/CreateType.vue +38 -38
  72. package/components/common/vm/actions/common/select/createType/lib/models/interfaces.ts +5 -5
  73. package/components/common/vm/actions/common/select/options/New.vue +258 -227
  74. package/components/common/vm/actions/common/select/options/Old.vue +103 -75
  75. package/components/common/vm/actions/common/select/options/Options.vue +54 -38
  76. package/components/common/vm/actions/common/select/storage/Old.vue +125 -125
  77. package/components/common/vm/actions/common/select/storage/Storage.vue +178 -178
  78. package/components/common/vm/actions/common/select/storage/new/New.vue +311 -311
  79. package/components/common/vm/actions/common/select/storage/new/lib/models/interfaces.ts +5 -5
  80. package/components/common/vm/actions/common/select/storage/new/lib/utils/utils.ts +21 -21
  81. package/components/common/vm/actions/common/select/template/old/Old.vue +50 -50
  82. package/components/common/vm/actions/editSettings/new/Skeleton.vue +88 -88
  83. package/components/common/vm/actions/register/Register.vue +352 -352
  84. package/components/common/vm/actions/register/lib/config/steps.ts +86 -86
  85. package/components/common/wizards/common/compatibility/Compatibility.vue +35 -35
  86. package/components/common/wizards/common/compatibility/New.vue +99 -99
  87. package/components/common/wizards/common/compatibility/Old.vue +53 -53
  88. package/components/common/wizards/common/steps/computeResource/ComputeResource.vue +86 -86
  89. package/components/common/wizards/common/steps/computeResource/New.vue +93 -93
  90. package/components/common/wizards/common/steps/computeResource/Old.vue +103 -103
  91. package/components/common/wizards/common/steps/name/Name.vue +178 -178
  92. package/components/common/wizards/common/steps/name/New.vue +221 -221
  93. package/components/common/wizards/common/steps/name/Old.vue +121 -121
  94. package/components/common/wizards/common/steps/name/lib/models/interfaces.ts +4 -4
  95. package/components/common/wizards/common/steps/name/location/Location.vue +85 -85
  96. package/components/common/wizards/common/steps/name/location/New.vue +40 -40
  97. package/components/common/wizards/datastore/add/Add.vue +228 -228
  98. package/components/common/wizards/datastore/add/lib/utils.ts +85 -85
  99. package/components/common/wizards/datastore/add/steps/typeMode/lib/config/typeOptions.ts +43 -43
  100. package/components/common/wizards/vm/migrate/select/computeResource/ComputeResource.vue +205 -205
  101. package/components/common/wizards/vm/migrate/select/network/Network.vue +103 -103
  102. package/composables/useAppVersion.ts +21 -21
  103. package/composables/useLocal.ts +6 -6
  104. package/composables/useLocalCommon.ts +39 -39
  105. package/package.json +1 -1
  106. package/plugins/console.ts +21 -21
  107. package/plugins/date.ts +233 -233
  108. package/plugins/mouse.ts +21 -21
  109. package/plugins/panelStates.ts +70 -70
  110. package/plugins/text.ts +59 -59
  111. package/public/spice-console/application/clientgui.js +854 -854
  112. package/public/spice-console/application/packetfactory.js +211 -211
  113. package/public/spice-console/application/virtualmouse.js +147 -147
  114. package/public/spice-console/lib/images/bitmap.js +203 -203
  115. package/public/spice-console/network/spicechannel.js +440 -440
  116. package/public/spice-console/process/cursorprocess.js +121 -121
  117. package/public/spice-console/process/inputprocess.js +227 -227
  118. package/public/spice-console/process/mainprocess.js +210 -210
  119. package/public/spice-console/run.js +210 -210
  120. package/store/main/mutations.ts +7 -7
  121. package/store/main/state.ts +7 -7
@@ -1,951 +1,960 @@
1
- <template>
2
- <common-vm-actions-add-new
3
- v-if="isNewView"
4
- v-model:vm-form="vmForm"
5
- v-model:selected-create-type="selectedCreateType"
6
- v-model:is-power-on-by-default="isPowerOnByDefault"
7
- :project="props.project"
8
- :is-vmt="props.isVmt"
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
- :import-from-v-m-warev-sphere="props.importFromVMWarevSphere"
18
- :get-datastore-table-func="props.getDatastoreTableFunc"
19
- :passthrough-devices="props.passthroughDevices"
20
- :mediated-devices="props.mediatedDevices"
21
- :templates-tree="props.templatesTree"
22
- :wizard="wizard"
23
- :selected-scheme="selectedScheme"
24
- :template-submit="templateSubmit"
25
- :name-form-submit="nameFormSubmit"
26
- :storage-submit="storageSubmit"
27
- :customize-hardware-submit="customizeHardwareSubmit"
28
- :customize-hardware-for-template-submit="customizeHardwareForTemplateSubmit"
29
- :is-sphere="isSphere"
30
- :compatibility="compatibility"
31
- :guestOsFamilies="guestOsFamilies"
32
- :guestOsVersions="guestOsVersions"
33
- :machineTypes="machineTypes"
34
- :virtual-hardware-hard-disks-local="virtualHardwareHardDisksLocal"
35
- :virtual-hardware-cd-dvd-drives-local="virtualHardwareCdDvdDrivesLocal"
36
- :virtual-hardware-networks-local="virtualHardwareNetworksLocal"
37
- :max-cpus="maxCpus"
38
- :max-memory="maxMemory"
39
- :cpu-models="cpuModels"
40
- :selected-nav-item="selectedNavItem"
41
- :compatibility-info="compatibilityInfo"
42
- :is-show-power-on="isShowPowerOn"
43
- :is-show-select-template="isShowSelectTemplate"
44
- :data-center="props.dataCenter"
45
- :compute-resource="props.computeResource"
46
- :compute-resource-tree="props.computeResourceTree"
47
- :location-nodes="props.locationNodes"
48
- :allowed-location-kinds="allowedLocationKinds"
49
- :location-description="locationDescription"
50
- :vmt-settings="props.vmtSettings"
51
- :is-loading="isLoading"
52
- :selected-template-id="props.selectedTemplateId"
53
- :validate-empty-name="props.validateEmptyName"
54
- :title="title"
55
- :name-request-url="props.nameRequestUrl"
56
- :validation-description="validationDescription"
57
- :name-exist-validation="nameExistValidation"
58
- :name-test-ids="nameTestIds"
59
- :is-loading-compute-tree="isLoadingComputeTree"
60
- :compute-resource-alert="computeResourceAlert"
61
- :compatibility-text="compatibilityText"
62
- @get-storage="emits('get-storage', $event)"
63
- @get-folders-or-files="emits('get-folders-or-files', $event)"
64
- @get-active-device-child="emits('get-active-device-child', $event)"
65
- @show-datastore-child="emits('show-datastore-child', $event)"
66
- @remove-error-by-title="emits('remove-error-by-title', $event)"
67
- @get-networks-table="emits('get-networks-table', $event)"
68
- @get-pci-devices="emits('get-pci-devices')"
69
- @change-steps="onChangeSteps"
70
- @change-template="onChangeTemplate"
71
- @change-name="onChangeName(...$event)"
72
- @change-storage="onChangeStorage"
73
- @change-select-options="onChangeSelectOptions"
74
- @change-compatibility="onChangeCompatibility"
75
- @change-boot-order="onChangeBootOrder"
76
- @change-customize-hardware="onChangeCustomizeHardware"
77
- @finish="onFinish"
78
- @hide="onHideModal"
79
- />
80
- <common-vm-actions-add-old
81
- v-else
82
- v-model:vm-form="vmForm"
83
- v-model:selected-create-type="selectedCreateType"
84
- v-model:is-power-on-by-default="isPowerOnByDefault"
85
- :project="props.project"
86
- :is-vmt="props.isVmt"
87
- :nodes="props.nodes"
88
- :files="props.files"
89
- :networks-table="props.networksTable"
90
- :datastore="props.datastore"
91
- :is-datastore-loading="props.isDatastoreLoading"
92
- :error-validation-fields="props.errorValidationFields"
93
- :ready-complete-table-info="props.readyCompleteTableInfo"
94
- :vm-cpu-help-text-second="props.vmCpuHelpTextSecond"
95
- :import-from-v-m-warev-sphere="props.importFromVMWarevSphere"
96
- :get-datastore-table-func="props.getDatastoreTableFunc"
97
- :passthrough-devices="props.passthroughDevices"
98
- :mediated-devices="props.mediatedDevices"
99
- :templates-tree="props.templatesTree"
100
- :wizard="wizard"
101
- :selected-scheme="selectedScheme"
102
- :template-submit="templateSubmit"
103
- :name-form-submit="nameFormSubmit"
104
- :storage-submit="storageSubmit"
105
- :customize-hardware-submit="customizeHardwareSubmit"
106
- :customize-hardware-for-template-submit="customizeHardwareForTemplateSubmit"
107
- :is-sphere="isSphere"
108
- :compatibility="compatibility"
109
- :guestOsFamilies="guestOsFamilies"
110
- :guestOsVersions="guestOsVersions"
111
- :machineTypes="machineTypes"
112
- :virtual-hardware-hard-disks-local="virtualHardwareHardDisksLocal"
113
- :virtual-hardware-cd-dvd-drives-local="virtualHardwareCdDvdDrivesLocal"
114
- :virtual-hardware-networks-local="virtualHardwareNetworksLocal"
115
- :max-cpus="maxCpus"
116
- :max-memory="maxMemory"
117
- :cpu-models="cpuModels"
118
- :selected-nav-item="selectedNavItem"
119
- :compatibility-info="compatibilityInfo"
120
- :is-show-power-on="isShowPowerOn"
121
- :data-center="props.dataCenter"
122
- :compute-resource="props.computeResource"
123
- :compute-resource-tree="props.computeResourceTree"
124
- :location-nodes="props.locationNodes"
125
- :allowed-location-kinds="allowedLocationKinds"
126
- :location-description="locationDescription"
127
- :vmt-settings="props.vmtSettings"
128
- :is-loading="isLoading"
129
- :validate-empty-name="props.validateEmptyName"
130
- :title="title"
131
- :name-request-url="props.nameRequestUrl"
132
- :validation-description="validationDescription"
133
- :name-exist-validation="nameExistValidation"
134
- :name-test-ids="nameTestIds"
135
- :is-loading-compute-tree="isLoadingComputeTree"
136
- :compute-resource-alert="computeResourceAlert"
137
- :compatibility-text="compatibilityText"
138
- @get-storage="emits('get-storage', $event)"
139
- @get-folders-or-files="emits('get-folders-or-files', $event)"
140
- @get-active-device-child="emits('get-active-device-child', $event)"
141
- @show-datastore-child="emits('show-datastore-child', $event)"
142
- @remove-error-by-title="emits('remove-error-by-title', $event)"
143
- @get-networks-table="emits('get-networks-table', $event)"
144
- @get-pci-devices="emits('get-pci-devices')"
145
- @change-steps="onChangeSteps"
146
- @change-template="onChangeTemplate"
147
- @change-name="onChangeName(...$event)"
148
- @change-storage="onChangeStorage"
149
- @change-select-options="onChangeSelectOptions"
150
- @change-compatibility="onChangeCompatibility"
151
- @change-boot-order="onChangeBootOrder"
152
- @change-customize-hardware="onChangeCustomizeHardware"
153
- @finish="onFinish"
154
- @hide="onHideModal"
155
- />
156
- </template>
157
-
158
- <script setup lang="ts">
159
- import type {
160
- UI_I_ValidationReturn,
161
- UI_I_WizardStep,
162
- } from '~/node_modules/bfg-uikit/components/ui/wizard/lib/models/interfaces'
163
- import Wizard from '~/node_modules/bfg-uikit/components/ui/wizard/lib/utils/utils'
164
- import type {
165
- UI_I_Localization,
166
- UI_I_ArbitraryObject,
167
- } from '~/lib/models/interfaces'
168
- import type { UI_T_Project } from '~/lib/models/types'
169
- import type { UI_I_FileTreeNode } from '~/components/lib/models/interfaces'
170
- import type { UI_I_NetworkTableItem } from '~/lib/models/store/network/interfaces'
171
- import type {
172
- UI_I_DatastoreTableItem,
173
- UI_I_FolderOrFileTreePayload,
174
- } from '~/lib/models/store/storage/interfaces'
175
- import type {
176
- // API_UI_I_Error,
177
- UI_I_ErrorValidationField,
178
- } from '~/lib/models/store/interfaces'
179
- import type { UI_I_TablePayload } from '~/lib/models/table/interfaces'
180
- import type { UI_I_TableInfoItem } from '~/components/atoms/table/info/lib/models/interfaces'
181
- import type {
182
- UI_T_AddVmFinishFunc,
183
- UI_T_SelectedNavItem,
184
- } from '~/components/common/vm/actions/common/lib/models/types'
185
- import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
186
- import type {
187
- UI_I_Capabilities,
188
- UI_I_VmForm,
189
- UI_I_VmFormCash,
190
- } from '~/components/common/vm/actions/common/lib/models/interfaces'
191
- import type { UI_I_SendDataCustomizeHardware } from '~/components/common/vm/actions/common/customizeHardware/lib/models/interfaces'
192
- import type {
193
- UI_I_SendDataCpu,
194
- UI_I_SendDataMemory,
195
- UI_I_SendDataNewCdDvdDrive,
196
- UI_I_SendDataNewHardDisk,
197
- UI_I_SendDataNewNetwork,
198
- } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/models/interfaces'
199
- import type { UI_I_OptionItem } from '~/components/atoms/lib/models/interfaces'
200
- import type { UI_T_ChangeBootOrder } from '~/components/common/vm/actions/lib/models/types'
201
- import type {
202
- UI_I_MediatedDevice,
203
- UI_I_PciDevice,
204
- UI_I_VmSettings,
205
- } from '~/lib/models/store/vm/interfaces'
206
- import type { UI_I_NameTestIds } from '~/components/common/wizards/common/steps/name/lib/models/interfaces'
207
- import type { UI_T_CompatibilityStatus } from '~/components/common/wizards/common/compatibility/lib/models/types'
208
- import { capabilities } from '~/components/common/vm/actions/common/lib/config/capabilities'
209
- import {
210
- stepsSchemeInitial,
211
- stepsFunc,
212
- dynamicSteps,
213
- } from '~/components/common/vm/actions/add/lib/config/steps'
214
- import { mapCapabilities } from '~/components/common/vm/actions/common/lib/utils/capabilities'
215
-
216
- const props = withDefaults(
217
- defineProps<{
218
- project: UI_T_Project
219
- nodes: UI_I_FileTreeNode[]
220
- files: UI_I_FileTreeNode[]
221
- networksTable: UI_I_NetworkTableItem[]
222
- datastore: UI_I_DatastoreTableItem[]
223
- isDatastoreLoading: boolean
224
- errorValidationFields: UI_I_ErrorValidationField[]
225
- readyCompleteTableInfo: UI_I_TableInfoItem[]
226
- vmCpuHelpTextSecond: string
227
- importFromVMWarevSphere: string
228
- finishFunc: UI_T_AddVmFinishFunc
229
- getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
230
- validateSendDataFunc: UI_T_AddVmFinishFunc<
231
- [UI_T_SelectedNavItem, null | number] | null
232
- >
233
- passthroughDevices: UI_I_PciDevice[]
234
- mediatedDevices: UI_I_MediatedDevice[]
235
- vmNameInWizard: string
236
- nameRequestUrl: string
237
- templatesTree?: UI_I_TreeNode[]
238
- capabilities?: UI_I_Capabilities
239
- vmtSettings?: UI_I_VmSettings | null
240
- validateEmptyName?: boolean
241
- dataCenter?: UI_I_TreeNode // для сферы
242
- computeResource?: UI_I_TreeNode // для сферы
243
- computeResourceTree?: UI_I_TreeNode[] // для сферы
244
- locationNodes?: UI_I_TreeNode[] // для сферы
245
- selectedTemplateId?: string // для сферы
246
- isVmt?: boolean // для сферы
247
- }>(),
248
- {
249
- templatesTree: [],
250
- capabilities: undefined,
251
- vmtSettings: undefined,
252
- validateEmptyName: false,
253
- dataCenter: null,
254
- computeResource: null,
255
- computeResourceTree: undefined,
256
- locationNodes: undefined,
257
- selectedTemplateId: '',
258
- isVmt: false,
259
- }
260
- )
261
-
262
- const emits = defineEmits<{
263
- (event: 'get-storage', value: UI_I_TablePayload): void
264
- (event: 'get-folders-or-files', value: UI_I_FolderOrFileTreePayload): void
265
- (event: 'get-active-device-child', value: UI_I_FileTreeNode): void
266
- (event: 'show-datastore-child', value: UI_I_FileTreeNode): void
267
- (event: 'remove-error-by-title', value: string): void
268
- (event: 'get-networks-table', value: UI_I_TablePayload): void
269
- (event: 'get-pci-devices'): void
270
- (event: 'get-pci-devices'): void
271
- (event: 'hide'): void
272
- (event: 'select-template', value: string): void
273
- (
274
- event: 'get-compute-resource-tree',
275
- value: { id: string | number; cb: () => void }
276
- ): void // для сферы
277
- (event: 'select-compute-resource-tree', value: UI_I_TreeNode): void // для сферы
278
- }>()
279
-
280
- const { $store, $recursion }: any = useNuxtApp()
281
- const isNewView = computed<boolean>(() => $store.getters['main/getIsNewView'])
282
-
283
- const localization = computed<UI_I_Localization>(() => useLocal())
284
-
285
- const isSphere = computed<boolean>(() => props.project === 'sphere')
286
-
287
- const title = computed<string>(() =>
288
- props.isVmt
289
- ? localization.value.vmt.newTemplate
290
- : localization.value.common.newVirtualMachine2
291
- )
292
-
293
- watch(
294
- () => props.capabilities,
295
- () => {
296
- if (props.capabilities) mapCapabilities(props.capabilities)
297
- },
298
- { deep: true, immediate: true }
299
- )
300
-
301
- const selectedCreateType = ref<string>('0')
302
- if (props.isVmt) selectedCreateType.value = '-1'
303
-
304
- const wizard: Wizard = new Wizard(
305
- stepsFunc(localization.value, props.isVmt, isSphere.value),
306
- stepsSchemeInitial
307
- )
308
- watch(
309
- selectedCreateType,
310
- (newValue) => {
311
- switch (newValue) {
312
- case '0':
313
- wizard.changeScheme(isSphere.value ? 1 : 0)
314
- break
315
- case '1':
316
- wizard.changeScheme(isSphere.value ? 6 : 2)
317
- break
318
- case '-1':
319
- wizard.changeScheme(isSphere.value ? 11 : 10)
320
- break
321
- }
322
- },
323
- { immediate: true }
324
- )
325
-
326
- // if (isSphere.value) wizard.changeScheme(1)
327
- const selectedScheme = computed<number[]>(() => wizard.selectedScheme.value)
328
- // const alertMessages = computed<string[][]>(() => wizard.alertMessages.value)
329
-
330
- const allowedLocationKinds = [3, 7] // TODO use from config
331
- const locationDescription = computed<string>(() =>
332
- props.isVmt
333
- ? localization.value.vmt.selectLocationTemplate
334
- : localization.value.common.selectLocationVirtualMachine
335
- )
336
-
337
- const nameTestIds: UI_I_NameTestIds = {
338
- name: 'virtual-machine-name',
339
- helpIcon: 'show-vm-name-help-icon',
340
- }
341
- const validationDescription =
342
- localization.value.common.enterValidLocationVirtualMachine
343
- const nameExistValidation =
344
- localization.value.common.vmNameExistInSelectedLocation
345
-
346
- const isShowSelectTemplate = computed<boolean>(
347
- () =>
348
- wizard.selectedStepId === dynamicSteps.selectTemplate &&
349
- selectedCreateType.value === '1'
350
- )
351
-
352
- const isShowPowerOn = computed<boolean>(
353
- () =>
354
- wizard.selectedStepId > dynamicSteps.customizeHardware &&
355
- selectedCreateType.value !== '1' &&
356
- !props.isVmt
357
- )
358
-
359
- const onChangeSteps = async (value: UI_I_WizardStep[]): Promise<void> => {
360
- wizard.changeSteps(value, validationFunc, validateSendData)
361
- }
362
- const validationFunc = async (
363
- value: UI_I_WizardStep[],
364
- currentStep: UI_I_WizardStep,
365
- nextStep: UI_I_WizardStep
366
- ): Promise<UI_I_ValidationReturn> => {
367
- let stepHasError = false
368
- let stepShouldStop = {
369
- ifOnCurrentStep: false,
370
- ifFromAnyStep: false,
371
- stoppageStepId: -1,
372
- }
373
-
374
- wizard.setLoader(true)
375
- if (
376
- wizard.isValidateForStep(
377
- dynamicSteps.selectTemplate,
378
- currentStep.id,
379
- nextStep.id
380
- )
381
- ) {
382
- const templateValidation = await checkTemplate(value)
383
-
384
- value = templateValidation.newValue
385
- stepHasError = stepHasError || templateValidation.stepHasError
386
- } else if (
387
- wizard.isValidateForStep(
388
- isSphere.value ? dynamicSteps.selectNameFolder : dynamicSteps.selectName,
389
- currentStep.id,
390
- nextStep.id
391
- )
392
- ) {
393
- const nameValidation = await onCheckName(value)
394
-
395
- value = nameValidation.newValue
396
- stepHasError = stepHasError || nameValidation.stepHasError
397
- } else if (
398
- isSphere.value &&
399
- wizard.isValidateForStep(
400
- dynamicSteps.selectComputeResource,
401
- currentStep.id,
402
- nextStep.id
403
- )
404
- ) {
405
- const computeResourceValidation = await checkComputeResource(value)
406
-
407
- value = computeResourceValidation.newValue
408
- stepHasError = stepHasError || computeResourceValidation.stepHasError
409
- } else if (
410
- wizard.isValidateForStep(
411
- dynamicSteps.selectStorage,
412
- currentStep.id,
413
- nextStep.id
414
- )
415
- ) {
416
- const storageValidation = await checkStorage(value)
417
-
418
- value = storageValidation.newValue
419
-
420
- stepHasError = stepHasError || storageValidation.stepHasError
421
- } else if (
422
- wizard.isValidateForStep(
423
- dynamicSteps.customizeHardware,
424
- currentStep.id,
425
- nextStep.id
426
- )
427
- ) {
428
- const validation = await checkCustomizeHardware(value)
429
-
430
- value = validation.newValue
431
-
432
- stepHasError = stepHasError || validation.stepHasError
433
- } else if (
434
- wizard.isValidateForStep(
435
- dynamicSteps.customizeHardwareTemplate,
436
- currentStep.id,
437
- nextStep.id
438
- )
439
- ) {
440
- const validation = await checkCustomizeHardwareForTemplate(value)
441
-
442
- value = validation.newValue
443
-
444
- stepHasError = stepHasError || validation.stepHasError
445
- }
446
- wizard.setLoader(false)
447
-
448
- return {
449
- newValue: value,
450
- stepHasError,
451
- stepShouldStop,
452
- }
453
- }
454
-
455
- const checkTemplate = async (
456
- value: UI_I_WizardStep[]
457
- ): Promise<UI_I_ValidationReturn> => {
458
- let stepHasError = false
459
-
460
- return new Promise((resolve) => {
461
- templateSubmit.value = (isValid: boolean) => {
462
- if (!isValid) {
463
- stepHasError = wizard.setValidation(
464
- dynamicSteps.selectTemplate,
465
- 'template',
466
- {
467
- fieldMessage: 'aaa',
468
- alertMessage: 'aaa',
469
- }
470
- )
471
- } else if (wizard.hasMessage(dynamicSteps.selectTemplate, 'template')) {
472
- value = wizard.removeValidation(
473
- dynamicSteps.selectTemplate,
474
- 'template',
475
- value
476
- )
477
- }
478
-
479
- resolve({
480
- stepHasError,
481
- newValue: value,
482
- })
483
- templateSubmit.value = null
484
- }
485
- })
486
- }
487
- const onCheckName = async (
488
- value: UI_I_WizardStep[]
489
- ): Promise<UI_I_ValidationReturn> => {
490
- let stepHasError = false
491
-
492
- return new Promise((resolve) => {
493
- const step = isSphere.value
494
- ? dynamicSteps.selectNameFolder
495
- : dynamicSteps.selectName
496
- nameFormSubmit.value = (isValid: boolean) => {
497
- if (!isValid) {
498
- stepHasError = wizard.setValidation(step, 'name', {
499
- fieldMessage: 'aaa',
500
- alertMessage: 'aaa',
501
- })
502
- } else if (wizard.hasMessage(step, 'name')) {
503
- value = wizard.removeValidation(step, 'name', value)
504
- }
505
-
506
- resolve({
507
- stepHasError,
508
- newValue: value,
509
- })
510
- nameFormSubmit.value = null
511
- }
512
- })
513
- }
514
- const compatibilityText = computed<[UI_T_CompatibilityStatus, string]>(() => {
515
- const { computeResource } = vmForm.value
516
-
517
- if (!computeResource)
518
- return [
519
- 'none',
520
- localization.value.vmWizard.noDestinationComputeResourceSelected,
521
- ]
522
-
523
- let res: [UI_T_CompatibilityStatus, string] = [
524
- 'success',
525
- localization.value.common.compatibilityChecksSucceeded,
526
- ]
527
-
528
- if (!['cluster', 'host', 'resource_pool'].includes(computeResource?.type)) {
529
- res = [
530
- 'error',
531
- localization.value.common.selectValidClusterOrHostDestination,
532
- ]
533
- }
534
- if (computeResource?.type === 'cluster') {
535
- const hasHost = !!computeResource.nodes.length
536
- if (!hasHost) {
537
- res = ['error', localization.value.common.clusterNotContainAnyHosts]
538
- }
539
- }
540
-
541
- if (computeResource?.type === 'host') {
542
- if (computeResource.state === 'Error') {
543
- // TODO check Maintenance Mode
544
- res = [
545
- 'error',
546
- localization.value.common.selectedHostDisconnectedMaintenanceMode,
547
- ]
548
- }
549
- }
550
-
551
- return res
552
- })
553
- const computeResourceAlert = ref<string[]>([])
554
- const checkComputeResource = (
555
- value: UI_I_WizardStep[]
556
- ): UI_I_ValidationReturn => {
557
- let stepHasError = false
558
-
559
- const { computeResource } = vmForm.value
560
-
561
- if (
562
- !computeResource ||
563
- // compatibilityText.value[0] !== 1 ||
564
- computeResource.type === 'datacenter' ||
565
- computeResource.type === 'folder' ||
566
- (computeResource.type === 'cluster' && !computeResource.nodes.length)
567
- ) {
568
- computeResourceAlert.value = [
569
- localization.value.common.specifyValidClusterOrHostDestination,
570
- ]
571
- stepHasError = wizard.setValidation(
572
- dynamicSteps.selectComputeResource,
573
- 'computeResource',
574
- {
575
- fieldMessage: 'aaa',
576
- alertMessage: 'aaa',
577
- }
578
- )
579
- } else {
580
- computeResourceAlert.value = []
581
- if (
582
- wizard.hasMessage(dynamicSteps.selectComputeResource, 'computeResource')
583
- ) {
584
- value = wizard.removeValidation(
585
- dynamicSteps.selectComputeResource,
586
- 'computeResource',
587
- value
588
- )
589
- }
590
- }
591
-
592
- return {
593
- stepHasError,
594
- newValue: value,
595
- }
596
- }
597
- const checkStorage = async (
598
- value: UI_I_WizardStep[]
599
- ): Promise<UI_I_ValidationReturn> => {
600
- let stepHasError = false
601
-
602
- return new Promise((resolve) => {
603
- storageSubmit.value = (isValid: boolean) => {
604
- if (!isValid) {
605
- stepHasError = wizard.setValidation(
606
- dynamicSteps.selectStorage,
607
- 'storage',
608
- {
609
- fieldMessage: 'aaa',
610
- alertMessage: 'aaa',
611
- }
612
- )
613
- } else if (wizard.hasMessage(dynamicSteps.selectStorage, 'storage')) {
614
- value = wizard.removeValidation(
615
- dynamicSteps.selectStorage,
616
- 'storage',
617
- value
618
- )
619
- }
620
-
621
- resolve({
622
- stepHasError,
623
- newValue: value,
624
- })
625
- storageSubmit.value = null
626
- }
627
- })
628
- }
629
- const checkCustomizeHardware = async (
630
- value: UI_I_WizardStep[]
631
- ): Promise<UI_I_ValidationReturn> => {
632
- let stepHasError = false
633
- isLoading.value = true
634
-
635
- return new Promise((resolve) => {
636
- customizeHardwareSubmit.value = (isValid: boolean) => {
637
- if (!isValid) {
638
- stepHasError = wizard.setValidation(
639
- dynamicSteps.customizeHardware,
640
- 'customizeHardware',
641
- {
642
- fieldMessage: 'aaa',
643
- alertMessage: 'aaa',
644
- }
645
- )
646
- } else if (
647
- wizard.hasMessage(dynamicSteps.customizeHardware, 'customizeHardware')
648
- ) {
649
- wizard.removeValidationLocal(
650
- dynamicSteps.customizeHardware,
651
- 'customizeHardware'
652
- )
653
- value = wizard.removeValidation(
654
- dynamicSteps.customizeHardware,
655
- 'customizeHardware',
656
- value
657
- )
658
- }
659
-
660
- resolve({
661
- stepHasError,
662
- newValue: value,
663
- })
664
- storageSubmit.value = null
665
- isLoading.value = false
666
- }
667
- })
668
- }
669
- const checkCustomizeHardwareForTemplate = async (
670
- value: UI_I_WizardStep[]
671
- ): Promise<UI_I_ValidationReturn> => {
672
- let stepHasError = false
673
-
674
- return new Promise((resolve) => {
675
- customizeHardwareForTemplateSubmit.value = (isValid: boolean) => {
676
- if (!isValid) {
677
- stepHasError = wizard.setValidation(
678
- dynamicSteps.customizeHardwareTemplate,
679
- 'customizeHardwareForTemplate',
680
- {
681
- fieldMessage: 'aaa',
682
- alertMessage: 'aaa',
683
- }
684
- )
685
- } else if (
686
- wizard.hasMessage(
687
- dynamicSteps.customizeHardwareTemplate,
688
- 'customizeHardwareForTemplate'
689
- )
690
- ) {
691
- value = wizard.removeValidation(
692
- dynamicSteps.customizeHardwareTemplate,
693
- 'customizeHardwareForTemplate',
694
- value
695
- )
696
- }
697
-
698
- resolve({
699
- stepHasError,
700
- newValue: value,
701
- })
702
- storageSubmit.value = null
703
- }
704
- })
705
- }
706
-
707
- const storageIdCash = ref<string | null>(null)
708
- const vmForm = ref<UI_I_VmForm>({
709
- name: '',
710
- compatibility: '',
711
- guestMachineType: null,
712
- guestOsFamily: null,
713
- guestOsVersion: null,
714
- computeResource: props.computeResource,
715
- storage: null,
716
- locationPath: '',
717
- dataCenter: null,
718
- })
719
-
720
- const isLoadingComputeTree = ref<boolean>(false)
721
- const onChangeName = (name: string, node: UI_I_TreeNode | null): void => {
722
- vmForm.value.name = name // TODO уже нету смысла
723
- if (isSphere.value) {
724
- vmForm.value.locationPath = node.id
725
- vmForm.value.dataCenter = $recursion.findParentByValue(
726
- node,
727
- 'datacenter',
728
- 'type',
729
- 'parent'
730
- )
731
- isLoadingComputeTree.value = true
732
- emits('get-compute-resource-tree', {
733
- id: node.id,
734
- cb: () => {
735
- isLoadingComputeTree.value = false
736
- },
737
- })
738
- }
739
- }
740
- // Для сферы
741
- const computeResourcePath = ref<string>('')
742
- const onSelectComputeResourceTree = (node: UI_I_TreeNode): void => {
743
- emits('select-compute-resource-tree', node)
744
- computeResourcePath.value = node.id
745
- }
746
- watch(
747
- () => vmForm.value.computeResource,
748
- (newValue, oldValue) => {
749
- if (newValue && newValue.id !== oldValue?.id) {
750
- onSelectComputeResourceTree(newValue)
751
- }
752
- },
753
- { deep: true, immediate: true }
754
- )
755
-
756
- const onChangeStorage = (storage: UI_I_DatastoreTableItem | null): void => {
757
- if (!storage) return
758
-
759
- vmForm.value.storage = storage
760
- storageIdCash.value = storage.id
761
- }
762
- const compatibilityInfo = ref<string>('')
763
- const onChangeCompatibility = (compatibility: UI_I_OptionItem): void => {
764
- vmForm.value.compatibility = compatibility.value
765
-
766
- const version = compatibility.value.split('-')[1]
767
- compatibilityInfo.value = `${localization.value.common.compatibility}: ${compatibility.text} (${localization.value.common.vmVersion} ${version})`
768
- }
769
- const customizeHardware = ref<UI_I_SendDataCustomizeHardware | null>(null)
770
- const onChangeCustomizeHardware = (
771
- data: UI_I_SendDataCustomizeHardware
772
- ): void => {
773
- customizeHardware.value = data
774
- }
775
-
776
- const virtualHardwareHardDisksLocal = computed<
777
- UI_I_SendDataNewHardDisk[] | null
778
- >(() => customizeHardware.value?.virtualHardware?.hardDisks || null)
779
- const virtualHardwareNetworksLocal = computed<UI_I_SendDataNewNetwork[] | null>(
780
- () => customizeHardware.value?.virtualHardware?.networks || null
781
- )
782
- const virtualHardwareCdDvdDrivesLocal = computed<
783
- UI_I_SendDataNewCdDvdDrive[] | null
784
- >(() => customizeHardware.value?.virtualHardware?.cdDvdDrives || null)
785
-
786
- const virtualHardwareCpu = computed<UI_I_SendDataCpu | null>(
787
- () => customizeHardware.value?.virtualHardware?.cpu || null
788
- )
789
- const virtualHardwareMemory = computed<UI_I_SendDataMemory | null>(
790
- () => customizeHardware.value?.virtualHardware?.memory || null
791
- )
792
- const virtualHardwareHardDisks = ref<UI_I_SendDataNewHardDisk[] | null>(null)
793
- const virtualHardwareCdDvdDrives = ref<UI_I_SendDataNewCdDvdDrive[] | null>(
794
- null
795
- )
796
- const virtualHardwareNetworks = ref<UI_I_SendDataNewNetwork[] | null>(null)
797
- const onChangeBootOrder = (data: UI_T_ChangeBootOrder): void => {
798
- virtualHardwareHardDisks.value = data[0]
799
- virtualHardwareCdDvdDrives.value = data[1]
800
- virtualHardwareNetworks.value = data[2]
801
- }
802
-
803
- const isPowerOnByDefault = ref<boolean>(true)
804
-
805
- watch(
806
- () => props.vmNameInWizard,
807
- (newValue) => {
808
- vmForm.value.name = newValue
809
- }
810
- )
811
-
812
- const validateSendData = async (
813
- value: UI_I_WizardStep[]
814
- ): Promise<UI_I_ValidationReturn> => {
815
- wizard.setLoader(true)
816
- let stepHasError = false
817
- isLoading.value = true
818
-
819
- const data = await props.validateSendDataFunc(
820
- vmForm.value,
821
- virtualHardwareCpu.value,
822
- virtualHardwareMemory.value,
823
- customizeHardware.value,
824
- virtualHardwareNetworks.value,
825
- virtualHardwareHardDisks.value,
826
- virtualHardwareCdDvdDrives.value,
827
- isPowerOnByDefault.value,
828
- localization.value,
829
- vmForm.value.locationPath, // для сферы
830
- computeResourcePath.value // для сферы
831
- )
832
-
833
- isLoading.value = false
834
- wizard.setLoader(false)
835
- if (data) {
836
- stepHasError = true
837
- selectedNavItem.value = data[0]
838
- data[1] !== null && wizard.selectStepHard(data[1])
839
- }
840
-
841
- return {
842
- stepHasError,
843
- newValue: value,
844
- }
845
- }
846
-
847
- const isLoading = ref<boolean>(false)
848
- const onFinish = (): void => {
849
- isLoading.value = true
850
- wizard.setLoader(false)
851
- props
852
- .finishFunc(
853
- vmForm.value,
854
- virtualHardwareCpu.value,
855
- virtualHardwareMemory.value,
856
- customizeHardware.value,
857
- virtualHardwareNetworks.value,
858
- virtualHardwareHardDisks.value,
859
- virtualHardwareCdDvdDrives.value,
860
- isPowerOnByDefault.value,
861
- localization.value,
862
- vmForm.value.locationPath, // для сферы
863
- computeResourcePath.value, // для сферы
864
- false,
865
- selectedTemplate.value,
866
- selectedCreateType.value
867
- )
868
- .then(() => {
869
- onHideModal()
870
- wizard.setLoader(false)
871
- isLoading.value = false
872
- })
873
- }
874
-
875
- const selectedNavItem = ref<UI_T_SelectedNavItem>(0)
876
-
877
- const nameFormSubmit = ref<null | Function>(null)
878
- const templateSubmit = ref<null | Function>(null)
879
- const storageSubmit = ref<null | Function>(null)
880
- const customizeHardwareSubmit = ref<null | Function>(null)
881
- const customizeHardwareForTemplateSubmit = ref<null | Function>(null)
882
- const compatibility = ref<UI_I_OptionItem[]>(capabilities.value.compatibility)
883
- const guestOsFamilies = ref<UI_I_OptionItem[]>(
884
- capabilities.value.guestOsFamilies
885
- )
886
- const guestOsVersions = ref<UI_I_ArbitraryObject<UI_I_OptionItem[]>>(
887
- capabilities.value.guestOsVersions
888
- )
889
- const machineTypes = ref<UI_I_OptionItem[]>(capabilities.value.machineTypes)
890
- const cpuModels = ref<UI_I_OptionItem[]>(capabilities.value.cpuModels)
891
- const maxCpus = ref<number>(capabilities.value.maxCpus)
892
- const maxMemory = ref<number>(capabilities.value.maxMemory)
893
-
894
- const selectedTemplate = ref<string>('')
895
- const onChangeTemplate = (node: UI_I_TreeNode): void => {
896
- selectedTemplate.value = node.id.toString()
897
- emits('select-template', node.id.toString())
898
- }
899
- const selectedOptions = ref<string[]>([])
900
- const onChangeSelectOptions = (options: string[]) => {
901
- selectedOptions.value = options
902
- if (
903
- options.includes('customize-os') &&
904
- options.includes('customize-hardware')
905
- ) {
906
- wizard.changeScheme(isSphere.value ? 9 : 5)
907
- } else if (options.includes('customize-os')) {
908
- wizard.changeScheme(isSphere.value ? 7 : 3)
909
- } else if (options.includes('customize-hardware')) {
910
- wizard.changeScheme(isSphere.value ? 8 : 4)
911
- } else {
912
- wizard.changeScheme(isSphere.value ? 6 : 2)
913
- }
914
-
915
- isPowerOnByDefault.value = options.includes('power-on')
916
- }
917
-
918
- const onHideModal = (): void => {
919
- emits('hide')
920
- }
921
-
922
- watch(
923
- () => props.vmtSettings,
924
- (newValue) => {
925
- if (newValue) {
926
- vmForm.value.name = newValue.name
927
- vmForm.value.compatibility =
928
- newValue.compatibility || vmForm.value.compatibility
929
- vmForm.value.storage = newValue.storage
930
- if (customizeHardware.value?.virtualHardware) {
931
- customizeHardware.value.virtualHardware.cdDvdDrives =
932
- newValue.cdDvdDrives
933
- customizeHardware.value.virtualHardware.hardDisks = newValue.hardDisks
934
- customizeHardware.value.virtualHardware.networks = newValue.networks
935
- customizeHardware.value.virtualHardware.cpu = newValue.cpu
936
- customizeHardware.value.virtualHardware.memory = newValue.memory
937
- customizeHardware.value.virtualHardware.videoCard = newValue.videoCard
938
- customizeHardware.value.virtualHardware.usbController =
939
- newValue.usbController
940
- customizeHardware.value.virtualHardware.pciDevices = newValue.pciDevices
941
- customizeHardware.value.vmOptions = newValue.options
942
- }
943
- maxCpus.value = newValue.cpu.max_vcpus
944
- cpuModels.value = newValue.cpu.model
945
- isPowerOnByDefault.value = false
946
- }
947
- }
948
- )
949
- </script>
950
-
951
- <style scoped lang="scss"></style>
1
+ <template>
2
+ <common-vm-actions-add-new
3
+ v-if="isNewView"
4
+ v-model:vm-form="vmForm"
5
+ v-model:selected-create-type="selectedCreateType"
6
+ v-model:is-power-on-by-default="isPowerOnByDefault"
7
+ :project="props.project"
8
+ :is-vmt="props.isVmt"
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
+ :import-from-v-m-warev-sphere="props.importFromVMWarevSphere"
18
+ :get-datastore-table-func="props.getDatastoreTableFunc"
19
+ :passthrough-devices="props.passthroughDevices"
20
+ :mediated-devices="props.mediatedDevices"
21
+ :templates-tree="props.templatesTree"
22
+ :wizard="wizard"
23
+ :selected-scheme="selectedScheme"
24
+ :template-submit="templateSubmit"
25
+ :name-form-submit="nameFormSubmit"
26
+ :storage-submit="storageSubmit"
27
+ :customize-hardware-submit="customizeHardwareSubmit"
28
+ :customize-hardware-for-template-submit="customizeHardwareForTemplateSubmit"
29
+ :is-sphere="isSphere"
30
+ :compatibility="compatibility"
31
+ :guestOsFamilies="guestOsFamilies"
32
+ :guestOsVersions="guestOsVersions"
33
+ :machineTypes="machineTypes"
34
+ :virtual-hardware-hard-disks-local="virtualHardwareHardDisksLocal"
35
+ :virtual-hardware-cd-dvd-drives-local="virtualHardwareCdDvdDrivesLocal"
36
+ :virtual-hardware-networks-local="virtualHardwareNetworksLocal"
37
+ :max-cpus="maxCpus"
38
+ :max-memory="maxMemory"
39
+ :cpu-models="cpuModels"
40
+ :selected-nav-item="selectedNavItem"
41
+ :compatibility-info="compatibilityInfo"
42
+ :is-show-power-on="isShowPowerOn"
43
+ :is-show-select-template="isShowSelectTemplate"
44
+ :data-center="props.dataCenter"
45
+ :compute-resource="props.computeResource"
46
+ :compute-resource-tree="props.computeResourceTree"
47
+ :location-nodes="props.locationNodes"
48
+ :allowed-location-kinds="allowedLocationKinds"
49
+ :location-description="locationDescription"
50
+ :vmt-settings="props.vmtSettings"
51
+ :is-loading="isLoading"
52
+ :selected-template-id="props.selectedTemplateId"
53
+ :validate-empty-name="props.validateEmptyName"
54
+ :title="title"
55
+ :name-request-url="props.nameRequestUrl"
56
+ :validation-description="validationDescription"
57
+ :name-exist-validation="nameExistValidation"
58
+ :name-test-ids="nameTestIds"
59
+ :is-loading-compute-tree="isLoadingComputeTree"
60
+ :compute-resource-alert="computeResourceAlert"
61
+ :compatibility-text="compatibilityText"
62
+ @get-storage="emits('get-storage', $event)"
63
+ @get-folders-or-files="emits('get-folders-or-files', $event)"
64
+ @get-active-device-child="emits('get-active-device-child', $event)"
65
+ @show-datastore-child="emits('show-datastore-child', $event)"
66
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
67
+ @get-networks-table="emits('get-networks-table', $event)"
68
+ @get-pci-devices="emits('get-pci-devices')"
69
+ @change-steps="onChangeSteps"
70
+ @change-template="onChangeTemplate"
71
+ @change-name="onChangeName(...$event)"
72
+ @change-storage="onChangeStorage"
73
+ @change-select-options="onChangeSelectOptions"
74
+ @change-clone-count="cloneCount = $event"
75
+ @change-compatibility="onChangeCompatibility"
76
+ @change-boot-order="onChangeBootOrder"
77
+ @change-customize-hardware="onChangeCustomizeHardware"
78
+ @finish="onFinish"
79
+ @hide="onHideModal"
80
+ />
81
+ <common-vm-actions-add-old
82
+ v-else
83
+ v-model:vm-form="vmForm"
84
+ v-model:selected-create-type="selectedCreateType"
85
+ v-model:is-power-on-by-default="isPowerOnByDefault"
86
+ :project="props.project"
87
+ :is-vmt="props.isVmt"
88
+ :nodes="props.nodes"
89
+ :files="props.files"
90
+ :networks-table="props.networksTable"
91
+ :datastore="props.datastore"
92
+ :is-datastore-loading="props.isDatastoreLoading"
93
+ :error-validation-fields="props.errorValidationFields"
94
+ :ready-complete-table-info="props.readyCompleteTableInfo"
95
+ :vm-cpu-help-text-second="props.vmCpuHelpTextSecond"
96
+ :import-from-v-m-warev-sphere="props.importFromVMWarevSphere"
97
+ :get-datastore-table-func="props.getDatastoreTableFunc"
98
+ :passthrough-devices="props.passthroughDevices"
99
+ :mediated-devices="props.mediatedDevices"
100
+ :templates-tree="props.templatesTree"
101
+ :wizard="wizard"
102
+ :selected-scheme="selectedScheme"
103
+ :template-submit="templateSubmit"
104
+ :name-form-submit="nameFormSubmit"
105
+ :storage-submit="storageSubmit"
106
+ :customize-hardware-submit="customizeHardwareSubmit"
107
+ :customize-hardware-for-template-submit="customizeHardwareForTemplateSubmit"
108
+ :is-sphere="isSphere"
109
+ :compatibility="compatibility"
110
+ :guestOsFamilies="guestOsFamilies"
111
+ :guestOsVersions="guestOsVersions"
112
+ :machineTypes="machineTypes"
113
+ :virtual-hardware-hard-disks-local="virtualHardwareHardDisksLocal"
114
+ :virtual-hardware-cd-dvd-drives-local="virtualHardwareCdDvdDrivesLocal"
115
+ :virtual-hardware-networks-local="virtualHardwareNetworksLocal"
116
+ :max-cpus="maxCpus"
117
+ :max-memory="maxMemory"
118
+ :cpu-models="cpuModels"
119
+ :selected-nav-item="selectedNavItem"
120
+ :compatibility-info="compatibilityInfo"
121
+ :is-show-power-on="isShowPowerOn"
122
+ :data-center="props.dataCenter"
123
+ :compute-resource="props.computeResource"
124
+ :compute-resource-tree="props.computeResourceTree"
125
+ :location-nodes="props.locationNodes"
126
+ :allowed-location-kinds="allowedLocationKinds"
127
+ :location-description="locationDescription"
128
+ :vmt-settings="props.vmtSettings"
129
+ :is-loading="isLoading"
130
+ :validate-empty-name="props.validateEmptyName"
131
+ :title="title"
132
+ :name-request-url="props.nameRequestUrl"
133
+ :validation-description="validationDescription"
134
+ :name-exist-validation="nameExistValidation"
135
+ :name-test-ids="nameTestIds"
136
+ :is-loading-compute-tree="isLoadingComputeTree"
137
+ :compute-resource-alert="computeResourceAlert"
138
+ :compatibility-text="compatibilityText"
139
+ @get-storage="emits('get-storage', $event)"
140
+ @get-folders-or-files="emits('get-folders-or-files', $event)"
141
+ @get-active-device-child="emits('get-active-device-child', $event)"
142
+ @show-datastore-child="emits('show-datastore-child', $event)"
143
+ @remove-error-by-title="emits('remove-error-by-title', $event)"
144
+ @get-networks-table="emits('get-networks-table', $event)"
145
+ @get-pci-devices="emits('get-pci-devices')"
146
+ @change-steps="onChangeSteps"
147
+ @change-template="onChangeTemplate"
148
+ @change-name="onChangeName(...$event)"
149
+ @change-storage="onChangeStorage"
150
+ @change-select-options="onChangeSelectOptions"
151
+ @change-clone-count="cloneCount = $event"
152
+ @change-compatibility="onChangeCompatibility"
153
+ @change-boot-order="onChangeBootOrder"
154
+ @change-customize-hardware="onChangeCustomizeHardware"
155
+ @finish="onFinish"
156
+ @hide="onHideModal"
157
+ />
158
+ </template>
159
+
160
+ <script setup lang="ts">
161
+ import type {
162
+ UI_I_ValidationReturn,
163
+ UI_I_WizardStep,
164
+ } from '~/node_modules/bfg-uikit/components/ui/wizard/lib/models/interfaces'
165
+ import Wizard from '~/node_modules/bfg-uikit/components/ui/wizard/lib/utils/utils'
166
+ import type {
167
+ UI_I_Localization,
168
+ UI_I_ArbitraryObject,
169
+ } from '~/lib/models/interfaces'
170
+ import type { UI_T_Project } from '~/lib/models/types'
171
+ import type { UI_I_FileTreeNode } from '~/components/lib/models/interfaces'
172
+ import type { UI_I_NetworkTableItem } from '~/lib/models/store/network/interfaces'
173
+ import type {
174
+ UI_I_DatastoreTableItem,
175
+ UI_I_FolderOrFileTreePayload,
176
+ } from '~/lib/models/store/storage/interfaces'
177
+ import type {
178
+ // API_UI_I_Error,
179
+ UI_I_ErrorValidationField,
180
+ } from '~/lib/models/store/interfaces'
181
+ import type { UI_I_TablePayload } from '~/lib/models/table/interfaces'
182
+ import type { UI_I_TableInfoItem } from '~/components/atoms/table/info/lib/models/interfaces'
183
+ import type {
184
+ UI_T_AddVmFinishFunc,
185
+ UI_T_SelectedNavItem,
186
+ } from '~/components/common/vm/actions/common/lib/models/types'
187
+ import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
188
+ import type {
189
+ UI_I_Capabilities,
190
+ UI_I_VmForm,
191
+ UI_I_VmFormCash,
192
+ } from '~/components/common/vm/actions/common/lib/models/interfaces'
193
+ import type { UI_I_SendDataCustomizeHardware } from '~/components/common/vm/actions/common/customizeHardware/lib/models/interfaces'
194
+ import type {
195
+ UI_I_SendDataCpu,
196
+ UI_I_SendDataMemory,
197
+ UI_I_SendDataNewCdDvdDrive,
198
+ UI_I_SendDataNewHardDisk,
199
+ UI_I_SendDataNewNetwork,
200
+ } from '~/components/common/vm/actions/common/customizeHardware/virtualHardware/lib/models/interfaces'
201
+ import type { UI_I_OptionItem } from '~/components/atoms/lib/models/interfaces'
202
+ import type { UI_T_ChangeBootOrder } from '~/components/common/vm/actions/lib/models/types'
203
+ import type {
204
+ UI_I_MediatedDevice,
205
+ UI_I_PciDevice,
206
+ UI_I_VmSettings,
207
+ } from '~/lib/models/store/vm/interfaces'
208
+ import type { UI_I_NameTestIds } from '~/components/common/wizards/common/steps/name/lib/models/interfaces'
209
+ import type { UI_T_CompatibilityStatus } from '~/components/common/wizards/common/compatibility/lib/models/types'
210
+ import { capabilities } from '~/components/common/vm/actions/common/lib/config/capabilities'
211
+ import {
212
+ stepsSchemeInitial,
213
+ stepsFunc,
214
+ dynamicSteps,
215
+ } from '~/components/common/vm/actions/add/lib/config/steps'
216
+ import { mapCapabilities } from '~/components/common/vm/actions/common/lib/utils/capabilities'
217
+
218
+ const props = withDefaults(
219
+ defineProps<{
220
+ project: UI_T_Project
221
+ nodes: UI_I_FileTreeNode[]
222
+ files: UI_I_FileTreeNode[]
223
+ networksTable: UI_I_NetworkTableItem[]
224
+ datastore: UI_I_DatastoreTableItem[]
225
+ isDatastoreLoading: boolean
226
+ errorValidationFields: UI_I_ErrorValidationField[]
227
+ readyCompleteTableInfo: UI_I_TableInfoItem[]
228
+ vmCpuHelpTextSecond: string
229
+ importFromVMWarevSphere: string
230
+ finishFunc: UI_T_AddVmFinishFunc
231
+ getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
232
+ validateSendDataFunc: UI_T_AddVmFinishFunc<
233
+ [UI_T_SelectedNavItem, null | number] | null
234
+ >
235
+ passthroughDevices: UI_I_PciDevice[]
236
+ mediatedDevices: UI_I_MediatedDevice[]
237
+ vmNameInWizard: string
238
+ nameRequestUrl: string
239
+ templatesTree?: UI_I_TreeNode[]
240
+ capabilities?: UI_I_Capabilities
241
+ vmtSettings?: UI_I_VmSettings | null
242
+ validateEmptyName?: boolean
243
+ dataCenter?: UI_I_TreeNode // для сферы
244
+ computeResource?: UI_I_TreeNode // для сферы
245
+ computeResourceTree?: UI_I_TreeNode[] // для сферы
246
+ locationNodes?: UI_I_TreeNode[] // для сферы
247
+ selectedTemplateId?: string // для сферы
248
+ isVmt?: boolean // для сферы
249
+ }>(),
250
+ {
251
+ templatesTree: [],
252
+ capabilities: undefined,
253
+ vmtSettings: undefined,
254
+ validateEmptyName: false,
255
+ dataCenter: null,
256
+ computeResource: null,
257
+ computeResourceTree: undefined,
258
+ locationNodes: undefined,
259
+ selectedTemplateId: '',
260
+ isVmt: false,
261
+ }
262
+ )
263
+
264
+ const emits = defineEmits<{
265
+ (event: 'get-storage', value: UI_I_TablePayload): void
266
+ (event: 'get-folders-or-files', value: UI_I_FolderOrFileTreePayload): void
267
+ (event: 'get-active-device-child', value: UI_I_FileTreeNode): void
268
+ (event: 'show-datastore-child', value: UI_I_FileTreeNode): void
269
+ (event: 'remove-error-by-title', value: string): void
270
+ (event: 'get-networks-table', value: UI_I_TablePayload): void
271
+ (event: 'get-pci-devices'): void
272
+ (event: 'get-pci-devices'): void
273
+ (event: 'hide'): void
274
+ (event: 'select-template', value: string): void
275
+ (
276
+ event: 'get-compute-resource-tree',
277
+ value: { id: string | number; cb: () => void }
278
+ ): void // для сферы
279
+ (event: 'select-compute-resource-tree', value: UI_I_TreeNode): void // для сферы
280
+ }>()
281
+
282
+ const { $store, $recursion }: any = useNuxtApp()
283
+ const isNewView = computed<boolean>(() => $store.getters['main/getIsNewView'])
284
+
285
+ const localization = computed<UI_I_Localization>(() => useLocal())
286
+
287
+ const isSphere = computed<boolean>(() => props.project === 'sphere')
288
+
289
+ const title = computed<string>(() =>
290
+ props.isVmt
291
+ ? localization.value.vmt.newTemplate
292
+ : localization.value.common.newVirtualMachine2
293
+ )
294
+
295
+ watch(
296
+ () => props.capabilities,
297
+ () => {
298
+ if (props.capabilities) mapCapabilities(props.capabilities)
299
+ },
300
+ { deep: true, immediate: true }
301
+ )
302
+
303
+ const selectedCreateType = ref<string>('0')
304
+ if (props.isVmt) selectedCreateType.value = '-1'
305
+
306
+ const wizard: Wizard = new Wizard(
307
+ stepsFunc(localization.value, props.isVmt, isSphere.value),
308
+ stepsSchemeInitial
309
+ )
310
+ watch(
311
+ selectedCreateType,
312
+ (newValue) => {
313
+ switch (newValue) {
314
+ case '0':
315
+ wizard.changeScheme(isSphere.value ? 1 : 0)
316
+ break
317
+ case '1':
318
+ wizard.changeScheme(isSphere.value ? 6 : 2)
319
+ break
320
+ case '-1':
321
+ wizard.changeScheme(isSphere.value ? 11 : 10)
322
+ break
323
+ }
324
+ },
325
+ { immediate: true }
326
+ )
327
+
328
+ // if (isSphere.value) wizard.changeScheme(1)
329
+ const selectedScheme = computed<number[]>(() => wizard.selectedScheme.value)
330
+ // const alertMessages = computed<string[][]>(() => wizard.alertMessages.value)
331
+
332
+ const allowedLocationKinds = [3, 7] // TODO use from config
333
+ const locationDescription = computed<string>(() =>
334
+ props.isVmt
335
+ ? localization.value.vmt.selectLocationTemplate
336
+ : localization.value.common.selectLocationVirtualMachine
337
+ )
338
+
339
+ const nameTestIds: UI_I_NameTestIds = {
340
+ name: 'virtual-machine-name',
341
+ helpIcon: 'show-vm-name-help-icon',
342
+ }
343
+ const validationDescription =
344
+ localization.value.common.enterValidLocationVirtualMachine
345
+ const nameExistValidation =
346
+ localization.value.common.vmNameExistInSelectedLocation
347
+
348
+ const isShowSelectTemplate = computed<boolean>(
349
+ () =>
350
+ wizard.selectedStepId === dynamicSteps.selectTemplate &&
351
+ selectedCreateType.value === '1'
352
+ )
353
+
354
+ const isShowPowerOn = computed<boolean>(
355
+ () =>
356
+ wizard.selectedStepId > dynamicSteps.customizeHardware &&
357
+ selectedCreateType.value !== '1' &&
358
+ !props.isVmt
359
+ )
360
+
361
+ const onChangeSteps = async (value: UI_I_WizardStep[]): Promise<void> => {
362
+ wizard.changeSteps(value, validationFunc, validateSendData)
363
+ }
364
+ const validationFunc = async (
365
+ value: UI_I_WizardStep[],
366
+ currentStep: UI_I_WizardStep,
367
+ nextStep: UI_I_WizardStep
368
+ ): Promise<UI_I_ValidationReturn> => {
369
+ let stepHasError = false
370
+ let stepShouldStop = {
371
+ ifOnCurrentStep: false,
372
+ ifFromAnyStep: false,
373
+ stoppageStepId: -1,
374
+ }
375
+
376
+ wizard.setLoader(true)
377
+ if (
378
+ wizard.isValidateForStep(
379
+ dynamicSteps.selectTemplate,
380
+ currentStep.id,
381
+ nextStep.id
382
+ )
383
+ ) {
384
+ const templateValidation = await checkTemplate(value)
385
+
386
+ value = templateValidation.newValue
387
+ stepHasError = stepHasError || templateValidation.stepHasError
388
+ } else if (
389
+ wizard.isValidateForStep(
390
+ isSphere.value ? dynamicSteps.selectNameFolder : dynamicSteps.selectName,
391
+ currentStep.id,
392
+ nextStep.id
393
+ )
394
+ ) {
395
+ const nameValidation = await onCheckName(value)
396
+
397
+ value = nameValidation.newValue
398
+ stepHasError = stepHasError || nameValidation.stepHasError
399
+ } else if (
400
+ isSphere.value &&
401
+ wizard.isValidateForStep(
402
+ dynamicSteps.selectComputeResource,
403
+ currentStep.id,
404
+ nextStep.id
405
+ )
406
+ ) {
407
+ const computeResourceValidation = await checkComputeResource(value)
408
+
409
+ value = computeResourceValidation.newValue
410
+ stepHasError = stepHasError || computeResourceValidation.stepHasError
411
+ } else if (
412
+ wizard.isValidateForStep(
413
+ dynamicSteps.selectStorage,
414
+ currentStep.id,
415
+ nextStep.id
416
+ )
417
+ ) {
418
+ const storageValidation = await checkStorage(value)
419
+
420
+ value = storageValidation.newValue
421
+
422
+ stepHasError = stepHasError || storageValidation.stepHasError
423
+ } else if (
424
+ wizard.isValidateForStep(
425
+ dynamicSteps.customizeHardware,
426
+ currentStep.id,
427
+ nextStep.id
428
+ )
429
+ ) {
430
+ const validation = await checkCustomizeHardware(value)
431
+
432
+ value = validation.newValue
433
+
434
+ stepHasError = stepHasError || validation.stepHasError
435
+ } else if (
436
+ wizard.isValidateForStep(
437
+ dynamicSteps.customizeHardwareTemplate,
438
+ currentStep.id,
439
+ nextStep.id
440
+ )
441
+ ) {
442
+ const validation = await checkCustomizeHardwareForTemplate(value)
443
+
444
+ value = validation.newValue
445
+
446
+ stepHasError = stepHasError || validation.stepHasError
447
+ }
448
+ wizard.setLoader(false)
449
+
450
+ return {
451
+ newValue: value,
452
+ stepHasError,
453
+ stepShouldStop,
454
+ }
455
+ }
456
+
457
+ const checkTemplate = async (
458
+ value: UI_I_WizardStep[]
459
+ ): Promise<UI_I_ValidationReturn> => {
460
+ let stepHasError = false
461
+
462
+ return new Promise((resolve) => {
463
+ templateSubmit.value = (isValid: boolean) => {
464
+ if (!isValid) {
465
+ stepHasError = wizard.setValidation(
466
+ dynamicSteps.selectTemplate,
467
+ 'template',
468
+ {
469
+ fieldMessage: 'aaa',
470
+ alertMessage: 'aaa',
471
+ }
472
+ )
473
+ } else if (wizard.hasMessage(dynamicSteps.selectTemplate, 'template')) {
474
+ value = wizard.removeValidation(
475
+ dynamicSteps.selectTemplate,
476
+ 'template',
477
+ value
478
+ )
479
+ }
480
+
481
+ resolve({
482
+ stepHasError,
483
+ newValue: value,
484
+ })
485
+ templateSubmit.value = null
486
+ }
487
+ })
488
+ }
489
+ const onCheckName = async (
490
+ value: UI_I_WizardStep[]
491
+ ): Promise<UI_I_ValidationReturn> => {
492
+ let stepHasError = false
493
+
494
+ return new Promise((resolve) => {
495
+ const step = isSphere.value
496
+ ? dynamicSteps.selectNameFolder
497
+ : dynamicSteps.selectName
498
+ nameFormSubmit.value = (isValid: boolean) => {
499
+ if (!isValid) {
500
+ stepHasError = wizard.setValidation(step, 'name', {
501
+ fieldMessage: 'aaa',
502
+ alertMessage: 'aaa',
503
+ })
504
+ } else if (wizard.hasMessage(step, 'name')) {
505
+ value = wizard.removeValidation(step, 'name', value)
506
+ }
507
+
508
+ resolve({
509
+ stepHasError,
510
+ newValue: value,
511
+ })
512
+ nameFormSubmit.value = null
513
+ }
514
+ })
515
+ }
516
+ const compatibilityText = computed<[UI_T_CompatibilityStatus, string]>(() => {
517
+ const { computeResource } = vmForm.value
518
+
519
+ if (!computeResource)
520
+ return [
521
+ 'none',
522
+ localization.value.vmWizard.noDestinationComputeResourceSelected,
523
+ ]
524
+
525
+ let res: [UI_T_CompatibilityStatus, string] = [
526
+ 'success',
527
+ localization.value.common.compatibilityChecksSucceeded,
528
+ ]
529
+
530
+ if (!['cluster', 'host', 'resource_pool'].includes(computeResource?.type)) {
531
+ res = [
532
+ 'error',
533
+ localization.value.common.selectValidClusterOrHostDestination,
534
+ ]
535
+ }
536
+ if (computeResource?.type === 'cluster') {
537
+ const hasHost = !!computeResource.nodes.length
538
+ if (!hasHost) {
539
+ res = ['error', localization.value.common.clusterNotContainAnyHosts]
540
+ }
541
+ }
542
+
543
+ if (computeResource?.type === 'host') {
544
+ if (computeResource.state === 'Error') {
545
+ // TODO check Maintenance Mode
546
+ res = [
547
+ 'error',
548
+ localization.value.common.selectedHostDisconnectedMaintenanceMode,
549
+ ]
550
+ }
551
+ }
552
+
553
+ return res
554
+ })
555
+ const computeResourceAlert = ref<string[]>([])
556
+ const checkComputeResource = (
557
+ value: UI_I_WizardStep[]
558
+ ): UI_I_ValidationReturn => {
559
+ let stepHasError = false
560
+
561
+ const { computeResource } = vmForm.value
562
+
563
+ if (
564
+ !computeResource ||
565
+ // compatibilityText.value[0] !== 1 ||
566
+ computeResource.type === 'datacenter' ||
567
+ computeResource.type === 'folder' ||
568
+ (computeResource.type === 'cluster' && !computeResource.nodes.length)
569
+ ) {
570
+ computeResourceAlert.value = [
571
+ localization.value.common.specifyValidClusterOrHostDestination,
572
+ ]
573
+ stepHasError = wizard.setValidation(
574
+ dynamicSteps.selectComputeResource,
575
+ 'computeResource',
576
+ {
577
+ fieldMessage: 'aaa',
578
+ alertMessage: 'aaa',
579
+ }
580
+ )
581
+ } else {
582
+ computeResourceAlert.value = []
583
+ if (
584
+ wizard.hasMessage(dynamicSteps.selectComputeResource, 'computeResource')
585
+ ) {
586
+ value = wizard.removeValidation(
587
+ dynamicSteps.selectComputeResource,
588
+ 'computeResource',
589
+ value
590
+ )
591
+ }
592
+ }
593
+
594
+ return {
595
+ stepHasError,
596
+ newValue: value,
597
+ }
598
+ }
599
+ const checkStorage = async (
600
+ value: UI_I_WizardStep[]
601
+ ): Promise<UI_I_ValidationReturn> => {
602
+ let stepHasError = false
603
+
604
+ return new Promise((resolve) => {
605
+ storageSubmit.value = (isValid: boolean) => {
606
+ if (!isValid) {
607
+ stepHasError = wizard.setValidation(
608
+ dynamicSteps.selectStorage,
609
+ 'storage',
610
+ {
611
+ fieldMessage: 'aaa',
612
+ alertMessage: 'aaa',
613
+ }
614
+ )
615
+ } else if (wizard.hasMessage(dynamicSteps.selectStorage, 'storage')) {
616
+ value = wizard.removeValidation(
617
+ dynamicSteps.selectStorage,
618
+ 'storage',
619
+ value
620
+ )
621
+ }
622
+
623
+ resolve({
624
+ stepHasError,
625
+ newValue: value,
626
+ })
627
+ storageSubmit.value = null
628
+ }
629
+ })
630
+ }
631
+ const checkCustomizeHardware = async (
632
+ value: UI_I_WizardStep[]
633
+ ): Promise<UI_I_ValidationReturn> => {
634
+ let stepHasError = false
635
+ isLoading.value = true
636
+
637
+ return new Promise((resolve) => {
638
+ customizeHardwareSubmit.value = (isValid: boolean) => {
639
+ if (!isValid) {
640
+ stepHasError = wizard.setValidation(
641
+ dynamicSteps.customizeHardware,
642
+ 'customizeHardware',
643
+ {
644
+ fieldMessage: 'aaa',
645
+ alertMessage: 'aaa',
646
+ }
647
+ )
648
+ } else if (
649
+ wizard.hasMessage(dynamicSteps.customizeHardware, 'customizeHardware')
650
+ ) {
651
+ wizard.removeValidationLocal(
652
+ dynamicSteps.customizeHardware,
653
+ 'customizeHardware'
654
+ )
655
+ value = wizard.removeValidation(
656
+ dynamicSteps.customizeHardware,
657
+ 'customizeHardware',
658
+ value
659
+ )
660
+ }
661
+
662
+ resolve({
663
+ stepHasError,
664
+ newValue: value,
665
+ })
666
+ storageSubmit.value = null
667
+ isLoading.value = false
668
+ }
669
+ })
670
+ }
671
+ const checkCustomizeHardwareForTemplate = async (
672
+ value: UI_I_WizardStep[]
673
+ ): Promise<UI_I_ValidationReturn> => {
674
+ let stepHasError = false
675
+
676
+ return new Promise((resolve) => {
677
+ customizeHardwareForTemplateSubmit.value = (isValid: boolean) => {
678
+ if (!isValid) {
679
+ stepHasError = wizard.setValidation(
680
+ dynamicSteps.customizeHardwareTemplate,
681
+ 'customizeHardwareForTemplate',
682
+ {
683
+ fieldMessage: 'aaa',
684
+ alertMessage: 'aaa',
685
+ }
686
+ )
687
+ } else if (
688
+ wizard.hasMessage(
689
+ dynamicSteps.customizeHardwareTemplate,
690
+ 'customizeHardwareForTemplate'
691
+ )
692
+ ) {
693
+ value = wizard.removeValidation(
694
+ dynamicSteps.customizeHardwareTemplate,
695
+ 'customizeHardwareForTemplate',
696
+ value
697
+ )
698
+ }
699
+
700
+ resolve({
701
+ stepHasError,
702
+ newValue: value,
703
+ })
704
+ storageSubmit.value = null
705
+ }
706
+ })
707
+ }
708
+
709
+ const storageIdCash = ref<string | null>(null)
710
+ const vmForm = ref<UI_I_VmForm>({
711
+ name: '',
712
+ compatibility: '',
713
+ guestMachineType: null,
714
+ guestOsFamily: null,
715
+ guestOsVersion: null,
716
+ computeResource: props.computeResource,
717
+ storage: null,
718
+ locationPath: '',
719
+ dataCenter: null,
720
+ })
721
+
722
+ const isLoadingComputeTree = ref<boolean>(false)
723
+ const onChangeName = (name: string, node: UI_I_TreeNode | null): void => {
724
+ vmForm.value.name = name // TODO уже нету смысла
725
+ if (isSphere.value) {
726
+ vmForm.value.locationPath = node.id
727
+ vmForm.value.dataCenter = $recursion.findParentByValue(
728
+ node,
729
+ 'datacenter',
730
+ 'type',
731
+ 'parent'
732
+ )
733
+ isLoadingComputeTree.value = true
734
+ emits('get-compute-resource-tree', {
735
+ id: node.id,
736
+ cb: () => {
737
+ isLoadingComputeTree.value = false
738
+ },
739
+ })
740
+ }
741
+ }
742
+ // Для сферы
743
+ const computeResourcePath = ref<string>('')
744
+ const onSelectComputeResourceTree = (node: UI_I_TreeNode): void => {
745
+ emits('select-compute-resource-tree', node)
746
+ computeResourcePath.value = node.id
747
+ }
748
+ watch(
749
+ () => vmForm.value.computeResource,
750
+ (newValue, oldValue) => {
751
+ if (newValue && newValue.id !== oldValue?.id) {
752
+ onSelectComputeResourceTree(newValue)
753
+ }
754
+ },
755
+ { deep: true, immediate: true }
756
+ )
757
+
758
+ const onChangeStorage = (storage: UI_I_DatastoreTableItem | null): void => {
759
+ if (!storage) return
760
+
761
+ vmForm.value.storage = storage
762
+ storageIdCash.value = storage.id
763
+ }
764
+ const compatibilityInfo = ref<string>('')
765
+ const onChangeCompatibility = (compatibility: UI_I_OptionItem): void => {
766
+ vmForm.value.compatibility = compatibility.value
767
+
768
+ const version = compatibility.value.split('-')[1]
769
+ compatibilityInfo.value = `${localization.value.common.compatibility}: ${compatibility.text} (${localization.value.common.vmVersion} ${version})`
770
+ }
771
+ const customizeHardware = ref<UI_I_SendDataCustomizeHardware | null>(null)
772
+ const onChangeCustomizeHardware = (
773
+ data: UI_I_SendDataCustomizeHardware
774
+ ): void => {
775
+ customizeHardware.value = data
776
+ }
777
+
778
+ const virtualHardwareHardDisksLocal = computed<
779
+ UI_I_SendDataNewHardDisk[] | null
780
+ >(() => customizeHardware.value?.virtualHardware?.hardDisks || null)
781
+ const virtualHardwareNetworksLocal = computed<UI_I_SendDataNewNetwork[] | null>(
782
+ () => customizeHardware.value?.virtualHardware?.networks || null
783
+ )
784
+ const virtualHardwareCdDvdDrivesLocal = computed<
785
+ UI_I_SendDataNewCdDvdDrive[] | null
786
+ >(() => customizeHardware.value?.virtualHardware?.cdDvdDrives || null)
787
+
788
+ const virtualHardwareCpu = computed<UI_I_SendDataCpu | null>(
789
+ () => customizeHardware.value?.virtualHardware?.cpu || null
790
+ )
791
+ const virtualHardwareMemory = computed<UI_I_SendDataMemory | null>(
792
+ () => customizeHardware.value?.virtualHardware?.memory || null
793
+ )
794
+ const virtualHardwareHardDisks = ref<UI_I_SendDataNewHardDisk[] | null>(null)
795
+ const virtualHardwareCdDvdDrives = ref<UI_I_SendDataNewCdDvdDrive[] | null>(
796
+ null
797
+ )
798
+ const virtualHardwareNetworks = ref<UI_I_SendDataNewNetwork[] | null>(null)
799
+ const onChangeBootOrder = (data: UI_T_ChangeBootOrder): void => {
800
+ virtualHardwareHardDisks.value = data[0]
801
+ virtualHardwareCdDvdDrives.value = data[1]
802
+ virtualHardwareNetworks.value = data[2]
803
+ }
804
+
805
+ const isPowerOnByDefault = ref<boolean>(true)
806
+ const isCreateLinkedClone = ref<boolean>(false)
807
+
808
+ watch(
809
+ () => props.vmNameInWizard,
810
+ (newValue) => {
811
+ vmForm.value.name = newValue
812
+ }
813
+ )
814
+
815
+ const validateSendData = async (
816
+ value: UI_I_WizardStep[]
817
+ ): Promise<UI_I_ValidationReturn> => {
818
+ wizard.setLoader(true)
819
+ let stepHasError = false
820
+ isLoading.value = true
821
+
822
+ const data = await props.validateSendDataFunc(
823
+ vmForm.value,
824
+ virtualHardwareCpu.value,
825
+ virtualHardwareMemory.value,
826
+ customizeHardware.value,
827
+ virtualHardwareNetworks.value,
828
+ virtualHardwareHardDisks.value,
829
+ virtualHardwareCdDvdDrives.value,
830
+ isPowerOnByDefault.value,
831
+ localization.value,
832
+ vmForm.value.locationPath, // для сферы
833
+ computeResourcePath.value, // для сферы
834
+ selectedCreateType.value
835
+ )
836
+
837
+ isLoading.value = false
838
+ wizard.setLoader(false)
839
+ if (data) {
840
+ stepHasError = true
841
+ selectedNavItem.value = data[0]
842
+ data[1] !== null && wizard.selectStepHard(data[1])
843
+ }
844
+
845
+ return {
846
+ stepHasError,
847
+ newValue: value,
848
+ }
849
+ }
850
+
851
+ const isLoading = ref<boolean>(false)
852
+ const onFinish = (): void => {
853
+ isLoading.value = true
854
+ wizard.setLoader(false)
855
+ props
856
+ .finishFunc(
857
+ vmForm.value,
858
+ virtualHardwareCpu.value,
859
+ virtualHardwareMemory.value,
860
+ customizeHardware.value,
861
+ virtualHardwareNetworks.value,
862
+ virtualHardwareHardDisks.value,
863
+ virtualHardwareCdDvdDrives.value,
864
+ isPowerOnByDefault.value,
865
+ localization.value,
866
+ vmForm.value.locationPath, // для сферы
867
+ computeResourcePath.value, // для сферы
868
+ false,
869
+ selectedTemplate.value,
870
+ selectedCreateType.value,
871
+ isCreateLinkedClone.value, // для шаблонов
872
+ cloneCount.value // для шаблонов
873
+ )
874
+ .then(() => {
875
+ onHideModal()
876
+ wizard.setLoader(false)
877
+ isLoading.value = false
878
+ })
879
+ }
880
+
881
+ const selectedNavItem = ref<UI_T_SelectedNavItem>(0)
882
+
883
+ const nameFormSubmit = ref<null | Function>(null)
884
+ const templateSubmit = ref<null | Function>(null)
885
+ const storageSubmit = ref<null | Function>(null)
886
+ const customizeHardwareSubmit = ref<null | Function>(null)
887
+ const customizeHardwareForTemplateSubmit = ref<null | Function>(null)
888
+ const compatibility = ref<UI_I_OptionItem[]>(capabilities.value.compatibility)
889
+ const guestOsFamilies = ref<UI_I_OptionItem[]>(
890
+ capabilities.value.guestOsFamilies
891
+ )
892
+ const guestOsVersions = ref<UI_I_ArbitraryObject<UI_I_OptionItem[]>>(
893
+ capabilities.value.guestOsVersions
894
+ )
895
+ const machineTypes = ref<UI_I_OptionItem[]>(capabilities.value.machineTypes)
896
+ const cpuModels = ref<UI_I_OptionItem[]>(capabilities.value.cpuModels)
897
+ const maxCpus = ref<number>(capabilities.value.maxCpus)
898
+ const maxMemory = ref<number>(capabilities.value.maxMemory)
899
+
900
+ const selectedTemplate = ref<string>('')
901
+ const onChangeTemplate = (node: UI_I_TreeNode): void => {
902
+ selectedTemplate.value = node.id.toString()
903
+ emits('select-template', node.id.toString())
904
+ }
905
+ const selectedOptions = ref<string[]>([])
906
+ const onChangeSelectOptions = (options: string[]) => {
907
+ selectedOptions.value = options
908
+ if (
909
+ options.includes('customize-os') &&
910
+ options.includes('customize-hardware')
911
+ ) {
912
+ wizard.changeScheme(isSphere.value ? 9 : 5)
913
+ } else if (options.includes('customize-os')) {
914
+ wizard.changeScheme(isSphere.value ? 7 : 3)
915
+ } else if (options.includes('customize-hardware')) {
916
+ wizard.changeScheme(isSphere.value ? 8 : 4)
917
+ } else {
918
+ wizard.changeScheme(isSphere.value ? 6 : 2)
919
+ }
920
+
921
+ isPowerOnByDefault.value = options.includes('power-on')
922
+ isCreateLinkedClone.value = options.includes('create-inked-clone')
923
+ }
924
+ const cloneCount = ref<number>(1)
925
+
926
+ const onHideModal = (): void => {
927
+ emits('hide')
928
+ }
929
+
930
+ watch(
931
+ () => props.vmtSettings,
932
+ (newValue) => {
933
+ if (newValue) {
934
+ vmForm.value.name = newValue.name
935
+ vmForm.value.compatibility =
936
+ newValue.compatibility || vmForm.value.compatibility
937
+ vmForm.value.storage = newValue.storage
938
+ if (customizeHardware.value?.virtualHardware) {
939
+ customizeHardware.value.virtualHardware.cdDvdDrives =
940
+ newValue.cdDvdDrives
941
+ customizeHardware.value.virtualHardware.hardDisks = newValue.hardDisks
942
+ customizeHardware.value.virtualHardware.networks = newValue.networks
943
+ customizeHardware.value.virtualHardware.cpu = newValue.cpu
944
+ customizeHardware.value.virtualHardware.memory = newValue.memory
945
+ customizeHardware.value.virtualHardware.videoCard = newValue.videoCard
946
+ customizeHardware.value.virtualHardware.usbController =
947
+ newValue.usbController
948
+ customizeHardware.value.virtualHardware.pciDevices = newValue.pciDevices
949
+ customizeHardware.value.vmOptions = newValue.options
950
+ }
951
+ maxCpus.value = newValue.cpu.max_vcpus
952
+ // cpuModels.value = newValue.cpu.model
953
+ isPowerOnByDefault.value = false
954
+ isCreateLinkedClone.value = false
955
+ }
956
+ }
957
+ )
958
+ </script>
959
+
960
+ <style scoped lang="scss"></style>