import { keepPreviousData } from '@tanstack/react-query' import { useDebounce } from '@uidotdev/usehooks' import { Check, ChevronsUpDown } from 'lucide-react' import { useMemo, useState } from 'react' import { toast } from 'sonner' import { Button, cn, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, Popover, PopoverContent, PopoverTrigger, ScrollArea, } from 'ui' import { Admonition, GenericSkeletonLoader } from 'ui-patterns' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { User, useUsersInfiniteQuery } from '@/data/auth/users-infinite-query' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { useRoleImpersonationStateSnapshot } from '@/state/role-impersonation-state' import { ResponseError } from '@/types' export const UserSelector = () => { const { data: project } = useSelectedProjectQuery() const state = useRoleImpersonationStateSnapshot() const [open, setOpen] = useState(false) const [searchText, setSearchText] = useState('') const debouncedSearchText = useDebounce(searchText, 300) const { data, error, isSuccess, isPending, isError } = useUsersInfiniteQuery( { projectRef: project?.ref, connectionString: project?.connectionString, keywords: debouncedSearchText.trim().toLocaleLowerCase(), }, { placeholderData: keepPreviousData } ) const users = useMemo(() => data?.pages.flatMap((page) => page.result) ?? [], [data?.pages]) const impersonatingUser = state.role?.type === 'postgrest' && state.role.role === 'authenticated' && state.role.userType === 'native' ? state.role.user : undefined const onSelectUser = async (user: User) => { try { await state.setRole({ type: 'postgrest', role: 'authenticated', userType: 'native', user, aal: 'aal1', }) } catch (error) { toast.error(`Failed to impersonate user: ${(error as ResponseError).message}`) } } return ( {isError ? ( Failed to fetch users: {error.message} ) : ( No user found )} {isPending && (
)} {isSuccess && ( 7 ? 'h-full md:h-[210px]' : ''}> {users.map((user) => { return ( { onSelectUser(user) setOpen(false) }} >

{user.email} {user.id?.slice(0, 8)}

{impersonatingUser?.id === user.id && }
) })}
)}
) }