* [pve-devel] [PATCH widget-toolkit] ui: Extend BandwithSelector with selecatble units
2023-07-27 9:53 [pve-devel] [PATCH widget-toolkit 0/1]ui: Extend BandwithSelector with selecatble units Noel Ullreich
@ 2023-07-27 9:53 ` Noel Ullreich
0 siblings, 0 replies; 2+ messages in thread
From: Noel Ullreich @ 2023-07-27 9:53 UTC (permalink / raw)
To: pve-devel
Work in progress! But today is my last day and I want to send what I have.
Comments and TODOS on what needs to still be done and what doesn't work
are inline.
Extends the BandwithSelector to add features:
* selectable units via dropdown menu
* pass lists of minvalues/stepsize (TODO: maxvalue) for each unit
* set flag to autoconvert units (E.g. 1024 MiB -> 1 GiB)
Signed-off-by: Noel Ullreich <n.ullreich@proxmox.com>
---
src/form/BandwidthSelector.js | 96 ++++++++++++++++++++++++++++++-----
1 file changed, 84 insertions(+), 12 deletions(-)
diff --git a/src/form/BandwidthSelector.js b/src/form/BandwidthSelector.js
index 434ab62..fae10b7 100644
--- a/src/form/BandwidthSelector.js
+++ b/src/form/BandwidthSelector.js
@@ -8,6 +8,8 @@ Ext.define('Proxmox.form.SizeField', {
data: {
unit: 'MiB',
unitPostfix: '',
+ step: 1,
+ min: 1,
},
formulas: {
unitlabel: (get) => get('unit') + get('unitPostfix'),
@@ -22,6 +24,7 @@ Ext.define('Proxmox.form.SizeField', {
},
// display unit (TODO: make (optionally) selectable)
+ unitname: 'unit',
unit: 'MiB',
unitPostfix: '',
@@ -37,6 +40,22 @@ Ext.define('Proxmox.form.SizeField', {
emptyValue: null,
+ // if using the same minimum value for all units, set it here. otherwise pass a minarray
+ minvalue: 1,
+ // to have different min values for different units, pass an array of min values
+ minarray: false,
+
+ // array of units that are selectable, doesn't have to be consecutive units
+ datastore: Object.keys(Proxmox.Utils.SizeUnits),
+
+ // if using the same stepsize for all units, set it here. otherwise pass a steparray
+ step: 1,
+ // to have different stepsizes for different units, pass an array of stepsizes
+ steparray: false,
+
+ // in the setvalue, auto scale the units. e.g. 1024MiB->1GiB
+ autoscale: true,
+
items: [
{
xtype: 'numberfield',
@@ -45,32 +64,45 @@ Ext.define('Proxmox.form.SizeField', {
emptyText: '{emptyText}',
allowZero: '{allowZero}',
emptyValue: '{emptyValue}',
+ step: '{step}',
+ autoscale: '{autoscale}',
+ datastore: '{datastore}',
+ steparray: '{steparray}',
+ minValue: '{minvalue}',
+ minarray: '{minarray}',
+
},
- minValue: 0,
- step: 1,
submitLocaleSeparator: false,
fieldStyle: 'text-align: right',
- flex: 1,
+ flex: 2,
enableKeyEvents: true,
setValue: function(v) {
if (!this._transformed) {
+ let me = this;
let fieldContainer = this.up('fieldcontainer');
let vm = fieldContainer.getViewModel();
- let unit = vm.get('unit');
if (typeof v === "string") {
v = Proxmox.Utils.size_unit_to_bytes(v);
}
- v /= Proxmox.Utils.SizeUnits[unit];
+ v /= Proxmox.Utils.SizeUnits[vm.get('unit')];
v *= fieldContainer.backendFactor;
+ if (me.autoscale) {
+ for (let key of me.datastore) {
+ if (v%(Proxmox.Utils.SizeUnits[key]/fieldContainer.backendFactor)===0) {
+ vm.set('unit', key);
+ }
+ }
+ v = v*fieldContainer.backendFactor/Proxmox.Utils.SizeUnits[vm.get('unit')];
+ }
+
this._transformed = true;
}
if (Number(v) === 0 && !this.allowZero) {
v = undefined;
}
-
return Ext.form.field.Text.prototype.setValue.call(this, v);
},
getSubmitValue: function() {
@@ -101,22 +133,62 @@ Ext.define('Proxmox.form.SizeField', {
// our setValue gets only called if we have a value, avoid
// transformation of the first user-entered value
keydown: function() { this._transformed = true; },
+ change: function(f, v) {
+ let me = this;
+
+ //TODO: atm this is called each time a value is changed,
+ // update step somehwere else?
+ if (me.steparray) {
+ me.step = f.up('fieldcontainer').getViewModel().get('step');
+ }
+ if (me.minarray) {
+ console.log(f.up('fieldcontainer').getViewModel().get('min'));
+ me.setMinValue(f.up('fieldcontainer').getViewModel().get('min'));
+ }
+ },
},
},
{
- xtype: 'displayfield',
- name: 'unit',
- submitValue: false,
- padding: '0 0 0 10',
+ xtype: 'combobox',
+ cbind: {
+ //TODO: not ideal, fish out values form store instead of
+ //`me.datastore.indexOf` below?
+ datastore: '{datastore}',
+ store: '{datastore}',
+ name: '{unitname}',
+ steparray: '{steparray}',
+ minarray: '{minarray}',
+ numberfieldName: '{name}',
+ },
+ itemId: 'unit',
+ flex: 1,
+ editable: false,
+ allowBlank: false,
+ //padding: '0 0 0 10',
bind: {
value: '{unitlabel}',
},
listeners: {
- change: (f, v) => {
+ change: function(f, v) {
+ let me = this;
f.originalValue = v;
+ f.up('fieldcontainer').getViewModel().set('unit', v);
+
+ // TODO: i don't know if making a viewmodel entry to change stepsize
+ // is the best idea. Ideally I'd like to directly change `me.step` in
+ // the valuefield directly, but me.down doesn't work with this layout.
+ // plus, we need to run a `validate` on the valuefield
+ // Is there a better way of doing this?
+ if (me.steparray) {
+ let sa = me.steparray[me.datastore.indexOf(v)];
+ f.up('fieldcontainer').getViewModel().set('step', sa);
+ }
+ if (me.minarray) {
+ let ma = me.minarray[me.datastore.indexOf(v)];
+ f.up('fieldcontainer').getViewModel().set('min', ma);
+ }
},
},
- width: 40,
},
],
--
2.39.2
^ permalink raw reply [flat|nested] 2+ messages in thread