import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params'; import { useSession } from '@documenso/lib/client-only/providers/session'; import { isDocumentCompleted } from '@documenso/lib/utils/document'; import { findRecipientByEmail } from '@documenso/lib/utils/recipients'; import { formatDocumentsPath } from '@documenso/lib/utils/teams'; import type { TFindDocumentsResponse } from '@documenso/trpc/server/document-router/find-documents.types'; import { Checkbox } from '@documenso/ui/primitives/checkbox'; import type { DataTableColumnDef, RowSelectionState } 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 { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Loader } from 'lucide-react'; import { DateTime } from 'luxon'; import { useMemo, useTransition } from 'react'; import { Link } from 'react-router'; import { match } from 'ts-pattern'; import { DocumentStatus } from '~/components/general/document/document-status'; import { useCurrentTeam } 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; onMoveDocument?: (envelopeId: string) => void; enableSelection?: boolean; rowSelection?: RowSelectionState; onRowSelectionChange?: (selection: RowSelectionState) => void; }; type DocumentsTableRow = TFindDocumentsResponse['data'][number]; export const DocumentsTable = ({ data, isLoading, isLoadingError, onMoveDocument, enableSelection, rowSelection, onRowSelectionChange, }: DocumentsTableProps) => { const { _, i18n } = useLingui(); const team = useCurrentTeam(); const [isPending, startTransition] = useTransition(); const updateSearchParams = useUpdateSearchParams(); const columns = useMemo(() => { const cols: DataTableColumnDef[] = []; if (enableSelection) { cols.push({ id: 'select', header: ({ table }) => ( table.toggleAllPageRowsSelected(!!value)} aria-label={_(msg`Select all`)} onClick={(e) => e.stopPropagation()} /> ), cell: ({ row }) => ( row.toggleSelected(!!value)} aria-label={_(msg`Select row`)} onClick={(e) => e.stopPropagation()} /> ), enableSorting: false, enableHiding: false, size: 40, }); } cols.push( { 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 || isDocumentCompleted(row.original.status)) && (
onMoveDocument(row.original.envelopeId) : undefined} />
), }, ); return cols; }, [team, onMoveDocument, enableSelection]); const onPaginationChange = (page: number, perPage: number) => { startTransition(() => { updateSearchParams({ page, perPage, }); }); }; const results = data ?? { data: [], perPage: 10, currentPage: 1, totalPages: 1, }; return (
{enableSelection && ( )}
), }} enableRowSelection={enableSelection} rowSelection={rowSelection} onRowSelectionChange={onRowSelectionChange} getRowId={(row) => row.envelopeId} > {(table) => }
{isPending && (
)}
); }; type DataTableTitleProps = { row: DocumentsTableRow; teamUrl: string; teamEmail?: string; }; const DataTableTitle = ({ row, teamUrl, teamEmail }: DataTableTitleProps) => { const { user } = useSession(); const recipient = findRecipientByEmail({ recipients: row.recipients, userEmail: user.email, teamEmail, }); const isOwner = row.user.id === user.id; const isRecipient = !!recipient; const isCurrentTeamDocument = teamUrl && row.team?.url === teamUrl; const documentsPath = formatDocumentsPath(teamUrl); const formatPath = `${documentsPath}/${row.envelopeId}`; return match({ isOwner, isRecipient, isCurrentTeamDocument, }) .with({ isOwner: true }, { isCurrentTeamDocument: true }, () => ( {row.title} )) .with({ isRecipient: true }, () => ( {row.title} )) .otherwise(() => ( {row.title} )); };