Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ENH] Implement Notification Icon with Badge for Warnings and Its Test #432

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Tusharjamdade
Copy link

@Tusharjamdade Tusharjamdade commented Jan 8, 2025

Changes proposed in this pull request:

  • Implemented a notification badge for non-critical warnings
  • Additionally, added a test for the notification badge

Checklist

This section is for the PR reviewer

  • PR has an interpretable title with a prefix ([ENH], [FIX], [REF], [TST], [CI], [MNT], [INF], [MODEL], [DOC]) (see our Contributing Guidelines for more info)
  • PR has a label for the release changelog or skip-release (to be applied by maintainers only)
  • PR links to GitHub issue with mention Closes #XXXX
  • Tests pass
  • Checks pass
  • If the PR changes the participant-level and/or the dataset-level result file, the query-tool-results files in the neurobagel_examples repo have been regenerated

For new features:

  • Tests have been added

For bug fixes:

  • There is at least one test that would fail under the original bug conditions.

Summary by Sourcery

Add a notification icon with a badge to display non-critical warnings to the user.

New Features:

  • Display non-critical warnings as notifications in a popover.

Tests:

  • Add tests for the notification icon and badge.

Copy link

sourcery-ai bot commented Jan 8, 2025

Reviewer's Guide by Sourcery

This pull request implements a notification icon with a badge in the navigation bar to display non-critical warnings to the user. It also includes a test for the new notification badge feature.

Sequence diagram for the new warning notification flow

sequenceDiagram
    participant User
    participant App
    participant Navbar
    participant NotificationSystem

    App->>NotificationSystem: Initialize warnings state
    App->>Navbar: Render with notifications prop
    Note over Navbar: Display notification badge
    User->>Navbar: Click notification icon
    Navbar->>NotificationSystem: Open notification popover
    NotificationSystem-->>User: Display warning messages
    User->>NotificationSystem: View warnings
    User->>NotificationSystem: Close notification popover
Loading

Class diagram for updated Navbar component

classDiagram
    class Navbar {
        +boolean isLoggedIn
        +function onLogin()
        +string[] notifications
        -HTMLElement anchorEl
        -HTMLElement anchorMailEl
        -boolean openAccountMenu
        -boolean openMailMenu
        +handleClick(event)
        +handleClose()
        +handleMailClick(event)
        +handleMailClose()
    }
    note for Navbar "Added notifications support"

    class Badge {
        +number badgeContent
        +string color
    }

    class NotificationsIcon {
        +string color
    }

    Navbar --> Badge
    Navbar --> NotificationsIcon
Loading

File-Level Changes

Change Details Files
Added a notification icon and badge to the navigation bar
  • Introduced a notification icon with a badge to display the number of warnings.
  • The notification icon opens a popover that lists the warning messages.
  • Included warning messages in the state and updated them when errors occur during data fetching.
  • Added tests to check the visibility of the notification icon and badge.
src/components/Navbar.tsx
src/App.tsx
cypress/component/Navbar.cy.tsx
Updated the Navbar component to handle notifications
  • Added a new notifications prop to the Navbar component to receive warning messages.
  • Implemented the popover functionality to display the list of warnings when the notification icon is clicked.
src/components/Navbar.tsx
Implemented warning handling in the App component
  • Added a warnings state variable to store warning messages.
  • Updated the error handling logic to add warning messages to the state instead of displaying snackbars.
  • Passed the warnings state to the Navbar component as a prop.
src/App.tsx
Added tests for the notification badge
  • Added tests to verify that the notification icon and badge are visible in the navigation bar.
cypress/component/Navbar.cy.tsx

Assessment against linked issues

Issue Objective Addressed Explanation
#393 Provide a way to remove or hide non-critical warnings from the UI
#393 Make current warning behavior a 'debug' mode and default to 'off' The PR implements a notification badge for warnings, but does not explicitly create a 'debug' mode or change the default warning display behavior
#393 Show only a little counter of warnings and errors with a badge that can be expanded on click

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time. You can also use
    this command to specify where the summary should be inserted.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions github-actions bot added the _community [BOT ONLY] PR label for community contributions. Used for tracking label Jan 8, 2025
Copy link

netlify bot commented Jan 8, 2025

Deploy Preview for neurobagel-query ready!

Name Link
🔨 Latest commit 2573528
🔍 Latest deploy log https://app.netlify.com/sites/neurobagel-query/deploys/67869dbb60f41f000838c326
😎 Deploy Preview https://deploy-preview-432--neurobagel-query.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@rmanaem rmanaem self-requested a review January 14, 2025 17:18
@rmanaem rmanaem added the pr-patch Incremental feature improvement, will increment patch version when merged (0.0.+1) label Jan 14, 2025
Copy link
Contributor

@rmanaem rmanaem left a comment

Choose a reason for hiding this comment

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

Hi @Tusharjamdade,

Congratulations on your first contribution to Neurobagel! 🎉 The changes look great overall. However, there are a few areas that need adjustments:

  • Currently, the implementation doesn't support deleting notifications, either individually or all at once.
  • The way warnings are passed to the Navbar component is too specific, limiting reusability.
  • Some of the e2e and component tests are failing due to these changes.

To address these, we can:

  • Implement delete functionality for each notification and a "clear all notifications" feature for the popover.
  • Refactor the logic for passing notifications to the Navbar component to make it more generic. This will allow us to pass different types of notifications (info, errors) to the Navbar.
    • For that the type of notification so that the appropriate title and color can be set in the ListItemText.
    • Once the logic is updated, we can also display info notifications in the popover.
  • Update the tests to reflect these changes.

I understand this might be overwhelming for your first PR and contribution. Please don't hesitate to reach out with any questions, or let us know if you would prefer one of the maintainers to take over this PR.

const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const openAccountMenu = Boolean(anchorEl);

const { user, logout } = useAuth0();
const [anchorMailEl, setAnchorMailEl] = useState<null | HTMLElement>(null);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const [anchorMailEl, setAnchorMailEl] = useState<null | HTMLElement>(null);
const [anchorNotifEl, setAnchorNotifEl] = useState<null | HTMLElement>(null);

Since we switched out the mail icon for notification, it's good to update the relevant variables.

const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const openAccountMenu = Boolean(anchorEl);

const { user, logout } = useAuth0();
const [anchorMailEl, setAnchorMailEl] = useState<null | HTMLElement>(null);
const openMailMenu = Boolean(anchorMailEl);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const openMailMenu = Boolean(anchorMailEl);
const openNotifMenu = Boolean(anchorNotifEl);

Comment on lines +52 to +54
const handleMailClick = (event: React.MouseEvent<HTMLElement>) => {
setAnchorMailEl(event.currentTarget);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const handleMailClick = (event: React.MouseEvent<HTMLElement>) => {
setAnchorMailEl(event.currentTarget);
};
const handleNotifClick = (event: React.MouseEvent<HTMLElement>) => {
setAnchorNotifEl(event.currentTarget);
};

Comment on lines +56 to +57
const handleMailClose = () => {
setAnchorMailEl(null);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const handleMailClose = () => {
setAnchorMailEl(null);
const handleNotifClose = () => {
setAnchorNotifEl(null);

@@ -56,9 +81,83 @@ function Navbar({ isLoggedIn, onLogin }: { isLoggedIn: boolean; onLogin: () => v
<Article />
</IconButton>
</Tooltip>
<Tooltip title="Notifications">
<IconButton onClick={handleMailClick}>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<IconButton onClick={handleMailClick}>
<IconButton onClick={handleNotifClick}>

vertical: 'top',
horizontal: 'right',
}}
PaperProps={{
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe the PaperProps is deprecated see the relevant documentation section here

Comment on lines +123 to +126
primary={
<Typography variant="subtitle2" className="font-bold text-[#E65100]">
{/* Add the appropriate title for the notification if any */}
</Typography>
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can use the type of notification e.g., warning, error, info for the primary content.

Comment on lines +135 to +139
<IconButton
edge="end"
aria-label="delete"
className="text-[#FF5722] hover:bg-[#FF572220]"
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

You may have forgotten to add the delete icon and implement the logic for deleting a list item.

<ListItem
key={notification}
alignItems="flex-start"
className="mb-2 rounded-md border-l-4 border-[#FF9800] bg-[#FFF3E0] transition-colors duration-200 hover:bg-gray-200"
Copy link
Contributor

Choose a reason for hiding this comment

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

The issue with this implementation is it doesn't take into account the type of notification and colors them all the same see other comments for more context

@@ -24,5 +31,7 @@ describe('Navbar', () => {
cy.get("[data-cy='navbar'] a")
.eq(1)
.should('have.attr', 'href', 'https://github.com/neurobagel/query-tool/');
// Test for Notification Icon and Badge
cy.get("[data-cy='navbar'] button").eq(1).find('svg').should('be.visible'); // Check if the notification icon exists
Copy link
Contributor

Choose a reason for hiding this comment

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

It's good to expand this test to include some assertions about the contents of the popover

@Tusharjamdade
Copy link
Author

Hi @Tusharjamdade,

Congratulations on your first contribution to Neurobagel! 🎉 The changes look great overall. However, there are a few areas that need adjustments:

  • Currently, the implementation doesn't support deleting notifications, either individually or all at once.
  • The way warnings are passed to the Navbar component is too specific, limiting reusability.
  • Some of the e2e and component tests are failing due to these changes.

To address these, we can:

  • Implement delete functionality for each notification and a "clear all notifications" feature for the popover.

  • Refactor the logic for passing notifications to the Navbar component to make it more generic. This will allow us to pass different types of notifications (info, errors) to the Navbar.

    • For that the type of notification so that the appropriate title and color can be set in the ListItemText.
    • Once the logic is updated, we can also display info notifications in the popover.
  • Update the tests to reflect these changes.

I understand this might be overwhelming for your first PR and contribution. Please don't hesitate to reach out with any questions, or let us know if you would prefer one of the maintainers to take over this PR.

Thank you for the review, @rmanaem.

I appreciate the detailed feedback and suggestions.
I will work on the details shared and will reach out if I need any help!!

@Tusharjamdade
Copy link
Author

Hi @Tusharjamdade,

Congratulations on your first contribution to Neurobagel! 🎉 The changes look great overall. However, there are a few areas that need adjustments:

  • Currently, the implementation doesn't support deleting notifications, either individually or all at once.
  • The way warnings are passed to the Navbar component is too specific, limiting reusability.
  • Some of the e2e and component tests are failing due to these changes.

To address these, we can:

  • Implement delete functionality for each notification and a "clear all notifications" feature for the popover.

  • Refactor the logic for passing notifications to the Navbar component to make it more generic. This will allow us to pass different types of notifications (info, errors) to the Navbar.

    • For that the type of notification so that the appropriate title and color can be set in the ListItemText.
    • Once the logic is updated, we can also display info notifications in the popover.
  • Update the tests to reflect these changes.

I understand this might be overwhelming for your first PR and contribution. Please don't hesitate to reach out with any questions, or let us know if you would prefer one of the maintainers to take over this PR.

Hi @rmanaem

export type Notification = {
  id: number;
  type: 'info' | 'warning';
  message: string;
};

const [notifications, setNotifications] = useState<Notification[]>([]);

<Navbar
  isLoggedIn={isAuthenticated}
  onLogin={() => setOpenAuthDialog(true)}
  notifications={notifications}
  setNotifications={setNotifications}
/>

// Navbar component
function Navbar({
  isLoggedIn,
  onLogin,
  notifications,
  setNotifications
}: {
  isLoggedIn: boolean;
  onLogin: () => void;
  notifications: Notification[];
  setNotifications: React.Dispatch<React.SetStateAction<Notification[]>>;
}) 

This is an overview of the implementation I have used. I have stored all notifications based on their types (warning, info) and messages, assigning each one a unique identifier (which will be used to delete the notification when the delete icon is clicked).

I passed the notifications and setNotifications to update the notifications (when the user clicks the delete button or the clear all button). Is this approach acceptable, or do I need to work on something else?

@rmanaem
Copy link
Contributor

rmanaem commented Jan 16, 2025

Hi @Tusharjamdade,
That's a good approach. Could you push your changes so I can take a look at them in context?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
_community [BOT ONLY] PR label for community contributions. Used for tracking pr-patch Incremental feature improvement, will increment patch version when merged (0.0.+1)
Projects
Status: Community
Development

Successfully merging this pull request may close these issues.

Make non-critical warnings less intrusive
2 participants