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

NEO-2435: Global Custom Filter improvements #560

Merged
merged 14 commits into from
Oct 10, 2024

Conversation

enrique-prado
Copy link
Contributor

@enrique-prado enrique-prado commented Oct 8, 2024

Link to updated story in Deploy Preview

Before tagging the team for a review, I have done the following:

  • run yarn all locally: ensures that all tests pass, formatting is done, types pass, and builds pass
  • reviewed my code changes
  • updated the Deploy Preview link at the top of this PR (or remove it if not applicable)
  • added any important information to this PR (description, images, GIFs, ect.)
  • done an accessibility check on my work (tested with Chrome's axe Dev Tools, Mac's VoiceOver, etc.)
  • tagged @avaya-dux/dux-devs

This PR adds the ability to Apply multiple column filters while providing a custom UI for specifying those filters.

  • This is mainly accomplished by exposing the setAllFilters() Table instance api.
  • The story shows how to provide custom UI and apply filters.
  • To clear previously applied filters, click the x clear button in the TextInput and apply.
image

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced multiple new story exports for the Table component, including filtering, row selection, and pagination functionalities.
    • Added advanced filtering capabilities with a new filter drawer and the ability to pre-select rows.
  • Functionality Enhancements

    • Enhanced state management for filters and row selections, improving interactivity and user experience.
    • Improved filtering capabilities with the addition of a new allFilters prop for dynamic filter application.
  • Bug Fixes

    • Improved handling of row deletions and data synchronization to ensure accurate table updates.
  • Documentation

    • Updated type definitions to include new properties for enhanced flexibility in the Table component.

Copy link
Contributor

coderabbitai bot commented Oct 8, 2024

Walkthrough

The changes in this pull request enhance the Table component by introducing new story exports and improving filtering functionalities. New stories such as CustomBasicTableFilterDrawer, WithRowSeparator, and PreSelectedRows have been added to showcase various features. The Table component's props are updated to include allFilters, enabling dynamic filter application. Additionally, state management has been refined to handle filters and row selections more effectively. Overall, these modifications improve the interactivity and usability of the Table component within the Storybook environment.

Changes

File Path Change Summary
src/components/Table/Table.stories.tsx Added new stories: CustomBasicTableFilterDrawer, WithRowSeparator, PreSelectedRows, SecondPage, DisabledRows. Enhanced CustomBasicTableFilterDrawer with handleApply function for filter management. Modified EmbeddedSelects story for row actions.
src/components/Table/Table.tsx Introduced allFilters prop for filter management. Updated state management and logging for filters. Modified handleDeleteWrapper for row selection after deletion. Adjusted memoizedRows logic.
src/components/Table/types/TableTypes.ts Added allFilters property of type ColumnFilter[] to TableProps interface. Maintained existing properties for backward compatibility.
src/components/Table/index.ts Updated exports to include ColumnFilter type alongside TableProps.
package.json Version updated from 1.3.5 to 1.3.6.

Possibly related PRs

Suggested reviewers

  • joe-s-avaya

Poem

🐇 In the meadow where tables play,
New stories bloom in bright array.
Filters dance and rows align,
With every click, the data shines.
So hop along, let's celebrate,
The Table's charm, oh isn't it great! 🌼


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

netlify bot commented Oct 8, 2024

Deploy Preview for neo-react-library-storybook ready!

Name Link
🔨 Latest commit 9724abd
🔍 Latest deploy log https://app.netlify.com/sites/neo-react-library-storybook/deploys/67082c3589496100084fded0
😎 Deploy Preview https://deploy-preview-560--neo-react-library-storybook.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.

Copy link
Contributor

@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: 4

🧹 Outside diff range and nitpick comments (2)
src/components/Table/types/TableTypes.ts (1)

Line range hint 1-106: Consider improving overall type safety and documentation

While the file structure is generally good, there are a few areas where it could be improved:

  1. Type safety: The use of any in AnyRecord and other places reduces type safety. Consider using more specific types where possible.

  2. Documentation: Many types and interfaces lack JSDoc comments. Adding these would improve code understanding and maintainability.

  3. Consistency: The file mixes interfaces and type aliases. While not incorrect, choosing one style could improve consistency.

Here are some suggestions:

  1. Replace AnyRecord with a more specific type when possible, or use generics to constrain the type.

  2. Add JSDoc comments to major types and interfaces. For example:

    /**
     * Represents the properties for the Table component.
     * @template T The type of data in the table rows.
     */
    export type TableProps<T extends AnyRecord> = {
      // ... existing properties
    }
  3. Consider using either interfaces or type aliases consistently throughout the file, unless there's a specific reason to mix them.

These changes would make the code more robust, self-documenting, and consistent.

src/components/Table/Table.tsx (1)

209-214: Approve new useEffect for filter updates, but consider refinements

The new useEffect hook appropriately updates the table's filters when allFilters changes. However, consider the following suggestions:

  1. Remove the logger.info statement for production builds to avoid unnecessary console output.
  2. Reconsider the dependency array. While the lint rule is disabled, it's generally better to include all dependencies. If setAllFilters is stable (e.g., from useCallback), including it won't cause issues.

Consider applying these changes:

 useEffect(() => {
-  logger.info(allFilters, filters);
   setAllFilters(allFilters);
-}, [allFilters]);
+}, [allFilters, setAllFilters]);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b206712 and 2ade080.

📒 Files selected for processing (3)
  • src/components/Table/Table.stories.tsx (1 hunks)
  • src/components/Table/Table.tsx (2 hunks)
  • src/components/Table/types/TableTypes.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (4)
src/components/Table/Table.tsx (4)

117-117: LGTM: New allFilters prop enhances filtering capabilities

The addition of the allFilters prop with a default empty array is a good enhancement. It allows for more flexible and dynamic filter application while maintaining backward compatibility.


200-200: LGTM: Destructured filters from state enhances filter management

The addition of filters to the destructured state from useTable hook is a good practice. It allows for better management and access to the current filters applied to the table, supporting the enhanced filtering functionality.


206-206: LGTM: Added setAllFilters for comprehensive filter updates

The inclusion of setAllFilters from the useTable hook is appropriate. This function will allow for updating all filters simultaneously, which is consistent with the new allFilters prop and enhances the table's filtering capabilities.


Line range hint 269-275: LGTM: Improved handleDeleteWrapper with row deselection

The addition of toggleAllRowsSelected(false) after the delete operation is a good improvement. It ensures that all rows are deselected after a delete operation, preventing potential confusion or unintended actions on deleted rows.

src/components/Table/types/TableTypes.ts Outdated Show resolved Hide resolved
src/components/Table/Table.stories.tsx Show resolved Hide resolved
src/components/Table/Table.stories.tsx Show resolved Hide resolved
src/components/Table/Table.stories.tsx Show resolved Hide resolved
Copy link
Contributor

@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: 2

🧹 Outside diff range and nitpick comments (1)
src/components/Table/Table.stories.tsx (1)

Line range hint 1097-1170: DisabledRows story demonstrates disabled rows functionality

This story effectively showcases the Table component with disabled rows. It implements:

  1. State management for data and readonly status.
  2. Handlers for create, delete, edit, and refresh actions.
  3. Logging of data modifications.

The implementation is consistent with other stories and demonstrates good practices.

Consider adding a comment or visual indicator in the story to explicitly show how rows are disabled in the data. This would make it clearer for developers how to implement disabled rows in their own tables.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 2ade080 and 55e3c56.

📒 Files selected for processing (3)
  • src/components/Table/Table.stories.tsx (2 hunks)
  • src/components/Table/Table.tsx (2 hunks)
  • src/components/Table/types/TableTypes.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/Table/types/TableTypes.ts
🧰 Additional context used
🔇 Additional comments (11)
src/components/Table/Table.stories.tsx (7)

44-44: New import added for ColumnFilter type

The ColumnFilter type has been imported from "./types". This suggests that filter-related functionality has been added or modified in the Table component.


893-894: Update Table component with allFilters prop

The Table component is now using a new prop 'allFilters' to apply filters. This is a good addition for managing filters externally.


903-915: Add 'value' prop to TextInput components

The TextInput components for name and other filters are missing the 'value' prop, making them uncontrolled components. This issue was identified in a previous review and is still valid.

To fix this, add the 'value' prop to both TextInput components:

<TextInput
  clearable
  label="Name"
  type="text"
+ value={nameFilter ?? ''}
  onChange={(e) => setNameFilter(e.currentTarget.value)}
/>

<TextInput
  clearable
  label="Other"
  type="text"
+ value={otherFilter ?? ''}
  onChange={(e) => setOtherFilter(e.currentTarget.value)}
/>

Line range hint 919-923: WithRowSeparator story looks good

This story effectively demonstrates the usage of the 'showRowSeparator' prop for the Table component. The implementation is clean and straightforward.


Line range hint 925-979: PreSelectedRows story demonstrates good practices

This story effectively showcases the pre-selection of rows in the Table component. It demonstrates several good practices:

  1. Uses the 'defaultSelectedRowIds' prop to set initial selected rows.
  2. Implements a custom 'handleToggle' function to manage row selection state.
  3. Provides visual feedback through logging of selection changes.
  4. Uses the 'selectableRows' prop to enable multiple row selection.

The implementation is clean, well-structured, and serves as a good example for managing row selection in the Table component.


Line range hint 981-1095: SecondPage story provides comprehensive pagination example

This story excellently demonstrates advanced pagination functionality:

  1. Defaults to the second page and tracks the current page index.
  2. Manages state for data, readonly status, page index, and page size.
  3. Implements handlers for create, delete, edit, and refresh actions.
  4. Provides clear explanations of the functionality through comments and UI text.
  5. Demonstrates how to handle page changes and maintain the current page when data is modified.

The implementation is thorough and serves as a great example for managing complex pagination scenarios in the Table component.


Line range hint 1172-1295: EmbeddedSelects story demonstrates advanced table functionality

This story effectively showcases embedding Select components within table cells and implementing custom action handling for each row. The implementation is creative and demonstrates advanced usage of the Table component.

Consider the following improvements:

  1. Memoize the handleSelectedValueChange function using useCallback to optimize performance.
  2. Simplify the switch statement in handleSelectedValueChange by using an object lookup or reducing repetitive code.

There's a HACK comment mentioning that actions are being called twice. This needs investigation:

This will help identify if the issue is in the Table component itself or if it's specific to this story's implementation.

✅ Verification successful

Verified: No additional instances of double action calls found beyond the scoped component. The HACK in Table.stories.tsx effectively addresses the issue within this context.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for potential double action calls in the Table component
rg --type typescript 'handleSelectedValueChange|onChange.*Select' src/components/Table

Length of output: 123


Script:

#!/bin/bash
# Search for potential double action calls in the Table component with correct file extensions
rg 'handleSelectedValueChange|onChange.*Select' src/components/Table --glob '*.ts' --glob '*.tsx'

Length of output: 270

src/components/Table/Table.tsx (4)

117-117: Addition of allFilters prop

The allFilters prop is correctly added to the component's props with a default value of an empty array. This allows the table to accept multiple filters externally.


200-200: Destructuring filters from state

Destructuring filters from the state enables access to the current filters applied to the table, which is necessary for managing filter states effectively.


206-206: Destructuring setAllFilters from the table instance

Extracting setAllFilters from the table instance allows for programmatically updating all filters, which is essential for the new filtering functionality.


209-215: Consider updating the dependency array in useEffect

The useEffect hook does not include setAllFilters in its dependency array and includes a comment to ignore exhaustive dependencies for performance reasons. While this might prevent unnecessary re-renders, omitting dependencies can lead to bugs if setAllFilters changes. Ensure that setAllFilters is stable or consider including it in the dependency array.

src/components/Table/Table.stories.tsx Show resolved Hide resolved
src/components/Table/Table.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@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: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 55e3c56 and 685520c.

📒 Files selected for processing (1)
  • src/components/Table/Table.tsx (2 hunks)
🧰 Additional context used
🔇 Additional comments (5)
src/components/Table/Table.tsx (5)

117-117: LGTM: New allFilters prop added

The addition of the allFilters prop with a default empty array is a good enhancement. It allows for external control of filters while maintaining backward compatibility.


200-200: LGTM: Destructuring filters from useTable state

Extracting filters from the useTable hook's state is a good practice. It allows for easier access to the current filters applied to the table, which is essential for the new filtering functionality.


206-206: LGTM: Destructuring setAllFilters from useTable

The addition of setAllFilters to the destructured values from useTable is appropriate. This function will be crucial for updating all filters simultaneously, which aligns with the new filtering functionality introduced by the allFilters prop.


Line range hint 284-291: LGTM: Improved handleDeleteWrapper function

The modification to handleDeleteWrapper is a good improvement. Calling toggleAllRowsSelected(false) after the delete operation ensures that all rows are deselected, which is a good practice after performing a bulk action like delete. This prevents potential confusion or unintended actions on stale selections.


Line range hint 1-624: Overall assessment: Good improvements with one concern

The changes to the Table component generally enhance its functionality, particularly in terms of filtering and state management. The addition of the allFilters prop and related logic improves the component's flexibility. However, there's one important issue to address:

  1. The suppressed TypeScript error in the new useEffect hook should be resolved rather than ignored.

Once this issue is addressed, the changes will significantly improve the Table component without introducing potential type-related bugs.

src/components/Table/Table.tsx Outdated Show resolved Hide resolved
@enrique-prado enrique-prado requested a review from a team October 10, 2024 18:53
Copy link
Contributor

@joe-s-avaya joe-s-avaya left a comment

Choose a reason for hiding this comment

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

consider adding unit tests, but otherwise this all looks good

Copy link
Contributor

@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: 0

🧹 Outside diff range and nitpick comments (2)
src/components/Table/index.ts (2)

2-2: LGTM! Consider adding a brief comment for the new export.

The addition of ColumnFilter to the exports aligns well with the PR objective of enhancing global custom filter functionality. This change will allow consumers of the library to access and use the ColumnFilter type, which is likely crucial for implementing the new filtering capabilities.

Consider adding a brief comment above the export line to explain the purpose of ColumnFilter. This can help other developers understand its role in the new filtering system. For example:

// ColumnFilter type used for configuring custom column filters
export type { ColumnFilter, TableProps } from "./types";

Line range hint 6-6: Consider enhancing the note about TableNext

The note about TableNext not being exported is informative. To provide more context for other developers, consider expanding this note slightly.

You could modify the note to include more details or a timeline if available:

// NOTE: `TableNext` is *not* exported as it is not ready for production use.
// It is under active development and is expected to be available in a future release.
// For updates, please check the project roadmap or upcoming release notes.

This additional information can help set expectations for when TableNext might become available and where to look for updates.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 84ee064 and 9724abd.

📒 Files selected for processing (2)
  • package.json (1 hunks)
  • src/components/Table/index.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • package.json
🧰 Additional context used
📓 Learnings (1)
📓 Common learnings
Learnt from: enrique-prado
PR: avaya-dux/neo-react-library#560
File: src/components/Table/Table.stories.tsx:866-885
Timestamp: 2024-10-10T17:30:21.136Z
Learning: In `src/components/Table/Table.stories.tsx`, suggestions to `CustomBasicTableFilterDrawer` should focus on significant and relevant improvements, as minor suggestions may be considered irrelevant.

@enrique-prado enrique-prado merged commit e9490bb into main Oct 10, 2024
8 checks passed
@enrique-prado enrique-prado deleted the NEO-2435-filter-improvements branch October 10, 2024 20:58
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.

2 participants