import { useMemo } from 'react'; import { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Trans } from '@lingui/react/macro'; import { OrganisationGroupType, OrganisationMemberRole } from '@prisma/client'; import { EditIcon, MoreHorizontal, Trash2Icon } from 'lucide-react'; import { useSearchParams } from 'react-router'; import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params'; import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation'; import { EXTENDED_TEAM_MEMBER_ROLE_MAP } from '@documenso/lib/constants/teams-translations'; import { ZUrlSearchParamsSchema } from '@documenso/lib/types/search-params'; import { extractInitials } from '@documenso/lib/utils/recipient-formatter'; import { isTeamRoleWithinUserHierarchy } from '@documenso/lib/utils/teams'; import { trpc } from '@documenso/trpc/react'; import { AnimateGenericFadeInOut } from '@documenso/ui/components/animate/animate-generic-fade-in-out'; import { AvatarWithText } from '@documenso/ui/primitives/avatar'; import type { DataTableColumnDef } from '@documenso/ui/primitives/data-table'; import { DataTable } from '@documenso/ui/primitives/data-table'; import { DataTablePagination } from '@documenso/ui/primitives/data-table-pagination'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuTrigger, } from '@documenso/ui/primitives/dropdown-menu'; import { Skeleton } from '@documenso/ui/primitives/skeleton'; import { TableCell } from '@documenso/ui/primitives/table'; import { useCurrentTeam } from '~/providers/team'; import { TeamMemberDeleteDialog } from '../dialogs/team-member-delete-dialog'; import { TeamMemberUpdateDialog } from '../dialogs/team-member-update-dialog'; import { TeamInheritMemberAlert } from '../general/teams/team-inherit-member-alert'; export const TeamMembersTable = () => { const { _ } = useLingui(); const [searchParams] = useSearchParams(); const updateSearchParams = useUpdateSearchParams(); const organisation = useCurrentOrganisation(); const team = useCurrentTeam(); const parsedSearchParams = ZUrlSearchParamsSchema.parse(Object.fromEntries(searchParams ?? [])); const groupQuery = trpc.team.group.find.useQuery({ teamId: team.id, types: [OrganisationGroupType.INTERNAL_ORGANISATION, OrganisationGroupType.INTERNAL_TEAM], organisationRoles: [OrganisationMemberRole.MEMBER], perPage: 100, // Lets hope this is enough. }); const { data, isLoading, isLoadingError } = trpc.team.member.find.useQuery( { teamId: team.id, query: parsedSearchParams.query, page: parsedSearchParams.page, perPage: parsedSearchParams.perPage, }, { placeholderData: (previousData) => previousData, }, ); const onPaginationChange = (page: number, perPage: number) => { updateSearchParams({ page, perPage, }); }; const results = data ?? { data: [], perPage: 10, currentPage: 1, totalPages: 1, }; const groups = groupQuery.data?.data ?? []; const memberAccessTeamGroup = groups.find( (group) => group.organisationGroupType === OrganisationGroupType.INTERNAL_ORGANISATION && group.teamRole === OrganisationMemberRole.MEMBER, ); const columns = useMemo(() => { return [ { header: _(msg`Team Member`), cell: ({ row }) => { const avatarFallbackText = row.original.name ? extractInitials(row.original.name) : row.original.email.slice(0, 1).toUpperCase(); return ( {row.original.name} } secondaryText={row.original.email} /> ); }, }, { header: _(msg`Role`), accessorKey: 'role', cell: ({ row }) => _(EXTENDED_TEAM_MEMBER_ROLE_MAP[row.original.teamRole]), }, { header: _(msg`Source`), cell: ({ row }) => { const internalTeamGroupFound = groups.find( (group) => group.organisationGroupType === OrganisationGroupType.INTERNAL_TEAM && group.members.some((member) => member.id === row.original.id), ); return internalTeamGroupFound ? _(msg`Member`) : _(msg`Group`); }, }, { header: _(msg`Actions`), cell: ({ row }) => ( Actions e.preventDefault()} title="Update team member role" > Update role } /> e.preventDefault()} disabled={ organisation.ownerUserId === row.original.userId || !isTeamRoleWithinUserHierarchy(team.currentTeamRole, row.original.teamRole) } title={_(msg`Remove team member`)} > Remove } /> ), }, ] satisfies DataTableColumnDef<(typeof results)['data'][number]>[]; }, [groups]); return (
), }} > {(table) => }
{!groupQuery.isPending && ( )}
); };