bfg-common 1.4.785 → 1.4.787
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.
- package/assets/localization/local_ru.json +1 -1
- package/components/atoms/autocomplete/Autocomplete.vue +66 -11
- package/components/common/pages/tasks/Tasks.vue +8 -0
- package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDiskNew.vue +1 -1
- package/components/common/vm/actions/common/customizeHardware/virtualHardware/newHardDisk/NewHardDiskOld.vue +1 -1
- package/components/common/wizards/vm/migrate/Migrate.vue +288 -288
- package/components/common/wizards/vm/migrate/select/computeResource/ComputeResource.vue +1 -1
- package/package.json +1 -1
|
@@ -1202,7 +1202,7 @@
|
|
|
1202
1202
|
"relatedObjects": "Связанные Объекты",
|
|
1203
1203
|
"releaseDate": "Дата выпуска",
|
|
1204
1204
|
"remoteConsole": "Удаленная консоль {0}",
|
|
1205
|
-
"remoteConsoleDescription": "Используйте {trademark} Remote Console (VMRC) для подключения к клиентским устройствам и доступа к расширенным функциям клавиатуры.\nЕсли у
|
|
1205
|
+
"remoteConsoleDescription": "Используйте {trademark} Remote Console (VMRC) для подключения к клиентским устройствам и доступа к расширенным функциям клавиатуры.\nЕсли у Вас уже установлена {trademark} Remote Console, она запустится автоматически, когда Вы нажмете кнопку Launch Remote Console. Если нет, Вы можете использовать ссылку ниже, чтобы загрузить его.",
|
|
1206
1206
|
"remoteConsoleOptions": "Параметры удаленной консоли",
|
|
1207
1207
|
"remoteConsoleType": "Тип удаленной консоли",
|
|
1208
1208
|
"remoteConsoleVmrc": "Удаленная консоль {trademark} (VMRC)",
|
|
@@ -17,16 +17,32 @@
|
|
|
17
17
|
name="search"
|
|
18
18
|
/>
|
|
19
19
|
</div>
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
|
|
21
|
+
<div class="clr-error">
|
|
22
|
+
<div class="form-group__input">
|
|
23
|
+
<input
|
|
24
|
+
:id="`${props.testId}-search-input`"
|
|
25
|
+
v-model.trim="search"
|
|
26
|
+
:data-id="`${props.testId}-search-input`"
|
|
27
|
+
type="text"
|
|
28
|
+
class="search-input"
|
|
29
|
+
:class="fieldErrorText && 'clr-input'"
|
|
30
|
+
autocomplete="off"
|
|
31
|
+
:placeholder="props.placeholder"
|
|
32
|
+
@blur="onInitValidation"
|
|
33
|
+
@input="onSearch"
|
|
34
|
+
/>
|
|
35
|
+
<div v-show="fieldErrorText" class="form-validate">
|
|
36
|
+
<atoms-the-icon class="is-error tooltip-trigger" name="info" />
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
<div
|
|
40
|
+
v-show="fieldErrorText"
|
|
41
|
+
class="form-group__input-error clr-subtext"
|
|
42
|
+
>
|
|
43
|
+
{{ fieldErrorText }}
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
30
46
|
</div>
|
|
31
47
|
<div
|
|
32
48
|
v-show="isShow"
|
|
@@ -50,6 +66,8 @@
|
|
|
50
66
|
</template>
|
|
51
67
|
|
|
52
68
|
<script setup lang="ts">
|
|
69
|
+
import type { UI_I_Localization } from '~/lib/models/interfaces'
|
|
70
|
+
|
|
53
71
|
const props = withDefaults(
|
|
54
72
|
defineProps<{
|
|
55
73
|
placeholder: string
|
|
@@ -57,23 +75,27 @@ const props = withDefaults(
|
|
|
57
75
|
loading?: boolean
|
|
58
76
|
testId?: string
|
|
59
77
|
ms?: number
|
|
78
|
+
showValidation?: boolean
|
|
60
79
|
}>(),
|
|
61
80
|
{
|
|
62
81
|
testId: 'ui-autocomplete',
|
|
63
82
|
ms: 500,
|
|
64
83
|
loading: false,
|
|
84
|
+
showValidation: false,
|
|
65
85
|
}
|
|
66
86
|
)
|
|
67
|
-
|
|
68
87
|
const emits = defineEmits<{
|
|
69
88
|
(event: 'search', value: string): void
|
|
70
89
|
(event: 'select', value: string): void
|
|
71
90
|
}>()
|
|
72
91
|
|
|
92
|
+
const localization = computed<UI_I_Localization>(() => useLocal())
|
|
93
|
+
|
|
73
94
|
const search = ref<string>('')
|
|
74
95
|
|
|
75
96
|
let timer: NodeJS.Timeout
|
|
76
97
|
const onSearch = (): void => {
|
|
98
|
+
onInitValidation()
|
|
77
99
|
clearTimeout(timer)
|
|
78
100
|
timer = setTimeout(
|
|
79
101
|
(value) => {
|
|
@@ -83,7 +105,16 @@ const onSearch = (): void => {
|
|
|
83
105
|
search.value
|
|
84
106
|
)
|
|
85
107
|
}
|
|
108
|
+
const isInitFieldValidation = ref<boolean>(false)
|
|
109
|
+
const onInitValidation = (): void => {
|
|
110
|
+
isInitFieldValidation.value = true
|
|
111
|
+
}
|
|
112
|
+
const fieldErrorText = computed<string>(() => {
|
|
113
|
+
if (!isInitFieldValidation.value) return ''
|
|
86
114
|
|
|
115
|
+
if (!search.value && props.showValidation)
|
|
116
|
+
return localization.value.common.fieldRequired
|
|
117
|
+
})
|
|
87
118
|
const items = computed<any[]>(() => {
|
|
88
119
|
return [...props.items].map((text) => {
|
|
89
120
|
const term = search.value.toLowerCase()
|
|
@@ -155,6 +186,13 @@ watch(isHide, (newValue) => {
|
|
|
155
186
|
window.removeEventListener('keydown', onKeyDown, true)
|
|
156
187
|
}
|
|
157
188
|
})
|
|
189
|
+
watch(
|
|
190
|
+
() => props.showValidation,
|
|
191
|
+
(newValue: boolean) => {
|
|
192
|
+
isInitFieldValidation.value = newValue
|
|
193
|
+
},
|
|
194
|
+
{ immediate: true }
|
|
195
|
+
)
|
|
158
196
|
</script>
|
|
159
197
|
|
|
160
198
|
<style scoped lang="scss">
|
|
@@ -239,5 +277,22 @@ watch(isHide, (newValue) => {
|
|
|
239
277
|
}
|
|
240
278
|
}
|
|
241
279
|
}
|
|
280
|
+
.form-group {
|
|
281
|
+
&__input {
|
|
282
|
+
display: flex;
|
|
283
|
+
.form-validate {
|
|
284
|
+
svg {
|
|
285
|
+
width: 24px;
|
|
286
|
+
height: 24px;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
input {
|
|
290
|
+
width: 100%;
|
|
291
|
+
}
|
|
292
|
+
&-error {
|
|
293
|
+
margin-top: 0;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
242
297
|
}
|
|
243
298
|
</style>
|
|
@@ -25,6 +25,7 @@ import type {
|
|
|
25
25
|
} from '~/lib/models/table/interfaces'
|
|
26
26
|
import type { UI_I_Task } from '~/lib/models/store/tasks/interfaces'
|
|
27
27
|
import type { UI_T_Project } from '~/lib/models/types'
|
|
28
|
+
import { useOnline } from '@vueuse/core'
|
|
28
29
|
|
|
29
30
|
const localization = computed<UI_I_Localization>(() => useLocal())
|
|
30
31
|
const { $store }: any = useNuxtApp()
|
|
@@ -74,6 +75,13 @@ const isLoading = computed<boolean>(() =>
|
|
|
74
75
|
$store.getters['tasks/getLoading']('tasks')
|
|
75
76
|
)
|
|
76
77
|
|
|
78
|
+
const isOnline = useOnline()
|
|
79
|
+
watch(isOnline, (newValue: boolean) => {
|
|
80
|
+
if (newValue) {
|
|
81
|
+
getTasks()
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
|
|
77
85
|
onUnmounted(() => {
|
|
78
86
|
pauseGlobalRefresh()
|
|
79
87
|
})
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
v-model:limit-iops-type="limitIopsType"
|
|
106
106
|
:index="props.index"
|
|
107
107
|
:error-validation-fields="props.errorValidationFields"
|
|
108
|
-
:disabled="props.isRunning"
|
|
108
|
+
:disabled="props.isRunning && props.type !== 'new'"
|
|
109
109
|
@valid="limitIopsInvalid = $event"
|
|
110
110
|
@remove-error-by-title="emits('remove-error-by-title', $event)"
|
|
111
111
|
/>
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
v-model:limit-iops-type="limitIopsType"
|
|
138
138
|
:index="props.index"
|
|
139
139
|
:error-validation-fields="props.errorValidationFields"
|
|
140
|
-
:disabled="props.isRunning"
|
|
140
|
+
:disabled="props.isRunning && props.type !== 'new'"
|
|
141
141
|
@valid="limitIopsInvalid = $event"
|
|
142
142
|
@remove-error-by-title="emits('remove-error-by-title', $event)"
|
|
143
143
|
/>
|
|
@@ -1,288 +1,288 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="migrate-vm">
|
|
3
|
-
<atoms-wizard
|
|
4
|
-
show
|
|
5
|
-
:wizard="wizard"
|
|
6
|
-
:selected-scheme="selectedScheme"
|
|
7
|
-
:title="title"
|
|
8
|
-
:localization="localization"
|
|
9
|
-
class="migrate-vm-wizard"
|
|
10
|
-
test-id="migrate-vm-wizard"
|
|
11
|
-
@change-steps="onChangeSteps"
|
|
12
|
-
@hide="onHideModal"
|
|
13
|
-
@submit="onFinish"
|
|
14
|
-
>
|
|
15
|
-
<template #modalBody="{ selectedStep }">
|
|
16
|
-
<common-pages-scheduled-tasks-modals-common-new-task-form
|
|
17
|
-
v-if="selectedStep.id === 0"
|
|
18
|
-
v-model="modelSchedulerTask"
|
|
19
|
-
:target="selectedVirtualMachine"
|
|
20
|
-
/>
|
|
21
|
-
|
|
22
|
-
<common-wizards-vm-migrate-select-type
|
|
23
|
-
v-if="selectedStep.id === 1"
|
|
24
|
-
v-model="form.migrate_type"
|
|
25
|
-
:project="props.project"
|
|
26
|
-
/>
|
|
27
|
-
|
|
28
|
-
<common-wizards-vm-migrate-select-target-server
|
|
29
|
-
v-if="selectedStep.id === 2"
|
|
30
|
-
v-model="form.target_server"
|
|
31
|
-
v-model:connect-server="isConnectSourceServer"
|
|
32
|
-
:wizard="wizard"
|
|
33
|
-
/>
|
|
34
|
-
|
|
35
|
-
<common-wizards-vm-migrate-select-compute-resource
|
|
36
|
-
v-show="selectedStep.id === 3"
|
|
37
|
-
v-model="form"
|
|
38
|
-
:alert-messages="alertMessages[3]"
|
|
39
|
-
:get-compute-resource-data="props.getComputeResourceData"
|
|
40
|
-
:compute-resource-data="props.computeResourceTableData"
|
|
41
|
-
:compute-resource-tree="props.computeResourceTree"
|
|
42
|
-
@hide-alert="onHideAlert"
|
|
43
|
-
/>
|
|
44
|
-
|
|
45
|
-
<common-wizards-vm-migrate-select-storage
|
|
46
|
-
v-show="selectedStep.id === 4"
|
|
47
|
-
v-model="form"
|
|
48
|
-
:alert-messages="alertMessages[4]"
|
|
49
|
-
:get-datastore-table-func="props.getDatastoreTableFunc"
|
|
50
|
-
:datastore="props.datastore"
|
|
51
|
-
:connected-storage-id-default="connectedStorageIdOnVm"
|
|
52
|
-
:configure-per-disks="props.configurePerDisks"
|
|
53
|
-
@hide-alert="onHideAlert"
|
|
54
|
-
/>
|
|
55
|
-
|
|
56
|
-
<common-wizards-vm-migrate-select-network
|
|
57
|
-
v-show="selectedStep.id === 5"
|
|
58
|
-
v-model="form.network"
|
|
59
|
-
/>
|
|
60
|
-
|
|
61
|
-
<common-wizards-vm-migrate-select-priority
|
|
62
|
-
v-if="selectedStep.id === 6"
|
|
63
|
-
v-model="form.vMotion_priority"
|
|
64
|
-
/>
|
|
65
|
-
|
|
66
|
-
<common-ready-to-complete
|
|
67
|
-
v-if="selectedStep.id === 7"
|
|
68
|
-
:data="dataReadyView"
|
|
69
|
-
/>
|
|
70
|
-
</template>
|
|
71
|
-
</atoms-wizard>
|
|
72
|
-
</div>
|
|
73
|
-
</template>
|
|
74
|
-
|
|
75
|
-
<script setup lang="ts">
|
|
76
|
-
import type {
|
|
77
|
-
UI_I_WizardStep,
|
|
78
|
-
UI_I_ValidationReturn,
|
|
79
|
-
} from '~/components/atoms/wizard/lib/models/interfaces'
|
|
80
|
-
import Wizard from '~/components/atoms/wizard/lib/utils/utils'
|
|
81
|
-
import {
|
|
82
|
-
stepsFunc,
|
|
83
|
-
stepsSchemeInitial,
|
|
84
|
-
} from '~/components/common/wizards/vm/migrate/lib/config/steps'
|
|
85
|
-
import type { UI_I_Localization } from '~/lib/models/interfaces'
|
|
86
|
-
import type { UI_T_Project } from '~/lib/models/types'
|
|
87
|
-
import type {
|
|
88
|
-
UI_I_MigrateFormLocal,
|
|
89
|
-
UI_I_ChangeStepsSchemes,
|
|
90
|
-
} from '~/components/common/wizards/vm/migrate/lib/models/interfaces'
|
|
91
|
-
import type { UI_T_VmMigrateType } from '~/components/common/wizards/vm/migrate/select/type/lib/models/types'
|
|
92
|
-
import type { UI_I_TablePayload } from '~/lib/models/table/interfaces'
|
|
93
|
-
import type { UI_I_DatastoreTableItem } from '~/lib/models/store/storage/interfaces'
|
|
94
|
-
import type { UI_I_VmSettings } from '~/lib/models/store/vm/interfaces'
|
|
95
|
-
import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
|
|
96
|
-
import type { UI_I_StorageConfigurePerDiskItem } from '~/components/common/wizards/vm/migrate/select/storage/configure/disk/table/lib/models/interfaces'
|
|
97
|
-
import type { UI_I_TableInfoItem } from '~/components/atoms/table/info/lib/models/interfaces'
|
|
98
|
-
import type { UI_I_ScheduleNewTasksForm } from '~/components/common/pages/scheduledTasks/modals/lib/models/interfaces'
|
|
99
|
-
import { constructDataReadyViewFunc } from '~/components/common/wizards/vm/migrate/lib/config/constructDataReady'
|
|
100
|
-
import * as validation from '~/components/common/wizards/vm/migrate/lib/validations'
|
|
101
|
-
|
|
102
|
-
const props = withDefaults(
|
|
103
|
-
defineProps<{
|
|
104
|
-
project: UI_T_Project
|
|
105
|
-
isScheduledTasks: boolean
|
|
106
|
-
isEditScheduledTasks: boolean
|
|
107
|
-
vmSettings: UI_I_VmSettings | null
|
|
108
|
-
vmName: string
|
|
109
|
-
getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
|
|
110
|
-
getComputeResourceData: (payload: UI_I_TablePayload) => Promise<void>
|
|
111
|
-
datastore: UI_I_DatastoreTableItem[]
|
|
112
|
-
configurePerDisks: UI_I_StorageConfigurePerDiskItem[]
|
|
113
|
-
computeResourceTableData?: any
|
|
114
|
-
computeResourceTree?: UI_I_TreeNode | null
|
|
115
|
-
selectedVirtualMachine?: string
|
|
116
|
-
}>(),
|
|
117
|
-
{
|
|
118
|
-
computeResourceTree: null,
|
|
119
|
-
}
|
|
120
|
-
)
|
|
121
|
-
const emits = defineEmits<{
|
|
122
|
-
(event: 'hide'): void
|
|
123
|
-
(event: 'finish', value: UI_I_MigrateFormLocal): void
|
|
124
|
-
}>()
|
|
125
|
-
const modelSchedulerTask = defineModel<UI_I_ScheduleNewTasksForm>(
|
|
126
|
-
'schedulerForm',
|
|
127
|
-
{ required: true }
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
const localization = computed<UI_I_Localization>(() => useLocal())
|
|
131
|
-
|
|
132
|
-
const wizard: Wizard = new Wizard(
|
|
133
|
-
stepsFunc(localization.value, props.isScheduledTasks),
|
|
134
|
-
stepsSchemeInitial
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
const selectedScheme = computed<number[]>(() => wizard.selectedScheme.value)
|
|
138
|
-
const alertMessages = computed<string[][]>(() => wizard.alertMessages.value)
|
|
139
|
-
|
|
140
|
-
const title = computed<string>(() => {
|
|
141
|
-
const { scheduleNewTasks, scheduleTaskEdit, migrate } =
|
|
142
|
-
localization.value.common
|
|
143
|
-
let result = migrate
|
|
144
|
-
if (props.isScheduledTasks) {
|
|
145
|
-
const schedulerMode = props.isEditScheduledTasks
|
|
146
|
-
? scheduleTaskEdit
|
|
147
|
-
: scheduleNewTasks
|
|
148
|
-
|
|
149
|
-
result = `${schedulerMode} (${migrate})`
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return result
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
const isConnectSourceServer = ref<boolean>(false)
|
|
156
|
-
const form = ref<UI_I_MigrateFormLocal>({
|
|
157
|
-
migrate_type: props.project === 'procurator' ? 'storage' : 'resource',
|
|
158
|
-
disk_format: 0,
|
|
159
|
-
storage: null,
|
|
160
|
-
configure: {
|
|
161
|
-
type: 'batch-configure',
|
|
162
|
-
disks: [],
|
|
163
|
-
},
|
|
164
|
-
target_server: {
|
|
165
|
-
fqdn: '',
|
|
166
|
-
user: '',
|
|
167
|
-
password: '',
|
|
168
|
-
},
|
|
169
|
-
network: {
|
|
170
|
-
data: null,
|
|
171
|
-
},
|
|
172
|
-
resource: {
|
|
173
|
-
selectedNode: null,
|
|
174
|
-
host: null,
|
|
175
|
-
cluster: null,
|
|
176
|
-
resourcePool: null,
|
|
177
|
-
vApps: null,
|
|
178
|
-
},
|
|
179
|
-
vMotion_priority: 'high',
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
const validationFunc = async (
|
|
183
|
-
value: UI_I_WizardStep[],
|
|
184
|
-
currentStep: UI_I_WizardStep,
|
|
185
|
-
nextStep: UI_I_WizardStep
|
|
186
|
-
): Promise<UI_I_ValidationReturn> => {
|
|
187
|
-
let stepHasError = false
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (wizard.isValidateForStep(4, currentStep.id, nextStep.id)) {
|
|
203
|
-
const nameValidation = await validation.checkSelectedDatastoreSync(
|
|
204
|
-
localization.value,
|
|
205
|
-
form.value.storage,
|
|
206
|
-
wizard,
|
|
207
|
-
value
|
|
208
|
-
)
|
|
209
|
-
|
|
210
|
-
value = nameValidation.newValue
|
|
211
|
-
|
|
212
|
-
stepHasError = nameValidation.stepHasError
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return {
|
|
216
|
-
newValue: value,
|
|
217
|
-
stepHasError,
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
const onChangeSteps = async (value: UI_I_WizardStep[]): Promise<void> =>
|
|
221
|
-
wizard.changeSteps(value, validationFunc)
|
|
222
|
-
|
|
223
|
-
// Choosing Scheme
|
|
224
|
-
watch(
|
|
225
|
-
() => form.value.migrate_type,
|
|
226
|
-
(newValue: UI_T_VmMigrateType) => {
|
|
227
|
-
const schemes: UI_I_ChangeStepsSchemes = {
|
|
228
|
-
procurator: {
|
|
229
|
-
storage: props.isScheduledTasks ? 1 : 0,
|
|
230
|
-
},
|
|
231
|
-
sphere: {
|
|
232
|
-
storage: props.isScheduledTasks ? 1 : 0,
|
|
233
|
-
resource: props.isScheduledTasks ? 3 : 2,
|
|
234
|
-
'resource-storage': 2,
|
|
235
|
-
server: 3,
|
|
236
|
-
},
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const projectSchemes = schemes[props.project]
|
|
240
|
-
|
|
241
|
-
if (projectSchemes && projectSchemes[newValue] !== undefined) {
|
|
242
|
-
wizard.changeScheme(projectSchemes[newValue] as number)
|
|
243
|
-
}
|
|
244
|
-
},
|
|
245
|
-
{ deep: true, immediate: true }
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
watch(
|
|
249
|
-
modelSchedulerTask,
|
|
250
|
-
(newValue: UI_I_ScheduleNewTasksForm) => {
|
|
251
|
-
if (props.isScheduledTasks) wizard.setDisabledNextButton(newValue.isValid)
|
|
252
|
-
},
|
|
253
|
-
{ immediate: true, deep: true }
|
|
254
|
-
)
|
|
255
|
-
|
|
256
|
-
const loading = ref<boolean>(false)
|
|
257
|
-
|
|
258
|
-
const connectedStorageIdOnVm = computed<string>(
|
|
259
|
-
() => props.vmSettings?.storage.id || ''
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
const dataReadyView = computed<UI_I_TableInfoItem>(() =>
|
|
263
|
-
constructDataReadyViewFunc(props.vmName, form.value)
|
|
264
|
-
)
|
|
265
|
-
const onFinish = (): void => {
|
|
266
|
-
loading.value = true
|
|
267
|
-
emits('finish', form.value)
|
|
268
|
-
loading.value = false
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const onHideModal = (): void => {
|
|
272
|
-
emits('hide')
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
const onHideAlert = (stepId: number): void => {
|
|
276
|
-
wizard.hideAlertMessagesByStepId(stepId)
|
|
277
|
-
}
|
|
278
|
-
</script>
|
|
279
|
-
|
|
280
|
-
<style scoped lang="scss">
|
|
281
|
-
@import 'assets/scss/common/mixins.scss';
|
|
282
|
-
.migrate-vm {
|
|
283
|
-
:deep(.modal-body) {
|
|
284
|
-
height: inherit;
|
|
285
|
-
@include flex($dir: column);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<div class="migrate-vm">
|
|
3
|
+
<atoms-wizard
|
|
4
|
+
show
|
|
5
|
+
:wizard="wizard"
|
|
6
|
+
:selected-scheme="selectedScheme"
|
|
7
|
+
:title="title"
|
|
8
|
+
:localization="localization"
|
|
9
|
+
class="migrate-vm-wizard"
|
|
10
|
+
test-id="migrate-vm-wizard"
|
|
11
|
+
@change-steps="onChangeSteps"
|
|
12
|
+
@hide="onHideModal"
|
|
13
|
+
@submit="onFinish"
|
|
14
|
+
>
|
|
15
|
+
<template #modalBody="{ selectedStep }">
|
|
16
|
+
<common-pages-scheduled-tasks-modals-common-new-task-form
|
|
17
|
+
v-if="selectedStep.id === 0"
|
|
18
|
+
v-model="modelSchedulerTask"
|
|
19
|
+
:target="selectedVirtualMachine"
|
|
20
|
+
/>
|
|
21
|
+
|
|
22
|
+
<common-wizards-vm-migrate-select-type
|
|
23
|
+
v-if="selectedStep.id === 1"
|
|
24
|
+
v-model="form.migrate_type"
|
|
25
|
+
:project="props.project"
|
|
26
|
+
/>
|
|
27
|
+
|
|
28
|
+
<common-wizards-vm-migrate-select-target-server
|
|
29
|
+
v-if="selectedStep.id === 2"
|
|
30
|
+
v-model="form.target_server"
|
|
31
|
+
v-model:connect-server="isConnectSourceServer"
|
|
32
|
+
:wizard="wizard"
|
|
33
|
+
/>
|
|
34
|
+
|
|
35
|
+
<common-wizards-vm-migrate-select-compute-resource
|
|
36
|
+
v-show="selectedStep.id === 3"
|
|
37
|
+
v-model="form"
|
|
38
|
+
:alert-messages="alertMessages[3]"
|
|
39
|
+
:get-compute-resource-data="props.getComputeResourceData"
|
|
40
|
+
:compute-resource-data="props.computeResourceTableData"
|
|
41
|
+
:compute-resource-tree="props.computeResourceTree"
|
|
42
|
+
@hide-alert="onHideAlert"
|
|
43
|
+
/>
|
|
44
|
+
|
|
45
|
+
<common-wizards-vm-migrate-select-storage
|
|
46
|
+
v-show="selectedStep.id === 4"
|
|
47
|
+
v-model="form"
|
|
48
|
+
:alert-messages="alertMessages[4]"
|
|
49
|
+
:get-datastore-table-func="props.getDatastoreTableFunc"
|
|
50
|
+
:datastore="props.datastore"
|
|
51
|
+
:connected-storage-id-default="connectedStorageIdOnVm"
|
|
52
|
+
:configure-per-disks="props.configurePerDisks"
|
|
53
|
+
@hide-alert="onHideAlert"
|
|
54
|
+
/>
|
|
55
|
+
|
|
56
|
+
<common-wizards-vm-migrate-select-network
|
|
57
|
+
v-show="selectedStep.id === 5"
|
|
58
|
+
v-model="form.network"
|
|
59
|
+
/>
|
|
60
|
+
|
|
61
|
+
<common-wizards-vm-migrate-select-priority
|
|
62
|
+
v-if="selectedStep.id === 6"
|
|
63
|
+
v-model="form.vMotion_priority"
|
|
64
|
+
/>
|
|
65
|
+
|
|
66
|
+
<common-ready-to-complete
|
|
67
|
+
v-if="selectedStep.id === 7"
|
|
68
|
+
:data="dataReadyView"
|
|
69
|
+
/>
|
|
70
|
+
</template>
|
|
71
|
+
</atoms-wizard>
|
|
72
|
+
</div>
|
|
73
|
+
</template>
|
|
74
|
+
|
|
75
|
+
<script setup lang="ts">
|
|
76
|
+
import type {
|
|
77
|
+
UI_I_WizardStep,
|
|
78
|
+
UI_I_ValidationReturn,
|
|
79
|
+
} from '~/components/atoms/wizard/lib/models/interfaces'
|
|
80
|
+
import Wizard from '~/components/atoms/wizard/lib/utils/utils'
|
|
81
|
+
import {
|
|
82
|
+
stepsFunc,
|
|
83
|
+
stepsSchemeInitial,
|
|
84
|
+
} from '~/components/common/wizards/vm/migrate/lib/config/steps'
|
|
85
|
+
import type { UI_I_Localization } from '~/lib/models/interfaces'
|
|
86
|
+
import type { UI_T_Project } from '~/lib/models/types'
|
|
87
|
+
import type {
|
|
88
|
+
UI_I_MigrateFormLocal,
|
|
89
|
+
UI_I_ChangeStepsSchemes,
|
|
90
|
+
} from '~/components/common/wizards/vm/migrate/lib/models/interfaces'
|
|
91
|
+
import type { UI_T_VmMigrateType } from '~/components/common/wizards/vm/migrate/select/type/lib/models/types'
|
|
92
|
+
import type { UI_I_TablePayload } from '~/lib/models/table/interfaces'
|
|
93
|
+
import type { UI_I_DatastoreTableItem } from '~/lib/models/store/storage/interfaces'
|
|
94
|
+
import type { UI_I_VmSettings } from '~/lib/models/store/vm/interfaces'
|
|
95
|
+
import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
|
|
96
|
+
import type { UI_I_StorageConfigurePerDiskItem } from '~/components/common/wizards/vm/migrate/select/storage/configure/disk/table/lib/models/interfaces'
|
|
97
|
+
import type { UI_I_TableInfoItem } from '~/components/atoms/table/info/lib/models/interfaces'
|
|
98
|
+
import type { UI_I_ScheduleNewTasksForm } from '~/components/common/pages/scheduledTasks/modals/lib/models/interfaces'
|
|
99
|
+
import { constructDataReadyViewFunc } from '~/components/common/wizards/vm/migrate/lib/config/constructDataReady'
|
|
100
|
+
import * as validation from '~/components/common/wizards/vm/migrate/lib/validations'
|
|
101
|
+
|
|
102
|
+
const props = withDefaults(
|
|
103
|
+
defineProps<{
|
|
104
|
+
project: UI_T_Project
|
|
105
|
+
isScheduledTasks: boolean
|
|
106
|
+
isEditScheduledTasks: boolean
|
|
107
|
+
vmSettings: UI_I_VmSettings | null
|
|
108
|
+
vmName: string
|
|
109
|
+
getDatastoreTableFunc: (payload: UI_I_TablePayload) => Promise<void>
|
|
110
|
+
getComputeResourceData: (payload: UI_I_TablePayload) => Promise<void>
|
|
111
|
+
datastore: UI_I_DatastoreTableItem[]
|
|
112
|
+
configurePerDisks: UI_I_StorageConfigurePerDiskItem[]
|
|
113
|
+
computeResourceTableData?: any
|
|
114
|
+
computeResourceTree?: UI_I_TreeNode | null
|
|
115
|
+
selectedVirtualMachine?: string
|
|
116
|
+
}>(),
|
|
117
|
+
{
|
|
118
|
+
computeResourceTree: null,
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
const emits = defineEmits<{
|
|
122
|
+
(event: 'hide'): void
|
|
123
|
+
(event: 'finish', value: UI_I_MigrateFormLocal): void
|
|
124
|
+
}>()
|
|
125
|
+
const modelSchedulerTask = defineModel<UI_I_ScheduleNewTasksForm>(
|
|
126
|
+
'schedulerForm',
|
|
127
|
+
{ required: true }
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
const localization = computed<UI_I_Localization>(() => useLocal())
|
|
131
|
+
|
|
132
|
+
const wizard: Wizard = new Wizard(
|
|
133
|
+
stepsFunc(localization.value, props.isScheduledTasks),
|
|
134
|
+
stepsSchemeInitial
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
const selectedScheme = computed<number[]>(() => wizard.selectedScheme.value)
|
|
138
|
+
const alertMessages = computed<string[][]>(() => wizard.alertMessages.value)
|
|
139
|
+
|
|
140
|
+
const title = computed<string>(() => {
|
|
141
|
+
const { scheduleNewTasks, scheduleTaskEdit, migrate } =
|
|
142
|
+
localization.value.common
|
|
143
|
+
let result = migrate
|
|
144
|
+
if (props.isScheduledTasks) {
|
|
145
|
+
const schedulerMode = props.isEditScheduledTasks
|
|
146
|
+
? scheduleTaskEdit
|
|
147
|
+
: scheduleNewTasks
|
|
148
|
+
|
|
149
|
+
result = `${schedulerMode} (${migrate})`
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return result
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
const isConnectSourceServer = ref<boolean>(false)
|
|
156
|
+
const form = ref<UI_I_MigrateFormLocal>({
|
|
157
|
+
migrate_type: props.project === 'procurator' ? 'storage' : 'resource',
|
|
158
|
+
disk_format: 0,
|
|
159
|
+
storage: null,
|
|
160
|
+
configure: {
|
|
161
|
+
type: 'batch-configure',
|
|
162
|
+
disks: [],
|
|
163
|
+
},
|
|
164
|
+
target_server: {
|
|
165
|
+
fqdn: '',
|
|
166
|
+
user: '',
|
|
167
|
+
password: '',
|
|
168
|
+
},
|
|
169
|
+
network: {
|
|
170
|
+
data: null,
|
|
171
|
+
},
|
|
172
|
+
resource: {
|
|
173
|
+
selectedNode: null,
|
|
174
|
+
host: null,
|
|
175
|
+
cluster: null,
|
|
176
|
+
resourcePool: null,
|
|
177
|
+
vApps: null,
|
|
178
|
+
},
|
|
179
|
+
vMotion_priority: 'high',
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
const validationFunc = async (
|
|
183
|
+
value: UI_I_WizardStep[],
|
|
184
|
+
currentStep: UI_I_WizardStep,
|
|
185
|
+
nextStep: UI_I_WizardStep
|
|
186
|
+
): Promise<UI_I_ValidationReturn> => {
|
|
187
|
+
let stepHasError = false
|
|
188
|
+
|
|
189
|
+
if (wizard.isValidateForStep(3, currentStep.id, nextStep.id)) {
|
|
190
|
+
const nameValidation = await validation.checkSelectedResourceSync(
|
|
191
|
+
localization.value,
|
|
192
|
+
form.value.resource,
|
|
193
|
+
wizard,
|
|
194
|
+
value
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
value = nameValidation.newValue
|
|
198
|
+
|
|
199
|
+
stepHasError = nameValidation.stepHasError
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (wizard.isValidateForStep(4, currentStep.id, nextStep.id)) {
|
|
203
|
+
const nameValidation = await validation.checkSelectedDatastoreSync(
|
|
204
|
+
localization.value,
|
|
205
|
+
form.value.storage,
|
|
206
|
+
wizard,
|
|
207
|
+
value
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
value = nameValidation.newValue
|
|
211
|
+
|
|
212
|
+
stepHasError = nameValidation.stepHasError
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
newValue: value,
|
|
217
|
+
stepHasError,
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
const onChangeSteps = async (value: UI_I_WizardStep[]): Promise<void> =>
|
|
221
|
+
wizard.changeSteps(value, validationFunc)
|
|
222
|
+
|
|
223
|
+
// Choosing Scheme
|
|
224
|
+
watch(
|
|
225
|
+
() => form.value.migrate_type,
|
|
226
|
+
(newValue: UI_T_VmMigrateType) => {
|
|
227
|
+
const schemes: UI_I_ChangeStepsSchemes = {
|
|
228
|
+
procurator: {
|
|
229
|
+
storage: props.isScheduledTasks ? 1 : 0,
|
|
230
|
+
},
|
|
231
|
+
sphere: {
|
|
232
|
+
storage: props.isScheduledTasks ? 1 : 0,
|
|
233
|
+
resource: props.isScheduledTasks ? 3 : 2,
|
|
234
|
+
'resource-storage': 2,
|
|
235
|
+
server: 3,
|
|
236
|
+
},
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const projectSchemes = schemes[props.project]
|
|
240
|
+
|
|
241
|
+
if (projectSchemes && projectSchemes[newValue] !== undefined) {
|
|
242
|
+
wizard.changeScheme(projectSchemes[newValue] as number)
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
{ deep: true, immediate: true }
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
watch(
|
|
249
|
+
modelSchedulerTask,
|
|
250
|
+
(newValue: UI_I_ScheduleNewTasksForm) => {
|
|
251
|
+
if (props.isScheduledTasks) wizard.setDisabledNextButton(newValue.isValid)
|
|
252
|
+
},
|
|
253
|
+
{ immediate: true, deep: true }
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
const loading = ref<boolean>(false)
|
|
257
|
+
|
|
258
|
+
const connectedStorageIdOnVm = computed<string>(
|
|
259
|
+
() => props.vmSettings?.storage.id || ''
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
const dataReadyView = computed<UI_I_TableInfoItem>(() =>
|
|
263
|
+
constructDataReadyViewFunc(props.vmName, form.value)
|
|
264
|
+
)
|
|
265
|
+
const onFinish = (): void => {
|
|
266
|
+
loading.value = true
|
|
267
|
+
emits('finish', form.value)
|
|
268
|
+
loading.value = false
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const onHideModal = (): void => {
|
|
272
|
+
emits('hide')
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const onHideAlert = (stepId: number): void => {
|
|
276
|
+
wizard.hideAlertMessagesByStepId(stepId)
|
|
277
|
+
}
|
|
278
|
+
</script>
|
|
279
|
+
|
|
280
|
+
<style scoped lang="scss">
|
|
281
|
+
@import 'assets/scss/common/mixins.scss';
|
|
282
|
+
.migrate-vm {
|
|
283
|
+
:deep(.modal-body) {
|
|
284
|
+
height: inherit;
|
|
285
|
+
@include flex($dir: column);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
</style>
|
|
@@ -53,9 +53,9 @@ import type { UI_I_CollapseNavItem } from '~/components/atoms/collapse/lib/model
|
|
|
53
53
|
import type { UI_I_TreeNode } from '~/components/common/recursionTree/lib/models/interfaces'
|
|
54
54
|
import type { UI_I_TablePayload } from '~/lib/models/table/interfaces'
|
|
55
55
|
import type { UI_T_SelectComputeResourceTabType } from '~/components/common/wizards/vm/migrate/select/storage/lib/models/types'
|
|
56
|
-
import type { UI_E_ComputeResourceTabKamelKeys } from '~/components/common/wizards/vm/migrate/select/computeResource/lib/models/enums'
|
|
57
56
|
import type { UI_I_MigrateFormLocal } from '~/components/common/wizards/vm/migrate/lib/models/interfaces'
|
|
58
57
|
import type { UI_I_SelectedTableDataKeys } from '~/components/common/wizards/vm/migrate/select/computeResource/lib/models/interfaces'
|
|
58
|
+
import { UI_E_ComputeResourceTabKamelKeys } from '~/components/common/wizards/vm/migrate/select/computeResource/lib/models/enums'
|
|
59
59
|
import { vmMigrateComputeResourceTabsFunc } from '~/components/common/wizards/vm/migrate/select/computeResource/lib/config/tabsPannel'
|
|
60
60
|
|
|
61
61
|
const props = defineProps<{
|