1616// under the License.
1717
1818<template >
19- <a-spin :spinning =" fetchLoading" >
20- <a-button :disabled =" !('associateIpAddress' in $store.getters.apis)" type =" dashed" icon =" plus" style =" width : 100% ; margin-bottom : 15px " @click =" acquireIpAddress" >
21- {{ $t('label.acquire.new.ip') }}
22- </a-button >
23- <div v-if =" $route.path.startsWith('/vpc')" >
24- Select Tier:
25- <a-select
26- style =" width : 40% ; margin-left : 15px ;margin-bottom : 15px "
27- :loading =" fetchLoading"
28- defaultActiveFirstOption
29- :value =" vpcTier"
30- @change =" handleTierSelect"
31- >
32- <a-select-option key =" all" value =" " >
33- {{ $t('label.view.all') }}
34- </a-select-option >
35- <a-select-option v-for =" network in networksList" :key =" network.id" :value =" network.id" >
36- {{ network.name }}
37- </a-select-option >
38- </a-select >
39- </div >
40- <a-table
41- size =" small"
42- style =" overflow-y : auto "
43- :columns =" columns"
44- :dataSource =" ips"
45- :rowKey =" item => item.id"
46- :pagination =" false" >
47- <template slot="ipaddress" slot-scope="text, record">
48- <router-link :to =" { path: '/publicip/' + record.id }" >{{ text }} </router-link >
49- <a-tag v-if =" record.issourcenat === true" >source-nat</a-tag >
50- </template >
51-
52- <template slot="state" slot-scope="text, record">
53- <status :text =" record.state" displayText />
54- </template >
55-
56- <template slot="virtualmachineid" slot-scope="text, record">
57- <a-icon type =" desktop" v-if =" record.virtualmachineid" />
58- <router-link :to =" { path: '/vm/' + record.virtualmachineid }" > {{ record.virtualmachinename || record.virtualmachineid }} </router-link >
59- </template >
60-
61- <template slot="associatednetworkname" slot-scope="text, record">
62- <router-link :to =" { path: '/guestnetwork/' + record.associatednetworkid }" > {{ record.associatednetworkname || record.associatednetworkid }} </router-link >
63- </template >
64-
65- <template slot="action" slot-scope="text, record">
66- <a-button
67- v-if =" record.issourcenat !== true"
68- type =" danger"
69- icon =" delete"
70- shape =" circle"
71- :disabled =" !('disassociateIpAddress' in $store.getters.apis)"
72- @click =" releaseIpAddress(record)" />
73- </template >
74- </a-table >
75- <a-divider />
76- <a-pagination
77- class =" row-element pagination"
78- size =" small"
79- :current =" page"
80- :pageSize =" pageSize"
81- :total =" totalIps"
82- :showTotal =" total => `Total ${total} items`"
83- :pageSizeOptions =" ['10', '20', '40', '80', '100']"
84- @change =" changePage"
85- @showSizeChange =" changePageSize"
86- showSizeChanger />
87- </a-spin >
19+ <div >
20+ <a-spin :spinning =" fetchLoading" >
21+ <a-button
22+ :disabled =" !('associateIpAddress' in $store.getters.apis)"
23+ type =" dashed"
24+ icon =" plus"
25+ style =" width : 100% ; margin-bottom : 15px "
26+ @click =" onShowAcquireIp" >
27+ {{ $t('label.acquire.new.ip') }}
28+ </a-button >
29+ <div v-if =" $route.path.startsWith('/vpc')" >
30+ Select Tier:
31+ <a-select
32+ style =" width : 40% ; margin-left : 15px ;margin-bottom : 15px "
33+ :loading =" fetchLoading"
34+ defaultActiveFirstOption
35+ :value =" vpcTier"
36+ @change =" handleTierSelect"
37+ >
38+ <a-select-option key =" all" value =" " >
39+ {{ $t('label.view.all') }}
40+ </a-select-option >
41+ <a-select-option v-for =" network in networksList" :key =" network.id" :value =" network.id" >
42+ {{ network.name }}
43+ </a-select-option >
44+ </a-select >
45+ </div >
46+ <a-table
47+ size =" small"
48+ style =" overflow-y : auto "
49+ :columns =" columns"
50+ :dataSource =" ips"
51+ :rowKey =" item => item.id"
52+ :pagination =" false" >
53+ <template slot="ipaddress" slot-scope="text, record">
54+ <router-link :to =" { path: '/publicip/' + record.id }" >{{ text }} </router-link >
55+ <a-tag v-if =" record.issourcenat === true" >source-nat</a-tag >
56+ </template >
57+
58+ <template slot="state" slot-scope="text, record">
59+ <status :text =" record.state" displayText />
60+ </template >
61+
62+ <template slot="virtualmachineid" slot-scope="text, record">
63+ <a-icon type =" desktop" v-if =" record.virtualmachineid" />
64+ <router-link :to =" { path: '/vm/' + record.virtualmachineid }" > {{ record.virtualmachinename || record.virtualmachineid }} </router-link >
65+ </template >
66+
67+ <template slot="associatednetworkname" slot-scope="text, record">
68+ <router-link :to =" { path: '/guestnetwork/' + record.associatednetworkid }" > {{ record.associatednetworkname || record.associatednetworkid }} </router-link >
69+ </template >
70+
71+ <template slot="action" slot-scope="text, record">
72+ <a-button
73+ v-if =" record.issourcenat !== true"
74+ type =" danger"
75+ icon =" delete"
76+ shape =" circle"
77+ :disabled =" !('disassociateIpAddress' in $store.getters.apis)"
78+ @click =" releaseIpAddress(record)" />
79+ </template >
80+ </a-table >
81+ <a-divider />
82+ <a-pagination
83+ class =" row-element pagination"
84+ size =" small"
85+ :current =" page"
86+ :pageSize =" pageSize"
87+ :total =" totalIps"
88+ :showTotal =" total => `Total ${total} items`"
89+ :pageSizeOptions =" ['10', '20', '40', '80', '100']"
90+ @change =" changePage"
91+ @showSizeChange =" changePageSize"
92+ showSizeChanger />
93+ </a-spin >
94+ <a-modal
95+ v-if =" showAcquireIp"
96+ :visible =" showAcquireIp"
97+ :title =" $t('label.acquire.new.ip')"
98+ :closable =" true"
99+ @cancel =" onCloseModal"
100+ @ok =" acquireIpAddress"
101+ centered
102+ width =" 450px" >
103+ <a-spin :spinning =" acquireLoading" >
104+ <a-alert :message =" $t('message.action.acquire.ip')" type =" warning" />
105+ <a-form-item :label =" $t('label.ipaddress')" >
106+ <a-select
107+ style =" width : 100% ;"
108+ showSearch
109+ v-model =" acquireIp" >
110+ <a-select-option
111+ v-for =" ip in listPublicIpAddress"
112+ :key =" ip.ipaddress" >{{ ip.ipaddress }}</a-select-option >
113+ </a-select >
114+ </a-form-item >
115+ </a-spin >
116+ </a-modal >
117+ </div >
88118</template >
89119<script >
90120import { api } from ' @/api'
@@ -142,7 +172,11 @@ export default {
142172 title: ' ' ,
143173 scopedSlots: { customRender: ' action' }
144174 }
145- ]
175+ ],
176+ showAcquireIp: false ,
177+ acquireLoading: false ,
178+ acquireIp: null ,
179+ listPublicIpAddress: []
146180 }
147181 },
148182 mounted () {
@@ -181,6 +215,21 @@ export default {
181215 this .fetchLoading = false
182216 })
183217 },
218+ fetchListPublicIpAddress () {
219+ return new Promise ((resolve , reject ) => {
220+ const params = {
221+ zoneid: this .resource .zoneid ,
222+ domainid: this .resource .domainid ,
223+ account: this .resource .account ,
224+ forvirtualnetwork: true ,
225+ allocatedonly: false
226+ }
227+ api (' listPublicIpAddresses' , params).then (json => {
228+ const listPublicIps = json .listpublicipaddressesresponse .publicipaddress || []
229+ resolve (listPublicIps)
230+ }).catch (reject)
231+ })
232+ },
184233 handleTierSelect (tier ) {
185234 this .vpcTier = tier
186235 this .fetchData ()
@@ -205,7 +254,9 @@ export default {
205254 } else {
206255 params .networkid = this .resource .id
207256 }
208- this .fetchLoading = true
257+ params .ipaddress = this .acquireIp
258+ this .acquireLoading = true
259+
209260 api (' associateIpAddress' , params).then (response => {
210261 this .$pollJob ({
211262 jobId: response .associateipaddressresponse .jobid ,
@@ -221,12 +272,14 @@ export default {
221272 catchMessage: ' Error encountered while fetching async job result'
222273 })
223274 }).catch (error => {
224- this .fetchLoading = false
225275 this .$notification .error ({
226276 message: ` Error ${ error .response .status } ` ,
227277 description: error .response .data .errorresponse .errortext ,
228278 duration: 0
229279 })
280+ }).finally (() => {
281+ this .acquireLoading = false
282+ this .onCloseModal ()
230283 })
231284 },
232285 releaseIpAddress (ip ) {
@@ -255,6 +308,35 @@ export default {
255308 duration: 0
256309 })
257310 })
311+ },
312+ async onShowAcquireIp () {
313+ this .showAcquireIp = true
314+ this .acquireLoading = true
315+ this .listPublicIpAddress = []
316+
317+ try {
318+ const listPublicIpAddress = await this .fetchListPublicIpAddress ()
319+ listPublicIpAddress .forEach (item => {
320+ if (item .state === ' Free' ) {
321+ this .listPublicIpAddress .push ({
322+ ipaddress: item .ipaddress
323+ })
324+ }
325+ })
326+ this .listPublicIpAddress .sort (function (a , b ) {
327+ if (a .ipaddress < b .ipaddress ) { return - 1 }
328+ if (a .ipaddress > b .ipaddress ) { return 1 }
329+ return 0
330+ })
331+ this .acquireIp = this .listPublicIpAddress && this .listPublicIpAddress .length > 0 ? this .listPublicIpAddress [0 ].ipaddress : null
332+ this .acquireLoading = false
333+ } catch (e) {
334+ this .acquireLoading = false
335+ this .$notifyError (e)
336+ }
337+ },
338+ onCloseModal () {
339+ this .showAcquireIp = false
258340 }
259341 }
260342}
0 commit comments