Show the confirmed backup as a card, not a sentence
Moving the results under the Folder field kept the placement but threw away the presentation: the card became a line of prose. Path, snapshot count and age read better as a card, and that is what the found list already used. One renderer now serves both. The same fact should not look like two different things depending on whether it came from the scan or from pressing Check — only whether it is still a choice differs, so a pickable one is a <button> and a confirmed one is a <div> with a quiet accent edge and no hover. A card that looks clickable but is not is worse than one that does not. The geometry moved off the button-only selector for the same reason; the confirmed card is a div and was collapsing without it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
7fef102369
commit
853e51baac
@ -1570,7 +1570,8 @@ body.setup-wizard-open .custom-select-popup { z-index: 10001; }
|
||||
It cannot borrow .setup-app-card's look, because that class carries no
|
||||
layout of its own — it is a bare wrapper elsewhere, and a <button> with no
|
||||
layout collapses to a single cramped line. So this owns its geometry. */
|
||||
button.setup-found-backup {
|
||||
button.setup-found-backup,
|
||||
.setup-found-backup {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
@ -1586,8 +1587,8 @@ button.setup-found-backup {
|
||||
background: rgba(var(--text-rgb), 0.05);
|
||||
transition: border-color 0.15s ease, background 0.15s ease, transform 0.08s ease;
|
||||
}
|
||||
button.setup-found-backup .setup-app-name { font-weight: 600; }
|
||||
button.setup-found-backup .setup-app-desc {
|
||||
.setup-found-backup .setup-app-name { font-weight: 600; }
|
||||
.setup-found-backup .setup-app-desc {
|
||||
margin-left: auto;
|
||||
font-size: 0.85em;
|
||||
opacity: 0.72;
|
||||
@ -1603,6 +1604,15 @@ button.setup-found-backup:focus-visible {
|
||||
outline-offset: 2px;
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
button.setup-found-backup { flex-wrap: wrap; }
|
||||
button.setup-found-backup .setup-app-desc { margin-left: 0; width: 100%; }
|
||||
.setup-found-backup { flex-wrap: wrap; }
|
||||
.setup-found-backup .setup-app-desc { margin-left: 0; width: 100%; }
|
||||
}
|
||||
|
||||
/* The confirmed repository: the same card as a pickable one, but it is not a
|
||||
choice any more — no hover, no pointer, and a quiet accent edge so it reads
|
||||
as settled rather than waiting to be clicked. */
|
||||
.setup-found-chosen {
|
||||
cursor: default;
|
||||
border-color: rgba(79, 195, 247, 0.42);
|
||||
background: rgba(79, 195, 247, 0.07);
|
||||
}
|
||||
|
||||
@ -1114,6 +1114,24 @@ class SetupWizard {
|
||||
this.renderFoundBackups();
|
||||
}
|
||||
|
||||
// One repository, rendered. Used both for the list of what was found and for
|
||||
// the answer to Check: it is the same fact either way, and it should not look
|
||||
// like two different things depending on how it was arrived at.
|
||||
//
|
||||
// `tag` says which of the two it is, so a button is only a button when
|
||||
// there is actually something to choose.
|
||||
_backupCard(f, tag) {
|
||||
const badge = `${f.snapshots} snapshot${f.snapshots === 1 ? '' : 's'}`;
|
||||
const when = f.newest ? `newest ${this._restoreWhen(f.newest)}` : '';
|
||||
const body = `
|
||||
<span class="setup-app-name">${this.escapeHtml(f.path)}</span>
|
||||
<span class="setup-storage-badge setup-storage-badge-ok">${badge}</span>
|
||||
<span class="setup-app-desc">${when}</span>`;
|
||||
return tag === 'pick'
|
||||
? `<button type="button" class="setup-app-card setup-found-backup" data-found="${f._i}">${body}</button>`
|
||||
: `<div class="setup-app-card setup-found-backup setup-found-chosen">${body}</div>`;
|
||||
}
|
||||
|
||||
renderFoundBackups() {
|
||||
const box = this.container.querySelector('#sw-rs-found');
|
||||
if (!box) return;
|
||||
@ -1138,12 +1156,7 @@ class SetupWizard {
|
||||
|
||||
box.innerHTML =
|
||||
`<p class="setup-section-hint">Backups found on this machine \u2014 pick one:</p>` +
|
||||
found.map((f, i) => `
|
||||
<button type="button" class="setup-app-card setup-found-backup" data-found="${i}">
|
||||
<span class="setup-app-name">${this.escapeHtml(f.path)}</span>
|
||||
<span class="setup-storage-badge setup-storage-badge-ok">${f.snapshots} snapshot${f.snapshots === 1 ? '' : 's'}</span>
|
||||
<span class="setup-app-desc">${f.newest ? 'newest ' + this._restoreWhen(f.newest) : ''}</span>
|
||||
</button>`).join('');
|
||||
found.map((f, i) => this._backupCard(Object.assign({ _i: i }, f), 'pick')).join('');
|
||||
|
||||
this._adoptSingleResult();
|
||||
|
||||
@ -1219,10 +1232,8 @@ class SetupWizard {
|
||||
const box = this.container.querySelector('#sw-rs-verify-result');
|
||||
if (!box) return;
|
||||
if (d && d.repo) {
|
||||
box.innerHTML = `<p class="setup-rs-ok">Backup found \u2014
|
||||
<strong>${d.snapshots} snapshot${d.snapshots === 1 ? '' : 's'}</strong>${
|
||||
d.newest ? `, newest ${this._restoreWhen(d.newest)}` : ''}.
|
||||
Enter its password to see what is inside.</p>`;
|
||||
box.innerHTML = this._backupCard(d, 'chosen') +
|
||||
`<p class="setup-section-hint">Enter its password below to see what is inside.</p>`;
|
||||
return;
|
||||
}
|
||||
// A suggestion means they pointed at the folder holding the repositories
|
||||
|
||||
@ -143,6 +143,15 @@ read -r -d '' DRIVE <<'JS'
|
||||
w.renderFoundBackups();
|
||||
out.singlePrefillsThePath = ($('#sw-rs-path') || {}).value === '/only/one';
|
||||
out.singleShowsItsVerdict = /4 snapshots/.test(($('#sw-rs-verify-result') || {}).textContent || '');
|
||||
// Rendered as the same CARD the found list uses, not as a sentence. It is
|
||||
// the same fact either way and should not look like two different things
|
||||
// depending on how it was arrived at.
|
||||
const chosen = $('#sw-rs-verify-result .setup-found-backup');
|
||||
out.singleRendersAsACard = !!chosen;
|
||||
out.singleCardCarriesTheBadge = !!(chosen && chosen.querySelector('.setup-storage-badge'));
|
||||
// Not a button: there is nothing left to choose, and a card that looks
|
||||
// clickable but is not is worse than one that does not.
|
||||
out.singleCardIsNotClickable = !!chosen && chosen.tagName !== 'BUTTON';
|
||||
// The card and the verdict would otherwise say the same thing twice.
|
||||
out.singleDrawsNoDuplicateCard = $('#sw-rs-found .setup-found-backup') === null;
|
||||
// Pressing Check must confirm, not reply "give a full path" about the backup
|
||||
@ -306,6 +315,9 @@ chk "so does the verdict" "$(g .verdictInsideTheGroup)" true
|
||||
echo " one result is the answer, not a choice"
|
||||
chk "it fills the path in" "$(g .singlePrefillsThePath)" true
|
||||
chk "and shows its verdict" "$(g .singleShowsItsVerdict)" true
|
||||
chk "as a card, not a sentence" "$(g .singleRendersAsACard)" true
|
||||
chk "carrying the snapshot badge" "$(g .singleCardCarriesTheBadge)" true
|
||||
chk "and not looking clickable" "$(g .singleCardIsNotClickable)" true
|
||||
chk "without a duplicate card" "$(g .singleDrawsNoDuplicateCard)" true
|
||||
chk "Check confirms, not scolds" "$(g .singleCheckDoesNotScold)" true
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user