diff --git a/weed/admin/static/js/admin.js b/weed/admin/static/js/admin.js index 175a424c5..b09790059 100644 --- a/weed/admin/static/js/admin.js +++ b/weed/admin/static/js/admin.js @@ -634,7 +634,7 @@ function formatDate(date) { function adminCopyToClipboard(text) { if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(() => { - showAlert('Copied to clipboard!', 'success'); + showToast('Copied to clipboard!'); }).catch(err => { console.error('Failed to copy text: ', err); fallbackCopyText(text); @@ -660,7 +660,7 @@ function fallbackCopyText(text) { try { const successful = document.execCommand('copy'); if (successful) { - showAlert('Copied to clipboard!', 'success'); + showToast('Copied to clipboard!'); } else { showAlert('Failed to copy to clipboard', 'danger'); } @@ -2265,11 +2265,11 @@ function copyFromInput(inputId) { try { const successful = document.execCommand('copy'); if (successful) { - showAlert('Copied to clipboard!', 'success'); + showToast('Copied to clipboard!'); } else { // Try modern clipboard API as fallback navigator.clipboard.writeText(input.value).then(() => { - showAlert('Copied to clipboard!', 'success'); + showToast('Copied to clipboard!'); }).catch(() => { showAlert('Failed to copy', 'danger'); }); @@ -2277,7 +2277,7 @@ function copyFromInput(inputId) { } catch (err) { // Try modern clipboard API as fallback navigator.clipboard.writeText(input.value).then(() => { - showAlert('Copied to clipboard!', 'success'); + showToast('Copied to clipboard!'); }).catch(() => { showAlert('Failed to copy', 'danger'); }); diff --git a/weed/admin/static/js/modal-alerts.js b/weed/admin/static/js/modal-alerts.js index e8ccd54b8..765561254 100644 --- a/weed/admin/static/js/modal-alerts.js +++ b/weed/admin/static/js/modal-alerts.js @@ -168,6 +168,36 @@ bsModal.show(); }; + /** + * Show a transient message that does not have to be dismissed + * @param {string} message - The message to display + * @param {string} type - Bootstrap contextual color, defaults to 'success' + */ + window.showToast = function (message, type) { + let container = document.getElementById('globalToastContainer'); + if (!container) { + container = document.createElement('div'); + container.id = 'globalToastContainer'; + container.className = 'toast-container position-fixed top-0 end-0 p-3'; + // Above any modal, however deeply they are stacked. + container.style.zIndex = '9999'; + document.body.appendChild(container); + } + + const toast = document.createElement('div'); + toast.className = 'toast align-items-center text-white bg-' + (type || 'success') + ' border-0'; + toast.setAttribute('role', 'alert'); + toast.innerHTML = '