librelad 79d2a4750d feat(webui): Phase 4 — Improvements (hotfix) stream + per-app chip
Surfaces the hotfix channel in the WebUI. Primary home is the Updates &
Improvements page (the updater component) — its own "Improvements" tab — with a
secondary chip on the App detail page (fork 3 locality = both).

Updater component (components/updater):
- New "Improvements" sidebar tab + panel; renderImprovements() reads the host-
  generated artifacts_available.json (severity badge, scope chip, applied/auto/
  not-applicable badges, plain-English why). Apply/Revert buttons dispatch
  artifact_apply / artifact_revert through the TASK system (services.tasks.route)
  — no mutating API. Apply is disabled when the index is UNSIGNED.
- Overview gains an "Improvements" stat card; task-refresh now also repaints on
  artifact_* task completion; URL tab routing + dispose teardown extended.

Task plumbing (core/tasks): artifactApply/artifactRevert action methods (id is
charset-guarded before it enters the command string) + artifact_apply/
artifact_revert routeAction cases. Task list/format gain icons + friendly labels.

Apps component: an amber " N improvements" chip on an installed app's detail
header (populated async from artifacts_available.json filtered by app, applicable
& not-applied), linking to /updater/improvements. Best-effort, never throws.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-31 21:07:01 +01:00

81 lines
4.3 KiB
HTML

<!-- App Updater page — layout mirrors the Backup page (shared .sidebar/.category
+ .page-header + .config-section card with a padded .updater-page-body).
Panels are filled by components/updater/updater-page.js. Page identity hue
(--page-updater, teal) is set on #updater-page. -->
<div class="container updater-layout">
<div class="mobile-overlay" id="mobile-overlay"></div>
<div class="sidebar" id="sidebar">
<div class="sidebar-section" id="updater-sidebar-list">
<div class="category active" data-updater-tab="overview">
<svg class="category-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="3" width="7" height="9"></rect><rect x="14" y="3" width="7" height="5"></rect>
<rect x="14" y="12" width="7" height="9"></rect><rect x="3" y="16" width="7" height="5"></rect>
</svg>
Overview
</div>
<div class="category" data-updater-tab="updates">
<svg class="category-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 3v12"></path><polyline points="7 8 12 3 17 8"></polyline><path d="M5 21h14"></path>
</svg>
Updates
</div>
<div class="category" data-updater-tab="improvements">
<svg class="category-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"></path>
</svg>
Improvements
</div>
<div class="category" data-updater-tab="security">
<svg class="category-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
</svg>
Security
</div>
<div class="category" data-updater-tab="recovery">
<svg class="category-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="1 4 1 10 7 10"></polyline><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path>
</svg>
Recovery
</div>
<div class="category" data-updater-tab="history">
<svg class="category-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"></circle><polyline points="12 7 12 12 15 14"></polyline>
</svg>
History
</div>
</div>
</div>
<div class="main">
<div class="updater-page" id="updater-page" style="--page: var(--page-updater); --page-rgb: var(--page-updater-rgb);">
<div class="config-section updater-page-section">
<div class="page-header" id="updater-page-header">
<div class="page-header-icon-slot" id="updater-page-header-icon"></div>
<div class="page-header-title">
<h1 id="updater-section-title">Overview</h1>
<p id="updater-section-subtitle">Update health, security posture, and recovery readiness at a glance.</p>
</div>
<div class="page-header-actions">
<button class="updater-btn" data-updater-action="check" title="Refresh versions &amp; vulnerabilities">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="23 4 23 10 17 10"></polyline>
<path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path>
</svg>
Check now
</button>
</div>
</div>
<div class="updater-page-body">
<section class="updater-tabpanel active" id="updater-panel-overview"></section>
<section class="updater-tabpanel" id="updater-panel-updates"></section>
<section class="updater-tabpanel" id="updater-panel-improvements"></section>
<section class="updater-tabpanel" id="updater-panel-security"></section>
<section class="updater-tabpanel" id="updater-panel-recovery"></section>
<section class="updater-tabpanel" id="updater-panel-history"></section>
</div>
</div>
</div>
</div>
</div>