Harden aliasmanager, add live search, copy, ru_RU localization

This commit is contained in:
stuzer05 committed 2026-10-01 16:06:58 +03:00
1 parent a185391f9d
commit 86e2db4717
8 files changed
+395 -281

No files matched your search

+114 -74
View File
@@ -1,96 +1,136 @@
$(function() {
function updateAliasesList() {
const labels = rcmail.env.aliasmanager_labels || {};
function call(action, data, onSuccess) {
data = $.extend({_token: rcmail.env.request_token}, data);
$.ajax({
type: 'POST',
url: '/?_task=settings&_action=plugin.aliasmanager-get-alias-list',
url: rcmail.url('plugin.aliasmanager-' + action).replace(/&_unlock=[^&]*/, ''),
data: data,
dataType: 'json',
success: function(response) {
if (response.success) {
$('[name=alias_new_name]').val('');
// Clear table
$('.alias-list').html('');
// Make template
let template = $('template#alias-list-row').html();
for (let i = 0; i < response.data.alias_list.length; i++) {
const row = response.data.alias_list[i];
let tpl = template.replaceAll('{i}', i);
tpl = tpl.replaceAll('{email}', row.email);
tpl = tpl.replaceAll('{active}', row.active == 1);
tpl = tpl.replaceAll('{checked}', row.active == 1 ? 'checked' : '');
$('.alias-list').append(tpl);
}
onSuccess(response.data || {});
} else {
rcmail.display_message(response.message, 'error');
updateAliasesList();
}
},
dataType: 'json'
error: function() {
rcmail.display_message(labels.list_failed, 'error');
}
});
}
$(document).on('click', '.btn-aliasmanager-add-alias', function() {
const email = $('[name=alias_new_name]').val();
if (!/[a-z0-9]/.test(email)) {
function renderRow(row, i) {
const id = 'toggle-active-' + i;
const toggle = $('<input type="checkbox" class="form-check-input custom-control-input btn-aliasmanager-toggle-alias">')
.attr('id', id)
.attr('data-email', row.email)
.prop('checked', row.active);
const copy = $('<button type="button" class="button btn-sm btn-secondary btn-aliasmanager-copy-alias"></button>')
.attr('data-email', row.email)
.text(labels.copy);
const del = $('<button type="button" class="button btn-sm btn-danger btn-aliasmanager-delete-alias"></button>')
.attr('data-email', row.email)
.text(labels.delete);
return $('<tr class="form-group"></tr>')
.append($('<td></td>').append($('<span class="alias-email"></span>').text(row.email)))
.append($('<td></td>').text(row.created))
.append($('<td></td>').append(
$('<div class="custom-control custom-switch"></div>')
.append(toggle)
.append($('<label class="custom-control-label"></label>').attr('for', id))
))
.append($('<td></td>').append(copy, ' ', del));
}
function updateAliasesList() {
call('get-alias-list', {}, function(data) {
const list = $('.alias-list').empty();
data.alias_list.forEach(function(row, i) {
list.append(renderRow(row, i));
});
list.append($('<tr class="alias-empty-row"><td colspan="4" class="alias-empty"></td></tr>'));
applyFilter();
});
}
// Hides rows that do not match the search query, shows a placeholder row when nothing is left
function applyFilter() {
const query = $('#alias-search').val().trim().toLowerCase();
const rows = $('.alias-list tr').not('.alias-empty-row');
let visible = 0;
rows.each(function() {
const match = !query || $(this).find('.alias-email').text().toLowerCase().indexOf(query) !== -1;
$(this).toggle(match);
if (match) {
visible++;
}
});
$('.alias-empty-row')
.toggle(visible === 0)
.find('td')
.text(rows.length ? labels.no_matches : labels.empty);
}
let searchTimer;
$(document).on('input', '#alias-search', function() {
clearTimeout(searchTimer);
searchTimer = setTimeout(applyFilter, 250);
});
function addAlias() {
const input = $('[name=alias_new_name]');
const name = input.val().trim();
if (!/[a-z0-9]/i.test(name)) {
rcmail.display_message(labels.name_required, 'warning');
return;
}
$.ajax({
type: 'POST',
url: '/?_task=settings&_action=plugin.aliasmanager-add-alias',
data: {
email: email,
},
success: function(response) {
if (response.success) {
$('[name=alias_new_name]').val('');
updateAliasesList();
}
},
dataType: 'json'
call('add-alias', {email: name}, function() {
input.val('');
updateAliasesList();
});
})
}
$(document).on('submit', '#aliasmanager-form', function(e) {
e.preventDefault();
addAlias();
});
$(document).on('change', '.btn-aliasmanager-toggle-alias', function() {
const email = $(this).attr('data-email');
const isOn = $(this).is(':checked');
$.ajax({
type: 'POST',
url: '/?_task=settings&_action=plugin.aliasmanager-toggle-alias',
data: {
state: isOn,
email: email,
},
success: function(response) {
if (response.success) {
updateAliasesList();
}
},
dataType: 'json'
});
})
call('toggle-alias', {
email: $(this).attr('data-email'),
state: $(this).is(':checked'),
}, function() {});
});
$(document).on('click', '.btn-aliasmanager-delete-alias', function() {
const email = $(this).attr('data-email');
if (confirm(labels.confirm_delete + '\n' + $(this).attr('data-email'))) {
call('delete-alias', {email: $(this).attr('data-email')}, updateAliasesList);
}
});
if (confirm('You really want to delete ' + email + '?')) {
$.ajax({
type: 'POST',
url: '/?_task=settings&_action=plugin.aliasmanager-delete-alias',
data: {
email: email,
},
success: function(response) {
if (response.success) {
updateAliasesList();
}
},
dataType: 'json'
$(document).on('click', '.btn-aliasmanager-copy-alias', function() {
const text = $(this).attr('data-email');
if (navigator.clipboard) {
navigator.clipboard.writeText(text).then(function() {
rcmail.display_message(labels.copied, 'confirmation');
});
}
})
});
// Init
updateAliasesList()
});
updateAliasesList();
});