Files
LaunchPad/apps/frontend/src/hooks/useScanActivity.ts

57 lines
1.7 KiB
TypeScript

import { useEffect, useState } from "react";
interface ScanActivity {
running: boolean;
pendingCount: number;
}
/**
* Geräteübergreifender Hinweis, ob gerade ein Scan läuft oder es
* unbestätigte Scan-Ergebnisse gibt - für ein Abzeichen am
* "Scanner"-Navigationspunkt, sichtbar von jeder Admin-Seite UND jedem
* Gerät/Browser aus, da der Zustand jetzt vom BACKEND abgefragt wird
* (siehe apps/backend/src/scanJobs.ts), nicht mehr aus dem lokalen
* sessionStorage des jeweiligen Browsers gelesen wird - Ersteres kann
* naturgemäß nicht geräteübergreifend sein.
*/
export function useScanActivity(): ScanActivity {
const [activity, setActivity] = useState<ScanActivity>({ running: false, pendingCount: 0 });
useEffect(() => {
let cancelled = false;
async function poll() {
try {
const [devicesRes, apisRes] = await Promise.all([
fetch("/api/scan/devices/all/status"),
fetch("/api/scan/apis/status"),
]);
if (cancelled) return;
const devicesStatus = devicesRes.ok ? await devicesRes.json() : null;
const apisStatus = apisRes.ok ? await apisRes.json() : null;
const running = !!devicesStatus?.running || !!apisStatus?.running;
const lastResult = devicesStatus?.lastResult;
const pendingCount = lastResult
? (lastResult.nameChanges?.length ?? 0) + (lastResult.staleServices?.length ?? 0)
: 0;
setActivity({ running, pendingCount });
} catch {
// Netzwerk-Hänger beim Poll ignorieren, nächster Versuch folgt.
}
}
poll();
const interval = setInterval(poll, 2000);
return () => {
cancelled = true;
clearInterval(interval);
};
}, []);
return activity;
}