Symptom
The Refresh button on the Recommendations page (recommendations-freshness-refresh-btn, rendered by frontend/src/freshness.ts:renderFreshness) gave no transient feedback while the underlying POST /api/recommendations/refresh call was in flight: the label stayed Refresh, the button only flipped to disabled (no visible state change), and there was no toast on start or completion. On a slow refresh the user couldn't tell whether the click had registered, was running, or had finished.
Expected behaviour
- Click → button label flips to
Refreshing... and becomes disabled.
- Sticky info toast
Refreshing recommendations… appears for the duration of the call.
- On success: info toast is dismissed, a 5 s success toast
Recommendations refreshed shows, the freshness pill re-renders with the new timestamp, and the button restores itself.
- On failure: info toast is dismissed, an error toast
Refresh failed: <message> shows, and the button restores its original label + enabled state. Non-Error throws (null / undefined) must not crash the error handler itself.
Why it matters
A refresh round-trip can take several seconds on accounts with many regions. Without affordances the user is liable to click again, or assume the action did nothing.
Severity
LOW — UX polish only; the underlying refresh always worked.
Resolution
Tracked by PR #52.
Symptom
The Refresh button on the Recommendations page (
recommendations-freshness-refresh-btn, rendered byfrontend/src/freshness.ts:renderFreshness) gave no transient feedback while the underlyingPOST /api/recommendations/refreshcall was in flight: the label stayedRefresh, the button only flipped todisabled(no visible state change), and there was no toast on start or completion. On a slow refresh the user couldn't tell whether the click had registered, was running, or had finished.Expected behaviour
Refreshing...and becomes disabled.Refreshing recommendations…appears for the duration of the call.Recommendations refreshedshows, the freshness pill re-renders with the new timestamp, and the button restores itself.Refresh failed: <message>shows, and the button restores its original label + enabled state. Non-Error throws (null/undefined) must not crash the error handler itself.Why it matters
A refresh round-trip can take several seconds on accounts with many regions. Without affordances the user is liable to click again, or assume the action did nothing.
Severity
LOW — UX polish only; the underlying refresh always worked.
Resolution
Tracked by PR #52.