Skip to content

Conversation

@matheusysd
Copy link
Contributor

@matheusysd matheusysd commented Nov 5, 2024

  • Add Storybook for notifications components:
    • NotificationsPopover
    • NotificationsList (with notifications, loading state and empty state)
    • NotificationItem

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced Storybook support for notifications components, enhancing documentation and testing.
    • Added new components: NotificationItemWithQuery and NotificationsPopover with respective stories.
    • Implemented mock data for various notification states, including empty and populated lists.
    • Added new entries for notifications in the Storybook configuration.
  • Bug Fixes

    • Improved handling of mock resolvers and data in the withProviders function.
  • Documentation

    • Updated changelog to reflect new version 0.0.15 and recent changes.

@changeset-bot
Copy link

changeset-bot bot commented Nov 5, 2024

⚠️ No Changeset found

Latest commit: 60e7d90

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@matheusysd matheusysd self-assigned this Nov 6, 2024
@matheusysd matheusysd force-pushed the BA-1738-notifications-storybook branch from 29dbb18 to 2f60f5a Compare November 8, 2024 15:24
@deboracosilveira
Copy link
Collaborator

can we mock the "Mark all as read" action as well?

Copy link
Collaborator

Choose a reason for hiding this comment

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

This first list is related to the design-system package stories, since both storybooks are composed here. So you don't need to add stories here, since they are from components package and if you can, please change the name storiesOrder to designSystemStoriesOrder. Besides that, you can move //Notifications prior to // Social and NotificationItem before NotificationsList

Copy link
Collaborator

Choose a reason for hiding this comment

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

image
look like body is not appearing on the story

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems we have some bug here, @anicioalexandre tried to help me, but we decided to left like this and work on a bug later

Copy link
Collaborator

Choose a reason for hiding this comment

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

image
i think we need to mock the data for the drawer as well, now is just loading

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we decided to mock only the first call, and I think that's why we are not rendering the list. Now that we have queueOperationResolver I'll try using it

@matheusysd matheusysd force-pushed the BA-1738-notifications-storybook branch from 2996eb1 to 1796cfe Compare November 12, 2024 14:00
@coderabbitai
Copy link

coderabbitai bot commented Nov 12, 2024

Walkthrough

The changes in this pull request introduce enhancements to the Storybook configuration for notifications components. Key modifications include the addition of new components, mock data, and Storybook stories for NotificationItem, NotificationsList, and NotificationsPopover. The withProviders function has been updated to handle mock resolvers and data more dynamically. Additionally, the changelog has been updated to reflect these changes and the new versioning. Overall, these updates improve the documentation and testing capabilities of the notifications components within the project.

Changes

File Change Summary
packages/components/.storybook/decorators/withProviders.tsx Updated withProviders to include useEffect for handling mockResolvers and mockData. Destructured resolveMostRecentOperation from relayMockEnvironment. Initialized mockResolvers as undefined.
packages/components/.storybook/preview.ts Renamed storiesOrder to designSystemStoriesOrder. Added entries for NotificationItem, NotificationsList, and NotificationsPopover to componentsStoriesOrder. Updated final array to reflect new naming.
packages/components/CHANGELOG.md Added new version entry 0.0.15 for Storybook notifications components. Included previous version changes.
packages/components/modules/notifications/NotificationsList/NotificationItem/__storybook__/NotificationItemWithQuery/index.tsx Introduced NotificationItemWithQuery component using useLazyLoadQuery to fetch notification data.
packages/components/modules/notifications/NotificationsList/NotificationItem/__storybook__/mockResolvers.ts Added mockResolvers export with a resolver function returning a mock notification object.
packages/components/modules/notifications/NotificationsList/NotificationItem/__storybook__/stories.tsx Created Storybook configuration for NotificationItem, including metadata and a default story.
packages/components/modules/notifications/NotificationsList/__storybook__/mockResolvers.ts Added emptyNotificationsListMockData and notificationsListMockData for testing different notification states.
packages/components/modules/notifications/NotificationsList/__storybook__/stories.tsx Introduced Storybook configuration for NotificationsList with three story variations: DefaultNotificationsList, EmptyNotificationsList, and LoadingNotificationsList.
packages/components/modules/notifications/NotificationsPopover/__storybook__/mockResolvers.ts Added unreadNotificationsMockData and unreadNotificationsEmptyMockData for simulating unread notifications.
packages/components/modules/notifications/NotificationsPopover/__storybook__/stories.tsx Created Storybook configuration for NotificationsPopover, defining two story variations: DefaultNotificationsPopover and NotificationsPopoverWithUnreadNotifications.

Poem

In the land of notifications bright,
New tales emerge, a wondrous sight.
With queries and mocks, we play and cheer,
Storybook magic, oh so near!
Hopping through changes, our joy is clear,
For every new feature, we give a cheer! 🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/components/.storybook/preview.ts

Oops! Something went wrong! :(

ESLint: 8.57.1

Error: Cannot read config file: /packages/components/.eslintrc.js
Error: Cannot find module '@baseapp-frontend/config/.eslintrc.js'
Require stack:

  • /packages/components/.eslintrc.js
  • /node_modules/.pnpm/@eslint+eslintrc@2.1.4/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/lib/cli-engine/cli-engine.js
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/lib/eslint/eslint.js
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/lib/eslint/index.js
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/lib/cli.js
  • /node_modules/.pnpm/eslint@8.57.1/node_modules/eslint/bin/eslint.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/packages/components/.eslintrc.js:1:18)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 1796cfe3f86d70a0e39fd7e13452e4e7248b6db1 and 60e7d90.

📒 Files selected for processing (2)
  • packages/components/.storybook/preview.ts (3 hunks)
  • packages/components/package.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/components/package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/components/.storybook/preview.ts

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Outside diff range and nitpick comments (16)
packages/components/modules/notifications/NotificationsPopover/__storybook__/mockResolvers.ts (1)

1-3: Consider adding TypeScript interfaces for better type safety.

The mock data structure looks good, but could benefit from explicit typing.

Consider adding an interface:

interface NotificationsResponse {
  data: {
    me: {
      id: string;
      notificationsUnreadCount: number;
    };
  };
}

export const unreadNotificationsMockData: NotificationsResponse = {
  data: { me: { id: 'user-1', notificationsUnreadCount: 2 } },
}
packages/components/modules/notifications/NotificationsList/NotificationItem/__storybook__/mockResolvers.ts (1)

1-28: Consider enhancing the mock data structure

The mock resolver provides a good foundation but could be enhanced for better testing coverage:

  1. The data.extra object is empty but might need realistic test data
  2. Consider adding more fields that might be relevant for notifications (e.g., createdAt, updatedAt)
  3. The actor object could include more fields like name or avatar that might be needed in the UI

Here's a suggested enhancement:

 export const mockResolvers = {
   Node: () => ({
     id: 'Tm90aWZpY2F0aW9uOjIyNQ==',
     unread: true,
     pk: 225,
     timestamp: '2024-10-25T19:46:09.288290+00:00',
+    createdAt: '2024-10-25T19:46:09.288290+00:00',
+    updatedAt: '2024-10-25T19:46:09.288290+00:00',
     level: 'INFO',
     verb: 'COMMENTS.COMMENT_REPLY_CREATED',
     description: 'Someone replied to your comment 1.',
     data: {
-      extra: {},
+      extra: {
+        commentThread: 'thread-123',
+        contextUrl: '/posts/123#comment-237'
+      },
     },
     actor: {
       __typename: 'Profile',
       id: 'UHJvZmlsZToxNTM=',
+      name: 'John Doe',
+      avatar: 'https://example.com/avatar.jpg'
     },
     target: {
       id: 'Q29tbWVudDoyMzc=',
       __typename: 'Comment',
+      body: 'Original comment text'
     },
     actionObject: {
       id: 'Q29tbWVudDoyNDg=',
       __typename: 'Comment',
       body: 'This is the first comment reply.',
     },
     __typename: 'Notification',
   }),
 }
packages/components/modules/notifications/NotificationsList/NotificationItem/__storybook__/NotificationItemWithQuery/index.tsx (2)

8-19: Consider making the test ID configurable and documenting query options.

While the implementation is functional, consider these improvements:

  1. Make the "test-id" configurable through props to support different test scenarios
  2. Document the purpose of the empty options object in useLazyLoadQuery

Here's a suggested improvement:

-const NotificationItemWithQuery = (props: NotificationItemProps) => {
+interface NotificationItemWithQueryProps extends NotificationItemProps {
+  testId?: string; // Allow custom test IDs
+}
+
+const NotificationItemWithQuery = ({ testId = 'test-id', ...props }: NotificationItemWithQueryProps) => {
   const data = useLazyLoadQuery<Query>(
     graphql`
       query NotificationItemWithQuery @relay_test_operation {
-        target: node(id: "test-id") {
+        target: node(id: $testId) {
           ...NotificationItemFragment
         }
       }
     `,
-    {},
+    {}, // Empty options object - no variables needed for Storybook testing
   )

20-23: Consider adding runtime type validation.

The type casting of data.target could benefit from runtime validation to ensure type safety.

Here's a suggested improvement:

+  if (!data.target) {
+    throw new Error('Failed to load notification data');
+  }
+
   return <NotificationItem {...props} notification={data.target as NotificationItemFragment$key} />
packages/components/modules/notifications/NotificationsList/NotificationItem/__storybook__/stories.tsx (1)

12-20: Enhance notification prop documentation

While the basic documentation is present, consider enhancing the notification prop documentation:

  1. Add examples of valid notification objects
  2. Document required vs optional fields
  3. Include possible values or constraints
 notification: {
   description: 'The notification data.',
+  description: 'The notification data object containing id, message, timestamp, and read status.',
   control: 'object',
   table: {
     type: {
       summary: 'NotificationItem_notification$key',
+      detail: `{
+        id: string;
+        message: string;
+        timestamp: string;
+        read: boolean;
+        // Add other relevant fields
+      }`
     },
   },
 },
packages/components/.storybook/decorators/withProviders.tsx (1)

28-28: Simplify boolean condition

Remove the redundant double negation.

-    if (!!mockResolvers) {
+    if (mockResolvers) {
🧰 Tools
🪛 Biome

[error] 28-28: Avoid redundant double-negation.

It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation

(lint/complexity/noExtraBooleanCast)

packages/components/modules/notifications/NotificationsList/__storybook__/stories.tsx (3)

6-57: Add "Mark all as read" action to Storybook controls

Based on the PR comments, consider adding the "Mark all as read" action to allow interaction testing in Storybook.

 const meta: Meta<typeof NotificationsList> = {
   title: '@baseapp-frontend | components/Notifications/NotificationsList',
   component: NotificationsList,
   tags: ['autodocs'],
   argTypes: {
+    onMarkAllAsRead: {
+      action: 'marked all as read',
+      description: 'Callback fired when marking all notifications as read',
+      table: {
+        type: {
+          summary: '() => void',
+        },
+      },
+    },
     // ... existing argTypes
   },
 }

11-55: Enhance prop descriptions for better documentation

Consider adding more detailed descriptions for the component props:

  • Include type constraints or accepted values
  • Mention default behaviors
  • Add examples where applicable

For instance:

     setIsDrawerOpened: {
       control: false,
-      description: 'Function to toggle the Drawer open/close state.',
+      description: 'Function to toggle the Drawer open/close state. Called with the new state value when the drawer visibility changes.',
       // ...
     },
     LoadingStateProps: {
       control: 'object',
-      description: 'Props to pass to the LoadingState component.',
+      description: 'Props to pass to the LoadingState component. Customize the loading state appearance (e.g., number of skeleton items to show).',
       // ...
     },

63-83: Consider adding error state and improving story names

The stories could be enhanced with:

  1. An additional story for error states
  2. More descriptive names that indicate the use case
 export const DefaultNotificationsList: Story = {
-  name: 'Default NotificationsList',
+  name: 'With Active Notifications',
   // ...
 }

 export const EmptyNotificationsList: Story = {
-  name: 'Empty NotificationsList',
+  name: 'With No Notifications',
   // ...
 }

 export const LoadingNotificationsList: Story = {
-  name: 'Loading NotificationsList',
+  name: 'In Loading State',
   // ...
 }

+export const ErrorNotificationsList: Story = {
+  name: 'With Error State',
+  args: {},
+  parameters: {
+    mockData: {
+      error: new Error('Failed to fetch notifications'),
+      data: null
+    },
+  },
+}
packages/components/modules/notifications/NotificationsPopover/__storybook__/stories.tsx (1)

6-84: Enhance props documentation with examples

The meta configuration is well-structured, but the documentation could be more helpful by including:

  • Example values for object-type props (DrawerProps, BadgeProps, etc.)
  • Specific use cases or constraints for each component override

Consider enhancing the documentation like this:

 DrawerProps: {
   control: 'object',
   description: 'Props to pass to the Drawer component.',
   table: {
     type: {
       summary: 'Partial<DrawerProps>',
+      detail: 'Example: { open: boolean, onClose: () => void, anchor: "right" }'
     },
   },
 },
packages/components/.storybook/preview.ts (3)

Line range hint 37-112: Reduce code duplication between story order arrays

The designSystemStoriesOrder and componentsStoriesOrder arrays contain identical entries up to the "General" section. Consider extracting these common entries to a shared array to improve maintainability.

+ const commonStoriesOrder = [
+   'Iconography',
+   // Avatars
+   'AvatarWithPlaceholder',
+   'ClickableAvatar',
+   // ... other common entries
+   'Logo',
+   'Scrollbar',
+ ]

- const designSystemStoriesOrder = [
-   'Iconography',
-   // Avatars
-   'AvatarWithPlaceholder',
-   // ... duplicate entries
- ]

+ const designSystemStoriesOrder = [...commonStoriesOrder]

- const componentsStoriesOrder = [
-   'Iconography',
-   // Avatars
-   'AvatarWithPlaceholder',
-   // ... duplicate entries
- ]

+ const componentsStoriesOrder = [
+   ...commonStoriesOrder,
+   // Navigation
+   'NavigationLayout',
+   // ... remaining unique entries
+ ]

98-101: Reorder notification components for better logical flow

The notification components should follow a hierarchical order from smallest to largest component for better readability and understanding of the component structure.

  //Notifications
  'NotificationItem',
- 'NotificationsList',
- 'NotificationsPopover',
+ 'NotificationsPopover',
+ 'NotificationsList',

36-36: Enhance comment about external variables

The current comment could be more descriptive about why external variables aren't accepted and provide context about the Storybook limitation.

- // NOTE: Storybook does not accept importing external variables for storySort,
+ // NOTE: Storybook's storySort function runs in an isolated context and cannot access
+ // external variables or imports. This is a known limitation, so we define the sort
+ // order arrays inline. See: https://storybook.js.org/docs/react/writing-stories/sorting-stories
packages/components/CHANGELOG.md (1)

3-8: Enhance the changelog entry with more detailed information.

While the entry follows the correct format, consider expanding it to provide more comprehensive details about the changes, such as:

 ## 0.0.15

 ### Patch Changes

-Add Storybook for notifications components.
+Add Storybook for notifications components:
+- Add stories for NotificationsPopover, NotificationsList, and NotificationItem components
+- Include various states: notifications list with items, loading state, and empty state
+- Add mock data and resolvers for testing notification interactions

This would better reflect the scope of changes mentioned in the PR objectives and provide more valuable information for future reference.

packages/components/modules/notifications/NotificationsList/__storybook__/mockResolvers.ts (2)

17-322: Add mock resolver for "Mark all as read" action

In response to @deboracosilveira's comment about mocking the "Mark all as read" action, consider adding a mock resolver that:

  1. Updates the unread status of all notifications
  2. Resets the unreadCount to 0
  3. Triggers a UI refresh

Would you like me to help implement the mock resolver for the "Mark all as read" action?


1-322: Add TypeScript interfaces for mock data structure

Consider adding TypeScript interfaces to define the shape of the mock data. This would:

  • Provide better type safety
  • Make the data structure more maintainable
  • Help catch potential structure mismatches early
  • Serve as documentation for other developers
interface NotificationNode {
  id: string;
  unread: boolean;
  pk: number;
  timestamp: string;
  level: 'INFO' | 'WARNING' | 'ERROR';
  verb: string;
  description: string;
  data: {
    extra: Record<string, unknown>;
  };
  actor: {
    __typename: string;
    id: string;
  };
  target: {
    id: string;
    __typename: string;
  };
  actionObject: {
    id: string;
    __typename: string;
    body: string;
  };
  __typename: 'Notification';
}

interface NotificationsData {
  data: {
    me: {
      id: string;
      notificationsUnreadCount: number;
      notifications: {
        edges: Array<{
          cursor: string;
          node: NotificationNode;
        }>;
        pageInfo: {
          hasNextPage: boolean;
          endCursor: string | null;
        };
      };
    };
  };
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between bd53fc7 and 1796cfe3f86d70a0e39fd7e13452e4e7248b6db1.

⛔ Files ignored due to path filters (1)
  • packages/components/__generated__/NotificationItemWithQuery.graphql.ts is excluded by !**/__generated__/**
📒 Files selected for processing (10)
  • packages/components/.storybook/decorators/withProviders.tsx (2 hunks)
  • packages/components/.storybook/preview.ts (3 hunks)
  • packages/components/CHANGELOG.md (1 hunks)
  • packages/components/modules/notifications/NotificationsList/NotificationItem/__storybook__/NotificationItemWithQuery/index.tsx (1 hunks)
  • packages/components/modules/notifications/NotificationsList/NotificationItem/__storybook__/mockResolvers.ts (1 hunks)
  • packages/components/modules/notifications/NotificationsList/NotificationItem/__storybook__/stories.tsx (1 hunks)
  • packages/components/modules/notifications/NotificationsList/__storybook__/mockResolvers.ts (1 hunks)
  • packages/components/modules/notifications/NotificationsList/__storybook__/stories.tsx (1 hunks)
  • packages/components/modules/notifications/NotificationsPopover/__storybook__/mockResolvers.ts (1 hunks)
  • packages/components/modules/notifications/NotificationsPopover/__storybook__/stories.tsx (1 hunks)
🧰 Additional context used
🪛 Biome
packages/components/.storybook/decorators/withProviders.tsx

[error] 28-28: Avoid redundant double-negation.

It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation

(lint/complexity/noExtraBooleanCast)

🔇 Additional comments (6)
packages/components/modules/notifications/NotificationsList/NotificationItem/__storybook__/mockResolvers.ts (2)

24-24: Address the body visibility issue in Storybook

A previous review comment indicated that the body field wasn't appearing in the story. Let's verify if this field is being properly handled in the component and story.

#!/bin/bash
# Description: Check how the body field is used in the component and story files

echo "Checking for body field usage in component and story files..."
rg -A 5 "body.*prop|body.*interface" packages/components/modules/notifications

echo "Checking for body field rendering in stories..."
rg -A 5 "body.*render|body.*{.*}" packages/components/modules/notifications

3-3: Verify the GraphQL ID encoding format

The IDs appear to be base64 encoded, which is common in GraphQL. Let's verify they decode to meaningful values:

Also applies to: 15-15, 18-18, 22-22

packages/components/modules/notifications/NotificationsList/NotificationItem/__storybook__/NotificationItemWithQuery/index.tsx (2)

1-7: LGTM! Well-structured imports with proper type definitions.

The imports are well-organized and make good use of generated types for type safety.


1-23: Verify Storybook integration and mock data setup.

Let's verify the component is properly integrated with Storybook configuration and mock data.

packages/components/modules/notifications/NotificationsList/NotificationItem/__storybook__/stories.tsx (1)

3-5: Verify component usage consistency

The story configuration uses NotificationItemWithQuery as the main component in meta while using NotificationItem for the Story type. This might lead to confusion. Please verify if this is intentional and consider:

  1. Using consistent component types
  2. Adding documentation to explain why different components are used
packages/components/.storybook/decorators/withProviders.tsx (1)

27-34: LGTM! Well-structured mock data handling

The useEffect implementation is clean and logical:

  1. Sets up mock resolvers if provided
  2. Resolves operations with combined mock data
  3. Correctly specifies all dependencies

This implementation aligns well with the PR objective of supporting Storybook for Notifications components.

🧰 Tools
🪛 Biome

[error] 28-28: Avoid redundant double-negation.

It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation

(lint/complexity/noExtraBooleanCast)

Comment on lines +5 to +7
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding more test scenarios and "Mark all as read" action.

While the empty state is covered, consider adding:

  1. Error state scenarios
  2. Mock resolver for "Mark all as read" action (as requested in PR comments)
  3. Edge cases (e.g., very high notification counts)

Here's a suggested implementation:

export const markAllAsReadMockResolver = {
  Mutation: {
    markAllNotificationsAsRead: () => ({
      success: true,
      notifications: [],
    }),
  },
}

export const errorStateMockData = {
  error: {
    message: 'Failed to fetch notifications',
  },
}

export const highCountMockData = {
  data: { me: { id: 'user-1', notificationsUnreadCount: 99 } },
}

Comment on lines +28 to +33
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add more story variants and interactions

Consider enhancing the stories with:

  1. Different notification states (read/unread)
  2. Various content lengths
  3. Interactive examples (e.g., marking as read)
  4. Error states

This aligns with the PR comment about mocking "Mark all as read" functionality.

 export const DefaultNotificationItem: Story = {
   name: 'Default NotificationItem',
   parameters: {
     mockResolvers,
   },
 }
+
+export const ReadNotification: Story = {
+  name: 'Read Notification',
+  parameters: {
+    mockResolvers: {
+      ...mockResolvers,
+      NotificationItem: () => ({
+        ...mockResolvers.NotificationItem(),
+        read: true,
+      }),
+    },
+  },
+}
+
+export const LongContent: Story = {
+  name: 'Long Content Notification',
+  parameters: {
+    mockResolvers: {
+      ...mockResolvers,
+      NotificationItem: () => ({
+        ...mockResolvers.NotificationItem(),
+        message: 'This is a very long notification message that demonstrates how the component handles text wrapping and overflow...',
+      }),
+    },
+  },
+}
+
+export const WithInteraction: Story = {
+  name: 'Interactive Notification',
+  parameters: {
+    mockResolvers,
+  },
+  play: async ({ canvasElement }) => {
+    // Add interaction test here
+  },
+}

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +24 to +25
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Change to mockResolvers affects existing stories and tests

Multiple Storybook story and test files use mockResolvers. Please ensure that changing the default value to undefined does not break these existing implementations.

🔗 Analysis chain

Verify backward compatibility of mockResolvers change

Changing the default value from an empty object to undefined might affect existing stories that expect mockResolvers to be an object. Please ensure this change doesn't break existing stories.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for stories that might be affected by this change
rg -l "mockResolvers" --type stories

# Check for any direct references to mockResolvers in test files
rg -l "mockResolvers" --type test

Length of output: 131


Script:

#!/bin/bash
# Search for Storybook stories that might be affected by this change
rg -l "mockResolvers" --glob "*.stories.tsx" --glob "*.stories.jsx"

# Search for test files that reference mockResolvers
rg -l "mockResolvers" --glob "*.test.tsx" --glob "*.spec.tsx" --glob "*.test.jsx" --glob "*.spec.jsx"

Length of output: 318


Script:

#!/bin/bash
# Search for Storybook stories that might be affected by this change
fd --glob "*.stories.tsx" --glob "*.stories.jsx" -e tsx -e jsx | xargs rg -l "mockResolvers"

# Search for test files that reference mockResolvers
fd --glob "*.test.tsx" --glob "*.spec.tsx" --glob "*.test.jsx" --glob "*.spec.jsx" -e tsx -e jsx | xargs rg -l "mockResolvers"

Length of output: 3854


Script:

#!/bin/bash
# Search for Storybook stories that might be affected by this change
fd --glob "*.stories.tsx" --glob "*.stories.jsx" | xargs rg -l "mockResolvers"

# Search for test files that reference mockResolvers
fd --glob "*.test.tsx" --glob "*.spec.tsx" --glob "*.test.jsx" --glob "*.spec.jsx" | xargs rg -l "mockResolvers"

Length of output: 3826

Comment on lines +79 to +83
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add mock data for LoadingNotificationsList story

The LoadingNotificationsList story is missing mock data in its parameters. Consider adding appropriate loading state mock data to simulate the loading experience accurately.

 export const LoadingNotificationsList: Story = {
   name: 'Loading NotificationsList',
   args: {},
-  parameters: {},
+  parameters: {
+    mockData: {
+      loading: true,
+      data: null
+    },
+  },
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const LoadingNotificationsList: Story = {
name: 'Loading NotificationsList',
args: {},
parameters: {},
}
export const LoadingNotificationsList: Story = {
name: 'Loading NotificationsList',
args: {},
parameters: {
mockData: {
loading: true,
data: null
},
},
}

Comment on lines +1 to +4
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Mock data for NotificationsList is not properly implemented in Storybook

The mockResolvers.ts in the Storybook directory does not define notificationsListMockData or emptyNotificationsListMockData. Please ensure that these mock data are correctly implemented and imported within the Storybook stories.

🔗 Analysis chain

Verify mock data implementation for notifications

The mock data imports look correct, but let's verify the implementation of the mock resolvers to ensure they cover all necessary notification states and properties.


Correct the search command to target TypeScript files appropriately

The previous rg command failed due to an unrecognized file type. Please verify mock data implementations using the updated shell script below.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for mock resolver implementation
echo "Searching for mockResolvers.ts file..."
fd mockResolvers.ts

# Check mock data structure
echo "Checking mock data structure..."
rg -A 10 "notificationsListMockData|emptyNotificationsListMockData" --type typescript

Length of output: 1107


Script:

#!/bin/bash
# Search for mock resolver implementation files
echo "Searching for mockResolvers.ts files..."
fd mockResolvers.ts

# Check mock data structure
echo "Checking mock data structure..."
rg -A 10 "notificationsListMockData|emptyNotificationsListMockData" -g "*.{ts,tsx}"

Length of output: 16823

Comment on lines +90 to +104
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add more comprehensive story variations

The current stories are missing several key scenarios mentioned in the PR objectives:

  1. Loading state story
  2. Interactive "Mark all as read" functionality
  3. Various drawer states and interactions

Consider adding these additional stories:

export const LoadingState: Story = {
  name: 'Loading State',
  args: {},
  parameters: {
    mockData: {
      loading: true
    }
  }
}

export const WithMarkAllAsRead: Story = {
  name: 'With Mark All as Read Action',
  args: {},
  parameters: {
    mockData: {
      ...unreadNotificationsMockData,
      resolvers: {
        Mutation: {
          markAllNotificationsAsRead: () => ({
            success: true
          })
        }
      }
    }
  }
}

Comment on lines +1 to +4
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Missing mock implementation for "Mark all as read" action

The markAllAsRead mock resolver is not found in the codebase. Please implement the required mock to align with PR objectives.

🔗 Analysis chain

Verify mock data implementation for complete notification scenarios

Based on the PR objectives and past review comments, we should ensure the mock data covers all notification scenarios, including the "Mark all as read" action.

Let's check the mock resolvers implementation:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check mock resolvers implementation
rg -A 10 "unreadNotificationsMockData|unreadNotificationsEmptyMockData" --type typescript

Length of output: 126


Script:

#!/bin/bash
# Check mock resolvers implementation in TypeScript and TSX files
rg -A 10 "unreadNotificationsMockData|unreadNotificationsEmptyMockData" --type ts --type tsx

Length of output: 122


Script:

#!/bin/bash
# Check mock resolvers implementation in TypeScript and TSX files
rg -A 10 "unreadNotificationsMockData|unreadNotificationsEmptyMockData" -g "*.ts" -g "*.tsx"

Length of output: 16559


Script:

#!/bin/bash
# Check for "markAllAsRead" mock resolver implementation in TypeScript and TSX files
rg "markAllAsRead" -g "*.ts" -g "*.tsx"

Length of output: 39

Comment on lines +17 to +322
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance mock data variety for better test coverage

The current mock data has several patterns that might limit testing scenarios:

  1. All notifications are unread
  2. All notifications are comment replies
  3. All notifications target the same comment
  4. All notifications have the same actor

Consider diversifying the mock data to:

  • Include both read and unread notifications
  • Add different notification types (not just comment replies)
  • Vary the target and actor IDs
  • Include different notification levels (not just INFO)

This would help ensure the component handles various real-world scenarios correctly.

Comment on lines +1 to +15
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adjusting unread count in empty state mock

There's an inconsistency in the empty state mock where notificationsUnreadCount is 12 but the notifications list is empty. This might not accurately represent a real empty state scenario and could confuse developers. Consider setting notificationsUnreadCount to 0 to maintain data consistency.

   me: {
     id: 'user-1',
-    notificationsUnreadCount: 12,
+    notificationsUnreadCount: 0,
     notifications: {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const emptyNotificationsListMockData = {
data: {
me: {
id: 'user-1',
notificationsUnreadCount: 12,
notifications: {
edges: [],
pageInfo: {
hasNextPage: false,
endCursor: null,
},
},
},
},
}
export const emptyNotificationsListMockData = {
data: {
me: {
id: 'user-1',
notificationsUnreadCount: 0,
notifications: {
edges: [],
pageInfo: {
hasNextPage: false,
endCursor: null,
},
},
},
},
}

@matheusysd matheusysd force-pushed the BA-1738-notifications-storybook branch from 1796cfe to 60e7d90 Compare November 12, 2024 19:40
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
51.0% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants