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

[Perf]: Optimize Team Members Component #3693

Merged
merged 5 commits into from
Mar 26, 2025

Conversation

Innocent-Akim
Copy link
Contributor

@Innocent-Akim Innocent-Akim commented Mar 26, 2025

Description

Please include a summary of the changes and the related issues.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented on my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings

Previous screenshots

Please add here videos or images of the previous status

Current screenshots

Please add here videos or images of the current (new) status

Summary by CodeRabbit

  • Refactor
    • Streamlined the team view for faster, more efficient filtering and sorting of members.
    • Enhanced the team status section with dynamic displays for a clearer, more responsive overview of member activity.
    • Consolidated loading state management across various components for improved clarity and performance.
    • Introduced column visibility management in the activity table for better user control over displayed data.

- Extract and memoize filter/sort functions with useCallback
- Improve useMemo dependencies for better performance
- Fix loose equality operators to strict equality
- Add null safety checks for optional properties
- Split complex computations into smaller reusable functions
- Add TypeScript type safety improvements
- Remove unnecessary re-renders
- Add comprehensive code documentation
- Add proper TypeScript types for timer status and filters
- Implement useMemo for member status counting
- Replace map with reduce for better performance
- Add type guards for status validation
- Create reusable initialFilter constant
- Fix code formatting and indentation
- Improve code readability and maintainability
- Add proper TypeScript types and interfaces
- Create reusable status buttons configuration
- Fix import paths and module resolution
- Improve code maintainability with DRY principles
- Add type safety for translations
- Reduce code duplication in status buttons
- Optimize component rendering with proper types
@Innocent-Akim Innocent-Akim self-assigned this Mar 26, 2025
Copy link
Contributor

coderabbitai bot commented Mar 26, 2025

Walkthrough

The pull request refactors components within the team features. In the TeamMembers components, memoized functions have been introduced to efficiently filter and sort members using hooks such as useCallback and useMemo, and strict equality checks now replace loose comparisons. The UserTeamBlockHeader component has been restructured with reordered imports, new type definitions, and a dynamic calculation of members’ status data using a reducer pattern. Rendering logic for status buttons has also been simplified, enhancing maintainability while keeping core functionality unchanged. Additionally, loading state management has been consolidated across various components.

Changes

File(s) Change Summary
apps/web/.../team-members.tsx Refactored TeamMembers and TeamMembersView components by adding memoized functions (filterValidMembers, sortMembers, filterBlockViewMembers, filterOtherMembers, sortOtherMembers), consolidating filter and sort logic with useMemo, and updating sortByWorkStatus to use strict equality checks.
apps/web/.../user-team-block-header.tsx Improved UserTeamBlockHeader by reordering imports, introducing new types (TimerStatus, FilterType), and updating the IFilter interface. Added an initialFilter constant and a memoized reducer for computing members status, and refactored the rendering of status buttons into a separate function.
apps/web/.../dashboard/app-url/[teamId]/page.tsx Simplified loading state management in AppUrls by replacing loadingActivityReport with a generalized loading variable across productivity tables.
apps/web/.../team-dashboard/[teamId]/page.tsx Consolidated loading state variables in TeamDashboard into a single loading variable, simplifying prop management for child components.
apps/web/.../time-and-activity/Components/ActivityTable.tsx Introduced column visibility management in ActivityTable, utilizing a Map for visibility states and providing user feedback when no columns are visible.
apps/web/.../hooks/features/useReportActivity.ts Enhanced useReportActivity by introducing memoization for computed values, consolidating loading state management into a single loading variable.

Sequence Diagram(s)

sequenceDiagram
    participant C as Component (TeamMembers)
    participant UM as useMemo
    participant FV as filterValidMembers
    participant SM as sortMembers
    participant UI as UI

    C->>UM: Trigger memoized computation on render
    UM->>FV: Filter valid members
    FV-->>UM: Return filtered members
    UM->>SM: Sort the filtered result
    SM-->>UM: Return sorted list
    UM-->>C: Provide optimized members list
    C->>UI: Render updated team members
Loading
sequenceDiagram
    participant C as Component (UserTeamBlockHeader)
    participant UM as useMemo for status count
    participant R as Reducer (reduce)
    participant SB as statusButtons
    participant UI as UI

    C->>UM: Calculate membersStatusNumber
    UM->>R: Reduce member statuses
    R-->>UM: Return aggregated status counts
    C->>SB: Generate button configurations based on counts
    SB-->>C: Return dynamic status buttons
    C->>UI: Render header with updated buttons
Loading

Suggested labels

WEB, Improvement, feature

Suggested reviewers

  • evereq

Poem

I'm hopping through the code with glee,
Each memoized jump is light and free.
Filters and sorts now play as one,
With strict checks, our work is done!
A rabbit's cheer for clean code fun 🐇✨

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.

apps/web/app/[locale]/dashboard/app-url/[teamId]/page.tsx

Oops! Something went wrong! :(

ESLint: 8.46.0

ESLint couldn't find the config "next/core-web-vitals" to extend from. Please check that the name of the config is correct.

The config "next/core-web-vitals" was referenced from the config file in "/apps/web/.eslintrc.json".

If you still have problems, please stop by https://eslint.org/chat/help to chat with the team.

apps/web/app/[locale]/dashboard/team-dashboard/[teamId]/page.tsx

Oops! Something went wrong! :(

ESLint: 8.46.0

ESLint couldn't find the config "next/core-web-vitals" to extend from. Please check that the name of the config is correct.

The config "next/core-web-vitals" was referenced from the config file in "/apps/web/.eslintrc.json".

If you still have problems, please stop by https://eslint.org/chat/help to chat with the team.

apps/web/lib/features/team-members.tsx

Oops! Something went wrong! :(

ESLint: 8.46.0

ESLint couldn't find the config "next/core-web-vitals" to extend from. Please check that the name of the config is correct.

The config "next/core-web-vitals" was referenced from the config file in "/apps/web/.eslintrc.json".

If you still have problems, please stop by https://eslint.org/chat/help to chat with the team.

  • 3 others

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 46a93fa and d12b0e4.

📒 Files selected for processing (6)
  • apps/web/app/[locale]/dashboard/app-url/[teamId]/page.tsx (2 hunks)
  • apps/web/app/[locale]/dashboard/team-dashboard/[teamId]/page.tsx (4 hunks)
  • apps/web/app/[locale]/time-and-activity/Components/ActivityTable.tsx (1 hunks)
  • apps/web/app/hooks/features/useReportActivity.ts (5 hunks)
  • apps/web/lib/features/team-members.tsx (4 hunks)
  • apps/web/lib/features/team/user-team-block/user-team-block-header.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/web/lib/features/team-members.tsx
  • apps/web/lib/features/team/user-team-block/user-team-block-header.tsx
🧰 Additional context used
🧬 Code Definitions (2)
apps/web/app/[locale]/dashboard/app-url/[teamId]/page.tsx (2)
apps/web/app/hooks/features/useReportActivity.ts (1)
  • useReportActivity (76-362)
apps/web/app/[locale]/dashboard/app-url/components/ProductivityTable.tsx (1)
  • ProductivityTable (17-206)
apps/web/app/[locale]/dashboard/team-dashboard/[teamId]/page.tsx (1)
apps/web/app/[locale]/dashboard/team-dashboard/[teamId]/components/team-stats-table.tsx (1)
  • TeamStatsTable (42-370)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: deploy
🔇 Additional comments (14)
apps/web/app/[locale]/dashboard/app-url/[teamId]/page.tsx (2)

41-42: Good consolidation of loading state handling

The change from destructuring loadingActivityReport to using a consolidated loading variable from the useReportActivity hook improves code clarity and maintainability.


145-152: Consistent loading state management

Replacing multiple instances of loadingActivityReport with the consolidated loading variable creates a more unified approach to loading state management across different productivity tables.

apps/web/app/[locale]/dashboard/team-dashboard/[teamId]/page.tsx (2)

31-39: Good refactoring of loading state variables

The consolidation of multiple loading state variables into a single loading variable simplifies the component and improves maintainability.


80-83: Consistent loading state propagation

The consistent use of the consolidated loading variable across all child components (TeamStatsGrid, TeamStatsChart, and TeamStatsTable) ensures a unified approach to loading state management.

Also applies to: 105-105, 131-131

apps/web/app/hooks/features/useReportActivity.ts (6)

80-80: Performance optimization with useMemo

Good use of useMemo to optimize the calculation of isManage, preventing unnecessary recalculations when unrelated state changes.


98-109: Efficient memoization of derived data

The introduction of memoized employeeIds and teamIds variables is a good performance optimization, especially for frequently accessed values that depend on other state.


134-136: Improved use of memoized values

The code now properly uses the memoized employeeIds and teamIds variables, ensuring consistent data access and reducing unnecessary calculations.


152-152: Comprehensive dependency array

Good update to the dependency array for getMergedProps to include the new memoized variables, ensuring the function is properly recalculated when these dependencies change.


154-166: Well-implemented loading state consolidation

The creation of a consolidated loading variable using useMemo is a great refactoring that simplifies the API of this hook while maintaining all the necessary loading information.


344-344: Clean API through loading state consolidation

Returning a single loading variable instead of multiple specific loading states creates a cleaner and more maintainable API for consumers of this hook.

apps/web/app/[locale]/time-and-activity/Components/ActivityTable.tsx (4)

34-46: Well-implemented column visibility logic

Good use of useMemo to create the column visibility map from the view options, with sensible defaults. This approach efficiently handles the dynamic column visibility feature.


48-70: Improved user experience with empty state handling

Excellent addition of a user-friendly message when no columns are selected, guiding the user to select at least one column to display data.


124-153: Clean conditional rendering of table headers

The conditional rendering of table headers based on column visibility is well-implemented and maintains a clean code structure while providing dynamic functionality.


163-232: Consistent conditional rendering throughout table

The conditional rendering approach is consistently applied to both table headers and cells, ensuring that the table structure remains intact while allowing dynamic column visibility.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

Performance optimization changes to the team members components, focusing on memoization strategies and TypeScript improvements for better type safety and reduced re-renders.

  • Introduced proper TypeScript types for timer status and filters in /apps/web/lib/features/team/user-team-block/user-team-block-header.tsx
  • Added memoized status button configuration with statusButtons function for better maintainability
  • Implemented useCallback hooks for filter and sort operations in /apps/web/lib/features/team-members.tsx
  • Optimized member status counting using reduce with type-safe accumulator
  • Combined expensive operations within useMemo hooks using proper dependency arrays

2 file(s) reviewed, 4 comment(s)
Edit PR Review Bot Settings | Greptile

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

🧹 Nitpick comments (1)
apps/web/lib/features/team-members.tsx (1)

112-118: Consider improving sortOtherMembers logic.

While correctly memoized, the sorting logic could be more robust by handling the case where one member has an order and the other doesn't.

 const sortOtherMembers = useCallback((members: OT_Member[]) => {
   return members.sort((a, b) => {
-    if (a.order && b.order) return a.order > b.order ? -1 : 1;
-    else return -1;
+    if (a.order !== undefined && b.order !== undefined) return a.order > b.order ? -1 : 1;
+    if (a.order !== undefined) return -1;
+    if (b.order !== undefined) return 1;
+    return 0;
   });
 }, []);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a25c68f and 46a93fa.

📒 Files selected for processing (2)
  • apps/web/lib/features/team-members.tsx (1 hunks)
  • apps/web/lib/features/team/user-team-block/user-team-block-header.tsx (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: deploy
🔇 Additional comments (19)
apps/web/lib/features/team-members.tsx (12)

15-15: Excellent addition of React hooks for optimizations.

The addition of useMemo and useCallback imports is a good foundation for the performance improvements in this file.


23-28: Good job adding descriptive comments for hooks.

Adding comments to explain the purpose of hooks with expensive computations improves code readability and maintainability.


29-32: Well-implemented memoization of filter function.

Memoizing the filter function with useCallback prevents unnecessary recreations on each render, improving performance.


34-37: Good pattern for memoizing sort function.

The sort function is correctly memoized with useCallback, with an empty dependency array since it doesn't depend on any external variables.


39-44: Excellent consolidation of filter and sort operations.

Combining filter and sort operations into a single useMemo hook reduces the number of iterations over the data and improves performance.


46-53: Well-implemented memoization of block view filter function.

The block view filter function is correctly memoized with appropriate logic for different filter cases.


55-59: Good dependency management in useMemo hook.

The dependencies array for the blockViewMembers useMemo hook correctly includes all necessary dependencies: orderedMembers, activeFilter, and filterBlockViewMembers.


61-65: Effective memoization of current user lookup.

Memoizing the current user lookup prevents unnecessary recalculations when other state changes occur.


67-68: Good insight on simple computation.

Correctly identifying that simple computations don't need memoization helps prevent unnecessary overhead.


107-110: Good implementation of filterOtherMembers.

The filterOtherMembers function is correctly memoized with useCallback and has appropriate filtering logic.


120-125: Excellent pattern for combining filter and sort in one memoized computation.

Combining filter and sort operations with proper dependency management improves performance and readability.


209-217: Good improvement in type safety for sorting function.

Updating the sortByWorkStatus function to use strict equality checks (=== and !==) instead of loose checks (== and !=) enhances type safety and predictability.

apps/web/lib/features/team/user-team-block/user-team-block-header.tsx (7)

7-12: Good organization of imports.

The imports are well-organized with React hooks, utilities, and SVG assets properly grouped.


13-26: Excellent addition of type definitions for better type safety.

The introduction of TimerStatus and FilterType along with extending the IFilter interface with IStatusCount significantly improves type safety and code maintainability.


28-34: Good initialization of filter state.

Creating an initialFilter constant provides a single source of truth for the initial state of status counts.


36-68: Excellent refactoring to extract status button configuration.

Extracting the status button configuration into a separate function improves maintainability and reduces duplication in the JSX.

However, the activeTeam parameter is typed as any. Consider adding a proper type.

-const statusButtons = (t: ReturnType<typeof useTranslations>, membersStatusNumber: IFilter, activeTeam: any) => [
+const statusButtons = (
+  t: ReturnType<typeof useTranslations>,
+  membersStatusNumber: IFilter,
+  activeTeam: { members?: Array<{ timerStatus?: TimerStatus }> }
+) => [

75-75: Good type annotation for activeFilter.

Using the newly defined FilterType for the activeFilter state improves type safety.


80-98: Excellent use of useMemo for performance optimization.

The implementation of useMemo for calculating membersStatusNumber with a reducer pattern is a significant performance improvement over the previous approach. The code handles edge cases well and includes proper type checking.


107-134: Great refactoring of button rendering.

Replacing hardcoded buttons with a dynamic rendering using the map function significantly improves code maintainability and reduces duplication.

- Add proper TypeScript types for timer status and filters
- Implement useMemo for member status counting
- Replace map with reduce for better performance
- Add type guards for status validation
- Create reusable initialFilter constant
- Fix code formatting and indentation
- Improve code readability and maintainability
@Innocent-Akim Innocent-Akim force-pushed the perf/optimize-team-members-component branch from 46a93fa to d12b0e4 Compare March 26, 2025 03:44
@evereq evereq merged commit c9f2e47 into develop Mar 26, 2025
12 of 13 checks passed
@evereq evereq deleted the perf/optimize-team-members-component branch March 26, 2025 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants