public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH manager 0/2] ui: vCPU flag editor: switch radio group approach to segmented button
@ 2026-05-25 13:15 Thomas Lamprecht
  2026-05-25 13:15 ` [PATCH manager 1/2] ui: vCPU flag selector: replace radio group with " Thomas Lamprecht
  2026-05-25 13:15 ` [PATCH manager 2/2] ui: vCPU flag selector: re-enable sortable columns Thomas Lamprecht
  0 siblings, 2 replies; 5+ messages in thread
From: Thomas Lamprecht @ 2026-05-25 13:15 UTC (permalink / raw)
  To: pve-devel

Replace the status and three-radio-button columns with a unified
segmented button one. See actual patches for details.

Thomas Lamprecht (2):
  ui: vCPU flag selector: replace radio group with segmented button
  ui: vCPU flag selector: re-enable sortable columns

 www/manager6/form/VMCPUFlagSelector.js | 69 +++++++-------------------
 1 file changed, 18 insertions(+), 51 deletions(-)

-- 
2.47.3





^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH manager 1/2] ui: vCPU flag selector: replace radio group with segmented button
  2026-05-25 13:15 [PATCH manager 0/2] ui: vCPU flag editor: switch radio group approach to segmented button Thomas Lamprecht
@ 2026-05-25 13:15 ` Thomas Lamprecht
  2026-05-26  6:02   ` Arthur Bied-Charreton
  2026-05-25 13:15 ` [PATCH manager 2/2] ui: vCPU flag selector: re-enable sortable columns Thomas Lamprecht
  1 sibling, 1 reply; 5+ messages in thread
From: Thomas Lamprecht @ 2026-05-25 13:15 UTC (permalink / raw)
  To: pve-devel

The per-flag state used a radio group of three single-character
options (- force-off, = default, + force-on) alongside a separate
read-only "State" column that re-rendered the same value as Off,
Default, or On. That was a bit cramped and also not the best UX.

Use one segmented button labeled Off/Default/On that both shows and
sets the state, and drop the now-superfluous text column. A segmented
button also reports a plain value to its change listener instead of
the radio group's keyed object, simplifying the dirty-tracking
handler.

The classic Ext.button.Segmented already existed in ExtJS 6.0.1, the
version PVE shipped when I added this selector back in 06064872c
("gui: vm: add CPU flag selector with tri-state awareness"), not
really sure though why I did not favor it over the radio group
approach.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
 www/manager6/form/VMCPUFlagSelector.js | 66 +++++++-------------------
 1 file changed, 18 insertions(+), 48 deletions(-)

diff --git a/www/manager6/form/VMCPUFlagSelector.js b/www/manager6/form/VMCPUFlagSelector.js
index d4adbc0f5..5972ee678 100644
--- a/www/manager6/form/VMCPUFlagSelector.js
+++ b/www/manager6/form/VMCPUFlagSelector.js
@@ -216,68 +216,38 @@ Ext.define('PVE.form.VMCPUFlagSelector', {
         return res;
     },
     columns: [
-        {
-            text: gettext('State'),
-            dataIndex: 'state',
-            renderer: function (v) {
-                switch (v) {
-                    case '=':
-                        return 'Default';
-                    case '-':
-                        return 'Off';
-                    case '+':
-                        return 'On';
-                    default:
-                        return 'Unknown';
-                }
-            },
-            width: 65,
-        },
         {
             text: gettext('Value'),
             xtype: 'widgetcolumn',
             dataIndex: 'state',
-            width: 95,
+            width: 200,
             onWidgetAttach: function (column, widget, record) {
-                let val = record.get('state') || '=';
-                widget.down('[inputValue=' + val + ']').setValue(true);
+                widget.setValue(record.get('state') || '=');
                 // TODO: disable if selected CPU model and flag are incompatible
             },
             widget: {
-                xtype: 'radiogroup',
-                hideLabel: true,
-                layout: 'hbox',
-                validateOnChange: false,
+                xtype: 'segmentedbutton',
+                allowMultiple: false,
+                defaultUI: 'default-toolbar',
                 value: '=',
+                items: [
+                    { text: gettext('Off'), value: '-', width: 50 },
+                    { text: gettext('Default'), value: '=', width: 90 },
+                    { text: gettext('On'), value: '+', width: 50 },
+                ],
                 listeners: {
                     change: function (f, value) {
-                        let v = Object.values(value)[0];
-                        f.getWidgetRecord().set('state', v);
+                        let rec = f.getWidgetRecord();
+                        if (!rec) {
+                            return;
+                        }
+                        rec.set('state', value);
 
-                        let view = this.up('grid');
-                        view.dirty = view.getValue() !== view.originalValue;
-                        view.checkDirty();
-                        //view.checkChange();
+                        let grid = f.up('grid');
+                        grid.dirty = grid.getValue() !== grid.originalValue;
+                        grid.checkDirty();
                     },
                 },
-                items: [
-                    {
-                        boxLabel: '-',
-                        boxLabelAlign: 'before',
-                        inputValue: '-',
-                        isFormField: false,
-                    },
-                    {
-                        checked: true,
-                        inputValue: '=',
-                        isFormField: false,
-                    },
-                    {
-                        boxLabel: '+',
-                        inputValue: '+',
-                        isFormField: false,
-                    },
-                ],
             },
         },
         {
-- 
2.47.3





^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH manager 2/2] ui: vCPU flag selector: re-enable sortable columns
  2026-05-25 13:15 [PATCH manager 0/2] ui: vCPU flag editor: switch radio group approach to segmented button Thomas Lamprecht
  2026-05-25 13:15 ` [PATCH manager 1/2] ui: vCPU flag selector: replace radio group with " Thomas Lamprecht
@ 2026-05-25 13:15 ` Thomas Lamprecht
  2026-05-26  5:49   ` Arthur Bied-Charreton
  1 sibling, 1 reply; 5+ messages in thread
From: Thomas Lamprecht @ 2026-05-25 13:15 UTC (permalink / raw)
  To: pve-devel

The preceding commit replaced the radio widgets, whose inputs went
stale in reordered rows, with segmented buttons that re-sync on widget
attach. As that was the only reason sorting was disabled as a
stop-gap, we can drop that again.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
 www/manager6/form/VMCPUFlagSelector.js | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/www/manager6/form/VMCPUFlagSelector.js b/www/manager6/form/VMCPUFlagSelector.js
index 5972ee678..9cd076166 100644
--- a/www/manager6/form/VMCPUFlagSelector.js
+++ b/www/manager6/form/VMCPUFlagSelector.js
@@ -4,9 +4,6 @@ Ext.define('PVE.form.VMCPUFlagSelector', {
 
     bufferedRenderer: false,
 
-    // FIXME: stop-gap; sorting caused glitches with the inputs of radio widgets in moved rows.
-    sortableColumns: false,
-
     mixins: {
         field: 'Ext.form.field.Field',
     },
-- 
2.47.3





^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH manager 2/2] ui: vCPU flag selector: re-enable sortable columns
  2026-05-25 13:15 ` [PATCH manager 2/2] ui: vCPU flag selector: re-enable sortable columns Thomas Lamprecht
@ 2026-05-26  5:49   ` Arthur Bied-Charreton
  0 siblings, 0 replies; 5+ messages in thread
From: Arthur Bied-Charreton @ 2026-05-26  5:49 UTC (permalink / raw)
  To: Thomas Lamprecht; +Cc: pve-devel

On Mon, May 25, 2026 at 03:15:26PM +0200, Thomas Lamprecht wrote:
> The preceding commit replaced the radio widgets, whose inputs went
> stale in reordered rows, with segmented buttons that re-sync on widget
> attach. As that was the only reason sorting was disabled as a
> stop-gap, we can drop that again.
> 
> Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
> ---
>  www/manager6/form/VMCPUFlagSelector.js | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/www/manager6/form/VMCPUFlagSelector.js b/www/manager6/form/VMCPUFlagSelector.js
> index 5972ee678..9cd076166 100644
> --- a/www/manager6/form/VMCPUFlagSelector.js
> +++ b/www/manager6/form/VMCPUFlagSelector.js
> @@ -4,9 +4,6 @@ Ext.define('PVE.form.VMCPUFlagSelector', {
>  
>      bufferedRenderer: false,
>  
> -    // FIXME: stop-gap; sorting caused glitches with the inputs of radio widgets in moved rows.
> -    sortableColumns: false,
> -
>      mixins: {
>          field: 'Ext.form.field.Field',
>      },
> -- 
> 2.47.3
> 
Did you intend to make the flags sortable by state? Ext.js does not seem
to enable sorting by default on widgetcolumns (at least the examples in
the docs [0] are also not sortable).

If yes (I think such a sort would be helpful to see which flags are
enabled), we would need to add sortable: true to the "Value" column. 

[0] https://docs.sencha.com/extjs/7.0.0/guides/components/widgets_widgets_columns.html




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH manager 1/2] ui: vCPU flag selector: replace radio group with segmented button
  2026-05-25 13:15 ` [PATCH manager 1/2] ui: vCPU flag selector: replace radio group with " Thomas Lamprecht
@ 2026-05-26  6:02   ` Arthur Bied-Charreton
  0 siblings, 0 replies; 5+ messages in thread
From: Arthur Bied-Charreton @ 2026-05-26  6:02 UTC (permalink / raw)
  To: Thomas Lamprecht; +Cc: pve-devel

On Mon, May 25, 2026 at 03:15:25PM +0200, Thomas Lamprecht wrote:
> The per-flag state used a radio group of three single-character
> options (- force-off, = default, + force-on) alongside a separate
> read-only "State" column that re-rendered the same value as Off,
> Default, or On. That was a bit cramped and also not the best UX.
> 
> Use one segmented button labeled Off/Default/On that both shows and
> sets the state, and drop the now-superfluous text column. A segmented
> button also reports a plain value to its change listener instead of
> the radio group's keyed object, simplifying the dirty-tracking
> handler.
> 
> The classic Ext.button.Segmented already existed in ExtJS 6.0.1, the
> version PVE shipped when I added this selector back in 06064872c
> ("gui: vm: add CPU flag selector with tri-state awareness"), not
> really sure though why I did not favor it over the radio group
> approach.
> 
> Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Looks good! I also profiled this with the Bitwarden extension enabled 
[0] and it looks like it works a lot better with segmented buttons. 

One comment inline, with that addressed consider this:

Reviewed-by: Arthur Bied-Charreton <a.bied-charreton@proxmox.com>
Tested-by: Arthur Bied-Charreton <a.bied-charreton@proxmox.com>

[0] https://share.firefox.dev/4tYqt21
> ---
>  www/manager6/form/VMCPUFlagSelector.js | 66 +++++++-------------------
>  1 file changed, 18 insertions(+), 48 deletions(-)
> 
> diff --git a/www/manager6/form/VMCPUFlagSelector.js b/www/manager6/form/VMCPUFlagSelector.js
> index d4adbc0f5..5972ee678 100644
> --- a/www/manager6/form/VMCPUFlagSelector.js
> +++ b/www/manager6/form/VMCPUFlagSelector.js
> @@ -216,68 +216,38 @@ Ext.define('PVE.form.VMCPUFlagSelector', {
>          return res;
>      },
>      columns: [
> -        {
> -            text: gettext('State'),
> -            dataIndex: 'state',
> -            renderer: function (v) {
> -                switch (v) {
> -                    case '=':
> -                        return 'Default';
> -                    case '-':
> -                        return 'Off';
> -                    case '+':
> -                        return 'On';
> -                    default:
> -                        return 'Unknown';
> -                }
> -            },
> -            width: 65,
> -        },
>          {
>              text: gettext('Value'),
>              xtype: 'widgetcolumn',
>              dataIndex: 'state',
As mentioned in my answer to your other commit [1], we would need a
sortable: true here if we want the flags to be sortable by state, which
I think would be helpful. 

[1] https://lore.proxmox.com/pve-devel/g745uimm7nvpgvwomleawpklz2qst4saexjvd6syxv67s2jxa4@vhmlqwx5q6yb/
> -            width: 95,
> +            width: 200,
>              onWidgetAttach: function (column, widget, record) {
> -                let val = record.get('state') || '=';
> -                widget.down('[inputValue=' + val + ']').setValue(true);
> +                widget.setValue(record.get('state') || '=');
>                  // TODO: disable if selected CPU model and flag are incompatible
>              },
[...]




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-05-26  6:03 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-25 13:15 [PATCH manager 0/2] ui: vCPU flag editor: switch radio group approach to segmented button Thomas Lamprecht
2026-05-25 13:15 ` [PATCH manager 1/2] ui: vCPU flag selector: replace radio group with " Thomas Lamprecht
2026-05-26  6:02   ` Arthur Bied-Charreton
2026-05-25 13:15 ` [PATCH manager 2/2] ui: vCPU flag selector: re-enable sortable columns Thomas Lamprecht
2026-05-26  5:49   ` Arthur Bied-Charreton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal