Files
Docker/Voltaserve/ui/src/pages/group/group-list-page.tsx
2024-04-17 20:22:30 +02:00

160 lines
4.3 KiB
TypeScript

import { useEffect } from 'react'
import {
Link,
useLocation,
useNavigate,
useSearchParams,
} from 'react-router-dom'
import {
Heading,
Link as ChakraLink,
Table,
Tbody,
Td,
Th,
Thead,
Tr,
Avatar,
Badge,
} from '@chakra-ui/react'
import cx from 'classnames'
import { Helmet } from 'react-helmet-async'
import GroupAPI, { SortOrder } from '@/client/api/group'
import { swrConfig } from '@/client/options'
import { CreateGroupButton } from '@/components/top-bar/top-bar-buttons'
import prettyDate from '@/helpers/pretty-date'
import { decodeQuery } from '@/helpers/query'
import { groupPaginationStorage } from '@/infra/pagination'
import { SectionSpinner, PagePagination, usePagePagination } from '@/lib'
const GroupListPage = () => {
const navigate = useNavigate()
const location = useLocation()
const [searchParams] = useSearchParams()
const query = decodeQuery(searchParams.get('q') as string)
const { page, size, steps, setPage, setSize } = usePagePagination({
navigate,
location,
storage: groupPaginationStorage(),
})
const {
data: list,
error,
mutate,
} = GroupAPI.useList(
{ query, page, size, sortOrder: SortOrder.Desc },
swrConfig(),
)
useEffect(() => {
mutate()
}, [query, page, size, mutate])
return (
<>
<Helmet>
<title>Groups</title>
</Helmet>
<div className={cx('flex', 'flex-col', 'gap-3.5', 'pb-3.5')}>
<Heading className={cx('pl-2', 'text-heading')}>Groups</Heading>
{error && (
<div
className={cx(
'flex',
'items-center',
'justify-center',
'h-[300px]',
)}
>
<span>Failed to load groups.</span>
</div>
)}
{!list && !error && <SectionSpinner />}
{list && list.data.length === 0 && (
<div
className={cx(
'flex',
'items-center',
'justify-center',
'h-[300px]',
)}
>
<div className={cx('flex', 'flex-col', 'gap-1.5')}>
<span>There are no groups.</span>
<CreateGroupButton />
</div>
</div>
)}
{list && list.data.length > 0 && (
<Table variant="simple">
<Thead>
<Tr>
<Th>Name</Th>
<Th>Organization</Th>
<Th>Permission</Th>
<Th>Date</Th>
</Tr>
</Thead>
<Tbody>
{list.data.map((g) => (
<Tr key={g.id}>
<Td>
<div
className={cx(
'flex',
'flex-row',
'items-center',
'gap-1.5',
)}
>
<Avatar
name={g.name}
size="sm"
className={cx('w-[40px]', 'h-[40px]')}
/>
<ChakraLink
as={Link}
to={`/group/${g.id}/member`}
className={cx('no-underline')}
>
{g.name}
</ChakraLink>
</div>
</Td>
<Td>
<ChakraLink
as={Link}
to={`/organization/${g.organization.id}/member`}
className={cx('no-underline')}
>
{g.organization.name}
</ChakraLink>
</Td>
<Td>
<Badge>{g.permission}</Badge>
</Td>
<Td>{prettyDate(g.createTime)}</Td>
</Tr>
))}
</Tbody>
</Table>
)}
{list && (
<PagePagination
style={{ alignSelf: 'end' }}
totalElements={list.totalElements}
totalPages={list.totalPages}
page={page}
size={size}
steps={steps}
setPage={setPage}
setSize={setSize}
/>
)}
</div>
</>
)
}
export default GroupListPage