From b79692c50a1b2713f3468917b8d15ef77645d29b Mon Sep 17 00:00:00 2001 From: Philip Weir <88682+johndoh@users.noreply.github.com> Date: Sat, 29 Nov 2025 17:26:44 +0000 Subject: [PATCH] managesieve: show warning when actions in wrong order (#10015) * managesieve: show warning when actions in wrong order * simplify action prioirty detection --- .../lib/Roundcube/rcube_sieve_engine.php | 3 +- plugins/managesieve/localization/en_US.inc | 1 + plugins/managesieve/managesieve.js | 35 +++++++++++++++++++ skins/elastic/styles/widgets/forms.less | 6 ++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php index df36fdf20..b5b8d308b 100644 --- a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php +++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php @@ -1649,7 +1649,8 @@ class rcube_sieve_engine $this->rc->output->add_label( 'managesieve.ruledeleteconfirm', - 'managesieve.actiondeleteconfirm' + 'managesieve.actiondeleteconfirm', + 'managesieve.saving.actionordererror' ); $this->rc->output->set_env('rule_disabled', !empty($scr['disabled'])); $this->rc->output->add_gui_object('sieveform', 'filterform'); diff --git a/plugins/managesieve/localization/en_US.inc b/plugins/managesieve/localization/en_US.inc index 2c69fac09..04750343e 100644 --- a/plugins/managesieve/localization/en_US.inc +++ b/plugins/managesieve/localization/en_US.inc @@ -283,3 +283,4 @@ $messages['duplicate.conflict.err'] = 'Both header and unique identifier are not $messages['disabledaction'] = 'Action not permitted.'; $messages['lastindexempty'] = 'Index is required when counting from end'; $messages['noflagset'] = 'At least one flag must be selected.'; +$messages['saving.actionordererror'] = 'The \'$previous\' action must be after the \'$current\' action.'; diff --git a/plugins/managesieve/managesieve.js b/plugins/managesieve/managesieve.js index de462f568..db11d978c 100644 --- a/plugins/managesieve/managesieve.js +++ b/plugins/managesieve/managesieve.js @@ -530,12 +530,47 @@ rcube_webmail.prototype.managesieve_save = function () { this.gui_objects.sieveform.elements._fid.value = parent.rcmail.filters_list.rows[id].uid; } } + + // validate action order e.g. setflag not after fileinto (#6590) + var action_priority_errors = { previous: null, current: null }; + var action_priority_last = 0; + $('#actions select[id^=action_type].error').removeClass('error is-invalid'); + $('#actions select[id^=action_type] option:selected').each(function (idx, elem) { + var priority = rcmail.managesieve_action_priority($(elem).val()); + + if (priority > action_priority_last) { + action_priority_errors.current = idx; + } else if (!action_priority_errors.current) { + action_priority_errors.previous = idx; + action_priority_last = priority; + } + }); + + if (action_priority_errors.current) { + $('#actions select[id^=action_type]').eq(action_priority_errors.previous).addClass('error is-invalid'); + $('#actions select[id^=action_type]').eq(action_priority_errors.current).addClass('error is-invalid'); + var action_priority_message = { previous: $('#actions select[id^=action_type] option:selected').eq(action_priority_errors.previous).text(), current: $('#actions select[id^=action_type] option:selected').eq(action_priority_errors.current).text() }; + this.display_message(this.get_label('managesieve.saving.actionordererror', null, action_priority_message), 'error'); + return; + } + this.gui_objects.sieveform.submit(); } else if (this.gui_objects.sievesetrawform) { this.gui_objects.sievesetrawform.submit(); } }; +rcube_webmail.prototype.managesieve_action_priority = function (val) { + switch (val) { + case 'fileinto': + return -1; + case 'stop': + return -2; + default: + return 0; + } +}; + // Operations on filters form rcube_webmail.prototype.managesieve_ruleadd = function (id) { this.http_post('plugin.managesieve-action', '_act=ruleadd&_rid=' + id); diff --git a/skins/elastic/styles/widgets/forms.less b/skins/elastic/styles/widgets/forms.less index 6e912f590..d89c6da43 100644 --- a/skins/elastic/styles/widgets/forms.less +++ b/skins/elastic/styles/widgets/forms.less @@ -1263,6 +1263,12 @@ body > li.recipient.ui-sortable-helper { .form-control { color: @color-font; + // override bootstap default behaviour (specifically prevent .is-invalid issues) + &.custom-select { + padding-right: 1.75rem; + background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px; + } + &:focus { color: @color-font; border-color: @color-input-border-focus;