🥂 feat: Toasts on All Save Actions#75
Conversation
Wires click-ui's Toast component into every save mutation in the admin panel: config editor (per-field, bulk, YAML import), groups (create / edit / delete), roles (create / edit / delete), users (invite, delete, role / group assignment, user profile create / delete), system grants (EditCapabilitiesDialog), and per-field profile mutations (useProfileMutations). Uses click-ui's official createToast directly; ClickUIProvider already mounts the matching ToastProvider, so the global createToast routes through it. Toasts inherit click-ui brand colours, WCAG contrast, keyboard accessibility, swipe-to-dismiss, close button, ARIA live region, and 5s auto-dismiss from the library. src/utils/toast.ts is a five-line wrapper exposing notifySuccess and notifyError that delegate to click-ui's createToast. Call sites pass the affected resource through mutation variables (not closed-over component state) so the toast renders the correct name even when the confirm dialog has already cleared its target by the time the response lands. Refs AI-1206.
|
@codex review |
|
Codex Review: Didn't find any major issues. Delightful! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
…tions EditGroupDialog, EditRoleDialog and EditCapabilitiesDialog mutationFns used to bail with an empty return when their target (group, role, principal) was missing, which React Query treats as success and which caused the new onSuccess handlers to fire a success toast and close the dialog without anything having been persisted. Throw a localised error in the unavailable case so onError fires instead, and add a matching guard at each call site so mutate is never invoked with a missing target in the first place.
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep it up! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit db90e9b. Configure here.
The five create and edit dialogs used to read the resource name from component state inside onSuccess instead of from the value that was submitted with the mutation. If the user edited the name field while the request was in flight (or the dialog reset before the toast fired), the toast could render an empty or wrong name even though the server saved the original value. Pass the submitted name through the mutation variables, use it for the actual API call, and read it back from the mutation's data or variables argument in onSuccess so the toast always reflects what was persisted.
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep them coming! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |

Summary
Wires
@clickhouse/click-ui'sToastinto every save mutation in the admin panel so admins get visible feedback on both success and failure. Before this PR most save sites silently swallowed errors toconsole.errorand showed nothing on success.Stacked on #74 (Radix
react-dismissable-layerdedupe). The dedupe is a hard prerequisite. Without it click-ui's toast auto-dismiss timer is killed by the shared-layer-set race as soon as any modal opens or closes. Once #74 merges tomainthis PR rebases cleanly ontomain.notifySuccess(title)andnotifyError(title)helpers insrc/utils/toast.tsthat delegate to click-ui's exportedcreateToast.ClickUIProvideralready mounts the matchingToastProvider, so no extra wiring is needed at the root.UserDetailDialog, user-profile create/delete, system grants inEditCapabilitiesDialog, and per-field profile values inuseProfileMutations.onSuccess, so the toast still renders the correct name when the confirm dialog has cleared its target by the time the response lands..config-toast*CSS block andToastStatetype left over from the oldConfigPage-local toast portal.com_toast_*for the per-resource success messages (com_toast_group_deleted,com_toast_role_updated, etc.).Change Type
Implementation
src/utils/toast.ts: five-line module exportingnotifySuccessandnotifyErrorovercreateToast({ type: 'success' | 'danger', title }). Toasts inherit click-ui's brand colours, WCAG contrast, dismiss button, swipe-to-dismiss, ARIA live region, keyboard accessibility, and 5s auto-dismiss from the library.GroupsTab,RolesTab,UsersPagedelete-mutationmutationFnnow takes the full target object;UserDetailDialog's add/remove role/group mutations take{ id, name };EditCapabilitiesDialog's save passes{ name: principalName }. EachonSuccessreads from the mutation'svariablesarg so the toast cannot read an empty string when the confirm dialog has already closed.ConfigPagedrops its localuseState<ToastState>+ portal and instead callsnotifySuccessandnotifyErrordirectly. ThenotifySavingintermediate state is gone since the bulk save flow already shows pending state viaConfirmSaveDialog'ssavingprop and the StickyActionBar's disabled save button.Testing
SESSION_SECRET=12345678901234567890123456789012 bun run test: 675 tests pass across 17 files.bun run lint: clean.SESSION_SECRET=12345678901234567890123456789012 bun run build: production build green.Checklist
Note
Low Risk
UI-only feedback and mutation variable wiring; no changes to authorization or server APIs.
Overview
Adds click-ui toasts for admin save/delete flows via new
notifySuccess/notifyErrorhelpers insrc/utils/toast.ts, replacing silent failures and the ConfigPage custom toast portal.Success and error toasts now fire across groups/roles (create, edit, delete), users (invite, delete, role/group/profile assignment), system capabilities, config bulk save/import/validation, and per-field profile overrides in
useProfileMutations. Newcom_toast_*i18n strings name the affected resource.Mutations pass resource identity through variables (e.g. full group/role/user on delete,
{ name }on create/update) so toast text stays correct after confirm dialogs clear state. Several sites route API errors to toasts instead of inlinesetErrororConfirmDialogerror props (RolesTab dropsdeleteError).Removes dead
.config-toast*CSS and theToastStatetype. ConfigPage no longer shows a separate “Saving…” toast; pending state remains on the save dialog and sticky bar.Reviewed by Cursor Bugbot for commit 8419332. Bugbot is set up for automated code reviews on this repo. Configure here.