public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH widget-toolkit/pve-manager] move node selection into combogrid
@ 2023-01-18 13:12 Dominik Csapak
  2023-01-18 13:12 ` [pve-devel] [PATCH widget-toolkit 1/2] ComboGrid: use the grids view for the error message Dominik Csapak
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-01-18 13:12 UTC (permalink / raw)
  To: pve-devel

instead of having it as a seperate input on storage creation.
This aims to reduce confusion about what it exactly is and how it
interacts with the rest of the input fields.

With this series, it sits in a toolbar of the relevant dropdown, which
were converted to combogrids. The selection box is only shown if the
number of nodes in the cluster is greater than one.

for accomodating the toolbar, we have to make 2 slight adaptions to the
combogrid

patch 3,4,5,6 of pve-manager are mostly cleanups and are not strictly
necessary for this series to work, but since i touched the files anyway,
i converted them to our 'modern' js style

The cleanups come after the change, because thats the order in which i wrote
it. If wanted i can send the cleanups seperately for the current master,
and rebase the changes for the node selection on top.

proxmox-widget-toolkit:

Dominik Csapak (2):
  ComboGrid: use the grids view for the error message
  ComboGrid: make height for the error configurable

 src/form/ComboGrid.js | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

pve-manager:

Dominik Csapak (6):
  ui: StorageScanNodeSelector: use null as empty value
  ui: storage: move node scan selector inside combobox
  ui: storage/LvmThinInputPanel: modernize & cleanup code
  ui: storage/IScsiInputPanel: modernize, cleanup & improve panel
  ui: storage/ZFSPoolInputPanel: modernize & cleanup code
  ui: storage/LVMInputPanel: modernize & cleanup code

 www/manager6/form/ComboBoxSetStoreNode.js    |  45 +++-
 www/manager6/form/StorageScanNodeSelector.js |   8 +-
 www/manager6/storage/IScsiEdit.js            | 129 +++++++-----
 www/manager6/storage/LVMEdit.js              | 209 +++++++++++--------
 www/manager6/storage/LvmThinEdit.js          | 150 +++++++------
 www/manager6/storage/ZFSPoolEdit.js          | 100 +++++----
 6 files changed, 361 insertions(+), 280 deletions(-)

-- 
2.30.2





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

* [pve-devel] [PATCH widget-toolkit 1/2] ComboGrid: use the grids view for the error message
  2023-01-18 13:12 [pve-devel] [PATCH widget-toolkit/pve-manager] move node selection into combogrid Dominik Csapak
@ 2023-01-18 13:12 ` Dominik Csapak
  2023-01-18 13:12 ` [pve-devel] [PATCH widget-toolkit 2/2] ComboGrid: make height for the error configurable Dominik Csapak
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-01-18 13:12 UTC (permalink / raw)
  To: pve-devel

for most of the combogrids, this does not make a difference, but we
want to have a node selection in some of their toolbars. There
having the error over the whole grid makes it impossible to select a
different node (which might be necessary to get rid of the error), so
we show the error on the view (which is the grids content body only).

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/form/ComboGrid.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/form/ComboGrid.js b/src/form/ComboGrid.js
index 4cb79d0..e903223 100644
--- a/src/form/ComboGrid.js
+++ b/src/form/ComboGrid.js
@@ -306,7 +306,7 @@ Ext.define('Proxmox.form.ComboGrid', {
 		picker.setMinHeight(100);
 	    }
 	    if (me.loadError) {
-		Proxmox.Utils.setErrorMask(picker, me.loadError);
+		Proxmox.Utils.setErrorMask(picker.getView(), me.loadError);
 		delete me.loadError;
 		picker.updateLayout();
 	    }
@@ -428,7 +428,7 @@ Ext.define('Proxmox.form.ComboGrid', {
 		    // if the picker exists, we reset its minHeight to the previous saved one or 0
 		    if (me.picker) {
 			me.picker.setMinHeight(me.savedMinHeight || 0);
-			Proxmox.Utils.setErrorMask(me.picker);
+			Proxmox.Utils.setErrorMask(me.picker.getView());
 			delete me.savedMinHeight;
 			// we have to update the layout, otherwise the height gets not recalculated
 			me.picker.updateLayout();
@@ -463,7 +463,7 @@ Ext.define('Proxmox.form.ComboGrid', {
 	    } else {
 		let msg = Proxmox.Utils.getResponseErrorMessage(o.getError());
 		if (me.picker) {
-		    Proxmox.Utils.setErrorMask(me.picker, msg);
+		    Proxmox.Utils.setErrorMask(me.picker.getView(), msg);
 		}
 		me.loadError = msg;
 	    }
-- 
2.30.2





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

* [pve-devel] [PATCH widget-toolkit 2/2] ComboGrid: make height for the error configurable
  2023-01-18 13:12 [pve-devel] [PATCH widget-toolkit/pve-manager] move node selection into combogrid Dominik Csapak
  2023-01-18 13:12 ` [pve-devel] [PATCH widget-toolkit 1/2] ComboGrid: use the grids view for the error message Dominik Csapak
@ 2023-01-18 13:12 ` Dominik Csapak
  2023-01-18 13:12 ` [pve-devel] [PATCH manager 1/6] ui: StorageScanNodeSelector: use null as empty value Dominik Csapak
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-01-18 13:12 UTC (permalink / raw)
  To: pve-devel

by introducing a errorHeight config property. This is necessary when
the ComboGrid has e.g. a toolbar and we show the error in the grid body
only, 100 pixels is not enough then. To solve that without hardcoding
different heights, let the subclass/caller configure that

also set this when the store load fails completely (was not done until now)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/form/ComboGrid.js | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/form/ComboGrid.js b/src/form/ComboGrid.js
index e903223..ba3ce40 100644
--- a/src/form/ComboGrid.js
+++ b/src/form/ComboGrid.js
@@ -31,6 +31,7 @@ Ext.define('Proxmox.form.ComboGrid', {
 	skipEmptyText: false,
 	notFoundIsValid: false,
 	deleteEmpty: false,
+	errorHeight: 100,
     },
 
     // needed to trigger onKeyUp etc.
@@ -302,8 +303,8 @@ Ext.define('Proxmox.form.ComboGrid', {
 	picker.on('show', function() {
 	    me.store.fireEvent('refresh');
 	    if (me.enableLoadMask) {
-		me.savedMinHeight = picker.getMinHeight();
-		picker.setMinHeight(100);
+		me.savedMinHeight = me.savedMinHeight ?? picker.getMinHeight();
+		picker.setMinHeight(me.errorHeight);
 	    }
 	    if (me.loadError) {
 		Proxmox.Utils.setErrorMask(picker.getView(), me.loadError);
@@ -463,7 +464,10 @@ Ext.define('Proxmox.form.ComboGrid', {
 	    } else {
 		let msg = Proxmox.Utils.getResponseErrorMessage(o.getError());
 		if (me.picker) {
+		    me.savedMinHeight = me.savedMinHeight ?? me.picker.getMinHeight();
+		    me.picker.setMinHeight(me.errorHeight);
 		    Proxmox.Utils.setErrorMask(me.picker.getView(), msg);
+		    me.picker.updateLayout();
 		}
 		me.loadError = msg;
 	    }
-- 
2.30.2





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

* [pve-devel] [PATCH manager 1/6] ui: StorageScanNodeSelector: use null as empty value
  2023-01-18 13:12 [pve-devel] [PATCH widget-toolkit/pve-manager] move node selection into combogrid Dominik Csapak
  2023-01-18 13:12 ` [pve-devel] [PATCH widget-toolkit 1/2] ComboGrid: use the grids view for the error message Dominik Csapak
  2023-01-18 13:12 ` [pve-devel] [PATCH widget-toolkit 2/2] ComboGrid: make height for the error configurable Dominik Csapak
@ 2023-01-18 13:12 ` Dominik Csapak
  2023-01-18 13:12 ` [pve-devel] [PATCH manager 2/6] ui: storage: move node scan selector inside combobox Dominik Csapak
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-01-18 13:12 UTC (permalink / raw)
  To: pve-devel

otherwise it can happen that there as additional change event from
null to '', even though the value did not change

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/manager6/form/StorageScanNodeSelector.js | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/www/manager6/form/StorageScanNodeSelector.js b/www/manager6/form/StorageScanNodeSelector.js
index d6c9508a1..b2e013e9c 100644
--- a/www/manager6/form/StorageScanNodeSelector.js
+++ b/www/manager6/form/StorageScanNodeSelector.js
@@ -9,7 +9,7 @@ Ext.define('PVE.form.StorageScanNodeSelector', {
     disallowedNodes: undefined,
     autoSelect: false,
     submitValue: false,
-    value: "",
+    value: null,
     autoEl: {
 	tag: 'div',
 	'data-qtip': gettext('Scan for available storages on the selected node'),
@@ -18,14 +18,16 @@ Ext.define('PVE.form.StorageScanNodeSelector', {
 	clear: {
 	    handler: function() {
 		let me = this;
-		me.setValue("");
+		me.setValue(null);
 	    },
 	},
     },
 
+    emptyText: Proxmox.NodeName,
+
     setValue: function(value) {
 	let me = this;
 	me.callParent([value]);
-	me.triggers.clear.setVisible(value !== "");
+	me.triggers.clear.setVisible(!!value);
     },
 });
-- 
2.30.2





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

* [pve-devel] [PATCH manager 2/6] ui: storage: move node scan selector inside combobox
  2023-01-18 13:12 [pve-devel] [PATCH widget-toolkit/pve-manager] move node selection into combogrid Dominik Csapak
                   ` (2 preceding siblings ...)
  2023-01-18 13:12 ` [pve-devel] [PATCH manager 1/6] ui: StorageScanNodeSelector: use null as empty value Dominik Csapak
@ 2023-01-18 13:12 ` Dominik Csapak
  2023-01-18 13:13 ` [pve-devel] [PATCH manager 3/6] ui: storage/LvmThinInputPanel: modernize & cleanup code Dominik Csapak
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-01-18 13:12 UTC (permalink / raw)
  To: pve-devel

by converting the relevant selection boxes to combogrids.
This is done to reduce confusion for how/why to select a node,
and doing it this way it is moved closer to the selection
of the actual value we want.

It still restricts the nodes when selecting a specific one.

Show it only when there is more than one node according to
PVE.data.ResourceStore

Suggested-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/manager6/form/ComboBoxSetStoreNode.js | 45 +++++++++++++-
 www/manager6/storage/IScsiEdit.js         | 53 +++++++++--------
 www/manager6/storage/LVMEdit.js           | 71 +++++++++++++++++------
 www/manager6/storage/LvmThinEdit.js       | 71 +++++++++++++----------
 www/manager6/storage/ZFSPoolEdit.js       | 29 +++++----
 5 files changed, 180 insertions(+), 89 deletions(-)

diff --git a/www/manager6/form/ComboBoxSetStoreNode.js b/www/manager6/form/ComboBoxSetStoreNode.js
index 3490ddd7d..a654636b7 100644
--- a/www/manager6/form/ComboBoxSetStoreNode.js
+++ b/www/manager6/form/ComboBoxSetStoreNode.js
@@ -1,16 +1,57 @@
 Ext.define('PVE.form.ComboBoxSetStoreNode', {
-    extend: 'Ext.form.field.ComboBox',
+    extend: 'Proxmox.form.ComboGrid',
     config: {
 	apiBaseUrl: '/api2/json/nodes/',
 	apiSuffix: '',
     },
 
+    showNodeSelector: false,
+
     setNodeName: function(value) {
 	let me = this;
 	value ||= Proxmox.NodeName;
 
 	me.getStore().getProxy().setUrl(`${me.apiBaseUrl}${value}${me.apiSuffix}`);
-	this.clearValue();
+	me.clearValue();
+    },
+
+    nodeChange: function(_field, value) {
+	let me = this;
+	// disable autoSelect if there is already a selection or we have the picker open
+	if (me.getValue() || me.isExpanded) {
+	    let autoSelect = me.autoSelect;
+	    me.autoSelect = false;
+	    me.store.on('afterload', function() {
+		me.autoSelect = autoSelect;
+	    }, { single: true });
+	}
+	me.setNodeName(value);
+	me.fireEvent('nodechanged', value);
     },
 
+    initComponent: function() {
+	let me = this;
+
+	if (me.showNodeSelector && PVE.data.ResourceStore.getNodes().length > 1) {
+	    me.errorHeight = 140;
+	    Ext.apply(me.listConfig ?? {}, {
+		tbar: {
+		    xtype: 'toolbar',
+		    items: [
+			{
+			    xtype: "pveStorageScanNodeSelector",
+			    autoSelect: false,
+			    fieldLabel: gettext('Node to scan'),
+			    listeners: {
+				change: (field, value) => me.nodeChange(field, value),
+			    },
+			},
+		    ],
+		},
+		emptyText: me.listConfig?.emptyText ?? gettext('Nothing found'),
+	    });
+	}
+
+	me.callParent();
+    },
 });
diff --git a/www/manager6/storage/IScsiEdit.js b/www/manager6/storage/IScsiEdit.js
index 96c1aa28b..6a1e4aeb5 100644
--- a/www/manager6/storage/IScsiEdit.js
+++ b/www/manager6/storage/IScsiEdit.js
@@ -6,32 +6,43 @@ Ext.define('PVE.storage.IScsiScan', {
     valueField: 'target',
     displayField: 'target',
     matchFieldWidth: false,
+    allowBlank: false,
+
     listConfig: {
-	loadingText: gettext('Scanning...'),
 	width: 350,
+	columns: [
+	    {
+		dataIndex: 'target',
+		flex: 1,
+	    },
+	],
+	emptyText: gettext('No iSCSI target found'),
     },
+
     config: {
 	apiSuffix: '/scan/iscsi',
     },
-    doRawQuery: function() {
-	// do nothing
-    },
 
-    onTriggerClick: function() {
-	let me = this;
+    showNodeSelector: true,
 
-	if (!me.queryCaching || me.lastQuery !== me.portal) {
-	    me.store.removeAll();
+    reload: function() {
+	let me = this;
+	if (!me.isDisabled()) {
+	    me.getStore().load();
 	}
-
-	me.allQuery = me.portal;
-
-	me.callParent();
     },
 
     setPortal: function(portal) {
 	let me = this;
 	me.portal = portal;
+	me.getStore().getProxy().setExtraParams({ portal });
+	me.reload();
+    },
+
+    setNodeName: function(value) {
+	let me = this;
+	me.callParent([value]);
+	me.reload();
     },
 
     initComponent: function() {
@@ -81,19 +92,6 @@ Ext.define('PVE.storage.IScsiInputPanel', {
 	let me = this;
 
 	me.column1 = [
-	    {
-		xtype: 'pveStorageScanNodeSelector',
-		disabled: !me.isCreate,
-		hidden: !me.isCreate,
-		listeners: {
-		    change: {
-			fn: function(field, value) {
-			    me.lookup('iScsiTargetScan').setNodeName(value);
-			    me.lookup('storageNodeRestriction').setValue(value);
-			},
-		    },
-		},
-	    },
 	    {
 		xtype: me.isCreate ? 'textfield' : 'displayfield',
 		name: 'portal',
@@ -117,6 +115,11 @@ Ext.define('PVE.storage.IScsiInputPanel', {
 		fieldLabel: gettext('Target'),
 		allowBlank: false,
 		reference: 'iScsiTargetScan',
+		listeners: {
+		    nodechanged: function(value) {
+			me.lookup('storageNodeRestriction').setValue(value);
+		    },
+		},
 	    }),
 	];
 
diff --git a/www/manager6/storage/LVMEdit.js b/www/manager6/storage/LVMEdit.js
index b323a529d..84ee198da 100644
--- a/www/manager6/storage/LVMEdit.js
+++ b/www/manager6/storage/LVMEdit.js
@@ -5,10 +5,23 @@ Ext.define('PVE.storage.VgSelector', {
     displayField: 'vg',
     queryMode: 'local',
     editable: false,
+
+    listConfig: {
+	columns: [
+	    {
+		dataIndex: 'vg',
+		flex: 1,
+	    },
+	],
+	emptyText: gettext('No volume groups found'),
+    },
+
     config: {
 	apiSuffix: '/scan/lvm',
     },
 
+    showNodeSelector: true,
+
     setNodeName: function(value) {
 	let me = this;
 	me.callParent([value]);
@@ -35,9 +48,6 @@ Ext.define('PVE.storage.VgSelector', {
 
 	Ext.apply(me, {
 	    store: store,
-	    listConfig: {
-		loadingText: gettext('Scanning...'),
-	    },
 	});
 
 	me.callParent();
@@ -93,6 +103,42 @@ Ext.define('PVE.storage.BaseStorageSelector', {
     },
 });
 
+Ext.define('PVE.storage.LunSelector', {
+    extend: 'PVE.form.FileSelector',
+    alias: 'widget.pveStorageLunSelector',
+
+    nodename: 'localhost',
+    storageContent: 'images',
+    allowBlank: false,
+
+    initComponent: function() {
+	let me = this;
+
+	if (PVE.data.ResourceStore.getNodes().length > 1) {
+	    me.errorHeight = 140;
+	    Ext.apply(me.listConfig ?? {}, {
+		tbar: {
+		    xtype: 'toolbar',
+		    items: [
+			{
+			    xtype: "pveStorageScanNodeSelector",
+			    autoSelect: false,
+			    fieldLabel: gettext('Node to scan'),
+			    listeners: {
+				change: (_field, value) => me.setNodename(value),
+			    },
+			},
+		    ],
+		},
+		emptyText: me.listConfig?.emptyText ?? gettext('Nothing found'),
+	    });
+	}
+
+	me.callParent();
+    },
+
+});
+
 Ext.define('PVE.storage.LVMInputPanel', {
     extend: 'PVE.panel.StorageBase',
 
@@ -118,27 +164,16 @@ Ext.define('PVE.storage.LVMInputPanel', {
 		fieldLabel: gettext('Volume group'),
 		reference: 'volumeGroupSelector',
 		allowBlank: false,
-	    });
-	    me.column1.push({
-	        xtype: 'pveStorageScanNodeSelector',
-	        listeners: {
-	            change: {
-			fn: function(field, value) {
-			    me.lookup('volumeGroupSelector').setNodeName(value);
-			    me.lookup('storageNodeRestriction').setValue(value);
-			},
-		    },
-	        },
+		listeners: {
+		    nodechanged: (value) => me.lookup('storageNodeRestriction').setValue(value),
+		}
 	    });
 
-	    let baseField = Ext.createWidget('pveFileSelector', {
+	    let baseField = Ext.createWidget('pveStorageLunSelector', {
 		name: 'base',
 		hidden: true,
 		disabled: true,
-		nodename: 'localhost',
-		storageContent: 'images',
 		fieldLabel: gettext('Base volume'),
-		allowBlank: false,
 	    });
 
 	    me.column1.push({
diff --git a/www/manager6/storage/LvmThinEdit.js b/www/manager6/storage/LvmThinEdit.js
index 92e6c2962..0c288bb04 100644
--- a/www/manager6/storage/LvmThinEdit.js
+++ b/www/manager6/storage/LvmThinEdit.js
@@ -6,31 +6,40 @@ Ext.define('PVE.storage.TPoolSelector', {
     valueField: 'lv',
     displayField: 'lv',
     editable: false,
+    allowBlank: false,
+
+    listConfig: {
+	emptyText: gettext("No thinpool found"),
+	columns: [
+	    {
+		dataIndex: 'lv',
+		flex: 1,
+	    },
+	],
+    },
 
     config: {
 	apiSuffix: '/scan/lvmthin',
     },
 
-    doRawQuery: function() {
-	// nothing
-    },
-
-    onTriggerClick: function() {
+    reload: function() {
 	let me = this;
-
-	if (!me.queryCaching || me.lastQuery !== me.vg) {
-	    me.store.removeAll();
+	if (!me.isDisabled()) {
+	    me.getStore().load();
 	}
-
-	me.allQuery = me.vg;
-
-	me.callParent();
     },
 
     setVG: function(myvg) {
 	let me = this;
-
 	me.vg = myvg;
+	me.getStore().getProxy().setExtraParams({ vg: myvg });
+	me.reload();
+    },
+
+    setNodeName: function(value) {
+	let me = this;
+	me.callParent([value]);
+	me.reload();
     },
 
     initComponent: function() {
@@ -52,9 +61,6 @@ Ext.define('PVE.storage.TPoolSelector', {
 
 	Ext.apply(me, {
 	    store: store,
-	    listConfig: {
-		loadingText: gettext('Scanning...'),
-	    },
 	});
 
 	me.callParent();
@@ -69,6 +75,19 @@ Ext.define('PVE.storage.BaseVGSelector', {
     displayField: 'vg',
     queryMode: 'local',
     editable: false,
+    allowBlank: false,
+
+    listConfig: {
+	columns: [
+	    {
+		dataIndex: 'vg',
+		flex: 1,
+	    },
+	],
+    },
+
+    showNodeSelector: true,
+
     config: {
 	apiSuffix: '/scan/lvm',
     },
@@ -97,9 +116,6 @@ Ext.define('PVE.storage.BaseVGSelector', {
 
 	Ext.apply(me, {
 	    store: store,
-	    listConfig: {
-		loadingText: gettext('Scanning...'),
-	    },
 	});
 
 	me.callParent();
@@ -135,24 +151,15 @@ Ext.define('PVE.storage.LvmThinInputPanel', {
 	});
 
 	if (me.isCreate) {
-	    me.column1.push({
-	        xtype: 'pveStorageScanNodeSelector',
-	        listeners: {
-		    change: {
-			fn: function(field, value) {
-			    me.lookup('thinPoolSelector').setNodeName(value);
-			    me.lookup('volumeGroupSelector').setNodeName(value);
-			    me.lookup('storageNodeRestriction').setValue(value);
-			},
-		    },
-		},
-	    });
-
 	    me.column1.push(Ext.create('PVE.storage.BaseVGSelector', {
 		name: 'vgname',
 		fieldLabel: gettext('Volume group'),
 		reference: 'volumeGroupSelector',
 		listeners: {
+		    nodechanged: function(value) {
+			me.lookup('thinPoolSelector').setNodeName(value);
+			me.lookup('storageNodeRestriction').setValue(value);
+		    },
 		    change: function(f, value) {
 			if (me.isCreate) {
 			    let vgField = me.lookup('thinPoolSelector');
diff --git a/www/manager6/storage/ZFSPoolEdit.js b/www/manager6/storage/ZFSPoolEdit.js
index 65e152beb..df12fbbc8 100644
--- a/www/manager6/storage/ZFSPoolEdit.js
+++ b/www/manager6/storage/ZFSPoolEdit.js
@@ -5,13 +5,24 @@ Ext.define('PVE.storage.ZFSPoolSelector', {
     displayField: 'pool',
     queryMode: 'local',
     editable: false,
+    allowBlank: false,
+
     listConfig: {
-	loadingText: gettext('Scanning...'),
+	columns: [
+	    {
+		dataIndex: 'pool',
+		flex: 1,
+	    },
+	],
+	emptyText: gettext('No ZFS Pools found'),
     },
+
     config: {
 	apiSuffix: '/scan/zfs',
     },
 
+    showNodeSelector: true,
+
     setNodeName: function(value) {
 	let me = this;
 	me.callParent([value]);
@@ -54,22 +65,16 @@ Ext.define('PVE.storage.ZFSPoolInputPanel', {
 	me.column1 = [];
 
 	if (me.isCreate) {
-	    me.column1.push({
-	        xtype: 'pveStorageScanNodeSelector',
-	        listeners: {
-		    change: {
-			fn: function(field, value) {
-			    me.lookup('zfsPoolSelector').setNodeName(value);
-			    me.lookup('storageNodeRestriction').setValue(value);
-			},
-		    },
-		},
-	    });
 	    me.column1.push(Ext.create('PVE.storage.ZFSPoolSelector', {
 		name: 'pool',
 		fieldLabel: gettext('ZFS Pool'),
 		reference: 'zfsPoolSelector',
 		allowBlank: false,
+		listeners: {
+		    nodechanged: function(value) {
+			me.lookup('storageNodeRestriction').setValue(value);
+		    },
+		},
 	    }));
 	} else {
 	    me.column1.push(Ext.createWidget('displayfield', {
-- 
2.30.2





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

* [pve-devel] [PATCH manager 3/6] ui: storage/LvmThinInputPanel: modernize & cleanup code
  2023-01-18 13:12 [pve-devel] [PATCH widget-toolkit/pve-manager] move node selection into combogrid Dominik Csapak
                   ` (3 preceding siblings ...)
  2023-01-18 13:12 ` [pve-devel] [PATCH manager 2/6] ui: storage: move node scan selector inside combobox Dominik Csapak
@ 2023-01-18 13:13 ` Dominik Csapak
  2023-01-18 13:13 ` [pve-devel] [PATCH manager 4/6] ui: storage/IScsiInputPanel: modernize, cleanup & improve panel Dominik Csapak
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-01-18 13:13 UTC (permalink / raw)
  To: pve-devel

using cbind + pmxDisplayEditField, getting rid of the initComponent

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/manager6/storage/LvmThinEdit.js | 83 ++++++++++++-----------------
 1 file changed, 35 insertions(+), 48 deletions(-)

diff --git a/www/manager6/storage/LvmThinEdit.js b/www/manager6/storage/LvmThinEdit.js
index 0c288bb04..ece5512b0 100644
--- a/www/manager6/storage/LvmThinEdit.js
+++ b/www/manager6/storage/LvmThinEdit.js
@@ -124,67 +124,56 @@ Ext.define('PVE.storage.BaseVGSelector', {
 
 Ext.define('PVE.storage.LvmThinInputPanel', {
     extend: 'PVE.panel.StorageBase',
+    mixins: ['Proxmox.Mixin.CBind'],
 
     onlineHelp: 'storage_lvmthin',
 
-    initComponent: function() {
-	let me = this;
-
-	me.column1 = [];
+    column1: [
+	{
+	    xtype: 'pmxDisplayEditField',
+	    cbind: {
+		editable: '{isCreate}',
+	    },
 
-	let vgnameField = Ext.createWidget(me.isCreate ? 'textfield' : 'displayfield', {
 	    name: 'vgname',
-	    hidden: !!me.isCreate,
-	    disabled: !!me.isCreate,
-	    value: '',
 	    fieldLabel: gettext('Volume group'),
-	    allowBlank: false,
-	});
 
-	let thinpoolField = Ext.createWidget(me.isCreate ? 'textfield' : 'displayfield', {
-	    name: 'thinpool',
-	    hidden: !!me.isCreate,
-	    disabled: !!me.isCreate,
-	    value: '',
-	    fieldLabel: gettext('Thin Pool'),
-	    allowBlank: false,
-	});
-
-	if (me.isCreate) {
-	    me.column1.push(Ext.create('PVE.storage.BaseVGSelector', {
-		name: 'vgname',
-		fieldLabel: gettext('Volume group'),
-		reference: 'volumeGroupSelector',
+	    editConfig: {
+		xtype: 'pveBaseVGSelector',
 		listeners: {
 		    nodechanged: function(value) {
-			me.lookup('thinPoolSelector').setNodeName(value);
-			me.lookup('storageNodeRestriction').setValue(value);
+			let panel = this.up('inputpanel');
+			panel.lookup('thinPoolSelector').setNodeName(value);
+			panel.lookup('storageNodeRestriction').setValue(value);
 		    },
 		    change: function(f, value) {
-			if (me.isCreate) {
-			    let vgField = me.lookup('thinPoolSelector');
+			let vgField = this.up('inputpanel').lookup('thinPoolSelector');
+			if (vgField) {
+			    vgField.setDisabled(!value);
 			    vgField.setVG(value);
 			    vgField.setValue('');
 			}
 		    },
 		},
-	    }));
-
-	    me.column1.push(Ext.create('PVE.storage.TPoolSelector', {
-		name: 'thinpool',
-		fieldLabel: gettext('Thin Pool'),
-		reference: 'thinPoolSelector',
-		allowBlank: false,
-	    }));
-	}
-
-	me.column1.push(vgnameField);
+	    },
+	},
+	{
+	    xtype: 'pmxDisplayEditField',
+	    cbind: {
+		editable: '{isCreate}',
+	    },
 
-	me.column1.push(thinpoolField);
+	    name: 'thinpool',
+	    fieldLabel: gettext('Thin Pool'),
+	    allowBlank: false,
 
-	// here value is an array,
-	// while before it was a string
-	me.column1.push({
+	    editConfig: {
+		xtype: 'pveTPSelector',
+		reference: 'thinPoolSelector',
+		disabled: true,
+	    },
+	},
+	{
 	    xtype: 'pveContentTypeSelector',
 	    cts: ['images', 'rootdir'],
 	    fieldLabel: gettext('Content'),
@@ -192,10 +181,8 @@ Ext.define('PVE.storage.LvmThinInputPanel', {
 	    value: ['images', 'rootdir'],
 	    multiSelect: true,
 	    allowBlank: false,
-	});
+	},
+    ],
 
-	me.column2 = [];
-
-	me.callParent();
-    },
+    column2: [],
 });
-- 
2.30.2





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

* [pve-devel] [PATCH manager 4/6] ui: storage/IScsiInputPanel: modernize, cleanup & improve panel
  2023-01-18 13:12 [pve-devel] [PATCH widget-toolkit/pve-manager] move node selection into combogrid Dominik Csapak
                   ` (4 preceding siblings ...)
  2023-01-18 13:13 ` [pve-devel] [PATCH manager 3/6] ui: storage/LvmThinInputPanel: modernize & cleanup code Dominik Csapak
@ 2023-01-18 13:13 ` Dominik Csapak
  2023-01-18 13:13 ` [pve-devel] [PATCH manager 5/6] ui: storage/ZFSPoolInputPanel: modernize & cleanup code Dominik Csapak
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-01-18 13:13 UTC (permalink / raw)
  To: pve-devel

using cbind + pmxDisplayEditField, getting rid of initComponent

Disables the target selector until a portal is entered. For this, we
currently cannot use the pmxDisplayEditField, since that
disabled/enables the fields automatically based on 'editable'.

Also setting buffer for the portal entry change handler to 500ms (so that
we don't query the backend that often)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/manager6/storage/IScsiEdit.js | 90 +++++++++++++++++--------------
 1 file changed, 51 insertions(+), 39 deletions(-)

diff --git a/www/manager6/storage/IScsiEdit.js b/www/manager6/storage/IScsiEdit.js
index 6a1e4aeb5..314882b44 100644
--- a/www/manager6/storage/IScsiEdit.js
+++ b/www/manager6/storage/IScsiEdit.js
@@ -71,6 +71,7 @@ Ext.define('PVE.storage.IScsiScan', {
 
 Ext.define('PVE.storage.IScsiInputPanel', {
     extend: 'PVE.panel.StorageBase',
+    mixins: ['Proxmox.Mixin.CBind'],
 
     onlineHelp: 'storage_open_iscsi',
 
@@ -88,50 +89,61 @@ Ext.define('PVE.storage.IScsiInputPanel', {
 	this.callParent([values]);
     },
 
-    initComponent: function() {
-	let me = this;
+    column1: [
+	{
+	    xtype: 'pmxDisplayEditField',
+	    cbind: {
+		editable: '{isCreate}',
+	    },
 
-	me.column1 = [
-	    {
-		xtype: me.isCreate ? 'textfield' : 'displayfield',
-		name: 'portal',
-		value: '',
-		fieldLabel: 'Portal',
-		allowBlank: false,
+	    name: 'portal',
+	    value: '',
+	    fieldLabel: 'Portal',
+	    allowBlank: false,
+
+	    editConfig: {
 		listeners: {
-		    change: function(f, value) {
-			if (me.isCreate) {
-			    let exportField = me.down('field[name=target]');
-			    exportField.setPortal(value);
-			    exportField.setValue('');
-			}
+		    change: {
+			fn: function(f, value) {
+			    let panel = this.up('inputpanel');
+			    let exportField = panel.lookup('iScsiTargetScan');
+			    if (exportField) {
+				exportField.setDisabled(!value);
+				exportField.setPortal(value);
+				exportField.setValue('');
+			    }
+			},
+			buffer: 500,
 		    },
 		},
 	    },
-	    Ext.createWidget(me.isCreate ? 'pveIScsiScan' : 'displayfield', {
-		readOnly: !me.isCreate,
-		name: 'target',
-		value: '',
-		fieldLabel: gettext('Target'),
-		allowBlank: false,
-		reference: 'iScsiTargetScan',
-		listeners: {
-		    nodechanged: function(value) {
-			me.lookup('storageNodeRestriction').setValue(value);
-		    },
-		},
-	    }),
-	];
-
-	me.column2 = [
-	    {
-		xtype: 'checkbox',
-		name: 'luns',
-		checked: true,
-		fieldLabel: gettext('Use LUNs directly'),
+	},
+	{
+	    cbind: {
+		xtype: (get) => get('isCreate') ? 'pveIScsiScan' : 'displayfield',
+		readOnly: '{!isCreate}',
+		disabled: '{isCreate}',
 	    },
-	];
 
-	me.callParent();
-    },
+	    name: 'target',
+	    value: '',
+	    fieldLabel: gettext('Target'),
+	    allowBlank: false,
+	    reference: 'iScsiTargetScan',
+	    listeners: {
+		nodechanged: function(value) {
+		    this.up('inputpanel').lookup('storageNodeRestriction').setValue(value);
+		},
+	    },
+	},
+    ],
+
+    column2: [
+	{
+	    xtype: 'checkbox',
+	    name: 'luns',
+	    checked: true,
+	    fieldLabel: gettext('Use LUNs directly'),
+	},
+    ],
 });
-- 
2.30.2





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

* [pve-devel] [PATCH manager 5/6] ui: storage/ZFSPoolInputPanel: modernize & cleanup code
  2023-01-18 13:12 [pve-devel] [PATCH widget-toolkit/pve-manager] move node selection into combogrid Dominik Csapak
                   ` (5 preceding siblings ...)
  2023-01-18 13:13 ` [pve-devel] [PATCH manager 4/6] ui: storage/IScsiInputPanel: modernize, cleanup & improve panel Dominik Csapak
@ 2023-01-18 13:13 ` Dominik Csapak
  2023-01-18 13:13 ` [pve-devel] [PATCH manager 6/6] ui: storage/LVMInputPanel: " Dominik Csapak
  2023-01-18 15:08 ` [pve-devel] applied-series: [PATCH widget-toolkit/pve-manager] move node selection into combogrid Thomas Lamprecht
  8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-01-18 13:13 UTC (permalink / raw)
  To: pve-devel

using cbind + pmxDisplayEditField, getting rid of initComponent

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/manager6/storage/ZFSPoolEdit.js | 77 +++++++++++++----------------
 1 file changed, 35 insertions(+), 42 deletions(-)

diff --git a/www/manager6/storage/ZFSPoolEdit.js b/www/manager6/storage/ZFSPoolEdit.js
index df12fbbc8..f4c8894e5 100644
--- a/www/manager6/storage/ZFSPoolEdit.js
+++ b/www/manager6/storage/ZFSPoolEdit.js
@@ -56,38 +56,32 @@ Ext.define('PVE.storage.ZFSPoolSelector', {
 
 Ext.define('PVE.storage.ZFSPoolInputPanel', {
     extend: 'PVE.panel.StorageBase',
+    mixins: ['Proxmox.Mixin.CBind'],
 
     onlineHelp: 'storage_zfspool',
 
-    initComponent: function() {
-	let me = this;
+    column1: [
+	{
+	    xtype: 'pmxDisplayEditField',
+	    cbind: {
+		editable: '{isCreate}',
+	    },
 
-	me.column1 = [];
+	    name: 'pool',
+	    fieldLabel: gettext('ZFS Pool'),
+	    allowBlank: false,
 
-	if (me.isCreate) {
-	    me.column1.push(Ext.create('PVE.storage.ZFSPoolSelector', {
-		name: 'pool',
-		fieldLabel: gettext('ZFS Pool'),
+	    editConfig: {
+		xtype: 'pveZFSPoolSelector',
 		reference: 'zfsPoolSelector',
-		allowBlank: false,
 		listeners: {
 		    nodechanged: function(value) {
-			me.lookup('storageNodeRestriction').setValue(value);
+			this.up('inputpanel').lookup('storageNodeRestriction').setValue(value);
 		    },
 		},
-	    }));
-	} else {
-	    me.column1.push(Ext.createWidget('displayfield', {
-		name: 'pool',
-		value: '',
-		fieldLabel: gettext('ZFS Pool'),
-		allowBlank: false,
-	    }));
-	}
-
-	// value is an array,
-	// while before it was a string
-	me.column1.push({
+	    },
+	},
+	{
 	    xtype: 'pveContentTypeSelector',
 	    cts: ['images', 'rootdir'],
 	    fieldLabel: gettext('Content'),
@@ -95,24 +89,23 @@ Ext.define('PVE.storage.ZFSPoolInputPanel', {
 	    value: ['images', 'rootdir'],
 	    multiSelect: true,
 	    allowBlank: false,
-	});
-	me.column2 = [
-	    {
-		xtype: 'proxmoxcheckbox',
-		name: 'sparse',
-		checked: false,
-		uncheckedValue: 0,
-		fieldLabel: gettext('Thin provision'),
-	    },
-	    {
-		xtype: 'textfield',
-		name: 'blocksize',
-		emptyText: '8k',
-		fieldLabel: gettext('Block Size'),
-		allowBlank: true,
-	    },
-	];
-
-	me.callParent();
-    },
+	}
+    ],
+
+    column2: [
+	{
+	    xtype: 'proxmoxcheckbox',
+	    name: 'sparse',
+	    checked: false,
+	    uncheckedValue: 0,
+	    fieldLabel: gettext('Thin provision'),
+	},
+	{
+	    xtype: 'textfield',
+	    name: 'blocksize',
+	    emptyText: '8k',
+	    fieldLabel: gettext('Block Size'),
+	    allowBlank: true,
+	},
+    ],
 });
-- 
2.30.2





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

* [pve-devel] [PATCH manager 6/6] ui: storage/LVMInputPanel: modernize & cleanup code
  2023-01-18 13:12 [pve-devel] [PATCH widget-toolkit/pve-manager] move node selection into combogrid Dominik Csapak
                   ` (6 preceding siblings ...)
  2023-01-18 13:13 ` [pve-devel] [PATCH manager 5/6] ui: storage/ZFSPoolInputPanel: modernize & cleanup code Dominik Csapak
@ 2023-01-18 13:13 ` Dominik Csapak
  2023-01-18 15:08 ` [pve-devel] applied-series: [PATCH widget-toolkit/pve-manager] move node selection into combogrid Thomas Lamprecht
  8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-01-18 13:13 UTC (permalink / raw)
  To: pve-devel

using cbin, gettin rid of initComponent

this is a bit more complicated than the other refactorings in storage
recently, since we have a few fields with non trivial dependecies
between the selected mode (existing vgs/base storage) and isCreate

Because of that, using a cbind for the xtype here instead of the
pmxDisplayEditField is much more convenient
(accessing the pmxDisplayEditField and the editField below is currently
not really ideal)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/manager6/storage/LVMEdit.js | 152 ++++++++++++++++----------------
 1 file changed, 74 insertions(+), 78 deletions(-)

diff --git a/www/manager6/storage/LVMEdit.js b/www/manager6/storage/LVMEdit.js
index 84ee198da..1b6edd08e 100644
--- a/www/manager6/storage/LVMEdit.js
+++ b/www/manager6/storage/LVMEdit.js
@@ -141,78 +141,76 @@ Ext.define('PVE.storage.LunSelector', {
 
 Ext.define('PVE.storage.LVMInputPanel', {
     extend: 'PVE.panel.StorageBase',
+    mixins: ['Proxmox.Mixin.CBind'],
 
     onlineHelp: 'storage_lvm',
 
-    initComponent: function() {
-	let me = this;
-
-	me.column1 = [];
-
-	let vgnameField = Ext.createWidget(me.isCreate ? 'textfield' : 'displayfield', {
+    column1: [
+	{
+	    xtype: 'pveBaseStorageSelector',
+	    name: 'basesel',
+	    fieldLabel: gettext('Base storage'),
+	    cbind: {
+		disabled: '{!isCreate}',
+		hidden: '{!isCreate}',
+	    },
+	    submitValue: false,
+	    listeners: {
+		change: function(f, value) {
+		    let me = this;
+		    let vgField = me.up('inputpanel').lookup('volumeGroupSelector');
+		    let vgNameField = me.up('inputpanel').lookup('vgName');
+		    let baseField = me.up('inputpanel').lookup('lunSelector');
+
+		    vgField.setVisible(!value);
+		    vgField.setDisabled(!!value);
+
+		    baseField.setVisible(!!value);
+		    baseField.setDisabled(!value);
+		    baseField.setStorage(value);
+
+		    vgNameField.setVisible(!!value);
+		    vgNameField.setDisabled(!value);
+		},
+	    },
+	},
+	{
+	    xtype: 'pveStorageLunSelector',
+	    name: 'base',
+	    fieldLabel: gettext('Base volume'),
+	    reference: 'lunSelector',
+	    hidden: true,
+	    disabled: true,
+	},
+	{
+	    xtype: 'pveVgSelector',
 	    name: 'vgname',
-	    hidden: !!me.isCreate,
-	    disabled: !!me.isCreate,
-	    value: '',
 	    fieldLabel: gettext('Volume group'),
+	    reference: 'volumeGroupSelector',
+	    cbind: {
+		disabled: '{!isCreate}',
+		hidden: '{!isCreate}',
+	    },
 	    allowBlank: false,
-	});
-
-	if (me.isCreate) {
-	    let vgField = Ext.create('PVE.storage.VgSelector', {
-		name: 'vgname',
-		fieldLabel: gettext('Volume group'),
-		reference: 'volumeGroupSelector',
-		allowBlank: false,
-		listeners: {
-		    nodechanged: (value) => me.lookup('storageNodeRestriction').setValue(value),
-		}
-	    });
-
-	    let baseField = Ext.createWidget('pveStorageLunSelector', {
-		name: 'base',
-		hidden: true,
-		disabled: true,
-		fieldLabel: gettext('Base volume'),
-	    });
-
-	    me.column1.push({
-		xtype: 'pveBaseStorageSelector',
-		name: 'basesel',
-		fieldLabel: gettext('Base storage'),
-		submitValue: false,
-		listeners: {
-		    change: function(f, value) {
-			if (value) {
-			    vgnameField.setVisible(true);
-			    vgnameField.setDisabled(false);
-			    vgField.setVisible(false);
-			    vgField.setDisabled(true);
-			    baseField.setVisible(true);
-			    baseField.setDisabled(false);
-			} else {
-			    vgnameField.setVisible(false);
-			    vgnameField.setDisabled(true);
-			    vgField.setVisible(true);
-			    vgField.setDisabled(false);
-			    baseField.setVisible(false);
-			    baseField.setDisabled(true);
-			}
-			baseField.setStorage(value);
-		    },
+	    listeners: {
+		nodechanged: function(value) {
+		    this.up('inputpanel').lookup('storageNodeRestriction').setValue(value);
 		},
-	    });
-
-	    me.column1.push(baseField);
-
-	    me.column1.push(vgField);
-	}
-
-	me.column1.push(vgnameField);
-
-	// here value is an array,
-	// while before it was a string
-	me.column1.push({
+	    },
+	},
+	{
+	    name: 'vgname',
+	    fieldLabel: gettext('Volume group'),
+	    reference: 'vgName',
+	    cbind: {
+		xtype: (get) => get('isCreate') ? 'textfield' : 'displayfield',
+		hidden: '{isCreate}',
+		disabled: '{isCreate}',
+	    },
+	    value: '',
+	    allowBlank: false,
+	},
+	{
 	    xtype: 'pveContentTypeSelector',
 	    cts: ['images', 'rootdir'],
 	    fieldLabel: gettext('Content'),
@@ -220,17 +218,15 @@ Ext.define('PVE.storage.LVMInputPanel', {
 	    value: ['images', 'rootdir'],
 	    multiSelect: true,
 	    allowBlank: false,
-	});
-
-	me.column2 = [
-	    {
-		xtype: 'proxmoxcheckbox',
-		name: 'shared',
-		uncheckedValue: 0,
-		fieldLabel: gettext('Shared'),
-	    },
-	];
-
-	me.callParent();
-    },
+	},
+    ],
+
+    column2: [
+	{
+	    xtype: 'proxmoxcheckbox',
+	    name: 'shared',
+	    uncheckedValue: 0,
+	    fieldLabel: gettext('Shared'),
+	},
+    ],
 });
-- 
2.30.2





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

* [pve-devel] applied-series: [PATCH widget-toolkit/pve-manager] move node selection into combogrid
  2023-01-18 13:12 [pve-devel] [PATCH widget-toolkit/pve-manager] move node selection into combogrid Dominik Csapak
                   ` (7 preceding siblings ...)
  2023-01-18 13:13 ` [pve-devel] [PATCH manager 6/6] ui: storage/LVMInputPanel: " Dominik Csapak
@ 2023-01-18 15:08 ` Thomas Lamprecht
  8 siblings, 0 replies; 10+ messages in thread
From: Thomas Lamprecht @ 2023-01-18 15:08 UTC (permalink / raw)
  To: Proxmox VE development discussion, Dominik Csapak

Am 18/01/2023 um 14:12 schrieb Dominik Csapak:
> proxmox-widget-toolkit:
> 
> Dominik Csapak (2):
>   ComboGrid: use the grids view for the error message
>   ComboGrid: make height for the error configurable
> 
>  src/form/ComboGrid.js | 14 +++++++++-----
>  1 file changed, 9 insertions(+), 5 deletions(-)
> 
> pve-manager:
> 
> Dominik Csapak (6):
>   ui: StorageScanNodeSelector: use null as empty value
>   ui: storage: move node scan selector inside combobox
>   ui: storage/LvmThinInputPanel: modernize & cleanup code
>   ui: storage/IScsiInputPanel: modernize, cleanup & improve panel
>   ui: storage/ZFSPoolInputPanel: modernize & cleanup code
>   ui: storage/LVMInputPanel: modernize & cleanup code
> 
>  www/manager6/form/ComboBoxSetStoreNode.js    |  45 +++-
>  www/manager6/form/StorageScanNodeSelector.js |   8 +-
>  www/manager6/storage/IScsiEdit.js            | 129 +++++++-----
>  www/manager6/storage/LVMEdit.js              | 209 +++++++++++--------
>  www/manager6/storage/LvmThinEdit.js          | 150 +++++++------
>  www/manager6/storage/ZFSPoolEdit.js          | 100 +++++----
>  6 files changed, 361 insertions(+), 280 deletions(-)
> 


nice! applied series with touching up some commit message (subjects) slightly to
my (opinionated) liking, thanks!

as mentioned off-list: currently the outer/main picker is closed unexpected when:
- one wants to close the nested/inner one by clicking somewhere in the outer one.
- the node-selection input field  of the nested-picker has focus and one clicks
  somewhere in the outer/main picker.

It's not a big thing, but otoh: it *is* slightly irritating..




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

end of thread, other threads:[~2023-01-18 15:08 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-18 13:12 [pve-devel] [PATCH widget-toolkit/pve-manager] move node selection into combogrid Dominik Csapak
2023-01-18 13:12 ` [pve-devel] [PATCH widget-toolkit 1/2] ComboGrid: use the grids view for the error message Dominik Csapak
2023-01-18 13:12 ` [pve-devel] [PATCH widget-toolkit 2/2] ComboGrid: make height for the error configurable Dominik Csapak
2023-01-18 13:12 ` [pve-devel] [PATCH manager 1/6] ui: StorageScanNodeSelector: use null as empty value Dominik Csapak
2023-01-18 13:12 ` [pve-devel] [PATCH manager 2/6] ui: storage: move node scan selector inside combobox Dominik Csapak
2023-01-18 13:13 ` [pve-devel] [PATCH manager 3/6] ui: storage/LvmThinInputPanel: modernize & cleanup code Dominik Csapak
2023-01-18 13:13 ` [pve-devel] [PATCH manager 4/6] ui: storage/IScsiInputPanel: modernize, cleanup & improve panel Dominik Csapak
2023-01-18 13:13 ` [pve-devel] [PATCH manager 5/6] ui: storage/ZFSPoolInputPanel: modernize & cleanup code Dominik Csapak
2023-01-18 13:13 ` [pve-devel] [PATCH manager 6/6] ui: storage/LVMInputPanel: " Dominik Csapak
2023-01-18 15:08 ` [pve-devel] applied-series: [PATCH widget-toolkit/pve-manager] move node selection into combogrid Thomas Lamprecht

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