[pve-devel] [PATCH widget-toolkit 2/3] add form/MultiDiskSelector

Dominik Csapak d.csapak at proxmox.com
Thu Jun 25 13:59:31 CEST 2020


from pve's ZFSCreate window, refactored to be self-contained using
field mixin, as well as be configureable enough to be used by pve as
well as other products

Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
 src/Makefile                  |   1 +
 src/form/MultiDiskSelector.js | 164 ++++++++++++++++++++++++++++++++++
 2 files changed, 165 insertions(+)
 create mode 100644 src/form/MultiDiskSelector.js

diff --git a/src/Makefile b/src/Makefile
index 3311bbe..f4f8bf5 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -30,6 +30,7 @@ JSSRC=					\
 	form/RealmComboBox.js		\
 	form/RoleSelector.js		\
 	form/DiskSelector.js		\
+	form/MultiDiskSelector.js	\
 	button/Button.js		\
 	button/HelpButton.js		\
 	grid/ObjectGrid.js		\
diff --git a/src/form/MultiDiskSelector.js b/src/form/MultiDiskSelector.js
new file mode 100644
index 0000000..9e989a4
--- /dev/null
+++ b/src/form/MultiDiskSelector.js
@@ -0,0 +1,164 @@
+Ext.define('Proxmox.form.MultiDiskSelector', {
+    extend: 'Ext.grid.Panel',
+    alias: 'widget.pmxMultiDiskSelector',
+
+    mixins: {
+	field: 'Ext.form.field.Field',
+    },
+
+    selModel: 'checkboxmodel',
+
+    store: {
+	data: [],
+	proxy: {
+	    type: 'proxmox',
+	},
+    },
+
+    // which field of the disklist is used for getValue
+    valueField: 'devpath',
+
+    // which parameter is used for the type
+    typeParameter: 'type',
+
+    // the type of disks to show
+    diskType: 'unused',
+
+    disks: [],
+
+    allowBlank: false,
+
+    getValue: function() {
+	let me = this;
+	return me.disks;
+    },
+
+    setValue: function(value) {
+	let me = this;
+
+	if (!Ext.isArray(value)) {
+	    value = value.split(/;, /);
+	}
+
+	let store = me.getStore();
+	let selection = [];
+
+	let keyField = me.valueField;
+
+	value.forEach(item => {
+	    let rec = store.findRecord(keyField, item, 0, false, true, true);
+	    if (rec) {
+		selection.push(rec);
+	    }
+	});
+
+	me.setSelection(selection);
+
+	return me.mixins.field.setValue.call(me, value);
+    },
+
+    getErrors: function(value) {
+	let me = this;
+	if (me.allowBlank === false &&
+	    me.getSelectionModel().getCount() === 0) {
+	    me.addBodyCls(['x-form-trigger-wrap-default', 'x-form-trigger-wrap-invalid']);
+	    return [gettext('No Disk selected')];
+	}
+
+	me.removeBodyCls(['x-form-trigger-wrap-default', 'x-form-trigger-wrap-invalid']);
+	return [];
+    },
+
+    update_disklist: function() {
+	var me = this;
+	var disks = me.getSelection();
+
+	var val = [];
+	disks.sort(function(a, b) {
+	    var aorder = a.get('order') || 0;
+	    var border = b.get('order') || 0;
+	    return aorder - border;
+	});
+
+	disks.forEach(function(disk) {
+	    val.push(disk.get(me.valueField));
+	});
+
+	me.validate();
+	me.disks = val;
+    },
+
+    columns: [
+	{
+	    text: gettext('Device'),
+	    dataIndex: 'devpath',
+	    flex: 2,
+	},
+	{
+	    text: gettext('Model'),
+	    dataIndex: 'model',
+	    flex: 2,
+	},
+	{
+	    text: gettext('Serial'),
+	    dataIndex: 'serial',
+	    flex: 2,
+	},
+	{
+	    text: gettext('Size'),
+	    dataIndex: 'size',
+	    renderer: Proxmox.Utils.format_size,
+	    flex: 1,
+	},
+	{
+	    header: gettext('Order'),
+	    xtype: 'widgetcolumn',
+	    dataIndex: 'order',
+	    sortable: true,
+	    flex: 1,
+	    widget: {
+		xtype: 'proxmoxintegerfield',
+		minValue: 1,
+		isFormField: false,
+		listeners: {
+		    change: function(numberfield, value, old_value) {
+			let grid = this.up('pmxMultiDiskSelector');
+			var record = numberfield.getWidgetRecord();
+			record.set('order', value);
+			grid.update_disklist(record);
+		    },
+		},
+	    },
+	},
+    ],
+
+    listeners: {
+	selectionchange: function() {
+	    this.update_disklist();
+	},
+    },
+
+    initComponent: function() {
+	let me = this;
+
+	if (!me.url) {
+	    if (!me.nodename) {
+		throw "no url or nodename given";
+	    }
+
+	    let node = me.nodename;
+	    let param = me.typeParameter;
+	    let type = me.diskType;
+	    me.url = `/api2/json/nodes/${node}/disks/list?${param}=${type}`;
+	}
+
+	me.disks = [];
+
+	me.callParent();
+	let store = me.getStore();
+	store.getProxy().setUrl(me.url);
+	store.load();
+	store.sort({ property: me.valueField });
+    },
+
+});
-- 
2.20.1





More information about the pve-devel mailing list