mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
ui: fix select networks for template nic (#5933)
* ui: fix select networks for template nic Fixes #5927 Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
parent
5db6b86200
commit
81b49b835a
@ -552,6 +552,7 @@
|
||||
"label.certificate.upload.failed": "Certificate Upload Failed",
|
||||
"label.certificate.upload.failed.description": "Failed to update SSL Certificate. Failed to pass certificate validation check",
|
||||
"label.certificateid": "Certificate ID",
|
||||
"label.change": "Change",
|
||||
"label.change.affinity": "Change Affinity",
|
||||
"label.change.ip.addess": "Change IP Address",
|
||||
"label.change.ipaddress": "Change IP address for NIC",
|
||||
@ -1978,6 +1979,7 @@
|
||||
"label.select.instance": "Select instance",
|
||||
"label.select.instance.to.attach.volume.to": "Select instance to attach volume to",
|
||||
"label.select.iso.or.template": "Select ISO or template",
|
||||
"label.select.network": "Select Network",
|
||||
"label.select.offering": "Select offering",
|
||||
"label.select.project": "Select Project",
|
||||
"label.select.projects": "Select Projects",
|
||||
|
||||
149
ui/src/components/view/InstanceNicsNetworkSelectListView.vue
Normal file
149
ui/src/components/view/InstanceNicsNetworkSelectListView.vue
Normal file
@ -0,0 +1,149 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<a-table
|
||||
class="top-spaced"
|
||||
size="small"
|
||||
style="max-height: 250px; overflow-y: auto"
|
||||
:columns="nicColumns"
|
||||
:dataSource="nics"
|
||||
:pagination="false"
|
||||
:rowKey="record => record.InstanceID">
|
||||
<template slot="displaytext" slot-scope="record">
|
||||
<span>{{ record.elementName + ' - ' + record.name }}
|
||||
<a-tooltip :title="record.nicDescription" placement="top">
|
||||
<a-icon type="info-circle" class="table-tooltip-icon" />
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<div slot="size" slot-scope="record">
|
||||
<span v-if="record.size">
|
||||
{{ $bytesToHumanReadableSize(record.size) }}
|
||||
</span>
|
||||
</div>
|
||||
<template slot="selectednetwork" slot-scope="record">
|
||||
<span>{{ record.selectednetworkname || '' }}</span>
|
||||
</template>
|
||||
<template slot="select" slot-scope="record">
|
||||
<div style="display: flex; justify-content: flex-end;"><a-button @click="openNicNetworkSelector(record)">{{ record.selectednetworkid ? $t('label.change') : $t('label.select') }}</a-button></div>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<a-modal
|
||||
:visible="!(!selectedNicForNetworkSelection.id)"
|
||||
:title="$t('label.select.network')"
|
||||
:closable="true"
|
||||
:maskClosable="false"
|
||||
:footer="null"
|
||||
:cancelText="$t('label.cancel')"
|
||||
@cancel="closeNicNetworkSelector()"
|
||||
centered
|
||||
width="auto">
|
||||
<nic-network-select-form
|
||||
:resource="selectedNicForNetworkSelection"
|
||||
:zoneid="zoneid"
|
||||
:isOpen="!(!selectedNicForNetworkSelection.id)"
|
||||
@close-action="closeNicNetworkSelector()"
|
||||
@select="handleNicNetworkSelection" />
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NicNetworkSelectForm from '@/components/view/NicNetworkSelectForm'
|
||||
|
||||
export default {
|
||||
name: 'InstanceNicsNetworkSelectListView',
|
||||
components: {
|
||||
NicNetworkSelectForm
|
||||
},
|
||||
props: {
|
||||
nics: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
zoneid: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
nicColumns: [
|
||||
{
|
||||
title: this.$t('label.nic'),
|
||||
scopedSlots: { customRender: 'displaytext' }
|
||||
},
|
||||
{
|
||||
title: this.$t('label.network'),
|
||||
scopedSlots: { customRender: 'selectednetwork' }
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
scopedSlots: { customRender: 'select' }
|
||||
}
|
||||
],
|
||||
selectedNicForNetworkSelection: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
resetSelection () {
|
||||
var nics = this.nics
|
||||
this.nics = []
|
||||
for (var nic of nics) {
|
||||
nic.selectednetworkid = null
|
||||
nic.selectednetworkname = ''
|
||||
}
|
||||
this.nics = nics
|
||||
this.updateNicToNetworkSelection()
|
||||
},
|
||||
openNicNetworkSelector (nic) {
|
||||
this.selectedNicForNetworkSelection = nic
|
||||
},
|
||||
closeNicNetworkSelector () {
|
||||
this.selectedNicForNetworkSelection = {}
|
||||
},
|
||||
handleNicNetworkSelection (nicId, network) {
|
||||
for (const nic of this.nics) {
|
||||
if (nic.id === nicId) {
|
||||
nic.selectednetworkid = network.id
|
||||
nic.selectednetworkname = network.name
|
||||
break
|
||||
}
|
||||
}
|
||||
this.updateNicToNetworkSelection()
|
||||
},
|
||||
updateNicToNetworkSelection () {
|
||||
var nicToNetworkSelection = []
|
||||
for (const nic of this.nics) {
|
||||
if (nic.selectednetworkid && nic.selectednetworkid !== -1) {
|
||||
nicToNetworkSelection.push({ nic: nic.id, network: nic.selectednetworkid })
|
||||
}
|
||||
}
|
||||
this.$emit('select', nicToNetworkSelection)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.top-spaced {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
228
ui/src/components/view/NicNetworkSelectForm.vue
Normal file
228
ui/src/components/view/NicNetworkSelectForm.vue
Normal file
@ -0,0 +1,228 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
<template>
|
||||
<div class="form" v-ctrl-enter="handleKeyboardSubmit">
|
||||
<div>
|
||||
<a-input-search
|
||||
class="top-spaced"
|
||||
:placeholder="$t('label.search')"
|
||||
v-model="searchQuery"
|
||||
style="margin-bottom: 10px;"
|
||||
@search="fetchNetworks"
|
||||
autoFocus />
|
||||
<a-table
|
||||
size="small"
|
||||
style="overflow-y: auto"
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:dataSource="networks"
|
||||
:pagination="false"
|
||||
:rowKey="record => record.id">
|
||||
<template slot="select" slot-scope="record">
|
||||
<a-radio
|
||||
@click="updateSelection(record)"
|
||||
:checked="selectedNetwork != null && record.id === selectedNetwork.id">
|
||||
</a-radio>
|
||||
</template>
|
||||
</a-table>
|
||||
<a-pagination
|
||||
class="top-spaced"
|
||||
size="small"
|
||||
:current="page"
|
||||
:pageSize="pageSize"
|
||||
:total="totalCount"
|
||||
:showTotal="total => `${$t('label.total')} ${total} ${$t('label.items')}`"
|
||||
:pageSizeOptions="['10', '20', '40', '80', '100']"
|
||||
@change="handleChangePage"
|
||||
@showSizeChange="handleChangePageSize"
|
||||
showSizeChanger>
|
||||
<template slot="buildOptionText" slot-scope="props">
|
||||
<span>{{ props.value }} / {{ $t('label.page') }}</span>
|
||||
</template>
|
||||
</a-pagination>
|
||||
</div>
|
||||
|
||||
<a-divider />
|
||||
|
||||
<div class="actions">
|
||||
<a-button @click="closeModal">{{ $t('label.cancel') }}</a-button>
|
||||
<a-button type="primary" ref="submit" :disabled="!selectedNetwork" @click="submitForm">{{ $t('label.ok') }}</a-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
|
||||
export default {
|
||||
name: 'NicNetworkSelectForm',
|
||||
props: {
|
||||
resource: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
zoneid: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isOpen: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
networks: [],
|
||||
searchQuery: '',
|
||||
totalCount: 0,
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
selectedNetwork: null,
|
||||
columns: [
|
||||
{
|
||||
title: this.$t('label.networkid'),
|
||||
dataIndex: 'name'
|
||||
},
|
||||
{
|
||||
title: this.$t('label.guestiptype'),
|
||||
dataIndex: 'type'
|
||||
},
|
||||
{
|
||||
title: this.$t('label.vpc'),
|
||||
dataIndex: 'vpcName'
|
||||
},
|
||||
{
|
||||
title: this.$t('label.cidr'),
|
||||
dataIndex: 'cidr'
|
||||
},
|
||||
{
|
||||
title: this.$t('label.select'),
|
||||
scopedSlots: { customRender: 'select' }
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.fetchNetworks()
|
||||
this.preselectNetwork()
|
||||
},
|
||||
watch: {
|
||||
isOpen (newValue) {
|
||||
if (newValue) {
|
||||
setTimeout(() => {
|
||||
this.reset()
|
||||
}, 50)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchNetworks () {
|
||||
this.loading = true
|
||||
var params = {
|
||||
zoneid: this.zoneid,
|
||||
keyword: this.searchQuery,
|
||||
page: this.page,
|
||||
pagesize: this.pageSize,
|
||||
canusefordeploy: true,
|
||||
projectid: this.$store.getters.project ? this.$store.getters.project.id : null,
|
||||
domainid: this.$store.getters.project && this.$store.getters.project.id ? null : this.$store.getters.userInfo.domainid,
|
||||
account: this.$store.getters.project && this.$store.getters.project.id ? null : this.$store.getters.userInfo.account
|
||||
}
|
||||
api('listNetworks', params).then(response => {
|
||||
this.networks = response.listnetworksresponse.network || []
|
||||
this.totalCount = response.listnetworksresponse.count
|
||||
}).catch(error => {
|
||||
this.$notifyError(error)
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
handleChangePage (page, pageSize) {
|
||||
this.page = page
|
||||
this.pageSize = pageSize
|
||||
this.fetchNetworks()
|
||||
},
|
||||
handleChangePageSize (currentPage, pageSize) {
|
||||
this.page = currentPage
|
||||
this.pageSize = pageSize
|
||||
this.fetchNetworks()
|
||||
},
|
||||
preselectNetwork () {
|
||||
if (this.resource && 'selectednetworkid' in this.resource) {
|
||||
this.selectedNetwork = { id: this.resource.selectednetworkid }
|
||||
}
|
||||
},
|
||||
clearView () {
|
||||
this.networks = []
|
||||
this.searchQuery = ''
|
||||
this.totalCount = 0
|
||||
this.page = 1
|
||||
this.pageSize = 10
|
||||
this.selectedNetwork = null
|
||||
},
|
||||
reset () {
|
||||
this.clearView()
|
||||
this.preselectNetwork()
|
||||
this.fetchNetworks()
|
||||
},
|
||||
updateSelection (network) {
|
||||
this.selectedNetwork = network
|
||||
},
|
||||
closeModal () {
|
||||
this.$emit('close-action')
|
||||
},
|
||||
handleKeyboardSubmit () {
|
||||
if (this.selectedNetwork != null) {
|
||||
this.submitForm()
|
||||
}
|
||||
},
|
||||
submitForm () {
|
||||
this.$emit('select', this.resource.id, this.selectedNetwork)
|
||||
this.closeModal()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.form {
|
||||
width: 80vw;
|
||||
|
||||
@media (min-width: 900px) {
|
||||
width: 850px;
|
||||
}
|
||||
}
|
||||
|
||||
.top-spaced {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 20px;
|
||||
|
||||
button {
|
||||
&:not(:last-child) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -330,31 +330,10 @@
|
||||
<template slot="description">
|
||||
<div v-if="zoneSelected">
|
||||
<div v-if="vm.templateid && templateNics && templateNics.length > 0">
|
||||
<a-form-item
|
||||
v-for="(nic, nicIndex) in templateNics"
|
||||
:key="nicIndex"
|
||||
:v-bind="nic.name" >
|
||||
<tooltip-label slot="label" :title="nic.elementName + ' - ' + nic.name" :tooltip="nic.networkDescription"/>
|
||||
<a-select
|
||||
showSearch
|
||||
optionFilterProp="children"
|
||||
v-decorator="[
|
||||
'networkMap.nic-' + nic.InstanceID.toString(),
|
||||
{ initialValue: options.networks && options.networks.length > 0 ? options.networks[Math.min(nicIndex, options.networks.length - 1)].id : null }
|
||||
]"
|
||||
:placeholder="nic.networkDescription"
|
||||
:filterOption="(input, option) => {
|
||||
return option.componentOptions.children[0].children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}"
|
||||
>
|
||||
<a-select-option v-for="opt in options.networks" :key="opt.id">
|
||||
<span v-if="opt.type!=='L2'">
|
||||
{{ opt.name || opt.description }} ({{ `${$t('label.cidr')}: ${opt.cidr}` }})
|
||||
</span>
|
||||
<span v-else>{{ opt.name || opt.description }}</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<instance-nics-network-select-list-view
|
||||
:nics="templateNics"
|
||||
:zoneid="selectedZone"
|
||||
@select="handleNicsNetworkSelection" />
|
||||
</div>
|
||||
<div v-show="!(vm.templateid && templateNics && templateNics.length > 0)" >
|
||||
<network-selection
|
||||
@ -711,6 +690,7 @@ import NetworkConfiguration from '@views/compute/wizard/NetworkConfiguration'
|
||||
import SshKeyPairSelection from '@views/compute/wizard/SshKeyPairSelection'
|
||||
import SecurityGroupSelection from '@views/compute/wizard/SecurityGroupSelection'
|
||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||
import InstanceNicsNetworkSelectListView from '@/components/view/InstanceNicsNetworkSelectListView.vue'
|
||||
|
||||
export default {
|
||||
name: 'Wizard',
|
||||
@ -728,7 +708,8 @@ export default {
|
||||
ComputeSelection,
|
||||
SecurityGroupSelection,
|
||||
ResourceIcon,
|
||||
TooltipLabel
|
||||
TooltipLabel,
|
||||
InstanceNicsNetworkSelectListView
|
||||
},
|
||||
props: {
|
||||
visible: {
|
||||
@ -848,7 +829,8 @@ export default {
|
||||
minIops: 0,
|
||||
maxIops: 0,
|
||||
zones: [],
|
||||
selectedZone: ''
|
||||
selectedZone: '',
|
||||
nicToNetworkSelection: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -1691,13 +1673,11 @@ export default {
|
||||
deployVmData.affinitygroupids = (values.affinitygroupids || []).join(',')
|
||||
// step 6: select network
|
||||
if (this.zone.networktype !== 'Basic') {
|
||||
if ('networkMap' in values) {
|
||||
const keys = Object.keys(values.networkMap)
|
||||
for (var j = 0; j < keys.length; ++j) {
|
||||
if (values.networkMap[keys[j]] && values.networkMap[keys[j]].length > 0) {
|
||||
deployVmData['nicnetworklist[' + j + '].nic'] = keys[j].replace('nic-', '')
|
||||
deployVmData['nicnetworklist[' + j + '].network'] = values.networkMap[keys[j]]
|
||||
}
|
||||
if (this.nicToNetworkSelection && this.nicToNetworkSelection.length > 0) {
|
||||
for (var j in this.nicToNetworkSelection) {
|
||||
var nicNetwork = this.nicToNetworkSelection[j]
|
||||
deployVmData['nicnetworklist[' + j + '].nic'] = nicNetwork.nic
|
||||
deployVmData['nicnetworklist[' + j + '].network'] = nicNetwork.network
|
||||
}
|
||||
} else {
|
||||
const arrNetwork = []
|
||||
@ -2067,6 +2047,17 @@ export default {
|
||||
nics.sort(function (a, b) {
|
||||
return a.InstanceID - b.InstanceID
|
||||
})
|
||||
if (this.options.networks && this.options.networks.length > 0) {
|
||||
this.nicToNetworkSelection = []
|
||||
for (var i = 0; i < nics.length; ++i) {
|
||||
var nic = nics[i]
|
||||
nic.id = nic.InstanceID
|
||||
var network = this.options.networks[Math.min(i, this.options.networks.length - 1)]
|
||||
nic.selectednetworkid = network.id
|
||||
nic.selectednetworkname = network.name
|
||||
this.nicToNetworkSelection.push({ nic: nic.id, network: network.id })
|
||||
}
|
||||
}
|
||||
}
|
||||
return nics
|
||||
},
|
||||
@ -2228,6 +2219,9 @@ export default {
|
||||
onBootTypeChange (value) {
|
||||
this.fetchBootModes(value)
|
||||
this.updateFieldValue('bootmode', this.options.bootModes?.[0]?.id || undefined)
|
||||
},
|
||||
handleNicsNetworkSelection (nicToNetworkSelection) {
|
||||
this.nicToNetworkSelection = nicToNetworkSelection
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user