16
16
// under the License.
17
17
18
18
<template >
19
- <div >
20
- {{ resource }}
21
- This needs to implement migrate wizard
22
- </div >
19
+ <a-list :dataSource =" hosts" itemLayout =" vertical" class =" list" :loading =" loading" >
20
+ <div slot =" header" class =" list__header" >
21
+ <a-input-search
22
+ placeholder =" Search"
23
+ v-model =" searchQuery"
24
+ @search =" fetchData" />
25
+ </div >
26
+ <a-list-item
27
+ slot =" renderItem"
28
+ slot-scope =" host, index"
29
+ class =" host-item"
30
+ :class =" { 'host-item--selected' : selectedIndex === index }"
31
+ >
32
+ <div class =" host-item__row" >
33
+ <div class =" host-item__value" >
34
+ <span class =" host-item__title" >{{ $t('name') }}</span >
35
+ {{ host.name }}
36
+ </div >
37
+ <div class =" host-item__value host-item__value--small" >
38
+ <span class =" host-item__title" >Suitability</span >
39
+ <a-icon
40
+ class =" host-item__suitability-icon"
41
+ type =" check-circle"
42
+ theme =" twoTone"
43
+ twoToneColor =" #52c41a"
44
+ v-if =" host.suitableformigration" />
45
+ <a-icon
46
+ class =" host-item__suitability-icon"
47
+ type =" close-circle"
48
+ theme =" twoTone"
49
+ twoToneColor =" #f5222d"
50
+ v-else />
51
+ </div >
52
+ <div class =" host-item__value host-item__value--full" >
53
+ <span class =" host-item__title" >{{ $t('cpuused') }}</span >
54
+ {{ host.cpuused }}
55
+ </div >
56
+ <div class =" host-item__value" >
57
+ <span class =" host-item__title" >{{ $t('memused') }}</span >
58
+ {{ host.memoryused | byteToGigabyte }} GB
59
+ </div >
60
+ <a-radio
61
+ class =" host-item__radio"
62
+ @click =" selectedIndex = index"
63
+ :checked =" selectedIndex === index"
64
+ :disabled =" !host.suitableformigration" ></a-radio >
65
+ </div >
66
+ </a-list-item >
67
+ <div slot =" footer" class =" list__footer" >
68
+ <a-button type =" primary" :disabled =" selectedIndex === null" @click =" submitForm" >
69
+ {{ $t('OK') }}
70
+ </a-button >
71
+ </div >
72
+ </a-list >
23
73
</template >
24
74
25
75
<script >
76
+ import { api } from ' @/api'
77
+ import { pollActionCompletion } from ' @/utils/methods'
26
78
27
79
export default {
28
80
name: ' VMMigrateWizard' ,
29
- components: {
30
- },
31
81
props: {
32
82
resource: {
33
83
type: Object ,
@@ -36,12 +86,152 @@ export default {
36
86
},
37
87
data () {
38
88
return {
89
+ loading: true ,
90
+ hosts: [],
91
+ selectedIndex: null ,
92
+ searchQuery: ' '
39
93
}
40
94
},
95
+ mounted () {
96
+ this .fetchData ()
97
+ },
41
98
methods: {
99
+ fetchData () {
100
+ this .loading = true
101
+ api (' findHostsForMigration' , {
102
+ virtualmachineid: this .resource .id ,
103
+ keyword: this .searchQuery ,
104
+ page: 1 ,
105
+ pagesize: 500
106
+ }).then (response => {
107
+ this .hosts = response .findhostsformigrationresponse .host
108
+ this .loading = false
109
+ }).catch (error => {
110
+ this .$message .error (' Failed to load hosts: ' + error)
111
+ })
112
+ },
113
+ submitForm () {
114
+ this .loading = true
115
+ api (' migrateVirtualMachine' , {
116
+ hostid: this .hosts [this .selectedIndex ].id ,
117
+ virtualmachineid: this .resource .id
118
+ }).then (response => {
119
+ this .$store .dispatch (' AddAsyncJob' , {
120
+ title: ` Migrating ${ this .resource .name } ` ,
121
+ jobid: response .migratevirtualmachineresponse .jobid ,
122
+ description: this .resource .name ,
123
+ status: ' progress'
124
+ })
125
+ pollActionCompletion ({
126
+ jobId: response .migratevirtualmachineresponse .jobid ,
127
+ successMessage: ` Migration completed successfully for ${ this .resource .name } ` ,
128
+ successMethod : () => {
129
+ this .$parent .$parent .close ()
130
+ },
131
+ errorMessage: ' Migration failed' ,
132
+ errorMethod : () => {
133
+ this .$parent .$parent .close ()
134
+ },
135
+ loadingMessage: ` Migration in progress for ${ this .resource .name } ` ,
136
+ catchMessage: ' Error encountered while fetching async job result' ,
137
+ catchMethod : () => {
138
+ this .$parent .$parent .close ()
139
+ }
140
+ })
141
+ this .$parent .$parent .close ()
142
+ }).catch (error => {
143
+ console .error (error)
144
+ this .$message .error (' Failed to migrate host.' )
145
+ })
146
+ }
147
+ },
148
+ filters: {
149
+ byteToGigabyte : value => {
150
+ if (! value) return ' '
151
+ value = value / Math .pow (10 , 9 )
152
+ return value .toFixed (2 )
153
+ }
42
154
}
43
155
}
44
156
</script >
45
157
46
- <style scoped>
158
+ <style scoped lang="scss">
159
+
160
+ .list {
161
+ max-height : 95vh ;
162
+ width : 95vw ;
163
+ overflow-y : scroll ;
164
+ margin : -24px ;
165
+
166
+ @media (min-width : 1000px ) {
167
+ max-height : 70vh ;
168
+ width : 60vw ;
169
+ }
170
+
171
+ & __header ,
172
+ & __footer {
173
+ padding-left : 20px ;
174
+ padding-right : 20px ;
175
+ }
176
+
177
+ & __footer {
178
+ display : flex ;
179
+ justify-content : flex-end ;
180
+ }
181
+
182
+ }
183
+
184
+ .host-item {
185
+ padding-right : 20px ;
186
+ padding-bottom : 0 ;
187
+ padding-left : 20px ;
188
+
189
+ & --selected {
190
+ background-color : #e6f7ff ;
191
+ }
192
+
193
+ & __row {
194
+ display : flex ;
195
+ flex-direction : column ;
196
+ width : 100% ;
197
+
198
+ @media (min-width : 760px ) {
199
+ flex-direction : row ;
200
+ }
201
+
202
+ }
203
+
204
+ & __value {
205
+ display : flex ;
206
+ flex-direction : column ;
207
+ align-items : flex-start ;
208
+ flex : 1 ;
209
+ margin-bottom : 10px ;
210
+
211
+ & --small {
212
+
213
+ @media (min-width : 760px ) {
214
+ flex : none ;
215
+ margin-right : 40px ;
216
+ margin-left : 40px ;
217
+ }
218
+
219
+ }
220
+
221
+ }
222
+
223
+ & __title {
224
+ font-weight : bold ;
225
+ }
226
+
227
+ & __suitability-icon {
228
+ margin-top : 5px ;
229
+ }
230
+
231
+ & __radio {
232
+ display : flex ;
233
+ align-items : center ;
234
+ }
235
+
236
+ }
47
237
</style >
0 commit comments