diff --git a/server/src/wled_controller/static/app.js b/server/src/wled_controller/static/app.js index 235977e..bacb218 100644 --- a/server/src/wled_controller/static/app.js +++ b/server/src/wled_controller/static/app.js @@ -464,22 +464,22 @@ function createDeviceCard(device) {
${isProcessing ? ` - ` : ` - `} - - -
@@ -542,7 +542,8 @@ async function stopProcessing(deviceId) { } async function removeDevice(deviceId) { - if (!confirm('Are you sure you want to remove this device?')) { + const confirmed = await showConfirm(t('device.remove.confirm')); + if (!confirmed) { return; } @@ -603,6 +604,7 @@ async function showSettings(deviceId) { // Show modal const modal = document.getElementById('device-settings-modal'); modal.style.display = 'flex'; + document.body.classList.add('modal-open'); // Focus first input setTimeout(() => { @@ -620,6 +622,7 @@ function closeDeviceSettingsModal() { const error = document.getElementById('settings-error'); modal.style.display = 'none'; error.style.display = 'none'; + document.body.classList.remove('modal-open'); } async function saveDeviceSettings() { @@ -742,6 +745,40 @@ function showToast(message, type = 'info') { }, 3000); } +// Confirmation modal +let confirmResolve = null; + +function showConfirm(message, title = null) { + return new Promise((resolve) => { + confirmResolve = resolve; + + const modal = document.getElementById('confirm-modal'); + const titleEl = document.getElementById('confirm-title'); + const messageEl = document.getElementById('confirm-message'); + const yesBtn = document.getElementById('confirm-yes-btn'); + const noBtn = document.getElementById('confirm-no-btn'); + + titleEl.textContent = title || t('confirm.title'); + messageEl.textContent = message; + yesBtn.textContent = t('confirm.yes'); + noBtn.textContent = t('confirm.no'); + + modal.style.display = 'flex'; + document.body.classList.add('modal-open'); + }); +} + +function closeConfirmModal(result) { + const modal = document.getElementById('confirm-modal'); + modal.style.display = 'none'; + document.body.classList.remove('modal-open'); + + if (confirmResolve) { + confirmResolve(result); + confirmResolve = null; + } +} + // Calibration functions async function showCalibration(deviceId) { try { @@ -788,6 +825,7 @@ async function showCalibration(deviceId) { // Show modal const modal = document.getElementById('calibration-modal'); modal.style.display = 'flex'; + document.body.classList.add('modal-open'); } catch (error) { console.error('Failed to load calibration:', error); @@ -800,6 +838,7 @@ function closeCalibrationModal() { const error = document.getElementById('calibration-error'); modal.style.display = 'none'; error.style.display = 'none'; + document.body.classList.remove('modal-open'); } function updateCalibrationPreview() { diff --git a/server/src/wled_controller/static/index.html b/server/src/wled_controller/static/index.html index 9c1b848..8d064f6 100644 --- a/server/src/wled_controller/static/index.html +++ b/server/src/wled_controller/static/index.html @@ -86,6 +86,16 @@ + +
@@ -285,6 +295,22 @@ + + +