Frontend UX: add toast notifications — mutations currently succeed silently #47
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Severity: High. From a frontend UX audit.
Problem
There is no toast/notification system (grep for
toast|sonner|notification|snackbaracrossweb/srcandpackage.json→ nothing). Every mutation — create/rename/delete vocab·term·authority·field, set-visibility, object create/update/delete — communicates success only by navigation or by closing a dialog;onSuccessis otherwise silent (web/src/api/queries.tsmutations onlyinvalidateQueries). Errors are surfaced inconsistently: inline<p role="alert">in most forms, in-dialog for deletes, three message kinds inpublish-control.tsx.Why it matters
In daily bulk cataloguing, a silent save leaves curators unsure whether the edit persisted — encouraging double-submits and re-checking. Network failures on some mutation paths can vanish with no global error channel.
Suggested fix
Add a toast system (Base UI Toast, or
sonner) and wire it into the TanStack Query mutation defaults (onSuccess/onError) so every mutation gets consistent success + error feedback for free. Keep the inline field-level errors where they add value (422 field highlight).Source: frontend UX/design audit, 2026-06-06.
Done in
1bfa44a(merged tomain). Added an app-wide Base UI toast region bridged to the (out-of-React)QueryClientvia a module-scopecreateToastManager(). A globalMutationCachegives every mutation feedback: an opt-in success toast (meta.successMessage) on the discrete CRUD/publish actions, and a catch-all error toast (type-aware:InUseError→"used by N", 503→"search unavailable", else generic) unless the mutation setsmeta.suppressErrorToast(set on the ones that already show errors inline — the object form's 422 highlight, login, the delete dialogs' 409).metais type-checked via a react-queryRegisteraugmentation; the cache config is a sharedmakeQueryClient()factory. Inline field/dialog errors are preserved (not replaced). No new dependency. Out of scope: replacing inline UX, undo/queued toasts, toasting read errors.