1616// under the License.
1717
1818<template >
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 >
19+ <div class =" form" >
20+ <a-input-search
21+ placeholder =" Search"
22+ v-model =" searchQuery"
23+ style =" margin-bottom : 10px ;"
24+ @search =" fetchData" />
25+ <a-table
26+ size =" small"
27+ style =" overflow-y : auto "
28+ :loading =" loading"
29+ :columns =" columns"
30+ :dataSource =" hosts"
31+ :pagination =" false"
32+ :rowKey =" record => record.id" >
33+ <div slot =" suitability" slot-scope =" record" >
34+ <a-icon
35+ class =" host-item__suitability-icon"
36+ type =" check-circle"
37+ theme =" twoTone"
38+ twoToneColor =" #52c41a"
39+ v-if =" record.suitableformigration" />
40+ <a-icon
41+ class =" host-item__suitability-icon"
42+ type =" close-circle"
43+ theme =" twoTone"
44+ twoToneColor =" #f5222d"
45+ v-else />
46+ </div >
47+ <div slot =" memused" slot-scope =" record" >
48+ {{ record.memoryused | byteToGigabyte }} GB
49+ </div >
50+ <template slot="select" slot-scope="record">
6051 <a-radio
6152 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') }}
53+ @click =" selectedHost = record"
54+ :checked =" record.id === selectedHost.id"
55+ :disabled =" !record.suitableformigration" ></a-radio >
56+ </template >
57+ </a-table >
58+ <a-pagination
59+ class =" pagination"
60+ size =" small"
61+ :current =" page"
62+ :pageSize =" pageSize"
63+ :total =" totalCount"
64+ :showTotal =" total => `Total ${total} items`"
65+ :pageSizeOptions =" ['10', '20', '40', '80', '100']"
66+ @change =" handleChangePage"
67+ @showSizeChange =" handleChangePageSize"
68+ showSizeChanger />
69+
70+ <div style =" margin-top : 20px ; display : flex ; justify-content :flex-end ;" >
71+ <a-button type =" primary" :disabled =" !selectedHost.id" @click =" submitForm" >
72+ {{ $t('ok') }}
7073 </a-button >
7174 </div >
72- </a-list >
75+ </div >
76+
7377</template >
7478
7579<script >
@@ -87,8 +91,33 @@ export default {
8791 return {
8892 loading: true ,
8993 hosts: [],
90- selectedIndex: null ,
91- searchQuery: ' '
94+ selectedHost: {},
95+ searchQuery: ' ' ,
96+ totalCount: 0 ,
97+ page: 1 ,
98+ pageSize: 10 ,
99+ columns: [
100+ {
101+ title: this .$t (' name' ),
102+ dataIndex: ' name'
103+ },
104+ {
105+ title: this .$t (' Suitability' ),
106+ scopedSlots: { customRender: ' suitability' }
107+ },
108+ {
109+ title: this .$t (' cpuused' ),
110+ dataIndex: ' cpuused'
111+ },
112+ {
113+ title: this .$t (' memused' ),
114+ scopedSlots: { customRender: ' memused' }
115+ },
116+ {
117+ title: this .$t (' select' ),
118+ scopedSlots: { customRender: ' select' }
119+ }
120+ ]
92121 }
93122 },
94123 mounted () {
@@ -100,20 +129,24 @@ export default {
100129 api (' findHostsForMigration' , {
101130 virtualmachineid: this .resource .id ,
102131 keyword: this .searchQuery ,
103- page: 1 ,
104- pagesize: 500
132+ page: this . page ,
133+ pagesize: this . pageSize
105134 }).then (response => {
106135 this .hosts = response .findhostsformigrationresponse .host
107- this .loading = false
136+ this .totalCount = response .findhostsformigrationresponse .count
137+ if (this .totalCount > 0 ) {
138+ this .totalCount -= 1
139+ }
108140 }).catch (error => {
109141 this .$message .error (' Failed to load hosts: ' + error)
142+ }).finally (() => {
143+ this .loading = false
110144 })
111145 },
112146 submitForm () {
113147 this .loading = true
114- const host = this .hosts [this .selectedIndex ]
115- api (host .requiresStorageMotion ? ' migrateVirtualMachineWithVolume' : ' migrateVirtualMachine' , {
116- hostid: host .id ,
148+ api (this .selectedHost .requiresStorageMotion ? ' migrateVirtualMachineWithVolume' : ' migrateVirtualMachine' , {
149+ hostid: this .selectedHost .id ,
117150 virtualmachineid: this .resource .id
118151 }).then (response => {
119152 this .$store .dispatch (' AddAsyncJob' , {
@@ -141,42 +174,34 @@ export default {
141174 this .$parent .$parent .close ()
142175 }).catch (error => {
143176 console .error (error)
144- this .$message .error (' Failed to migrate host. ' )
177+ this .$message .error (` Failed to migrate VM to host ${ this . selectedHost . name } ` )
145178 })
179+ },
180+ handleChangePage (page , pageSize ) {
181+ this .page = page
182+ this .pageSize = pageSize
183+ this .fetchData ()
184+ },
185+ handleChangePageSize (currentPage , pageSize ) {
186+ this .page = currentPage
187+ this .pageSize = pageSize
188+ this .fetchData ()
146189 }
147190 },
148191 filters: {
149192 byteToGigabyte : value => {
150- if (! value) return ' '
151- value = value / Math .pow (10 , 9 )
152- return value .toFixed (2 )
193+ return (value / Math .pow (10 , 9 )).toFixed (2 )
153194 }
154195 }
155196}
156197 </script >
157198
158199<style scoped lang="scss">
159200
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 ;
201+ .form {
202+ width : 85vw ;
203+ @media (min-width : 800px ) {
204+ width : 750px ;
180205 }
181206 }
182207
@@ -230,4 +255,8 @@ export default {
230255 }
231256
232257 }
258+
259+ .pagination {
260+ margin-top : 20px ;
261+ }
233262 </style >
0 commit comments