import { 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 AlertError from '@/components/ui/AlertError' import { useAccessTokenDeleteMutation } from '@/data/access-tokens/access-tokens-delete-mutation' import { AccessToken, useAccessTokensQuery } from '@/data/access-tokens/access-tokens-query' import { useTrack } from '@/lib/telemetry/track' export interface AccessTokenListProps { searchString?: string onDeleteSuccess: (id: number) => void } export const AccessTokenList = ({ searchString = '', onDeleteSuccess }: AccessTokenListProps) => { const track = useTrack() const [isOpen, setIsOpen] = useState(false) const [token, setToken] = useState(undefined) const [sort, setSort] = useQueryState( 'sort', parseAsStringLiteral(ACCESS_TOKEN_SORT_VALUES).withDefault('created_at:desc') ) const { data: tokens, error, isPending: isLoading, isError } = useAccessTokensQuery() const { mutate: deleteToken } = useAccessTokenDeleteMutation({ onSuccess: (_, vars) => { track('access_token_removed', { tokenType: 'classic' }) 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 access tokens found

You do not have any tokens created yet

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

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

) }