Repository navigation
UI: allow memory setting in flex compute offering in GiB with unit selector (#14082) #14413
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,23 +57,40 @@ | |
| </a-col> | ||
| <a-col :md="colContraned" :lg="colContraned" v-if="isCustomized"> | ||
| <a-form-item | ||
| :label="$t('label.memory.mb')" | ||
| :label="$t('label.memory')" | ||
| :validate-status="errors.memory.status" | ||
| :help="errors.memory.message"> | ||
| <a-row :gutter="12"> | ||
| <a-col :md="10" :lg="10" v-show="isConstrained && maxMemory && !isNaN(maxMemory)"> | ||
| <a-col :md="14" :lg="14" v-show="isConstrained && maxMemory && !isNaN(maxMemory)"> | ||
| <a-slider | ||
| :min="minMemory" | ||
| :max="maxMemory" | ||
| v-model:value="memoryInputValue" | ||
| :min="minMemoryInUnit" | ||
| :max="maxMemoryInUnit" | ||
| :step="memoryStep" | ||
| v-model:value="memoryDisplayValue" | ||
| @change="($event) => updateComputeMemory($event)" | ||
| /> | ||
| </a-col> | ||
| <a-col :md="4" :lg="4"> | ||
| <a-input-number | ||
| v-model:value="memoryInputValue" | ||
| @change="($event) => updateComputeMemory($event)" | ||
| /> | ||
| <a-col :md="isConstrained && maxMemory && !isNaN(maxMemory) ? 10 : 24" :lg="isConstrained && maxMemory && !isNaN(maxMemory) ? 10 : 24"> | ||
| <a-input-group compact style="display: flex"> | ||
| <a-tooltip :title="memoryTooltipText" placement="topLeft" style="flex: 1; display: flex"> | ||
| <a-input-number | ||
| style="width: 100%; min-width: 60px" | ||
| :min="isConstrained ? minMemoryInUnit : 0" | ||
| :max="isConstrained ? maxMemoryInUnit : undefined" | ||
| :step="memoryStep" | ||
| :precision="memoryUnit === 'GiB' ? 2 : 0" | ||
| v-model:value="memoryDisplayValue" | ||
| @change="($event) => updateComputeMemory($event)" | ||
| /> | ||
| </a-tooltip> | ||
| <a-select | ||
| v-model:value="memoryUnit" | ||
| style="width: 75px" | ||
| @change="handleUnitChange"> | ||
| <a-select-option value="GiB">GiB</a-select-option> | ||
| <a-select-option value="MiB">MiB</a-select-option> | ||
| </a-select> | ||
| </a-input-group> | ||
| </a-col> | ||
| </a-row> | ||
| </a-form-item> | ||
|
|
@@ -165,6 +182,8 @@ export default { | |
| cpuNumberInputValue: 0, | ||
| cpuSpeedInputValue: 0, | ||
| memoryInputValue: 0, | ||
| memoryDisplayValue: 0, | ||
| memoryUnit: 'GiB', | ||
| errors: { | ||
| cpu: { | ||
| status: '', | ||
|
|
@@ -192,6 +211,37 @@ export default { | |
| } | ||
|
|
||
| return 8 | ||
| }, | ||
| minMemoryInUnit () { | ||
| if (!this.minMemory) return 0 | ||
| if (this.memoryUnit === 'GiB') { | ||
| return Math.ceil(this.minMemory / 256) * 0.25 | ||
| } | ||
| return this.minMemory | ||
| }, | ||
| maxMemoryInUnit () { | ||
| if (!this.maxMemory) return 0 | ||
| if (this.memoryUnit === 'GiB') { | ||
| return Math.max(this.minMemoryInUnit, Math.floor(this.maxMemory / 256) * 0.25) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @saurabhkushwaha438 For custom offerings with a memory range like 2000-2300 MiB, the field is effectively restricted to 2.00 GiB when the unit is switched to GiB. The slider cannot be moved to any other value within the allowed range, preventing selection of valid memory sizes between 2000 MiB and 2300 MiB. |
||
| } | ||
| return this.maxMemory | ||
| }, | ||
| memoryStep () { | ||
| if (this.memoryUnit === 'GiB') { | ||
| return 0.25 | ||
| } | ||
| return 1 | ||
| }, | ||
| memoryTooltipText () { | ||
| if (!this.memoryInputValue) return '' | ||
| const exactGiB = this.memoryInputValue / 1024 | ||
| if (this.memoryUnit === 'GiB') { | ||
| if (this.memoryDisplayValue === exactGiB) { | ||
| return `${this.memoryDisplayValue} GiB = ${this.memoryInputValue} MiB` | ||
| } | ||
| return `Exact: ${exactGiB} GiB (${this.memoryInputValue} MiB)` | ||
| } | ||
| return `${this.memoryInputValue} MiB = ${exactGiB} GiB` | ||
| } | ||
| }, | ||
| watch: { | ||
|
|
@@ -209,13 +259,24 @@ export default { | |
| methods: { | ||
| fillValue () { | ||
| this.cpuNumberInputValue = this.initialCpuValue > 0 ? this.initialCpuValue : this.minCpu | ||
| this.memoryInputValue = this.initialMemoryValue > 0 ? this.initialMemoryValue : this.minMemory | ||
| const rawMemory = (this.preFillContent && this.preFillContent.memory) | ||
| ? this.preFillContent.memory | ||
| : (this.initialMemoryValue > 0 ? this.initialMemoryValue : this.minMemory) | ||
|
|
||
| // MiB is the authoritative internal state | ||
| this.memoryInputValue = rawMemory | ||
|
|
||
| // Default to GiB if rawMemory is a multiple of 256 MiB (exact 0.25 GiB increment) | ||
| const isQuarterGiB = rawMemory >= 256 && (rawMemory % 256 === 0) | ||
| this.memoryUnit = isQuarterGiB ? 'GiB' : 'MiB' | ||
| this.memoryDisplayValue = isQuarterGiB ? (rawMemory / 1024) : rawMemory | ||
|
|
||
| this.cpuSpeedInputValue = this.cpuSpeed | ||
|
|
||
| if (!this.preFillContent) { | ||
| this.updateComputeCpuNumber(this.cpuNumberInputValue) | ||
| this.updateComputeCpuSpeed(this.cpuSpeedInputValue) | ||
| this.updateComputeMemory(this.memoryInputValue) | ||
| this.$emit('update-compute-memory', this.memoryInputDecorator, this.memoryInputValue) | ||
| return | ||
| } | ||
| if (this.preFillContent.cpunumber) { | ||
|
|
@@ -224,12 +285,25 @@ export default { | |
| if (this.preFillContent.cpuspeed) { | ||
| this.cpuSpeedInputValue = this.preFillContent.cpuspeed | ||
| } | ||
| if (this.preFillContent.memory) { | ||
| this.memoryInputValue = this.preFillContent.memory | ||
| } | ||
|
|
||
| this.updateComputeCpuNumber(this.preFillContent.cpunumber || this.cpuNumberInputValue) | ||
| this.updateComputeCpuSpeed(this.preFillContent.cpuspeed || this.cpuSpeedInputValue) | ||
| this.updateComputeMemory(this.preFillContent.memory || this.memoryInputValue) | ||
| // Emit exact prefilled MiB without any conversion on load | ||
| this.$emit('update-compute-memory', this.memoryInputDecorator, this.memoryInputValue) | ||
| }, | ||
| handleUnitChange (newUnit) { | ||
| if (newUnit === 'MiB') { | ||
| this.memoryDisplayValue = this.memoryInputValue | ||
| } else { | ||
| this.memoryDisplayValue = Math.round(this.memoryInputValue / 256) * 0.25 | ||
| } | ||
| if (this.isConstrained) { | ||
| if (this.memoryDisplayValue < this.minMemoryInUnit) { | ||
| this.memoryDisplayValue = this.minMemoryInUnit | ||
| } else if (this.memoryDisplayValue > this.maxMemoryInUnit) { | ||
| this.memoryDisplayValue = this.maxMemoryInUnit | ||
| } | ||
| } | ||
| }, | ||
| updateComputeCpuNumber (value) { | ||
| if (!value) this.cpuNumberInputValue = 0 | ||
|
|
@@ -241,18 +315,37 @@ export default { | |
| updateComputeCpuSpeed (value) { | ||
| this.$emit('update-compute-cpuspeed', this.cpuSpeedInputDecorator, value) | ||
| }, | ||
| updateComputeMemory (value) { | ||
| if (!value) this.memoryInputValue = 0 | ||
| if (!this.validateInput('memory', value)) { | ||
| updateComputeMemory (displayValue) { | ||
| if (displayValue === null || displayValue === undefined || displayValue === '') { | ||
| this.memoryDisplayValue = 0 | ||
| this.memoryInputValue = 0 | ||
| } else { | ||
| this.memoryDisplayValue = displayValue | ||
| } | ||
| if (!this.validateInput('memory', displayValue)) { | ||
| return | ||
| } | ||
| this.$emit('update-compute-memory', this.memoryInputDecorator, value) | ||
| let memoryInMiB | ||
| if (this.memoryUnit === 'GiB') { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @saurabhkushwaha438 The memory field and its hover text show different amounts of memory value at the minimum and maximum of a constrained offering.
|
||
| if (this.isConstrained && displayValue === this.minMemoryInUnit) { | ||
| memoryInMiB = this.minMemory | ||
| } else if (this.isConstrained && displayValue === this.maxMemoryInUnit) { | ||
| memoryInMiB = this.maxMemory | ||
| } else { | ||
| memoryInMiB = Math.round(displayValue * 1024) | ||
| } | ||
| } else { | ||
| memoryInMiB = Math.round(displayValue) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @saurabhkushwaha438 Switching between MiB and GiB updates only the displayed memory value, while the deploy form continues to retain the previously entered MiB value. On an unconstrained custom offering:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks for pointing out this "Enter 100 MiB and then switch to GiB. The field displays 0 GiB, but instance creation still succeeds, and the deploy request sends 100 MiB, resulting in a VM being created with 100 MiB of memory."
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
hey i am not able reproduce this problem , could you attach screenshot of it |
||
| } | ||
|
|
||
| this.memoryInputValue = memoryInMiB | ||
| this.$emit('update-compute-memory', this.memoryInputDecorator, memoryInMiB) | ||
| }, | ||
| validateInput (input, value) { | ||
| this.errors[input].status = '' | ||
| this.errors[input].message = '' | ||
|
|
||
| if (value === null || value === undefined || value.length === 0) { | ||
| if (value === null || value === undefined || value.length === 0 || value === '' || value === 0) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @saurabhkushwaha438 Setting the CPU value to 0 does not clear the previously stored CPU count in the form. For example, after selecting a constrained offering, the form stores CPU = 2. When switching to an unconstrained custom offering, the CPU field displays 0 with the validation message "Please enter input". However, instance creation still proceeds successfully, and the VM is created with 2 CPUs, as the previously stored value is retained.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well this is not related to this issue |
||
| this.errors[input].status = 'error' | ||
| this.errors[input].message = this.$t('message.error.required.input') | ||
| return false | ||
|
|
@@ -271,8 +364,8 @@ export default { | |
| max = this.maxCpu | ||
| break | ||
| case 'memory': | ||
| min = this.minMemory | ||
| max = this.maxMemory | ||
| min = this.minMemoryInUnit | ||
| max = this.maxMemoryInUnit | ||
| break | ||
| } | ||
|
|
||
|
|
@@ -285,7 +378,8 @@ export default { | |
| return true | ||
| }, | ||
| checkValidRange (value, min, max) { | ||
| if (value < min || value > max) { | ||
| const epsilon = 0.001 | ||
| if (value < (min - epsilon) || value > (max + epsilon)) { | ||
| return false | ||
| } | ||
|
|
||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@saurabhkushwaha438 An out-of-range GiB value is rejected with "Invalid memory value, specify a value between 32 and 2147483647" and the message does not say the unit (MiB or GiB).
For example: 0.01 GiB is sent as 10 MiB and hits this error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think you can raise separate issue for that