import Link from 'next/link' import { Badge, Button, Card, CardContent, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from 'ui' import { PageSection, PageSectionContent, PageSectionMeta, PageSectionSummary, PageSectionTitle, } from 'ui-patterns/PageSection' import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' import { summarizeProjectAccess } from './General.utils' import AlertError from '@/components/ui/AlertError' import { useOrganizationRolesV2Query } from '@/data/organization-members/organization-roles-query' import { useOrganizationMembersQuery } from '@/data/organizations/organization-members-query' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { useProfile } from '@/lib/profile' export const ProjectAccessSection = () => { const { data: project } = useSelectedProjectQuery() const { data: organization } = useSelectedOrganizationQuery() const { profile } = useProfile() const isBranch = Boolean(project?.parent_project_ref) const projectRef = project?.parent_project_ref ?? project?.ref const { data: organizationMembers = [], error: organizationMembersError, isPending: isLoadingOrganizationMembers, isError: isErrorOrganizationMembers, } = useOrganizationMembersQuery( { slug: organization?.slug }, { enabled: !!organization?.slug, } ) const { data: organizationRoles, error: organizationRolesError, isPending: isLoadingOrganizationRoles, isError: isErrorOrganizationRoles, } = useOrganizationRolesV2Query( { slug: organization?.slug }, { enabled: !!organization?.slug, } ) const userMemberData = organizationMembers.find( (member) => member.gotrue_id === profile?.gotrue_id ) const orgScopedRoleIds = new Set( (organizationRoles?.org_scoped_roles ?? []).map((role) => role.id) ) const hasProjectScopedRoles = (organizationRoles?.project_scoped_roles ?? []).length > 0 const isOrgScopedRole = (userMemberData?.role_ids ?? []).some((roleId) => orgScopedRoleIds.has(roleId) ) const hasLimitedVisibility = hasProjectScopedRoles && !isOrgScopedRole const { visibleMembers, hiddenMembersCount, projectMemberCount, organizationMemberCount, shouldShowOrgComparison, hasOrganizationWideAccess, } = summarizeProjectAccess({ organizationMembers, roles: organizationRoles, projectRef, hasLimitedVisibility, currentUserId: profile?.gotrue_id, }) const isLoadingProjectAccess = isLoadingOrganizationMembers || isLoadingOrganizationRoles const isErrorProjectAccess = isErrorOrganizationMembers || isErrorOrganizationRoles const projectAccessError = organizationMembersError ?? organizationRolesError if (isBranch) return null const projectAccessTitle = hasLimitedVisibility ? 'You have limited visibility in this organization' : shouldShowOrgComparison && hasOrganizationWideAccess ? 'Organization-wide access' : 'Restricted project access' const projectAccessDescription = hasLimitedVisibility ? 'Your access is limited to specific projects, so you can’t see all members or settings.' : shouldShowOrgComparison ? hasOrganizationWideAccess ? `All ${organizationMemberCount} organization members can access this project.` : `${projectMemberCount} of ${organizationMemberCount} organization members can access this project.` : `${projectMemberCount} project member${projectMemberCount === 1 ? '' : 's'} currently ${projectMemberCount === 1 ? 'has' : 'have'} access.` return ( Project access {isErrorProjectAccess ? ( ) : ( {isLoadingProjectAccess ? ( ) : ( <>

{projectAccessTitle}

{projectAccessDescription}

{!!organization?.slug && ( )}
{visibleMembers.length > 0 ? ( Member Role {visibleMembers.map((member) => (

{member.email}

{member.id === profile?.gotrue_id && ( You )}
{member.role ?? ''}
))} {hiddenMembersCount > 0 && (

+{hiddenMembersCount} more project member {hiddenMembersCount === 1 ? '' : 's'}

)}
) : (

No visible project members in your current access scope.

)} )}
)}
) }