这是indexloc提供的服务,不要输入任何密码
Skip to content

feat(router): optional router in ActivitySidebar #4199

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

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

rafalmaksymiuk
Copy link
Contributor

@rafalmaksymiuk rafalmaksymiuk commented Jul 24, 2025

Enabled an optional Router usage in ActivitySidebar component.
Converted related tests to RTL and added coverage for new logic.

Summary by CodeRabbit

  • New Features

    • Added support for internal sidebar navigation as an alternative to React Router, allowing navigation handling without relying on the router.
    • Introduced new options to control navigation behavior in the activity sidebar.
    • Made the active feed entry ID optional in the activity annotations sidebar view.
  • Bug Fixes

    • Improved handling of annotation selection and reply updates when router navigation is disabled.
  • Tests

    • Added comprehensive new tests for the activity sidebar component covering navigation and event handling.
    • Removed outdated or redundant tests related to reply updates and annotation selection.

@rafalmaksymiuk rafalmaksymiuk requested review from a team as code owners July 24, 2025 15:37
Copy link

coderabbitai bot commented Jul 24, 2025

"""

Walkthrough

This change introduces an internal sidebar navigation mechanism to the ActivitySidebar component, providing an alternative to React Router-based navigation. It updates type definitions to make certain navigation properties optional, adds new props and conditional navigation logic, and refactors tests to support and verify the new navigation behavior.

Changes

File(s) Change Summary
src/elements/common/types/SidebarNavigation.ts Made activeFeedEntryId optional in ActivityAnnotationsSidebarView type definition.
src/elements/content-sidebar/ActivitySidebar.js Added internal navigation props and conditional logic for navigation; updated methods to use new navigation.
src/elements/content-sidebar/tests/ActivitySidebar.rtl.test.js Added comprehensive RTL test suite for ActivitySidebar, covering internal navigation and event handling.
src/elements/content-sidebar/tests/ActivitySidebar.test.js Removed test cases for updateReplies() and handleAnnotationSelect(); cleaned up unused imports.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ActivitySidebar
    participant InternalNavHandler
    participant RouterHistory

    User->>ActivitySidebar: Select annotation or update replies
    alt routerDisabled and internalSidebarNavigationHandler present
        ActivitySidebar->>InternalNavHandler: Call handler with navigation object
    else router enabled
        ActivitySidebar->>RouterHistory: Push or replace path
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Poem

In the warren of code, a new path appears,
Internal navigation now steers!
With options and handlers, the sidebar’s more spry,
Old tests retire, while new ones hop by.
A rabbit applauds this navigational feat—
Hopping between sidebars is now quite neat!
🐇✨
"""

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 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 6cb72df and fbd8c25.

📒 Files selected for processing (1)
  • src/elements/content-sidebar/ActivitySidebar.js (9 hunks)
🧰 Additional context used
🪛 Biome (2.1.2)
src/elements/content-sidebar/ActivitySidebar.js

[error] 80-80: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 1130-1130: Expected an expression but instead found '}'.

Expected an expression here.

(parse)


[error] 1136-1136: expected } but instead found ;

Remove ;

(parse)


[error] 1137-1137: Unexpected token. Did you mean {'}'} or }?

(parse)


[error] 1138-1138: expected } but instead found const

Remove const

(parse)


[error] 1140-1140: Unexpected token. Did you mean {'}'} or }?

(parse)


[error] 1145-1145: expected } but instead found if

Remove if

(parse)


[error] 1151-1151: expected } but instead found ;

Remove ;

(parse)


[error] 1152-1152: Unexpected token. Did you mean {'}'} or }?

(parse)


[error] 1153-1153: expected } but instead found ;

Remove ;

(parse)


[error] 1154-1154: Unexpected token. Did you mean {'}'} or }?

(parse)


[error] 1196-1196: expected } but instead found const

Remove const

(parse)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint_test_build
  • GitHub Check: Summary
🔇 Additional comments (5)
src/elements/content-sidebar/ActivitySidebar.js (5)

31-31: Import statement looks good.

The addition of ViewType and FeedEntryType imports is appropriate for the new internal navigation functionality.


91-93: Type definitions for new navigation props are well-structured.

The optional nature of these props is appropriate since they're only needed when the router is disabled. The type annotations follow Flow conventions correctly.

Also applies to: 101-101


555-555: Conditional navigation implementation is well-designed.

The implementation correctly handles both router-enabled and router-disabled scenarios:

  • Properly checks for both routerDisabled flag and handler existence before using internal navigation
  • Falls back gracefully to the original history.replace behavior when the router is enabled
  • Constructs appropriate navigation object with the correct view type

Also applies to: 575-584


1125-1129: Annotation selection logic handles both navigation modes correctly.

The implementation properly:

  • Determines the selected file version ID based on router state (internal navigation vs router params)
  • Conditionally navigates using either internal handler or history API
  • Passes appropriate parameters including activeFeedEntryId, activeFeedEntryType, and fileVersionId

The conditional navigation logic is consistent with the pattern used in updateReplies.

Also applies to: 1134-1154


1196-1197: Props are correctly passed to AddTaskButton component.

The navigation-related props are appropriately passed to the AddTaskButton component, ensuring consistent navigation behavior throughout the sidebar. The destructuring and prop passing syntax is correct.

Also applies to: 1207-1208, 1211-1211

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this 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: 0

🧹 Nitpick comments (1)
src/elements/content-sidebar/ActivitySidebar.js (1)

1134-1143: Consider extracting file version selection logic for better readability.

The implementation correctly handles both navigation modes, but the file version selection logic could be extracted into a helper method for improved readability and testability.

-        let selectedFileVersionId = currentFileVersionId;
-        if (routerDisabled && internalSidebarNavigation) {
-            // Use fileVersionId from internal navigation when router is disabled
-            selectedFileVersionId = getProp(internalSidebarNavigation, 'fileVersionId', currentFileVersionId);
-        } else {
-            // Use router-based approach when router is enabled
-            const match = getAnnotationsMatchPath(location);
-            selectedFileVersionId = getProp(match, 'params.fileVersionId', currentFileVersionId);
-        }
+        const selectedFileVersionId = this.getSelectedFileVersionId(
+            currentFileVersionId,
+            routerDisabled,
+            internalSidebarNavigation,
+            location,
+            getAnnotationsMatchPath
+        );

Add this helper method to the class:

getSelectedFileVersionId = (
    currentFileVersionId: string,
    routerDisabled: ?boolean,
    internalSidebarNavigation: ?InternalSidebarNavigation,
    location: Object,
    getAnnotationsMatchPath: Function
): string => {
    if (routerDisabled && internalSidebarNavigation) {
        // Use fileVersionId from internal navigation when router is disabled
        return getProp(internalSidebarNavigation, 'fileVersionId', currentFileVersionId);
    }
    // Use router-based approach when router is enabled
    const match = getAnnotationsMatchPath(location);
    return getProp(match, 'params.fileVersionId', currentFileVersionId);
};
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1506020 and 2cca0c2.

📒 Files selected for processing (4)
  • src/elements/common/types/SidebarNavigation.ts (1 hunks)
  • src/elements/content-sidebar/ActivitySidebar.js (9 hunks)
  • src/elements/content-sidebar/__tests__/ActivitySidebar.rtl.test.js (1 hunks)
  • src/elements/content-sidebar/__tests__/ActivitySidebar.test.js (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: rafalmaksymiuk
PR: box/box-ui-elements#4144
File: src/elements/content-sidebar/versions/VersionsList.js:24-33
Timestamp: 2025-06-17T13:30:02.172Z
Learning: In the box-ui-elements codebase, Flow components use .flow.js type definition files, not TypeScript .ts files. The InternalSidebarNavigation type is a union type where different variants may have different properties like versionId, and proper type safety is ensured through conditional checks in methods like getSelectedVersionId.
Learnt from: rafalmaksymiuk
PR: box/box-ui-elements#4136
File: src/elements/common/types/SidebarNavigation.ts:16-26
Timestamp: 2025-06-11T16:30:10.431Z
Learning: `VersionSidebarView` intentionally uses the `versionId` field to stay consistent with current URL parameter naming; a potential rename to `fileVersionId` is deferred until React Router is removed.
src/elements/common/types/SidebarNavigation.ts (2)

Learnt from: rafalmaksymiuk
PR: #4144
File: src/elements/content-sidebar/versions/VersionsList.js:24-33
Timestamp: 2025-06-17T13:30:02.172Z
Learning: In the box-ui-elements codebase, Flow components use .flow.js type definition files, not TypeScript .ts files. The InternalSidebarNavigation type is a union type where different variants may have different properties like versionId, and proper type safety is ensured through conditional checks in methods like getSelectedVersionId.

Learnt from: rafalmaksymiuk
PR: #4136
File: src/elements/common/types/SidebarNavigation.ts:16-26
Timestamp: 2025-06-11T16:30:10.431Z
Learning: VersionSidebarView intentionally uses the versionId field to stay consistent with current URL parameter naming; a potential rename to fileVersionId is deferred until React Router is removed.

src/elements/content-sidebar/ActivitySidebar.js (3)

Learnt from: rafalmaksymiuk
PR: #4144
File: src/elements/content-sidebar/versions/VersionsList.js:24-33
Timestamp: 2025-06-17T13:30:02.172Z
Learning: In the box-ui-elements codebase, Flow components use .flow.js type definition files, not TypeScript .ts files. The InternalSidebarNavigation type is a union type where different variants may have different properties like versionId, and proper type safety is ensured through conditional checks in methods like getSelectedVersionId.

Learnt from: rafalmaksymiuk
PR: #4136
File: src/elements/common/types/SidebarNavigation.ts:16-26
Timestamp: 2025-06-11T16:30:10.431Z
Learning: VersionSidebarView intentionally uses the versionId field to stay consistent with current URL parameter naming; a potential rename to fileVersionId is deferred until React Router is removed.

Learnt from: rafalmaksymiuk
PR: #4160
File: src/elements/content-sidebar/SidebarToggle.js:13-19
Timestamp: 2025-06-25T13:09:45.168Z
Learning: Files with @flow or @flow strict comments at the top use Flow type syntax, not TypeScript. Flow type definitions like type Props = { ... } and type imports like type { RouterHistory } are valid Flow syntax and should not be flagged as TypeScript-only features.

🪛 Biome (2.1.2)
src/elements/content-sidebar/ActivitySidebar.js

[error] 80-80: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 1130-1130: Expected an expression but instead found '}'.

Expected an expression here.

(parse)


[error] 1137-1137: expected } but instead found ;

Remove ;

(parse)


[error] 1138-1138: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 1140-1140: expected } but instead found const

Remove const

(parse)


[error] 1142-1142: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 1147-1147: expected } but instead found if

Remove if

(parse)


[error] 1148-1148: expected } but instead found const

Remove const

(parse)


[error] 1149-1149: expected } but instead found :

Remove :

(parse)


[error] 1150-1150: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 1152-1152: expected } but instead found ;

Remove ;

(parse)


[error] 1155-1155: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 1157-1157: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 1158-1158: expected } but instead found ;

Remove ;

(parse)


[error] 1159-1159: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 1139-1139: Wrap comments inside children within braces.

Unsafe fix: Wrap the comments with braces

(lint/suspicious/noCommentText)


[error] 1201-1201: expected } but instead found const

Remove const

(parse)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint_test_build
  • GitHub Check: Summary
🔇 Additional comments (6)
src/elements/common/types/SidebarNavigation.ts (1)

21-26: LGTM! Making activeFeedEntryId optional aligns with the internal navigation feature.

The change to make activeFeedEntryId optional is appropriate for supporting navigation scenarios where the active feed entry may not be specified, particularly when using the internal sidebar navigation mechanism instead of React Router.

src/elements/content-sidebar/__tests__/ActivitySidebar.test.js (1)

6-7: RTL tests cover updateReplies and handleAnnotationSelect
Confirmed that ActivitySidebar.rtl.test.js includes:

  • A describe('updateReplies()') block testing the updateFeedItem API and router-disabled behavior
  • A describe('handleAnnotationSelect()') block covering both default and router-disabled scenarios
  • An import and use of formattedReplies from ../fixtures

No further action required.

src/elements/content-sidebar/__tests__/ActivitySidebar.rtl.test.js (1)

1-522: Excellent RTL test implementation with comprehensive coverage!

The new RTL test suite provides thorough coverage for both handleAnnotationSelect and updateReplies methods, properly testing:

  • Router-enabled and router-disabled scenarios
  • Edge cases (null file versions, same file versions, missing annotations)
  • Navigation state transitions
  • API interactions and callbacks

The test structure is clean, well-organized, and follows RTL best practices.

src/elements/content-sidebar/ActivitySidebar.js (3)

554-590: Well-implemented conditional navigation in updateReplies!

The method correctly handles both router-based and internal navigation scenarios when hiding replies. The logic properly detects when the active feed entry needs to be cleared and uses the appropriate navigation mechanism.


1147-1160: Excellent navigation handling with proper type safety!

The conditional navigation logic correctly uses the enum types and constructs a well-formed navigation object. The fallback to router-based navigation is properly implemented.


1200-1217: Good prop propagation to AddTaskButton component.

The navigation-related props are correctly passed down to maintain consistent navigation behavior throughout the component tree.

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

🔭 Outside diff range comments (1)
src/elements/content-sidebar/ActivitySidebar.js (1)

134-156: Fix critical syntax errors in handleAnnotationSelect method.

Static analysis shows multiple parsing errors in this code segment that would prevent the code from compiling/running. The conditional logic structure appears malformed.

The current code has syntax issues. Please verify the conditional logic structure and ensure proper JavaScript syntax. The intended logic should be:

-        let selectedFileVersionId = currentFileVersionId;
-        if (routerDisabled && internalSidebarNavigation) {
-            // Use fileVersionId from internal navigation when router is disabled
-            selectedFileVersionId = getProp(internalSidebarNavigation, 'fileVersionId', currentFileVersionId);
-        } else {
-            // Use router-based approach when router is enabled
-            const match = getAnnotationsMatchPath(location);
-            selectedFileVersionId = getProp(match, 'params.fileVersionId', currentFileVersionId);
-        }
+        let selectedFileVersionId = currentFileVersionId;
+        if (routerDisabled && internalSidebarNavigation) {
+            // Use fileVersionId from internal navigation when router is disabled
+            selectedFileVersionId = getProp(internalSidebarNavigation, 'fileVersionId', currentFileVersionId);
+        } else {
+            // Use router-based approach when router is enabled
+            const match = getAnnotationsMatchPath(location);
+            selectedFileVersionId = getProp(match, 'params.fileVersionId', currentFileVersionId);
+        }

Please also fix the navigation conditional block at lines 147-156.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2cca0c2 and 6cb72df.

📒 Files selected for processing (1)
  • src/elements/content-sidebar/ActivitySidebar.js (9 hunks)
🧰 Additional context used
🪛 Biome (2.1.2)
src/elements/content-sidebar/ActivitySidebar.js

[error] 80-80: 'import type' are a TypeScript only feature. Convert your file to a TypeScript file or remove the syntax.

TypeScript only syntax

(parse)


[error] 1130-1130: Expected an expression but instead found '}'.

Expected an expression here.

(parse)


[error] 1137-1137: expected } but instead found ;

Remove ;

(parse)


[error] 1138-1138: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 1140-1140: expected } but instead found const

Remove const

(parse)


[error] 1142-1142: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 1147-1147: expected } but instead found if

Remove if

(parse)


[error] 1153-1153: expected } but instead found ;

Remove ;

(parse)


[error] 1154-1154: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 1155-1155: expected } but instead found ;

Remove ;

(parse)


[error] 1156-1156: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 1139-1139: Wrap comments inside children within braces.

Unsafe fix: Wrap the comments with braces

(lint/suspicious/noCommentText)


[error] 1198-1198: expected } but instead found const

Remove const

(parse)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint_test_build
  • GitHub Check: Summary
🔇 Additional comments (5)
src/elements/content-sidebar/ActivitySidebar.js (5)

91-92: LGTM: Well-structured props for internal navigation.

The new props are properly typed as optional and clearly named to support the internal navigation mechanism when router is disabled.

Also applies to: 101-101


555-555: LGTM: Conditional navigation logic correctly implemented.

The updateReplies method properly handles navigation based on router availability. When router is disabled, it uses the internal navigation handler; otherwise, it falls back to the standard history.replace approach.

Also applies to: 575-584


555-590: Implementation approach for optional router is well-designed.

Once syntax errors are resolved, the conditional navigation logic provides a clean separation between router-enabled and router-disabled modes. The approach:

  • Uses internal navigation handler when router is disabled
  • Falls back to standard history methods when router is enabled
  • Handles file version ID selection appropriately for each mode
  • Maintains backward compatibility

This design aligns well with the PR objective of enabling optional router usage.

Also applies to: 1117-1160


1-1362: Ignore syntax error warning: ActivitySidebar.js is syntactically valid.

Node’s -c syntax check passed without errors, and no unclosed braces or broken conditionals were found. The file parses correctly as JavaScript/Flow—there’s no need to address syntax issues.

Likely an incorrect or invalid review comment.


554-590: Test coverage for ActivitySidebar navigation logic verified

All paths through the new navigation logic are exercised:

  • ActivitySidebar.rtl.test.js includes
    • A describe('handleAnnotationSelect()') block for router-enabled behavior
    • A describe('handleAnnotationSelect() – Router Disabled') block
    • A describe('updateReplies()') block for router-enabled behavior
    • A describe('updateReplies() – Router Disabled') block
  • File version ID selection is tested via cases where getAnnotationsMatchPath returns valid, undefined, or null IDs
  • Edge cases such as missing handlers, null file versions, and unchanged feed items are covered
  • SidebarToggle, SidebarNavButton, SidebarNavTablist, and AddTaskButton tests similarly cover both routerDisabled modes

No additional tests are needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

new file can be tsx and doesn't need the .rtl. name

Copy link
Contributor

Choose a reason for hiding this comment

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

nvm i see the name is to not conflict with the existing file

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.

3 participants