[pve-devel] [RFC manager 1/4] Add new selector for pool-wide bulk actions

Thomas Lamprecht t.lamprecht at proxmox.com
Thu Aug 31 08:37:48 CEST 2017


n 08/30/2017 05:22 PM, Philip Abernethy wrote:
> The new selector is functionally identical to the VMSelector,
> except that it filters the resource list with a pool name, instead
> of a node name.

Yes its really quite identical, as a diff on both files shows.

Instead of deduplicate all the code the existing one could be modified
to allow both use cases, which could be looking something like:

----8<----
diff --git a/www/manager6/form/VMSelector.js b/www/manager6/form/VMSelector.js
index 59d2b587..7e285fba 100644
--- a/www/manager6/form/VMSelector.js
+++ b/www/manager6/form/VMSelector.js
@@ -54,6 +54,7 @@ Ext.define('PVE.form.VMSelector', {
         {
             header: gettext('Pool'),
             dataIndex: 'pool',
+           hidden: !!me.poolname
             filter: {
                 type: 'list'
             }
@@ -175,6 +176,11 @@ Ext.define('PVE.form.VMSelector', {
                 property: 'node',
                 value: me.nodename
             });
+       } else if(me.poolname) {
+           me.store.filters.add({
+               property: 'pool',
+               value: me.poolname
+           });
         }

         // only show the relevant guests by default

---->8----


> ---
>   www/manager6/form/MemberVMSelector.js | 207 ++++++++++++++++++++++++++++++++++
>   1 file changed, 207 insertions(+)
>   create mode 100644 www/manager6/form/MemberVMSelector.js
> 
> diff --git a/www/manager6/form/MemberVMSelector.js b/www/manager6/form/MemberVMSelector.js
> new file mode 100644
> index 00000000..e1944d5d
> --- /dev/null
> +++ b/www/manager6/form/MemberVMSelector.js
> @@ -0,0 +1,207 @@
> +
> +/*jslint confusion: true*/
> +/* filter is a javascript builtin, but extjs calls it also filter */
> +Ext.define('PVE.form.MemberVMSelector', {
> +    extend: 'Ext.grid.Panel',
> +    alias: 'widget.membervmselector',
> +
> +    mixins: {
> +	field: 'Ext.form.field.Field'
> +    },
> +
> +    allowBlank: true,
> +    selectAll: false,
> +    isFormField: true,
> +
> +    plugins: 'gridfilters',
> +
> +    store: {
> +	model: 'PVEResources',
> +	autoLoad: true,
> +	sorters: 'vmid',
> +	filters: [{
> +	    property: 'type',
> +	    value: /lxc|qemu/
> +	}]
> +    },
> +    columns: [
> +	{
> +	    header: 'ID',
> +	    dataIndex: 'vmid',
> +	    width: 80,
> +	    filter: {
> +		type: 'number'
> +	    }
> +	},
> +	{
> +	    header: gettext('Node'),
> +	    dataIndex: 'node'
> +	},
> +	{
> +	    header: gettext('Status'),
> +	    dataIndex: 'status',
> +	    filter: {
> +		type: 'list'
> +	    }
> +	},
> +	{
> +	    header: gettext('Name'),
> +	    dataIndex: 'name',
> +	    flex: 1,
> +	    filter: {
> +		type: 'string'
> +	    }
> +	},
> +	{
> +	    header: gettext('Type'),
> +	    dataIndex: 'type',
> +	    width: 120,
> +	    renderer: function(value) {
> +		if (value === 'qemu') {
> +		    return gettext('Virtual Machine');
> +		} else if (value === 'lxc') {
> +		    return gettext('LXC Container');
> +		}
> +
> +		return '';
> +	    },
> +	    filter: {
> +		type: 'list',
> +		store: {
> +		    data: [
> +			{id: 'qemu', text: gettext('Virtual Machine')},
> +			{id: 'lxc', text: gettext('LXC Container')}
> +		    ],
> +		    // due to EXTJS-18711
> +		    // we have to do a static list via a store
> +		    // but to avoid creating an object,
> +		    // we have to have a pseudo un function
> +		    un: function(){}
> +		}
> +	    }
> +	},
> +	{
> +	    header: 'HA ' + gettext('Status'),
> +	    dataIndex: 'hastate',
> +	    flex: 1,
> +	    filter: {
> +		type: 'list'
> +	    }
> +	}
> +    ],
> +
> +    selModel: {
> +	selType: 'checkboxmodel',
> +	checkOnly: true
> +    },
> +
> +    checkChangeEvents: [
> +	'selectionchange',
> +	'change'
> +    ],
> +
> +    listeners: {
> +	selectionchange: function() {
> +	    // to trigger validity and error checks
> +	    this.checkChange();
> +	}
> +    },
> +
> +    getValue: function() {
> +	var me = this;
> +	var sm = me.getSelectionModel();
> +	var selection = sm.getSelection();
> +	var values = [];
> +	var store = me.getStore();
> +	selection.forEach(function(item) {
> +	    // only add if not filtered
> +	    if (store.findExact('vmid', item.data.vmid) !== -1) {
> +		values.push(item.data.vmid);
> +	    }
> +	});
> +	return values;
> +    },
> +
> +    setValue: function(value) {
> +	console.log(value);
> +	var me = this;
> +	var sm = me.getSelectionModel();
> +	if (!Ext.isArray(value)) {
> +	    value = value.split(',');
> +	}
> +	var selection = [];
> +	var store = me.getStore();
> +
> +	value.forEach(function(item) {
> +	    var rec = store.findRecord('vmid',item, 0, false, true, true);
> +	    console.log(store);
> +
> +	    if (rec) {
> +		console.log(rec);
> +		selection.push(rec);
> +	    }
> +	});
> +
> +	sm.select(selection);
> +
> +	return me.mixins.field.setValue.call(me, value);
> +    },
> +
> +    getErrors: function(value) {
> +	var 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 VM selected')];
> +	}
> +
> +	me.removeBodyCls(['x-form-trigger-wrap-default','x-form-trigger-wrap-invalid']);
> +	return [];
> +    },
> +
> +    initComponent: function() {
> +	var me = this;
> +
> +	me.callParent();
> +
> +	if (me.poolname) {
> +	    me.store.filters.add({
> +		property: 'pool',
> +		value: me.poolname
> +	    });
> +	}
> +
> +	// only show the relevant guests by default
> +	if (me.action) {
> +	    var statusfilter = '';
> +	    switch (me.action) {
> +		case 'startall':
> +		    statusfilter = 'stopped';
> +		    break;
> +		case 'stopall':
> +		    statusfilter = 'running';
> +		    break;
> +	    }
> +	    if (statusfilter !== '') {
> +		me.store.filters.add({
> +		    property: 'template',
> +		    value: 0
> +		},{
> +		    id: 'x-gridfilter-status',
> +		    operator: 'in',
> +		    property: 'status',
> +		    value: [statusfilter]
> +		});
> +	    }
> +	}
> +
> +	var store = me.getStore();
> +	var sm = me.getSelectionModel();
> +
> +	if (me.selectAll) {
> +	    me.mon(store,'load', function(){
> +		me.getSelectionModel().selectAll(false);
> +	    });
> +	}
> +    }
> +});
> 





More information about the pve-devel mailing list