Skip to content

feat(studio): replace guardrails side panel with dedicated detail route - #610

Merged
aray12 merged 2 commits into
mainfrom
astd-236-follow-up-on-guardrails-ui
Jul 8, 2026
Merged

feat(studio): replace guardrails side panel with dedicated detail route#610
aray12 merged 2 commits into
mainfrom
astd-236-follow-up-on-guardrails-ui

Conversation

@aray12

@aray12 aray12 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replaces the GuardrailsDetailPanel slide-out with a full-page GuardrailDetailRoute at /workspaces/:workspace/guardrails/:guardrailConfigName, consistent with how other Studio resource types handle detail views
  • Removes the GUARDRAILS_ENABLED feature flag gate — guardrails routes are now always registered (gating is handled by gateGuardrailsRoutes)
  • Adds guardrailDetail route constant, getGuardrailDetailRoute helper, and a MSW mock for GET /configs/:name
  • Fixes an optional-chaining crash in GuardrailsDataView when data.data is undefined

Test plan

  • Navigate to Guardrails list — clicking a row navigates to the detail page
  • Detail page shows config name, description, model count, rail count, created/updated times, and raw config JSON
  • Delete from the detail page works and redirects back to the list
  • Breadcrumb "Guardrails" link navigates back to the list
  • GuardrailDetailRoute unit tests pass
  • GuardrailsRoute unit tests pass
  • title-change.test.tsx passes

Summary by CodeRabbit

  • New Features
    • Guardrail items now open a dedicated detail page showing config name, descriptive metadata, timestamps, and a JSON preview.
    • Added a delete flow on the detail page with confirmation and navigation back to the guardrails list.
    • Clicking a guardrail row now navigates directly to its detail view.
  • Bug Fixes
    • Improved guardrails empty-state logic to safely handle cases when guardrail data is not available.
  • Tests
    • Added/updated route tests covering guardrail navigation and detail-page success/loading/error/delete behaviors.

Promotes the guardrails config detail from a slide-out SidePanel into a
full-page route (/guardrails/:guardrailConfigName), removing the
GUARDRAILS_ENABLED feature flag gate and aligning with the pattern used
by other resource types in Studio.

- Delete GuardrailsDetailPanel (side panel component + test)
- Add GuardrailDetailRoute (full-page detail view with breadcrumbs, delete)
- Add guardrailDetail route constant and getGuardrailDetailRoute helper
- Register both routes in guardrailsRoutes (list + detail)
- Add mock GET /configs/:name handler for Storybook/test MSW
- Fix optional chaining crash in GuardrailsDataView empty-state check

Signed-off-by: Alex Ray <alray@nvidia.com>
@aray12
aray12 requested review from a team as code owners July 8, 2026 17:41
@github-actions github-actions Bot added the feat label Jul 8, 2026
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 87c90d49-1939-4d8f-8068-b92431993d13

📥 Commits

Reviewing files that changed from the base of the PR and between d8dc54e and 9c0502a.

📒 Files selected for processing (1)
  • web/packages/studio/src/routes/guardrails/GuardrailsRoute/index.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/packages/studio/src/routes/guardrails/GuardrailsRoute/index.tsx

📝 Walkthrough

Walkthrough

Adds a standalone guardrail config detail route, updates list navigation to use it, removes the in-page detail panel, and fixes one empty-state null check.

Changes

Guardrail detail flow

Layer / File(s) Summary
Route params and detail API
web/packages/studio/src/constants/routes.ts, web/packages/studio/src/routes/utils.ts, web/packages/studio/src/mocks/handlers/guardrails.ts, web/packages/studio/src/tests/title-change.test.tsx
Adds guardrailConfigName, workspace.guardrailDetail, getGuardrailDetailRoute, and an MSW handler for fetching one config by name.
Guardrail detail page
web/packages/studio/src/routes/guardrails/GuardrailDetailRoute/index.tsx, .../index.test.tsx
Adds the detail page, loading/error/success render paths, delete confirmation flow, query invalidation, and tests for render, loading, error, and delete navigation.
Route registration and list navigation
web/packages/studio/src/routes/groups/guardrailsRoutes.tsx, web/packages/studio/src/routes/guardrails/GuardrailsRoute/index.tsx, .../index.test.tsx, web/packages/studio/src/routes/guardrails/GuardrailsDetailPanel/index.tsx, .../index.test.tsx
Registers list/detail routes together, navigates from row clicks to the detail page, and removes the old in-page detail panel and its tests.
Empty-state safety
web/packages/studio/src/components/dataViews/GuardrailsDataView/index.tsx
Changes the empty-state condition to safely handle undefined data.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant GuardrailsRoute
  participant GuardrailDetailRoute
  participant API
  participant QueryClient

  User->>GuardrailsRoute: click guardrail row
  GuardrailsRoute->>QueryClient: cache selected config
  GuardrailsRoute->>GuardrailDetailRoute: navigate to detail route
  GuardrailDetailRoute->>API: fetch config by name
  API-->>GuardrailDetailRoute: config data or error
  GuardrailDetailRoute-->>User: render loading, error, or config details

  User->>GuardrailDetailRoute: confirm delete
  GuardrailDetailRoute->>API: delete config
  API-->>GuardrailDetailRoute: delete result
  GuardrailDetailRoute->>QueryClient: invalidate guardrail config queries
  GuardrailDetailRoute-->>User: navigate back to list
Loading

Possibly related PRs

Suggested labels: fix

Suggested reviewers: htolentino-nvidia

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change from a side panel to a dedicated guardrails detail route.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch astd-236-follow-up-on-guardrails-ui

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
web/packages/studio/src/routes/guardrails/GuardrailDetailRoute/index.tsx (2)

14-14: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

countRails reused from a sibling component's private utils file.

Importing countRails from @studio/components/dataViews/GuardrailsDataView/guardrailUtils into an unrelated route module couples this page to GuardrailsDataView's internals. Since the util is now shared across a component and a route, consider moving it to a shared location (e.g. @studio/utils/guardrails) to keep component-local utils decoupled from route consumers.

Also applies to: 82-82

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/packages/studio/src/routes/guardrails/GuardrailDetailRoute/index.tsx` at
line 14, `countRails` is being imported from `GuardrailsDataView`’s private
utils, which tightly couples `GuardrailDetailRoute` to a sibling component’s
internals. Move `countRails` into a shared guardrails utility location and
update both `GuardrailDetailRoute` and any other consumers to import it from
that shared module instead of `guardrailUtils`.

52-64: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Delete-and-invalidate logic duplicated with GuardrailsRoute.handleDelete.

This callback (delete → invalidate list query → handle success/failure) mirrors the logic in GuardrailsRoute/index.tsx almost exactly (differing only in the post-delete navigation). Consider extracting a shared hook (e.g. useDeleteGuardrailConfig) to avoid drift between the two call sites.

♻️ Sketch of shared hook
export function useDeleteGuardrailConfig(workspace: string) {
  const queryClient = useQueryClient();
  const { mutateAsync: deleteConfig } = useGuardrailsDeleteConfig();

  return useCallback(
    async (name: string): Promise<boolean> => {
      try {
        await deleteConfig({ workspace, name });
        await queryClient.invalidateQueries({
          queryKey: [`/apis/guardrails/v2/workspaces/${workspace}/configs`],
        });
        return true;
      } catch {
        return false;
      }
    },
    [deleteConfig, queryClient, workspace]
  );
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/packages/studio/src/routes/guardrails/GuardrailDetailRoute/index.tsx`
around lines 52 - 64, The delete flow in handleDelete is duplicated with
GuardrailsRoute.handleDelete, so extract the shared
delete/invalidate/error-handling logic into a reusable hook such as
useDeleteGuardrailConfig. Move the deleteConfig call and
queryClient.invalidateQueries behavior into that hook, returning a boolean
success value, and keep only the route-specific navigation
(navigate(getGuardrailsRoute(workspace))) in GuardrailDetailRoute. Update both
call sites to use the shared hook so the guardrail deletion behavior stays
consistent and easier to maintain.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@web/packages/studio/src/routes/guardrails/GuardrailDetailRoute/index.tsx`:
- Line 14: `countRails` is being imported from `GuardrailsDataView`’s private
utils, which tightly couples `GuardrailDetailRoute` to a sibling component’s
internals. Move `countRails` into a shared guardrails utility location and
update both `GuardrailDetailRoute` and any other consumers to import it from
that shared module instead of `guardrailUtils`.
- Around line 52-64: The delete flow in handleDelete is duplicated with
GuardrailsRoute.handleDelete, so extract the shared
delete/invalidate/error-handling logic into a reusable hook such as
useDeleteGuardrailConfig. Move the deleteConfig call and
queryClient.invalidateQueries behavior into that hook, returning a boolean
success value, and keep only the route-specific navigation
(navigate(getGuardrailsRoute(workspace))) in GuardrailDetailRoute. Update both
call sites to use the shared hook so the guardrail deletion behavior stays
consistent and easier to maintain.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 30bdc846-240e-4b02-b462-bf83bd45afbe

📥 Commits

Reviewing files that changed from the base of the PR and between ac00f50 and d8dc54e.

📒 Files selected for processing (12)
  • web/packages/studio/src/components/dataViews/GuardrailsDataView/index.tsx
  • web/packages/studio/src/constants/routes.ts
  • web/packages/studio/src/mocks/handlers/guardrails.ts
  • web/packages/studio/src/routes/groups/guardrailsRoutes.tsx
  • web/packages/studio/src/routes/guardrails/GuardrailDetailRoute/index.test.tsx
  • web/packages/studio/src/routes/guardrails/GuardrailDetailRoute/index.tsx
  • web/packages/studio/src/routes/guardrails/GuardrailsDetailPanel/index.test.tsx
  • web/packages/studio/src/routes/guardrails/GuardrailsDetailPanel/index.tsx
  • web/packages/studio/src/routes/guardrails/GuardrailsRoute/index.test.tsx
  • web/packages/studio/src/routes/guardrails/GuardrailsRoute/index.tsx
  • web/packages/studio/src/routes/utils.ts
  • web/packages/studio/src/tests/title-change.test.tsx
💤 Files with no reviewable changes (2)
  • web/packages/studio/src/routes/guardrails/GuardrailsDetailPanel/index.tsx
  • web/packages/studio/src/routes/guardrails/GuardrailsDetailPanel/index.test.tsx

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 23324/30499 76.5% 61.3%
Integration Tests 13631/29179 46.7% 20.0%

…ant navigation

Signed-off-by: Alex Ray <alray@nvidia.com>
@aray12
aray12 added this pull request to the merge queue Jul 8, 2026
Merged via the queue into main with commit cc26e71 Jul 8, 2026
55 checks passed
@aray12
aray12 deleted the astd-236-follow-up-on-guardrails-ui branch July 8, 2026 21:36
arpitsardhana pushed a commit that referenced this pull request Jul 9, 2026
…te (#610)

* feat(studio): replace guardrails side panel with dedicated detail route

Promotes the guardrails config detail from a slide-out SidePanel into a
full-page route (/guardrails/:guardrailConfigName), removing the
GUARDRAILS_ENABLED feature flag gate and aligning with the pattern used
by other resource types in Studio.

- Delete GuardrailsDetailPanel (side panel component + test)
- Add GuardrailDetailRoute (full-page detail view with breadcrumbs, delete)
- Add guardrailDetail route constant and getGuardrailDetailRoute helper
- Register both routes in guardrailsRoutes (list + detail)
- Add mock GET /configs/:name handler for Storybook/test MSW
- Fix optional chaining crash in GuardrailsDataView empty-state check

Signed-off-by: Alex Ray <alray@nvidia.com>

* feat(studio): seed detail query cache on guardrail row click for instant navigation

Signed-off-by: Alex Ray <alray@nvidia.com>

---------

Signed-off-by: Alex Ray <alray@nvidia.com>
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