update UX: badge→modal flow, orange update button, Update All, toast notifications, workflow triggers

This commit is contained in:
Hermes
2026-05-27 23:57:32 -07:00
parent 11823a1466
commit 588188edb5
4 changed files with 125 additions and 17 deletions
+31 -9
View File
@@ -41,8 +41,11 @@
dismissedUpdates = new Set();
}
// Track global update state for cross-component access
let knownUpdates = [];
// Fetch update data and show badges
async function refreshCardUpdates() {
async function refreshCardUpdates(notifyNew) {
try {
const res = await fetch('/api/v1/updates/available');
const data = await res.json();
@@ -51,9 +54,21 @@
// Clear all update badges first
document.querySelectorAll('.update-available-badge').forEach(el => el.classList.remove('visible'));
if (!data.updates?.length) return;
const updates = data.updates || [];
knownUpdates = updates; // store globally
for (const upd of data.updates) {
// Notify if new updates appeared (periodic check with notification)
if (notifyNew && updates.length > 0) {
const prev = window._lastKnownUpdateCount || 0;
if (prev > 0 && updates.length > prev) {
showNotification(`${updates.length} container update(s) available — click Update Management to review.`, 'info');
}
window._lastKnownUpdateCount = updates.length;
}
if (!updates.length) return;
for (const upd of updates) {
// Try to match by container name to service id
const apps = window.APPS || [];
for (const app of apps) {
@@ -61,17 +76,24 @@
// Skip dismissed updates
if (dismissedUpdates.has(app.id)) break;
const badge = document.getElementById('update-badge-' + app.id);
const updateBtn = document.getElementById('update-btn-' + app.id);
if (badge) {
badge.classList.add('visible');
badge.title = `Image digest changed. Click to dismiss if already up to date.\n${upd.imageName || ''}`;
badge.title = `Update available — click to open Update Management.`;
badge.style.cursor = 'pointer';
badge.onclick = (e) => {
e.stopPropagation();
badge.classList.remove('visible');
dismissedUpdates.add(app.id);
safeSessionSet('dismissed-updates', JSON.stringify([...dismissedUpdates]));
// Open Update Management modal focused on this app
if (window.openUpdateModal) window.openUpdateModal(app.id);
};
}
// Highlight update button if update is available
if (updateBtn) {
updateBtn.style.background = '#f97316';
updateBtn.style.borderColor = '#f97316';
updateBtn.style.boxShadow = '0 0 6px #f9731688';
updateBtn.title = `Update available — click to open Update Management.`;
}
break;
}
}
@@ -90,10 +112,10 @@
refreshCardUpdates();
}, 5000);
// Periodic refresh every 60 seconds
// Periodic refresh every 60 seconds — notify on new updates detected
setInterval(() => {
refreshCardHealth();
refreshCardUpdates();
refreshCardUpdates(true); // true = notify if new updates found
}, 60000);
}