import dayjs from 'dayjs' import { useMemo } from 'react' import { Card, CardContent, cn, ScrollArea, Sheet, SheetContent, SheetHeader, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from 'ui' import { TimestampInfo } from 'ui-patterns/TimestampInfo' import { ACCESS_TOKEN_RESOURCES } from '../AccessToken.constants' import { formatAccessText, getRealAccess } from '../AccessToken.utils' import { useOrgAndProjectData } from '../hooks/useOrgAndProjectData' import { DocsButton } from '@/components/ui/DocsButton' import { useScopedAccessTokenQuery } from '@/data/scoped-access-tokens/scoped-access-token-query' interface ViewTokenSheetProps { visible: boolean tokenId: string | undefined onClose: () => void } export function ViewTokenSheet({ visible, tokenId, onClose }: ViewTokenSheetProps) { const { organizations, projects } = useOrgAndProjectData() const { data: token, isLoading: isTokenLoading, error: tokenError, } = useScopedAccessTokenQuery( { id: tokenId! }, { enabled: visible && !!tokenId, retry: 1, retryDelay: 1000, } ) const groupedResourcesByAccess = useMemo(() => { const grouped: Record = {} if (!token?.permissions) { return grouped } ACCESS_TOKEN_RESOURCES.forEach((resource) => { const access = getRealAccess(resource.resource, token.permissions) if (access !== 'no access') { const formattedAccess = formatAccessText(access) if (!grouped[formattedAccess]) { grouped[formattedAccess] = [] } grouped[formattedAccess].push(resource.title) } }) return grouped }, [token?.permissions]) const getResourceAccessInfo = () => { const resources: Array<{ name: string; type: string; identifier: string }> = [] const organizationSlugs = token?.organization_slugs if (organizationSlugs && Array.isArray(organizationSlugs) && organizationSlugs.length > 0) { organizationSlugs.forEach((orgSlug: string) => { const org = organizations.find((o) => o.slug === orgSlug) resources.push({ name: org?.name || orgSlug, type: 'Organization', identifier: orgSlug, }) }) } const projectRefs = token?.project_refs if (projectRefs && Array.isArray(projectRefs) && projectRefs.length > 0) { projectRefs.forEach((projectRef: string) => { const project = projects.find((p) => p.ref === projectRef) resources.push({ name: project?.name || projectRef, type: 'Project', identifier: projectRef, }) }) } return resources } return ( <> onClose()}>

View access for {token?.name}

{isTokenLoading && (

Loading token information...

)} {tokenError && (

Error loading token information. Please try again.

)} {token && ( <>

Token Information

Info Date

Created

{token?.created_at ? ( ) : ( Unknown )}

Last used

{token?.last_used_at ? ( ) : ( Never )}

Expires

{token?.expires_at ? ( ) : ( Never )}

Resource Access

Resource Type {getResourceAccessInfo().length > 0 ? ( getResourceAccessInfo().map((resource, index) => (

{resource.name}

{resource.type}
)) ) : (

{(token?.organization_slugs && token.organization_slugs.length > 0) || (token?.project_refs && token.project_refs.length > 0) ? 'This token has access to specific organizations and projects.' : 'This token has access to all resources.'}

)}

Permissions

Permission Access {Object.keys(groupedResourcesByAccess).length === 0 ? (

No permissions configured for this token.

) : ( Object.entries(groupedResourcesByAccess).map( ([accessLevel, resources]) => { return resources.map((resource) => (

{resource}

{formatAccessText(accessLevel)}
)) } ) )}
)}
) }