screentinker/frontend/js
Claude 9ea1b5e07b Stop eight dashboard views reporting success for requests the server refused
Each of these views carries its own copy of a fetch helper ending in `.then(r => r.json())`. A 403,
404 or 500 body resolves as an ordinary value, so the surrounding try/catch is unreachable and every
handler treats the failure as success. The shared client in api.js has always thrown on !res.ok;
these local copies never did.

Two concrete consequences, both of which tell the operator something untrue:

- The layout editor renders a Delete button on built-in templates for everyone. The server returns
  403. The handler shows "Layout deleted" and re-renders the list with the template still sitting
  there.
- A rejected platform-role change in Admin shows "Role updated", and the revert that would put the
  dropdown back lives only in the dead catch — so the UI keeps displaying a value the server
  refused. The same control in Settings uses the throwing client, so the two pages disagree about
  whether the change happened.

All eight now match the shared contract: reject on !ok with the server's own message, and treat 401
as session expiry the way api.js does.

This makes previously-silent failures visible, which is the point — some of them will surface
refusals that were always happening. The layout template Delete button, for instance, is now
honestly reported as refused rather than falsely confirmed; whether that button should be shown at
all is a separate question.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL
2026-07-30 21:21:56 -05:00
..
components Translate the labels that never went through t() 2026-07-28 19:52:52 -05:00
i18n Push layout edits to displays, and let a layout be renamed 2026-07-30 19:58:21 -05:00
lib Draw a schedule that runs past midnight 2026-07-28 19:28:04 -05:00
views Stop eight dashboard views reporting success for requests the server refused 2026-07-30 21:21:56 -05:00
agency-portal.js feat(agency): per-token upload folder — auto-created, subtree-confined (#158) (#171) 2026-07-12 21:23:25 -05:00
api.js Let a display's playlist actually be cleared 2026-07-30 18:29:18 -05:00
app.js Put Members in the nav, reveal titles on touch, and stop a stale heartbeat killing a socket 2026-07-28 20:00:35 -05:00
brand-prime.js fix(branding): inject instance branding into the app shell, no default flash (#76) 2026-06-11 09:30:23 -05:00
branding.js fix(branding): no ScreenTinker default flash on load/switch (#38) 2026-06-09 11:43:42 -05:00
i18n.js i18n: register Italian locale in language registry (followup to PR #2) 2026-05-11 20:05:09 -05:00
socket.js feat(device-owner): tier foundation + QR provisioning + content-expiry & device enhancements (#168) 2026-07-12 19:41:07 -05:00
utils.js fix(dashboard): make auth-image hydration lazy by default (#182 follow-up) (#185) 2026-07-14 13:28:12 -05:00