mirror of
https://github.com/docmost/docmost.git
synced 2026-08-22 06:02:11 +10:00
112 lines
4.2 KiB
TypeScript
112 lines
4.2 KiB
TypeScript
import { Table, Group, Text, Anchor, VisuallyHidden } from "@mantine/core";
|
|
import { useGetGroupsQuery } from "@/features/group/queries/group-query";
|
|
import { Link } from "react-router-dom";
|
|
import { IconGroupCircle } from "@/components/icons/icon-people-circle.tsx";
|
|
import { useTranslation } from "react-i18next";
|
|
import { formatMemberCount } from "@/lib";
|
|
import { IGroup } from "@/features/group/types/group.types.ts";
|
|
import Paginate from "@/components/common/paginate.tsx";
|
|
import { queryClient } from "@/main.tsx";
|
|
import { getGroupMembers } from "@/features/group/services/group-service.ts";
|
|
import { AutoTooltipText } from "@/components/ui/auto-tooltip-text.tsx";
|
|
import { SearchInput } from "@/components/common/search-input.tsx";
|
|
import NoTableResults from "@/components/common/no-table-results.tsx";
|
|
import { usePaginateAndSearch } from "@/hooks/use-paginate-and-search.tsx";
|
|
import rowClasses from "@/components/ui/clickable-table-row.module.css";
|
|
import GroupActionMenu from "@/features/group/components/group-action-menu.tsx";
|
|
|
|
export default function GroupList() {
|
|
const { t } = useTranslation();
|
|
const { search, cursor, goNext, goPrev, handleSearch } = usePaginateAndSearch();
|
|
const { data, isLoading } = useGetGroupsQuery({ cursor, query: search });
|
|
|
|
const prefetchGroupMembers = (groupId: string) => {
|
|
queryClient.prefetchQuery({
|
|
queryKey: ["groupMembers", groupId, {}],
|
|
queryFn: () => getGroupMembers(groupId, {}),
|
|
});
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<SearchInput onSearch={handleSearch} />
|
|
<Table.ScrollContainer minWidth={500}>
|
|
<Table highlightOnHover verticalSpacing="sm" layout="fixed">
|
|
<Table.Thead>
|
|
<Table.Tr>
|
|
<Table.Th>{t("Group")}</Table.Th>
|
|
<Table.Th>{t("Members")}</Table.Th>
|
|
<Table.Th w={60}>
|
|
<VisuallyHidden>{t("Actions")}</VisuallyHidden>
|
|
</Table.Th>
|
|
</Table.Tr>
|
|
</Table.Thead>
|
|
|
|
<Table.Tbody>
|
|
{data?.items.length > 0 ? (
|
|
data?.items.map((group: IGroup, index: number) => (
|
|
<Table.Tr key={index} className={rowClasses.row}>
|
|
<Table.Td onMouseEnter={() => prefetchGroupMembers(group.id)}>
|
|
<Anchor
|
|
size="sm"
|
|
underline="never"
|
|
style={{
|
|
cursor: "pointer",
|
|
color: "var(--mantine-color-text)",
|
|
}}
|
|
className={rowClasses.link}
|
|
component={Link}
|
|
to={`/settings/groups/${group.id}`}
|
|
>
|
|
<Group gap="sm" wrap="nowrap">
|
|
<IconGroupCircle />
|
|
<div style={{ minWidth: 0, overflow: "hidden" }}>
|
|
<AutoTooltipText fz="sm" fw={500} lineClamp={1}>
|
|
{group.name}
|
|
</AutoTooltipText>
|
|
<Text fz="xs" c="dimmed" lineClamp={2}>
|
|
{group.description}
|
|
</Text>
|
|
</div>
|
|
</Group>
|
|
</Anchor>
|
|
</Table.Td>
|
|
<Table.Td>
|
|
<Anchor
|
|
size="sm"
|
|
underline="never"
|
|
style={{
|
|
cursor: "pointer",
|
|
color: "var(--mantine-color-text)",
|
|
whiteSpace: "nowrap",
|
|
}}
|
|
component={Link}
|
|
to={`/settings/groups/${group.id}`}
|
|
>
|
|
{formatMemberCount(group.memberCount, t)}
|
|
</Anchor>
|
|
</Table.Td>
|
|
<Table.Td>
|
|
<GroupActionMenu group={group} />
|
|
</Table.Td>
|
|
</Table.Tr>
|
|
))
|
|
) : (
|
|
<NoTableResults colSpan={3} />
|
|
)}
|
|
</Table.Tbody>
|
|
</Table>
|
|
</Table.ScrollContainer>
|
|
|
|
{data?.items.length > 0 && (
|
|
<Paginate
|
|
hasPrevPage={data?.meta?.hasPrevPage}
|
|
hasNextPage={data?.meta?.hasNextPage}
|
|
onNext={() => goNext(data?.meta?.nextCursor)}
|
|
onPrev={goPrev}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
}
|