Skip to content

feat: suggested display of rootkey for filters#3028

Merged
MichaelUnkey merged 5 commits intomainfrom
eng-1688-a-root-key-filter-should-show-something-other-than-empty-if
Mar 25, 2025
Merged

feat: suggested display of rootkey for filters#3028
MichaelUnkey merged 5 commits intomainfrom
eng-1688-a-root-key-filter-should-show-something-other-than-empty-if

Conversation

@MichaelUnkey
Copy link
Collaborator

@MichaelUnkey MichaelUnkey commented Mar 24, 2025

What does this PR do?

Fixes # (issue)

If there is not an issue for this, please create one first. This is used to tracking purposes and also helps use understand why this PR exists

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Chore (refactoring code, technical debt, workflow improvements)
  • Enhancement (small improvements)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How should this be tested?

  • Test A
  • Test B

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read Contributing Guide
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand areas
  • Ran pnpm build
  • Ran pnpm fmt
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Unkey Docs if changes were necessary

Summary by CodeRabbit

  • New Features

    • Enhanced the display of filter option labels in the dashboard, offering a more consistent and informative presentation for audit logs.
    • Introduced a simplified role management interface, allowing users to connect roles to API keys through checkboxes.
  • Documentation

    • Updated user instructions for connecting roles to API keys, including new navigation steps and visual aids for clarity.
    • Revised instructions for accessing roles and permissions, streamlining the process and enhancing user understanding.

@linear
Copy link

linear bot commented Mar 24, 2025

@changeset-bot
Copy link

changeset-bot bot commented Mar 24, 2025

⚠️ No Changeset found

Latest commit: e52f5de

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Mar 24, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
dashboard ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 25, 2025 5:31pm
engineering ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 25, 2025 5:31pm
play ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 25, 2025 5:31pm
www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 25, 2025 5:31pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 24, 2025

📝 Walkthrough

Walkthrough

The changes introduce a new function, getRootKeyLabel, in the root keys filter component of the Dashboard Audit application. This function formats labels for each root key by extracting specific parts of the key's ID and name. Additionally, a significant refactoring of the APIKeyDetailPage component simplifies the handling of roles and permissions by replacing a nested structure with a flat list. The PermissionList component has also been restructured to manage role connections through checkboxes, enhancing the UI and functionality. Documentation updates reflect these changes in user instructions.

Changes

File(s) Change Summary
apps/dashboard/app/(app)/audit/.../logs-filters/components/root-keys-filter.tsx Added getRootKeyLabel function to format labels by extracting segments of the root key's ID, replacing the previous direct assignment of rootKey.name or a placeholder string.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/[keyId]/page.tsx Refactored role handling to a flat list rolesList, removing nested permissions structure and simplifying logic. Renamed variable from roleTee to rolesList.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/[keyId]/permission-list.tsx Restructured PermissionList component, modified Role type, updated PermissionTreeProps, and changed function signature to include keyId. Removed local state management for active role.
apps/docs/apis/features/authorization/example.mdx Updated instructions for connecting roles to API keys, added breadcrumb navigation image, and simplified references to permissions.
apps/docs/apis/features/authorization/roles-and-permissions.mdx Similar updates to instructions for connecting roles to keys, added breadcrumb navigation image, and simplified references to permissions.

Suggested labels

Feature, 🕹️ oss.gg, :joystick: 150 points, hacktoberfest

Suggested reviewers

  • mcstepp
  • perkinsjr
  • chronark
  • ogzhanolguncu
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 24, 2025

Thank you for following the naming conventions for pull request titles! 🙏

@vercel vercel bot temporarily deployed to Preview – dashboard March 24, 2025 19:38 Inactive
@MichaelUnkey MichaelUnkey marked this pull request as ready for review March 25, 2025 13:48
@MichaelUnkey MichaelUnkey enabled auto-merge March 25, 2025 13:48
@vercel vercel bot temporarily deployed to Preview – engineering March 25, 2025 13:48 Inactive
@vercel vercel bot temporarily deployed to Preview – play March 25, 2025 13:48 Inactive
@vercel vercel bot temporarily deployed to Preview – www March 25, 2025 13:49 Inactive
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: 2

🧹 Nitpick comments (3)
apps/dashboard/app/(app)/audit/components/controls/components/logs-filters/components/root-keys-filter.tsx (3)

39-42: Simplify the obfuscation logic.

The current obfuscation logic is complex and may be confusing. The current calculation for obfuscatedMiddle checks if a substring has length > 0, but this will always be true if there are at least 5 characters after the underscore.

Consider simplifying the formatting logic:

-  const obfuscatedMiddle =
-    id.substring(id.indexOf("_") + 1, id.indexOf("_") + 5).length > 0 ? "..." : "";
-  const nextFour = id.substring(id.indexOf("_") + 1, id.indexOf("_") + 5);
-  const lastFour = id.substring(id.length - 4);
-  return rootKey.name ?? prefix + nextFour + obfuscatedMiddle + lastFour;
+  const underscoreIndex = id.indexOf("_");
+  const middlePartStart = underscoreIndex + 1;
+  const middlePartEnd = id.length - 4;
+  
+  // Show "..." only if there are characters between nextFour and lastFour
+  const shouldShowObfuscation = middlePartEnd - (middlePartStart + 4) > 0;
+  
+  const nextFour = id.substring(middlePartStart, Math.min(middlePartStart + 4, id.length));
+  const lastFour = id.substring(Math.max(id.length - 4, 0));
+  
+  return rootKey.name ?? prefix + nextFour + (shouldShowObfuscation ? "..." : "") + lastFour;

This approach more clearly expresses the intent and handles edge cases better.


43-43: Consider handling empty string names.

The current implementation uses the nullish coalescing operator (??), which will return the right-hand value only if rootKey.name is null or undefined. However, an empty string ("") is considered a valid value, which might not be what you want.

If you want to use the formatted ID when the name is an empty string as well:

-  return rootKey.name ?? prefix + nextFour + obfuscatedMiddle + lastFour;
+  return rootKey.name && rootKey.name.trim() !== "" ? 
+    rootKey.name : 
+    prefix + nextFour + obfuscatedMiddle + lastFour;

36-44: Add comments explaining the formatting logic.

The function uses a specific formatting pattern for the root key IDs, but there are no comments explaining the intent or expected format of these IDs.

Consider adding explanatory comments:

const getRootKeyLabel = (rootKey: { id: string; name: string | null }) => {
+  // If the root key has a name, use it; otherwise, format the ID
+  // Expected format for IDs: "prefix_randomstring" (e.g., "root_a1b2c3d4e5f6g7h8")
+  // We show: "prefix_abcd...wxyz" where abcd are the first 4 chars after prefix and wxyz are the last 4
  const id = rootKey.id;
  const prefix = id.substring(0, id.indexOf("_") + 1);
  const obfuscatedMiddle =
    id.substring(id.indexOf("_") + 1, id.indexOf("_") + 5).length > 0 ? "..." : "";
  const nextFour = id.substring(id.indexOf("_") + 1, id.indexOf("_") + 5);
  const lastFour = id.substring(id.length - 4);
  return rootKey.name ?? prefix + nextFour + obfuscatedMiddle + lastFour;
};
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3ef6b02 and 3e71949.

📒 Files selected for processing (1)
  • apps/dashboard/app/(app)/audit/components/controls/components/logs-filters/components/root-keys-filter.tsx (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (17)
  • GitHub Check: Test Go API Local / Test (Shard 8/8)
  • GitHub Check: Test Go API Local / Test (Shard 6/8)
  • GitHub Check: Test Go API Local / Test (Shard 4/8)
  • GitHub Check: Test Packages / Test ./packages/rbac
  • GitHub Check: Test Packages / Test ./packages/hono
  • GitHub Check: Test Go API Local / Test (Shard 1/8)
  • GitHub Check: Test Go API Local / Test (Shard 3/8)
  • GitHub Check: Test Packages / Test ./packages/cache
  • GitHub Check: Test Go API Local / Test (Shard 2/8)
  • GitHub Check: Test Packages / Test ./packages/api
  • GitHub Check: Test Go API Local / Test (Shard 7/8)
  • GitHub Check: Test Packages / Test ./internal/encryption
  • GitHub Check: Test Packages / Test ./internal/clickhouse
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Build / Build
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
apps/dashboard/app/(app)/audit/components/controls/components/logs-filters/components/root-keys-filter.tsx (1)

17-17: Good addition of formatted labels.

The change to use a dedicated function for formatting the labels improves consistency and readability. This allows for a more sophisticated presentation of root keys in the filter component.

@vercel vercel bot temporarily deployed to Preview – dashboard March 25, 2025 13:52 Inactive
Copy link
Collaborator

ignore that, we can guarantee they’ll have an underscore

@vercel vercel bot temporarily deployed to Preview – engineering March 25, 2025 14:02 Inactive
@vercel vercel bot temporarily deployed to Preview – www March 25, 2025 14:02 Inactive
@vercel vercel bot temporarily deployed to Preview – play March 25, 2025 14:03 Inactive
@vercel vercel bot temporarily deployed to Preview – dashboard March 25, 2025 14:06 Inactive
@vercel vercel bot temporarily deployed to Preview – play March 25, 2025 16:15 Inactive
@vercel vercel bot temporarily deployed to Preview – engineering March 25, 2025 16:15 Inactive
@vercel vercel bot temporarily deployed to Preview – www March 25, 2025 16:16 Inactive
@vercel vercel bot temporarily deployed to Preview – dashboard March 25, 2025 16:19 Inactive
Copy link
Collaborator

can we fix the toast not vanishing?
CleanShot 2025-03-25 at 17.48.51@2x.png

@vercel vercel bot temporarily deployed to Preview – www March 25, 2025 17:27 Inactive
@vercel vercel bot temporarily deployed to Preview – play March 25, 2025 17:27 Inactive
@vercel vercel bot temporarily deployed to Preview – engineering March 25, 2025 17:28 Inactive
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 (2)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/[keyId]/permission-list.tsx (2)

60-81: Improved UI implementation with checkboxes, but missing loading states.

The checkbox-based UI is a more intuitive way to manage role assignments compared to the previous tree structure. However, there's no visual indication or disabled state when a mutation is in progress.

Consider disabling checkboxes during mutation loading states to prevent multiple clicks:

<Checkbox
  checked={role.isActive}
+ disabled={connectRole.isLoading || disconnectRole.isLoading}
  onCheckedChange={(checked) => {
    if (checked) {
      connectRole.mutate({ keyId: keyId, roleId: role.id });
    } else {
      disconnectRole.mutate({ keyId: keyId, roleId: role.id });
    }
  }}
/>

18-85: Consider using optimistic updates for a smoother UX.

The current implementation refreshes the entire page after each role connection/disconnection, which may cause a noticeable flicker or delay in the UI.

Consider implementing optimistic updates to provide immediate feedback without waiting for the server response:

export function PermissionList({ roles, keyId }: PermissionTreeProps) {
  const router = useRouter();
+ const [optimisticRoles, setOptimisticRoles] = useState(roles);
  
  const connectRole = trpc.rbac.connectRoleToKey.useMutation({
    onMutate: ({ roleId }) => {
      toast.loading("Connecting role to key");
+     // Apply optimistic update
+     setOptimisticRoles(prev => 
+       prev.map(role => role.id === roleId ? {...role, isActive: true} : role)
+     );
    },
    // ... rest of the implementation
  });
  
  // Apply similar changes to disconnectRole mutation
  
  return (
    // ... existing code
    <div className="space-y-1">
-      {roles.map((role) => (
+      {optimisticRoles.map((role) => (
        // ... existing render logic
      ))}
    </div>
  );
}

This would provide immediate feedback to users while the server operation completes in the background.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e52f5de and 1838a7b.

📒 Files selected for processing (1)
  • apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/[keyId]/permission-list.tsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (14)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Test Go API Local / Test (Shard 6/8)
  • GitHub Check: Test Go API Local / Test (Shard 7/8)
  • GitHub Check: Test Go API Local / Test (Shard 5/8)
  • GitHub Check: Test Packages / Test ./internal/hash
  • GitHub Check: Test Go API Local / Test (Shard 3/8)
  • GitHub Check: Test Packages / Test ./packages/rbac
  • GitHub Check: Test Packages / Test ./packages/api
  • GitHub Check: Test Packages / Test ./internal/resend
  • GitHub Check: Test Packages / Test ./internal/clickhouse
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Build / Build
  • GitHub Check: autofix
🔇 Additional comments (4)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/[keyId]/permission-list.tsx (4)

3-6: Good use of necessary imports for the new implementation.

The addition of Checkbox, trpc, useRouter, and toast imports aligns well with the component's new functionality for managing role connections through checkboxes with proper user feedback.


10-10: Improved naming with isActive vs. active.

Renaming from "active" to "isActive" follows better boolean naming conventions, making the code more readable and self-documenting.


15-15: Necessary addition of keyId parameter.

Adding the keyId property to PermissionTreeProps is essential for the role connection/disconnection mutations.


54-56: Clear and concise UI text.

The updated card title and description provide better context about the component's purpose.

@vercel vercel bot temporarily deployed to Preview – dashboard March 25, 2025 17:31 Inactive
@MichaelUnkey MichaelUnkey added this pull request to the merge queue Mar 25, 2025
Merged via the queue into main with commit 01fc2c6 Mar 25, 2025
35 of 37 checks passed
@MichaelUnkey MichaelUnkey deleted the eng-1688-a-root-key-filter-should-show-something-other-than-empty-if branch March 25, 2025 18:28
@coderabbitai coderabbitai bot mentioned this pull request Jun 25, 2025
18 tasks
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.

3 participants