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:
parent
a339a73bd6
commit
73b06b1fb6
13 changed files with 491 additions and 5 deletions
|
|
@ -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",
|
||||
|
|
|
|||
46
frontend/src/i18n/locales/de/scheduler.json
Normal file
46
frontend/src/i18n/locales/de/scheduler.json
Normal 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."
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
"searchPlaceholder": "Search your subscriptions…",
|
||||
"channelManager": "Channel manager",
|
||||
"usageStats": "Usage & stats",
|
||||
"scheduler": "Scheduler",
|
||||
"scope": {
|
||||
"label": "Feed source",
|
||||
"my": "Mine",
|
||||
|
|
@ -16,6 +17,7 @@
|
|||
"channels": "Channels",
|
||||
"playlists": "Playlists",
|
||||
"stats": "Stats",
|
||||
"scheduler": "Scheduler",
|
||||
"settings": "Settings",
|
||||
"about": "About",
|
||||
"signOut": "Sign out",
|
||||
|
|
|
|||
46
frontend/src/i18n/locales/en/scheduler.json
Normal file
46
frontend/src/i18n/locales/en/scheduler.json
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"title": "Background scheduler",
|
||||
"loading": "Loading scheduler…",
|
||||
"running": "Running",
|
||||
"paused": "Paused",
|
||||
"notHere": "Not running in this instance",
|
||||
"notHereNote": "The scheduler runs on the server. This instance shows the shared queue and quota, but live job activity appears only where the scheduler runs.",
|
||||
"updating": "updating…",
|
||||
"pause": "Pause",
|
||||
"resume": "Resume",
|
||||
"pauseHint": "Pause or resume all background sync for the whole app (every user).",
|
||||
"toggleFailed": "Couldn't change the scheduler state",
|
||||
"jobsTitle": "Jobs",
|
||||
"queueTitle": "Work queued",
|
||||
"quotaTitle": "Shared API quota",
|
||||
"everyMin": "every {{count}} min",
|
||||
"runningNow": "Running now…",
|
||||
"lastRun": "Last run {{time}}",
|
||||
"neverRun": "Hasn't run yet this session",
|
||||
"active": "active",
|
||||
"nextRun": "next",
|
||||
"quotaUsed": "{{used}} / {{budget}} units used today",
|
||||
"quotaRemaining": "{{formatted}} left",
|
||||
"quotaNote": "Shared YouTube Data API budget; resets at midnight US Pacific. Backfill yields to leave headroom for interactive use.",
|
||||
"jobs": {
|
||||
"rss_poll": "RSS poll (new uploads)",
|
||||
"enrich": "Enrichment + live refresh",
|
||||
"backfill": "Backfill (recent + full history)",
|
||||
"autotag": "Auto-tagging",
|
||||
"shorts": "Shorts classification",
|
||||
"subscriptions": "Subscription resync",
|
||||
"playlist_sync": "YouTube playlist sync"
|
||||
},
|
||||
"queue": {
|
||||
"recentPending": "Channels to sync",
|
||||
"recentPendingHint": "Channels whose recent uploads haven't been fetched yet.",
|
||||
"deepPending": "Full-history pending",
|
||||
"deepPendingHint": "Channels opted into full-history backfill that aren't finished yet.",
|
||||
"enrichPending": "Videos to enrich",
|
||||
"enrichPendingHint": "Videos awaiting details (duration, stats, live/short classification).",
|
||||
"shortsPending": "Shorts to classify",
|
||||
"shortsPendingHint": "Enriched videos still awaiting the Shorts probe.",
|
||||
"liveRefresh": "Live to refresh",
|
||||
"liveRefreshHint": "Live/upcoming videos (and just-ended streams without a duration yet) re-checked until they settle."
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
"searchPlaceholder": "Keresés a feliratkozásaid között…",
|
||||
"channelManager": "Csatornakezelő",
|
||||
"usageStats": "Használat és statisztika",
|
||||
"scheduler": "Ütemező",
|
||||
"scope": {
|
||||
"label": "Hírfolyam forrása",
|
||||
"my": "Sajátom",
|
||||
|
|
@ -16,6 +17,7 @@
|
|||
"channels": "Csatornák",
|
||||
"playlists": "Lejátszási listák",
|
||||
"stats": "Statisztika",
|
||||
"scheduler": "Ütemező",
|
||||
"settings": "Beállítások",
|
||||
"about": "Névjegy",
|
||||
"signOut": "Kijelentkezés",
|
||||
|
|
|
|||
46
frontend/src/i18n/locales/hu/scheduler.json
Normal file
46
frontend/src/i18n/locales/hu/scheduler.json
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"title": "Háttér-ütemező",
|
||||
"loading": "Ütemező betöltése…",
|
||||
"running": "Fut",
|
||||
"paused": "Szüneteltetve",
|
||||
"notHere": "Ebben a példányban nem fut",
|
||||
"notHereNote": "Az ütemező a szerveren fut. Ez a példány a közös sort és kvótát mutatja, de az élő job-aktivitás csak ott látszik, ahol az ütemező fut.",
|
||||
"updating": "frissítés…",
|
||||
"pause": "Szüneteltetés",
|
||||
"resume": "Folytatás",
|
||||
"pauseHint": "A teljes app háttér-szinkronjának szüneteltetése vagy folytatása (minden felhasználóra).",
|
||||
"toggleFailed": "Nem sikerült módosítani az ütemező állapotát",
|
||||
"jobsTitle": "Feladatok",
|
||||
"queueTitle": "Sorban álló munka",
|
||||
"quotaTitle": "Közös API-kvóta",
|
||||
"everyMin": "{{count}} percenként",
|
||||
"runningNow": "Most fut…",
|
||||
"lastRun": "Utolsó futás {{time}}",
|
||||
"neverRun": "Ebben a munkamenetben még nem futott",
|
||||
"active": "aktív",
|
||||
"nextRun": "köv.",
|
||||
"quotaUsed": "{{used}} / {{budget}} egység ma felhasználva",
|
||||
"quotaRemaining": "{{formatted}} maradt",
|
||||
"quotaNote": "Közös YouTube Data API-keret; éjfélkor (US Pacific) nullázódik. A backfill hátrébb sorol, hogy maradjon hely az interaktív használatnak.",
|
||||
"jobs": {
|
||||
"rss_poll": "RSS-lekérdezés (új feltöltések)",
|
||||
"enrich": "Adatdúsítás + élő frissítés",
|
||||
"backfill": "Backfill (friss + teljes előzmény)",
|
||||
"autotag": "Automatikus címkézés",
|
||||
"shorts": "Shorts-besorolás",
|
||||
"subscriptions": "Feliratkozások újraszinkronja",
|
||||
"playlist_sync": "YouTube lejátszási listák szinkronja"
|
||||
},
|
||||
"queue": {
|
||||
"recentPending": "Szinkronra váró csatorna",
|
||||
"recentPendingHint": "Csatornák, amelyek friss feltöltéseit még nem kértük le.",
|
||||
"deepPending": "Teljes előzmény függőben",
|
||||
"deepPendingHint": "Teljes előzményre kijelölt csatornák, amelyek még nincsenek kész.",
|
||||
"enrichPending": "Dúsításra váró videó",
|
||||
"enrichPendingHint": "Videók, amelyek még adatokra várnak (hossz, statisztikák, live/short besorolás).",
|
||||
"shortsPending": "Besorolásra váró Shorts",
|
||||
"shortsPendingHint": "Már dúsított videók, amelyek még a Shorts-próbára várnak.",
|
||||
"liveRefresh": "Frissítendő élő",
|
||||
"liveRefreshHint": "Élő/közelgő videók (és a frissen véget ért, hossz nélküli adások), amíg le nem ülepednek."
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue