import { useMemo, useTransition } from 'react'; import { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Loader } from 'lucide-react'; import { DateTime } from 'luxon'; import { Link } from 'react-router'; import { match } from 'ts-pattern'; import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params'; import { useSession } from '@documenso/lib/client-only/providers/session'; import { formatDocumentsPath } from '@documenso/lib/utils/teams'; import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status'; import type { TFindDocumentsResponse } from '@documenso/trpc/server/document-router/schema'; 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 { Skeleton } from '@documenso/ui/primitives/skeleton'; import { TableCell } from '@documenso/ui/primitives/table'; import { DocumentStatus } from '~/components/general/document/document-status'; import { useOptionalCurrentTeam } from '~/providers/team'; import { StackAvatarsWithTooltip } from '../general/stack-avatars-with-tooltip'; import { DocumentsTableActionButton } from './documents-table-action-button'; import { DocumentsTableActionDropdown } from './documents-table-action-dropdown'; export type DocumentsTableProps = { data?: TFindDocumentsResponse; isLoading?: boolean; isLoadingError?: boolean; }; type DocumentsTableRow = TFindDocumentsResponse['data'][number]; export const DocumentsTable = ({ data, isLoading, isLoadingError }: DocumentsTableProps) => { const { _, i18n } = useLingui(); const team = useOptionalCurrentTeam(); const [isPending, startTransition] = useTransition(); const updateSearchParams = useUpdateSearchParams(); const columns = useMemo(() => { return [ { header: _(msg`Created`), accessorKey: 'createdAt', cell: ({ row }) => i18n.date(row.original.createdAt, { ...DateTime.DATETIME_SHORT, hourCycle: 'h12' }), }, { header: _(msg`Title`), cell: ({ row }) => , }, { id: 'sender', header: _(msg`Sender`), cell: ({ row }) => row.original.user.name ?? row.original.user.email, }, { header: _(msg`Recipient`), accessorKey: 'recipient', cell: ({ row }) => ( ), }, { header: _(msg`Status`), accessorKey: 'status', cell: ({ row }) => , size: 140, }, { header: _(msg`Actions`), cell: ({ row }) => (!row.original.deletedAt || row.original.status === ExtendedDocumentStatus.COMPLETED) && (
), }, ] satisfies DataTableColumnDef[]; }, [team]); const onPaginationChange = (page: number, perPage: number) => { startTransition(() => { updateSearchParams({ page, perPage, }); }); }; const results = data ?? { data: [], perPage: 10, currentPage: 1, totalPages: 1, }; return (
), }} > {(table) => }
{isPending && (
)}
); }; type DataTableTitleProps = { row: DocumentsTableRow; teamUrl?: string; }; const DataTableTitle = ({ row, teamUrl }: DataTableTitleProps) => { const { user } = useSession(); const recipient = row.recipients.find((recipient) => recipient.email === user.email); const isOwner = row.user.id === user.id; const isRecipient = !!recipient; const isCurrentTeamDocument = teamUrl && row.team?.url === teamUrl; const documentsPath = formatDocumentsPath(isCurrentTeamDocument ? teamUrl : undefined); return match({ isOwner, isRecipient, isCurrentTeamDocument, }) .with({ isOwner: true }, { isCurrentTeamDocument: true }, () => ( {row.title} )) .with({ isRecipient: true }, () => ( {row.title} )) .otherwise(() => ( {row.title} )); };