From 4e5c3529a547d1bfc4d4bdab93063e8b26b1005c Mon Sep 17 00:00:00 2001 From: camilevahviraki Date: Sat, 6 Sep 2025 04:39:36 +0200 Subject: [PATCH 1/3] refactor(frontend): Show sieve filter match type dropdown conditionnaly --- modules/imap/setup.php | 2 ++ modules/sievefilters/functions.php | 7 ------- modules/sievefilters/site.js | 21 ++++++++++++++++++++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/modules/imap/setup.php b/modules/imap/setup.php index e7ec865760..7f0cb05f88 100644 --- a/modules/imap/setup.php +++ b/modules/imap/setup.php @@ -16,6 +16,8 @@ /* add stuff to the info page */ add_output('info', 'display_imap_status', true, 'imap', 'server_status_start', 'after'); add_output('info', 'display_imap_capability', true, 'imap', 'server_capabilities_start', 'after'); +add_output('info', 'server_capabilities_end', true, 'developer', 'server_capabilities_start', 'after'); +add_output('info', 'config_map', true, 'developer', 'server_capabilities_end', 'after'); add_output('info', 'imap_server_ids', true, 'imap', 'page_js', 'before'); /* servers page data */ diff --git a/modules/sievefilters/functions.php b/modules/sievefilters/functions.php index 0db05d011c..ee819b35ae 100644 --- a/modules/sievefilters/functions.php +++ b/modules/sievefilters/functions.php @@ -46,13 +46,6 @@ function get_classic_filter_modal_content() -
- - -

Conditions & Actions

Filters must have at least one action and one condition diff --git a/modules/sievefilters/site.js b/modules/sievefilters/site.js index b189bbabb3..3815ee5781 100644 --- a/modules/sievefilters/site.js +++ b/modules/sievefilters/site.js @@ -630,7 +630,7 @@ function sieveFiltersPageHandler() { }); let extra_options = ''; $('.sieve_list_conditions_modal').append( - ' ' + + ' ' + ' ' + ' ' + + ' ' + + ' ' + + " " + + " of the following rules:" + + "
" + ); + } + } + } + /** * Add Condition Button */ $(document).on('click', '.sieve_add_condition_modal_button', function () { add_filter_condition(); + add_filter_match_mode(); }); function add_filter_action(default_value = '') { From 422b93021b484b06cd604c0190b43dcd9698dc74 Mon Sep 17 00:00:00 2001 From: camilevahviraki Date: Sat, 6 Sep 2025 22:25:28 +0200 Subject: [PATCH 2/3] feat: add sieve filter action drag and drop --- modules/imap/setup.php | 2 - modules/sievefilters/site.css | 6 +++ modules/sievefilters/site.js | 85 +++++++++++++++++++++-------------- 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/modules/imap/setup.php b/modules/imap/setup.php index 7f0cb05f88..e7ec865760 100644 --- a/modules/imap/setup.php +++ b/modules/imap/setup.php @@ -16,8 +16,6 @@ /* add stuff to the info page */ add_output('info', 'display_imap_status', true, 'imap', 'server_status_start', 'after'); add_output('info', 'display_imap_capability', true, 'imap', 'server_capabilities_start', 'after'); -add_output('info', 'server_capabilities_end', true, 'developer', 'server_capabilities_start', 'after'); -add_output('info', 'config_map', true, 'developer', 'server_capabilities_end', 'after'); add_output('info', 'imap_server_ids', true, 'imap', 'page_js', 'before'); /* servers page data */ diff --git a/modules/sievefilters/site.css b/modules/sievefilters/site.css index 124080c0b1..b0b13752f5 100644 --- a/modules/sievefilters/site.css +++ b/modules/sievefilters/site.css @@ -1,3 +1,9 @@ +.sortable-ghost { + background-color: var(--bs-secondary-bg-subtle); + border: 2px dashed var(--bs-secondary); + opacity: 0.6; +} + .tingle-modal * { box-sizing: border-box } diff --git a/modules/sievefilters/site.js b/modules/sievefilters/site.js index 3815ee5781..84a0d5ed69 100644 --- a/modules/sievefilters/site.js +++ b/modules/sievefilters/site.js @@ -10,56 +10,56 @@ var hm_sieve_condition_fields = function() { description: 'Subject', type: 'string', selected: true, - options: ['Contains', 'Matches', 'Regex'] + options: ['Contains', 'Matches', 'Regex'], }, { name: 'body', - description: 'Body', + description: 'Message body', type: 'string', - options: ['Contains', 'Matches', 'Regex'] + options: ['Contains', 'Matches', 'Regex'], }, { name: 'size', description: 'Size (KB)', type: 'int', - options: ['Over', 'Under'] - } + options: ['Over', 'Under'], + }, ], - 'Header': [ + Header: [ { name: 'to', - description: 'To', + description: 'Recipient (To)', type: 'string', extra_option: false, - options: ['Contains', 'Matches', 'Regex'] + options: ['Contains', 'Matches', 'Regex'], }, { name: 'from', - description: 'From', + description: 'Sender (From)', type: 'string', extra_option: false, - options: ['Contains', 'Matches', 'Regex'] + options: ['Contains', 'Matches', 'Regex'], }, { name: 'cc', - description: 'CC', + description: 'Copied recipient (CC)', type: 'string', extra_option: false, - options: ['Contains', 'Matches', 'Regex'] + options: ['Contains', 'Matches', 'Regex'], }, { name: 'to_or_cc', - description: 'To or CC', + description: 'Recipient (To or CC)', type: 'string', extra_option: false, - options: ['Contains', 'Matches', 'Regex'] + options: ['Contains', 'Matches', 'Regex'], }, { name: 'bcc', - description: 'BCC', + description: 'Blind copied recipient (BCC)', type: 'string', extra_option: false, - options: ['Contains', 'Matches', 'Regex'] + options: ['Contains', 'Matches', 'Regex'], }, { name: 'custom', @@ -67,9 +67,9 @@ var hm_sieve_condition_fields = function() { type: 'string', extra_option: true, extra_option_description: 'Field Name', - options: ['Contains', 'Matches', 'Regex'] - } - ] + options: ['Contains', 'Matches', 'Regex'], + }, + ], }; }; @@ -700,6 +700,19 @@ function sieveFiltersPageHandler() { add_filter_match_mode(); }); + /** + * Actions Drag and Drop + */ + const actionsTbody = document.querySelector(".filter_actions_modal_table"); + + if (actionsTbody) { + new Sortable(actionsTbody, { + handle: ".drag-handle", + animation: 150, + ghostClass: "sortable-ghost", + }); + } + function add_filter_action(default_value = '') { let possible_actions_html = ''; @@ -711,21 +724,25 @@ function sieveFiltersPageHandler() { possible_actions_html += ''; }); let extra_options = ''; - $('.filter_actions_modal_table').append( - '' + - ' ' + - ' ' + - ' ' + - extra_options + - ' ' + - ' ' + - ' ' + - ' ' + - ' Delete' + - ' ' + - '' + $(".filter_actions_modal_table").append( + '' + + ' ☰' + + ' ' + + ' " + + " " + + extra_options + + ' ' + + ' ' + + " " + + ' ' + + ' Delete' + + " " + + "" ); } From 4162bb263e36d5661d4820c6adfe805f7bc21bd7 Mon Sep 17 00:00:00 2001 From: camilevahviraki Date: Fri, 19 Sep 2025 13:35:50 +0200 Subject: [PATCH 3/3] Improve sieve filter layout --- modules/sievefilters/functions.php | 38 ++++++++++++------------ modules/sievefilters/site.css | 1 + modules/sievefilters/site.js | 47 ++++++++++++++++++++++++++---- 3 files changed, 61 insertions(+), 25 deletions(-) diff --git a/modules/sievefilters/functions.php b/modules/sievefilters/functions.php index ee819b35ae..408272e2ae 100644 --- a/modules/sievefilters/functions.php +++ b/modules/sievefilters/functions.php @@ -34,50 +34,44 @@ function get_script_modal_content() function get_classic_filter_modal_content() { return '
-
-

General

- Input a name and order for your filter. In filters, the order of execution is important. You can define an order value (or priority value) for your filter. Filters will run from lowest to highest priority value. -
-
+
+ Input the name for your filter.
-
+
-
-
-

Conditions & Actions

- Filters must have at least one action and one condition + In filters, the order of execution is important. Filters will run from lowest to highest priority value.
-
Conditions
-
-
- +

Conditions

-
+
+
+ +

-
Actions
-
-
- +

Actions

-
+
+
+ +

@@ -90,10 +84,14 @@ function get_classic_filter_modal_content()
+
+ Filters must have at least one action and one condition. +
'; } } + if (!hm_exists('get_mailbox_filters')) { function get_mailbox_filters($mailbox, $site_config, $user_config) { diff --git a/modules/sievefilters/site.css b/modules/sievefilters/site.css index b0b13752f5..bfa5b739f8 100644 --- a/modules/sievefilters/site.css +++ b/modules/sievefilters/site.css @@ -271,6 +271,7 @@ border: 1px solid #ccc; border-collapse: collapse; margin: 0; + margin-bottom: 1rem; padding: 0; width: 100%; } diff --git a/modules/sievefilters/site.js b/modules/sievefilters/site.js index 84a0d5ed69..9d022c5618 100644 --- a/modules/sievefilters/site.js +++ b/modules/sievefilters/site.js @@ -400,6 +400,31 @@ function sieveFiltersPageHandler() { /************************************************************************************** * FUNCTIONS **************************************************************************************/ + + function showErrorMsg(msg, parentClass, fadeTime = null) { + let $parent = $(parentClass); + + if (!$parent.data("highlight-added")) { + $parent.data("highlight-added", true); + $parent.addClass("highlight-active border border-info rounded p-2 bg-light"); + } + + let $msg = $('').text(msg); + + $parent.append($msg).show(); + + if (fadeTime !== null) { + setTimeout(function () { + $msg.remove(); + + if ($parent.data("highlight-added") && $parent.find("small").length === 0) { + $parent.removeClass("highlight-active border border-info rounded p-2 bg-light"); + $parent.removeData("highlight-added"); + } + }, fadeTime); + } + } + function save_filter(imap_account, gen_script = false) { let validation_failed = false let conditions_parsed = [] @@ -422,7 +447,11 @@ function sieveFiltersPageHandler() { let idx = 0; if (conditions.length === 0) { - Hm_Notices.show('You must provide at least one condition', 'warning'); + showErrorMsg( + "You must provide at least one condition", + ".sieve-filter-conditions-block", + 10000 + ); return false; } @@ -431,7 +460,11 @@ function sieveFiltersPageHandler() { let order = ordinal_number(key + 1); let previous_messages = $('.sys_messages').html(); previous_messages += previous_messages ? '
': ''; - Hm_Notices.show('The ' + order + ' condition (' + elem + ') must be provided', 'warning'); + showErrorMsg( + "The " + order + " condition (" + elem + ") must be provided", + ".sieve-filter-conditions-block", + 10000 + ); validation_failed = true; } conditions_parsed.push( @@ -460,7 +493,7 @@ function sieveFiltersPageHandler() { }).get(); if (actions_type.length === 0) { - Hm_Notices.show('You must provide at least one action', 'warning'); + showErrorMsg('You must provide at least one action', '.sieve-filter-actions-block', 10000); return false; } @@ -471,7 +504,11 @@ function sieveFiltersPageHandler() { let order = ordinal_number(key + 1); let previous_messages = $('.sys_messages').html(); previous_messages += previous_messages ? '
': ''; - Hm_Notices.show('The ' + order + ' action (' + elem + ') must be provided', 'waring'); + showErrorMsg( + "The " + order + " action (" + elem + ") must be provided", + ".sieve-filter-actions-block", + 10000 + ); validation_failed = true; } actions_parsed.push( @@ -496,7 +533,7 @@ function sieveFiltersPageHandler() { ) } if ($('.modal_sieve_filter_name').val() == "") { - Hm_Notices.show('Filter name is required', 'danger'); + showErrorMsg("Filter name is required", ".sieve-filter-name-group"); return false; }