blob: 048a70671d98f3db9df9bf7beeac71a90269a3bc [file] [log] [blame]
// 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
:loading="loading"
:columns="columns"
:dataSource="tableSource"
:rowKey="record => record.id"
:pagination="false"
:rowSelection="rowSelection"
:scroll="{ y: 225 }" >
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'name'">
<span>{{ record.displaytext || record.name }}</span>
<div v-if="record.meta">
<div v-for="meta in record.meta" :key="meta.key">
<a-tag style="margin-top: 5px" :key="meta.key">{{ meta.key + ': ' + meta.value }}</a-tag>
</div>
</div>
</template>
<template v-if="column.key === 'network'">
<a-alert
v-if="hypervisor === 'KVM' && unableToMatch"
type="warning"
showIcon
banner
style="margin-bottom: 10px"
:message="$t('message.select.nic.network')"
/>
<a-select
style="width: 100%"
v-if="validNetworks[record.id] && validNetworks[record.id].length > 0"
:defaultValue="validNetworks[record.id][0].id"
@change="val => handleNetworkChange(record, val)"
showSearch
optionFilterProp="label"
:filterOption="(input, option) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
}" >
<a-select-option
v-for="network in hypervisor !== 'KVM' ? validNetworks[record.id] : networks"
:key="network.id"
:label="network.displaytext + (network.broadcasturi ? ' (' + network.broadcasturi + ')' : '')">
<div>{{ network.displaytext + (network.broadcasturi ? ' (' + network.broadcasturi + ')' : '') }}</div>
</a-select-option>
</a-select>
<span v-else>
{{ $t('label.no.matching.network') }}
</span>
</template>
<template v-if="column.key === 'ipaddress'">
<check-box-input-pair
layout="vertical"
:resourceKey="record.id"
:checkBoxLabel="$t('label.auto.assign.random.ip')"
:defaultCheckBoxValue="true"
:reversed="true"
:visible="(indexNum > 0 && ipAddressesEnabled[record.id])"
@handle-checkinputpair-change="setIpAddress" />
</template>
</template>
</a-table>
</div>
</template>
<script>
import { api } from '@/api'
import _ from 'lodash'
import CheckBoxInputPair from '@/components/CheckBoxInputPair'
export default {
name: 'MultiDiskSelection',
components: {
CheckBoxInputPair
},
props: {
items: {
type: Array,
default: () => []
},
zoneId: {
type: String,
default: () => ''
},
selectionEnabled: {
type: Boolean,
default: true
},
filterUnimplementedNetworks: {
type: Boolean,
default: false
},
filterMatchKey: {
type: String,
default: null
},
hypervisor: {
type: String,
default: null
}
},
data () {
return {
columns: [
{
key: 'name',
dataIndex: 'name',
title: this.$t('label.nic')
},
{
key: 'network',
dataIndex: 'network',
title: this.$t('label.network')
},
{
key: 'ipaddress',
dataIndex: 'ipaddress',
title: this.$t('label.ipaddress')
}
],
loading: false,
selectedRowKeys: [],
networks: [],
validNetworks: {},
unableToMatch: false,
values: {},
ipAddressesEnabled: {},
ipAddresses: {},
indexNum: 1,
sendValuesTimer: null
}
},
computed: {
tableSource () {
return this.items.map(item => {
var nic = { ...item, disabled: this.validNetworks[item.id] && this.validNetworks[item.id].length === 0 }
nic.name = item.displaytext || item.name
return nic
})
},
rowSelection () {
if (this.selectionEnabled === true) {
return {
type: 'checkbox',
selectedRowKeys: this.selectedRowKeys,
getCheckboxProps: record => ({
props: {
disabled: record.disabled
}
}),
onChange: (rows) => {
this.selectedRowKeys = rows
this.sendValues()
}
}
}
return null
}
},
watch: {
items: {
deep: true,
handler () {
this.selectedRowKeys = []
this.fetchNetworks()
}
},
zoneId () {
this.fetchNetworks()
}
},
created () {
this.fetchNetworks()
},
methods: {
fetchNetworks () {
this.networks = []
if (!this.zoneId || this.zoneId.length === 0) {
return
}
this.loading = true
api('listNetworks', {
zoneid: this.zoneId,
listall: true
}).then(response => {
this.networks = response.listnetworksresponse.network || []
this.orderNetworks()
}).finally(() => {
this.loading = false
})
},
orderNetworks () {
this.loading = true
this.validNetworks = {}
for (const item of this.items) {
this.validNetworks[item.id] = this.networks
if (this.filterUnimplementedNetworks) {
this.validNetworks[item.id] = this.validNetworks[item.id].filter(x => (x.state === 'Implemented' || (x.state === 'Setup' && ['Shared', 'L2'].includes(x.type))))
}
if (this.filterMatchKey) {
const filtered = this.networks.filter(x => x[this.filterMatchKey] === item[this.filterMatchKey])
if (this.hypervisor === 'KVM') {
this.unableToMatch = filtered.length === 0
this.validNetworks[item.id] = filtered.length === 0 ? this.networks : filtered.concat(this.networks.filter(x => filtered.includes(x)))
} else {
this.validNetworks[item.id] = filtered
}
}
}
this.setDefaultValues()
this.loading = false
},
setIpAddressEnabled (nic, network) {
this.ipAddressesEnabled[nic.id] = network && network.type !== 'L2'
this.ipAddresses[nic.id] = (!network || network.type === 'L2') ? null : 'auto'
this.values[nic.id] = network ? network.id : null
this.indexNum = (this.indexNum % 2) + 1
},
setIpAddress (nicId, autoAssign, ipAddress) {
this.ipAddresses[nicId] = autoAssign ? 'auto' : ipAddress
this.sendValuesTimed()
},
setDefaultValues () {
this.values = {}
this.ipAddresses = {}
for (const item of this.items) {
var network = this.validNetworks[item.id]?.[0] || null
this.values[item.id] = network ? network.id : ''
this.ipAddresses[item.id] = (!network || network.type === 'L2') ? null : 'auto'
this.setIpAddressEnabled(item, network)
}
this.sendValuesTimed()
},
handleNetworkChange (nic, networkId) {
if (this.hypervisor === 'KVM') {
this.setIpAddressEnabled(nic, _.find(this.networks, (option) => option.id === networkId))
} else {
this.setIpAddressEnabled(nic, _.find(this.validNetworks[nic.id], (option) => option.id === networkId))
}
this.sendValuesTimed()
},
sendValuesTimed () {
clearTimeout(this.sendValuesTimer)
this.sendValuesTimer = setTimeout(() => {
this.sendValues(this.selectedScope)
}, 500)
},
sendValues () {
const data = {}
if (this.selectionEnabled) {
this.selectedRowKeys.map(x => {
var d = { network: this.values[x] }
if (this.ipAddresses[x]) {
d.ipAddress = this.ipAddresses[x]
}
data[x] = d
})
} else {
for (var x in this.values) {
var d = { network: this.values[x] }
if (this.ipAddresses[x] != null && this.ipAddresses[x] !== undefined) {
d.ipAddress = this.ipAddresses[x]
}
data[x] = d
}
}
this.$emit('select-multi-network', data)
}
}
}
</script>
<style lang="less" scoped>
.ant-table-wrapper {
margin: 2rem 0;
}
</style>