1- import { Check , Minus , User , X } from 'lucide-react'
1+ import { ArrowRight , Check , Minus , User , X } from 'lucide-react'
22import Image from 'next/legacy/image'
33import { useState } from 'react'
44
55import { useParams } from 'common'
66import Table from 'components/to-be-cleaned/Table'
7+ import PartnerIcon from 'components/ui/PartnerIcon'
78import { useOrganizationRolesV2Query } from 'data/organization-members/organization-roles-query'
89import { OrganizationMember } from 'data/organizations/organization-members-query'
910import { useProjectsQuery } from 'data/projects/projects-query'
1011import { useHasAccessToProjectLevelPermissions } from 'data/subscriptions/org-subscription-query'
1112import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
1213import { useProfile } from 'lib/profile'
13- import { Badge , TooltipContent_Shadcn_ , TooltipTrigger_Shadcn_ , Tooltip_Shadcn_ } from 'ui'
14+ import {
15+ Badge ,
16+ HoverCardContent_Shadcn_ ,
17+ HoverCardTrigger_Shadcn_ ,
18+ HoverCard_Shadcn_ ,
19+ ScrollArea ,
20+ cn ,
21+ } from 'ui'
1422import ShimmeringLoader from 'ui-patterns/ShimmeringLoader'
1523import { getUserDisplayName , isInviteExpired } from '../Organization.utils'
1624import { MemberActions } from './MemberActions'
17- import PartnerIcon from 'components/ui/PartnerIcon '
25+ import Link from 'next/link '
1826
1927interface MemberRowProps {
2028 member : OrganizationMember
@@ -25,17 +33,16 @@ const MEMBER_ORIGIN_TO_MANAGED_BY = {
2533} as const
2634
2735export const MemberRow = ( { member } : MemberRowProps ) => {
28- const { slug } = useParams ( )
2936 const { profile } = useProfile ( )
30- const { data : projects } = useProjectsQuery ( )
3137 const selectedOrganization = useSelectedOrganization ( )
3238 const [ hasInvalidImg , setHasInvalidImg ] = useState ( false )
33- const isOptedIntoProjectLevelPermissions = useHasAccessToProjectLevelPermissions ( slug as string )
3439
40+ const { data : projects } = useProjectsQuery ( )
3541 const { data : roles , isLoading : isLoadingRoles } = useOrganizationRolesV2Query ( {
3642 slug : selectedOrganization ?. slug ,
3743 } )
3844
45+ const orgProjects = projects ?. filter ( ( p ) => p . organization_id === selectedOrganization ?. id )
3946 const hasProjectScopedRoles = ( roles ?. project_scoped_roles ?? [ ] ) . length > 0
4047 const memberIsUser = member . gotrue_id == profile ?. gotrue_id
4148 const isInvitedUser = Boolean ( member . invited_id )
@@ -139,10 +146,10 @@ export const MemberRow = ({ member }: MemberRowProps) => {
139146 const roleName = ( role ?. name ?? '' ) . split ( '_' ) [ 0 ]
140147 const projectsApplied =
141148 role ?. project_ids === null
142- ? projects ?. map ( ( p ) => p . name ) ?? [ ]
149+ ? orgProjects ?. map ( ( p ) => p . name ) ?? [ ]
143150 : ( role ?. project_ids ?? [ ] )
144151 . map ( ( id ) => {
145- return projects ?. find ( ( p ) => p . id === id ) ?. name ?? ''
152+ return orgProjects ?. find ( ( p ) => p . id === id ) ?. name ?? ''
146153 } )
147154 . filter ( ( x ) => x . length > 0 )
148155
@@ -157,28 +164,43 @@ export const MemberRow = ({ member }: MemberRowProps) => {
157164 { projectsApplied [ 0 ] }
158165 </ span >
159166 ) : (
160- < Tooltip_Shadcn_ >
161- < TooltipTrigger_Shadcn_ asChild >
167+ < HoverCard_Shadcn_ openDelay = { 200 } >
168+ < HoverCardTrigger_Shadcn_ asChild >
162169 < span className = "text-foreground" >
163170 { role ?. project_ids === null
164171 ? 'Organization'
165172 : `${ projectsApplied . length } project${ projectsApplied . length > 1 ? 's' : '' } ` }
166173 </ span >
167- </ TooltipTrigger_Shadcn_ >
168- { role ?. project_ids !== null && projectsApplied . length > 1 && (
169- < TooltipContent_Shadcn_ side = "bottom" className = "flex flex-col gap-y-1" >
170- { projectsApplied
171- ?. slice ( 0 , 2 )
172- . map ( ( name ) => < span key = { name } > { name } </ span > ) }
173- { projectsApplied . length > 2 && (
174- < span >
175- And { projectsApplied . length - 2 } other project
176- { projectsApplied . length > 4 ? 's' : '' }
177- </ span >
178- ) }
179- </ TooltipContent_Shadcn_ >
180- ) }
181- </ Tooltip_Shadcn_ >
174+ </ HoverCardTrigger_Shadcn_ >
175+ < HoverCardContent_Shadcn_ className = "p-0" >
176+ < p className = "p-2 text-xs" >
177+ { roleName } role applies to { projectsApplied . length } project
178+ { projectsApplied . length > 1 ? 's' : '' }
179+ </ p >
180+ < div className = "border-t flex flex-col py-1" >
181+ < ScrollArea
182+ className = { cn ( projectsApplied . length > 5 ? 'h-[130px]' : '' ) }
183+ >
184+ { projectsApplied . map ( ( name ) => {
185+ const ref = orgProjects ?. find ( ( p ) => p . name === name ) ?. ref
186+ return (
187+ < Link
188+ key = { name }
189+ href = { `/project/${ ref } ` }
190+ className = "px-2 py-1 group hover:bg-surface-300 hover:text-foreground transition flex items-center justify-between"
191+ >
192+ < span className = "text-xs truncate max-w-[60%]" > { name } </ span >
193+ < span className = "text-xs text-foreground flex items-center gap-x-1 opacity-0 group-hover:opacity-100 transition" >
194+ Go to project
195+ < ArrowRight size = { 14 } />
196+ </ span >
197+ </ Link >
198+ )
199+ } ) }
200+ </ ScrollArea >
201+ </ div >
202+ </ HoverCardContent_Shadcn_ >
203+ </ HoverCard_Shadcn_ >
182204 ) }
183205 </ >
184206 ) }
0 commit comments