Skip to content

feat: improve Studio navigation and namespace/organization switching#2408

Merged
wilsonrivera merged 3 commits intomainfrom
wilson/eng-8650-improve-studio-navigation
Dec 12, 2025
Merged

feat: improve Studio navigation and namespace/organization switching#2408
wilsonrivera merged 3 commits intomainfrom
wilson/eng-8650-improve-studio-navigation

Conversation

@wilsonrivera
Copy link
Copy Markdown
Contributor

@wilsonrivera wilsonrivera commented Dec 11, 2025

Summary by CodeRabbit

  • Bug Fixes

    • More reliable namespace selection and validation with improved state and route handling.
    • Navigation now preserves and applies namespace parameters consistently.
    • Organization switching and route detection fixed for more accurate navigation and highlighting.
    • Graph/subgraph selection is now case-insensitive for more consistent results.
  • New Features

    • Dashboard navigation now includes namespace support across key sections.
  • Style

    • Visual divider added to namespace selector and small layout/spacing refinements.

✏️ Tip: You can customize this high-level summary in your review settings.

Checklist

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 11, 2025

Walkthrough

Adjusted namespace handling and routing across dashboard components: moved namespace state update to occur after navigation, added actualNamespace validation and fallback logic, switched route computations to use router.asPath with case-insensitive slug matching, appended namespace query params to navigation links, and refined organization-switch routing and minor UI structure changes.

Changes

Cohort / File(s) Summary
Namespace state & navigation flow
studio/src/components/dashboard/graph-command-group.tsx
Moved setNamespace(namespace.name) into a finally after router.push, ensuring namespace state is updated only after navigation completes (or fails). No public API changes.
Workspace namespace resolution & effects
studio/src/components/dashboard/workspace-provider.tsx
Introduced actualNamespace derived from `router.query.namespace
Route computation & selectors
studio/src/components/dashboard/workspace-selector.tsx, studio/src/components/dashboard/namespace-selector.tsx
Switched from router.pathname to router.asPath for route segment computation and dependency memoization; normalized currentSlug to lowercase for case-insensitive matching. In namespace-selector, wrapped a Link and added a 1px divider element when viewing graph/subgraph; minor class string formatting tweak.
Minor component structure
studio/src/components/dashboard/workspace-command-wrapper.tsx
Removed an unnecessary React fragment around GraphCommandGroup in a namespace map; key moved onto component.
Layout navigation & sidenav routing
studio/src/components/layout/dashboard-layout.tsx, studio/src/components/layout/sidenav.tsx
Added workspace namespace query param to several navigation hrefs and included namespace in memo deps. Reworked organization-switch routing to use pathname segmentation, construct route objects with organizationSlug query, added guards for account/invitations pages, and adjusted active-link comparison logic and UI item layout.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas needing extra attention:
    • workspace-provider.tsx effect dependency changes and ordering around applyParams, state updates, and localStorage.
    • graph-command-group.tsx navigation sequencing change (ensure no race with route updates).
    • sidenav.tsx route-object navigation and active-link comparison adjustments.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main changes across multiple files, highlighting improvements to navigation and namespace/organization switching logic.
✨ Finishing touches
  • 📝 Generate docstrings

📜 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 011e88f and 089e959.

📒 Files selected for processing (1)
  • studio/src/components/dashboard/workspace-provider.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • studio/src/components/dashboard/workspace-provider.tsx
⏰ 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). (4)
  • GitHub Check: Analyze (go)
  • GitHub Check: build_test
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: build_push_image

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
studio/src/components/dashboard/workspace-provider.tsx (1)

94-97: Critical bug: Variable shadowing causes validation to always pass.

The inner ns in the .some() callback shadows the outer ns parameter, making the condition ns.toLowerCase() === ns.toLowerCase() compare the same variable to itself (always true), so .some() always returns true, and the negation makes the guard condition always false—effectively disabling the namespace validation.

-  const setNamespaceCallback = useCallback((ns: string, applyRouteParams: boolean) => {
-    if (!ns || namespace === ns || !namespaces.some((ns) => ns.toLowerCase() === ns.toLowerCase())) {
+  const setNamespaceCallback = useCallback((newNamespace: string, applyRouteParams: boolean) => {
+    if (!newNamespace || namespace === newNamespace || !namespaces.some((ns) => ns.toLowerCase() === newNamespace.toLowerCase())) {
       return;
     }
 
-    setNamespace(ns);
-    setStoredNamespace(ns);
+    setNamespace(newNamespace);
+    setStoredNamespace(newNamespace);
     if (applyRouteParams) {
-      applyParams({namespace: ns});
+      applyParams({namespace: newNamespace});
     }
-  }, [namespace, namespaces, setStoredNamespace, applyParams]);
+  }, [namespace, namespaces, setStoredNamespace, applyParams]);
🧹 Nitpick comments (1)
studio/src/components/layout/sidenav.tsx (1)

91-92: Consider adding a clarifying comment for the path segmentation logic.

The isOrganizationRoot check determines if we're on a top-level org page (e.g., /org-slug/graphs). A brief comment explaining this would improve maintainability.

+  // Determine if we're on an organization-level page (e.g., /org-slug/graphs)
   const pathSegments = router.pathname.substring(1).split('/');
   const isOrganizationRoot = pathSegments.length === 2;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 607b176 and 011e88f.

📒 Files selected for processing (7)
  • studio/src/components/dashboard/graph-command-group.tsx (1 hunks)
  • studio/src/components/dashboard/namespace-selector.tsx (2 hunks)
  • studio/src/components/dashboard/workspace-command-wrapper.tsx (1 hunks)
  • studio/src/components/dashboard/workspace-provider.tsx (2 hunks)
  • studio/src/components/dashboard/workspace-selector.tsx (2 hunks)
  • studio/src/components/layout/dashboard-layout.tsx (5 hunks)
  • studio/src/components/layout/sidenav.tsx (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-03T21:12:18.149Z
Learnt from: JivusAyrus
Repo: wundergraph/cosmo PR: 2156
File: cli/src/commands/subgraph/commands/link.ts:21-28
Timestamp: 2025-09-03T21:12:18.149Z
Learning: Subgraph names in the Cosmo platform can contain slashes, so when parsing formats like `<namespace>/<subgraph-name>`, only the first slash should be treated as the delimiter between namespace and subgraph name. The subgraph name portion can contain additional slashes.

Applied to files:

  • studio/src/components/dashboard/workspace-selector.tsx
🧬 Code graph analysis (5)
studio/src/components/dashboard/workspace-selector.tsx (1)
studio/src/lib/utils.ts (1)
  • cn (6-8)
studio/src/components/layout/sidenav.tsx (1)
studio/src/components/ui/dropdown-menu.tsx (1)
  • DropdownMenuRadioItem (208-208)
studio/src/components/layout/dashboard-layout.tsx (2)
studio/src/hooks/use-workspace.ts (1)
  • useWorkspace (4-11)
studio/src/components/layout/sidenav.tsx (1)
  • NavLink (31-38)
studio/src/components/dashboard/namespace-selector.tsx (1)
studio/src/lib/utils.ts (1)
  • cn (6-8)
studio/src/components/dashboard/workspace-command-wrapper.tsx (1)
studio/src/components/dashboard/graph-command-group.tsx (1)
  • GraphCommandGroup (20-57)
⏰ 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). (4)
  • GitHub Check: build_push_image
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: build_test
🔇 Additional comments (10)
studio/src/components/dashboard/workspace-command-wrapper.tsx (1)

125-136: LGTM!

The fragment removal is a clean simplification. The key is now correctly placed on GraphCommandGroup itself, and the setNamespace(ns, false) callback aligns with the post-navigation pattern used elsewhere in this PR.

studio/src/components/dashboard/graph-command-group.tsx (1)

122-131: Good timing improvement for namespace state updates.

Moving setNamespace to .finally() ensures the namespace state is updated after navigation resolves, preventing potential race conditions. Note that .finally() executes regardless of success or failure—if you need to update state only on successful navigation, consider using .then() instead.

studio/src/components/dashboard/workspace-selector.tsx (2)

23-24: Using asPath for route segment detection is appropriate here.

router.asPath provides the actual URL path (e.g., /my-org/default/graph/my-graph), which correctly identifies the "graph" segment. The case-insensitive matching via .toLowerCase() on currentSlug ensures reliable graph name comparisons.


41-44: LGTM!

The added h-9 text-sm classes provide consistent sizing for the workspace selector container.

studio/src/components/layout/dashboard-layout.tsx (2)

137-159: Namespace-aware navigation links look good.

The namespace query parameter is correctly applied to graph-related links (Graphs, Subgraphs, Feature Flags) while org-level links (Members, Groups) remain namespace-agnostic. Using encodeURIComponent ensures safe URL encoding.


281-290: Dependency array is correctly updated.

Adding namespace and isApiKeyManager ensures the navigation links recompute when these values change.

studio/src/components/layout/sidenav.tsx (2)

115-124: Organization switch routing logic is correct but complex.

The conditional preserves the current page segment (e.g., graphs) when switching organizations, unless on account/invitations pages. This ensures users stay on the same view after switching orgs.


206-210: Good fix for active state detection with query parameters.

Stripping query parameters before comparison ensures namespace-aware URLs (e.g., /org/graphs?namespace=default) correctly highlight the active nav item.

studio/src/components/dashboard/namespace-selector.tsx (1)

52-67: LGTM!

The vertical divider cleanly separates the namespace link from the dropdown trigger when viewing a graph/subgraph. The fragment grouping is appropriate for this sibling element arrangement.

studio/src/components/dashboard/workspace-provider.tsx (1)

36-69: Improved namespace validation logic.

The actualNamespace approach correctly prioritizes the URL query parameter over internal state, ensuring the UI reflects the intended namespace from navigation. The fallback to default or first available namespace handles edge cases well.

Comment thread studio/src/components/dashboard/workspace-provider.tsx Outdated
Copy link
Copy Markdown
Contributor

@StarpTech StarpTech left a comment

Choose a reason for hiding this comment

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

LGTM

@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 12, 2025

Codecov Report

❌ Patch coverage is 0% with 72 lines in your changes missing coverage. Please review.
✅ Project coverage is 1.49%. Comparing base (a53bb35) to head (71d2b3d).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...io/src/components/dashboard/namespace-selector.tsx 0.00% 16 Missing ⚠️
studio/src/components/layout/sidenav.tsx 0.00% 15 Missing ⚠️
...io/src/components/dashboard/workspace-provider.tsx 0.00% 14 Missing ⚠️
...components/dashboard/workspace-command-wrapper.tsx 0.00% 12 Missing ⚠️
studio/src/components/layout/dashboard-layout.tsx 0.00% 10 Missing ⚠️
...io/src/components/dashboard/workspace-selector.tsx 0.00% 4 Missing ⚠️
...o/src/components/dashboard/graph-command-group.tsx 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #2408       +/-   ##
==========================================
- Coverage   42.75%   1.49%   -41.26%     
==========================================
  Files        1030     292      -738     
  Lines      142648   46926    -95722     
  Branches     8660     431     -8229     
==========================================
- Hits        60984     703    -60281     
+ Misses      79997   45940    -34057     
+ Partials     1667     283     -1384     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@wilsonrivera wilsonrivera merged commit 923cd4f into main Dec 12, 2025
11 checks passed
@wilsonrivera wilsonrivera deleted the wilson/eng-8650-improve-studio-navigation branch December 12, 2025 15:40
@coderabbitai coderabbitai Bot mentioned this pull request Mar 11, 2026
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants