Skip to content

fix: Automatic collapse via pathname#3199

Merged
chronark merged 6 commits intounkeyed:mainfrom
revogabe:nested-nav-autocollapse
May 6, 2025
Merged

fix: Automatic collapse via pathname#3199
chronark merged 6 commits intounkeyed:mainfrom
revogabe:nested-nav-autocollapse

Conversation

@revogabe
Copy link
Contributor

@revogabe revogabe commented Apr 26, 2025

What does this PR do?

Adjusted the sidebar collapse so that it automatically closes and opens children by path name, making it easier to recognize and improving state management.

Recording.2025-04-25.225719.mp4

Fixes #3183

If there is not an issue for this, please create one first. This is used to tracking purposes and also helps use understand why this PR exists

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Chore (refactoring code, technical debt, workflow improvements)
  • Enhancement (small improvements)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How should this be tested?

  • Test A
  • Test B

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read Contributing Guide
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand areas
  • Ran pnpm build
  • Ran pnpm fmt
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Unkey Docs if changes were necessary

Summary by CodeRabbit

  • Refactor
    • Improved the logic for expanding and highlighting nested navigation items to better reflect the current page location.
    • Navigation items now open and highlight based on the current URL, providing a more intuitive sidebar experience.
  • New Features
    • Breadcrumb links in the navigation bar now use client-side navigation for faster page transitions.

@changeset-bot
Copy link

changeset-bot bot commented Apr 26, 2025

⚠️ No Changeset found

Latest commit: 95b8ad6

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

@vercel
Copy link

vercel bot commented Apr 26, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
dashboard ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 6, 2025 6:06am
engineering ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 6, 2025 6:06am

@vercel
Copy link

vercel bot commented Apr 26, 2025

@revogabe is attempting to deploy a commit to the Unkey Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 26, 2025

📝 Walkthrough

"""

Walkthrough

The changes refactor the logic in the NestedNavItem component to determine when a sidebar navigation item should be open or active. Instead of using a recursive function to check if any child or grandchild items are active, the component now uses the current pathname and a useLayoutEffect hook to update its open state. The state and style logic for the navigation button are also simplified to directly reflect the item's active status based on the pathname. Additionally, the breadcrumb links in the navbar component were updated to use Next.js Link for client-side navigation instead of anchor tags. No changes are made to exported interfaces except for an added optional parameter isSubItem in NestedNavItem.

Changes

File(s) Change Summary
apps/dashboard/components/navigation/sidebar/app-sidebar/components/nav-items/nested-nav-item.tsx Refactored open/active state logic to use pathname and layout effect instead of recursive function; updated UI state and style logic accordingly; added isSubItem parameter.
apps/dashboard/components/navigation/navbar.tsx Replaced anchor tags with Next.js Link component in breadcrumb links for client-side navigation.

Assessment against linked issues

Objective Addressed Explanation
Sidebar should collapse old API and expand new one when switching APIs (#3183)
Sidebar should keep the list of APIs expanded when navigating to /apis (#3183)

Suggested reviewers

  • perkinsjr
    """

📜 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 3d1955a and 6db3849.

📒 Files selected for processing (1)
  • apps/dashboard/components/navigation/sidebar/app-sidebar/components/nav-items/nested-nav-item.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/dashboard/components/navigation/sidebar/app-sidebar/components/nav-items/nested-nav-item.tsx
✨ Finishing Touches
  • 📝 Generate Docstrings

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.
    • 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 generate sequence diagram to generate a sequence diagram of the changes in 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.

@github-actions github-actions bot added the app:dashboard Unkey dashboard related label Apr 26, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Apr 26, 2025

Thank you for following the naming conventions for pull request titles! 🙏

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/dashboard/components/navigation/sidebar/app-sidebar/components/nav-items/nested-nav-item.tsx (1)

165-169: Simplified active state logic.

The component now correctly uses the item's active state directly, making the code more readable and maintainable by removing conditional logic complexity.

The comment on line 165 is now slightly misaligned with the implementation since we're no longer excluding child activity from affecting the parent's highlight. Consider updating the comment to match the current behavior if this is the intended design.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b089583 and ea1a723.

📒 Files selected for processing (1)
  • apps/dashboard/components/navigation/sidebar/app-sidebar/components/nav-items/nested-nav-item.tsx (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/dashboard/components/navigation/sidebar/app-sidebar/components/nav-items/nested-nav-item.tsx (2)
apps/dashboard/components/ui/sidebar.tsx (2)
  • SidebarMenuItem (596-596)
  • SidebarMenuButton (595-595)
apps/dashboard/components/navigation/sidebar/app-sidebar/components/nav-items/utils.ts (1)
  • getButtonStyles (3-11)
🔇 Additional comments (4)
apps/dashboard/components/navigation/sidebar/app-sidebar/components/nav-items/nested-nav-item.tsx (4)

11-12: Good addition of pathname and lifecycle hooks.

The addition of usePathname and useLayoutEffect hooks is well-aligned with the PR objective to control sidebar collapse based on the current path.


32-35: Improved state initialization based on pathname.

Setting the initial state of isOpen based on the pathname creates a direct connection between the navigation state and the URL, which solves the mentioned issue in PR #3183.


37-44: Good implementation of automatic sidebar state control.

The useLayoutEffect hook is an excellent choice here as it ensures the UI updates synchronously before browser paint, preventing flickering. The logic properly tracks both direct matches and active children to determine when a navigation item should be open.

Using useLayoutEffect instead of useEffect was a good decision for UI changes that could cause layout shifts.


158-158: Properly connected defaultOpen with component state.

Setting defaultOpen to match the current isOpen state ensures consistent behavior during initial render and subsequent updates.

Copy link
Member

@perkinsjr perkinsjr left a comment

Choose a reason for hiding this comment

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

This produces a really bad user experience.

You can see it in the video and also when using the application. The side nav bounces around because you are now collapsing everything when a path changes, so it's hard to click on the right thing.

The original issue only needs to do two things:

  1. When I switch APIs, the sidebar doesn't update and still shows the old API expanded. Instead it should collapse the old one and expand the new one
  2. When I navigate to /apis the sidebar collapses entirely
    Instead it should collapse the api itself, but keep the list of apis expanded

This is the only sidebar changes we should see.

@revogabe
Copy link
Contributor Author

Sorry but I didn't understand, isn't that exactly what's happening?

1- this was asked: "Instead it should collapse the old one and expand the new one"

2- this was asked: "Instead it should collapse the api itself, but keep the list of apis expanded"

And these two things are happening now in this PR. I didn't understand what was done wrong.

Something that I can clearly see that could be improved to improve the UX is to improve the layout shift to expand the collapse

@perkinsjr
Copy link
Member

As you can see in the video. Every collapsing field collapses on navigation when you navigate around the application.

The only part of the side bar that needs collapsing is the API or Ratelimits sections and it only needs to partially collapse for example

I am on test API

I navigate to settings, it should collapse the sub nav and keep the APIs open with the list of APIs.

If I am on the settings section and navigate to APIs it shouldn't collapse the settings unless the user collapses it themselves. It makes the experience for a user horrible if you click through items, everything shifts around making navigation hard.

Also if you collapse a field because you don't need it open this implementation reopens the collapse navigation which is also bad for the user.

Screen.Recording.2025-04-28.at.1.05.38.PM.mov

@revogabe
Copy link
Contributor Author

I got it, it makes sense

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

🔭 Outside diff range comments (1)
apps/dashboard/components/navigation/sidebar/app-sidebar/components/nav-items/nested-nav-item.tsx (1)

114-127: 🛠️ Refactor suggestion

⚠️ Potential issue

Stale closure when resetting subPending leads to inconsistent spinners

Inside setTimeout, you copy the captured subPending object; if state has changed meanwhile, the reset may drop newer keys. Use functional updates instead:

- setTimeout(() => {
-   const resetPending = { ...subPending };
-   resetPending[subItem.label as string] = false;
-   setSubPending(resetPending);
- }, 300);
+ setTimeout(() => {
+   setSubPending((prev) => ({
+     ...prev,
+     [subItem.label as string]: false,
+   }));
+ }, 300);

This guarantees you don’t overwrite concurrent pending states.

🧹 Nitpick comments (2)
apps/dashboard/components/navigation/navbar.tsx (1)

4-4: Replace <a> with next/link> LGTM, but consider prefetch / scroll flags

Migrating to next/link improves client-side routing and removes full-page reloads.
Optional follow-ups you may want to consider:

  1. prefetch={false} (or true) – disable/enable auto-prefetching if the breadcrumb list is large.
  2. scroll={false} – prevents the browser from scrolling to top on route change, which can feel more natural for in-page breadcrumb navigation.

No blocking issues – just optimisation suggestions.

Also applies to: 116-129

apps/dashboard/components/navigation/sidebar/app-sidebar/components/nav-items/nested-nav-item.tsx (1)

165-167: Opening state source of truth split between parent & sub-items

open={isSubItem ? isChildrenOpen : isOpen} means two separate booleans can control visibility of the same Collapsible. Keeping them in sync is error-prone. Consider deriving open from a single piece of state (e.g., isOpen for all levels) or lifting the state up to avoid bifurcation.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ea1a723 and 3d1955a.

📒 Files selected for processing (2)
  • apps/dashboard/components/navigation/navbar.tsx (3 hunks)
  • apps/dashboard/components/navigation/sidebar/app-sidebar/components/nav-items/nested-nav-item.tsx (4 hunks)

@revogabe
Copy link
Contributor Author

I believe I now better understood what was requested. I made a few adjustments:

  1. Opening other NavItems no longer collapses everything automatically.
  2. Maintained the auto-collapse behavior for child items only.
  3. Closing an open NavItem no longer navigates to the page — navigation only occurs when opening a new NavItem.
  4. Added next/link to the breadcrumb to take advantage of Next.js caching, since without it, glitches were occurring (e.g., collapsing all collapsibles when navigating back to /apis).

I’ve attached a video showing the current behavior after these latest commits.


Recording.2025-04-28.200236.mp4

@perkinsjr perkinsjr changed the title Fix: Automatic collapse via pathname fix: Automatic collapse via pathname Apr 29, 2025
@chronark chronark enabled auto-merge May 6, 2025 06:17
@chronark chronark requested a review from perkinsjr May 6, 2025 06:18
@chronark chronark added this pull request to the merge queue May 6, 2025
Merged via the queue into unkeyed:main with commit d5af916 May 6, 2025
26 checks passed
@coderabbitai coderabbitai bot mentioned this pull request May 6, 2025
18 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app:dashboard Unkey dashboard related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API navigation should persist state when navigating

3 participants