Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughA tabbed API Authentication panel was added with "Select Project" and "Manual" modes, project picker (desktop/mobile), automatic admin-token refresh/population when a project is chosen, per-header validation and inline error banners, and responsive status indicators showing Ready / Not configured. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant AuthPanel as Auth Panel UI
participant Dropdown as Project Dropdown
participant AdminAPI as Admin API
participant Status as Status Indicator
User->>AuthPanel: Open auth panel / switch to "Select Project"
User->>Dropdown: Open project list
Dropdown->>Dropdown: Sort projects / show owned projects
User->>Dropdown: Select project
Dropdown-->>AuthPanel: emit selectedProjectId
AuthPanel->>AuthPanel: set headers (X-Stack-Project-Id, X-Stack-Access-Type, ...)
AuthPanel->>AdminAPI: request admin token refresh (useEffect on header change)
AdminAPI-->>AuthPanel: return X-Stack-Admin-Access-Token
AuthPanel->>AuthPanel: populate admin token header
AuthPanel->>Status: evaluate readiness -> "Ready"
Status-->>User: display Ready banner
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ❌ 3❌ Failed checks (2 warnings, 1 inconclusive)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
Greptile OverviewGreptile SummaryImplements a tabbed UI overhaul for the API authentication panel, replacing the previous single-view design with a cleaner two-tab interface ("Select Project" and "Manual"). Key changes:
Issues found:
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant AuthPanel
participant SidebarContext
participant APIContext
participant InternalUser
User->>SidebarContext: toggleAuth()
SidebarContext->>AuthPanel: isAuthOpen = true
AuthPanel->>InternalUser: useOwnedProjects()
InternalUser-->>AuthPanel: projects[]
alt Select Project Tab
User->>AuthPanel: Click "Select Project" tab
AuthPanel->>AuthPanel: setActiveTab('select-project')
User->>AuthPanel: Open dropdown
AuthPanel->>AuthPanel: setIsDropdownOpen(true)
User->>AuthPanel: Click project
AuthPanel->>AuthPanel: handleProjectSelect(projectId)
AuthPanel->>InternalUser: user.getAuthJson()
InternalUser-->>AuthPanel: { accessToken }
AuthPanel->>APIContext: updateSharedHeaders({...headers, admin token})
APIContext-->>AuthPanel: Headers updated
AuthPanel->>AuthPanel: setIsDropdownOpen(false)
else Manual Tab
User->>AuthPanel: Click "Manual" tab
AuthPanel->>AuthPanel: setActiveTab('manual')
User->>AuthPanel: Enter header values
AuthPanel->>APIContext: updateSharedHeaders({...headers, [key]: value})
APIContext-->>AuthPanel: Headers updated
end
AuthPanel->>User: Display status indicator (Ready/Not configured)
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@docs/src/components/api/auth-panel.tsx`:
- Around line 467-506: The mobile dropdown's container div (rendered when
isDropdownOpen is true) is missing the dropdownRef used by the click-outside
handler, so clicks outside won't close it; attach the same dropdownRef (or a new
ref wired into the same click-outside logic) to the dropdown wrapper element
that renders the project list (the absolute top-full left-0 right-0 div) and
ensure the click-outside handler toggles setIsDropdownOpen(false) when events
occur outside that ref; this uses the existing dropdownRef, isDropdownOpen, and
setIsDropdownOpen identifiers referenced in the component.
- Line 6: Replace the lucide-react import in auth-panel.tsx with the local
bundled icons from icons.tsx: remove "AlertTriangle, Check, ChevronDown, X"
import and instead import "TriangleAlert, Check, ChevronDown, X" from the local
icons export; update any usages of AlertTriangle to TriangleAlert to match the
local export and ensure lucide-react is no longer referenced in this file.
🧹 Nitpick comments (4)
docs/src/components/api/auth-panel.tsx (4)
159-161: Dead conditional logic.Both branches of these ternaries evaluate to the same values:
topPosition:'top-0'in both casesheight:'h-screen'and'h-[calc(100vh)]'are effectively identicalThis appears to be leftover from refactoring. Simplify to constants or remove the conditionals entirely.
♻️ Suggested simplification
- // Calculate position based on homepage and scroll state (same as AIChatDrawer) - const topPosition = isHomePage && isScrolled ? 'top-0' : 'top-0'; - const height = isHomePage && isScrolled ? 'h-screen' : 'h-[calc(100vh)]'; + // Position constants + const topPosition = 'top-0'; + const height = 'h-screen';If different values were intended for homepage vs. non-homepage states, please update accordingly.
167-196: Consider memoizinghandleProjectSelect.This function is recreated on every render. While it's not a performance concern since it's only used in click handlers, wrapping it with
useCallbackwould be more consistent with React best practices and prevent unnecessary re-renders if passed to memoized child components in the future.
380-396: Consider extracting repeated status condition.The condition
missingRequiredHeaders.length === 0 && Object.values(headers).some(v => v.trim())is repeated three times here and again in the mobile footer. Extract to a memoized value for clarity and DRY.♻️ Suggested refactor
+ const isReady = useMemo(() => + missingRequiredHeaders.length === 0 && Object.values(headers).some(v => v.trim()), + [missingRequiredHeaders, headers] + ); {/* Footer Status */} <div className="border-t border-fd-border p-4 rounded-b-xl"> <div className="flex items-center gap-2 text-sm"> <div className={`w-2 h-2 rounded-full ${ - missingRequiredHeaders.length === 0 && Object.values(headers).some(v => v.trim()) - ? 'bg-green-500' - : 'bg-fd-muted-foreground' + isReady ? 'bg-green-500' : 'bg-fd-muted-foreground' }`} /> <span className={`${ - missingRequiredHeaders.length === 0 && Object.values(headers).some(v => v.trim()) - ? 'text-green-600 dark:text-green-400' - : 'text-fd-muted-foreground' + isReady ? 'text-green-600 dark:text-green-400' : 'text-fd-muted-foreground' }`}> - {missingRequiredHeaders.length === 0 && Object.values(headers).some(v => v.trim()) - ? 'Ready' - : 'Not configured'} + {isReady ? 'Ready' : 'Not configured'} </span> </div> </div>
203-598: Consider extracting shared sub-components to reduce duplication.The desktop and mobile panels share nearly identical logic for:
- Tab buttons (lines 226-247, 421-442)
- Error banner (lines 249-264, 444-459)
- Project dropdown (lines 269-337, 463-532)
- Manual input form (lines 339-376, 534-571)
- Status footer (lines 379-397, 574-596)
Extracting these into reusable sub-components with size/style props would improve maintainability and ensure consistent behavior across both variants.
| const isOutsideDesktop = dropdownRef.current && !dropdownRef.current.contains(target); | ||
| const isOutsideMobile = mobileDropdownRef.current && !mobileDropdownRef.current.contains(target); | ||
|
|
||
| // Only close if click is outside both dropdowns (or if the ref doesn't exist for that viewport) | ||
| if ( | ||
| (!dropdownRef.current || isOutsideDesktop) && | ||
| (!mobileDropdownRef.current || isOutsideMobile) | ||
| ) { | ||
| setIsDropdownOpen(false); |
There was a problem hiding this comment.
| const isOutsideDesktop = dropdownRef.current && !dropdownRef.current.contains(target); | |
| const isOutsideMobile = mobileDropdownRef.current && !mobileDropdownRef.current.contains(target); | |
| // Only close if click is outside both dropdowns (or if the ref doesn't exist for that viewport) | |
| if ( | |
| (!dropdownRef.current || isOutsideDesktop) && | |
| (!mobileDropdownRef.current || isOutsideMobile) | |
| ) { | |
| setIsDropdownOpen(false); | |
| // Determine which dropdown is currently visible based on viewport | |
| const isDesktopViewport = window.matchMedia('(min-width: 768px)').matches; | |
| if (isDesktopViewport) { | |
| // On desktop, only check the desktop dropdown ref | |
| const isOutsideDesktop = dropdownRef.current && !dropdownRef.current.contains(target); | |
| if (isOutsideDesktop) { | |
| setIsDropdownOpen(false); | |
| } | |
| } else { | |
| // On mobile, only check the mobile dropdown ref | |
| const isOutsideMobile = mobileDropdownRef.current && !mobileDropdownRef.current.contains(target); | |
| if (isOutsideMobile) { | |
| setIsDropdownOpen(false); | |
| } |
Click-outside handler uses AND logic that requires clicks to be outside both desktop and mobile dropdowns, preventing dropdown from closing when clicking outside the currently visible one on the hidden viewport.
I'm not sure what happened to #1080 but that was supposed to have the UI changes. This contains the actual ui changes now. - I probably never commited the ui changes, and lost them, couldnt find them so redid it.
Summary by CodeRabbit