fix(audit-sprint-7b): consolidate 3 in-house toasts onto sonner - #176
fix(audit-sprint-7b): consolidate 3 in-house toasts onto sonner#176ejay-dev wants to merge 1 commit into
Conversation
Modal-audit agent found 4 hand-rolled toast implementations across the
codebase. This PR migrates 3 of them to the shared sonner Toaster
(Sprint 4c). The 4th (motion/InteractionFeedback.ToastItem) has no
external consumers and is left in place for separate cleanup.
Each migration preserves the component's call-site contract — only the
internals change. Visual unification is the win: same neutral default
surface across notifications, automation alerts, and compliance graph
events. Off-brand cyan/teal/violet badges go away (matches stored
"enterprise aesthetic" preference).
Migrated
- components/notifications/notification-toast.tsx (-60 LoC):
Realtime Supabase subscription stays (the actual job of the
component). Hand-rolled portal + queue + ToastItem render replaced
with toast.error / toast.warning. Click-to-route preserved via
sonner's action prop. Component now returns null; mount in
app/app/layout.tsx unchanged.
- components/automation/ComplianceToastAlerts.tsx (-140 LoC):
30-second polling against getAutomationHistory() stays. ToastItem
renderer + dismiss button + slide-in animation deleted. Critical
triggers (control_failed, risk_score_change) → toast.error;
others → toast.warning. Same returns-null pattern.
- components/compliance-system/compliance-toast.tsx (-150 LoC):
Trickier — this one has external consumers via the
useComplianceToast() hook in use-compliance-action.tsx. Preserves
the full public API (ComplianceToastData type, showToast,
dismissToast). Provider becomes a passthrough; internally
showToast maps to sonner's typed variants and builds a short
description from message/nodeType/nodeAction/impactArea/impactDelta.
No caller changes needed.
Out of scope
- components/motion/InteractionFeedback.tsx ToastItem export
(~30 lines of a 437-line utility module). Zero external consumers
of ToastItem found via grep — left in place. Can be a one-line
re-export removal later.
Built on top of fix/audit-sprint-4c-modal-primitives (PR #167) for the
shared Toaster.
Validation
- tsc -p tsconfig.typecheck.json: clean
- eslint: 0 errors, 18 warnings (baseline)
- jest: 5319/5334 pass (no test changes)
Test plan
- Send a critical notification → top-right red sonner toast with
title + body + View action that routes to data.href
- Trigger a control_failed automation → bottom-right red toast
- Call useComplianceToast().showToast({ type:'success', title:'x',
nodeType:'policy', nodeAction:'created' }) from a React component
→ green toast with description "policy created"
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR consolidates three in-house toast implementations onto the shared sonner Toaster that’s mounted at the app root, keeping the underlying notification/polling/subscription “work” while removing custom portal/queue/rendering code.
Changes:
NotificationToastnow only subscribes to Supabase realtime inserts and emitssonnertoasts (no local queue/UI).ComplianceToastAlertskeeps 30s polling of automation history but emitssonnertoasts (no portal/UI).compliance-toastis refactored into a thin shim oversonnerwhile preserving the hook/provider/data API shape.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| components/notifications/notification-toast.tsx | Replaces hand-rolled notification toast rendering/queue with sonner toasts triggered from the realtime subscription. |
| components/compliance-system/compliance-toast.tsx | Replaces custom compliance toast renderer/provider with a sonner-backed shim for useComplianceToast() / provider usage. |
| components/automation/ComplianceToastAlerts.tsx | Replaces custom polling toast UI with sonner toasts while preserving the polling behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| async function checkForNewAlerts() { | ||
| if (cancelled) return; | ||
| try { | ||
| const history = await getAutomationHistory(5); | ||
| if (!Array.isArray(history) || history.length === 0) return; | ||
|
|
||
| const latest = history[0]; | ||
| if (latest.id === lastSeenIdRef.current) return; | ||
| lastSeenIdRef.current = latest.id; |
| </div> | ||
| </ToastContext.Provider> | ||
| ); | ||
| } |
| variant(data.title, { | ||
| id: data.id, | ||
| description, | ||
| duration: data.duration, | ||
| }); |
| } | ||
| if (data.impactArea && typeof data.impactDelta === "number") { | ||
| const sign = data.impactDelta > 0 ? "+" : ""; | ||
| parts.push(`${data.impactArea}: ${sign}${data.impactDelta}`); |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e29629649
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
| </div> | ||
| </ToastContext.Provider> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Restore removed ComplianceToast export from module
This refactor removed the ComplianceToast named export, but components/compliance-system/index.ts still re-exports it (export { ComplianceToast, ... } from './compliance-toast'). In ESM module linking, that mismatch can make any import from @/components/compliance-system fail with a missing-export error before runtime, which would break existing consumers even if they never import ComplianceToast directly.
Useful? React with 👍 / 👎.
| variant(data.title, { | ||
| id: data.id, | ||
| description, | ||
| duration: data.duration, | ||
| }); |
There was a problem hiding this comment.
Preserve legacy duration semantics in compliance toasts
Forwarding duration: data.duration directly to Sonner changes the previous API contract from this provider: omitted durations no longer default to 5000ms, and duration: 0 no longer gets the old sticky/manual-dismiss behavior. That is a behavioral regression for existing useComplianceToast/useComplianceAction callers that rely on those semantics for important notifications.
Useful? React with 👍 / 👎.
Summary
Modal-audit agent found 4 hand-rolled toast implementations. This PR consolidates 3 onto the shared sonner Toaster from Sprint 4c. Net -325 LoC. The 4th has no consumers and is left in place.
Migrated
toast.error; others →toast.warning.useComplianceToast(),ComplianceToastProvider,ComplianceToastDataunchanged. Callers (use-compliance-action.tsx) don't need to change.Out of scope
What we lose
What we keep
Validation
npm run type-checkcleannpm run lint0 errors, 18 warnings (baseline)npx jest5319/5334 pass (no test changes)Test plan
control_failedautomation → red toast with title + descriptionuseComplianceToast().showToast({ type:'success', title:'X', nodeType:'policy', nodeAction:'created' })→ green toast with "policy created" description🤖 Generated with Claude Code