feat(scheduler): live admin Scheduler dashboard + reusable poll hook (HU/EN/DE)

New admin Scheduler page (left-nav entry) with a live, self-refreshing view of
job activity, queued work and quota. Polling is factored into a reusable
useLiveQuery hook (pauses when the tab is unfocused) that the notification bell
and future yt-dlp job queue will reuse instead of re-implementing.
This commit is contained in:
npeter83 2026-06-16 14:38:51 +02:00
parent a339a73bd6
commit 73b06b1fb6
13 changed files with 491 additions and 5 deletions

View file

@ -3,6 +3,7 @@
"searchPlaceholder": "Deine Abos durchsuchen…",
"channelManager": "Kanalverwaltung",
"usageStats": "Nutzung & Statistik",
"scheduler": "Planer",
"scope": {
"label": "Feed-Quelle",
"my": "Meine",
@ -16,6 +17,7 @@
"channels": "Kanäle",
"playlists": "Wiedergabelisten",
"stats": "Statistik",
"scheduler": "Planer",
"settings": "Einstellungen",
"about": "Über",
"signOut": "Abmelden",

View file

@ -0,0 +1,46 @@
{
"title": "Hintergrund-Planer",
"loading": "Planer wird geladen…",
"running": "Läuft",
"paused": "Pausiert",
"notHere": "Läuft in dieser Instanz nicht",
"notHereNote": "Der Planer läuft auf dem Server. Diese Instanz zeigt die gemeinsame Warteschlange und das Kontingent, aber die Live-Job-Aktivität erscheint nur dort, wo der Planer läuft.",
"updating": "wird aktualisiert…",
"pause": "Pausieren",
"resume": "Fortsetzen",
"pauseHint": "Die gesamte Hintergrund-Synchronisierung der App pausieren oder fortsetzen (für alle Nutzer).",
"toggleFailed": "Der Planer-Status konnte nicht geändert werden",
"jobsTitle": "Jobs",
"queueTitle": "Wartende Arbeit",
"quotaTitle": "Gemeinsames API-Kontingent",
"everyMin": "alle {{count}} Min",
"runningNow": "Läuft gerade…",
"lastRun": "Letzter Lauf {{time}}",
"neverRun": "In dieser Sitzung noch nicht gelaufen",
"active": "aktiv",
"nextRun": "nächster",
"quotaUsed": "{{used}} / {{budget}} Einheiten heute verbraucht",
"quotaRemaining": "{{formatted}} übrig",
"quotaNote": "Gemeinsames YouTube-Data-API-Budget; Reset um Mitternacht US-Pazifik. Backfill tritt zurück, um Spielraum für interaktive Nutzung zu lassen.",
"jobs": {
"rss_poll": "RSS-Abfrage (neue Uploads)",
"enrich": "Anreicherung + Live-Aktualisierung",
"backfill": "Backfill (aktuell + ganze Historie)",
"autotag": "Automatisches Tagging",
"shorts": "Shorts-Klassifizierung",
"subscriptions": "Abo-Resync",
"playlist_sync": "YouTube-Wiedergabelisten-Sync"
},
"queue": {
"recentPending": "Zu synchronisierende Kanäle",
"recentPendingHint": "Kanäle, deren neueste Uploads noch nicht abgerufen wurden.",
"deepPending": "Ganze Historie ausstehend",
"deepPendingHint": "Für vollständigen Verlauf vorgemerkte Kanäle, die noch nicht fertig sind.",
"enrichPending": "Zu anreichernde Videos",
"enrichPendingHint": "Videos, die noch auf Details warten (Dauer, Statistiken, Live-/Short-Klassifizierung).",
"shortsPending": "Zu klassifizierende Shorts",
"shortsPendingHint": "Bereits angereicherte Videos, die noch auf die Shorts-Prüfung warten.",
"liveRefresh": "Live zu aktualisieren",
"liveRefreshHint": "Live-/bevorstehende Videos (und gerade beendete Streams ohne Dauer), bis sie sich stabilisieren."
}
}