Files
supabase/apps/studio/components/interfaces/Auth/Users/Users.tsx
Alaister Young e9c1966ab5 chore: improve auth screens loading (#19940)
* chore: improve auth screens loading

* Update apps/studio/components/interfaces/Auth/Users/UsersList.tsx

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>

* handle error

* better pagination for users list

* disgusting boolean logic

* return user to previous page after deleting last user

* only show reloading indicator when it's refetching

* fix date formatting

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2024-01-02 05:13:33 +00:00

159 lines
5.0 KiB
TypeScript

import { useQueryClient } from '@tanstack/react-query'
import { useState } from 'react'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { useParams } from 'common'
import { useIsAPIDocsSidePanelEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
import APIDocsButton from 'components/ui/APIDocsButton'
import NoPermission from 'components/ui/NoPermission'
import { useUsersQuery } from 'data/auth/users-query'
import { useCheckPermissions, usePermissionsLoaded } from 'hooks'
import { Button, IconRefreshCw, IconSearch, IconX, Input, Listbox } from 'ui'
import AddUserDropdown from './AddUserDropdown'
import UsersList from './UsersList'
import { authKeys } from 'data/auth/keys'
const Users = () => {
const queryClient = useQueryClient()
const { project } = useProjectContext()
const { ref: projectRef } = useParams()
const isNewAPIDocsEnabled = useIsAPIDocsSidePanelEnabled()
const [page, setPage] = useState(1)
const [search, setSearch] = useState('')
const [filterKeywords, setFilterKeywords] = useState('')
const [filterVerified, setFilterVerified] = useState<'verified' | 'unverified'>()
const canReadUsers = useCheckPermissions(PermissionAction.TENANT_SQL_SELECT, 'auth.users')
const isPermissionsLoaded = usePermissionsLoaded()
const {
data,
isLoading,
isSuccess,
refetch,
isRefetching,
error,
isPreviousData: isFetchingNextPage,
} = useUsersQuery(
{
projectRef,
page,
keywords: filterKeywords,
verified: filterVerified,
},
{
keepPreviousData: true,
onSuccess(data) {
if (data.users.length <= 0 && data.total > 0) {
queryClient.removeQueries(
authKeys.users(projectRef, { page, keywords: filterKeywords, verified: filterVerified })
)
setPage((prev) => prev - 1)
}
},
}
)
function onVerifiedFilterChange(e: any) {
setFilterVerified(e)
}
function clearSearch() {
setSearch('')
setFilterKeywords('')
setFilterVerified(undefined)
}
return (
<div>
<div className="justify-between px-6 pt-6 pb-2 md:flex">
<div className="relative flex space-x-4">
<Input
size="small"
value={search}
onChange={(e) => setSearch(e.target.value)}
onKeyDown={(e) => {
if (e.keyCode == 13) setFilterKeywords(search)
}}
className="min-w-[275px]"
name="email"
id="email"
placeholder="Search by email or phone number"
icon={<IconSearch size="tiny" />}
actions={[
search && (
<Button
size="tiny"
type="text"
icon={<IconX size="tiny" />}
onClick={() => clearSearch()}
/>
),
]}
/>
<Listbox
size="small"
value={filterVerified}
onChange={onVerifiedFilterChange}
name="verified"
id="verified"
className="w-[200px]"
>
<Listbox.Option label="All Users" value="">
All Users
</Listbox.Option>
<Listbox.Option label="Verified Users" value="verified">
Verified Users
</Listbox.Option>
<Listbox.Option label="Un-Verified Users" value="unverified">
Un-Verified Users
</Listbox.Option>
</Listbox>
</div>
<div className="mt-4 flex items-center gap-2 md:mt-0">
{isNewAPIDocsEnabled && <APIDocsButton section={['user-management']} />}
<Button
size="tiny"
icon={<IconRefreshCw />}
type="default"
loading={isRefetching && !isFetchingNextPage}
onClick={() => refetch()}
>
Reload
</Button>
<AddUserDropdown projectKpsVersion={project?.kpsVersion} />
</div>
</div>
<section className="thin-scrollbars mt-4 overflow-visible px-6">
<div className="section-block--body relative overflow-x-auto rounded">
<div className="inline-block min-w-full align-middle">
{isPermissionsLoaded && !canReadUsers ? (
<div className="mt-8">
<NoPermission isFullPage resourceText="access your project's users" />
</div>
) : (
<UsersList
page={page}
setPage={setPage}
keywords={filterKeywords}
verified={filterVerified}
total={data?.total ?? 0}
users={data?.users ?? []}
isLoading={isLoading}
isSuccess={isSuccess}
isFetchingNextPage={isFetchingNextPage}
error={error}
/>
)}
</div>
</div>
</section>
</div>
)
}
export default Users