diff --git a/containers/libreportal/frontend/components/apps/core/html/apps-unified-layout.html b/containers/libreportal/frontend/components/apps/core/html/apps-unified-layout.html index 61cfeaa..91832f3 100755 --- a/containers/libreportal/frontend/components/apps/core/html/apps-unified-layout.html +++ b/containers/libreportal/frontend/components/apps/core/html/apps-unified-layout.html @@ -9,7 +9,8 @@
+ onclick="if(window.navigateToRoute){window.navigateToRoute('/overview');}else{window.location.href='/overview';}" + onkeydown="if(event.key==='Enter'||event.key===' '){event.preventDefault();this.click();}">

Security

${ cves.length ? cveItems : '

No known CVEs. 🎉

'}
`; - const can = !!a.last_snapshot; - const snap = can + // A rollback target exists if a snapshot field is present (future-proofing) + // OR — the data the generator actually emits today — this app has a prior + // update/rollback in history (updater_apply always snapshots first, so that + // pre-update snapshot is the rollback point). Gating only on the never- + // written last_snapshot* fields would make the Roll back button unreachable. + const priorUpdate = ((this.history && this.history.entries) || []) + .some((e) => e.app === a.name && (e.action === 'update' || e.action === 'rollback')); + const can = !!a.last_snapshot || priorUpdate; + const snap = a.last_snapshot ? `${this.escape(a.last_snapshot_version || '')} · ${this.fmtRel(a.last_snapshot_at)}` - : 'A recovery snapshot is taken automatically before the next update.'; + : (priorUpdate + ? 'Roll back to the snapshot taken before the last update.' + : 'A recovery snapshot is taken automatically before the next update.'); const recovery = `

Recovery

${can ? 'recoverable' : 'protected'} ${snap}