fix: improve alert acknowledgement button responsiveness

Add immediate visual feedback for alert acknowledgement buttons to resolve slow/unresponsive feel:
- Show spinning loader icon when acknowledge button is clicked
- Disable button during API call to prevent duplicate requests
- Add smooth transitions and proper error recovery
- Apply changes to both dropdown and modal acknowledgement buttons

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
rcourtman
2025-06-11 15:16:45 +01:00
parent 7256f9e460
commit 4c53a4308d
3 changed files with 45 additions and 2 deletions
+14
View File
@@ -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) {
* {
+29 -1
View File
@@ -431,7 +431,8 @@ PulseApp.alerts = (() => {
<div class="flex-shrink-0 space-x-1">
${!acknowledged ? `
<button onclick="PulseApp.alerts.acknowledgeAlert('${alert.id}', '${alert.ruleId}');"
class="text-xs px-1 py-0.5 bg-green-500 text-white rounded hover:bg-green-600 focus:outline-none"
class="text-xs px-1 py-0.5 bg-green-500 text-white rounded hover:bg-green-600 focus:outline-none transition-all"
data-alert-id="${alert.id}"
title="Acknowledge alert">
</button>
@@ -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 = '<span class="inline-block animate-spin">⟳</span>';
});
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);
}
}
+2 -1
View File
@@ -3817,7 +3817,8 @@ ${isEditing ? 'Update Alert' : 'Create Alert'}
<div class="flex gap-1 flex-wrap">
${!acknowledged ? `
<button onclick="PulseApp.alerts.acknowledgeAlert('${alert.id}', '${alert.ruleId}');"
class="px-2 py-1 text-xs bg-green-600 hover:bg-green-700 text-white rounded whitespace-nowrap">
class="px-2 py-1 text-xs bg-green-600 hover:bg-green-700 text-white rounded whitespace-nowrap transition-all"
data-alert-id="${alert.id}">
Acknowledge
</button>
` : ''}