From 02e4f7d6ab33e45caae7afc20e55f7cab4b6dd76 Mon Sep 17 00:00:00 2001 From: librelad Date: Sat, 23 May 2026 14:46:03 +0100 Subject: [PATCH] style(backup): match location editor tabs to the app-detail tab design MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reuse the shared .tabs-wrapper/.tab-button/.tab-panel components (same as an app's Config/Tasks tabs) for the location editor instead of bespoke tab CSS: emoji + label buttons, equal-width strip, accent active state. Panels toggle via the .active class like the rest of the UI; only the panel padding is trimmed so it nests inside the backup row. Also drop the now-dead 'No advanced options' empty state — every type has at least Engine + append-only in the Advanced tab. Co-Authored-By: Claude Opus 4.7 Signed-off-by: librelad --- .../libreportal/frontend/css/backup.css | 42 ++----------- .../js/components/backup/backup-page.js | 62 ++++++++++--------- 2 files changed, 39 insertions(+), 65 deletions(-) diff --git a/containers/libreportal/frontend/css/backup.css b/containers/libreportal/frontend/css/backup.css index 047bed5..bab47c4 100755 --- a/containers/libreportal/frontend/css/backup.css +++ b/containers/libreportal/frontend/css/backup.css @@ -723,44 +723,14 @@ border-top: 1px dashed rgba(var(--text-rgb), 0.08); } -/* Tabbed location editor (Connection | Retention | Advanced). Splits the - formerly long single form into one panel per concern. */ -.backup-loc-tabs { - display: flex; - gap: 4px; - border-bottom: 1px solid rgba(var(--text-rgb), 0.10); - margin-bottom: 16px; +/* The location editor reuses the app-detail tab design (.tabs-wrapper / + .tab-button / .tab-panel from style.css). Only trim the panel padding so it + sits inside the backup row's own padding instead of doubling it. */ +.backup-location-details .tab-panel { + padding: 16px 2px 2px; } -.backup-loc-tab { - appearance: none; - background: transparent; - border: none; - border-bottom: 2px solid transparent; - margin-bottom: -1px; - padding: 8px 14px; - color: rgba(var(--text-rgb), 0.6); - font: inherit; - font-size: 0.9rem; - font-weight: 600; - cursor: pointer; - transition: color 0.15s ease, border-color 0.15s ease; -} - -.backup-loc-tab:hover { - color: var(--text-primary); -} - -.backup-loc-tab.active { - color: var(--accent); - border-bottom-color: var(--accent); -} - -.backup-loc-tab-panel[hidden] { - display: none; -} - -.backup-loc-tab-panel > .category-description { +.backup-location-details .tab-panel > .category-description { margin-top: 0; margin-bottom: 12px; } diff --git a/containers/libreportal/frontend/js/components/backup/backup-page.js b/containers/libreportal/frontend/js/components/backup/backup-page.js index affb874..963fc84 100644 --- a/containers/libreportal/frontend/js/components/backup/backup-page.js +++ b/containers/libreportal/frontend/js/components/backup/backup-page.js @@ -215,7 +215,7 @@ class BackupPage { b.setAttribute('aria-selected', on ? 'true' : 'false'); }); root.querySelectorAll(`[data-tab-panel][data-loc="${tabIdx}"]`).forEach(p => { - p.toggleAttribute('hidden', p.dataset.tabPanel !== tabName); + p.classList.toggle('active', p.dataset.tabPanel === tabName); }); return; } @@ -678,35 +678,41 @@ class BackupPage { yearly: l.custom_retention ? (l.keep_yearly || '') : '' }; - const tab = (id, label) => ` - `; - const advancedBody = groups.advanced.length - ? this.renderLocFields(idx, groups.advanced, l) - : `
No advanced options for this location type.
`; + // Reuse the app-detail tab design (.tabs-wrapper/.tab-button/.tab-panel + // from style.css) so the Locations editor matches the rest of the UI. + const tab = (id, emoji, label) => ` + `; return `
-
- ${tab('connection', 'Connection')} - ${tab('retention', 'Retention')} - ${tab('advanced', 'Advanced')} -
-
-

How LibrePortal connects to this storage location.

-
- ${this.renderLocFields(idx, groups.connection, l)} +
+
+ ${tab('connection', '🔗', 'Connection')} + ${tab('retention', '♻️', 'Retention')} + ${tab('advanced', '⚙️', 'Advanced')}
-
- - @@ -776,9 +782,7 @@ class BackupPage { // applies to some types), so rebuild it alongside the Connection tab. const adv = document.getElementById(`backup-location-${idx}-advanced`); if (adv) { - adv.innerHTML = groups.advanced.length - ? this.renderLocFields(idx, groups.advanced, { ...loc, type }) - : `
No advanced options for this location type.
`; + adv.innerHTML = this.renderLocFields(idx, groups.advanced, { ...loc, type }); this.tagFieldsForSave(adv); }