import { useLimits } from '@documenso/ee/server-only/limits/provider/client'; import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params'; import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation'; import { formatTemplatesPath } from '@documenso/lib/utils/teams'; import type { TFindTemplatesResponse } from '@documenso/trpc/server/template-router/schema'; import { Alert, AlertDescription, AlertTitle } from '@documenso/ui/primitives/alert'; 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 { Tooltip, TooltipContent, TooltipTrigger } from '@documenso/ui/primitives/tooltip'; import { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Trans } from '@lingui/react/macro'; import { AlertTriangle, Building2Icon, Globe2Icon, InfoIcon, Link2Icon, Loader, LockIcon } from 'lucide-react'; import { useMemo, useTransition } from 'react'; import { Link } from 'react-router'; import { TemplateType } from '~/components/general/template/template-type'; import { useCurrentTeam } from '~/providers/team'; import { TemplateUseDialog } from '../dialogs/template-use-dialog'; import { TemplateDirectLinkBadge } from '../general/template/template-direct-link-badge'; import { TemplatesTableActionDropdown } from './templates-table-action-dropdown'; type TemplatesTableProps = { data?: TFindTemplatesResponse; isLoading?: boolean; isLoadingError?: boolean; documentRootPath: string; templateRootPath: string; enableSelection?: boolean; rowSelection?: RowSelectionState; onRowSelectionChange?: (selection: RowSelectionState) => void; }; type TemplatesTableRow = TFindTemplatesResponse['data'][number]; export const TemplatesTable = ({ data, isLoading, isLoadingError, documentRootPath, templateRootPath, enableSelection, rowSelection, onRowSelectionChange, }: TemplatesTableProps) => { const { _, i18n } = useLingui(); const { remaining } = useLimits(); const team = useCurrentTeam(); const organisation = useCurrentOrganisation(); const [isPending, startTransition] = useTransition(); const updateSearchParams = useUpdateSearchParams(); const formatTemplateLink = (row: TemplatesTableRow) => { const path = formatTemplatesPath(team.url); return `${path}/${row.envelopeId}`; }; 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), }, { header: _(msg`Title`), cell: ({ row }) => ( {row.original.title} ), }, { header: () => (
Type
  • Public

    Public templates are connected to your public profile. Any modifications to public templates will also appear in your public profile.

  • direct link

    Direct link templates contain one dynamic recipient placeholder. Anyone with access to this link can sign the document, and it will then appear on your documents page.

  • {team?.id ? Team Only : Private}

    {team?.id ? ( Team only templates are not linked anywhere and are visible only to your team. ) : ( Private templates can only be modified and viewed by you. )}

  • Organisation

    Organisation templates are shared across all teams within the same organisation. Only the owning team can edit them.

), accessorKey: 'type', cell: ({ row }) => { const isFromOtherTeam = row.original.teamId !== team?.id; return (
{isFromOtherTeam && row.original.team?.name && ( ({row.original.team.name}) )} {row.original.directLink?.token && ( )}
); }, }, { header: _(msg`Actions`), accessorKey: 'actions', cell: ({ row }) => { return (
); }, }, ); return cols; }, [documentRootPath, team?.id, templateRootPath, enableSelection]); const onPaginationChange = (page: number, perPage: number) => { startTransition(() => { updateSearchParams({ page, perPage, }); }); }; const results = data ?? { data: [], perPage: 10, currentPage: 1, totalPages: 1, }; return (
{remaining.documents === 0 && ( Document Limit Exceeded! You have reached your document limit.{' '} Upgrade your account to continue! )} row.envelopeId} error={{ enable: isLoadingError || false, }} skeleton={{ enable: isLoading || false, rows: 5, component: ( <> {enableSelection && ( )}
), }} > {(table) => }
{isPending && (
)}
); };