Is it a bad idea to move column2 as I did here? Seems strange to have column1 and 2 so different but I haven't found an easier way to make it available to the subclass yet.
@Thomas Is this sort of what you had in mind for this feature? Signed-off-by: Dominic Jäger <d.jae...@proxmox.com> --- www/manager6/Makefile | 1 + www/manager6/form/DiskStorageSelector.js | 5 + www/manager6/qemu/HDEdit.js | 50 +++++---- www/manager6/qemu/HDImport.js | 128 +++++++++++++++++++++++ www/manager6/qemu/HardwareView.js | 13 +++ 5 files changed, 176 insertions(+), 21 deletions(-) create mode 100644 www/manager6/qemu/HDImport.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index a29e280d..c1645748 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -143,6 +143,7 @@ JSSRC= \ qemu/Smbios1Edit.js \ qemu/CDEdit.js \ qemu/HDEdit.js \ + qemu/HDImport.js \ qemu/HDResize.js \ qemu/HDMove.js \ qemu/HDEfi.js \ diff --git a/www/manager6/form/DiskStorageSelector.js b/www/manager6/form/DiskStorageSelector.js index 445e3ac0..2c1555e1 100644 --- a/www/manager6/form/DiskStorageSelector.js +++ b/www/manager6/form/DiskStorageSelector.js @@ -32,6 +32,11 @@ Ext.define('PVE.form.DiskStorageSelector', { // string because else we get a type confusion defaultSize: '32', + setDiskSize: function(newSize) { + let field = this.getComponent('disksize'); + field.setValue(newSize); + }, + changeStorage: function(f, value) { var me = this; var formatsel = me.getComponent('diskformat'); diff --git a/www/manager6/qemu/HDEdit.js b/www/manager6/qemu/HDEdit.js index fd890600..5d6c12e9 100644 --- a/www/manager6/qemu/HDEdit.js +++ b/www/manager6/qemu/HDEdit.js @@ -13,6 +13,28 @@ Ext.define('PVE.qemu.HDInputPanel', { viewModel: {}, + diskStorageSelector: { + xtype: 'pveDiskStorageSelector', + storageContent: 'images', + name: 'disk', + reference: 'storageSelector', + }, + + column2: [ + { + xtype: 'CacheTypeSelector', + name: 'cache', + value: '__default__', + fieldLabel: gettext('Cache') + }, + { + xtype: 'proxmoxcheckbox', + fieldLabel: gettext('Discard'), + reference: 'discard', + name: 'discard' + }, + ], + controller: { xclass: 'Ext.app.ViewController', @@ -164,7 +186,6 @@ Ext.define('PVE.qemu.HDInputPanel', { me.drive = {}; me.column1 = []; - me.column2 = []; me.advancedColumn1 = []; me.advancedColumn2 = []; @@ -188,6 +209,8 @@ Ext.define('PVE.qemu.HDInputPanel', { me.column1.push(me.scsiController); } + me.diskStorageSelector.nodename = me.nodename; + me.diskStorageSelector.autoSelect = me.insideWizard; if (me.unused) { me.unusedDisks = Ext.create('Proxmox.form.KVComboBox', { name: 'unusedId', @@ -201,13 +224,7 @@ Ext.define('PVE.qemu.HDInputPanel', { }); me.column1.push(me.unusedDisks); } else if (me.isCreate) { - me.column1.push({ - xtype: 'pveDiskStorageSelector', - storageContent: 'images', - name: 'disk', - nodename: me.nodename, - autoSelect: me.insideWizard - }); + me.column1.push(me.diskStorageSelector); } else { me.column1.push({ xtype: 'textfield', @@ -219,18 +236,6 @@ Ext.define('PVE.qemu.HDInputPanel', { } me.column2.push( - { - xtype: 'CacheTypeSelector', - name: 'cache', - value: '__default__', - fieldLabel: gettext('Cache') - }, - { - xtype: 'proxmoxcheckbox', - fieldLabel: gettext('Discard'), - reference: 'discard', - name: 'discard' - } ); me.advancedColumn1.push( @@ -358,7 +363,9 @@ Ext.define('PVE.qemu.HDEdit', { backgroundDelay: 5, - initComponent : function() { + isImport: false, + + initComponent: function() { var me = this; var nodename = me.pveSelNode.data.node; @@ -374,6 +381,7 @@ Ext.define('PVE.qemu.HDEdit', { confid: me.confid, nodename: nodename, unused: unused, + isImport: me.isImport, isCreate: me.isCreate }); diff --git a/www/manager6/qemu/HDImport.js b/www/manager6/qemu/HDImport.js new file mode 100644 index 00000000..16e08ff2 --- /dev/null +++ b/www/manager6/qemu/HDImport.js @@ -0,0 +1,128 @@ +Ext.define('PVE.qemu.HDImportInputPanel', { + extend: 'PVE.qemu.HDInputPanel', + alias: 'widget.pveQemuHDImportInputPanel', + + constructor: function(config) { + let me = this; + this.callParent([config]); + }, + + column2: [ + { + xtype: 'textfield', + fieldLabel: gettext('Source image'), + name: 'inputImage', + emptyText: '/home/user/disk.qcow2', + submitValue: true, + }, + ], + + initComponent: function() { + let me = this; + this.column2 = this.superclass.column2.concat(this.column2); + Object.assign(this.diskStorageSelector, this.superclass.diskStorageSelector ); + let inputField = this.column2.find(el => el.name == 'inputImage'); + if (typeof inputField !== 'undefined') { + inputField.listeners = { + focusleave: function() { + // TODO get size of source image + let newSize = Math.floor(Math.random()*100); + me.lookup('storageSelector').setDiskSize(newSize); + }, + }; + } + this.callParent(); + let selector = this.lookup('storageSelector'); + }, + onGetValues: function(values) { + let params = this.callParent([values]); + params['source'] = values.inputImage; + return params; + }, +}); + +Ext.define('PVE.qemu.HDImport', { + extend: 'Proxmox.window.Edit', + + isImport: true, + isCreate: true, + subject: gettext('Import Hard Disk'), + submitText: gettext('Import'), + submit: function() { + let submitObject = this; + let params = submitObject.getValues(); + let importParams = {}; + let addParams = {}; + Ext.Object.each(params, function(name, val) { + if (name === 'storage' || name === 'source') { + importParams[name] = val; + } else { + addParams[name] = val; + } + }); + let me = this; + var form = me.formPanel.getForm(); + Proxmox.Utils.API2Request({ + url: submitObject.url.replace(/config/, 'importdisk'), + backgroundDelay: 0, + method: 'POST', + params: params, + failure: function(response, options) { + me.apiCallDone(false, response, options); + + if (response.result && response.result.errors) { + form.markInvalid(response.result.errors); + } + Ext.Msg.alert(gettext('Error'), response.htmlStatus); + }, + success: function(response, options) { + var hasProgressBar = (me.backgroundDelay || me.showProgress || me.showTaskViewer) && + response.result.data ? true : false; + + me.apiCallDone(true, response, options); + + if (hasProgressBar) { + // stay around so we can trigger our close events + // when background action is completed + me.hide(); + + var upid = response.result.data; + var viewerClass = me.showTaskViewer ? 'Viewer' : 'Progress'; + var win = Ext.create('Proxmox.window.Task' + viewerClass, { + upid: upid, + taskDone: me.taskDone, + listeners: { + destroy: function () { + me.close(); + } + } + }); + win.show(); + } else { + me.close(); + } + } + }); + }, + constructor: function(config) { + this.callParent([config]); + }, + + initComponent: function() { + let nodename = this.pveSelNode.data.node; + if (!nodename) { throw 'no node name specified'; } + + this.items = [ Ext.create('PVE.qemu.HDImportInputPanel', { + confid: this.confid, + nodename: nodename, + isImport: true, + isCreate: true, + })]; + + this.callParent(); + }, + + onGetValues: function(values) { + this.callParent(); + }, +}); diff --git a/www/manager6/qemu/HardwareView.js b/www/manager6/qemu/HardwareView.js index 6c831ad6..47fb5cea 100644 --- a/www/manager6/qemu/HardwareView.js +++ b/www/manager6/qemu/HardwareView.js @@ -438,6 +438,18 @@ Ext.define('PVE.qemu.HardwareView', { handler: run_move }); + var import_btn = new Proxmox.button.Button({ + text: gettext('Import disk'), + handler: function() { + var win = Ext.create('PVE.qemu.HDImport', { + url: '/api2/extjs/' + baseurl, + pveSelNode: me.pveSelNode, + }); + win.on('destroy', me.reload, me); + win.show(); + }, + }); + var remove_btn = new Proxmox.button.Button({ text: gettext('Remove'), defaultText: gettext('Remove'), @@ -754,6 +766,7 @@ Ext.define('PVE.qemu.HardwareView', { edit_btn, resize_btn, move_btn, + import_btn, revert_btn ], rows: rows, -- 2.20.1 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel