A free, open, self-hosted app platform (GNU AGPLv3): one-click app deploys, Traefik reverse proxy with automatic SSL, rootless Docker support, gluetun VPN routing, and a web dashboard to manage it all. Free & open forever to self-host; optional paid hosted services fund it. See PROMISE.md. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
168 lines
5.2 KiB
JavaScript
Executable File
168 lines
5.2 KiB
JavaScript
Executable File
/**
|
||
* Confirmation Dialog - Simple and Working
|
||
*/
|
||
|
||
class ConfirmationDialog {
|
||
constructor() {
|
||
this.overlay = null;
|
||
this.dialog = null;
|
||
this.callback = null;
|
||
this.init();
|
||
}
|
||
|
||
init() {
|
||
// Create overlay
|
||
this.overlay = document.createElement('div');
|
||
this.overlay.className = 'confirmation-overlay';
|
||
|
||
// Create dialog as child of overlay
|
||
this.dialog = document.createElement('div');
|
||
this.dialog.className = 'confirmation-dialog';
|
||
|
||
// Add dialog INSIDE overlay
|
||
this.overlay.appendChild(this.dialog);
|
||
|
||
// Add overlay to body
|
||
document.body.appendChild(this.overlay);
|
||
|
||
// Event listeners
|
||
this.overlay.addEventListener('click', () => this.hide());
|
||
this.dialog.addEventListener('click', (e) => e.stopPropagation());
|
||
|
||
//console.log('Confirmation dialog initialized');
|
||
}
|
||
|
||
show(title, message, onConfirm, confirmText = 'Confirm', cancelText = 'Cancel', confirmClass = 'primary', showDataLossCheckbox = false) {
|
||
//console.log('Showing confirmation dialog');
|
||
|
||
this.callback = onConfirm;
|
||
|
||
// Build dialog content
|
||
this.dialog.innerHTML = `
|
||
<div class="confirmation-header">
|
||
<h3>${this.escapeHtml(title)}</h3>
|
||
<button class="confirmation-close" onclick="window.confirmationDialog.hide()">×</button>
|
||
</div>
|
||
<div class="confirmation-body">
|
||
<div class="confirmation-content">
|
||
<div class="confirmation-icon">⚠️</div>
|
||
<div class="confirmation-text">${this.escapeHtml(message)}</div>
|
||
</div>
|
||
${showDataLossCheckbox ? `
|
||
<div class="confirmation-checkbox">
|
||
<label>
|
||
<input type="checkbox" id="dataLossCheckbox" onchange="window.confirmationDialog.updateConfirmButton(this.checked)">
|
||
<span>I understand I will lose all my data and it cannot be undone</span>
|
||
</label>
|
||
</div>
|
||
` : ''}
|
||
</div>
|
||
<div class="confirmation-footer">
|
||
<button class="confirmation-btn confirmation-btn-cancel" onclick="window.confirmationDialog.hide()">${cancelText}</button>
|
||
<button class="confirmation-btn confirmation-btn-confirm confirmation-btn-${confirmClass}" id="confirmBtn" ${showDataLossCheckbox ? 'disabled' : ''} onclick="window.confirmationDialog.confirm(${showDataLossCheckbox})">${confirmText}</button>
|
||
</div>
|
||
`;
|
||
|
||
// Show dialog
|
||
this.overlay.classList.add('active');
|
||
|
||
// Debug: Check if class was added
|
||
//console.log('Active class added:', this.overlay.className);
|
||
//console.log('Has active class:', this.overlay.classList.contains('active'));
|
||
|
||
// Handle checkbox if present
|
||
if (showDataLossCheckbox) {
|
||
const checkbox = document.getElementById('dataLossCheckbox');
|
||
const confirmBtn = document.getElementById('confirmBtn');
|
||
// Initial state
|
||
this.updateConfirmButton(checkbox.checked);
|
||
}
|
||
|
||
// Escape key
|
||
const handleEscape = (e) => {
|
||
if (e.key === 'Escape') {
|
||
this.hide();
|
||
document.removeEventListener('keydown', handleEscape);
|
||
}
|
||
};
|
||
document.addEventListener('keydown', handleEscape);
|
||
|
||
//console.log('Confirmation dialog shown');
|
||
}
|
||
|
||
updateConfirmButton(isChecked) {
|
||
const confirmBtn = document.getElementById('confirmBtn');
|
||
if (confirmBtn) {
|
||
if (isChecked) {
|
||
confirmBtn.classList.add('confirmation-btn-ticked');
|
||
confirmBtn.disabled = false;
|
||
} else {
|
||
confirmBtn.classList.remove('confirmation-btn-ticked');
|
||
confirmBtn.disabled = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
confirm(showDataLossCheckbox) {
|
||
if (showDataLossCheckbox) {
|
||
const checkbox = document.getElementById('dataLossCheckbox');
|
||
if (!checkbox.checked) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
//console.log('Confirmation dialog confirmed');
|
||
if (this.callback) {
|
||
this.callback();
|
||
}
|
||
this.hide();
|
||
}
|
||
|
||
hide() {
|
||
//console.log('Hiding confirmation dialog');
|
||
//console.log('Before remove - classes:', this.overlay.className);
|
||
|
||
this.overlay.classList.remove('active');
|
||
|
||
//console.log('After remove - classes:', this.overlay.className);
|
||
//console.log('Has active class after remove:', this.overlay.classList.contains('active'));
|
||
|
||
this.callback = null;
|
||
}
|
||
|
||
escapeHtml(text) {
|
||
const div = document.createElement('div');
|
||
div.textContent = text;
|
||
return div.innerHTML;
|
||
}
|
||
}
|
||
|
||
// Initialize
|
||
let confirmationDialog = null;
|
||
|
||
// Initialize immediately when script loads
|
||
function initConfirmationDialog() {
|
||
if (!confirmationDialog) {
|
||
confirmationDialog = new ConfirmationDialog();
|
||
window.confirmationDialog = confirmationDialog;
|
||
}
|
||
}
|
||
|
||
// Confirmation dialog initialization is now handled by SystemLoader
|
||
// initConfirmationDialog() will be called centrally
|
||
|
||
// Global function
|
||
window.showConfirmation = (title, message, onConfirm, confirmText, cancelText, confirmClass, showDataLossCheckbox) => {
|
||
// Ensure dialog is initialized
|
||
initConfirmationDialog();
|
||
|
||
if (confirmationDialog) {
|
||
confirmationDialog.show(title, message, onConfirm, confirmText, cancelText, confirmClass, showDataLossCheckbox);
|
||
} else {
|
||
// Fallback to native confirm
|
||
if (confirm(message)) {
|
||
onConfirm();
|
||
}
|
||
}
|
||
};
|