feat: improve Studio navigation and namespace/organization switching#2408
feat: improve Studio navigation and namespace/organization switching#2408wilsonrivera merged 3 commits intomainfrom
Conversation
WalkthroughAdjusted 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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)
Comment |
There was a problem hiding this comment.
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
nsin the.some()callback shadows the outernsparameter, making the conditionns.toLowerCase() === ns.toLowerCase()compare the same variable to itself (alwaystrue), so.some()always returnstrue, and the negation makes the guard condition alwaysfalse—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
isOrganizationRootcheck 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
📒 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
GraphCommandGroupitself, and thesetNamespace(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
setNamespaceto.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: UsingasPathfor route segment detection is appropriate here.
router.asPathprovides the actual URL path (e.g.,/my-org/default/graph/my-graph), which correctly identifies the "graph" segment. The case-insensitive matching via.toLowerCase()oncurrentSlugensures reliable graph name comparisons.
41-44: LGTM!The added
h-9 text-smclasses 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
encodeURIComponentensures safe URL encoding.
281-290: Dependency array is correctly updated.Adding
namespaceandisApiKeyManagerensures 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
actualNamespaceapproach 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.
Codecov Report❌ Patch coverage is 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. 🚀 New features to boost your workflow:
|
Summary by CodeRabbit
Bug Fixes
New Features
Style
✏️ Tip: You can customize this high-level summary in your review settings.
Checklist