Ext.define('PMG.RuleInfo', {
- extend: 'Ext.grid.GridPanel',
- alias: 'widget.pmgRuleInfo',
+ extend: 'Ext.panel.Panel',
+ xtype: 'pmgRuleInfo',
- baseurl: undefined,
+ controller: {
+ xclass: 'Ext.app.ViewController',
- ruledata: undefined,
+ setBaseUrl: function(baseurl) {
+ var me = this;
+ me.getViewModel().set('baseurl', baseurl);
+ me.reload();
+ },
- emptyText: gettext('Please select a rule.'),
+ reload: function() {
+ var me = this;
+ var viewmodel = me.getViewModel();
+ var baseurl = viewmodel.get('baseurl');
- setBaseUrl: function(baseurl) {
- var me = this;
+ if (!baseurl) {
+ me.setRuleInfo(undefined);
+ return;
+ }
- me.baseurl = baseurl;
+ Proxmox.Utils.API2Request({
+ url: baseurl + "/config",
+ method: 'GET',
+ success: function(response, opts) {
+ me.setRuleInfo(response.result.data);
+ },
+ failure: function(response, opts) {
+ Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+ },
+ });
+ },
- me.reload();
- },
+ removeObjectGroup: function(rec) {
+ var me = this;
+ Ext.Msg.confirm(
+ gettext('Confirm'),
+ Ext.String.format(
+ gettext('Are you sure you want to remove entry {0}'),
+ "'" + rec.data.name + "'"),
+ function(button) {
+ if (button === 'yes') {
+ Proxmox.Utils.API2Request({
+ url: me.getViewModel().get('baseurl') + '/' + rec.data.oclass + '/'+ rec.data.typeid,
+ method: 'DELETE',
+ waitMsgTarget: me.getView(),
+ callback: function() {
+ me.reload();
+ },
+ failure: function(response, opts) {
+ Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+ },
+ });
+ }
+ },
+ );
+ },
- reload: function() {
- var me = this;
+ addObjectGroup: function(type, record) {
+ var me = this;
+ var baseurl = me.getViewModel().get('baseurl');
+ var url = baseurl + '/' + type;
+ var id = type === 'action'?record.data.ogroup:record.data.id;
+ Proxmox.Utils.API2Request({
+ url: url,
+ params: { ogroup: id },
+ method: 'POST',
+ waitMsgTarget: me.getView(),
+ callback: function() {
+ me.reload();
+ },
+ failure: function(response, opts) {
+ Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+ },
+ });
+ },
- if (!me.baseurl) {
- me.setRuleInfo(undefined);
- return;
- }
+ setRuleInfo: function(ruledata) {
+ var me = this;
- Proxmox.Utils.API2Request({
- url: me.baseurl + "/config",
- method: 'GET',
- waitMsgTarget: me,
- success: function(response, opts) {
- me.setRuleInfo(response.result.data);
- },
- failure: function (response, opts) {
- Ext.Msg.alert(gettext('Error'), response.htmlStatus);
- }
- });
- },
+ var viewmodel = me.getViewModel();
- setRuleInfo: function(ruledata) {
- var me = this;
+ if (ruledata === undefined) {
+ viewmodel.set('selectedRule', null);
+ viewmodel.get('objects').setData([]);
+ } else {
+ viewmodel.set('selectedRule', ruledata);
- me.ruledata = ruledata;
+ var data = [];
+ Ext.Array.each(['from', 'to', 'when', 'what', 'action'], function(oc) {
+ var store = viewmodel.get(oc + 'objects');
+ if (ruledata[oc] === undefined || store === undefined) { return; }
- me.down('#addFromButton').setDisabled(me.ruledata === undefined);
- me.down('#addToButton').setDisabled(me.ruledata === undefined);
- me.down('#addWhenButton').setDisabled(me.ruledata === undefined);
- me.down('#addWhatButton').setDisabled(me.ruledata === undefined);
- me.down('#addActionButton').setDisabled(me.ruledata === undefined);
+ // we build a filter for the objects,
+ // which are already added to the rule,
+ // so what we only show the ones,
+ // which are still available
- if (me.ruledata === undefined) {
+ var ids = Ext.Array.pluck(ruledata[oc], 'id');
+ // for the actions, we have a different id field
+ var idField = oc === 'action'?'ogroup':'id';
+ store.clearFilter();
+ store.addFilter({
+ filterFn: function(record) {
+ // FIXME
+ // actions have the ogroup as a string
+ // -> parseInt
+ return ids.indexOf(parseInt(record.data[idField], 10)) === -1;
+ },
+ });
+ store.load();
+ Ext.Array.each(ruledata[oc], function(og) {
+ data.push({ oclass: oc, name: og.name, typeid: og.id });
+ });
+ });
- me.store.setData([]);
- me.down('#ruleinfo').update(me.emtpyText);
- me.down('#ruledata').setHidden(true);
+ viewmodel.get('objects').setData(data);
+ }
+ },
- } else {
+ removeIconClick: function(gridView, rowindex, colindex, button, event, record) {
+ var me = this;
+ me.removeObjectGroup(record);
+ },
- var html = '<b>' + Ext.String.htmlEncode(me.ruledata.name) + '</b>';
- html += '<br><br>';
- html += 'Priority: ' + me.ruledata.priority + '<br>';
- html += 'Direction: ' + PMG.Utils.format_rule_direction(me.ruledata.direction) + '<br>';
- html += 'Active: ' + Proxmox.Utils.format_boolean(me.ruledata.active) + '<br>';
+ removeDrop: function(gridView, data, overModel) {
+ var me = this;
+ var record = data.records[0]; // only one
+ me.removeObjectGroup(record);
+ return true;
+ },
- var data = [];
- Ext.Array.each(['from', 'to', 'when', 'what', 'action'], function(oc) {
- var list = ruledata[oc];
- if (list === undefined) { return; }
- Ext.Array.each(list, function(og) {
- data.push({ oclass: oc, name: og.name, id: og.id });
- });
- });
+ addIconClick: function(gridView, rowindex, colindex, button, event, record) {
+ var me = this;
+ me.addObjectGroup(gridView.panel.type, record);
+ return true;
+ },
- me.store.setData(data);
+ addDrop: function(gridView, data, overModel) {
+ var me = this;
+ var record = data.records[0]; // only one
+ me.addObjectGroup(data.view.panel.type, record);
+ return true;
+ },
- me.down('#ruleinfo').update(html);
- me.down('#ruledata').setHidden(false);
- }
+ control: {
+ 'grid[reference=usedobjects]': {
+ drop: 'addDrop',
+ },
+ 'tabpanel[reference=availobjects] > grid': {
+ drop: 'removeDrop',
+ },
+ },
},
- initComponent : function() {
- var me = this;
+ viewModel: {
+ data: {
+ baseurl: '',
+ },
- me.store = new Ext.data.Store({
- fields: [ 'oclass', 'name' ]
- });
+ stores: {
+ objects: {
+ fields: ['oclass', 'name', 'typeid'],
+ groupField: 'oclass',
+ sorters: 'name',
+ },
- me.columns = [
- {
- header: gettext('Type'),
- dataIndex: 'oclass',
+ actionobjects: {
+ model: 'pmg-action-list',
+ proxy: {
+ type: 'proxmox',
+ url: "/api2/json/config/ruledb/action/objects",
+ },
+ sorters: 'name',
},
- {
- header: gettext('name'),
- dataIndex: 'name',
- flex: 1
- }
- ];
+ fromobjects: {
+ model: 'pmg-object-group',
+ proxy: {
+ type: 'proxmox',
+ url: "/api2/json/config/ruledb/who",
+ },
+ sorters: 'name',
+ },
+ toobjects: {
+ model: 'pmg-object-group',
+ proxy: {
+ type: 'proxmox',
+ url: "/api2/json/config/ruledb/who",
+ },
+ sorters: 'name',
+ },
+ whatobjects: {
+ model: 'pmg-object-group',
+ proxy: {
+ type: 'proxmox',
+ url: "/api2/json/config/ruledb/what",
+ },
+ sorters: 'name',
+ },
+ whenobjects: {
+ model: 'pmg-object-group',
+ proxy: {
+ type: 'proxmox',
+ url: "/api2/json/config/ruledb/when",
+ },
+ sorters: 'name',
+ },
+ },
+ },
- me.selModel = Ext.create('Ext.selection.RowModel', {});
- var remove_btn = Ext.createWidget('proxmoxButton', {
- text: gettext('Remove'),
- disabled: true,
- selModel: me.selModel,
- confirmMsg: function (rec) {
- return Ext.String.format(
- gettext('Are you sure you want to remove entry {0}'),
- "'" + rec.data.name + "'");
+ defaults: {
+ padding: '5 10 5 10',
+ },
+
+ bodyPadding: '5 0 5 0',
+
+ layout: {
+ type: 'vbox',
+ align: 'stretch',
+ },
+
+ scrollable: true,
+
+ items: [
+ {
+ xtype: 'panel',
+ bodyPadding: '10 10 10 10',
+ data: {
+ name: '',
+ },
+ bind: {
+ data: {
+ name: '{selectedRule.name:htmlEncode}',
+ priority: '{selectedRule.priority}',
+ active: '{selectedRule.active}',
+ direction: '{selectedRule.direction}',
+ selected: '{selectedRule}',
+ },
},
- handler: function(btn, event, rec) {
- console.dir(rec.data);
- Proxmox.Utils.API2Request({
- url: me.baseurl + '/' + rec.data.oclass + '/'+ rec.data.id,
- method: 'DELETE',
- waitMsgTarget: me,
- callback: function() {
- me.reload();
+ tpl: [
+ '<tpl if="selected">',
+ '<b>{name}</b><br><br>',
+ gettext('Priority') + ': {priority}<br>',
+ gettext('Direction') + ': {[PMG.Utils.format_rule_direction(values.direction)]}<br>',
+ gettext('Active') + ': {[Proxmox.Utils.format_boolean(values.active)]}<br>',
+ '<tpl else>',
+ gettext('Please select a rule.'),
+ '</tpl>',
+ ],
+ },
+ {
+ xtype: 'grid',
+ reference: 'usedobjects',
+ hidden: true,
+ emptyText: gettext('No Objects'),
+ features: [{
+ id: 'group',
+ ftype: 'grouping',
+ enableGroupingMenu: false,
+ collapsible: false,
+ groupHeaderTpl: [
+ '{[PMG.Utils.format_oclass(values.name)]}',
+ ],
+ }],
+
+ title: gettext('Used Objects'),
+
+ viewConfig: {
+ plugins: {
+ ptype: 'gridviewdragdrop',
+ copy: true,
+ dragGroup: 'usedobjects',
+ dropGroup: 'unusedobjects',
+
+ // do not show default grid dragdrop behaviour
+ dropZone: {
+ indicatorHtml: '',
+ indicatorCls: '',
+ handleNodeDrop: Ext.emptyFn,
},
- failure: function (response, opts) {
- Ext.Msg.alert(gettext('Error'), response.htmlStatus);
- }
- });
- }
- });
+ },
+ },
- var add_object_group = function(url, ogroupId) {
- Proxmox.Utils.API2Request({
- url: url,
- params: { ogroup: ogroupId },
- method: 'POST',
- waitMsgTarget: me,
- callback: function() {
- me.reload();
+ columns: [
+ {
+ header: gettext('Type'),
+ dataIndex: 'oclass',
+ hidden: true,
},
- failure: function (response, opts) {
- Ext.Msg.alert(gettext('Error'), response.htmlStatus);
- }
- });
- };
+ {
+ header: gettext('Name'),
+ dataIndex: 'name',
+ flex: 1,
+ },
+ {
+ text: '',
+ xtype: 'actioncolumn',
+ align: 'center',
+ width: 40,
+ items: [
+ {
+ iconCls: 'fa fa-fw fa-minus-circle',
+ tooltip: gettext('Remove'),
+ handler: 'removeIconClick',
+ },
+ ],
+ },
+ ],
- me.dockedItems = [];
+ bind: {
+ store: '{objects}',
+ hidden: '{!selectedRule}',
+ },
+ },
+ {
+ xtype: 'tabpanel',
+ title: gettext('Available Objects'),
+ reference: 'availobjects',
+ hidden: true,
+ bind: {
+ hidden: '{!selectedRule}',
+ },
+ defaults: {
+ xtype: 'grid',
+ emptyText: gettext('No Objects'),
+ viewConfig: {
+ plugins: {
+ ptype: 'gridviewdragdrop',
+ dragGroup: 'unusedobjects',
+ dropGroup: 'usedobjects',
- me.dockedItems.push({
- xtype: 'toolbar',
- dock: 'top',
+ // do not show default grid dragdrop behaviour
+ dropZone: {
+ indicatorHtml: '',
+ indicatorCls: '',
+ handleNodeDrop: Ext.emptyFn,
+ },
+ },
+ },
+ columns: [
+ {
+ header: gettext('Name'),
+ dataIndex: 'name',
+ flex: 1,
+ },
+ {
+ text: '',
+ xtype: 'actioncolumn',
+ align: 'center',
+ width: 40,
+ items: [
+ {
+ iconCls: 'fa fa-fw fa-plus-circle',
+ tooltip: gettext('Add'),
+ handler: 'addIconClick',
+ },
+ ],
+ },
+ ],
+ },
items: [
{
- text: gettext('From'),
- disabled: true,
- itemId: 'addFromButton',
- handler: function() {
- var win = Ext.create('PMG.ObjectGroupSelector', {
- rulegroup: 'from',
- listeners: {
- selectObjectGroup: function(view, rec) {
- win.destroy();
- add_object_group(me.baseurl + '/from', rec.data.id);
- }
- }
- });
- win.show();
- }
+ title: gettext('Action'),
+ bind: {
+ store: '{actionobjects}',
+ },
+ type: 'action',
+ iconCls: 'fa fa-flag',
},
{
- text: gettext('To'),
- disabled: true,
- itemId: 'addToButton',
- handler: function() {
- var win = Ext.create('PMG.ObjectGroupSelector', {
- rulegroup: 'to',
- listeners: {
- selectObjectGroup: function(view, rec) {
- win.destroy();
- add_object_group(me.baseurl + '/to', rec.data.id);
- }
- }
- });
- win.show();
- }
+ title: gettext('From'),
+ iconCls: 'fa fa-user-circle',
+ type: 'from',
+ bind: {
+ store: '{fromobjects}',
+ },
},
{
- text: gettext('When'),
- disabled: true,
- itemId: 'addWhenButton',
- handler: function() {
- var win = Ext.create('PMG.ObjectGroupSelector', {
- rulegroup: 'when',
- listeners: {
- selectObjectGroup: function(view, rec) {
- win.destroy();
- add_object_group(me.baseurl + '/when', rec.data.id);
- }
- }
- });
- win.show();
- }
+ title: gettext('To'),
+ iconCls: 'fa fa-user-circle',
+ type: 'to',
+ bind: {
+ store: '{toobjects}',
+ },
},
{
- text: gettext('What'),
- disabled: true,
- itemId: 'addWhatButton',
- handler: function() {
- var win = Ext.create('PMG.ObjectGroupSelector', {
- rulegroup: 'what',
- listeners: {
- selectObjectGroup: function(view, rec) {
- win.destroy();
- add_object_group(me.baseurl + '/what', rec.data.id);
- }
- }
- });
- win.show();
- }
+ title: gettext('What'),
+ iconCls: 'fa fa-cube',
+ type: 'what',
+ bind: {
+ store: '{whatobjects}',
+ },
},
{
- text: gettext('Action'),
- disabled: true,
- itemId: 'addActionButton',
- handler: function() {
- var win = Ext.create('PMG.ObjectGroupSelector', {
- rulegroup: 'action',
- listeners: {
- selectObjectGroup: function(view, rec) {
- win.destroy();
- add_object_group(me.baseurl + '/action', rec.data.ogroup);
- }
- }
- });
- win.show();
- }
+ title: gettext('When'),
+ iconCls: 'fa fa-clock-o',
+ type: 'when',
+ bind: {
+ store: '{whenobjects}',
+ },
},
- remove_btn
- ]
- });
-
- me.dockedItems.push({
- dock: 'top',
- border: 1,
- layout: 'anchor',
- itemId: 'ruledata',
- items: [
- {
- xtype: 'component',
- anchor: '100%',
- itemId: 'ruleinfo',
- style: { 'white-space': 'pre' },
- padding: 10,
- html: me.emptyText,
- listeners: {
- dblclick: {
- fn: function(e, t) {
- if (me.ruledata === undefined) { return; }
- me.fireEvent('dblclickRuleInfo', me, e, t, me.ruledata);
- },
- element: 'el',
- scope: this,
- }
- }
- }
- ]
- });
-
- Ext.apply(me, {
- listeners: {
- activate: function() { me.reload() }
- }
- });
-
- me.callParent();
-
- if (me.baseurl) {
- me.reload();
- }
- }
+ ],
+ },
+ ],
});