From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 182518511 for ; Thu, 27 Jul 2023 11:53:57 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id EED179A71 for ; Thu, 27 Jul 2023 11:53:26 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Thu, 27 Jul 2023 11:53:26 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 1AAA240E31 for ; Thu, 27 Jul 2023 11:53:26 +0200 (CEST) From: Noel Ullreich To: pve-devel@lists.proxmox.com Date: Thu, 27 Jul 2023 11:53:12 +0200 Message-Id: <20230727095312.29713-2-n.ullreich@proxmox.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230727095312.29713-1-n.ullreich@proxmox.com> References: <20230727095312.29713-1-n.ullreich@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.093 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment POISEN_SPAM_PILL 0.1 Meta: its spam POISEN_SPAM_PILL_2 0.1 random spam to be learned in bayes POISEN_SPAM_PILL_4 0.1 random spam to be learned in bayes SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pve-devel] [PATCH widget-toolkit] ui: Extend BandwithSelector with selecatble units X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 Jul 2023 09:53:57 -0000 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 --- 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