This is an automated email from the ASF dual-hosted git repository.
shwstppr pushed a commit to branch 4.18
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.18 by this push:
new b09acb8fd05 UI: Fix deploy VM wizard vApp properties (#8072)
b09acb8fd05 is described below
commit b09acb8fd05d9b8bdf93bc817a95a1f4ed53af77
Author: Nicolas Vazquez <[email protected]>
AuthorDate: Wed Oct 25 01:58:42 2023 -0300
UI: Fix deploy VM wizard vApp properties (#8072)
This PR fixes the vApp properties values sent as part of the
deployVirtualMachine API through the UI
Fixes: #7998
---
ui/src/views/compute/DeployVM.vue | 125 ++++++++++++++++++++------------------
1 file changed, 65 insertions(+), 60 deletions(-)
diff --git a/ui/src/views/compute/DeployVM.vue
b/ui/src/views/compute/DeployVM.vue
index 5a962a37f36..9d07cb51db3 100644
--- a/ui/src/views/compute/DeployVM.vue
+++ b/ui/src/views/compute/DeployVM.vue
@@ -470,13 +470,13 @@
<span v-if="property.type &&
property.type==='boolean'">
<a-switch
- v-model:checked="form['properties.' +
escapePropertyKey(property.key)]"
+
v-model:checked="form.properties[escapePropertyKey(property.key)]"
:placeholder="property.description"
/>
</span>
<span v-else-if="property.type &&
(property.type==='int' || property.type==='real')">
<a-input-number
- v-model:value="form['properties.'+
escapePropertyKey(property.key)]"
+
v-model:value="form.properties[escapePropertyKey(property.key)]"
:placeholder="property.description"
:min="getPropertyQualifiers(property.qualifiers,
'number-select').min"
:max="getPropertyQualifiers(property.qualifiers,
'number-select').max" />
@@ -485,7 +485,7 @@
<a-select
showSearch
optionFilterProp="label"
- v-model:value="form['properties.' +
escapePropertyKey(property.key)]"
+
v-model:value="form.properties[escapePropertyKey(property.key)]"
:placeholder="property.description"
:filterOption="(input, option) => {
return
option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
@@ -498,12 +498,12 @@
</span>
<span v-else-if="property.type &&
property.type==='string' && property.password">
<a-input-password
- v-model:value="form['properties.' +
escapePropertyKey(property.key)]"
+
v-model:value="form.properties[escapePropertyKey(property.key)]"
:placeholder="property.description" />
</span>
<span v-else>
<a-input
- v-model:value="form['properties.' +
escapePropertyKey(property.key)]"
+
v-model:value="form.properties[escapePropertyKey(property.key)]"
:placeholder="property.description" />
</span>
</a-form-item>
@@ -1509,61 +1509,7 @@ export default {
})
}
- if (this.vm.templateid && this.templateProperties &&
Object.keys(this.templateProperties).length > 0) {
- this.templateProperties.forEach((props, category) => {
- props.forEach((property, propertyIndex) => {
- if (property.type && property.type === 'boolean') {
- this.form['properties.' +
this.escapePropertyKey(property.key)] = property.value === 'TRUE'
- } else if (property.type && (property.type === 'int' ||
property.type === 'real')) {
- this.form['properties.' +
this.escapePropertyKey(property.key)] = property.value
- } else if (property.type && property.type === 'string' &&
property.qualifiers && property.qualifiers.startsWith('ValueMap')) {
- this.form['properties.' +
this.escapePropertyKey(property.key)] = property.value && property.value.length
> 0
- ? property.value
- : this.getPropertyQualifiers(property.qualifiers,
'select')[0]
- } else if (property.type && property.type === 'string' &&
property.password) {
- this.form['properties.' +
this.escapePropertyKey(property.key)] = property.value
- this.rules['properties.' +
this.escapePropertyKey(property.key)] = [{
- validator: async (rule, value) => {
- if (!property.qualifiers) {
- return Promise.resolve()
- }
- var minlength =
this.getPropertyQualifiers(property.qualifiers, 'number-select').min
- var maxlength =
this.getPropertyQualifiers(property.qualifiers, 'number-select').max
- var errorMessage = ''
- var isPasswordInvalidLength = function () {
- return false
- }
- if (minlength) {
- errorMessage =
this.$t('message.validate.minlength').replace('{0}', minlength)
- isPasswordInvalidLength = function () {
- return !value || value.length < minlength
- }
- }
- if (maxlength !== Number.MAX_SAFE_INTEGER) {
- if (minlength) {
- errorMessage =
this.$t('message.validate.range.length').replace('{0}',
minlength).replace('{1}', maxlength)
- isPasswordInvalidLength = function () {
- return !value || (maxlength < value.length ||
value.length < minlength)
- }
- } else {
- errorMessage =
this.$t('message.validate.maxlength').replace('{0}', maxlength)
- isPasswordInvalidLength = function () {
- return !value || value.length > maxlength
- }
- }
- }
- if (isPasswordInvalidLength()) {
- return Promise.reject(errorMessage)
- }
- return Promise.resolve()
- }
- }]
- } else {
- this.form['properties.' +
this.escapePropertyKey(property.key)] = property.value
- }
- })
- })
- }
+ this.updateFormProperties()
if (this.vm.templateid && this.templateLicenses &&
this.templateLicenses.length > 0) {
this.rules.licensesaccepted = [{
@@ -2582,6 +2528,64 @@ export default {
this.dataPreFill.memory = params.memory
this.handleSearchFilter('serviceOfferings', params)
},
+ updateFormProperties () {
+ if (this.vm.templateid && this.templateProperties &&
Object.keys(this.templateProperties).length > 0) {
+ this.form.properties = {}
+ Object.keys(this.templateProperties).forEach((category, categoryIndex)
=> {
+ this.templateProperties[category].forEach((property, _) => {
+ if (property.type && property.type === 'boolean') {
+ this.form.properties[this.escapePropertyKey(property.key)] =
property.value === 'TRUE'
+ } else if (property.type && (property.type === 'int' ||
property.type === 'real')) {
+ this.form.properties[this.escapePropertyKey(property.key)] =
property.value
+ } else if (property.type && property.type === 'string' &&
property.qualifiers && property.qualifiers.startsWith('ValueMap')) {
+ this.form.properties[this.escapePropertyKey(property.key)] =
property.value && property.value.length > 0
+ ? property.value
+ : this.getPropertyQualifiers(property.qualifiers, 'select')[0]
+ } else if (property.type && property.type === 'string' &&
property.password) {
+ this.form.properties[this.escapePropertyKey(property.key)] =
property.value
+ this.rules['properties.' + this.escapePropertyKey(property.key)]
= [{
+ validator: async (rule, value) => {
+ if (!property.qualifiers) {
+ return Promise.resolve()
+ }
+ var minlength =
this.getPropertyQualifiers(property.qualifiers, 'number-select').min
+ var maxlength =
this.getPropertyQualifiers(property.qualifiers, 'number-select').max
+ var errorMessage = ''
+ var isPasswordInvalidLength = function () {
+ return false
+ }
+ if (minlength) {
+ errorMessage =
this.$t('message.validate.minlength').replace('{0}', minlength)
+ isPasswordInvalidLength = function () {
+ return !value || value.length < minlength
+ }
+ }
+ if (maxlength !== Number.MAX_SAFE_INTEGER) {
+ if (minlength) {
+ errorMessage =
this.$t('message.validate.range.length').replace('{0}',
minlength).replace('{1}', maxlength)
+ isPasswordInvalidLength = function () {
+ return !value || (maxlength < value.length ||
value.length < minlength)
+ }
+ } else {
+ errorMessage =
this.$t('message.validate.maxlength').replace('{0}', maxlength)
+ isPasswordInvalidLength = function () {
+ return !value || value.length > maxlength
+ }
+ }
+ }
+ if (isPasswordInvalidLength()) {
+ return Promise.reject(errorMessage)
+ }
+ return Promise.resolve()
+ }
+ }]
+ } else {
+ this.form.properties[this.escapePropertyKey(property.key)] =
property.value
+ }
+ })
+ })
+ }
+ },
updateTemplateParameters () {
if (this.template) {
this.templateNics = this.fetchTemplateNics(this.template)
@@ -2599,6 +2603,7 @@ export default {
this.updateComputeOffering(null) // reset as existing selection
may be incompatible
}
}, 500)
+ this.updateFormProperties()
}
},
onSelectTemplateConfigurationId (value) {