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 52AA0947E2 for ; Thu, 22 Feb 2024 10:14:52 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 35C9F4BA6 for ; Thu, 22 Feb 2024 10:14:22 +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 ; Thu, 22 Feb 2024 10:14:21 +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 40BC6447C4 for ; Thu, 22 Feb 2024 10:14:21 +0100 (CET) From: Dominik Csapak To: pmg-devel@lists.proxmox.com Date: Thu, 22 Feb 2024 10:14:19 +0100 Message-Id: <20240222091420.2732402-3-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20240222091420.2732402-1-d.csapak@proxmox.com> References: <20240222091420.2732402-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.019 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 - URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [defines.mk] Subject: [pmg-devel] [PATCH pmg-gui v3 2/3] 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: Thu, 22 Feb 2024 09:14:52 -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. When the mode changes for an object group, we reload the list of objects since that holds the info about the attributes, so to avoid having to keep track in the gui which field changed on the group, we simply reload the list with the current information. Signed-off-by: Dominik Csapak --- js/Makefile | 1 + js/ObjectGroup.js | 68 +++++++++++++++++++++++++++++++++- js/ObjectGroupConfiguration.js | 2 + js/RuleInfo.js | 42 +++++++++++++++++++++ js/form/MatchModeSelector.js | 11 ++++++ 5 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 js/form/MatchModeSelector.js diff --git a/js/Makefile b/js/Makefile index 5f57e0d..2fb7d19 100644 --- a/js/Makefile +++ b/js/Makefile @@ -3,6 +3,7 @@ include ../defines.mk JSSRC= \ Utils.js \ form/FilterField.js \ + form/MatchModeSelector.js \ FilterProxy.js \ LoginView.js \ RoleSelector.js \ diff --git a/js/ObjectGroup.js b/js/ObjectGroup.js index 387fd54..214e641 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, + objectClass: undefined, emptyText: gettext('Please select an object.'), @@ -32,10 +33,15 @@ 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); + me.down('#whatWarning').setHidden(true); } else { let html = '' + Ext.String.htmlEncode(me.ogdata.name) + ''; html += "

"; @@ -43,6 +49,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.objectClass !== 'what' || mode === 'any'); } }, @@ -216,13 +228,51 @@ 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: 'pmgMatchModeSelector', + itemId: 'modeSelector', + padding: '10 0 0 0', + listeners: { + change: function(_field, value) { + let invert = value.startsWith('not') ? 1 : 0; + let and = value.endsWith('all') ? 1 : 0; + + Proxmox.Utils.API2Request({ + url: `${me.baseurl}/config`, + method: 'PUT', + params: { + and, + invert, + }, + success: () => me.fireEvent('modeUpdate', me), + }); + }, + }, + }, + ], + }, { xtype: 'component', - anchor: '100%', + flex: 1, itemId: 'oginfo', style: { 'white-space': 'pre' }, padding: 10, @@ -241,6 +291,20 @@ Ext.define('PMG.ObjectGroup', { ], }); + me.dockedItems.push({ + dock: 'top', + border: 1, + hidden: true, + itemId: 'whatWarning', + bodyPadding: 5, + items: { + xtype: 'displayfield', + margin: 0, + value: gettext("Caution: 'What Objects' match each mail part separately, so be careful with any option besides 'Any matches'."), + userCls: 'pmx-hint', + }, + }); + Proxmox.Utils.monStoreErrors(me, me.store, true); Ext.apply(me, { diff --git a/js/ObjectGroupConfiguration.js b/js/ObjectGroupConfiguration.js index 1d72851..eb80032 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, + objectClass: me.ogclass, border: false, region: 'center', listeners: { @@ -40,6 +41,7 @@ Ext.define('PMG.ObjectGroupConfiguration', { left.run_editor(); } }, + modeUpdate: () => left.reload(), }, }); diff --git a/js/RuleInfo.js b/js/RuleInfo.js index 404c437..12c9dcb 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,23 @@ 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: { 'treepanel[reference=usedobjects]': { drop: 'addDrop', @@ -169,6 +188,9 @@ Ext.define('PMG.RuleInfo', { 'tabpanel[reference=availobjects] > grid': { drop: 'removeDrop', }, + 'pmgMatchModeSelector': { + change: 'updateMode', + }, }, }, @@ -312,6 +334,26 @@ Ext.define('PMG.RuleInfo', { }, flex: 1, }, + { + 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', diff --git a/js/form/MatchModeSelector.js b/js/form/MatchModeSelector.js new file mode 100644 index 0000000..07f6e59 --- /dev/null +++ b/js/form/MatchModeSelector.js @@ -0,0 +1,11 @@ +Ext.define('PMG.MatchModeSelector', { + extend: 'Proxmox.form.KVComboBox', + alias: 'widget.pmgMatchModeSelector', + + comboItems: [ + ['all', gettext('All match')], + ['any', gettext('Any matches')], + ['notall', gettext('At least one does not match')], + ['notany', gettext('None matches')], + ], +}); -- 2.30.2