From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 5093794277 for ; Fri, 9 Feb 2024 13:55:12 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 439503969F for ; Fri, 9 Feb 2024 13:54:46 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Fri, 9 Feb 2024 13:54:44 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 4B58E46820 for ; Fri, 9 Feb 2024 13:54:44 +0100 (CET) From: Dominik Csapak To: pmg-devel@lists.proxmox.com Date: Fri, 9 Feb 2024 13:54:40 +0100 Message-Id: <20240209125440.2572239-17-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20240209125440.2572239-1-d.csapak@proxmox.com> References: <20240209125440.2572239-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.020 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pmg-devel] [PATCH pmg-gui 2/2] rules/objects: add mode selector dropdown X-BeenThere: pmg-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Mail Gateway development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 09 Feb 2024 12:55:12 -0000 for objects and object types in rules. We add a simple dropdown for the 'and' and 'invert' flags, to be somewhat consistent with the notification matchers from pve and to make the wording more clear than simple and/invert. For What matches add a special warning hint, since that behaves a bit special because of the mail parts. Signed-off-by: Dominik Csapak --- js/Makefile | 1 + js/ObjectGroup.js | 64 ++++++++++++++++++++++++++++++++-- js/ObjectGroupConfiguration.js | 4 +++ js/RuleInfo.js | 44 +++++++++++++++++++++++ js/form/ModeSelector.js | 11 ++++++ 5 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 js/form/ModeSelector.js diff --git a/js/Makefile b/js/Makefile index 78f2b57..4267092 100644 --- a/js/Makefile +++ b/js/Makefile @@ -2,6 +2,7 @@ include ../defines.mk JSSRC= \ Utils.js \ + form/ModeSelector.js \ FilterProxy.js \ LoginView.js \ RoleSelector.js \ diff --git a/js/ObjectGroup.js b/js/ObjectGroup.js index 2223ffa..b91bf97 100644 --- a/js/ObjectGroup.js +++ b/js/ObjectGroup.js @@ -10,6 +10,7 @@ Ext.define('PMG.ObjectGroup', { showDirection: false, // only important for SMTP Whitelist ogdata: undefined, + oclass: undefined, emptyText: gettext('Please select an object.'), @@ -32,10 +33,14 @@ Ext.define('PMG.ObjectGroup', { setObjectInfo: function(ogdata) { let me = this; + let mode = ogdata.invert ? 'not' : ''; + mode += ogdata.and ? 'all' : 'any'; + me.ogdata = ogdata; if (me.ogdata === undefined) { me.down('#oginfo').update(me.emptyText); + me.down('#modeBox').setHidden(true); } else { let html = '' + Ext.String.htmlEncode(me.ogdata.name) + ''; html += "

"; @@ -43,6 +48,12 @@ Ext.define('PMG.ObjectGroup', { me.down('#oginfo').update(html); me.down('#ogdata').setHidden(false); + let modeSelector = me.down('#modeSelector'); + modeSelector.suspendEvents(); + me.down('#modeSelector').setValue(mode); + modeSelector.resumeEvents(); + me.down('#modeBox').setHidden(false); + me.down('#whatWarning').setHidden(me.oclass !== 'what'); } }, @@ -205,13 +216,62 @@ Ext.define('PMG.ObjectGroup', { me.dockedItems.push({ dock: 'top', border: 1, - layout: 'anchor', + layout: 'hbox', hidden: !!me.hideGroupInfo, itemId: 'ogdata', items: [ + { + xtype: 'container', + itemId: 'modeBox', + hidden: true, + width: 220, + padding: 10, + layout: { + type: 'vbox', + align: 'stretch', + }, + items: [ + { + xtype: 'box', + html: `${gettext("Match if")}`, + }, + { + xtype: 'pmgModeSelector', + itemId: 'modeSelector', + padding: '10 0 0 0', + listeners: { + change: function(_field, value) { + let invert = value.startsWith('not'); + let and = value.endsWith('all'); + + let url = `${me.baseurl}/config`; + + Proxmox.Utils.API2Request({ + url, + method: 'PUT', + params: { + and: and ? 1 : 0, + invert: invert ? 1 : 0, + }, + success: function() { + me.fireEvent('modeUpdate', me); + }, + }); + }, + }, + }, + { + xtype: 'displayfield', + itemId: 'whatWarning', + hidden: true, + value: gettext("Caution: What Objects match per mail part, so be careful with any option besides 'Any matches'."), + userCls: 'pmx-hint', + }, + ], + }, { xtype: 'component', - anchor: '100%', + flex: 1, itemId: 'oginfo', style: { 'white-space': 'pre' }, padding: 10, diff --git a/js/ObjectGroupConfiguration.js b/js/ObjectGroupConfiguration.js index 1d72851..f59f5ed 100644 --- a/js/ObjectGroupConfiguration.js +++ b/js/ObjectGroupConfiguration.js @@ -30,6 +30,7 @@ Ext.define('PMG.ObjectGroupConfiguration', { var right = Ext.create('PMG.ObjectGroup', { otype_list: me.otype_list, + oclass: me.ogclass, border: false, region: 'center', listeners: { @@ -40,6 +41,9 @@ Ext.define('PMG.ObjectGroupConfiguration', { left.run_editor(); } }, + modeUpdate: function() { + left.reload(); + }, }, }); diff --git a/js/RuleInfo.js b/js/RuleInfo.js index c29c0ca..d53c1c5 100644 --- a/js/RuleInfo.js +++ b/js/RuleInfo.js @@ -120,6 +120,8 @@ Ext.define('PMG.RuleInfo', { name: oc, oclass: oc, type: true, + invert: ruledata[`${oc}-invert`], + and: ruledata[`${oc}-and`], leaf: false, expanded: true, expandable: false, @@ -162,6 +164,25 @@ 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: function() { + me.reload(); + }, + }); + }, + control: { 'treepanel[reference=usedobjects]': { drop: 'addDrop', @@ -169,6 +190,9 @@ Ext.define('PMG.RuleInfo', { 'tabpanel[reference=availobjects] > grid': { drop: 'removeDrop', }, + 'pmgModeSelector': { + change: 'updateMode', + }, }, }, @@ -311,6 +335,26 @@ Ext.define('PMG.RuleInfo', { }, flex: 1, }, + { + header: gettext('Match if'), + xtype: 'widgetcolumn', + width: 200, + widget: { + xtype: 'pmgModeSelector', + }, + 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', diff --git a/js/form/ModeSelector.js b/js/form/ModeSelector.js new file mode 100644 index 0000000..9c9275b --- /dev/null +++ b/js/form/ModeSelector.js @@ -0,0 +1,11 @@ +Ext.define('PMG.ModeSelector', { + extend: 'Proxmox.form.KVComboBox', + alias: 'widget.pmgModeSelector', + + comboItems: [ + ['all', gettext('All match')], + ['any', gettext('Any matches')], + ['notall', gettext('At least one does not match')], + ['notany', gettext('None matches')], + ], +}); -- 2.30.2