diff --git a/apps/client/app/components/volume-file-browser.tsx b/apps/client/app/components/volume-file-browser.tsx index 0d144ed..1873fff 100644 --- a/apps/client/app/components/volume-file-browser.tsx +++ b/apps/client/app/components/volume-file-browser.tsx @@ -15,7 +15,6 @@ interface FileEntry { type VolumeFileBrowserProps = { volumeName: string; enabled?: boolean; - refetchInterval?: number | false; withCheckboxes?: boolean; selectedPaths?: Set; onSelectionChange?: (paths: Set) => void; @@ -28,7 +27,6 @@ type VolumeFileBrowserProps = { export const VolumeFileBrowser = ({ volumeName, enabled = true, - refetchInterval, withCheckboxes = false, selectedPaths, onSelectionChange, @@ -46,7 +44,6 @@ export const VolumeFileBrowser = ({ const { data, isLoading, error } = useQuery({ ...listFilesOptions({ path: { name: volumeName } }), enabled, - refetchInterval, }); useMemo(() => { diff --git a/apps/client/app/hooks/use-server-events.ts b/apps/client/app/hooks/use-server-events.ts index 8869dca..4b873aa 100644 --- a/apps/client/app/hooks/use-server-events.ts +++ b/apps/client/app/hooks/use-server-events.ts @@ -92,6 +92,17 @@ export function useServerEvents() { }); }); + eventSource.addEventListener("volume:status_updated", (e) => { + const data = JSON.parse(e.data) as VolumeEvent; + console.log("[SSE] Volume status updated:", data); + + queryClient.invalidateQueries(); + + handlersRef.current.get("volume:updated")?.forEach((handler) => { + handler(data); + }); + }); + eventSource.onerror = (error) => { console.error("[SSE] Connection error:", error); }; diff --git a/apps/client/app/modules/volumes/tabs/files.tsx b/apps/client/app/modules/volumes/tabs/files.tsx index 1e13028..9a2c4cc 100644 --- a/apps/client/app/modules/volumes/tabs/files.tsx +++ b/apps/client/app/modules/volumes/tabs/files.tsx @@ -30,7 +30,6 @@ export const FilesTabContent = ({ volume }: Props) => { void; - "backup:completed": (data: { scheduleId: number; volumeName: string; repositoryName: string; status: "success" | "error" }) => void; + "backup:completed": (data: { + scheduleId: number; + volumeName: string; + repositoryName: string; + status: "success" | "error"; + }) => void; "volume:mounted": (data: { volumeName: string }) => void; "volume:unmounted": (data: { volumeName: string }) => void; "volume:updated": (data: { volumeName: string }) => void; + "volume:status_changed": (data: { volumeName: string; status: string }) => void; } /** diff --git a/apps/server/src/modules/events/events.controller.ts b/apps/server/src/modules/events/events.controller.ts index f28e4cf..ee8f61d 100644 --- a/apps/server/src/modules/events/events.controller.ts +++ b/apps/server/src/modules/events/events.controller.ts @@ -75,7 +75,7 @@ export const eventsController = new Hono().get("/", (c) => { data: JSON.stringify({ timestamp: Date.now() }), event: "heartbeat", }); - await stream.sleep(30000); + await stream.sleep(5000); } }); }); diff --git a/apps/server/src/modules/volumes/volume.service.ts b/apps/server/src/modules/volumes/volume.service.ts index b7562bf..bf64a7b 100644 --- a/apps/server/src/modules/volumes/volume.service.ts +++ b/apps/server/src/modules/volumes/volume.service.ts @@ -224,6 +224,10 @@ const checkHealth = async (name: string) => { const backend = createVolumeBackend(volume); const { error, status } = await backend.checkHealth(); + if (status !== volume.status) { + serverEvents.emit("volume:status_changed", { volumeName: name, status }); + } + await db .update(volumesTable) .set({ lastHealthCheck: Date.now(), status, lastError: error ?? null })