success: function(response, opts) {
me.setRuleInfo(response.result.data);
},
- failure: function (response, opts) {
+ failure: function(response, opts) {
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
- }
+ },
});
},
callback: function() {
me.reload();
},
- failure: function (response, opts) {
+ failure: function(response, opts) {
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
- }
+ },
});
}
- }
+ },
);
},
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 },
callback: function() {
me.reload();
},
- failure: function (response, opts) {
+ failure: function(response, opts) {
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
- }
+ },
});
},
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; }
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);
}
},
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: {
type: 'proxmox',
url: "/api2/json/config/ruledb/action/objects",
},
- sorters: 'name'
+ sorters: 'name',
},
fromobjects: {
model: 'pmg-object-group',
type: 'proxmox',
url: "/api2/json/config/ruledb/who",
},
- sorters: 'name'
+ sorters: 'name',
},
toobjects: {
model: 'pmg-object-group',
type: 'proxmox',
url: "/api2/json/config/ruledb/who",
},
- sorters: 'name'
+ sorters: 'name',
},
whatobjects: {
model: 'pmg-object-group',
type: 'proxmox',
url: "/api2/json/config/ruledb/what",
},
- sorters: 'name'
+ sorters: 'name',
},
whenobjects: {
model: 'pmg-object-group',
type: 'proxmox',
url: "/api2/json/config/ruledb/when",
},
- sorters: 'name'
+ sorters: 'name',
},
- }
+ },
},
layout: {
type: 'vbox',
- align: 'stretch'
+ align: 'stretch',
},
scrollable: true,
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,
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}',
},
},
{
reference: 'availobjects',
hidden: true,
bind: {
- hidden: '{!selectedRule}'
+ hidden: '{!selectedRule}',
},
defaults: {
xtype: 'grid',
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',
iconCls: 'fa fa-user-circle',
type: 'from',
bind: {
- store: '{fromobjects}'
+ store: '{fromobjects}',
},
},
{
iconCls: 'fa fa-user-circle',
type: 'to',
bind: {
- store: '{toobjects}'
+ store: '{toobjects}',
},
},
{
iconCls: 'fa fa-cube',
type: 'what',
bind: {
- store: '{whatobjects}'
+ store: '{whatobjects}',
},
},
{
iconCls: 'fa fa-clock-o',
type: 'when',
bind: {
- store: '{whenobjects}'
+ store: '{whenobjects}',
},
},
- ]
- }
- ]
+ ],
+ },
+ ],
});