mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-11 03:06:54 +00:00
feat(system): background image update checker with stack badges
Adds an ImageUpdateService that queries OCI registry manifest endpoints every 6 hours to compare remote digests against local RepoDigests. Results are cached in a new stack_update_status SQLite table. A pulsing blue dot badge appears in the stack sidebar for stacks with updates available. Manual refresh available via POST /api/image-updates/refresh with a 10-minute rate limit.
This commit is contained in:
@@ -96,6 +96,9 @@ export default function EditorLayout() {
|
||||
const [logContainer, setLogContainer] = useState<{ id: string; name: string } | null>(null);
|
||||
|
||||
|
||||
// Image update checker state
|
||||
const [stackUpdates, setStackUpdates] = useState<Record<string, boolean>>({});
|
||||
|
||||
// Notifications & Settings state
|
||||
const [notifications, setNotifications] = useState<any[]>([]);
|
||||
const [settingsModalOpen, setSettingsModalOpen] = useState(false);
|
||||
@@ -172,6 +175,7 @@ export default function EditorLayout() {
|
||||
setIsEditing(false);
|
||||
setActiveView('dashboard');
|
||||
refreshStacks();
|
||||
fetchImageUpdates();
|
||||
}, [activeNode?.id]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
const fetchNotifications = async () => {
|
||||
@@ -184,6 +188,16 @@ export default function EditorLayout() {
|
||||
} catch (e) { }
|
||||
};
|
||||
|
||||
const fetchImageUpdates = async () => {
|
||||
try {
|
||||
const res = await apiFetch('/image-updates');
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
setStackUpdates(data);
|
||||
}
|
||||
} catch (e) { }
|
||||
};
|
||||
|
||||
const markAllRead = async () => {
|
||||
try {
|
||||
await apiFetch('/notifications/read', { method: 'POST' });
|
||||
@@ -769,6 +783,13 @@ export default function EditorLayout() {
|
||||
/>
|
||||
<span className="flex-1 truncate">{getDisplayName(file)}</span>
|
||||
|
||||
{stackUpdates[file] && (
|
||||
<span
|
||||
className="w-2 h-2 rounded-full bg-blue-400 animate-pulse shrink-0"
|
||||
title="Update available"
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0" onClick={(e) => e.stopPropagation()}>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
|
||||
Reference in New Issue
Block a user