Adding multi disk selection for supported templates

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
davidjumani 2020-09-24 19:53:31 +05:30 committed by Rohit Yadav
parent 39694aba8d
commit dcf482490c
4 changed files with 218 additions and 4 deletions

View File

@ -1466,6 +1466,7 @@
"label.no.grouping": "(no grouping)",
"label.no.isos": "No available ISOs",
"label.no.items": "No Available Items",
"label.no.matching.offering": "No matching offering found",
"label.no.security.groups": "No Available Security Groups",
"label.noderootdisksize": "Node root disk size (in GB)",
"label.nodiskcache": "No disk cache",

View File

@ -226,6 +226,21 @@
</template>
</a-step>
<a-step
:title="$t('label.data.disk')"
:status="zoneSelected ? 'process' : 'wait'"
v-if="!template.deployasis && template.childtemplates && template.childtemplates.length > 0" >
<template slot="description">
<div v-if="zoneSelected">
<multi-disk-selection
:items="template.childtemplates"
:diskOfferings="options.diskOfferings"
:zoneId="zoneId"
@select-multi-disk-offering="updateMultiDiskOffering($event)" />
</div>
</template>
</a-step>
<a-step
v-else
:title="tabKey == 'templateid' ? $t('label.data.disk') : $t('label.disk.size')"
:status="zoneSelected ? 'process' : 'wait'">
<template slot="description">
@ -607,6 +622,7 @@ import ComputeOfferingSelection from '@views/compute/wizard/ComputeOfferingSelec
import ComputeSelection from '@views/compute/wizard/ComputeSelection'
import DiskOfferingSelection from '@views/compute/wizard/DiskOfferingSelection'
import DiskSizeSelection from '@views/compute/wizard/DiskSizeSelection'
import MultiDiskSelection from '@views/compute/wizard/MultiDiskSelection'
import TemplateIsoSelection from '@views/compute/wizard/TemplateIsoSelection'
import AffinityGroupSelection from '@views/compute/wizard/AffinityGroupSelection'
import NetworkSelection from '@views/compute/wizard/NetworkSelection'
@ -623,6 +639,7 @@ export default {
AffinityGroupSelection,
TemplateIsoSelection,
DiskSizeSelection,
MultiDiskSelection,
DiskOfferingSelection,
InfoCard,
ComputeOfferingSelection,
@ -1040,7 +1057,11 @@ export default {
}
}
if (this.diskOffering) {
if (!this.template.deployasis && this.template.childtemplates && this.template.childtemplates.length > 0) {
this.vm.diskofferingid = ''
this.vm.diskofferingname = ''
this.vm.diskofferingsize = ''
} else if (this.diskOffering) {
this.vm.diskofferingid = this.diskOffering.id
this.vm.diskofferingname = this.diskOffering.displaytext
this.vm.diskofferingsize = this.diskOffering.disksize
@ -1072,6 +1093,7 @@ export default {
})
this.form.getFieldDecorator('computeofferingid', { initialValue: undefined, preserve: true })
this.form.getFieldDecorator('diskofferingid', { initialValue: undefined, preserve: true })
this.form.getFieldDecorator('multidiskoffering', { initialValue: undefined, preserve: true })
this.form.getFieldDecorator('affinitygroupids', { initialValue: [], preserve: true })
this.form.getFieldDecorator('networkids', { initialValue: [], preserve: true })
this.form.getFieldDecorator('keypair', { initialValue: undefined, preserve: true })
@ -1286,6 +1308,11 @@ export default {
diskofferingid: id
})
},
updateMultiDiskOffering (value) {
this.form.setFieldsValue({
multidiskoffering: value
})
},
updateAffinityGroups (ids) {
this.form.setFieldsValue({
affinitygroupids: ids
@ -1408,9 +1435,22 @@ export default {
deployVmData['details[0].configurationId'] = this.selectedTemplateConfiguration.id
}
// step 4: select disk offering
deployVmData.diskofferingid = values.diskofferingid
if (values.size) {
deployVmData.size = values.size
if (!this.template.deployasis && this.template.childtemplates && this.template.childtemplates.length > 0) {
if (values.multidiskoffering) {
let i = 0
Object.entries(values.multidiskoffering).forEach(([disk, offering]) => {
const diskKey = `datadiskofferinglist[${i}].datadisktemplateid`
const offeringKey = `datadiskofferinglist[${i}].diskofferingid`
deployVmData[diskKey] = disk
deployVmData[offeringKey] = offering
i++
})
}
} else {
deployVmData.diskofferingid = values.diskofferingid
if (values.size) {
deployVmData.size = values.size
}
}
// step 5: select an affinity group
deployVmData.affinitygroupids = (values.affinitygroupids || []).join(',')

View File

@ -133,6 +133,9 @@ export default {
},
created () {
this.initDataItem()
if (this.items) {
this.dataItems = this.dataItems.concat(this.items)
}
},
computed: {
tableSource () {

View File

@ -0,0 +1,170 @@
// 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 }" >
<span slot="offering" slot-scope="text, record">
<a-select
v-if="validOfferings[record.id] && validOfferings[record.id].length > 0"
@change="updateOffering($event, record.id)"
:defaultValue="validOfferings[record.id][0].id">
<a-select-option v-for="offering in validOfferings[record.id]" :key="offering.id">
{{ offering.displaytext }}
</a-select-option>
</a-select>
<span v-else>
{{ $t('label.no.matching.offering') }}
</span>
</span>
</a-table>
</div>
</template>
<script>
import { api } from '@/api'
export default {
name: 'MultiDiskSelection',
props: {
items: {
type: Array,
default: () => []
},
zoneId: {
type: String,
default: () => ''
}
},
data () {
return {
columns: [
{
dataIndex: 'name',
title: this.$t('label.data.disk')
},
{
dataIndex: 'offering',
title: this.$t('label.data.disk.offering'),
scopedSlots: { customRender: 'offering' }
}
],
loading: false,
selectedRowKeys: [],
diskOfferings: [],
validOfferings: {},
values: {}
}
},
computed: {
tableSource () {
return this.items.map(item => {
return {
id: item.id,
name: `${item.name} (${item.size} GB)`,
disabled: this.validOfferings[item.id] && this.validOfferings[item.id].length === 0
}
})
},
rowSelection () {
return {
type: 'checkbox',
selectedRowKeys: this.selectedRowKeys,
getCheckboxProps: record => ({
props: {
disabled: record.disabled
}
}),
onChange: (rows) => {
this.selectedRowKeys = rows
this.sendValues()
}
}
}
},
watch: {
items (newData, oldData) {
this.items = newData
this.selectedRowKeys = []
this.fetchDiskOfferings()
},
zoneId (newData) {
this.zoneId = newData
this.fetchDiskOfferings()
}
},
created () {
this.fetchDiskOfferings()
},
methods: {
fetchDiskOfferings () {
this.diskOfferings = []
this.loading = true
api('listDiskOfferings', {
zoneid: this.zoneId,
listall: true
}).then(response => {
this.diskOfferings = response.listdiskofferingsresponse.diskoffering || []
this.diskOfferings = this.diskOfferings.filter(x => !x.iscustomized)
this.orderDiskOfferings()
}).finally(() => {
this.loading = false
})
},
orderDiskOfferings () {
this.loading = true
this.validOfferings = {}
for (const item of this.items) {
this.validOfferings[item.id] = this.diskOfferings.filter(x => x.disksize >= item.size)
}
this.setDefaultValues()
this.loading = false
},
setDefaultValues () {
this.values = {}
for (const item of this.items) {
this.values[item.id] = this.validOfferings[item.id].length > 0 ? this.validOfferings[item.id][0].id : ''
}
},
updateOffering (value, templateid) {
this.values[templateid] = value
this.sendValues()
},
sendValues () {
const data = {}
this.selectedRowKeys.map(x => {
data[x] = this.values[x]
})
this.$emit('select-multi-disk-offering', data)
}
}
}
</script>
<style lang="less" scoped>
.ant-table-wrapper {
margin: 2rem 0;
}
</style>