Skip to content

Conversation

@akshaydeo
Copy link
Contributor

@akshaydeo akshaydeo commented Dec 17, 2025

Summary

Refactored the configuration pages to use dedicated routes instead of query parameters, improving navigation and URL structure.

Changes

  • Converted configuration tabs from query parameters to dedicated routes (e.g., /workspace/config?tab=security/workspace/config/security)
  • Created individual page components for each configuration section
  • Updated links throughout the application to point to the new route structure
  • Added loading state to the configuration layout
  • Modified the main config page to redirect to client settings by default
  • Updated sidebar navigation to work with the new route structure

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (Next.js)
  • Docs

How to test

  1. Navigate to the workspace configuration section
  2. Verify that each configuration section loads correctly with its own URL
  3. Check that links to configuration sections (like from API Keys to Security) work properly
  4. Verify that the sidebar navigation highlights the correct item based on the current route
# UI
cd ui
pnpm i
pnpm dev

Screenshots/Recordings

N/A

Breaking changes

  • Yes
  • No

Related issues

N/A

Security considerations

No security implications.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 17, 2025

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added dedicated Settings pages for API Keys, Security, Logging, Governance, Caching, Observability, Performance Tuning, Pricing, Proxy, and Client Settings.
    • Permission-based access control now gates Settings and redirects appropriately.
  • Improvements

    • Updated sidebar navigation and routing to use explicit Settings routes.
    • Adjusted loading behavior when configuration data is being fetched.
    • Fixed configuration links (e.g., API Keys/Security) to point to the new pages.

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

Walkthrough

Migrates workspace configuration from query-parameter tabs to path-based routes, adds individual client pages under /workspace/config/, adds a loading state to the config layout, replaces tab UI with an RBAC permission gate and redirect, updates sidebar navigation to use path prefixes, and fixes config-related link targets.

Changes

Cohort / File(s) Change Summary
New configuration page routes
ui/app/workspace/config/api-keys/page.tsx, ui/app/workspace/config/caching/page.tsx, ui/app/workspace/config/client-settings/page.tsx, ui/app/workspace/config/governance/page.tsx, ui/app/workspace/config/logging/page.tsx, ui/app/workspace/config/observability/page.tsx, ui/app/workspace/config/performance-tuning/page.tsx, ui/app/workspace/config/pricing-config/page.tsx, ui/app/workspace/config/security/page.tsx
Added client-side pages (default exports) that render their respective View components inside centered container wrappers.
Proxy page (enterprise gated)
ui/app/workspace/config/proxy/page.tsx
New client page that checks IS_ENTERPRISE and redirects non-enterprise users to /workspace/config/client-settings; renders ProxyView for enterprise.
Configuration layout & main config page
ui/app/workspace/config/layout.tsx, ui/app/workspace/config/page.tsx
layout.tsx imports FullPageLoader and useGetCoreConfigQuery and shows loader when loading; page.tsx removes tab-driven UI and uses RBAC permission check to either redirect to /workspace/config/client-settings or render NoPermissionView.
Sidebar navigation update
ui/components/sidebar.tsx
Removed useQueryState usage and query-param tab logic; simplified subitem active detection to path-prefix matching and expanded config subitem URLs to explicit /workspace/config/... routes (including api-keys, security, proxy, etc.).
Link target updates
ui/app/_fallbacks/enterprise/components/api-keys/APIKeysView.tsx, ui/app/workspace/config/views/securityView.tsx
Updated security/API keys links from query-parameter routes to direct paths (/workspace/config/security and /workspace/config/api-keys).
React import adjustment
ui/app/clientLayout.tsx
Added Suspense to React import alongside useEffect (imported but not used in visible diff).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Check sidebar path-prefix logic and edge cases (trailing slashes, deeper subpaths).
  • Verify RBAC permission gate and redirect behavior in page.tsx.
  • Confirm enterprise gating and redirect in proxy/page.tsx.
  • Review consistency across newly added page wrappers for layout and client directives.
  • Validate updated internal links to avoid broken navigation.

Poem

🐰 I hopped from tabs into tidy lanes,
Paths instead of queries, clearer brains.
Sidebar sings in routes, neat and spry,
Loader waits while configs fly.
Nose wiggles — onward, routes we ply!

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
Title check ✅ Passed The title accurately summarizes the main change: refactoring configuration views to use dedicated routes instead of query parameters.
Description check ✅ Passed The description follows the template and includes all key sections: summary, detailed changes, type of change, affected areas, testing instructions, and a completed checklist.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 12-17-moves_config_views_into_their_own_paths

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

Copy link
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@akshaydeo akshaydeo marked this pull request as ready for review December 17, 2025 14:13
@github-actions
Copy link
Contributor

🧪 Test Suite Available

This PR can be tested by a repository admin.

Run tests for PR #1124

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

♻️ Duplicate comments (1)
ui/app/workspace/config/governance/page.tsx (1)

1-12: Same duplication pattern noted.

This page follows the same wrapper pattern as api-keys/page.tsx and logging/page.tsx. See the refactoring suggestion in the api-keys page review.

🧹 Nitpick comments (4)
ui/app/workspace/config/performance-tuning/page.tsx (1)

7-7: Redundant max-width constraint.

The page wrapper applies max-w-7xl, but PerformanceTuningView internally constrains its root div to max-w-4xl (line 86 in performanceTuningView.tsx). Since the inner constraint is always smaller, the outer max-w-7xl has no effect and creates maintenance confusion.

Consider removing the redundant outer max-width:

-    <div className="mx-auto flex w-full max-w-7xl">
+    <div className="flex w-full">

Alternatively, if you want consistent spacing across all config pages, remove the max-width from the view component and manage it at the page level. Check other new config pages (api-keys, caching, security, etc.) for consistency.

ui/app/clientLayout.tsx (1)

15-15: Remove unused Suspense import.

The Suspense import from React is not used anywhere in this file.

Apply this diff to remove the unused import:

-import { Suspense, useEffect } from "react";
+import { useEffect } from "react";
ui/app/workspace/config/caching/page.tsx (1)

1-12: Consider abstracting the repeated page wrapper pattern.

Multiple config pages (pricing-config, client-settings, observability, caching, and others mentioned in the PR) share an identical structure:

  • "use client" directive
  • Import a View component
  • Render the View inside <div className="mx-auto flex w-full max-w-7xl">

This duplication could be reduced by creating a shared ConfigPageWrapper component or leveraging the layout system more effectively. However, the current approach is explicit and works well, so this is purely a maintainability consideration for future refactoring.

Example approach (optional):

Create ui/app/workspace/config/components/ConfigPageWrapper.tsx:

"use client"

export default function ConfigPageWrapper({ children }: { children: React.ReactNode }) {
  return (
    <div className="mx-auto flex w-full max-w-7xl">
      {children}
    </div>
  )
}

Then each page becomes:

import ConfigPageWrapper from "../components/ConfigPageWrapper"
import CachingView from "../views/cachingView"

export default function CachingPage() {
  return (
    <ConfigPageWrapper>
      <CachingView />
    </ConfigPageWrapper>
  )
}
ui/app/workspace/config/api-keys/page.tsx (1)

1-12: Consider extracting the common page wrapper pattern.

This file, along with logging/page.tsx and governance/page.tsx, follows an identical structure. While explicit page files are a valid Next.js pattern, you could reduce duplication by creating a shared wrapper component.

Example shared wrapper at ui/app/workspace/config/components/ConfigPageWrapper.tsx:

"use client"

interface ConfigPageWrapperProps {
  children: React.ReactNode
}

export default function ConfigPageWrapper({ children }: ConfigPageWrapperProps) {
  return (
    <div className="mx-auto flex w-full max-w-7xl">
      {children}
    </div>
  )
}

Then each page becomes:

 "use client"

 import APIKeysView from "@enterprise/components/api-keys/APIKeysView"
+import ConfigPageWrapper from "../components/ConfigPageWrapper"

 export default function APIKeysPage() {
-  return (
-    <div className="mx-auto flex w-full max-w-7xl">
-      <APIKeysView />
-    </div>
-  )
+  return <ConfigPageWrapper><APIKeysView /></ConfigPageWrapper>
 }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6fc2461 and 2efeb81.

📒 Files selected for processing (16)
  • ui/app/_fallbacks/enterprise/components/api-keys/APIKeysView.tsx (1 hunks)
  • ui/app/clientLayout.tsx (1 hunks)
  • ui/app/workspace/config/api-keys/page.tsx (1 hunks)
  • ui/app/workspace/config/caching/page.tsx (1 hunks)
  • ui/app/workspace/config/client-settings/page.tsx (1 hunks)
  • ui/app/workspace/config/governance/page.tsx (1 hunks)
  • ui/app/workspace/config/layout.tsx (1 hunks)
  • ui/app/workspace/config/logging/page.tsx (1 hunks)
  • ui/app/workspace/config/observability/page.tsx (1 hunks)
  • ui/app/workspace/config/page.tsx (1 hunks)
  • ui/app/workspace/config/performance-tuning/page.tsx (1 hunks)
  • ui/app/workspace/config/pricing-config/page.tsx (1 hunks)
  • ui/app/workspace/config/proxy/page.tsx (1 hunks)
  • ui/app/workspace/config/security/page.tsx (1 hunks)
  • ui/app/workspace/config/views/securityView.tsx (1 hunks)
  • ui/components/sidebar.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

always check the stack if there is one for the current PR. do not give localized reviews for the PR, always see all changes in the light of the whole stack of PRs (if there is a stack, if there is no stack you can continue to make localized suggestions/reviews)

Files:

  • ui/app/workspace/config/security/page.tsx
  • ui/app/workspace/config/logging/page.tsx
  • ui/app/workspace/config/layout.tsx
  • ui/app/workspace/config/views/securityView.tsx
  • ui/app/workspace/config/pricing-config/page.tsx
  • ui/app/workspace/config/governance/page.tsx
  • ui/app/workspace/config/observability/page.tsx
  • ui/app/workspace/config/proxy/page.tsx
  • ui/app/workspace/config/api-keys/page.tsx
  • ui/app/workspace/config/client-settings/page.tsx
  • ui/app/_fallbacks/enterprise/components/api-keys/APIKeysView.tsx
  • ui/components/sidebar.tsx
  • ui/app/clientLayout.tsx
  • ui/app/workspace/config/performance-tuning/page.tsx
  • ui/app/workspace/config/page.tsx
  • ui/app/workspace/config/caching/page.tsx
🧬 Code graph analysis (11)
ui/app/workspace/config/security/page.tsx (1)
ui/app/workspace/config/views/securityView.tsx (1)
  • SecurityView (36-324)
ui/app/workspace/config/logging/page.tsx (1)
ui/app/workspace/config/views/loggingView.tsx (1)
  • LoggingView (28-170)
ui/app/workspace/config/layout.tsx (2)
ui/app/_fallbacks/enterprise/lib/contexts/rbacContext.tsx (1)
  • useRbac (63-65)
ui/components/noPermissionView.tsx (1)
  • NoPermissionView (12-28)
ui/app/workspace/config/pricing-config/page.tsx (1)
ui/app/workspace/config/views/pricingConfigView.tsx (1)
  • PricingConfigView (17-161)
ui/app/workspace/config/governance/page.tsx (1)
ui/app/workspace/config/views/governanceView.tsx (1)
  • GovernanceView (26-99)
ui/app/workspace/config/proxy/page.tsx (2)
ui/lib/constants/config.ts (1)
  • IS_ENTERPRISE (124-124)
ui/app/workspace/config/views/proxyView.tsx (1)
  • ProxyView (24-349)
ui/app/workspace/config/client-settings/page.tsx (1)
ui/app/workspace/config/views/clientSettingsView.tsx (1)
  • ClientSettingsView (26-123)
ui/components/sidebar.tsx (1)
ui/lib/constants/config.ts (1)
  • IS_ENTERPRISE (124-124)
ui/app/workspace/config/performance-tuning/page.tsx (1)
ui/app/workspace/config/views/performanceTuningView.tsx (1)
  • PerformanceTuningView (28-166)
ui/app/workspace/config/page.tsx (2)
ui/app/_fallbacks/enterprise/lib/contexts/rbacContext.tsx (1)
  • useRbac (63-65)
ui/components/noPermissionView.tsx (1)
  • NoPermissionView (12-28)
ui/app/workspace/config/caching/page.tsx (1)
ui/app/workspace/config/views/cachingView.tsx (1)
  • CachingView (6-32)
🔇 Additional comments (13)
ui/app/workspace/config/performance-tuning/page.tsx (1)

1-11: LGTM! Clean page wrapper implementation.

The page component correctly uses the "use client" directive and follows Next.js App Router conventions for wrapping the view component.

ui/app/workspace/config/pricing-config/page.tsx (1)

1-12: LGTM with a pattern observation.

This page follows the correct client component pattern for Next.js 15. The structure is clean and consistent.

Note: This file and several others (client-settings, observability, caching) follow an identical wrapper pattern. See consolidated comment below about potential abstraction opportunity.

ui/app/workspace/config/layout.tsx (1)

3-19: LGTM! Proper loading state handling.

The loading state implementation is correct:

  • Permission check executes first (prevents unauthorized users from seeing the loader)
  • Loading state is checked before rendering children
  • Clean integration with the existing RBAC permission system
ui/app/workspace/config/proxy/page.tsx (1)

7-17: LGTM! Correct enterprise gating implementation.

The redirect usage is correct for Next.js 15. The redirect() function properly handles navigation by throwing a NEXT_REDIRECT error internally, which Next.js catches and processes.

The enterprise check ensures that non-enterprise users are redirected to client settings rather than seeing a feature they cannot access.

ui/app/workspace/config/client-settings/page.tsx (1)

1-12: LGTM with a pattern observation.

This page correctly implements the client component pattern for Next.js 15.

Note: See consolidated comment about the repeated wrapper pattern across multiple config pages.

ui/app/workspace/config/observability/page.tsx (1)

1-12: LGTM with a pattern observation.

Clean implementation following Next.js 15 conventions.

Note: See consolidated comment about the wrapper pattern duplication.

ui/app/_fallbacks/enterprise/components/api-keys/APIKeysView.tsx (1)

55-55: LGTM! Correct path-based routing update.

The link correctly updates from query parameter navigation (?tab=security) to the new path-based routing (/security), aligning with the PR's refactoring objectives.

ui/app/workspace/config/caching/page.tsx (1)

1-12: LGTM with a pattern observation.

This page follows the correct implementation pattern.

Note: See consolidated comment about potential abstraction for the wrapper pattern.

ui/app/workspace/config/logging/page.tsx (1)

1-12: LGTM! Clean page wrapper following Next.js conventions.

The client component wrapper is well-structured and follows the established pattern for config pages in this PR.

ui/components/sidebar.tsx (2)

238-238: LGTM! Correct active state logic for path-based routing.

The subitem active detection properly handles both scenarios:

  • Exact match (pathname === subItem.url) when a queryParam is present
  • Prefix match (pathname.startsWith(subItem.url)) for standard path-based routing

This aligns correctly with the migration from query-parameter-based tabs to dedicated route paths.


481-556: LGTM! Config navigation URLs updated correctly.

All configuration subitem URLs have been properly migrated to dedicated paths (/workspace/config/{section}), aligning with the new page structure introduced in this PR. The routing structure is consistent and maintains proper access control checks.

ui/app/workspace/config/views/securityView.tsx (1)

188-188: LGTM! Link correctly updated to new path-based routing.

The href update from /workspace/config?tab=api-keys to /workspace/config/api-keys aligns perfectly with the PR's migration to dedicated route paths.

ui/app/workspace/config/security/page.tsx (1)

1-11: The container pattern is consistent across all config pages and intentional by design.

All 11 config pages (security, observability, pricing-config, governance, logging, proxy, performance-tuning, caching, client-settings, api-keys) use the identical <div className="mx-auto flex w-full max-w-7xl"> wrapper pattern. This was introduced in the recent refactor "moves config views into their own paths" and provides a consistent, flexible layout foundation for the config suite. The flex class here enables the flexbox context needed for centering and future layout flexibility in conjunction with mx-auto and max-w-7xl. No changes needed.

Likely an incorrect or invalid review comment.

@akshaydeo akshaydeo force-pushed the 12-17-moves_config_views_into_their_own_paths branch from 2efeb81 to 17b5905 Compare December 17, 2025 15:17
Copy link
Contributor Author

akshaydeo commented Dec 17, 2025

Merge activity

  • Dec 17, 3:34 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Dec 17, 3:34 PM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo akshaydeo merged commit 5b24de3 into main Dec 17, 2025
8 of 9 checks passed
@akshaydeo akshaydeo deleted the 12-17-moves_config_views_into_their_own_paths branch December 17, 2025 15:34
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: 1

🧹 Nitpick comments (1)
ui/app/workspace/config/page.tsx (1)

8-22: LGTM! Client-side redirect pattern correctly implemented.

The previous issue with using redirect() in a client component has been properly addressed using useRouter().replace() within useEffect. The permission check and redirect flow is correct for Next.js 15.

Optional enhancement: Consider showing a loading indicator instead of null while the redirect is in progress to improve perceived performance:

  if (!hasConfigAccess) {
    return <NoPermissionView entity="configuration" />;
  }
- return null;
+ return <FullPageLoader />;
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2efeb81 and 17b5905.

📒 Files selected for processing (16)
  • ui/app/_fallbacks/enterprise/components/api-keys/APIKeysView.tsx (1 hunks)
  • ui/app/clientLayout.tsx (1 hunks)
  • ui/app/workspace/config/api-keys/page.tsx (1 hunks)
  • ui/app/workspace/config/caching/page.tsx (1 hunks)
  • ui/app/workspace/config/client-settings/page.tsx (1 hunks)
  • ui/app/workspace/config/governance/page.tsx (1 hunks)
  • ui/app/workspace/config/layout.tsx (1 hunks)
  • ui/app/workspace/config/logging/page.tsx (1 hunks)
  • ui/app/workspace/config/observability/page.tsx (1 hunks)
  • ui/app/workspace/config/page.tsx (1 hunks)
  • ui/app/workspace/config/performance-tuning/page.tsx (1 hunks)
  • ui/app/workspace/config/pricing-config/page.tsx (1 hunks)
  • ui/app/workspace/config/proxy/page.tsx (1 hunks)
  • ui/app/workspace/config/security/page.tsx (1 hunks)
  • ui/app/workspace/config/views/securityView.tsx (1 hunks)
  • ui/components/sidebar.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (11)
  • ui/app/workspace/config/performance-tuning/page.tsx
  • ui/components/sidebar.tsx
  • ui/app/workspace/config/api-keys/page.tsx
  • ui/app/workspace/config/security/page.tsx
  • ui/app/workspace/config/caching/page.tsx
  • ui/app/workspace/config/pricing-config/page.tsx
  • ui/app/workspace/config/logging/page.tsx
  • ui/app/workspace/config/views/securityView.tsx
  • ui/app/workspace/config/client-settings/page.tsx
  • ui/app/clientLayout.tsx
  • ui/app/_fallbacks/enterprise/components/api-keys/APIKeysView.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

always check the stack if there is one for the current PR. do not give localized reviews for the PR, always see all changes in the light of the whole stack of PRs (if there is a stack, if there is no stack you can continue to make localized suggestions/reviews)

Files:

  • ui/app/workspace/config/governance/page.tsx
  • ui/app/workspace/config/page.tsx
  • ui/app/workspace/config/layout.tsx
  • ui/app/workspace/config/observability/page.tsx
  • ui/app/workspace/config/proxy/page.tsx
🧬 Code graph analysis (4)
ui/app/workspace/config/governance/page.tsx (1)
ui/app/workspace/config/views/governanceView.tsx (1)
  • GovernanceView (26-99)
ui/app/workspace/config/page.tsx (2)
ui/app/_fallbacks/enterprise/lib/contexts/rbacContext.tsx (1)
  • useRbac (63-65)
ui/components/noPermissionView.tsx (1)
  • NoPermissionView (12-28)
ui/app/workspace/config/layout.tsx (2)
ui/app/_fallbacks/enterprise/lib/contexts/rbacContext.tsx (1)
  • useRbac (63-65)
ui/components/noPermissionView.tsx (1)
  • NoPermissionView (12-28)
ui/app/workspace/config/proxy/page.tsx (2)
ui/lib/constants/config.ts (1)
  • IS_ENTERPRISE (124-124)
ui/app/workspace/config/views/proxyView.tsx (1)
  • ProxyView (24-349)
🔇 Additional comments (3)
ui/app/workspace/config/layout.tsx (1)

10-18: LGTM! Loading state pattern is well-structured.

The loading state is correctly positioned after the permission check, ensuring users without access see the permission error immediately rather than a loading spinner. The hook is properly called at the top level before any conditional returns, which aligns with React 19 hook rules.

ui/app/workspace/config/governance/page.tsx (1)

1-11: LGTM! Follows the established page wrapper pattern.

This page wrapper is consistent with other config section pages introduced in this PR (client-settings, security, logging, etc.). The simple composition pattern keeps responsibilities clear.

ui/app/workspace/config/observability/page.tsx (1)

1-11: LGTM! Consistent with the page wrapper pattern.

This page follows the same simple composition pattern as the other config section pages in this refactoring. The approach is consistent and maintainable.

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.

2 participants