Skip to content

Migrate-Remaining-Toasts-to-Global-Banner-System Replace the copy act…#3665

Merged
Baalmart merged 4 commits into
airqo-platform:stagingfrom
BwanikaRobert:Migrate-Remaining-Toasts-to-Global-Banner-System
Jun 19, 2026
Merged

Migrate-Remaining-Toasts-to-Global-Banner-System Replace the copy act…#3665
Baalmart merged 4 commits into
airqo-platform:stagingfrom
BwanikaRobert:Migrate-Remaining-Toasts-to-Global-Banner-System

Conversation

@BwanikaRobert

@BwanikaRobert BwanikaRobert commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary of Changes (What does this PR do?)

Completes the migration of all remaining non-copy action notifications from floating ReusableToast calls to the context-aware InfoBanner system (useBanner). Also consolidates all direct navigator.clipboard.writeText usages under the shared useClipboard hook.

GlobalBannerContainer for app-wide events, or scoped inside dialogs/cards via <BannerSlot />.

Changes by file:

  • app/providers.tsx — Moved BannerProvider above AuthProvider so that core auth components (UserDataFetcher, AuthWrapper) can call useBanner. Previously they were outside the provider boundary.
  • core/auth/authProvider.tsx — Replaced 4 ReusableToast calls with showBanner({ scoped: false }): "Connection restored", "Could not load user details", "Your account has been deleted", "Your session has expired".
  • core/hooks/useRecentlyVisited.ts — Replaced localStorage read failure toast with a global banner.
  • core/hooks/useClipboard.ts — Success copies now use toast.success (floating, intentional for clipboard feedback); copy errors now use showBanner.
  • components/features/home/network-visibility-card.tsx — "Failed to update network visibility" now renders as a scoped banner inside the confirmation dialog's existing <BannerSlot />.
  • components/features/claim/FileUploadParser.tsx — Replaced 6 error toasts with scoped banners. Added <BannerSlot /> inside BulkClaimColumnMapper header and threaded showBanner as a prop.
  • components/features/cohorts/cohort-detail-card.tsx — Replaced inline clipboard try/catch with useClipboard hook.
  • components/features/cohorts/cohort-organizations-card.tsx — Removed ReusableToast import and manual handleCopyId; replaced with useClipboard hook.
  • components/features/networks/client-paginated-networks-table.tsx — Removed inline useBanner clipboard pattern; replaced with useClipboard hook.

Preserved (intentionally not migrated):

  • Clipboard copy toasts in ReusableInputField.tsx and cohort-organizations-card.tsx copy actions — per spec, clipboard feedback should remain as floating toasts.

Status of maturity (all need to be checked before merging):

How should this be manually tested?

Global banners (auth events):

  1. Sign in and let the session expire (or clear the auth cookie manually) — confirm "Your session has expired. Please log in again." renders as a banner in the main layout, not a floating toast.
  2. Disconnect from the internet while logged in, then reconnect — confirm "Connection restored." appears as a green banner.

Scoped banners — Network Visibility Card:
3. Navigate to Home and find the Network Visibility card.
4. Toggle any cohort's visibility switch and click "Confirm" in the dialog.
5. To force an error: disable network in DevTools before confirming — confirm "Failed to update network visibility" appears inside the dialog, not as a floating toast.

Scoped banners — File Upload Parser:
6. Navigate to the Claim Devices page.
7. Attempt to import a .txt file — confirm "Invalid file format" error appears inside the upload modal.
8. Attempt to import a file over 5MB — confirm "File too large" appears inside the modal.
9. Import a valid CSV, map both columns to the same field, click Import — confirm "Device name and claim token must be in different columns" appears inside the column mapper modal.

Clipboard hook consolidation:
10. On any cohort detail page, click the copy icon next to the Cohort ID — confirm a floating toast appears (not a banner).
11. On the Cohort Organizations card, click the copy icon next to an Org ID — confirm floating toast.
12. On the Admin → Networks page, click the copy icon on any network row — confirm floating toast.

What are the relevant tickets?

Summary by CodeRabbit

  • Bug Fixes
    • Fixed notification/banner scoping so InfoBanners display correctly across authentication and full-app screens.
    • Improved error reporting for failed “recently visited” loads using banner messaging.
  • Refactor
    • Migrated user feedback from floating toasts to context-aware InfoBanners for file upload validation, network update failures, auth/session events, and clipboard-related flows (copy success/error handling standardized).
  • UI/UX
    • Adjusted the Windows download call-to-action placement in the secondary sidebar.
  • Documentation
    • Updated the app changelog with Version 2.0.7 notes covering the notification/banner migration.

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5c833b44-35f6-47aa-8596-d4d808aa5ef6

📥 Commits

Reviewing files that changed from the base of the PR and between 2c731c6 and 2644fd5.

📒 Files selected for processing (1)
  • src/vertex/components/layout/secondary-sidebar.tsx

📝 Walkthrough

Walkthrough

This PR migrates remaining ReusableToast notifications to the useBanner/InfoBanner system across auth, feature components, and core hooks. It fixes the BannerProvider nesting order so it wraps AuthProvider, consolidates clipboard success feedback to toast.success in useClipboard, applies the useClipboard hook to multiple components that previously had inline clipboard logic, and makes a minor layout adjustment to reposition the Windows download CTA in the secondary sidebar.

Changes

Toast-to-Banner Migration and Hierarchy

Layer / File(s) Summary
BannerProvider hierarchy fix
src/vertex/app/providers.tsx
BannerProvider is reordered to wrap AuthProvider so banner context is available across the entire app tree, including auth-level components.
useClipboard success via toast
src/vertex/core/hooks/useClipboard.ts
Success path switches from showBanner to toast.success; error path stays on showBanner. No public API changes.
Auth provider notifications → useBanner
src/vertex/core/auth/authProvider.tsx
UserDataFetcher and AuthWrapper replace all ReusableToast calls with showBanner for connection-restored, user-detail failure, account-deletion, and session-expiry events.
useRecentlyVisited error → useBanner
src/vertex/core/hooks/useRecentlyVisited.ts
localStorage load failure notification migrated from ReusableToast to showBanner.
Clipboard consumers adopt useClipboard
src/vertex/components/features/cohorts/cohort-detail-card.tsx, src/vertex/components/features/cohorts/cohort-organizations-card.tsx, src/vertex/components/features/networks/client-paginated-networks-table.tsx
Inline navigator.clipboard.writeText logic removed; all three components delegate copy and feedback to useClipboard's handleCopy.
Feature components → useBanner with scoped BannerSlot
src/vertex/components/features/home/network-visibility-card.tsx, src/vertex/components/features/claim/FileUploadParser.tsx
NetworkVisibilityCard replaces ReusableToast with a scoped showBanner. FileUploadParser and BulkClaimColumnMapper migrate all validation errors to showBanner and add a BannerSlot in the modal header.
v2.0.7 changelog
src/vertex/app/changelog.md
Documents all notification migrations and the BannerProvider hierarchy correction.

Secondary Sidebar Layout Adjustment

Layer / File(s) Summary
Windows download CTA repositioning
src/vertex/components/layout/secondary-sidebar.tsx
Removes the Windows download link from the Card footer prop and re-renders it in a bottom-aligned container within the sidebar content, keeping the same conditional visibility logic.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • airqo-platform/AirQo-frontend#3481: Introduces the BannerProvider/useBanner/BannerSlot/GlobalBannerContainer infrastructure that this PR builds upon for its migrations.
  • airqo-platform/AirQo-frontend#3488: Migrates auth login/forgot-password/Google flows from ReusableToast to the same useBanner system being extended here in authProvider.tsx.
  • airqo-platform/AirQo-frontend#3546: Modifies cohort UI notification and clipboard feedback paths, especially in cohort-detail-card.tsx, shifting how copy-success/errors are surfaced via banner mechanisms that this PR further refines via useClipboard/toast consolidation.

Suggested labels

ready for review

Suggested reviewers

  • Baalmart
  • OchiengPaul442
  • Codebmk

Poem

🍞 Toast has left the building, banners take the stage,
Context wraps the tree now — auth, hooks, every page.
Clipboard whispers toast.success, errors ring the bell,
BannerProvider sits up top, all nesting done quite well.
Floaty pops are history, the InfoBanner reigns. 🎉

🚥 Pre-merge checks | ✅ 3 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title is truncated and vague, failing to clearly convey the main change of migrating toasts to the banner system and completing clipboard consolidation. Revise the title to be complete and descriptive, such as 'Migrate remaining toast notifications to banner system and consolidate clipboard operations'.
Out of Scope Changes check ⚠️ Warning The secondary-sidebar.tsx changes appear out-of-scope—moving a Windows download link is unrelated to the toast-to-banner migration objectives stated in PR summary and issue #3653. Remove secondary-sidebar.tsx changes or clarify their connection to the banner migration. If unrelated, split into a separate PR.
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed All primary requirements from issue #3653 are met: global banners for auth events, scoped banners for feature-specific errors, clipboard consolidation via useClipboard hook, and proper BannerProvider placement.
Description check ✅ Passed The PR description comprehensively documents all files updated, the migration strategy, critical provider reordering, and preservation requirements from issue #3653.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • JIRA integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
Contributor

New azure vertex changes available for preview here

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/vertex/core/hooks/useRecentlyVisited.ts (1)

52-71: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add showBanner to the dependency array.

The effect uses showBanner (line 67) but doesn't include it in the dependency array (line 71). While showBanner is memoized and stable, React best practices and ESLint exhaustive-deps require all values from component scope to be listed.

✅ Suggested fix
-  }, [storageKey]);
+  }, [storageKey, showBanner]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/vertex/core/hooks/useRecentlyVisited.ts` around lines 52 - 71, The
useEffect hook in useRecentlyVisited.ts uses the showBanner function on line 67
but fails to include it in the dependency array on line 71. Add showBanner to
the dependency array alongside storageKey to ensure React's exhaustive-deps rule
is satisfied and to maintain proper hook dependencies, even though showBanner is
memoized and stable.
src/vertex/components/features/home/network-visibility-card.tsx (1)

133-137: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep the dialog open on failure for scoped banner visibility.

showBanner({ scoped: true }) depends on the dialog’s banner slot, but the unconditional close/reset in finally removes that slot immediately, so the error is effectively hidden. Move dialog close/reset to the success path only.

Suggested fix
     try {
       await cohortsApi.updateCohortDetailsApi(pendingCohort._id, {
         visibility: targetVisibility,
       });
@@
       if (isPersonalScope) {
         queryClient.invalidateQueries({
           queryKey: ['personalUserCohorts', userId],
         });
       }
+      setIsDialogOpen(false);
+      setPendingCohort(null);
     } catch (error) {
       console.error(error);
       showBanner({ severity: 'error', message: 'Failed to update network visibility', scoped: true });
     } finally {
       setIsUpdating(false);
-      setIsDialogOpen(false);
-      setPendingCohort(null);
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/vertex/components/features/home/network-visibility-card.tsx` around lines
133 - 137, The finally block unconditionally closes the dialog with
setIsDialogOpen(false) and clears pending state with setPendingCohort(null),
which happens immediately even when an error occurs. Since showBanner with
scoped: true requires the dialog to remain open to display the error banner in
the dialog's banner slot, move the setIsDialogOpen(false) and
setPendingCohort(null) calls from the finally block into the success path only
(after the successful network visibility update completes), so the dialog stays
open when displaying the error banner.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/vertex/components/features/home/network-visibility-card.tsx`:
- Around line 133-137: The finally block unconditionally closes the dialog with
setIsDialogOpen(false) and clears pending state with setPendingCohort(null),
which happens immediately even when an error occurs. Since showBanner with
scoped: true requires the dialog to remain open to display the error banner in
the dialog's banner slot, move the setIsDialogOpen(false) and
setPendingCohort(null) calls from the finally block into the success path only
(after the successful network visibility update completes), so the dialog stays
open when displaying the error banner.

In `@src/vertex/core/hooks/useRecentlyVisited.ts`:
- Around line 52-71: The useEffect hook in useRecentlyVisited.ts uses the
showBanner function on line 67 but fails to include it in the dependency array
on line 71. Add showBanner to the dependency array alongside storageKey to
ensure React's exhaustive-deps rule is satisfied and to maintain proper hook
dependencies, even though showBanner is memoized and stable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 032ef110-29cb-498c-94d0-e9016bbec048

📥 Commits

Reviewing files that changed from the base of the PR and between 2db6b51 and c03ec0e.

📒 Files selected for processing (10)
  • src/vertex/app/changelog.md
  • src/vertex/app/providers.tsx
  • src/vertex/components/features/claim/FileUploadParser.tsx
  • src/vertex/components/features/cohorts/cohort-detail-card.tsx
  • src/vertex/components/features/cohorts/cohort-organizations-card.tsx
  • src/vertex/components/features/home/network-visibility-card.tsx
  • src/vertex/components/features/networks/client-paginated-networks-table.tsx
  • src/vertex/core/auth/authProvider.tsx
  • src/vertex/core/hooks/useClipboard.ts
  • src/vertex/core/hooks/useRecentlyVisited.ts

@github-actions

Copy link
Copy Markdown
Contributor

New azure vertex changes available for preview here

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Completes the migration of remaining non-clipboard notifications from floating toasts to the useBanner / InfoBanner system, and consolidates direct clipboard writes under the shared useClipboard hook to standardize copy feedback behavior.

Changes:

  • Migrates auth + core-hook notifications to global banners (scoped: false) and feature-level failures to scoped banners (scoped: true).
  • Refactors multiple clipboard copy implementations to use useClipboard, keeping success feedback as floating toasts.
  • Updates provider composition so auth-level components can safely call useBanner, and documents the release in the changelog.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/vertex/app/providers.tsx Reorders providers so BannerProvider wraps AuthProvider, enabling banner usage in auth-level components.
src/vertex/core/auth/authProvider.tsx Replaces ReusableToast auth events with global banners for session/account/network-related messages.
src/vertex/core/hooks/useRecentlyVisited.ts Converts localStorage read failure notification to a global banner.
src/vertex/core/hooks/useClipboard.ts Uses toast.success for copy success while routing copy failures to banners.
src/vertex/components/features/home/network-visibility-card.tsx Converts network visibility mutation failure from toast to scoped banner.
src/vertex/components/features/claim/FileUploadParser.tsx Replaces multiple validation/error toasts with scoped banners and adds a BannerSlot in the column mapper UI.
src/vertex/components/features/cohorts/cohort-detail-card.tsx Replaces inline clipboard handling with useClipboard.
src/vertex/components/features/cohorts/cohort-organizations-card.tsx Removes manual clipboard/toast logic and uses useClipboard.
src/vertex/components/features/networks/client-paginated-networks-table.tsx Refactors copy-to-clipboard banner logic to use useClipboard.
src/vertex/app/changelog.md Adds Version 2.0.7 release notes covering the migration and clipboard consolidation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/vertex/core/auth/authProvider.tsx Outdated
});
showBanner({ severity: 'success', message: 'Connection restored.', scoped: false });
}
}, [isOnline, cachedUser, fetchStatus]);
Comment thread src/vertex/core/auth/authProvider.tsx Outdated
showBanner({ severity: 'error', message: `Could not load user details: ${getApiErrorMessage(error)}`, scoped: false });
}
}
}, [isError, error, isOnline, cachedUser, fetchStatus]);
Comment on lines +60 to 64
File: {filePreview.fileName}
</p>
</div>
<BannerSlot />
</div>
message: 'Your session has expired. Please log in again.',
type: 'ERROR',
});
showBanner({ severity: 'error', message: 'Your session has expired. Please log in again.', scoped: false });
@github-actions

Copy link
Copy Markdown
Contributor

New azure vertex changes available for preview here

@github-actions

Copy link
Copy Markdown
Contributor

New azure vertex changes available for preview here

@Codebmk Codebmk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Baalmart
Baalmart merged commit ab6ed3e into airqo-platform:staging Jun 19, 2026
24 of 25 checks passed
@Baalmart Baalmart mentioned this pull request Jun 19, 2026
13 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Vertex: Migration] Migrate Remaining Toasts to Global Banner System (Auth, Claim, Home Features)

4 participants