feat(setup): wire storage data into regen, split candidate warnings

webuiGenerateStorageCandidates now runs as part of webuiSystemUpdate, so
frontend/data/storage.json exists without anyone remembering to generate
it — the wizard reads it to decide whether its Storage step appears, and
the Disks view reads the same file, so the two can never disagree.

Warnings arrive from the shell joined with "; ". Rendering that verbatim
produced one run-on paragraph that buried the fstab line the user is
supposed to copy, so the card splits them back onto separate lines.

Verified on the live install with lp-shot: with one filesystem the wizard
shows "Step 1 of 4" and the Storage step is correctly absent; with a
second filesystem attached it becomes "Step 4 of 5" with the drive
carrying a "needs care" badge and both warnings legible. That also
exercises the visible-step mapping in both directions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
librelad 2026-08-25 23:14:56 +01:00
parent cea653f67b
commit f5238f21ca
2 changed files with 10 additions and 2 deletions

View File

@ -422,7 +422,11 @@ class SetupWizard {
const refused = c.verdict === 'refuse';
const warned = c.verdict === 'warn';
const id = `sw-storage-${i}`;
const detail = refused ? c.refusals : (warned ? c.warnings : '');
// Checks are joined with "; " on the shell side. Split them back out:
// a drive can trip several at once, and one run-on paragraph buries the
// fstab line the user is meant to copy.
const detailParts = String((refused ? c.refusals : c.warnings) || '')
.split(/;\s+/).map(s => s.trim()).filter(Boolean);
const badge = refused
? '<span class="setup-storage-badge setup-storage-badge-bad">unusable</span>'
: (warned ? '<span class="setup-storage-badge setup-storage-badge-warn">needs care</span>' : '');
@ -435,7 +439,7 @@ class SetupWizard {
</span>
<span class="setup-app-desc">
${this.escapeHtml(c.fstype)} · ${this.escapeHtml(c.size)} (${this.escapeHtml(c.free)} free)${c.removable ? ' · removable' : ''}
${detail ? `<br><em>${this.escapeHtml(detail)}</em>` : ''}
${detailParts.length ? detailParts.map(d => `<br><em>${this.escapeHtml(d)}</em>`).join('') : ''}
</span>
</span>
</label>`;

View File

@ -11,6 +11,10 @@ webuiSystemUpdate() {
webuiSystemUpdateCheck
webuiSystemVerify
webuiSystemNetworkCheck
# Storage locations + candidate drives. The setup wizard reads this to
# decide whether its Storage step appears at all, and the Disks view reads
# the same file, so both always agree.
declare -f webuiGenerateStorageCandidates >/dev/null 2>&1 && webuiGenerateStorageCandidates
isSuccessful "System information updated!"
}