- Sidebar now groups items: Overview at top, a 'Config' heading over the config
categories, and the existing 'Tools' heading over SSH Access.
- Breadcrumb reflects the group: config pages read 'Config' (was 'Admin'), SSH
reads 'Tools', Overview stays 'Admin'.
- SSH Access page restyled to the config page's section layout
(.config-category/.domains-wrapper sections) instead of backup-style cards, so
it matches the other Admin config pages.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Add an Admin Overview as the Admin landing (default when you open Admin): an
ops/health board distinct from the user Dashboard. Four cards built from data
we already generate — Updates (update_status.json, with one-click update),
Backups (backup dashboard.json), SSH & Security (access.json), System
(disk/memory/system_info) — each with a Manage link into the right section.
Styled like the backup dashboard (tiles/status dots).
Wire-up: 'Overview' is the top sidebar item and the default category
(handleConfig + sidebar), rendered by AdminOverview into #config-section via a
renderConfig('overview') special case. Every Admin page now shows the same
'Admin' breadcrumb header (Overview, SSH Access, and the config categories) for
a consistent Admin → Section feel. User Dashboard gets an 'Admin overview →'
link.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Rename the Config top-nav to 'Admin' and move SSH Access into its sidebar
under a 'Tools' group, instead of a separate top-level nav item. SSH Access is
rendered by SshPage into the config main pane via a renderConfig('ssh-access')
special case; the sidebar item (config-sidebar.js) routes there. SshPage now
mounts into any container (defaults to #config-section). /ssh redirects to
/config?=ssh-access for old links; the standalone ssh-content.html is removed.
Declutters the top bar and gives system/admin features one home that scales
(updates, users, Connect settings can become sidebar entries later).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
- Display the restic engine as "Restic" to match BorgBackup/Kopia. The
lowercase name lived in scripts/backup/engines/restic.json (drives the
location-row engine pill, per-location engine select, and engine modal),
the hardcoded per-location dropdown options, the engine-list fallback, and
the config-option metadata. All set to "Restic".
- In each location's Engine dropdown, float the system-default engine
(CFG_BACKUP_ENGINE) to the top and tag it "(default)", mirroring the
retention-preset pattern.
Repo config metadata is the install template (add-only reconciliation), so
the live /docker/configs/backup/backup_engine label was updated in place too
for the global Configuration-tab dropdown on this install.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Drive the section title from the filename instead of the JS display-override
added earlier: rename configs/backup/backup_advanced -> backup_engine, update
the category SUBCATEGORY_ORDER and the file's header comment, and revert the
formatSubcategoryName override. The CFG_BACKUP_* keys are unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Empty tabs: generateSimpleTabsAndContent gated tabs on a hasFields heuristic
that drifted from what generateConfigFields actually emits, so a category like
Network could show a tab whose body only read "No configuration options
available". Render each category's fields first and emit the tab only when the
output is non-empty, keeping tabs and content in lockstep.
Rename: the backup_advanced subcategory now displays as "Engine" via a
display-name override in formatSubcategoryName. File and CFG_BACKUP_* keys are
unchanged, so saved values are unaffected.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
The location editor's Type, Path Mode, Engine and SSH Auth selects rendered
with no options. The config generator only scans flat per-category files and
never descends into configs/backup/locations/<n>/, so configData carries no
options for CFG_BACKUP_LOC_<n>_* keys — and the hardcoded fallbacks had been
removed in favour of generator-emitted ones.
Resolve these four dropdowns by suffix in ConfigOptions.getSelectOptions with
their static option lists (labels mirror location.config), so every location
works regardless of index — including locations added after install. The
global CFG_BACKUP_ENGINE/STRATEGY selects still come from the generator.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
CFG_BACKUP_VERIFY_DATA_PERCENT had no field-type case in config-shared.js so
it fell through to the default text input — no up/down stepper and no bounds.
Render it as a number input (min=1, max=100, % unit), which the custom-number
enhancer picks up automatically for the up/down controls.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Application backups were driven by one crontab entry per app, each offset by
id * CFG_BACKUP_CRONTAB_APP_INTERVAL minutes. That minute offset is written
straight into cron's 0-59 minute field, so past ~20 apps it overflowed into
an invalid entry that silently never fired, and the fixed spacing could not
serialize backups that ran longer than the gap.
Replace it with a single daily entry (`libreportal backup scheduled`) that
enqueues a backup task per enabled app. The existing systemd task processor
drains them serially — no minute overflow, real serialization, and backups
are now visible/cancellable in the Tasks UI. Per-app enable is read from
CFG_<APP>_BACKUP at schedule time instead of being mirrored into crontab.
Removes the stagger machinery (timing/setup/check/remove scripts), the
now-unused cron_jobs table + insert, and the CFG_BACKUP_CRONTAB_APP_INTERVAL
config knob and its WebUI field.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Add a config-divider after the header-only Danger Zone banner on the features page so a line separates it from the feature fields. Drop the now-redundant 24px top padding on .config-actions since the divider above the Save/Reset buttons already provides that spacing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Emit a config-divider before the Danger Zone / "Show Advanced Options" container in the shared renderer, so a line separates the regular fields from the advanced toggle — mirroring the dividers above Save/Reset and inside #advanced-sections. Applies to every config category.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Add a thin divider above the Save/Reset buttons, and one at the top of
#advanced-sections so a line appears between the "Show Advanced Options"
toggle and the advanced fields only when they're revealed. Shared config
renderer, so it applies to every config category (backup included).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
A free, open, self-hosted app platform (GNU AGPLv3): one-click app deploys,
Traefik reverse proxy with automatic SSL, rootless Docker support, gluetun
VPN routing, and a web dashboard to manage it all.
Free & open forever to self-host; optional paid hosted services fund it.
See PROMISE.md.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>