ui: fix add network offering for vpc (#5809)

* ui: fix add network offering for vpc

Fixes issues with form related to supported services provider and router service offering when offering to be created for VPC.

Fixes #5807

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix issues getting with making select element update on options change (loop infinity) (#72)

* fixes

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

Co-authored-by: Hoang Nguyen <hoangnm@unitech.vn>
This commit is contained in:
Abhishek Kumar 2021-12-30 16:26:54 +05:30 committed by GitHub
parent eb04a46541
commit d7a9873053
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 58 deletions

View File

@ -20,7 +20,6 @@
<a-row :gutter="6">
<a-col :md="24" :lg="layout === 'horizontal' ? 12 : 24">
<a-checkbox
v-decorator="[checkBoxDecorator, {}]"
:checked="checked"
@change="handleCheckChange">
{{ checkBoxLabel }}
@ -31,8 +30,7 @@
v-if="reversed != checked"
:label="selectLabel">
<a-select
v-decorator="[selectDecorator, { initialValue: selectedOption ? selectedOption : getSelectInitialValue()}]"
:defaultValue="selectDecorator ? undefined : selectedOption ? selectedOption : getSelectInitialValue()"
v-model="selectedOption"
showSearch
optionFilterProp="children"
:filterOption="(input, option) => {
@ -69,10 +67,6 @@ export default {
type: String,
required: true
},
checkBoxDecorator: {
type: String,
default: ''
},
defaultCheckBoxValue: {
type: Boolean,
default: false
@ -85,10 +79,6 @@ export default {
type: String,
default: ''
},
selectDecorator: {
type: String,
default: ''
},
reversed: {
type: Boolean,
default: false
@ -97,12 +87,21 @@ export default {
data () {
return {
checked: false,
selectedOption: null
selectedOption: null,
selectOptionsTimer: null
}
},
created () {
this.checked = this.defaultCheckBoxValue
},
watch: {
selectOptions () {
clearTimeout(this.selectOptionsTimer)
this.selectOptionsTimer = setTimeout(() => {
this.handleSelectOptionsUpdated()
}, 50)
}
},
computed: {
selectSource () {
return this.selectOptions.map(item => {
@ -118,18 +117,23 @@ export default {
arrayHasItems (array) {
return array !== null && array !== undefined && Array.isArray(array) && array.length > 0
},
getSelectInitialValue () {
const initialValue = this.selectSource?.filter(x => x.enabled !== false)?.[0]?.id || ''
this.handleSelectChange(initialValue)
return initialValue
},
handleCheckChange (e) {
this.checked = e.target.checked
if (this.checked && !this.selectedOption) {
this.selectedOption = this.selectSource?.filter(x => x.enabled !== false)?.[0]?.id || null
}
this.$emit('handle-checkselectpair-change', this.resourceKey, this.checked, this.selectedOption)
},
handleSelectChange (val) {
this.selectedOption = val
this.$emit('handle-checkselectpair-change', this.resourceKey, this.checked, this.selectedOption)
},
handleSelectOptionsUpdated () {
if (!this.checked) return
var enabledOptions = this.selectSource?.filter(x => x.enabled !== false) || []
if (this.selectedOption && !enabledOptions.includes(this.selectedOption)) {
this.handleSelectChange(enabledOptions[0]?.id || null)
}
}
}
}

View File

@ -89,25 +89,11 @@
</a-row>
<a-form-item v-if="guestType === 'isolated'">
<tooltip-label slot="label" :title="$t('label.vpc')" :tooltip="apiParams.forvpc.description"/>
<a-switch v-decorator="['forvpc', {initialValue: forVpc}]" :defaultChecked="forVpc" @change="val => { handleForVpcChange(val) }" />
<a-switch v-decorator="['forvpc']" :checked="forVpc" @change="val => { handleForVpcChange(val) }" />
</a-form-item>
<a-form-item :label="$t('label.userdatal2')" v-if="guestType === 'l2'">
<a-switch v-decorator="['userdatal2', {initialValue: false}]" />
</a-form-item>
<a-form-item :label="$t('label.lbtype')" v-if="forVpc && lbServiceChecked">
<a-radio-group
v-decorator="[' ', {
initialValue: 'publicLb'
}]"
buttonStyle="solid">
<a-radio-button value="publicLb">
{{ $t('label.public.lb') }}
</a-radio-button>
<a-radio-button value="internalLb">
{{ $t('label.internal.lb') }}
</a-radio-button>
</a-radio-group>
</a-form-item>
<a-row :gutter="12">
<a-col :md="12" :lg="12">
<a-form-item>
@ -202,15 +188,28 @@
v-decorator="['service.'+item.name, {}]"
:resourceKey="item.name"
:checkBoxLabel="item.description"
:checkBoxDecorator="'service.' + item.name"
:selectOptions="item.provider"
:selectDecorator="item.name + '.provider'"
:selectOptions="!supportedServiceLoading ? item.provider: []"
@handle-checkselectpair-change="handleSupportedServiceChange"/>
</a-list-item>
</a-list>
</div>
</a-form-item>
<a-form-item v-if="isVirtualRouterForAtLeastOneService">
<a-form-item :label="$t('label.lbtype')" v-if="forVpc && lbServiceChecked">
<a-radio-group
v-decorator="['lbType', {
initialValue: lbType
}]"
buttonStyle="solid"
@change="e => { handleLbTypeChange(e.target.value) }" >
<a-radio-button value="publicLb">
{{ $t('label.public.lb') }}
</a-radio-button>
<a-radio-button value="internalLb">
{{ $t('label.internal.lb') }}
</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item v-if="isVirtualRouterForAtLeastOneService || isVpcVirtualRouterForAtLeastOneService">
<tooltip-label slot="label" :title="$t('label.serviceofferingid')" :tooltip="apiParams.serviceofferingid.description"/>
<a-select
v-decorator="['serviceofferingid', {
@ -453,6 +452,7 @@ export default {
selectedDomains: [],
selectedZones: [],
forVpc: false,
lbType: 'publicLb',
macLearningValue: '',
supportedServices: [],
supportedServiceLoading: false,
@ -463,6 +463,8 @@ export default {
sourceNatServiceChecked: false,
lbServiceChecked: false,
lbServiceProvider: '',
registeredServicePackages: [],
registeredServicePackageLoading: false,
isElasticIp: false,
staticNatServiceChecked: false,
staticNatServiceProvider: '',
@ -531,6 +533,27 @@ export default {
},
handleGuestTypeChange (val) {
this.guestType = val
if (val === 'l2') {
this.forVpc = false
this.lbType = 'publicLb'
this.isVirtualRouterForAtLeastOneService = false
this.isVpcVirtualRouterForAtLeastOneService = false
this.serviceOfferings = []
this.serviceOfferingLoading = false
this.sourceNatServiceChecked = false
this.lbServiceChecked = false
this.lbServiceProvider = ''
this.registeredServicePackages = []
this.registeredServicePackageLoading = false
this.isElasticIp = false
this.staticNatServiceChecked = false
this.staticNatServiceProvider = ''
this.connectivityServiceChecked = false
this.firewallServiceChecked = false
this.firewallServiceProvider = ''
this.selectedServiceProviderMap = {}
this.updateSupportedServices()
}
},
fetchSupportedServiceData () {
const params = {}
@ -594,18 +617,21 @@ export default {
this.supportedServices[i].provider = providers
this.supportedServices[i].description = serviceDisplayName
}
}).finally(() => {
this.supportedServiceLoading = false
this.updateSupportedServices()
})
},
fetchServiceOfferingData () {
const params = {}
params.issystem = true
params.systemvmtype = 'domainrouter'
this.supportedServiceLoading = true
this.serviceOfferingLoading = true
api('listServiceOfferings', params).then(json => {
const listServiceOfferings = json.listserviceofferingsresponse.serviceoffering
this.serviceOfferings = this.serviceOfferings.concat(listServiceOfferings)
}).finally(() => {
this.supportedServiceLoading = false
this.serviceOfferingLoading = false
})
},
fetchRegisteredServicePackageData () {
@ -627,32 +653,41 @@ export default {
this.registeredServicePackageLoading = false
})
},
handleForVpcChange (forVpc) {
updateSupportedServices () {
this.supportedServiceLoading = true
var supportedServices = this.supportedServices
var self = this
this.forVpc = forVpc
this.supportedServices.forEach(function (svc, index) {
if (svc !== 'Connectivity') {
supportedServices.forEach(function (svc, index) {
if (svc.name !== 'Connectivity') {
var providers = svc.provider
providers.forEach(function (provider, providerIndex) {
if (self.forVpc) { // *** vpc ***
if (provider.name === 'InternalLbVm' || provider.name === 'VpcVirtualRouter' || provider.name === 'Netscaler' || provider.name === 'BigSwitchBcf' || provider.name === 'ConfigDrive') {
provider.enabled = true
} else {
provider.enabled = false
var enabledProviders = ['VpcVirtualRouter', 'Netscaler', 'BigSwitchBcf', 'ConfigDrive']
if (self.lbType === 'internalLb') {
enabledProviders.push('InternalLbVm')
}
provider.enabled = enabledProviders.includes(provider.name)
} else { // *** non-vpc ***
if (provider.name === 'InternalLbVm' || provider.name === 'VpcVirtualRouter') {
provider.enabled = false
} else {
provider.enabled = true
}
provider.enabled = !['InternalLbVm', 'VpcVirtualRouter'].includes(provider.name)
}
providers[providerIndex] = provider
})
svc.provider = providers
self.supportedServices[index] = svc
supportedServices[index] = svc
}
})
setTimeout(() => {
self.supportedServices = supportedServices
self.supportedServiceLoading = false
}, 50)
},
handleForVpcChange (forVpc) {
this.forVpc = forVpc
this.updateSupportedServices()
},
handleLbTypeChange (lbType) {
this.lbType = lbType
this.updateSupportedServices()
},
handleSupportedServiceChange (service, checked, provider) {
if (service === 'SourceNat') {
@ -696,13 +731,14 @@ export default {
providers.forEach(function (prvdr, idx) {
if (prvdr === 'VirtualRouter') {
self.isVirtualRouterForAtLeastOneService = true
if (self.serviceOfferings.length === 0) {
self.fetchServiceOfferingData()
}
}
if (prvdr === 'VpcVirtualRouter') {
self.isVpcVirtualRouterForAtLeastOneService = true
}
if ((self.isVirtualRouterForAtLeastOneService || self.isVpcVirtualRouterForAtLeastOneService) &&
self.serviceOfferings.length === 0) {
self.fetchServiceOfferingData()
}
})
},
handleSubmit (e) {
@ -724,7 +760,7 @@ export default {
var selectedServices = null
var keys = Object.keys(values)
const detailsKey = ['promiscuousmode', 'macaddresschanges', 'forgedtransmits', 'maclearning']
const ignoredKeys = [...detailsKey, 'state', 'status', 'allocationstate', 'forvpc', 'specifyvlan', 'ispublic', 'domainid', 'zoneid', 'egressdefaultpolicy', 'isolation', 'supportspublicaccess']
const ignoredKeys = [...detailsKey, 'state', 'status', 'allocationstate', 'forvpc', 'lbType', 'specifyvlan', 'ispublic', 'domainid', 'zoneid', 'egressdefaultpolicy', 'isolation', 'supportspublicaccess']
keys.forEach(function (key, keyIndex) {
if (self.isSupportedServiceObject(values[key])) {
if (selectedServices == null) {

View File

@ -48,9 +48,7 @@
v-decorator="['service.'+item.name, {}]"
:resourceKey="item.name"
:checkBoxLabel="item.description"
:checkBoxDecorator="'service.' + item.name"
:selectOptions="item.provider"
:selectDecorator="item.name + '.provider'"
@handle-checkselectpair-change="handleSupportedServiceChange"/>
</a-list-item>
</a-list>