Skip to content

Commit 81b49b8

Browse files
authored
ui: fix select networks for template nic (apache#5933)
* ui: fix select networks for template nic Fixes apache#5927 Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent 5db6b86 commit 81b49b8

4 files changed

Lines changed: 407 additions & 34 deletions

File tree

ui/public/locales/en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@
552552
"label.certificate.upload.failed": "Certificate Upload Failed",
553553
"label.certificate.upload.failed.description": "Failed to update SSL Certificate. Failed to pass certificate validation check",
554554
"label.certificateid": "Certificate ID",
555+
"label.change": "Change",
555556
"label.change.affinity": "Change Affinity",
556557
"label.change.ip.addess": "Change IP Address",
557558
"label.change.ipaddress": "Change IP address for NIC",
@@ -1978,6 +1979,7 @@
19781979
"label.select.instance": "Select instance",
19791980
"label.select.instance.to.attach.volume.to": "Select instance to attach volume to",
19801981
"label.select.iso.or.template": "Select ISO or template",
1982+
"label.select.network": "Select Network",
19811983
"label.select.offering": "Select offering",
19821984
"label.select.project": "Select Project",
19831985
"label.select.projects": "Select Projects",
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
<template>
19+
<div>
20+
<a-table
21+
class="top-spaced"
22+
size="small"
23+
style="max-height: 250px; overflow-y: auto"
24+
:columns="nicColumns"
25+
:dataSource="nics"
26+
:pagination="false"
27+
:rowKey="record => record.InstanceID">
28+
<template slot="displaytext" slot-scope="record">
29+
<span>{{ record.elementName + ' - ' + record.name }}
30+
<a-tooltip :title="record.nicDescription" placement="top">
31+
<a-icon type="info-circle" class="table-tooltip-icon" />
32+
</a-tooltip>
33+
</span>
34+
</template>
35+
<div slot="size" slot-scope="record">
36+
<span v-if="record.size">
37+
{{ $bytesToHumanReadableSize(record.size) }}
38+
</span>
39+
</div>
40+
<template slot="selectednetwork" slot-scope="record">
41+
<span>{{ record.selectednetworkname || '' }}</span>
42+
</template>
43+
<template slot="select" slot-scope="record">
44+
<div style="display: flex; justify-content: flex-end;"><a-button @click="openNicNetworkSelector(record)">{{ record.selectednetworkid ? $t('label.change') : $t('label.select') }}</a-button></div>
45+
</template>
46+
</a-table>
47+
48+
<a-modal
49+
:visible="!(!selectedNicForNetworkSelection.id)"
50+
:title="$t('label.select.network')"
51+
:closable="true"
52+
:maskClosable="false"
53+
:footer="null"
54+
:cancelText="$t('label.cancel')"
55+
@cancel="closeNicNetworkSelector()"
56+
centered
57+
width="auto">
58+
<nic-network-select-form
59+
:resource="selectedNicForNetworkSelection"
60+
:zoneid="zoneid"
61+
:isOpen="!(!selectedNicForNetworkSelection.id)"
62+
@close-action="closeNicNetworkSelector()"
63+
@select="handleNicNetworkSelection" />
64+
</a-modal>
65+
</div>
66+
</template>
67+
68+
<script>
69+
import NicNetworkSelectForm from '@/components/view/NicNetworkSelectForm'
70+
71+
export default {
72+
name: 'InstanceNicsNetworkSelectListView',
73+
components: {
74+
NicNetworkSelectForm
75+
},
76+
props: {
77+
nics: {
78+
type: Array,
79+
required: true
80+
},
81+
zoneid: {
82+
type: String,
83+
required: true
84+
}
85+
},
86+
data () {
87+
return {
88+
nicColumns: [
89+
{
90+
title: this.$t('label.nic'),
91+
scopedSlots: { customRender: 'displaytext' }
92+
},
93+
{
94+
title: this.$t('label.network'),
95+
scopedSlots: { customRender: 'selectednetwork' }
96+
},
97+
{
98+
title: '',
99+
scopedSlots: { customRender: 'select' }
100+
}
101+
],
102+
selectedNicForNetworkSelection: {}
103+
}
104+
},
105+
methods: {
106+
resetSelection () {
107+
var nics = this.nics
108+
this.nics = []
109+
for (var nic of nics) {
110+
nic.selectednetworkid = null
111+
nic.selectednetworkname = ''
112+
}
113+
this.nics = nics
114+
this.updateNicToNetworkSelection()
115+
},
116+
openNicNetworkSelector (nic) {
117+
this.selectedNicForNetworkSelection = nic
118+
},
119+
closeNicNetworkSelector () {
120+
this.selectedNicForNetworkSelection = {}
121+
},
122+
handleNicNetworkSelection (nicId, network) {
123+
for (const nic of this.nics) {
124+
if (nic.id === nicId) {
125+
nic.selectednetworkid = network.id
126+
nic.selectednetworkname = network.name
127+
break
128+
}
129+
}
130+
this.updateNicToNetworkSelection()
131+
},
132+
updateNicToNetworkSelection () {
133+
var nicToNetworkSelection = []
134+
for (const nic of this.nics) {
135+
if (nic.selectednetworkid && nic.selectednetworkid !== -1) {
136+
nicToNetworkSelection.push({ nic: nic.id, network: nic.selectednetworkid })
137+
}
138+
}
139+
this.$emit('select', nicToNetworkSelection)
140+
}
141+
}
142+
}
143+
</script>
144+
145+
<style scoped lang="less">
146+
.top-spaced {
147+
margin-top: 20px;
148+
}
149+
</style>
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
<template>
19+
<div class="form" v-ctrl-enter="handleKeyboardSubmit">
20+
<div>
21+
<a-input-search
22+
class="top-spaced"
23+
:placeholder="$t('label.search')"
24+
v-model="searchQuery"
25+
style="margin-bottom: 10px;"
26+
@search="fetchNetworks"
27+
autoFocus />
28+
<a-table
29+
size="small"
30+
style="overflow-y: auto"
31+
:loading="loading"
32+
:columns="columns"
33+
:dataSource="networks"
34+
:pagination="false"
35+
:rowKey="record => record.id">
36+
<template slot="select" slot-scope="record">
37+
<a-radio
38+
@click="updateSelection(record)"
39+
:checked="selectedNetwork != null && record.id === selectedNetwork.id">
40+
</a-radio>
41+
</template>
42+
</a-table>
43+
<a-pagination
44+
class="top-spaced"
45+
size="small"
46+
:current="page"
47+
:pageSize="pageSize"
48+
:total="totalCount"
49+
:showTotal="total => `${$t('label.total')} ${total} ${$t('label.items')}`"
50+
:pageSizeOptions="['10', '20', '40', '80', '100']"
51+
@change="handleChangePage"
52+
@showSizeChange="handleChangePageSize"
53+
showSizeChanger>
54+
<template slot="buildOptionText" slot-scope="props">
55+
<span>{{ props.value }} / {{ $t('label.page') }}</span>
56+
</template>
57+
</a-pagination>
58+
</div>
59+
60+
<a-divider />
61+
62+
<div class="actions">
63+
<a-button @click="closeModal">{{ $t('label.cancel') }}</a-button>
64+
<a-button type="primary" ref="submit" :disabled="!selectedNetwork" @click="submitForm">{{ $t('label.ok') }}</a-button>
65+
</div>
66+
67+
</div>
68+
</template>
69+
70+
<script>
71+
import { api } from '@/api'
72+
73+
export default {
74+
name: 'NicNetworkSelectForm',
75+
props: {
76+
resource: {
77+
type: Object,
78+
required: true
79+
},
80+
zoneid: {
81+
type: String,
82+
required: true
83+
},
84+
isOpen: {
85+
type: Boolean,
86+
required: false
87+
}
88+
},
89+
data () {
90+
return {
91+
loading: false,
92+
networks: [],
93+
searchQuery: '',
94+
totalCount: 0,
95+
page: 1,
96+
pageSize: 10,
97+
selectedNetwork: null,
98+
columns: [
99+
{
100+
title: this.$t('label.networkid'),
101+
dataIndex: 'name'
102+
},
103+
{
104+
title: this.$t('label.guestiptype'),
105+
dataIndex: 'type'
106+
},
107+
{
108+
title: this.$t('label.vpc'),
109+
dataIndex: 'vpcName'
110+
},
111+
{
112+
title: this.$t('label.cidr'),
113+
dataIndex: 'cidr'
114+
},
115+
{
116+
title: this.$t('label.select'),
117+
scopedSlots: { customRender: 'select' }
118+
}
119+
]
120+
}
121+
},
122+
created () {
123+
this.fetchNetworks()
124+
this.preselectNetwork()
125+
},
126+
watch: {
127+
isOpen (newValue) {
128+
if (newValue) {
129+
setTimeout(() => {
130+
this.reset()
131+
}, 50)
132+
}
133+
}
134+
},
135+
methods: {
136+
fetchNetworks () {
137+
this.loading = true
138+
var params = {
139+
zoneid: this.zoneid,
140+
keyword: this.searchQuery,
141+
page: this.page,
142+
pagesize: this.pageSize,
143+
canusefordeploy: true,
144+
projectid: this.$store.getters.project ? this.$store.getters.project.id : null,
145+
domainid: this.$store.getters.project && this.$store.getters.project.id ? null : this.$store.getters.userInfo.domainid,
146+
account: this.$store.getters.project && this.$store.getters.project.id ? null : this.$store.getters.userInfo.account
147+
}
148+
api('listNetworks', params).then(response => {
149+
this.networks = response.listnetworksresponse.network || []
150+
this.totalCount = response.listnetworksresponse.count
151+
}).catch(error => {
152+
this.$notifyError(error)
153+
}).finally(() => {
154+
this.loading = false
155+
})
156+
},
157+
handleChangePage (page, pageSize) {
158+
this.page = page
159+
this.pageSize = pageSize
160+
this.fetchNetworks()
161+
},
162+
handleChangePageSize (currentPage, pageSize) {
163+
this.page = currentPage
164+
this.pageSize = pageSize
165+
this.fetchNetworks()
166+
},
167+
preselectNetwork () {
168+
if (this.resource && 'selectednetworkid' in this.resource) {
169+
this.selectedNetwork = { id: this.resource.selectednetworkid }
170+
}
171+
},
172+
clearView () {
173+
this.networks = []
174+
this.searchQuery = ''
175+
this.totalCount = 0
176+
this.page = 1
177+
this.pageSize = 10
178+
this.selectedNetwork = null
179+
},
180+
reset () {
181+
this.clearView()
182+
this.preselectNetwork()
183+
this.fetchNetworks()
184+
},
185+
updateSelection (network) {
186+
this.selectedNetwork = network
187+
},
188+
closeModal () {
189+
this.$emit('close-action')
190+
},
191+
handleKeyboardSubmit () {
192+
if (this.selectedNetwork != null) {
193+
this.submitForm()
194+
}
195+
},
196+
submitForm () {
197+
this.$emit('select', this.resource.id, this.selectedNetwork)
198+
this.closeModal()
199+
}
200+
}
201+
}
202+
</script>
203+
204+
<style scoped lang="scss">
205+
.form {
206+
width: 80vw;
207+
208+
@media (min-width: 900px) {
209+
width: 850px;
210+
}
211+
}
212+
213+
.top-spaced {
214+
margin-top: 20px;
215+
}
216+
217+
.actions {
218+
display: flex;
219+
justify-content: flex-end;
220+
margin-top: 20px;
221+
222+
button {
223+
&:not(:last-child) {
224+
margin-right: 10px;
225+
}
226+
}
227+
}
228+
</style>

0 commit comments

Comments
 (0)