From 0b0fe3de40a866338b3d15a77e096659eb49e45b Mon Sep 17 00:00:00 2001 From: librelad Date: Sat, 1 Aug 2026 13:43:27 +0100 Subject: [PATCH] fix(backup): pair tags and paths on one row in snapshot details Tags and Paths were stacked full-width blocks, so a single tag chip and a single path each burned a whole row and left the panel mostly empty. Wrap them in a .bsm-blocks auto-fit grid that seats them side by side and falls back to stacking under ~460px. The wrapper now owns the divider, so it renders once for the pair instead of once per block, and is omitted entirely when neither block has content. Applied to both renderers of this markup: the global Backups view and the per-app backup card. Co-Authored-By: Claude Opus 5 --- .../components/backup/core/css/backup.css | 14 ++++++++++--- .../backup/snapshots/js/backup-snapshots.js | 21 +++++++++++-------- .../core/backup-card/js/backup-app-card.js | 21 +++++++++++-------- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/containers/libreportal/frontend/components/backup/core/css/backup.css b/containers/libreportal/frontend/components/backup/core/css/backup.css index b4be3a9..fc895c1 100755 --- a/containers/libreportal/frontend/components/backup/core/css/backup.css +++ b/containers/libreportal/frontend/components/backup/core/css/backup.css @@ -1356,7 +1356,7 @@ /* Snapshot detail panel. The shared .task-meta/.meta-item layout forces one nowrap line per item and clips long values (the full date, repo paths) mid-string, so the backup row gets its own label-over-value grid - plus full-width blocks for tags and paths that wrap cleanly. */ + plus a paired tags/paths row that wraps cleanly. */ .backup-snapshot-meta { display: flex; flex-direction: column; @@ -1398,12 +1398,20 @@ border-radius: 4px; word-break: break-all; } +/* Tags and paths sit side by side on one row, dropping to a single column + when the panel is too narrow to give both a readable width. */ +.backup-snapshot-meta .bsm-blocks { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 14px 18px; + padding-top: 13px; + border-top: 1px solid rgba(var(--text-rgb), 0.08); +} .backup-snapshot-meta .bsm-block { display: flex; flex-direction: column; gap: 8px; - padding-top: 13px; - border-top: 1px solid rgba(var(--text-rgb), 0.08); + min-width: 0; } .backup-snapshot-meta .bsm-tags { display: flex; diff --git a/containers/libreportal/frontend/components/backup/snapshots/js/backup-snapshots.js b/containers/libreportal/frontend/components/backup/snapshots/js/backup-snapshots.js index bf8067d..6036b18 100644 --- a/containers/libreportal/frontend/components/backup/snapshots/js/backup-snapshots.js +++ b/containers/libreportal/frontend/components/backup/snapshots/js/backup-snapshots.js @@ -109,15 +109,18 @@ Object.assign(BackupPage.prototype, { ${field('When', `${this.escape(this._fmtNiceTime(r.time))}`)} ${engineName ? field('Engine', this.escape(engineName)) : ''} - ${otherTags.length ? ` -
- Tags -
${otherTags.map(t => `${this.escape(t)}`).join('')}
-
` : ''} - ${r.paths && r.paths.length ? ` -
- Paths -
    ${r.paths.map(p => `
  • ${this.escape(p)}
  • `).join('')}
+ ${otherTags.length || (r.paths && r.paths.length) ? ` +
+ ${otherTags.length ? ` +
+ Tags +
${otherTags.map(t => `${this.escape(t)}`).join('')}
+
` : ''} + ${r.paths && r.paths.length ? ` +
+ Paths +
    ${r.paths.map(p => `
  • ${this.escape(p)}
  • `).join('')}
+
` : ''}
` : ''}
diff --git a/containers/libreportal/frontend/core/backup-card/js/backup-app-card.js b/containers/libreportal/frontend/core/backup-card/js/backup-app-card.js index f08d317..2b5f3b6 100644 --- a/containers/libreportal/frontend/core/backup-card/js/backup-app-card.js +++ b/containers/libreportal/frontend/core/backup-card/js/backup-app-card.js @@ -129,15 +129,18 @@ class BackupAppCard { ${field('When', `${this.escape(this._fmtNice(s.time))}`)} ${engineName ? field('Engine', this.escape(engineName)) : ''} - ${otherTags.length ? ` -
- Tags -
${otherTags.map(t => `${this.escape(t)}`).join('')}
-
` : ''} - ${s.paths && s.paths.length ? ` -
- Paths -
    ${s.paths.map(p => `
  • ${this.escape(p)}
  • `).join('')}
+ ${otherTags.length || (s.paths && s.paths.length) ? ` +
+ ${otherTags.length ? ` +
+ Tags +
${otherTags.map(t => `${this.escape(t)}`).join('')}
+
` : ''} + ${s.paths && s.paths.length ? ` +
+ Paths +
    ${s.paths.map(p => `
  • ${this.escape(p)}
  • `).join('')}
+
` : ''}
` : ''}