Files
crowdsec-dashy/web/static/js/modal.js
T

121 lines
3.8 KiB
JavaScript

(function () {
'use strict';
var el = {};
var _resolve = null;
var _busy = false;
function build() {
el.overlay = document.createElement('div');
el.overlay.id = 'app-modal';
el.overlay.style.cssText = [
'display:none', 'position:fixed', 'inset:0',
'background:rgba(0,0,0,0.65)', 'z-index:9999',
'align-items:center', 'justify-content:center'
].join(';');
el.box = document.createElement('div');
el.box.style.cssText = [
'background:#0f1520', 'border:1px solid #1e2d45',
'border-radius:8px', 'padding:24px 28px',
'max-width:440px', 'width:calc(100% - 48px)',
'box-shadow:0 16px 48px rgba(0,0,0,0.6)'
].join(';');
el.msg = document.createElement('p');
el.msg.style.cssText = 'margin:0 0 20px;color:#c9d1d9;font-size:14px;line-height:1.6;white-space:pre-wrap';
el.row = document.createElement('div');
el.row.style.cssText = 'display:flex;gap:8px;justify-content:flex-end';
el.cancelBtn = document.createElement('button');
el.cancelBtn.textContent = 'Cancel';
el.cancelBtn.className = 'btn-ghost';
el.confirmBtn = document.createElement('button');
el.confirmBtn.className = 'btn-danger';
el.row.appendChild(el.cancelBtn);
el.row.appendChild(el.confirmBtn);
el.box.appendChild(el.msg);
el.box.appendChild(el.row);
el.overlay.appendChild(el.box);
document.body.appendChild(el.overlay);
el.cancelBtn.addEventListener('click', function () { close(false); });
el.confirmBtn.addEventListener('click', function () { close(true); });
el.overlay.addEventListener('click', function (e) {
if (e.target === el.overlay) close(false);
});
document.addEventListener('keydown', function (e) {
if (el.overlay && el.overlay.style.display !== 'none' && e.key === 'Escape') close(false);
});
}
function openModal(msg, confirmLabel, isDanger, showCancel) {
if (!el.overlay) build();
el.msg.textContent = msg;
el.confirmBtn.textContent = confirmLabel || 'OK';
el.confirmBtn.className = isDanger !== false ? 'btn-danger' : 'btn-primary';
el.cancelBtn.style.display = showCancel === false ? 'none' : '';
el.overlay.style.display = 'flex';
el.confirmBtn.focus();
return new Promise(function (res) { _resolve = res; });
}
function close(result) {
if (el.overlay) el.overlay.style.display = 'none';
if (_resolve) { _resolve(result); _resolve = null; }
}
window.appModal = {
// Confirmation dialog — returns Promise<boolean>
confirm: function (msg, label) {
return openModal(msg, label || 'Confirm', true, true);
},
// Info/alert dialog — returns Promise<void>
info: function (msg) {
return openModal(msg, 'OK', false, false);
}
};
// Auto-intercept: buttons/links with data-confirm or data-confirm-fn attribute.
document.addEventListener('click', function (e) {
if (_busy) return;
var btn = e.target.closest('[data-confirm], [data-confirm-fn]');
if (!btn) return;
e.preventDefault();
e.stopImmediatePropagation();
var msg;
if (btn.dataset.confirm) {
msg = btn.dataset.confirm;
} else {
var fn = window[btn.dataset.confirmFn];
if (typeof fn !== 'function') return;
msg = fn(); // returns message string, or null/'' to abort (fn may show its own info modal)
}
if (!msg) return;
var label = btn.dataset.confirmLabel || 'Confirm';
window.appModal.confirm(msg, label).then(function (ok) {
if (!ok) return;
_busy = true;
// requestSubmit includes button name/value and respects formaction
if (btn.form && typeof btn.form.requestSubmit === 'function') {
btn.form.requestSubmit(btn);
} else if (btn.form) {
btn.form.submit();
} else {
btn.click();
}
setTimeout(function () { _busy = false; }, 100);
});
}, true);
})();