fix: remove inline JS handlers (onclick/onchange/onsubmit) -> event delegation + bump 0.4.4
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ipwhitelist",
|
||||
"version": "0.4.3",
|
||||
"version": "0.4.4",
|
||||
"description": "IP WhiteList microservice for cloud provider",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
|
||||
+51
-36
@@ -185,7 +185,7 @@
|
||||
<div class="card-body" style="padding:.75rem 1rem;">
|
||||
<form method="GET" action="/" style="display:flex;align-items:center;gap:1rem;flex-wrap:wrap;">
|
||||
<span style="font-size:.85rem;color:var(--muted);font-weight:500;">Компания:</span>
|
||||
<select name="company" onchange="this.form.submit()"
|
||||
<select name="company" id="company-select"
|
||||
style="padding:.4rem .75rem;border:1px solid var(--border);border-radius:6px;font-size:.85rem;background:#fff;">
|
||||
<% companies.forEach(c => { %>
|
||||
<option value="<%= c.id %>" <%= selectedCompany && c.id === selectedCompany.id ? 'selected' : '' %>>
|
||||
@@ -194,6 +194,7 @@
|
||||
<% }) %>
|
||||
</select>
|
||||
<!-- Быстрый доступ к admin-страницам прямо из главной -->
|
||||
<button type="submit" class="btn btn-sm">Выбрать</button>
|
||||
<a href="/audit<%= selectedCompany ? '?company=' + selectedCompany.id : '' %>"
|
||||
style="font-size:.82rem;color:var(--muted);text-decoration:none;">→ Аудит этой компании</a>
|
||||
<a href="/admin"
|
||||
@@ -296,19 +297,19 @@
|
||||
// Но в data-атрибуте JSON::stringify безопаснее.
|
||||
%>
|
||||
<!-- Кнопка редактирования: открывает modal и заполняет его данными из data-* -->
|
||||
<button class="btn"
|
||||
<button class="btn btn-edit"
|
||||
data-id="<%= e.id %>"
|
||||
data-value="<%= e.value_cidr %>"
|
||||
data-comment="<%= e.comment || '' %>"
|
||||
data-company="<%= companyPk || '' %>"
|
||||
onclick="openEditModal(this)"
|
||||
style="margin-right:.25rem;">
|
||||
Изменить
|
||||
</button>
|
||||
<!-- Форма удаления: company_id нужен для admin-ветки в server.js -->
|
||||
<form method="POST" action="/delete/<%= e.id %>"
|
||||
style="display:inline"
|
||||
onsubmit="return confirm('Удалить запись <%= e.value_cidr %>?')">
|
||||
class="delete-form"
|
||||
data-cidr="<%= e.value_cidr %>"
|
||||
style="display:inline">
|
||||
<input type="hidden" name="company_id" value="<%= companyPk || '' %>">
|
||||
<%# CSRF-токен: одно значение на всю страницу, сгенерировано сервером %>
|
||||
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
|
||||
@@ -361,7 +362,7 @@
|
||||
style="padding:.5rem .75rem;border:1px solid var(--border);border-radius:6px;font-size:.9rem;">
|
||||
</div>
|
||||
<div style="display:flex;gap:.75rem;justify-content:flex-end;">
|
||||
<button type="button" class="btn" onclick="closeEditModal()">Отмена</button>
|
||||
<button type="button" class="btn" id="edit-cancel">Отмена</button>
|
||||
<button type="submit" class="btn btn-primary">Сохранить</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -369,39 +370,53 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* Открыть modal редактирования.
|
||||
* Вызывается из onclick кнопки "Изменить" в таблице.
|
||||
* @param {HTMLElement} btn — кнопка с data-id, data-value, data-comment, data-company
|
||||
*/
|
||||
function openEditModal(btn) {
|
||||
// Заполняем поля из data-атрибутов (EJS уже HTML-экранировал значения)
|
||||
document.getElementById('edit-value').value = btn.dataset.value;
|
||||
document.getElementById('edit-comment').value = btn.dataset.comment;
|
||||
document.getElementById('edit-company-id').value = btn.dataset.company;
|
||||
// Устанавливаем action формы на конкретный /edit/:id
|
||||
document.getElementById('edit-form').action = '/edit/' + btn.dataset.id;
|
||||
// Показываем modal (display:flex для центрирования)
|
||||
const modal = document.getElementById('edit-modal');
|
||||
modal.style.display = 'flex';
|
||||
// Фокус на поле ввода для удобства клавиатурных пользователей
|
||||
setTimeout(() => document.getElementById('edit-value').focus(), 50);
|
||||
}
|
||||
(function () {
|
||||
var modal = document.getElementById('edit-modal');
|
||||
|
||||
/** Закрыть modal без сохранения */
|
||||
function closeEditModal() {
|
||||
document.getElementById('edit-modal').style.display = 'none';
|
||||
}
|
||||
function openModal(btn) {
|
||||
document.getElementById('edit-value').value = btn.getAttribute('data-value');
|
||||
document.getElementById('edit-comment').value = btn.getAttribute('data-comment');
|
||||
document.getElementById('edit-company-id').value = btn.getAttribute('data-company');
|
||||
document.getElementById('edit-form').action = '/edit/' + btn.getAttribute('data-id');
|
||||
modal.style.display = 'flex';
|
||||
setTimeout(function() { document.getElementById('edit-value').focus(); }, 50);
|
||||
}
|
||||
|
||||
// Закрытие кликом по backdrop (за пределами карточки)
|
||||
document.getElementById('edit-modal').addEventListener('click', function(e) {
|
||||
if (e.target === this) closeEditModal();
|
||||
});
|
||||
function closeModal() {
|
||||
modal.style.display = 'none';
|
||||
}
|
||||
|
||||
// Закрытие клавишей Escape
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') closeEditModal();
|
||||
});
|
||||
// Кнопки «Изменить» — event delegation на document
|
||||
document.addEventListener('click', function (e) {
|
||||
var btn = e.target.closest('.btn-edit');
|
||||
if (btn) { openModal(btn); return; }
|
||||
|
||||
var cancel = e.target.closest('#edit-cancel');
|
||||
if (cancel) { closeModal(); return; }
|
||||
|
||||
// Клик по backdrop
|
||||
if (e.target === modal) { closeModal(); return; }
|
||||
});
|
||||
|
||||
// Подтверждение удаления — event delegation
|
||||
document.addEventListener('submit', function (e) {
|
||||
var form = e.target.closest('.delete-form');
|
||||
if (!form) return;
|
||||
var cidr = form.getAttribute('data-cidr');
|
||||
if (!confirm('Удалить запись ' + cidr + '?')) e.preventDefault();
|
||||
});
|
||||
|
||||
// Смена компании — авто-сабмит при выборе
|
||||
var sel = document.getElementById('company-select');
|
||||
if (sel) {
|
||||
sel.addEventListener('change', function () { this.form.submit(); });
|
||||
}
|
||||
|
||||
// Escape закрывает modal
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Escape') closeModal();
|
||||
});
|
||||
}());
|
||||
</script>
|
||||
|
||||
<footer style="text-align:right;padding:.5rem 1.5rem;font-size:.72rem;color:var(--muted);">v<%= appVersion %></footer>
|
||||
|
||||
Reference in New Issue
Block a user