Skip to content

feat: redesign notification modal - #8140

Merged
sid-bruno merged 20 commits into
usebruno:mainfrom
prateek-bruno:feat/notification-modal
Jun 18, 2026
Merged

feat: redesign notification modal#8140
sid-bruno merged 20 commits into
usebruno:mainfrom
prateek-bruno:feat/notification-modal

Conversation

@prateek-bruno

@prateek-bruno prateek-bruno commented May 28, 2026

Copy link
Copy Markdown
Collaborator

Description

Jira

Redesign notification modal.

Screenshot 2026-05-31 at 5 51 55â€ŊPM
Screen.Recording.2026-06-18.at.9.26.32.PM.mov

Contribution Checklist:

  • I've used AI significantly to create this pull request
  • The pull request only addresses one issue or adds one feature.
  • The pull request does not introduce any breaking changes
  • I have added screenshots or gifs to help explain the change if applicable.
  • I have read the contribution guidelines.
  • Create an issue and link to the pull request.

Summary by CodeRabbit

  • New Features

    • New notifications experience: modal with All/Unread tabs, unread badge, list + detail pane, resizable sidebar, and bulk actions
    • Push-based notification delivery and a new notifications hook
  • Improvements

    • Notification detail shows sanitized rich-HTML previews with theme-aware styling
    • Modal supports optional padding toggle and improved close control
    • Persisted cleared-notification tracking and theme refinements across palettes
  • Refactor

    • Notifications component reworked to use hook + modal composition
  • Tests

    • Updated Notifications modal header test

Review Change Stack

prateek-bruno and others added 9 commits May 29, 2026 00:26
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • â–ķïļ Resume reviews
  • 🔍 Trigger review

Walkthrough

Refactors notifications into a hook-driven modal UI with a resizable sidebar (Tabs/List/Detail), adds NotificationList/NotificationTabs/NotificationDetail components, persists cleared IDs in Redux, switches Electron IPC to push, updates modal padding/icon, theme/schema entries, and a Playwright test.

Changes

Notifications Feature Refactor

Layer / File(s) Summary
Modal component close icon and padding support
packages/bruno-app/src/components/Modal/index.js
Modal close button now renders an IconX icon; ModalContent accepts a noPadding prop and is passed through when rendering the modal body.
useNotifications hook and tab/selection logic
packages/bruno-app/src/components/Notifications/hooks/useNotifications.js
New useNotifications hook (and TABS) that derives lists from Redux, pins unread IDs to avoid disappearing items, computes unreadCount, auto-marks items read on select/visibility, and exposes handlers for tab change, select, open/close (sends IPC opened), mark-all-read, and clear-all.
Notifications trigger refactor & trigger StyledWrapper
packages/bruno-app/src/components/Notifications/index.js, packages/bruno-app/src/components/Notifications/StyledWrapper.js
Refactors Notifications to use useNotifications(), renders the bell trigger via StyledWrapper (button) with unread badge and onClick={open}, and delegates modal rendering to NotificationsModal.
NotificationsModal shell & wiring
packages/bruno-app/src/components/Notifications/NotificationsModal/index.js
Adds NotificationsModal with sidebar sizing, useDragResize wiring, Portal/Modal wrapper, empty-state handling, and onClose confirm/cancel wiring.
NotificationList, NotificationTabs, NotificationDetail & modal styling
packages/bruno-app/src/components/Notifications/NotificationsModal/*
Implements NotificationList (selectable items, keyboard support, empty state), NotificationTabs (All/Unread, unread badge, action dropdown), NotificationDetail (sanitizes description, builds themed srcDoc, renders sandboxed iframe), and a modal-scoped StyledWrapper for layout and styles.
Redux notifications slice with localStorage and new thunk
packages/bruno-app/src/providers/ReduxStore/slices/notifications.js
Adds persisted clearedNotificationIds stored under bruno.notifications.cleared, removes loading/setFetchingStatus, adds clearAllNotifications, and replaces fetchNotifications thunk with loadNotifications(notifications) which filters by app version.
IPC notifications changed to push-based delivery
packages/bruno-electron/src/ipc/notifications.js
Replaces request/response ipcMain.handle with push model: new fetchNotifications() and pushNotifications(mainWindow) send main:load-notifications on app load and when notifications UI opens.
App provider IPC listener for incoming notifications
packages/bruno-app/src/providers/App/useIpcEvents.js
Adds main:load-notifications listener that dispatches loadNotifications(notifications) and is removed in cleanup.
Theme updates: notification list colors & schema
packages/bruno-app/src/themes/..., packages/bruno-app/src/themes/schema/oss.js
Adjusts notifications list and active/hover/border colors across multiple themes to use palette/token values, replaces borderRight with borderBottom, removes active border usage, and updates schema validation accordingly.
Modal header title test assertion
tests/footer/notifications/notifications.spec.js
Playwright test updated to expect Notifications in the modal header locator.

Estimated code review effort

ðŸŽŊ 4 (Complex) | ⏱ïļ ~45 minutes

Possibly related PRs

Suggested reviewers

  • helloanoop
  • lohit-bruno
  • naman-bruno
  • bijin-bruno

"🔔 A pane unfolds where small badges sing,
Hooks hum state and iframes bring,
Pushes from main keep the inbox bright,
Icons and themes now feel just right,
Bruno’s notifications take flight. 🎉"

ðŸšĨ Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: redesign notification modal' accurately describes the primary change—a comprehensive redesign of the notification modal UI with new components, styling, and architecture.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

âœĻ Finishing Touches
🧊 Generate unit tests (beta)
  • Create PR with unit tests

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.

@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.

Actionable comments posted: 4

ðŸ§đ Nitpick comments (2)
packages/bruno-app/src/components/Notifications/NotificationsModal/StyledWrapper.js (1)

218-224: ⚡ Quick win

Move the default badge color into the theme.

#8d43b1 (and the matching rgba) are hardcoded here while every data-variant below pulls from theme.*. Hardcoded hex won't adapt across themes and bypasses the theme system.

The same applies to the literal white/rgba(...) values at lines 76, 80-82 and 93 — prefer routing them through props.theme.*.

As per coding guidelines: "Use styled component's theme prop to manage CSS colors and not CSS variables when in the context of a styled component".

ðŸĪ– 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
`@packages/bruno-app/src/components/Notifications/NotificationsModal/StyledWrapper.js`
around lines 218 - 224, The .notif-type-badge styles in StyledWrapper.js use
hardcoded colors (`#8d43b1` and rgba(141,67,177,0.10)) and several other literal
values (white/rgba at the other notification style blocks) which bypass the
theme; replace these literals with theme properties (e.g.
props.theme.notifications.list.badgeColor and
props.theme.notifications.list.badgeBackground or similar keys) and update the
other places that use literal "white"/rgba to use appropriate props.theme.*
values so all colors come from the styled-components theme; ensure the new theme
keys exist or are added to the theme object so the components continue to render
correctly.
packages/bruno-app/src/components/Notifications/hooks/useNotifications.js (1)

33-45: ⚖ïļ Poor tradeoff

Selection-sync effect: confirm the auto-mark-read-on-open is intended.

This effect marks the most-recent item as read merely by opening the panel (no explicit user read). That matches the "auto-mark on visibility" intent in the summary, so flagging only to confirm it's deliberate.

Also, per repo guidance to avoid useEffect where feasible, the open/tab-entry selection could move into open()/onTabChange, leaving the effect to only react to external Redux-driven list changes (clear/markAll). Not blocking.

As per coding guidelines: "MUST: Avoid useEffect unless absolutely needed. Prefer derived state and event handlers in React".

ðŸĪ– 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 `@packages/bruno-app/src/components/Notifications/hooks/useNotifications.js`
around lines 33 - 45, The current useEffect both selects the first listed
notification on open and auto-marks it read; refactor so selection-and-auto-read
on panel open or tab change is handled inside the open()/onTabChange handlers
(call setSelectedNotification(first) and dispatch(markNotificationAsRead({
notificationId: first.id })) there when appropriate), and reduce the useEffect
to only respond to external list changes (clears/markAll) to keep selection in
sync (use listed and selectedNotification checks but do not perform open-time
selection/marking inside useEffect); also make the auto-mark-read behavior
explicit/configurable (e.g., comment or flag) so it’s clear this is intentional.
ðŸĪ– 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.

Inline comments:
In `@packages/bruno-app/src/components/Notifications/index.js`:
- Around line 13-18: The trigger element currently uses StyledWrapper (a
styled.a) which is not keyboard-focusable without an href; update StyledWrapper
in StyledWrapper.js to be a styled.button (preserving existing styles) and
ensure any instances (like the one rendering IconBell with onClick={open}) pass
type="button" and retain aria-label; also remove any href usage and ensure the
component forwards onClick and onKeyDown so the open handler is
keyboard-activatable via Enter/Space.

In
`@packages/bruno-app/src/components/Notifications/NotificationsModal/NotificationList.js`:
- Around line 11-18: The list item is only mouse-clickable; make rows
keyboard-accessible by adding role="button" and tabIndex={0} to the <li> with
className 'notif-list-item' (keyed by notification.id), and implement an
onKeyDown that calls the existing onSelect(notification) when Enter or Space is
pressed (preventDefault for Space to avoid scrolling); keep the existing onClick
handler and ensure you reference the same onSelect prop and notification object
so keyboard and mouse activation behave identically.

In `@packages/bruno-app/src/components/Notifications/StyledWrapper.js`:
- Around line 3-5: The notifications trigger is currently a non-focusable
styled.a used with onClick={open} in index.js; change StyledWrapper from
styled.a to styled.button so it becomes keyboard-focusable/activatable and
ensure it has type="button" to avoid form submit behavior; reset browser button
chrome inside StyledWrapper (e.g., background: none; border: none; padding: 0;
line-height: inherit; display: inline-flex; cursor: pointer;) so visual/layout
stays the same and retain any ARIA/props and the existing onClick={open} usage.

In `@packages/bruno-electron/src/ipc/notifications.js`:
- Around line 20-23: The did-finish-load handler is causing repeated
pushNotifications on reloads; update registerNotificationsIpc to guard so
pushNotifications(mainWindow) runs only once per window (e.g., replace
mainWindow.webContents.on('did-finish-load', ...) with
mainWindow.webContents.once('did-finish-load', ...) or set a boolean flag like
mainWindow.__notificationsPushed and check it before calling pushNotifications),
and keep ipcMain.on('renderer:notifications-opened', ...) as-is unless you later
observe duplicate listeners—ensure you reference the registerNotificationsIpc
function and pushNotifications symbol when making the change.

---

Nitpick comments:
In `@packages/bruno-app/src/components/Notifications/hooks/useNotifications.js`:
- Around line 33-45: The current useEffect both selects the first listed
notification on open and auto-marks it read; refactor so selection-and-auto-read
on panel open or tab change is handled inside the open()/onTabChange handlers
(call setSelectedNotification(first) and dispatch(markNotificationAsRead({
notificationId: first.id })) there when appropriate), and reduce the useEffect
to only respond to external list changes (clears/markAll) to keep selection in
sync (use listed and selectedNotification checks but do not perform open-time
selection/marking inside useEffect); also make the auto-mark-read behavior
explicit/configurable (e.g., comment or flag) so it’s clear this is intentional.

In
`@packages/bruno-app/src/components/Notifications/NotificationsModal/StyledWrapper.js`:
- Around line 218-224: The .notif-type-badge styles in StyledWrapper.js use
hardcoded colors (`#8d43b1` and rgba(141,67,177,0.10)) and several other literal
values (white/rgba at the other notification style blocks) which bypass the
theme; replace these literals with theme properties (e.g.
props.theme.notifications.list.badgeColor and
props.theme.notifications.list.badgeBackground or similar keys) and update the
other places that use literal "white"/rgba to use appropriate props.theme.*
values so all colors come from the styled-components theme; ensure the new theme
keys exist or are added to the theme object so the components continue to render
correctly.
🊄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

â„đïļ Review info
⚙ïļ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d90a6b52-35c6-457a-9dbd-4d9a0d08e4d3

ðŸ“Ĩ Commits

Reviewing files that changed from the base of the PR and between 244f528 and 364038c.

📒 Files selected for processing (14)
  • packages/bruno-app/src/components/Modal/index.js
  • packages/bruno-app/src/components/Notifications/NotificationsModal/NotificationDetail.js
  • packages/bruno-app/src/components/Notifications/NotificationsModal/NotificationList.js
  • packages/bruno-app/src/components/Notifications/NotificationsModal/NotificationTabs.js
  • packages/bruno-app/src/components/Notifications/NotificationsModal/StyledWrapper.js
  • packages/bruno-app/src/components/Notifications/NotificationsModal/index.js
  • packages/bruno-app/src/components/Notifications/StyleWrapper.js
  • packages/bruno-app/src/components/Notifications/StyledWrapper.js
  • packages/bruno-app/src/components/Notifications/hooks/useNotifications.js
  • packages/bruno-app/src/components/Notifications/index.js
  • packages/bruno-app/src/providers/App/useIpcEvents.js
  • packages/bruno-app/src/providers/ReduxStore/slices/notifications.js
  • packages/bruno-electron/src/ipc/notifications.js
  • tests/footer/notifications/notifications.spec.js
ðŸ’Ī Files with no reviewable changes (1)
  • packages/bruno-app/src/components/Notifications/StyleWrapper.js

Comment thread packages/bruno-app/src/components/Notifications/index.js
Comment thread packages/bruno-app/src/components/Notifications/StyledWrapper.js Outdated
Comment thread packages/bruno-electron/src/ipc/notifications.js
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Actionable comments posted: 0

Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Actionable comments posted: 0

prateek-bruno and others added 2 commits May 29, 2026 04:27
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>

@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.

Actionable comments posted: 0

â™ŧïļ Duplicate comments (1)
packages/bruno-app/src/components/Notifications/StyledWrapper.js (1)

3-3: ⚠ïļ Potential issue | ðŸŸĄ Minor | ⚡ Quick win

Add explicit button type to prevent accidental form submit

StyledWrapper is now a <button>, but without an explicit type it defaults to submit in forms. Please set type='button' (e.g., via attrs) at Line 3.

Suggested patch
-const StyledWrapper = styled.button`
+const StyledWrapper = styled.button.attrs({ type: 'button' })`
ðŸĪ– 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 `@packages/bruno-app/src/components/Notifications/StyledWrapper.js` at line 3,
StyledWrapper is defined as a styled.button and lacks an explicit button type,
which can make it default to type="submit" inside forms; update the
StyledWrapper definition (the styled.button) to set type='button' (for example
by using styled.button.attrs({ type: 'button' }) or equivalent) so the component
will not accidentally submit forms.
ðŸĪ– 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.

Duplicate comments:
In `@packages/bruno-app/src/components/Notifications/StyledWrapper.js`:
- Line 3: StyledWrapper is defined as a styled.button and lacks an explicit
button type, which can make it default to type="submit" inside forms; update the
StyledWrapper definition (the styled.button) to set type='button' (for example
by using styled.button.attrs({ type: 'button' }) or equivalent) so the component
will not accidentally submit forms.

â„đïļ Review info
⚙ïļ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3f50abdb-fbfa-47f4-8d94-9b422d488f80

ðŸ“Ĩ Commits

Reviewing files that changed from the base of the PR and between c1a075a and 8657cd5.

📒 Files selected for processing (2)
  • packages/bruno-app/src/components/Notifications/NotificationsModal/NotificationList.js
  • packages/bruno-app/src/components/Notifications/StyledWrapper.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/bruno-app/src/components/Notifications/NotificationsModal/NotificationList.js

prateek-bruno and others added 2 commits May 29, 2026 21:31
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>

@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.

Actionable comments posted: 1

ðŸĪ– 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.

Inline comments:
In
`@packages/bruno-app/src/components/Notifications/NotificationsModal/NotificationDetail.js`:
- Around line 5-8: The getBadgeStyle helper should guard against unknown remote
colors to avoid throwing when accessing theme.status[color]; update
getBadgeStyle (and any callers that pass notification.color) to first check that
theme.status has the requested color (e.g., via
Object.prototype.hasOwnProperty.call(theme.status, color) or optional chaining)
and fall back to a safe default key like "info" (or a default background/text
pair) when missing; ensure you return an object with backgroundColor and color
using the validated key (or default values) so
theme.status[color].background/.text never accesses undefined.
🊄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

â„đïļ Review info
⚙ïļ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 97964532-70f0-4389-b835-b2545761a2d1

ðŸ“Ĩ Commits

Reviewing files that changed from the base of the PR and between 8657cd5 and c9ebffc.

📒 Files selected for processing (5)
  • packages/bruno-app/src/components/Notifications/NotificationsModal/NotificationDetail.js
  • packages/bruno-app/src/components/Notifications/NotificationsModal/NotificationTabs.js
  • packages/bruno-app/src/components/Notifications/NotificationsModal/StyledWrapper.js
  • packages/bruno-app/src/components/Notifications/NotificationsModal/index.js
  • packages/bruno-app/src/components/Notifications/StyledWrapper.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/bruno-app/src/components/Notifications/NotificationsModal/NotificationTabs.js
  • packages/bruno-app/src/components/Notifications/NotificationsModal/index.js

Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
Comment thread packages/bruno-app/src/components/Notifications/hooks/useNotifications.js Outdated
naman-bruno
naman-bruno previously approved these changes Jun 18, 2026
Comment thread packages/bruno-app/src/components/Notifications/NotificationsModal/index.js Outdated
Co-authored-by: Sid <siddharth@usebruno.com>
Co-authored-by: Prateek Sunal
<41370460+prateekmedia@users.noreply.github.com>
@prateek-bruno
prateek-bruno requested a review from sid-bruno June 18, 2026 13:41
Co-authored-by: Prateek Sunal <41370460+prateekmedia@users.noreply.github.com>
@sid-bruno
sid-bruno merged commit 6711ccd into usebruno:main Jun 18, 2026
20 of 21 checks passed
@prateek-bruno
prateek-bruno deleted the feat/notification-modal branch June 18, 2026 16:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants