Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions modules/desktop_notifications/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ $(function() {
setInterval(() => {
// undefined_undefined: load with no filter and no keyword
new Hm_MessagesStore('unread', getParam('list_page') || 1, 'undefined_undefined').load(true, true).then((store) => {

store.newMessages.forEach((messageRow) => {
triggerNewMessageEvent($(messageRow).data('uid'), $(messageRow)[0]);
});
Expand Down
2 changes: 1 addition & 1 deletion modules/imap/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ var setup_imap_folder_page = async function(listPath, listPage = 1) {
e.preventDefault();
$('#imap_filter_form').trigger('submit');
});

// try to fetch from cache but also reload messages, so user don't wait 60 seconds to see the new list (useful for read/unread UI and other updates)
await select_imap_folder(listPath, listPage, true);
handleMessagesDragAndDrop();
Expand Down
45 changes: 18 additions & 27 deletions modules/sievefilters/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,57 +34,44 @@ function get_script_modal_content()
function get_classic_filter_modal_content()
{
return '<div id="edit_filter_modal" class="d-none">
<div class="mb-2">
<h3 class="mb-1">General</h3>
<small>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.</small>
</div>
<div class="mb-2 mt-4">
<div class="sieve-filter-name-group mb-2 mt-4">
<label for="sieve-filter-name" class="form-label fw-bold">Filter Name:</label>
<input type="text" class="modal_sieve_filter_name form-control" placeholder="Your filter name" id="sieve-filter-name" />
<small class="form-text text-muted">Input the name for your filter.</small>
</div>
<div class="mb-2">
<div class="sieve-filter-priority-group mb-2">
<label for="sieve-filter-priority" class="form-label fw-bold">Priority:</label>
<input class="modal_sieve_filter_priority form-control" type="number" placeholder="0" id="sieve-filter-priority" />
</div>
<div class="mb-2">
<label for="sieve-filter-test" class="form-label fw-bold">Test:</label>
<select class="modal_sieve_filter_test form-control" name="test_type" placeholder="0" id="sieve-filter-test">
<option value="ANYOF">ANYOF (OR)</option>
<option value="ALLOF" selected>ALLOF (AND)</option>
</select>
</div>
<div class="d-block mb-2 mt-4">
<h3 class="mb-1">Conditions & Actions</h3>
<small>Filters must have at least one action and one condition</small>
<small class="form-text text-muted"> In filters, the order of execution is important. Filters will run from lowest to highest priority value.</small>
</div>
<div class="mt-2 rounded card">
<div class="p-3">
<div class="d-flex">
<div class="col-sm-10">
<h5 class="mt-0">Conditions</h5>
</div>
<div class="flex-grow-1 text-end">
<button class="sieve_add_condition_modal_button btn btn-sm border btn-primary">Add Condition</button>
<h4 class="mt-0">Conditions</h4>
</div>
</div>
<div class="d-block mt-3 table-responsive">
<div class="sieve-filter-conditions-block d-block mt-3 table-responsive">
<table class="sieve_list_conditions_modal table">
</table>
<div class="flex-grow-1 text-end">
<button class="sieve_add_condition_modal_button btn btn-sm border btn-primary"><i class="bi bi-plus-lg me-1"></i> Add Condition</button>
</div>
</div>
</div>
<hr/>
<div class="p-3">
<div class="d-flex">
<div class="col-sm-10">
<h5 class="mt-0">Actions</h5>
</div>
<div class="flex-grow-1 text-end">
<button class="filter_modal_add_action_btn btn btn-sm border btn-primary">Add Action</button>
<h4 class="mt-0">Actions</h4>
</div>
</div>
<div class="d-block mt-3 table-responsive">
<div class="sieve-filter-actions-block d-block mt-3 table-responsive">
<table class="filter_actions_modal_table table">
</table>
<div class="flex-grow-1 text-end">
<button class="filter_modal_add_action_btn btn btn-sm border btn-primary"><i class="bi bi-plus-lg me-1"></i> Add Action</button>
</div>
</div>
</div>
<hr/>
Expand All @@ -97,10 +84,14 @@ function get_classic_filter_modal_content()
</div>
</div>
</div>
<div class="filter-error-msgs d-block mb-2 mt-4">
<small class="form-text text-muted">Filters must have at least one action and one condition.</small>
</div>
</div>';
}
}


if (!hm_exists('get_mailbox_filters')) {
function get_mailbox_filters($mailbox, $site_config, $user_config)
{
Expand Down
7 changes: 7 additions & 0 deletions modules/sievefilters/site.css
Original file line number Diff line number Diff line change
@@ -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
}
Expand Down Expand Up @@ -265,6 +271,7 @@
border: 1px solid #ccc;
border-collapse: collapse;
margin: 0;
margin-bottom: 1rem;
padding: 0;
width: 100%;
}
Expand Down
153 changes: 113 additions & 40 deletions modules/sievefilters/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,66 +10,66 @@ 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',
description: 'Custom',
type: 'string',
extra_option: true,
extra_option_description: 'Field Name',
options: ['Contains', 'Matches', 'Regex']
}
]
options: ['Contains', 'Matches', 'Regex'],
},
],
};
};

Expand Down Expand Up @@ -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 = $('<small class="text-info d-block mt-1"></small>').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 = []
Expand All @@ -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;
}

Expand All @@ -431,7 +460,11 @@ function sieveFiltersPageHandler() {
let order = ordinal_number(key + 1);
let previous_messages = $('.sys_messages').html();
previous_messages += previous_messages ? '<br>': '';
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(
Expand Down Expand Up @@ -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;
}

Expand All @@ -471,7 +504,11 @@ function sieveFiltersPageHandler() {
let order = ordinal_number(key + 1);
let previous_messages = $('.sys_messages').html();
previous_messages += previous_messages ? '<br>': '';
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(
Expand All @@ -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;
}

Expand Down Expand Up @@ -630,7 +667,7 @@ function sieveFiltersPageHandler() {
});
let extra_options = '<td class="col-sm-3"><input type="hidden" class="condition_extra_value form-control form-control-sm" name="sieve_selected_extra_option_value[]" /></td>';
$('.sieve_list_conditions_modal').append(
' <tr>' +
' <tr class="sieve_condition_row">' +
' <td class="col-sm-2">' +
' <select class="add_condition_sieve_filters form-control form-control-sm" name="sieve_selected_conditions_field[]">' +
' <optgroup label="Message">' +
Expand Down Expand Up @@ -674,13 +711,45 @@ function sieveFiltersPageHandler() {
);
}

function add_filter_match_mode() {
let conditionRows = $(".sieve_list_conditions_modal tr").length;
if (conditionRows >= 2) {
if ($(".sieve_match_mode").length === 0) {
$(".sieve_list_conditions_modal").before(
'<div class="sieve_match_mode mb-2">' +
' <label class="me-2">Match</label>' +
' <select name="sieve_match_mode" class="modal_sieve_filter_test form-select-sm d-inline w-auto">' +
' <option value="ALLOF">ALL</option>' +
' <option value="ANYOF">ANY</option>' +
" </select>" +
" of the following rules:" +
"</div>"
);
}
}
}

/**
* Add Condition Button
*/
$(document).on('click', '.sieve_add_condition_modal_button', function () {
add_filter_condition();
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 = '';

Expand All @@ -692,21 +761,25 @@ function sieveFiltersPageHandler() {
possible_actions_html += '<option value="'+value.name+'">' + value.description + '</option>';
});
let extra_options = '<td class="col-sm-3"><input type="hidden" class="condition_extra_action_value form-control form-control-sm" name="sieve_selected_extra_action_value[]" /></td>';
$('.filter_actions_modal_table').append(
'<tr class="border" default_value="'+default_value+'">' +
' <td class="col-sm-3">' +
' <select class="sieve_actions_select form-control form-control-sm" name="sieve_selected_actions[]">' +
' ' + possible_actions_html +
' </select>' +
' </td>' +
extra_options +
' <td class="col-sm-5">' +
' <input type="hidden" name="sieve_selected_action_value[]" value="">' +
' </input>' +
' <td class="col-sm-1 text-end align-middle">' +
' <a href="#" class="delete_action_modal_button btn btn-sm btn-secondary">Delete</a>' +
' </td>' +
'</tr>'
$(".filter_actions_modal_table").append(
'<tr class="border draggable_action_row" default_value="' +
default_value +
'">' +
' <td class="col-sm-1 drag-handle" style="cursor: grab;">&#9776;</td>' +
' <td class="col-sm-3">' +
' <select class="sieve_actions_select form-control form-control-sm" name="sieve_selected_actions[]">' +
" " +
possible_actions_html +
" </select>" +
" </td>" +
extra_options +
' <td class="col-sm-5">' +
' <input type="hidden" name="sieve_selected_action_value[]" value="">' +
" </input>" +
' <td class="col-sm-1 text-end align-middle">' +
' <a href="#" class="delete_action_modal_button btn btn-sm btn-secondary">Delete</a>' +
" </td>" +
"</tr>"
);
}

Expand Down
Loading