Frontend UX: add toast notifications — mutations currently succeed silently #47

Closed
opened 2026-06-06 18:51:10 +00:00 by logaritmisk · 1 comment
Owner

Severity: High. From a frontend UX audit.

Problem

There is no toast/notification system (grep for toast|sonner|notification|snackbar across web/src and package.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; onSuccess is otherwise silent (web/src/api/queries.ts mutations only invalidateQueries). Errors are surfaced inconsistently: inline <p role="alert"> in most forms, in-dialog for deletes, three message kinds in publish-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.

**Severity: High.** _From a frontend UX audit._ ## Problem There is **no toast/notification system** (grep for `toast|sonner|notification|snackbar` across `web/src` and `package.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; `onSuccess` is otherwise silent (`web/src/api/queries.ts` mutations only `invalidateQueries`). Errors are surfaced inconsistently: inline `<p role="alert">` in most forms, in-dialog for deletes, three message kinds in `publish-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._
Author
Owner

Done in 1bfa44a (merged to main). Added an app-wide Base UI toast region bridged to the (out-of-React) QueryClient via a module-scope createToastManager(). A global MutationCache gives 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 sets meta.suppressErrorToast (set on the ones that already show errors inline — the object form's 422 highlight, login, the delete dialogs' 409). meta is type-checked via a react-query Register augmentation; the cache config is a shared makeQueryClient() factory. Inline field/dialog errors are preserved (not replaced). No new dependency. Out of scope: replacing inline UX, undo/queued toasts, toasting read errors.

Done in `1bfa44a` (merged to `main`). Added an app-wide **Base UI toast** region bridged to the (out-of-React) `QueryClient` via a module-scope `createToastManager()`. A global `MutationCache` gives 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 sets `meta.suppressErrorToast` (set on the ones that already show errors inline — the object form's 422 highlight, login, the delete dialogs' 409). `meta` is type-checked via a react-query `Register` augmentation; the cache config is a shared `makeQueryClient()` factory. Inline field/dialog errors are preserved (not replaced). No new dependency. Out of scope: replacing inline UX, undo/queued toasts, toasting read errors.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: logaritmisk/biggus-dickus#47