]> git.proxmox.com Git - pmg-gui.git/blobdiff - js/RuleInfo.js
objects: don't reload on match mode change
[pmg-gui.git] / js / RuleInfo.js
index 91fef6f510ed16e4ed7e5e3fa1f15ce077bdb553..12c9dcb713962a93c2c44aba120f9092b59c94eb 100644 (file)
@@ -27,9 +27,9 @@ Ext.define('PMG.RuleInfo', {
                success: function(response, opts) {
                    me.setRuleInfo(response.result.data);
                },
-               failure: function (response, opts) {
+               failure: function(response, opts) {
                    Ext.Msg.alert(gettext('Error'), response.htmlStatus);
-               }
+               },
            });
        },
 
@@ -49,12 +49,12 @@ Ext.define('PMG.RuleInfo', {
                            callback: function() {
                                me.reload();
                            },
-                           failure: function (response, opts) {
+                           failure: function(response, opts) {
                                Ext.Msg.alert(gettext('Error'), response.htmlStatus);
-                           }
+                           },
                        });
                    }
-               }
+               },
            );
        },
 
@@ -62,7 +62,7 @@ Ext.define('PMG.RuleInfo', {
            var me = this;
            var baseurl = me.getViewModel().get('baseurl');
            var url = baseurl + '/' + type;
-           var id = (type === 'action')?record.data.ogroup:record.data.id;
+           var id = type === 'action'?record.data.ogroup:record.data.id;
            Proxmox.Utils.API2Request({
                url: url,
                params: { ogroup: id },
@@ -71,9 +71,9 @@ Ext.define('PMG.RuleInfo', {
                callback: function() {
                    me.reload();
                },
-               failure: function (response, opts) {
+               failure: function(response, opts) {
                    Ext.Msg.alert(gettext('Error'), response.htmlStatus);
-               }
+               },
            });
        },
 
@@ -83,18 +83,17 @@ Ext.define('PMG.RuleInfo', {
            var viewmodel = me.getViewModel();
 
            if (ruledata === undefined) {
-
                viewmodel.set('selectedRule', null);
                viewmodel.get('objects').setData([]);
-
            } else {
-
-               ruledata.name = Ext.String.htmlEncode(ruledata.name);
                viewmodel.set('selectedRule', ruledata);
 
-               var data = [];
+               let data = {
+                   leaf: false,
+                   expanded: true,
+                   children: [],
+               };
                Ext.Array.each(['from', 'to', 'when', 'what', 'action'], function(oc) {
-
                    var store = viewmodel.get(oc + 'objects');
                    if (ruledata[oc] === undefined || store === undefined) { return; }
 
@@ -105,23 +104,38 @@ Ext.define('PMG.RuleInfo', {
 
                    var ids = Ext.Array.pluck(ruledata[oc], 'id');
                    // for the actions, we have a different id field
-                   var idField = (oc === 'action')?'ogroup':'id';
+                   var idField = oc === 'action'?'ogroup':'id';
                    store.clearFilter();
                    store.addFilter({
-                       filterFn:function(record){
+                       filterFn: function(record) {
                            // FIXME
                            // actions have the ogroup as a string
                            // -> parseInt
-                           return (ids.indexOf(parseInt(record.data[idField])) === -1);
-                       }
+                           return ids.indexOf(parseInt(record.data[idField], 10)) === -1;
+                       },
                    });
                    store.load();
+
+                   let group = {
+                       name: oc,
+                       oclass: oc,
+                       type: true,
+                       invert: ruledata[`${oc}-invert`],
+                       and: ruledata[`${oc}-and`],
+                       leaf: false,
+                       expanded: true,
+                       expandable: false,
+                       children: [],
+                   };
                    Ext.Array.each(ruledata[oc], function(og) {
-                       data.push({ oclass: oc, name: og.name, typeid: og.id });
+                       group.children.push({ oclass: oc, name: og.name, typeid: og.id, leaf: true });
                    });
-               });
 
-               viewmodel.get('objects').setData(data);
+                   if (group.children.length) {
+                       data.children.push(group);
+                   }
+               });
+               viewmodel.get('objects').setRoot(data);
            }
        },
 
@@ -150,26 +164,47 @@ Ext.define('PMG.RuleInfo', {
            return true;
        },
 
+       updateMode: function(field, value) {
+           let me = this;
+           let vm = me.getViewModel();
+           let oclass = field.getWidgetRecord().data.oclass;
+
+           let params = {};
+           params[`${oclass}-invert`] = value.startsWith('not') ? 1 : 0;
+           params[`${oclass}-and`] = value.endsWith('all') ? 1 : 0;
+
+           Proxmox.Utils.API2Request({
+               url: `${vm.get('baseurl')}/config`,
+               method: 'PUT',
+               params,
+               success: () => me.reload(),
+           });
+       },
+
        control: {
-           'grid[reference=usedobjects]': {
-               drop: 'addDrop'
+           'treepanel[reference=usedobjects]': {
+               drop: 'addDrop',
            },
            'tabpanel[reference=availobjects] > grid': {
-               drop: 'removeDrop'
-           }
+               drop: 'removeDrop',
+           },
+           'pmgMatchModeSelector': {
+               change: 'updateMode',
+           },
        },
     },
 
     viewModel: {
        data: {
-           baseurl: undefined,
+           baseurl: '',
        },
 
        stores: {
            objects: {
+               type: 'tree',
                fields: ['oclass', 'name', 'typeid'],
                groupField: 'oclass',
-               sorters: 'name'
+               sorters: 'name',
            },
 
            actionobjects: {
@@ -178,7 +213,7 @@ Ext.define('PMG.RuleInfo', {
                    type: 'proxmox',
                    url: "/api2/json/config/ruledb/action/objects",
                },
-               sorters: 'name'
+               sorters: 'name',
            },
            fromobjects: {
                model: 'pmg-object-group',
@@ -186,7 +221,7 @@ Ext.define('PMG.RuleInfo', {
                    type: 'proxmox',
                    url: "/api2/json/config/ruledb/who",
                },
-               sorters: 'name'
+               sorters: 'name',
            },
            toobjects: {
                model: 'pmg-object-group',
@@ -194,7 +229,7 @@ Ext.define('PMG.RuleInfo', {
                    type: 'proxmox',
                    url: "/api2/json/config/ruledb/who",
                },
-               sorters: 'name'
+               sorters: 'name',
            },
            whatobjects: {
                model: 'pmg-object-group',
@@ -202,7 +237,7 @@ Ext.define('PMG.RuleInfo', {
                    type: 'proxmox',
                    url: "/api2/json/config/ruledb/what",
                },
-               sorters: 'name'
+               sorters: 'name',
            },
            whenobjects: {
                model: 'pmg-object-group',
@@ -210,9 +245,9 @@ Ext.define('PMG.RuleInfo', {
                    type: 'proxmox',
                    url: "/api2/json/config/ruledb/when",
                },
-               sorters: 'name'
+               sorters: 'name',
            },
-       }
+       },
     },
 
 
@@ -224,7 +259,7 @@ Ext.define('PMG.RuleInfo', {
 
     layout: {
        type: 'vbox',
-       align: 'stretch'
+       align: 'stretch',
     },
 
     scrollable: true,
@@ -232,48 +267,44 @@ Ext.define('PMG.RuleInfo', {
     items: [
        {
            xtype: 'panel',
-           bodyPadding: 10,
+           bodyPadding: '10 10 10 10',
            data: {
-               name: false,
+               name: '',
            },
            bind: {
                data: {
-                   name: '{selectedRule.name}',
+                   name: '{selectedRule.name:htmlEncode}',
                    priority: '{selectedRule.priority}',
                    active: '{selectedRule.active}',
                    direction: '{selectedRule.direction}',
-                   selected: '{selectedRule}'
-               }
+                   selected: '{selectedRule}',
+               },
            },
            tpl: [
                '<tpl if="selected">',
                '<b>{name}</b><br><br>',
-               'Priority: {priority}<br>',
-               'Direction: {[PMG.Utils.format_rule_direction(values.direction)]}<br>',
-               'Active: {[Proxmox.Utils.format_boolean(values.active)]}<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>'
+               '</tpl>',
            ],
        },
        {
-           xtype: 'grid',
+           xtype: 'treepanel',
            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'),
+           rootVisible: false,
+           useArrows: true,
+           rowLines: true,
+           userCls: 'pmx-rule-tree',
 
            viewConfig: {
+               getRowClass: record => record.data.type ? 'pmx-type-row' : '',
                plugins: {
                    ptype: 'gridviewdragdrop',
                    copy: true,
@@ -284,39 +315,64 @@ Ext.define('PMG.RuleInfo', {
                    dropZone: {
                        indicatorHtml: '',
                        indicatorCls: '',
-                       handleNodeDrop: Ext.emptyFn
-                   }
-               }
+                       handleNodeDrop: Ext.emptyFn,
+                   },
+               },
            },
 
            columns: [
-               {
-                   header: gettext('Type'),
-                   dataIndex: 'oclass',
-                   hidden: true,
-               },
                {
                    header: gettext('Name'),
                    dataIndex: 'name',
-                   flex: 1
+                   xtype: 'treecolumn',
+                   renderer: PMG.Utils.format_oclass,
+                   sorter: function(a, b) {
+                       if (a.data.type && b.data.type) {
+                           return a.data.oclass.localeCompare(b.data.oclass);
+                       }
+                       return a.data.text.localeCompare(b.data.text);
+                   },
+                   flex: 1,
                },
                {
-                   header: gettext('Actions'),
+                   header: gettext('Match if'),
+                   xtype: 'widgetcolumn',
+                   width: 200,
+                   widget: {
+                       xtype: 'pmgMatchModeSelector',
+                   },
+                   onWidgetAttach: function(col, widget, rec) {
+                       if (rec.data.type && rec.data.oclass !== 'action') {
+                           let mode = rec.data.invert ? 'not' : '';
+                           mode += rec.data.and ? 'all' : 'any';
+                           widget.suspendEvents();
+                           widget.setValue(mode);
+                           widget.resumeEvents();
+                           widget.setHidden(false);
+                       } else {
+                           widget.setHidden(true);
+                       }
+                   },
+               },
+               {
+                   text: '',
                    xtype: 'actioncolumn',
-                   width: 65,
+                   align: 'center',
+                   width: 40,
                    items: [
                        {
-                           iconCls: 'fa fa-fw fa-minus-circle',
                            tooltip: gettext('Remove'),
-                           handler: 'removeIconClick'
-                       }
-                   ]
-               }
+                           isActionDisabled: (v, rI, cI, i, rec) => rec.data.type,
+                           getClass: (v, mD, { data }) => data.type ? 'pmx-hidden' : 'fa fa-fw fa-minus-circle',
+                           handler: 'removeIconClick',
+                       },
+                   ],
+               },
            ],
 
            bind: {
                store: '{objects}',
-               hidden: '{!selectedRule}'
+               hidden: '{!selectedRule}',
            },
        },
        {
@@ -325,7 +381,7 @@ Ext.define('PMG.RuleInfo', {
            reference: 'availobjects',
            hidden: true,
            bind: {
-               hidden: '{!selectedRule}'
+               hidden: '{!selectedRule}',
            },
            defaults: {
                xtype: 'grid',
@@ -340,35 +396,36 @@ Ext.define('PMG.RuleInfo', {
                        dropZone: {
                            indicatorHtml: '',
                            indicatorCls: '',
-                           handleNodeDrop: Ext.emptyFn
-                       }
-                   }
+                           handleNodeDrop: Ext.emptyFn,
+                       },
+                   },
                },
                columns: [
                    {
                        header: gettext('Name'),
                        dataIndex: 'name',
-                       flex: 1
+                       flex: 1,
                    },
                    {
-                       header: gettext('Actions'),
-                       width: 65,
+                       text: '',
                        xtype: 'actioncolumn',
+                       align: 'center',
+                       width: 40,
                        items: [
                            {
                                iconCls: 'fa fa-fw fa-plus-circle',
                                tooltip: gettext('Add'),
-                               handler: 'addIconClick'
-                           }
-                       ]
-                   }
+                               handler: 'addIconClick',
+                           },
+                       ],
+                   },
                ],
            },
            items: [
                {
                    title: gettext('Action'),
                    bind: {
-                       store: '{actionobjects}'
+                       store: '{actionobjects}',
                    },
                    type: 'action',
                    iconCls: 'fa fa-flag',
@@ -378,7 +435,7 @@ Ext.define('PMG.RuleInfo', {
                    iconCls: 'fa fa-user-circle',
                    type: 'from',
                    bind: {
-                       store: '{fromobjects}'
+                       store: '{fromobjects}',
                    },
                },
                {
@@ -386,7 +443,7 @@ Ext.define('PMG.RuleInfo', {
                    iconCls: 'fa fa-user-circle',
                    type: 'to',
                    bind: {
-                       store: '{toobjects}'
+                       store: '{toobjects}',
                    },
                },
                {
@@ -394,7 +451,7 @@ Ext.define('PMG.RuleInfo', {
                    iconCls: 'fa fa-cube',
                    type: 'what',
                    bind: {
-                       store: '{whatobjects}'
+                       store: '{whatobjects}',
                    },
                },
                {
@@ -402,10 +459,10 @@ Ext.define('PMG.RuleInfo', {
                    iconCls: 'fa fa-clock-o',
                    type: 'when',
                    bind: {
-                       store: '{whenobjects}'
+                       store: '{whenobjects}',
                    },
                },
-           ]
-       }
-    ]
+           ],
+       },
+    ],
 });