* [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