-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Adds partner fast switcher #2931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughReplaced inline partner/group header selectors with reusable PartnerSelector and GroupSelector components; updated navigation to switch by ID while preserving query strings; filtered partner links to exclude falsy URLs; enabled SWR keepPreviousData; swapped combobox Scroll for ScrollContainer and increased bottom fade height; minor UI spacing tweaks. Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant Header as PartnerHeader (PartnerSelector)
participant Router as Next Router
participant Path as Pathname/SearchParams
participant API as usePartner/usePartners
U->>Header: Select partner (newPartnerId)
Header->>Path: read pathname + searchParams
Header->>Router: push(pathname with partnerId replaced, preserve query)
Router-->>API: fetch data for new partnerId
API-->>Header: return partner (links filtered to truthy URLs)
Note right of Header: variant prop affects styling only
sequenceDiagram
participant U as User
participant GHeader as GroupHeader (GroupSelector)
participant Groups as useGroups
participant Router as Next Router
U->>GHeader: Select group (groupId)
GHeader->>Groups: resolve groupId -> slug
alt slug == current
GHeader-->>U: no navigation
else
GHeader->>Router: push(path with new group slug)
end
Estimated code review effortπ― 4 (Complex) | β±οΈ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touchesβ Failed checks (1 warning)
β Passed checks (2 passed)
β¨ 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 |
There was a problem hiding this 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 (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/layout.tsx (1)
69-71: Avoid appending a bare β?β to the URL when no query exists.When
searchParams.toString()returns an empty string,urlbecomes/β¦?, which produces a trailing question mark in the address bar. It works but looks odd. Guard the append so?${β¦}is only added when there are actual params.
π Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
π Files selected for processing (4)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/layout.tsx(3 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/partner-header-selector.tsx(1 hunks)apps/web/lib/api/partners/get-partner-for-program.ts(1 hunks)apps/web/lib/api/partners/get-partners.ts(1 hunks)
π§° Additional context used
𧬠Code graph analysis (2)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/layout.tsx (2)
apps/web/lib/swr/use-partner.ts (1)
usePartner(6-29)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/partner-header-selector.tsx (2)
Partner(8-8)PartnerHeaderSelector(16-139)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/partner-header-selector.tsx (3)
apps/web/lib/types.ts (1)
PartnerProps(437-437)apps/web/lib/zod/schemas/partners.ts (1)
PARTNERS_MAX_PAGE_SIZE(31-31)packages/ui/src/combobox/index.tsx (1)
Combobox(85-367)
β° 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
There was a problem hiding this 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 (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/layout.tsx (1)
69-72: Handle empty query strings when pushing the new URLWith no search params,
searchParams.toString()is empty, so the generated URL ends with?. That leaves users on a slightly malformed route (/partners/:id?). Build the query string conditionally before pushing.Apply this diff:
- const url = `${pathname.replace( - `/partners/${params.partnerId}`, - `/partners/${newPartner.id}`, - )}?${searchParams.toString()}`; - - router.push(url); + const nextPath = pathname.replace( + `/partners/${params.partnerId}`, + `/partners/${newPartner.id}`, + ); + const queryString = searchParams.toString(); + + router.push(queryString ? `${nextPath}?${queryString}` : nextPath);
π Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
π Files selected for processing (4)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/layout.tsx(3 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/partner-header-selector.tsx(1 hunks)apps/web/lib/api/partners/get-partner-for-program.ts(1 hunks)apps/web/lib/api/partners/get-partners.ts(1 hunks)
π§° Additional context used
𧬠Code graph analysis (2)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/partner-header-selector.tsx (4)
apps/web/lib/types.ts (1)
PartnerProps(437-437)apps/web/lib/zod/schemas/partners.ts (1)
PARTNERS_MAX_PAGE_SIZE(31-31)packages/ui/src/combobox/index.tsx (1)
Combobox(85-367)apps/web/ui/partners/partner-selector.tsx (1)
PartnerSelector(14-110)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/layout.tsx (2)
apps/web/lib/swr/use-partner.ts (1)
usePartner(6-29)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/partner-header-selector.tsx (2)
Partner(8-8)PartnerHeaderSelector(16-139)
β° 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
.../app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/partner-header-selector.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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
Caution
Some comments are outside the diff and canβt be posted inline due to platform limitations.
β οΈ Outside diff range comments (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/group-header.tsx (1)
46-74: Switching to a searched group now fails when it isnβt in the prefetched list
switchToGrouponly looks up the slug inside the localgroupsarray. When the user searches inGroupSelectorand picks a group that wasnβt part of that initial page,targetGroupstaysundefinedand the navigation silently aborts. In production workspaces with many groups this regresses the fast-switcher: choosing any βoff-pageβ result wonβt navigate at all.Please resolve the slug from the selection itself (e.g. via
option.meta.slug) and only fall back to the cached list, and donβt append an empty?when there are no search params. One way to do it is:- const switchToGroup = (groupId: string) => { - if (group.id === groupId) return; - - // Find the group by ID to get the slug - const targetGroup = groups?.find((g) => g.id === groupId); - if (!targetGroup) return; - - const url = `${pathname.replace(`/groups/${params.groupSlug}`, `/groups/${targetGroup.slug}`)}?${searchParams.toString()}`; - - router.push(url); - }; + const switchToGroup = (groupId: string, groupSlug?: string) => { + if (group.id === groupId) return; + + const slug = + groupSlug ?? groups?.find((g) => g.id === groupId)?.slug; + + if (!slug) return; + + const query = searchParams.toString(); + router.push( + `${pathname.replace(`/groups/${params.groupSlug}`, `/groups/${slug}`)}${ + query ? `?${query}` : "" + }`, + ); + };β¦and pass the slug along from
<GroupSelector>(e.g. by settingoption.meta = { slug: group.slug }in the selector and supplying anonSelectcallback here). Oncemeta.slugis wired through, off-page selections will route correctly.
π Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
π Files selected for processing (9)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/group-header-selector.tsx(0 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/group-header.tsx(4 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/messages/[partnerId]/page-client.tsx(1 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/layout.tsx(4 hunks)apps/web/lib/swr/use-partners.ts(1 hunks)apps/web/ui/partners/groups/group-selector.tsx(4 hunks)apps/web/ui/partners/partner-selector.tsx(2 hunks)packages/ui/src/combobox/index.tsx(4 hunks)packages/ui/src/scroll-container.tsx(1 hunks)
π€ Files with no reviewable changes (1)
- apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/group-header-selector.tsx
π§° Additional context used
𧬠Code graph analysis (6)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/messages/[partnerId]/page-client.tsx (1)
packages/utils/src/constants/misc.ts (1)
OG_AVATAR_URL(29-29)
apps/web/ui/partners/partner-selector.tsx (2)
apps/web/lib/types.ts (1)
PartnerProps(437-437)packages/ui/src/combobox/index.tsx (1)
ComboboxProps(39-76)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/layout.tsx (2)
apps/web/lib/swr/use-partner.ts (1)
usePartner(6-29)apps/web/ui/partners/partner-selector.tsx (1)
PartnerSelector(18-140)
packages/ui/src/combobox/index.tsx (1)
packages/ui/src/scroll-container.tsx (1)
ScrollContainer(5-32)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/group-header.tsx (2)
apps/web/lib/swr/use-groups.ts (1)
useGroups(10-38)apps/web/ui/partners/groups/group-selector.tsx (1)
GroupSelector(19-128)
apps/web/ui/partners/groups/group-selector.tsx (3)
apps/web/lib/types.ts (1)
GroupProps(568-568)packages/ui/src/combobox/index.tsx (1)
ComboboxProps(39-76)apps/web/lib/zod/schemas/groups.ts (1)
GROUPS_MAX_PAGE_SIZE(24-24)
β° 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
|
@coderabbitai full review |
β Actions performedFull review triggered. |
There was a problem hiding this 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
β»οΈ Duplicate comments (1)
apps/web/ui/partners/groups/group-selector.tsx (1)
12-18: Still dropping null selection events β clearing is impossible.
setSelectedGroupIdstill only acceptsstring, and the handler exits when the combobox emitsnull, so the previous selection sticks and the user canβt clear the field (same issue called out earlier). Please allownullto flow through and handle it upstream.type GroupSelectorProps = { selectedGroupId: string | null; - setSelectedGroupId: (groupId: string) => void; + setSelectedGroupId: (groupId: string | null) => void; disabled?: boolean; variant?: "default" | "header"; } & Partial<ComboboxProps<false, any>>; β¦ - setSelected={(option) => { - if (!option) return; - setSelectedGroupId(option.value); - }} + setSelected={(option) => { + setSelectedGroupId(option?.value ?? null); + }}Also applies to: 72-75
π§Ή Nitpick comments (3)
apps/web/ui/partners/partner-selector.tsx (3)
89-95: Consider simplifying the icon placeholder condition.Since
selectedOption.iconis always defined whenselectedOptionexists, the condition could be simplified to!selectedOptionfor clarity.Apply this diff:
- icon={ - !selectedOption?.icon ? ( - <div className="size-5 flex-none animate-pulse rounded-full bg-neutral-200" /> - ) : ( - selectedOption?.icon - ) - } + icon={ + !selectedOption ? ( + <div className="size-5 flex-none animate-pulse rounded-full bg-neutral-200" /> + ) : ( + selectedOption.icon + ) + }
133-137: Consider a more flexible placeholder width.The fixed
w-[120px]width may cause layout shifts if partner names vary significantly in length. Consider usingmin-w-[120px]orw-32for more consistent sizing.Apply this diff:
- {!selectedOption?.label ? ( - <div className="h-6 w-[120px] animate-pulse rounded bg-neutral-100" /> + {!selectedOption?.label ? ( + <div className="h-6 min-w-[120px] animate-pulse rounded bg-neutral-100" /> ) : ( selectedOption.label )}
9-10: Remove unused Partner type export from partner-selector.tsx
ThePartnertype (Pick<PartnerProps, "id" | "name">) isnβt referenced anywhere and can be deleted.
π Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
π Files selected for processing (11)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/group-header-selector.tsx(0 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/group-header.tsx(4 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/messages/[partnerId]/page-client.tsx(1 hunks)apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/layout.tsx(4 hunks)apps/web/lib/api/partners/get-partner-for-program.ts(1 hunks)apps/web/lib/api/partners/get-partners.ts(1 hunks)apps/web/lib/swr/use-partners.ts(1 hunks)apps/web/ui/partners/groups/group-selector.tsx(4 hunks)apps/web/ui/partners/partner-selector.tsx(2 hunks)packages/ui/src/combobox/index.tsx(4 hunks)packages/ui/src/scroll-container.tsx(1 hunks)
π€ Files with no reviewable changes (1)
- apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/group-header-selector.tsx
π Additional comments (4)
apps/web/ui/partners/partner-selector.tsx (3)
15-15: LGTM!The variant prop is well-typed with a sensible default value.
Also applies to: 22-22
98-98: LGTM!Grammar improvement from singular to plural is correct.
104-130: LGTM!The variant-based styling is well-structured and correctly handles the
disabledprop in both branches. The header variant appropriately styles the component for header usage.Note: Ensure
bg-bg-subtleandbg-bg-emphasisare defined in your Tailwind theme configuration.packages/ui/src/scroll-container.tsx (1)
27-27: LGTM! Increased fade height improves visual feedback.The bottom fade height increase from
h-8(32px) toh-16(64px) provides a more prominent scroll indicator while maintaining the same opacity calculation.
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/group-header.tsx
Show resolved
Hide resolved
| import { AnimatedSizeContainer } from "../animated-size-container"; | ||
| import { Button, ButtonProps } from "../button"; | ||
| import { useMediaQuery, useScrollProgress } from "../hooks"; | ||
| import { useMediaQuery } from "../hooks"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π οΈ Refactor suggestion | π Major
π§© Analysis chain
Verify height behavior with ScrollContainer.
The refactoring to use ScrollContainer is good for code reuse. However, there's a potential class conflict to verify:
ScrollContainerhas a hardcodedh-[190px]in its internal div (scroll-container.tsx:17)- The Combobox passes
className="h-full max-h-[min(50vh,250px)]"to override this
While Tailwind's class merging should allow h-full to override h-[190px], please verify in the browser that:
- The combobox options list respects the
max-h-[min(50vh,250px)]constraint - The scrollable area adapts properly when viewport height changes
- No unexpected fixed height of 190px appears
Run the following script to check if the old Scroll component was fully removed:
Also applies to: 26-26, 253-253, 318-318
π Script executed:
#!/bin/bash
# Description: Verify that the old Scroll component in combobox is fully removed
# Search for any remaining references to the old Scroll component in combobox-related files
rg -n -C3 --type=tsx --type=ts -g '!node_modules' -g '!dist' -g '!build' 'function Scroll\(' packages/ui/src/combobox/
# Search for useScrollProgress usage that might be leftover
rg -n -C3 --type=tsx --type=ts -g '!node_modules' -g '!dist' -g '!build' 'useScrollProgress' packages/ui/src/combobox/Length of output: 55
π Script executed:
#!/bin/bash
# Find ScrollContainer implementation
echo "Locating scroll-container.tsx..."
fd scroll-container.tsx
# Inspect the first 50 lines for hardcoded height
fd scroll-container.tsx | xargs -I{} sed -n '1,50p' {} | grep -n 'h-\\[190px\\]'
# Verify old Scroll component references in combobox
rg -n -C3 'function Scroll\(' -g '*.tsx' -g '*.ts' packages/ui/src/combobox/
rg -n -C3 '<Scroll\b' -g '*.tsx' packages/ui/src/combobox/
rg -n -C3 'useScrollProgress' -g '*.tsx' -g '*.ts' packages/ui/src/combobox/Length of output: 69
π Script executed:
#!/bin/bash
# Confirm any hardcoded height classes in ScrollContainer
grep -R "h-\[" -n packages/ui/src/scroll-container.tsx
# Inspect className props usage
grep -R "className" -n packages/ui/src/scroll-container.tsxLength of output: 363
Allow parent to control ScrollContainer height. In packages/ui/src/scroll-container.tsx (line 17), remove the hardcoded h-[190px] (e.g. change to h-full) or expose a height/defaultHeight prop so that the h-full max-h-[min(50vh,250px)] passed by the Combobox can take effect.
π€ Prompt for AI Agents
In packages/ui/src/scroll-container.tsx around line 17 (and referenced by
packages/ui/src/combobox/index.tsx line 16), the ScrollContainer currently
forces a fixed class h-[190px] which prevents parent components like Combobox
from controlling height; remove the hardcoded h-[190px] (or replace it with
h-full) and instead accept an optional height/defaultHeight prop (string) that
gets applied to the container class when provided, defaulting to h-full if
absent, and ensure existing max-h and other parent classes from Combobox are
preserved by not overwriting them.
Screen.Recording.2025-10-05.at.10.58.59.AM.mov
Screen.Recording.2025-10-05.at.11.03.03.AM.mov
Summary by CodeRabbit
New Features
Bug Fixes
UI
Performance