mirror of
https://github.com/Joulenap/joulenap.git
synced 2026-08-11 13:21:43 +02:00
Let PVE/PBS run their own scheduled jobs (backup, prune, GC, sync) and use Joulenap purely as the power manager: at the scheduled time it wakes the PBS, watches its tasks, and powers it off once they have been quiet for a configurable window (issue #27). - backup.external config block (enabled, first_task_wait, idle_wait); both knobs are timeouts, not fixed delays — watching starts as soon as the first task appears, and the quiet countdown restarts whenever a new task starts, so staggered/chained jobs are never cut short - new monitor run kind + step: wake -> wait -> watch -> power off, recorded in run history with the number of tasks observed; a wake where no job ever appears still powers off and warns in the notification that the external schedule did not fire - monitor runs count as the backup slot for last-backup status and the missed-backup startup check - Schedule card mode switch (Scheduled by Joulenap / External schedules): external mode hides GC/retention/guest selection and shows the two timers with explanatory tooltips; manual panel runs the watch cycle instead of a backup and hides the GC button - notification titles, body lines and duration phase for the watch cycle, in both languages
Joulenap frontend
React + TypeScript + Vite SPA for Joulenap, recreated from the prototypes in
design/joulenap-remix/ and wired to the backend REST API.
Develop
cd frontend
npm install
npm run dev # Vite dev server on :5173, proxies /api -> http://localhost:8080
Run the backend (cd backend && joulenap or uvicorn app.main:create_app --factory)
alongside it so the proxied API is available.
Build
npm run build # type-checks (tsc --noEmit) then emits frontend/dist
The FastAPI backend serves frontend/dist as static files, so a production image just
needs the built output present. dist/ is git-ignored.
Layout
src/api/— typed client + response types for/api/*src/auth/,src/config/— auth + config React contextssrc/pages/—Login,Dashboard(+dashboard/panels),Settings(+settings/panels incl. the setup wizard)src/shell/— header + authenticated app shellsrc/components/,src/hooks/,src/utils/— shared widgets/helperssrc/i18n/—react-i18nextsetup;en.jsonis the base language,it.jsonthe translation
i18n
English is the source language. The active language follows app.language from the
backend config (the Localization settings panel changes it). Add a key to en.json
first, then mirror it in it.json.