What
While the merged-scan is in flight, Dev Fleet's Prune merged button shows a spinner but keeps its label unchanged. Because it is a danger-styled button, a spinner on it can be read as "the deletion is already running" rather than "I am scanning to find candidates".
Current busy state (website/src/pages/DevFleetPage.tsx):
<Btn danger onClick={pruneShipped} disabled={!!busy['__prune']} aria-busy={!!busy['__prune']}>
{iconLabel(busy['__prune']
? <LoaderCircle className="lucide-inline animate-spin" />
: <Trash2 size={13} className="lucide-inline" />,
i18nT('pages.devFleetPage.prune_merged'))}
</Btn>
Nothing is deleted during this window — the scan only builds the candidate list, and the review dialog with its checkboxes is a mandatory confirmation step before any removal. But the button cannot say that, so the affordance is ambiguous at exactly the moment a nervous user is most likely to react.
Why
It is a second-order version of the problem the spinner was added to solve. The spinner fixed "the page is frozen"; this is "something destructive is already happening". Both end in the same behaviour — the user reloads or navigates away mid-scan — and a reload during the scan throws away the work and starts the git + gh walk over from scratch.
Raised as an advisory suggestion by UX Review on PR #2439, where the spinner was introduced.
Additional Context
The fix is copy, not logic: either swap the label to a scanning phrase for the busy window, or add a short adjacent status next to the button. Either way it needs a new English catalog key plus translations for the other 11 shipped locales — website/src/i18n/catalogParity.test.ts requires every language to carry every key, so a partial addition fails CI. That is why it was not folded into PR #2439: that PR deliberately introduced no new catalog keys (the spinner reuses the existing pages.devFleetPage.sync_progress string as its accessible name), and adding one would have pulled a 12-locale translation pass into a frontend affordance fix.
Suggested shape when someone picks this up:
- New key under
pages.devFleetPage, e.g. a scanning_merged string, added to en.manual.json and translated across all shipped locales, with npm run i18n:pseudo re-run so en-XA.json stays in sync with its generator.
- Keep
aria-busy on the button as-is — it is already correct for assistive tech; this is about the visible label only.
- Worth deciding at the same time whether the whole danger styling should be suppressed during the scan, since the scan itself is read-only.
What
While the merged-scan is in flight, Dev Fleet's Prune merged button shows a spinner but keeps its label unchanged. Because it is a
danger-styled button, a spinner on it can be read as "the deletion is already running" rather than "I am scanning to find candidates".Current busy state (
website/src/pages/DevFleetPage.tsx):Nothing is deleted during this window — the scan only builds the candidate list, and the review dialog with its checkboxes is a mandatory confirmation step before any removal. But the button cannot say that, so the affordance is ambiguous at exactly the moment a nervous user is most likely to react.
Why
It is a second-order version of the problem the spinner was added to solve. The spinner fixed "the page is frozen"; this is "something destructive is already happening". Both end in the same behaviour — the user reloads or navigates away mid-scan — and a reload during the scan throws away the work and starts the
git+ghwalk over from scratch.Raised as an advisory suggestion by UX Review on PR #2439, where the spinner was introduced.
Additional Context
The fix is copy, not logic: either swap the label to a scanning phrase for the busy window, or add a short adjacent status next to the button. Either way it needs a new English catalog key plus translations for the other 11 shipped locales —
website/src/i18n/catalogParity.test.tsrequires every language to carry every key, so a partial addition fails CI. That is why it was not folded into PR #2439: that PR deliberately introduced no new catalog keys (the spinner reuses the existingpages.devFleetPage.sync_progressstring as its accessible name), and adding one would have pulled a 12-locale translation pass into a frontend affordance fix.Suggested shape when someone picks this up:
pages.devFleetPage, e.g. ascanning_mergedstring, added toen.manual.jsonand translated across all shipped locales, withnpm run i18n:pseudore-run soen-XA.jsonstays in sync with its generator.aria-busyon the button as-is — it is already correct for assistive tech; this is about the visible label only.