diff --git a/src/index.css b/src/index.css
index 474f40ea9..cf52205be 100644
--- a/src/index.css
+++ b/src/index.css
@@ -82,6 +82,20 @@ tr:hover td.sticky {
@apply bg-gray-50 dark:bg-gray-700 !important;
}
+/* Spin animation for loading indicators */
+@keyframes spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.animate-spin {
+ animation: spin 1s linear infinite;
+}
+
/* Respect user's motion preferences */
@media (prefers-reduced-motion: reduce) {
* {
diff --git a/src/public/js/alertsHandler.js b/src/public/js/alertsHandler.js
index af6abb7f4..bda2934b9 100644
--- a/src/public/js/alertsHandler.js
+++ b/src/public/js/alertsHandler.js
@@ -431,7 +431,8 @@ PulseApp.alerts = (() => {
${!acknowledged ? `
@@ -604,8 +605,25 @@ PulseApp.alerts = (() => {
}
}
+ // Track alerts currently being acknowledged to prevent duplicate requests
+ const acknowledgeInProgress = new Set();
+
async function acknowledgeAlert(alertId, ruleId) {
+ // Prevent duplicate acknowledgements
+ if (acknowledgeInProgress.has(alertId)) {
+ return;
+ }
+
+ acknowledgeInProgress.add(alertId);
+
try {
+ // Update button immediately to show loading state
+ const buttons = document.querySelectorAll(`button[data-alert-id="${alertId}"]`);
+ buttons.forEach(btn => {
+ btn.disabled = true;
+ btn.classList.add('opacity-50', 'cursor-not-allowed');
+ btn.innerHTML = '
⟳';
+ });
const response = await fetch(`/api/alerts/${alertId}/acknowledge`, {
method: 'POST',
@@ -640,6 +658,16 @@ PulseApp.alerts = (() => {
console.error('[Alerts] Failed to acknowledge alert:', error);
// Show user feedback for acknowledgment failures
showToastNotification(`Failed to acknowledge alert: ${error.message}`, 'error');
+
+ // Restore button state on error
+ const buttons = document.querySelectorAll(`button[data-alert-id="${alertId}"]`);
+ buttons.forEach(btn => {
+ btn.disabled = false;
+ btn.classList.remove('opacity-50', 'cursor-not-allowed');
+ btn.innerHTML = '✓';
+ });
+ } finally {
+ acknowledgeInProgress.delete(alertId);
}
}
diff --git a/src/public/js/ui/alertManagementModal.js b/src/public/js/ui/alertManagementModal.js
index cf853389c..7f7443a71 100644
--- a/src/public/js/ui/alertManagementModal.js
+++ b/src/public/js/ui/alertManagementModal.js
@@ -3817,7 +3817,8 @@ ${isEditing ? 'Update Alert' : 'Create Alert'}
${!acknowledged ? `
` : ''}