import { Key, MoreVertical, Trash } from 'lucide-react' import { parseAsStringLiteral, useQueryState } from 'nuqs' import { useMemo, useState } from 'react' import { toast } from 'sonner' import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from 'ui' import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' import { TableCell, TableRow } from 'ui/src/components/shadcn/ui/table' import { ACCESS_TOKEN_SORT_VALUES, AccessTokenSort, AccessTokenSortColumn, } from '../AccessToken.types' import { filterAndSortTokens, handleSortChange } from '../AccessToken.utils' import { RowLoading } from '../AccessTokenTable/RowLoading' import { TableContainer } from '../AccessTokenTable/TableContainer' import { ExpiresCell, LastUsedCell, TokenNameCell } from '../AccessTokenTable/TokenCells' import { ViewTokenSheet } from './ViewTokenSheet' import AlertError from '@/components/ui/AlertError' import { ScopedAccessToken, useScopedAccessTokensQuery, } from '@/data/scoped-access-tokens/scoped-access-token-query' import { useScopedAccessTokenDeleteMutation } from '@/data/scoped-access-tokens/scoped-access-tokens-delete-mutation' import { useTrack } from '@/lib/telemetry/track' export interface ScopedTokenListProps { searchString?: string onDeleteSuccess: (id: string | number) => void } export const ScopedTokenList = ({ searchString = '', onDeleteSuccess }: ScopedTokenListProps) => { const track = useTrack() const [isOpen, setIsOpen] = useState(false) const [token, setToken] = useState(undefined) const [viewToken, setViewToken] = useState(undefined) const [isViewSheetOpen, setIsViewSheetOpen] = useState(false) const [sort, setSort] = useQueryState( 'sort', parseAsStringLiteral(ACCESS_TOKEN_SORT_VALUES).withDefault('created_at:desc') ) const { data: tokensData, error, isPending: isLoading, isError } = useScopedAccessTokensQuery() const tokens = tokensData?.tokens const { mutate: deleteToken } = useScopedAccessTokenDeleteMutation({ onSuccess: (_, vars) => { track('access_token_removed', { tokenType: 'scoped' }) onDeleteSuccess(vars.id) toast.success('Successfully deleted access token') setIsOpen(false) }, onError: (error) => { toast.error(`Failed to delete access token: ${error.message}`) }, }) const onSortChange = (column: AccessTokenSortColumn) => { handleSortChange(sort, column, setSort) } const filteredTokens = useMemo( () => filterAndSortTokens(tokens, searchString, sort), [tokens, searchString, sort] ) const empty = filteredTokens?.length === 0 && !isLoading if (isError) { return ( ) } if (isLoading) { return ( ) } if (empty) { return (

No scoped access tokens found

You do not have any scoped tokens created yet

) } return ( <> {filteredTokens?.map((x) => (
))}
setIsOpen(false)} onConfirm={() => { if (token) deleteToken({ id: token.id as string }) }} >

This action cannot be undone. Are you sure you want to delete "{token?.name}" token?

{ setIsViewSheetOpen(false) setViewToken(undefined) }} /> ) }