@@ -7,21 +7,19 @@ import {
77import PropTypes from 'prop-types' ;
88
99import cockpit from 'cockpit' ;
10- import * as Select from 'cockpit-components-select.jsx' ;
1110import { ModalError } from 'cockpit-components-inline-notification.jsx' ;
1211import {
1312 units ,
1413 convertToUnit ,
15- toFixedPrecision ,
1614 vmId
1715} from '../../helpers.js' ;
16+ import MemorySelectRow from '../memorySelectRow.jsx' ;
1817import {
1918 setMemory ,
2019 setMaxMemory ,
2120 getVm
2221} from '../../actions/provider-actions.js' ;
2322
24- import './memoryModal.css' ;
2523import 'form-layout.less' ;
2624
2725const _ = cockpit . gettext ;
@@ -50,39 +48,24 @@ export class MemoryModal extends React.Component {
5048 const memoryKiB = convertToUnit ( value , this . state . memoryUnit , 'KiB' ) ;
5149
5250 if ( memoryKiB <= this . state . maxMemory ) {
53- stateDelta . memory = memoryKiB ;
51+ stateDelta . memory = Math . max ( memoryKiB , this . state . minAllowedMemory ) ;
5452 } else if ( memoryKiB > this . state . maxMemory && this . props . vm . state != 'running' ) {
55- stateDelta . memory = memoryKiB ;
56- stateDelta . maxMemory = memoryKiB ;
53+ stateDelta . memory = Math . min ( memoryKiB , this . state . nodeMaxMemory ) ;
54+ stateDelta . maxMemory = Math . min ( memoryKiB , this . state . nodeMaxMemory ) ;
5755 }
5856 } else if ( key == 'maxMemory' ) {
5957 const maxMemoryKiB = convertToUnit ( value , this . state . maxMemoryUnit , 'KiB' ) ;
6058
6159 if ( maxMemoryKiB < this . state . nodeMaxMemory ) {
62- stateDelta . maxMemory = maxMemoryKiB ;
60+ stateDelta . maxMemory = Math . max ( maxMemoryKiB , this . state . minAllowedMemory ) ;
61+ } else {
62+ stateDelta . maxMemory = this . state . nodeMaxMemory ;
6363 }
64- } else if ( key == 'memoryUnit' || key == 'maxMemoryUnit' )
65- stateDelta = { [ key ] : value } ;
66-
67- this . setState ( stateDelta ) ;
68- }
69-
70- onValueBlurred ( key , value ) {
71- // When input field get unfocused perform checks for lower limits
72- const stateDelta = { } ;
73-
74- if ( key == 'memory' ) {
75- const memoryKiB = convertToUnit ( value , this . state . memoryUnit , 'KiB' ) ;
76-
77- stateDelta . memory = Math . max ( memoryKiB , this . state . minAllowedMemory ) ;
78- } else if ( key == 'maxMemory' ) {
79- const maxMemoryKiB = convertToUnit ( value , this . state . maxMemoryUnit , 'KiB' ) ;
80-
81- stateDelta . maxMemory = Math . max ( maxMemoryKiB , this . state . minAllowedMemory ) ;
8264 if ( maxMemoryKiB < this . state . memory ) {
8365 stateDelta . memory = Math . max ( maxMemoryKiB , this . state . minAllowedMemory ) ;
8466 }
85- }
67+ } else if ( key == 'memoryUnit' || key == 'maxMemoryUnit' )
68+ stateDelta = { [ key ] : value } ;
8669
8770 this . setState ( stateDelta ) ;
8871 }
@@ -129,69 +112,27 @@ export class MemoryModal extends React.Component {
129112 < label className = 'control-label' >
130113 { _ ( "Current Allocation" ) }
131114 </ label >
132- < div className = 'form-group ct-validation-wrapper' >
133- < div role = 'group' >
134- < input id = { `${ idPrefix } -memory` }
135- className = 'form-control'
136- type = 'number'
137- value = { toFixedPrecision ( convertToUnit ( this . state . memory , 'KiB' , this . state . memoryUnit ) ) }
138- min = { toFixedPrecision ( convertToUnit ( 128 , 'MiB' , this . state . memoryUnit ) ) }
139- step = { 1 }
140- onChange = { e => this . onValueChanged ( 'memory' , e . target . value ) }
141- onClick = { e => { // releasing arrows does not trigger a seperate on blur event
142- this . onValueChanged ( 'memory' , e . target . value ) ;
143- this . onValueBlurred ( 'memory' , e . target . value ) ;
144- } }
145- onBlur = { e => this . onValueBlurred ( 'memory' , e . target . value ) } />
146- < Select . Select id = { `${ idPrefix } -memory-unit` }
147- initial = { this . state . memoryUnit }
148- onChange = { value => this . onValueChanged ( 'memoryUnit' , value ) } >
149- < Select . SelectEntry data = { units . MiB . name } key = { units . MiB . name } >
150- { _ ( "MiB" ) }
151- </ Select . SelectEntry >
152- < Select . SelectEntry data = { units . GiB . name } key = { units . GiB . name } >
153- { _ ( "GiB" ) }
154- </ Select . SelectEntry >
155- </ Select . Select >
156- </ div >
157- < HelpBlock >
158- { _ ( "Memory size between 128 MiB and the maximum allocation" ) }
159- </ HelpBlock >
160- </ div >
161-
115+ < MemorySelectRow id = { `${ idPrefix } -memory` }
116+ value = { Math . floor ( convertToUnit ( this . state . memory , 'KiB' , this . state . memoryUnit ) ) }
117+ minValue = { Math . floor ( convertToUnit ( this . state . minAllowedMemory , 'KiB' , this . state . memoryUnit ) ) }
118+ maxValue = { Math . floor ( convertToUnit ( this . state . maxMemory , 'KiB' , this . state . memoryUnit ) ) }
119+ initialUnit = { this . state . memoryUnit }
120+ onValueChange = { value => this . onValueChanged ( 'memory' , value ) }
121+ onUnitChange = { value => this . onValueChanged ( 'memoryUnit' , value ) } />
162122 < hr />
163123
164124 < label className = 'control-label' >
165125 { _ ( "Maximum Allocation" ) }
166126 </ label >
167127 < div className = 'form-group ct-validation-wrapper' >
168- < div role = 'group' >
169- < input id = { `${ idPrefix } -max-memory` }
170- className = 'form-control ct-form-split'
171- type = 'number'
172- value = { toFixedPrecision ( convertToUnit ( this . state . maxMemory , 'KiB' , this . state . memoryUnit ) ) }
173- min = { toFixedPrecision ( convertToUnit ( 128 , 'MiB' , this . state . maxMemoryUnit ) ) }
174- step = { 1 }
175- onChange = { e => this . onValueChanged ( 'maxMemory' , e . target . value ) }
176- onClick = { e => { // onInput does not trigger a seperate on blur event
177- this . onValueChanged ( 'maxMemory' , e . target . value ) ;
178- this . onValueBlurred ( 'maxMemory' , e . target . value ) ;
179- } }
180- onBlur = { e => this . onValueBlurred ( 'maxMemory' , e . target . value ) }
181- readOnly = { vm . state != 'shut off' } />
182- < Select . Select id = { `${ idPrefix } -max-memory-unit` }
183- className = 'ct-form-split'
184- initial = { this . state . maxMemoryUnit }
185- onChange = { value => this . onValueChanged ( 'maxMemoryUnit' , value ) }
186- enabled = { vm . state !== 'running' } >
187- < Select . SelectEntry data = { units . MiB . name } key = { units . MiB . name } >
188- { _ ( "MiB" ) }
189- </ Select . SelectEntry >
190- < Select . SelectEntry data = { units . GiB . name } key = { units . GiB . name } >
191- { _ ( "GiB" ) }
192- </ Select . SelectEntry >
193- </ Select . Select >
194- </ div >
128+ < MemorySelectRow id = { `${ idPrefix } -max-memory` }
129+ value = { Math . floor ( convertToUnit ( this . state . maxMemory , 'KiB' , this . state . maxMemoryUnit ) ) }
130+ minValue = { Math . floor ( convertToUnit ( this . state . minAllowedMemory , 'KiB' , this . state . maxMemoryUnit ) ) }
131+ maxValue = { Math . floor ( convertToUnit ( this . state . nodeMaxMemory , 'KiB' , this . state . maxMemoryUnit ) ) }
132+ initialUnit = { this . state . maxMemoryUnit }
133+ onValueChange = { value => this . onValueChanged ( 'maxMemory' , value ) }
134+ onUnitChange = { value => this . onValueChanged ( 'maxMemoryUnit' , value ) }
135+ readOnly = { vm . state != 'shut off' } />
195136 { vm . state === 'running' && < HelpBlock >
196137 { _ ( "Only editable when the guest is shut off" ) }
197138 </ HelpBlock > }
0 commit comments