[pve-devel] [PATCH manager 11/11] lxc/MPEdit: rework for advanced options
Dominik Csapak
d.csapak at proxmox.com
Thu Apr 5 16:03:56 CEST 2018
this is a complete rework of the inputpanel (long overdue)
it uses a viewModel and viewcontroller to avoid the
multiple is zfs/root/bind checks and concentrate them
in one place
also some features get optimized (e.g. the noreplication checkbox)
adds a setNodename to the DiskStorageSelector so that we can bind
the nodename there
Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
www/manager6/form/DiskStorageSelector.js | 9 +
www/manager6/lxc/MPEdit.js | 441 +++++++++++++++----------------
2 files changed, 227 insertions(+), 223 deletions(-)
diff --git a/www/manager6/form/DiskStorageSelector.js b/www/manager6/form/DiskStorageSelector.js
index 0fdb5c5c..d5aaa0f8 100644
--- a/www/manager6/form/DiskStorageSelector.js
+++ b/www/manager6/form/DiskStorageSelector.js
@@ -76,6 +76,15 @@ Ext.define('PVE.form.DiskStorageSelector', {
hdsizesel.setVisible(!select && !me.hideSize);
},
+ setNodename: function(nodename) {
+ var me = this;
+ var hdstorage = me.getComponent('hdstorage');
+ var hdfilesel = me.getComponent('hdimage');
+
+ hdstorage.setNodename(nodename);
+ hdfilesel.setNodename(nodename);
+ },
+
initComponent: function() {
var me = this;
diff --git a/www/manager6/lxc/MPEdit.js b/www/manager6/lxc/MPEdit.js
index 079b8ddc..37f725ea 100644
--- a/www/manager6/lxc/MPEdit.js
+++ b/www/manager6/lxc/MPEdit.js
@@ -1,6 +1,11 @@
+/*jslint confusion: true*/
+/* hidden: boolean and string
+ * bind: function and object
+ * disabled: boolean and string
+ */
Ext.define('PVE.lxc.MountPointInputPanel', {
extend: 'Proxmox.panel.InputPanel',
- alias: 'widget.pveLxcMountPointInputPanel',
+ xtype: 'pveLxcMountPointInputPanel',
insideWizard: false,
@@ -13,284 +18,274 @@ Ext.define('PVE.lxc.MountPointInputPanel', {
vmconfig: {}, // used to select unused disks
setUnprivileged: function(unprivileged) {
- this.unprivileged = unprivileged;
- this.quota.setDisabled(unprivileged);
+ var me = this;
+ var vm = me.getViewModel();
+ me.unprivileged = unprivileged;
+ vm.set('unpriv', unprivileged);
},
onGetValues: function(values) {
var me = this;
var confid = me.confid || values.mpsel;
+ values.file = me.down('field[name=file]').getValue();
if (me.unused) {
- me.mpdata.file = me.vmconfig[values.unusedId];
confid = values.mpsel;
} else if (me.isCreate) {
- me.mpdata.file = values.hdstorage + ':' + values.disksize;
- }
-
- if (confid !== 'rootfs') {
- me.mpdata.mp = values.mp;
- }
-
- if (values.ro) {
- me.mpdata.ro = 1;
- } else {
- delete me.mpdata.ro;
- }
-
- if (values.quota) {
- me.mpdata.quota = 1;
- } else {
- delete me.mpdata.quota;
- }
-
- if (values.acl === 'Default') {
- delete me.mpdata.acl;
- } else {
- me.mpdata.acl = values.acl;
- }
-
- if (values.backup) {
- me.mpdata.backup = 1;
- } else {
- delete me.mpdata.backup;
+ values.file = values.hdstorage + ':' + values.disksize;
}
- if (values.noreplicate) {
- me.mpdata.replicate = '0';
- }
- delete me.mpdata.noreplicate;
+ // delete unnecessary fields
+ delete values.mpsel;
+ delete values.hdstorage;
+ delete values.disksize;
+ delete values.diskformat;
var res = {};
- res[confid] = PVE.Parser.printLxcMountPoint(me.mpdata);
+ res[confid] = PVE.Parser.printLxcMountPoint(values);
return res;
},
+
setMountPoint: function(mp) {
var me = this;
-
- // the fields name is 'hdstorage',
- // but the api expects/has 'storage'
- mp.hdstorage = mp.storage;
- delete mp.hdstorage;
-
- me.mpdata = mp;
- if (!Ext.isDefined(me.mpdata.acl)) {
- me.mpdata.acl = 'Default';
- }
-
- if (mp.type === 'bind') {
- me.quota.setDisabled(true);
- me.acl.setDisabled(true);
- me.acl.setValue('Default');
- me.down('#hdstorage').setDisabled(true);
- if (me.confid !== 'rootfs') {
- me.backup.setDisabled(true);
- }
- }
-
- if (mp.replicate) { // check box reverses the config option
- mp.noreplicate = !PVE.Parser.parseBoolean(mp.replicate, 1);
- delete mp.replicate;
- }
-
+ var vm = this.getViewModel();
+ vm.set('mptype', mp.type);
me.setValues(mp);
},
setVMConfig: function(vmconfig) {
var me = this;
-
+ var vm = me.getViewModel();
me.vmconfig = vmconfig;
-
- if (me.mpsel) {
- var i;
- for (i = 0; i != 8; ++i) {
- var name = "mp" + i.toString();
- if (!Ext.isDefined(vmconfig[name])) {
- me.mpsel.setValue(name);
- break;
- }
+ vm.set('unpriv', vmconfig.unprivileged);
+ vm.notify();
+
+ PVE.Utils.forEachMP(function(bus, i) {
+ var name = "mp" + i.toString();
+ if (!Ext.isDefined(vmconfig[name])) {
+ me.down('field[name=mpsel]').setValue(name);
+ return false;
}
- }
-
- if (me.unusedDisks) {
- var disklist = [];
- Ext.Object.each(vmconfig, function(key, value) {
- if (key.match(/^unused\d+$/)) {
- disklist.push([key, value]);
- }
- });
- me.unusedDisks.store.loadData(disklist);
- me.unusedDisks.setValue(me.confid);
- }
+ });
},
setNodename: function(nodename) {
var me = this;
- me.down('#hdstorage').setNodename(nodename);
- me.down('#hdimage').setStorage(undefined, nodename);
+ var vm = me.getViewModel();
+ vm.set('node', nodename);
+ vm.notify();
+ me.down('#diskstorage').setNodename(nodename);
},
- initComponent : function() {
- var me = this;
-
- var isroot = me.confid === 'rootfs';
-
- me.mpdata = {};
+ controller: {
+ xclass: 'Ext.app.ViewController',
- me.column1 = [];
-
- if (!me.confid || me.unused) {
- var names = [];
- var i;
- for (i = 0; i != 8; ++i) {
- var name = 'mp' + i.toString();
- names.push([name, name]);
- }
- me.mpsel = Ext.create('Proxmox.form.KVComboBox', {
- name: 'mpsel',
- fieldLabel: gettext('Mount Point'),
- matchFieldWidth: false,
- allowBlank: false,
- comboItems: names,
- validator: function(value) {
- if (!me.rendered) {
+ control: {
+ 'field[name=mpsel]': {
+ change: function(field, value) {
+ field.validate();
+ }
+ },
+ '#hdstorage': {
+ change: function(field, newValue) {
+ var me = this;
+ if (!newValue) {
return;
}
- if (Ext.isDefined(me.vmconfig[value])) {
- return "Mount point is already in use.";
- }
- /*jslint confusion: true*/
- /* returns a string above */
- return true;
- },
- listeners: {
- change: function(field, value) {
- field.validate();
+
+ var rec = field.store.getById(newValue);
+ if (!rec) {
+ return;
}
+
+ var vm = me.getViewModel();
+ vm.set('type', rec.data.type);
+ vm.notify();
}
- });
- me.column1.push(me.mpsel);
+ }
+ },
+
+ init: function(view) {
+ var me = this;
+ var vm = this.getViewModel();
+ vm.set('confid', view.confid);
+ vm.set('unused', view.unused);
+ vm.set('node', view.nodename);
+ vm.set('unpriv', view.unprivileged);
+ vm.set('hideStorSelector', view.unused || !view.isCreate);
+ vm.notify();
}
+ },
- me.column1.push({
+ viewModel: {
+ data: {
+ unpriv: false,
+ unused: false,
+ showStorageSelector: false,
+ mptype: '',
+ type: '',
+ confid: '',
+ node: ''
+ },
+
+ formulas: {
+ quota: function(get) {
+ return !(get('type') === 'zfs' ||
+ get('type') === 'zfspool' ||
+ get('unpriv') ||
+ get('isBind'));
+ },
+ hasMP: function(get) {
+ return !!get('confid') && !get('unused');
+ },
+ isRoot: function(get) {
+ return get('confid') === 'rootfs';
+ },
+ isBind: function(get) {
+ return get('mptype') === 'bind';
+ },
+ isBindOrRoot: function(get) {
+ return get('isBind') || get('isRoot');
+ }
+ }
+ },
+
+ column1: [
+ {
+ xtype: 'proxmoxKVComboBox',
+ name: 'mpsel',
+ fieldLabel: gettext('Mount Point'),
+ matchFieldWidth: false,
+ hidden: true,
+ allowBlank: false,
+ bind: {
+ hidden: '{hasMP}',
+ disabled: '{hasMP}'
+ },
+ comboItems: (function(){
+ var mps = [];
+ PVE.Utils.forEachMP(function(bus,i) {
+ var name = 'mp' + i.toString();
+ mps.push([name,name]);
+ });
+ return mps;
+ }()),
+ validator: function(value) {
+ var me = this.up('inputpanel');
+ if (!me.rendered) {
+ return;
+ }
+ if (Ext.isDefined(me.vmconfig[value])) {
+ return "Mount point is already in use.";
+ }
+ /*jslint confusion: true*/
+ /* returns a string above */
+ return true;
+ }
+ },
+ {
xtype: 'pveDiskStorageSelector',
- nodename: me.nodename,
+ itemId: 'diskstorage',
storageContent: 'rootdir',
+ hidden: true,
autoSelect: true,
+ selectformat: false,
defaultSize: 8,
- hidden: me.unused || !me.isCreate
- });
-
- if (me.unused) {
- me.unusedDisks = Ext.create('Proxmox.form.KVComboBox', {
- name: 'unusedId',
- fieldLabel: gettext('Disk image'),
- matchFieldWidth: false,
- listConfig: {
- width: 350
- },
- data: [],
- allowBlank: false,
- listeners: {
- change: function(f, value) {
- // make sure our buttons are enabled/disabled when switching
- // between images on different storages:
- var disk = me.vmconfig[value];
- var storage = disk.split(':')[0];
- me.down('#hdstorage').setValue(storage);
- }
- }
- });
- me.column1.push(me.unusedDisks);
- } else if (!me.isCreate) {
- me.column1.push({
- xtype: 'textfield',
- disabled: true,
- submitValue: false,
- fieldLabel: gettext('Disk image'),
- name: 'file'
- });
+ bind: {
+ hidden: '{hideStorSelector}',
+ disabled: '{hideStorSelector}',
+ nodename: '{node}'
+ }
+ },
+ {
+ xtype: 'textfield',
+ disabled: true,
+ submitValue: false,
+ fieldLabel: gettext('Disk image'),
+ name: 'file',
+ bind: {
+ hidden: '{!hideStorSelector}'
+ }
}
+ ],
+
+ column2: [
+ {
+ xtype: 'textfield',
+ name: 'mp',
+ value: '',
+ emptyText: gettext('/some/path'),
+ allowBlank: false,
+ fieldLabel: gettext('Path'),
+ bind: {
+ hidden: '{isRoot}',
+ disabled: '{isRoot}'
+ }
+ },
+ {
+ xtype: 'proxmoxcheckbox',
+ name: 'backup',
+ fieldLabel: gettext('Backup'),
+ bind: {
+ hidden: '{isRoot}',
+ disabled: '{isBindOrRoot}'
+ }
+ }
+ ],
- me.acl = Ext.createWidget('proxmoxKVComboBox', {
- name: 'acl',
- fieldLabel: 'ACLs',
- comboItems: [['Default', 'Default'], ['1', 'On'], ['0', 'Off']],
- value: 'Default',
- allowBlank: true
- });
-
- me.quota = Ext.createWidget('proxmoxcheckbox', {
+ advancedColumn1: [
+ {
+ xtype: 'proxmoxcheckbox',
name: 'quota',
defaultValue: 0,
- disabled: me.unprivileged,
+ bind: {
+ disabled: '{!quota}'
+ },
fieldLabel: gettext('Enable quota'),
listeners: {
disable: function() {
this.reset();
}
}
- });
-
- me.column2 = [
- me.acl,
- me.quota
- ];
-
- if (!isroot) {
- me.column2.splice(1, 0, {
- xtype: 'proxmoxcheckbox',
- name: 'ro',
- defaultValue: 0,
- fieldLabel: gettext('Read-only'),
- hidden: me.insideWizard
- });
-
- me.backup = Ext.createWidget('proxmoxcheckbox',{
- xtype: 'proxmoxcheckbox',
- name: 'backup',
- fieldLabel: gettext('Backup')
- });
- if (me.mpdata.type !== 'bind') {
- me.column2.push(me.backup);
- }
- me.column2.push({
- xtype: 'proxmoxcheckbox',
- name: 'noreplicate',
- fieldLabel: gettext('Skip replication')
- });
- me.column2.push({
- xtype: 'textfield',
- name: 'mp',
- value: '',
- emptyText: gettext('/some/path'),
- allowBlank: false,
- hidden: isroot,
- fieldLabel: gettext('Path')
- });
+ },
+ {
+ xtype: 'proxmoxcheckbox',
+ name: 'ro',
+ defaultValue: 0,
+ bind: {
+ hidden: '{isRoot}',
+ disabled: '{isRoot}'
+ },
+ fieldLabel: gettext('Read-only')
}
+ ],
- me.callParent();
-
- if (me.unused || me.isCreate) {
- me.mon(me.down('#hdstorage'), 'change', function(field, newValue) {
- if (!newValue) {
- return;
- }
- var rec = field.store.getById(newValue);
- if (!rec) {
- return;
- }
- if (rec.data.type === 'zfs' || rec.data.type === 'zfspool') {
- me.quota.setDisabled(true);
- } else {
- me.quota.setDisabled(me.unprivileged);
- }
- });
+ advancedColumn2: [
+ {
+ xtype: 'proxmoxKVComboBox',
+ name: 'acl',
+ fieldLabel: 'ACLs',
+ deleteEmpty: false,
+ comboItems: [
+ ['__default__', Proxmox.Utils.defaultText],
+ ['1', Proxmox.Utils.enabledText],
+ ['0', Proxmox.Utils.disabledText]
+ ],
+ value: '__default__',
+ bind: {
+ disabled: '{isBind}'
+ },
+ allowBlank: true
+ },
+ {
+ xtype: 'proxmoxcheckbox',
+ inputValue: '0', // reverses the logic
+ name: 'replicate',
+ fieldLabel: gettext('Skip replication')
}
- }
+ ]
});
Ext.define('PVE.lxc.MountPointEdit', {
--
2.11.0
More information about the pve-devel
mailing list