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": "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",

View 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."
}
}