feat(updater): mirror auto-check line to fleet Updates tab; in-banner Check-now

Extends the per-app Updates treatment to the fleet App Center → Overview →
Updates list, and folds the manual check into the status line so it's the one
canonical (secondary) affordance rather than a top-level tab button:

- updater-page.js: renderAutoCheckLine() now ends with a right-aligned "↻ Check
  now" button (data-updater-action="check" — both surfaces already wire it).
- overview-manager.js: drop the "Check"/"Check now" button from the Updates tab
  header (keep "Update all", only when updates exist); lead renderUpdates() with
  the auto-check line.
- overview.css: .updater-autocheck wraps on narrow widths; .updater-autocheck-btn
  sits right (margin-left:auto), smaller.
- app-tabbed-manager.js: friendlier no-data copy ("You're all caught up — no
  updates found for this app.").

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
librelad 2026-07-18 23:10:49 +01:00
parent 3134afecd2
commit 1529776d5d
4 changed files with 16 additions and 6 deletions

View File

@ -594,7 +594,7 @@ class AppTabbedManager {
const autoLine = this.appUpdater.renderAutoCheckLine();
const body = app
? this.appUpdater.renderAppDetail(app, { includeVersion: true })
: `<div class="updater-empty">No scan data for this app yet — the first automatic check will fill this in shortly.</div>`;
: `<div class="updater-empty">You're all caught up — no updates found for this app.</div>`;
section.innerHTML = this.renderAppUpdaterHead(app) +
`<div class="updater-detail-container">${autoLine}${body}</div>`;
}

View File

@ -367,6 +367,7 @@
.updater-autocheck {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 9px;
margin: 0 0 14px;
padding: 9px 12px;
@ -377,6 +378,10 @@
color: rgba(var(--text-rgb), .72);
}
.updater-autocheck strong { color: var(--text-primary, #fff); font-weight: 600; }
.updater-autocheck-text { min-width: 0; }
/* Manual check lives here (right side), not as a top-level tab button a nudge
for the automatic scan, not the primary way updates are found. */
.updater-autocheck-btn { margin-left: auto; flex: 0 0 auto; padding: 4px 11px; font-size: .78rem; }
.updater-autocheck-dot {
width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto;
background: #36d399; box-shadow: 0 0 8px rgba(54, 211, 153, .6);

View File

@ -190,8 +190,10 @@ class OverviewManager {
const open = Array.from(document.querySelectorAll('#overview-view .ov-row-details:not([hidden])'))
.map((d) => d.id.replace(/^ov-detail-/, ''));
const anyUpdate = !!(this.updater && this.updater.apps.some((a) => a.update_available));
const actions = checkBtn('Check')
+ (anyUpdate ? ` <button class="updater-btn updater-btn-primary" data-updater-action="update-all">Update all</button>` : '');
// No manual "Check" in the header — the auto-check line at the top of the
// body carries the (secondary) Check-now nudge. Only the real "Update all"
// action lives up here, and only when there's actually something to apply.
const actions = anyUpdate ? `<button class="updater-btn updater-btn-primary" data-updater-action="update-all">Update all</button>` : '';
pane.innerHTML = this.renderHeader(id, actions) + body(this.renderUpdates());
open.forEach((app) => this._openDetail(app));
this._honorAppDeepLink();
@ -524,9 +526,11 @@ class OverviewManager {
const chip = (id, label, n) =>
`<button class="ov-chip${this.filter === id ? ' active' : ''}" data-overview-action="filter" data-filter="${id}">${label}${n != null ? ` <span class="ov-chip-n">${n}</span>` : ''}</button>`;
const rows = shown.map((a) => this.updateRow(a)).join('') || `<div class="updater-empty">Nothing matches this filter.</div>`;
// Check / Update all live in the tab header's action slot (renderTab), so
// the toolbar is just the filter chips.
// The auto-check line leads the body (with its right-side Check-now nudge);
// "Update all" lives in the tab header's action slot (renderTab), so the
// toolbar is just the filter chips.
return `
${up.renderAutoCheckLine()}
<div class="updater-toolbar ov-toolbar">
<div class="ov-chips">${chip('all', 'All', up.apps.length)}${chip('updates', 'Updates', nUpd)}${chip('security', 'Security', nSec)}</div>
</div>

View File

@ -575,7 +575,8 @@ class UpdaterPage {
nextBit = ` · next check ${this.fmtRelFuture(Date.parse(gen) + iv * 60000)}`;
}
return `<div class="updater-autocheck${off}"><span class="updater-autocheck-dot"></span>` +
`<span>Checked automatically · last checked <strong>${last}</strong>${nextBit}</span></div>`;
`<span class="updater-autocheck-text">Checked automatically · last checked <strong>${last}</strong>${nextBit}</span>` +
`<button class="updater-btn updater-autocheck-btn" data-updater-action="check" title="Check for updates now">↻ Check now</button></div>`;
}
}