From: Dominik Csapak Date: Thu, 25 Jun 2020 11:59:31 +0000 (+0200) Subject: add form/MultiDiskSelector X-Git-Url: https://git.proxmox.com/?p=proxmox-widget-toolkit.git;a=commitdiff_plain;h=a57a5c770aef42c54d0127bfd3672d5434c8cfe5 add form/MultiDiskSelector 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 --- 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 }); + }, + +});