Skip to content

Conversation

devkiran
Copy link
Collaborator

@devkiran devkiran commented Oct 17, 2025

Summary by CodeRabbit

  • New Features
    • Added OAuth Applications management section in workspace settings.
    • Introduced "Create OAuth App" button with role-based permission controls for authorized users.
    • Improved layout and spacing across OAuth application settings pages.

Copy link
Contributor

vercel bot commented Oct 17, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
dub Ready Ready Preview Oct 17, 2025 7:26am

Copy link
Contributor

coderabbitai bot commented Oct 17, 2025

Walkthrough

Adds an OAuth Apps layout and a Create OAuth App client component with a permission check; simplifies several OAuth Apps page client layouts and adjusts minor spacing on the app details page.

Changes

Cohort / File(s) Summary
Create button
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/create-oauth-app-button.tsx
New client-side React component CreateOAuthAppButton that checks oauth_apps.write permissions and conditionally renders a Next.js Link containing a Button; passes permission error as a disabled tooltip; only renders on pathname ending with /settings/oauth-apps.
Layout
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/layout.tsx
New OAuthAppsLayout exported component rendering PageContent with title, titleInfo (description + docs URL), controls set to CreateOAuthAppButton, and children wrapped in PageWidthWrapper.
Page client and page
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/new/page-client.tsx, apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/page.tsx
Simplified UI wrappers: new/page-client.tsx changed to a single max-width wrapper with vertical spacing and direct placement of AddOAuthAppForm; page.tsx simplified to return the client component only (removed outer PageContent wrappers).
Details spacing tweak
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/[appId]/page-client.tsx
Minor UI spacing change: added mt-4 to outer MaxWidthWrapper to increase top margin above OAuth app details.

Sequence Diagram

sequenceDiagram
    participant User
    participant Browser
    participant OAuthAppsLayout
    participant CreateOAuthAppButton
    participant PermissionCheck

    User->>Browser: Navigate to /{slug}/settings/oauth-apps
    Browser->>OAuthAppsLayout: Render layout + controls
    OAuthAppsLayout->>CreateOAuthAppButton: Mount component
    CreateOAuthAppButton->>PermissionCheck: clientAccessCheck("oauth_apps.write", role)
    
    alt permission granted
        PermissionCheck-->>CreateOAuthAppButton: no error
        CreateOAuthAppButton->>Browser: Render enabled Link/Button -> /{slug}/settings/oauth-apps/new
        User->>Browser: Click -> navigate to /new
    else permission denied
        PermissionCheck-->>CreateOAuthAppButton: permissionsError
        CreateOAuthAppButton->>Browser: Render disabled Button with tooltip (permissionsError)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • steven-tey

Poem

🐰
Hops to a button, shiny and new,
I checked permissions before it flew.
Layouts tidied, spacing just right,
OAuth apps sprout in morning light. 🥕✨

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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Fix OAuth Apps layout" directly aligns with the primary changes in the pull request. The changeset focuses on restructuring the OAuth Apps settings pages, including creating a new layout component (OAuthAppsLayout), simplifying the UI structure by removing wrapper elements, adjusting spacing, and reorganizing the component hierarchy. The title is concise, specific, and clearly identifies both the feature (OAuth Apps) and the type of change (layout fix), making it immediately clear to reviewers what the PR addresses.
✨ 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 fix-oauth-apps-layout

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@devkiran devkiran requested a review from steven-tey October 17, 2025 07:19
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/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/new/page-client.tsx (1)

18-20: Consider a more specific redirect target.

The redirect goes to the generic settings page. Consider redirecting to /${slug}/settings/oauth-apps instead, so users land on the OAuth Apps listing page where they can see existing apps (if any) even without write permissions.

   if (permissionsError) {
-    redirect(`/${slug}/settings`);
+    redirect(`/${slug}/settings/oauth-apps`);
   }
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/create-oauth-app-button.tsx (1)

22-30: Consider conditional prop spreading for consistency.

The disabledTooltip prop receives permissionsError directly, which can be false or a string. For consistency with the pattern used in AddOAuthAppForm (line 596 from add-edit-app-form.tsx), consider using conditional spreading to only pass the prop when there's an actual error.

     <Link href={`/${slug}/settings/oauth-apps/new`}>
       <Button
         className="flex h-10 items-center justify-center whitespace-nowrap rounded-lg border px-4 text-sm"
         text="Create OAuth App"
-        disabledTooltip={permissionsError}
+        {...(permissionsError && {
+          disabledTooltip: permissionsError,
+        })}
       />
     </Link>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 46a8b5a and 986fabb.

📒 Files selected for processing (4)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/create-oauth-app-button.tsx (1 hunks)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/layout.tsx (1 hunks)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/new/page-client.tsx (1 hunks)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/page.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-15T01:05:43.266Z
Learnt from: steven-tey
PR: dubinc/dub#2958
File: apps/web/app/app.dub.co/(dashboard)/[slug]/settings/members/page-client.tsx:432-457
Timestamp: 2025-10-15T01:05:43.266Z
Learning: In apps/web/app/app.dub.co/(dashboard)/[slug]/settings/members/page-client.tsx, defer refactoring the custom MenuItem component (lines 432-457) to use the shared dub/ui MenuItem component to a future PR, as requested by steven-tey.

Applied to files:

  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/new/page-client.tsx
🧬 Code graph analysis (4)
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/new/page-client.tsx (1)
apps/web/ui/oauth-apps/add-edit-app-form.tsx (1)
  • AddOAuthAppForm (43-599)
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/create-oauth-app-button.tsx (1)
apps/web/lib/api/tokens/permissions.ts (1)
  • clientAccessCheck (41-65)
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/page.tsx (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/page-client.tsx (1)
  • OAuthAppsPageClient (12-45)
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/layout.tsx (2)
apps/web/ui/layout/page-content/index.tsx (1)
  • PageContent (10-39)
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/create-oauth-app-button.tsx (1)
  • CreateOAuthAppButton (9-31)
⏰ 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). (1)
  • GitHub Check: build
🔇 Additional comments (4)
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/page.tsx (1)

3-4: LGTM!

The simplified page component correctly delegates to the client component. Layout responsibilities are now properly handled by the layout.tsx file, following Next.js App Router conventions.

apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/layout.tsx (1)

6-20: LGTM!

The layout component follows Next.js App Router conventions and provides a clean separation of concerns. The PageContent structure with title, documentation link, and controls is well-organized.

apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/create-oauth-app-button.tsx (1)

18-20: LGTM!

The pathname check correctly ensures the button only appears on the main OAuth Apps listing page and not on sub-pages like /new or individual app pages.

apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/new/page-client.tsx (1)

23-29: The double wrapping is intentional and serves distinct purposes—no changes needed.

PageWidthWrapper constrains to max-w-screen-xl (1280px) with padding and container query support, while MaxWidthWrapper also defaults to max-w-screen-xl but the page-client explicitly narrows it to max-w-screen-lg (1024px). This creates a two-level layout hierarchy: the outer PageWidthWrapper (from the layout) provides app-wide width constraints, while the inner MaxWidthWrapper (in the page-client) intentionally constrains the form content to a narrower width with additional vertical spacing via space-y-6. This pattern is consistent across similar form pages in the codebase and functions as designed.

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

🧹 Nitpick comments (2)
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/create-oauth-app-button.tsx (2)

18-20: Consider a more precise pathname check.

The pathname.endsWith() check could theoretically match unintended paths. Given the route structure, a more explicit pattern might be clearer.

-  if (!pathname.endsWith("/settings/oauth-apps")) {
+  if (!pathname.match(/\/[^\/]+\/settings\/oauth-apps$/)) {
     return null;
   }

15-15: Use ES6 shorthand property syntax.

     action: "oauth_apps.write",
-    role: role,
+    role,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 986fabb and 75aca83.

📒 Files selected for processing (2)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/[appId]/page-client.tsx (1 hunks)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/create-oauth-app-button.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/[appId]/page-client.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/create-oauth-app-button.tsx (1)
apps/web/lib/api/tokens/permissions.ts (1)
  • clientAccessCheck (41-65)
🔇 Additional comments (2)
apps/web/app/app.dub.co/(dashboard)/[slug]/settings/oauth-apps/create-oauth-app-button.tsx (2)

13-16: Permission action is now correct.

The previously flagged critical issue has been resolved—the permission check now correctly uses "oauth_apps.write" instead of "webhooks.write", aligning with the other OAuth app components in the codebase.


22-30: Button not actually disabled despite permission check.

The disabledTooltip shows an error message when the user lacks permission, but the Button component is not disabled and the Link wrapper remains clickable. Users without oauth_apps.write permission can still navigate to the create page.

Consider one of these approaches:

Option 1: Disable the button

     <Link href={`/${slug}/settings/oauth-apps/new`}>
       <Button
         className="flex h-10 items-center justify-center whitespace-nowrap rounded-lg border px-4 text-sm"
         text="Create OAuth App"
         disabledTooltip={permissionsError}
+        disabled={!!permissionsError}
       />
     </Link>

Option 2: Conditionally render the Link

-    <Link href={`/${slug}/settings/oauth-apps/new`}>
-      <Button
-        className="flex h-10 items-center justify-center whitespace-nowrap rounded-lg border px-4 text-sm"
-        text="Create OAuth App"
-        disabledTooltip={permissionsError}
-      />
-    </Link>
+    {permissionsError ? (
+      <Button
+        className="flex h-10 items-center justify-center whitespace-nowrap rounded-lg border px-4 text-sm"
+        text="Create OAuth App"
+        disabledTooltip={permissionsError}
+        disabled
+      />
+    ) : (
+      <Link href={`/${slug}/settings/oauth-apps/new`}>
+        <Button
+          className="flex h-10 items-center justify-center whitespace-nowrap rounded-lg border px-4 text-sm"
+          text="Create OAuth App"
+        />
+      </Link>
+    )}
⛔ Skipped due to learnings
Learnt from: TWilson023
PR: dubinc/dub#2936
File: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/analytics/add-hostname-modal.tsx:28-34
Timestamp: 2025-10-08T21:33:23.553Z
Learning: In the dub/ui Button component, when the `disabledTooltip` prop is set to a non-undefined value (e.g., a string), the button is automatically disabled. Therefore, it's not necessary to also add the same condition to the `disabled` prop—setting `disabledTooltip={permissionsError || undefined}` is sufficient to disable the button when there's a permissions error.

@steven-tey steven-tey merged commit a7ebfe8 into main Oct 17, 2025
7 of 8 checks passed
@steven-tey steven-tey deleted the fix-oauth-apps-layout branch October 17, 2025 17:12
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