Skip to content

refactor: replace preloaded teams/customers with TeamSelector/CustomerSelector in virtual keys table and sheet - #5644

Merged
akshaydeo merged 1 commit into
devfrom
07-29-fix_virtual_keys_page_optimizations_for_large_datasets
Jul 29, 2026
Merged

akshaydeo merged 1 commit into
devfrom
07-29-fix_virtual_keys_page_optimizations_for_large_datasets

Conversation

@impoiler

@impoiler impoiler commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

The virtual keys page and sheet previously fetched the full teams and customers lists upfront and passed them down as props for filtering and entity assignment. This PR removes those bulk fetches in favour of server-side search selectors (TeamSelector / CustomerSelector) that resolve their own labels on demand, eliminating unnecessary data loading and prop drilling.

Changes

  • Removed useGetTeamsQuery and useGetCustomersQuery calls from the governance virtual keys page; the page no longer fetches or holds teams/customers lists.
  • Dropped teams and customers props from VirtualKeysTable and VirtualKeySheet.
  • Replaced the static ComboboxSelect team/customer filters in the table toolbar with TeamSelector and CustomerSelector components, which search server-side. Added a FilterClearButton helper component to restore the "clear to all" affordance that ComboboxSelect previously provided for free.
  • In VirtualKeySheet, the entity assignment section is now always rendered (previously hidden when no teams/customers were loaded). The assignment type dropdown always shows both "Assign to Team" and "Assign to Customer" options. Switching type clears the id fields rather than defaulting to the first item in a list.
  • The locked-team banner in VirtualKeySheet now resolves the team name via a single useGetTeamQuery(attachedTeamId) call instead of searching through the full teams list.
  • The team/customer fallback labels in the selectors are now sourced from the team and customer objects embedded on the VirtualKey itself rather than from the previously fetched lists.
  • RBAC checks for Teams and Customers view permissions were removed from the governance page since no bulk fetches are gated on them anymore.
  • Error handling in the governance page was simplified to only track virtual key fetch errors.

Type of change

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

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

  1. Navigate to the Governance → Virtual Keys page and confirm it loads without fetching /teams or /customers on mount.
  2. Use the Team and Customer filter dropdowns — verify they search server-side and display results correctly.
  3. Select a filter value and confirm the clear (×) button resets the filter back to "All".
  4. Open the virtual key sheet for an existing key assigned to a team; confirm the team name resolves correctly in the locked banner and in the team selector fallback label.
  5. Create a new virtual key, switch the assignment type between Team and Customer, and confirm the id fields are cleared on each switch.
  6. Confirm error toasts still appear when the virtual keys fetch fails.
cd ui
pnpm i
pnpm build

Screenshots/Recordings

Add before/after screenshots of the filter toolbar and entity assignment section if available.

Breaking changes

  • No

Related issues

Security considerations

No new auth surfaces introduced. Removed RBAC checks for teams/customers on this page are safe because the underlying selectors enforce their own access controls server-side.

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

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added server-backed team and customer selectors for virtual key filtering and assignment.
    • Virtual key assignment controls are now available consistently, including when entity lists are still loading.
    • Added clearer filter reset controls.
  • Bug Fixes

    • Improved handling when switching assignment types so previous team or customer selections are cleared.
    • Improved virtual key loading and error notifications with clearer, deduplicated messages.
    • Preserved confirmation prompts when reassigning keys to another team.

Walkthrough

The virtual key governance page now queries only virtual keys. Entity assignment and filtering use dedicated team/customer selectors, while locked team details load by ID and VirtualKeySheet and VirtualKeysTable no longer receive full entity lists.

Changes

Virtual key entity flow

Layer / File(s) Summary
Virtual key page data isolation
ui/app/workspace/governance/virtual-keys/page.tsx
Removes team and customer queries and access checks, derives loading and error handling from virtual keys, and narrows table inputs.
Sheet assignment and attached team loading
ui/app/workspace/virtual-keys/views/virtualKeySheet.tsx
Removes entity-list props, loads locked teams by ID, and updates assignment, fallback, and budget state handling.
Server-side entity filters and sheet wiring
ui/app/workspace/virtual-keys/views/virtualKeysTable.tsx
Uses team/customer selectors and clear buttons for filters, removes entity-list props, and updates sheet render paths.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • maximhq/bifrost#5523: Both modify virtualKeySheet.tsx, including managed-profile and entity-related UI changes.
  • maximhq/bifrost#5616: Both refactor team/customer loading and assignment in virtualKeySheet.tsx.
  • maximhq/bifrost#5637: Both modify provider configuration budget handling in virtualKeySheet.tsx.

Suggested reviewers: akshaydeo, pratham-mishra04

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main refactor: replacing preloaded teams/customers with server-side selectors in the virtual keys UI.
Description check ✅ Passed The description includes all required template sections and gives clear summary, changes, testing, security, and impact details.
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 07-29-fix_virtual_keys_page_optimizations_for_large_datasets

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

Copy link
Copy Markdown
Contributor Author

@impoiler
impoiler force-pushed the 07-29-fix_virtual_keys_page_optimizations_for_large_datasets branch from d228c80 to c661edc Compare July 29, 2026 07:18
@impoiler impoiler changed the title fix: Virtual keys page optimizations for large datasets refactor: replace preloaded teams/customers with TeamSelector/CustomerSelector in virtual keys table and sheet Jul 29, 2026
@impoiler impoiler self-assigned this Jul 29, 2026
@impoiler
impoiler marked this pull request as ready for review July 29, 2026 07:20

@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)
ui/app/workspace/governance/virtual-keys/page.tsx (1)

65-74: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

The dedupe key is a constant, so shownErrorsRef no longer adds anything.

errorKey is `${!!vkError}` which is always "true" inside the guarded branch, so the Set holds at most one entry and is cleared whenever vkError clears. Since the effect only re-runs when vkError identity changes, a plain useRef<boolean> (or just toasting on change) expresses the same behavior with less machinery. Note the side effect: if a subsequent poll returns a different error message while the previous error is still set, no new toast is shown — acceptable, but worth being deliberate about.

♻️ Simplification
-	useEffect(() => {
-		if (!vkError) {
-			shownErrorsRef.current.clear();
-			return;
-		}
-		const errorKey = `${!!vkError}`;
-		if (shownErrorsRef.current.has(errorKey)) return;
-		shownErrorsRef.current.add(errorKey);
-		toast.error(`Failed to load virtual keys: ${getErrorMessage(vkError)}`);
-	}, [vkError]);
+	useEffect(() => {
+		if (!vkError) {
+			hasShownVkErrorRef.current = false;
+			return;
+		}
+		if (hasShownVkErrorRef.current) return;
+		hasShownVkErrorRef.current = true;
+		toast.error(`Failed to load virtual keys: ${getErrorMessage(vkError)}`);
+	}, [vkError]);

Also update line 16 to const hasShownVkErrorRef = useRef(false);.

🤖 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 `@ui/app/workspace/governance/virtual-keys/page.tsx` around lines 65 - 74, In
the virtual-key error effect, replace the constant-key Set-based deduplication
with the boolean ref `hasShownVkErrorRef` initialized via `useRef(false)`. Clear
it when `vkError` is absent, and when an error is present, toast only if the ref
is false before marking it true; preserve the existing error message and
dependency behavior.
ui/app/workspace/virtual-keys/views/virtualKeySheet.tsx (1)

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

All three branches of onValueChange do the same thing.

team, customer, and the else branch each clear both teamId and customerId and trigger the same fields — only the setValue ordering differs, which has no effect. Collapse to one path.

♻️ Proposed simplification
 														onValueChange={async (value) => {
 															const val = value ?? "none";
 															field.onChange(val);
 															// Switching type clears both ids and lets the user pick;
 															// there is no entity list loaded to default from.
-															if (val === "team") {
-																form.setValue("teamId", "", {
-																	shouldDirty: true,
-																	shouldValidate: true,
-																});
-																form.setValue("customerId", "", {
-																	shouldDirty: true,
-																	shouldValidate: true,
-																});
-																await form.trigger(["teamId", "customerId", "entityType"]);
-															} else if (val === "customer") {
-																...
-															} else {
-																...
-															}
+															form.setValue("teamId", "", { shouldDirty: true, shouldValidate: true });
+															form.setValue("customerId", "", { shouldDirty: true, shouldValidate: true });
+															await form.trigger(["teamId", "customerId", "entityType"]);
 														}}
🤖 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 `@ui/app/workspace/virtual-keys/views/virtualKeySheet.tsx` around lines 1570 -
1606, In the onValueChange handler for the entity type field, remove the
redundant team/customer/else branching and execute one shared path that clears
both teamId and customerId, then triggers teamId, customerId, and entityType
validation. Preserve the existing field.onChange call and update behavior for
every value.
🤖 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 `@ui/app/workspace/governance/virtual-keys/page.tsx`:
- Around line 65-74: In the virtual-key error effect, replace the constant-key
Set-based deduplication with the boolean ref `hasShownVkErrorRef` initialized
via `useRef(false)`. Clear it when `vkError` is absent, and when an error is
present, toast only if the ref is false before marking it true; preserve the
existing error message and dependency behavior.

In `@ui/app/workspace/virtual-keys/views/virtualKeySheet.tsx`:
- Around line 1570-1606: In the onValueChange handler for the entity type field,
remove the redundant team/customer/else branching and execute one shared path
that clears both teamId and customerId, then triggers teamId, customerId, and
entityType validation. Preserve the existing field.onChange call and update
behavior for every value.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 45dec4c8-ff49-402b-80f9-a269911c4734

📥 Commits

Reviewing files that changed from the base of the PR and between 8d8ed62 and c661edc.

📒 Files selected for processing (3)
  • ui/app/workspace/governance/virtual-keys/page.tsx
  • ui/app/workspace/virtual-keys/views/virtualKeySheet.tsx
  • ui/app/workspace/virtual-keys/views/virtualKeysTable.tsx

akshaydeo commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Merge activity

  • Jul 29, 7:51 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jul 29, 7:51 AM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo
akshaydeo merged commit 21283a7 into dev Jul 29, 2026
14 checks passed
@akshaydeo
akshaydeo deleted the 07-29-fix_virtual_keys_page_optimizations_for_large_datasets branch July 29, 2026 07:51
akhsaul pushed a commit to akhsaul/bifrost that referenced this pull request Aug 27, 2026
…omerSelector` in virtual keys table and sheet (maximhq#5644)

## Summary

The virtual keys page and sheet previously fetched the full teams and customers lists upfront and passed them down as props for filtering and entity assignment. This PR removes those bulk fetches in favour of server-side search selectors (`TeamSelector` / `CustomerSelector`) that resolve their own labels on demand, eliminating unnecessary data loading and prop drilling.

## Changes

- Removed `useGetTeamsQuery` and `useGetCustomersQuery` calls from the governance virtual keys page; the page no longer fetches or holds teams/customers lists.
- Dropped `teams` and `customers` props from `VirtualKeysTable` and `VirtualKeySheet`.
- Replaced the static `ComboboxSelect` team/customer filters in the table toolbar with `TeamSelector` and `CustomerSelector` components, which search server-side. Added a `FilterClearButton` helper component to restore the "clear to all" affordance that `ComboboxSelect` previously provided for free.
- In `VirtualKeySheet`, the entity assignment section is now always rendered (previously hidden when no teams/customers were loaded). The assignment type dropdown always shows both "Assign to Team" and "Assign to Customer" options. Switching type clears the id fields rather than defaulting to the first item in a list.
- The locked-team banner in `VirtualKeySheet` now resolves the team name via a single `useGetTeamQuery(attachedTeamId)` call instead of searching through the full teams list.
- The team/customer fallback labels in the selectors are now sourced from the `team` and `customer` objects embedded on the `VirtualKey` itself rather than from the previously fetched lists.
- RBAC checks for `Teams` and `Customers` view permissions were removed from the governance page since no bulk fetches are gated on them anymore.
- Error handling in the governance page was simplified to only track virtual key fetch errors.

## Type of change

- [ ] Bug fix
- [ ] Feature
- [x] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [ ] Core (Go)
- [ ] Transports (HTTP)
- [ ] Providers/Integrations
- [ ] Plugins
- [x] UI (React)
- [ ] Docs

## How to test

1. Navigate to the Governance → Virtual Keys page and confirm it loads without fetching `/teams` or `/customers` on mount.
2. Use the Team and Customer filter dropdowns — verify they search server-side and display results correctly.
3. Select a filter value and confirm the clear (`×`) button resets the filter back to "All".
4. Open the virtual key sheet for an existing key assigned to a team; confirm the team name resolves correctly in the locked banner and in the team selector fallback label.
5. Create a new virtual key, switch the assignment type between Team and Customer, and confirm the id fields are cleared on each switch.
6. Confirm error toasts still appear when the virtual keys fetch fails.

```sh
cd ui
pnpm i
pnpm build
```

## Screenshots/Recordings

_Add before/after screenshots of the filter toolbar and entity assignment section if available._

## Breaking changes

- [x] No

## Related issues

## Security considerations

No new auth surfaces introduced. Removed RBAC checks for teams/customers on this page are safe because the underlying selectors enforce their own access controls server-side.

## 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
occcat pushed a commit to occcat/bifrost that referenced this pull request Sep 2, 2026
…omerSelector` in virtual keys table and sheet (maximhq#5644)

## Summary

The virtual keys page and sheet previously fetched the full teams and customers lists upfront and passed them down as props for filtering and entity assignment. This PR removes those bulk fetches in favour of server-side search selectors (`TeamSelector` / `CustomerSelector`) that resolve their own labels on demand, eliminating unnecessary data loading and prop drilling.

## Changes

- Removed `useGetTeamsQuery` and `useGetCustomersQuery` calls from the governance virtual keys page; the page no longer fetches or holds teams/customers lists.
- Dropped `teams` and `customers` props from `VirtualKeysTable` and `VirtualKeySheet`.
- Replaced the static `ComboboxSelect` team/customer filters in the table toolbar with `TeamSelector` and `CustomerSelector` components, which search server-side. Added a `FilterClearButton` helper component to restore the "clear to all" affordance that `ComboboxSelect` previously provided for free.
- In `VirtualKeySheet`, the entity assignment section is now always rendered (previously hidden when no teams/customers were loaded). The assignment type dropdown always shows both "Assign to Team" and "Assign to Customer" options. Switching type clears the id fields rather than defaulting to the first item in a list.
- The locked-team banner in `VirtualKeySheet` now resolves the team name via a single `useGetTeamQuery(attachedTeamId)` call instead of searching through the full teams list.
- The team/customer fallback labels in the selectors are now sourced from the `team` and `customer` objects embedded on the `VirtualKey` itself rather than from the previously fetched lists.
- RBAC checks for `Teams` and `Customers` view permissions were removed from the governance page since no bulk fetches are gated on them anymore.
- Error handling in the governance page was simplified to only track virtual key fetch errors.

## Type of change

- [ ] Bug fix
- [ ] Feature
- [x] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [ ] Core (Go)
- [ ] Transports (HTTP)
- [ ] Providers/Integrations
- [ ] Plugins
- [x] UI (React)
- [ ] Docs

## How to test

1. Navigate to the Governance → Virtual Keys page and confirm it loads without fetching `/teams` or `/customers` on mount.
2. Use the Team and Customer filter dropdowns — verify they search server-side and display results correctly.
3. Select a filter value and confirm the clear (`×`) button resets the filter back to "All".
4. Open the virtual key sheet for an existing key assigned to a team; confirm the team name resolves correctly in the locked banner and in the team selector fallback label.
5. Create a new virtual key, switch the assignment type between Team and Customer, and confirm the id fields are cleared on each switch.
6. Confirm error toasts still appear when the virtual keys fetch fails.

```sh
cd ui
pnpm i
pnpm build
```

## Screenshots/Recordings

_Add before/after screenshots of the filter toolbar and entity assignment section if available._

## Breaking changes

- [x] No

## Related issues

## Security considerations

No new auth surfaces introduced. Removed RBAC checks for teams/customers on this page are safe because the underlying selectors enforce their own access controls server-side.

## 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
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