fix: dialog close on refresh (#1135)

Previously dialogs would be closed upon refocusing the browser tab due to router refetches occuring which would cause data-table columns to re-render. This is now resolved by extracting the column definitions outside of the returning render and into a memo hook.
This commit is contained in:
David Nguyen
2024-08-27 22:13:52 +09:00
committed by GitHub
parent 75c8772a02
commit 38a4b0f299
19 changed files with 1069 additions and 978 deletions

View File

@ -1,5 +1,7 @@
'use client';
import { useMemo } from 'react';
import { useRouter } from 'next/navigation';
import { Trans, msg } from '@lingui/macro';
@ -15,6 +17,7 @@ import {
} from '@documenso/prisma/client';
import { trpc } from '@documenso/trpc/react';
import { Button } from '@documenso/ui/primitives/button';
import type { DataTableColumnDef } from '@documenso/ui/primitives/data-table';
import { DataTable } from '@documenso/ui/primitives/data-table';
import {
Form,
@ -59,6 +62,50 @@ export const RecipientItem = ({ recipient }: RecipientItemProps) => {
const { mutateAsync: updateRecipient } = trpc.admin.updateRecipient.useMutation();
const columns = useMemo(() => {
return [
{
header: 'ID',
accessorKey: 'id',
cell: ({ row }) => <div>{row.original.id}</div>,
},
{
header: _(msg`Type`),
accessorKey: 'type',
cell: ({ row }) => <div>{row.original.type}</div>,
},
{
header: _(msg`Inserted`),
accessorKey: 'inserted',
cell: ({ row }) => <div>{row.original.inserted ? 'True' : 'False'}</div>,
},
{
header: _(msg`Value`),
accessorKey: 'customText',
cell: ({ row }) => <div>{row.original.customText}</div>,
},
{
header: _(msg`Signature`),
accessorKey: 'signature',
cell: ({ row }) => (
<div>
{row.original.Signature?.typedSignature && (
<span>{row.original.Signature.typedSignature}</span>
)}
{row.original.Signature?.signatureImageAsBase64 && (
<img
src={row.original.Signature.signatureImageAsBase64}
alt="Signature"
className="h-12 w-full dark:invert"
/>
)}
</div>
),
},
] satisfies DataTableColumnDef<(typeof recipient)['Field'][number]>[];
}, []);
const onUpdateRecipientFormSubmit = async ({ name, email }: TAdminUpdateRecipientFormSchema) => {
try {
await updateRecipient({
@ -143,50 +190,7 @@ export const RecipientItem = ({ recipient }: RecipientItemProps) => {
<Trans>Fields</Trans>
</h2>
<DataTable
data={recipient.Field}
columns={[
{
header: 'ID',
accessorKey: 'id',
cell: ({ row }) => <div>{row.original.id}</div>,
},
{
header: _(msg`Type`),
accessorKey: 'type',
cell: ({ row }) => <div>{row.original.type}</div>,
},
{
header: _(msg`Inserted`),
accessorKey: 'inserted',
cell: ({ row }) => <div>{row.original.inserted ? 'True' : 'False'}</div>,
},
{
header: _(msg`Value`),
accessorKey: 'customText',
cell: ({ row }) => <div>{row.original.customText}</div>,
},
{
header: _(msg`Signature`),
accessorKey: 'signature',
cell: ({ row }) => (
<div>
{row.original.Signature?.typedSignature && (
<span>{row.original.Signature.typedSignature}</span>
)}
{row.original.Signature?.signatureImageAsBase64 && (
<img
src={row.original.Signature.signatureImageAsBase64}
alt="Signature"
className="h-12 w-full dark:invert"
/>
)}
</div>
),
},
]}
/>
<DataTable columns={columns} data={recipient.Field} />
</div>
);
};

View File

@ -1,6 +1,6 @@
'use client';
import { useState } from 'react';
import { useMemo, useState } from 'react';
import Link from 'next/link';
import { useSearchParams } from 'next/navigation';
@ -14,6 +14,7 @@ import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-upda
import { extractInitials } from '@documenso/lib/utils/recipient-formatter';
import { trpc } from '@documenso/trpc/react';
import { Avatar, AvatarFallback } 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 { Input } from '@documenso/ui/primitives/input';
@ -49,6 +50,83 @@ export const AdminDocumentResults = () => {
},
);
const results = findDocumentsData ?? {
data: [],
perPage: 20,
currentPage: 1,
totalPages: 1,
};
const columns = useMemo(() => {
return [
{
header: _(msg`Created`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate date={row.original.createdAt} />,
},
{
header: _(msg`Title`),
accessorKey: 'title',
cell: ({ row }) => {
return (
<Link
href={`/admin/documents/${row.original.id}`}
className="block max-w-[5rem] truncate font-medium hover:underline md:max-w-[10rem]"
>
{row.original.title}
</Link>
);
},
},
{
header: _(msg`Status`),
accessorKey: 'status',
cell: ({ row }) => <DocumentStatus status={row.original.status} />,
},
{
header: _(msg`Owner`),
accessorKey: 'owner',
cell: ({ row }) => {
const avatarFallbackText = row.original.User.name
? extractInitials(row.original.User.name)
: row.original.User.email.slice(0, 1).toUpperCase();
return (
<Tooltip delayDuration={200}>
<TooltipTrigger>
<Link href={`/admin/users/${row.original.User.id}`}>
<Avatar className="dark:border-border h-12 w-12 border-2 border-solid border-white">
<AvatarFallback className="text-xs text-gray-400">
{avatarFallbackText}
</AvatarFallback>
</Avatar>
</Link>
</TooltipTrigger>
<TooltipContent className="flex max-w-xs items-center gap-2">
<Avatar className="dark:border-border h-12 w-12 border-2 border-solid border-white">
<AvatarFallback className="text-xs text-gray-400">
{avatarFallbackText}
</AvatarFallback>
</Avatar>
<div className="text-muted-foreground flex flex-col text-sm">
<span>{row.original.User.name}</span>
<span>{row.original.User.email}</span>
</div>
</TooltipContent>
</Tooltip>
);
},
},
{
header: 'Last updated',
accessorKey: 'updatedAt',
cell: ({ row }) => <LocaleDate date={row.original.updatedAt} />,
},
] satisfies DataTableColumnDef<(typeof results)['data'][number]>[];
}, []);
const onPaginationChange = (newPage: number, newPerPage: number) => {
updateSearchParams({
page: newPage,
@ -67,77 +145,11 @@ export const AdminDocumentResults = () => {
<div className="relative mt-4">
<DataTable
columns={[
{
header: _(msg`Created`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate date={row.original.createdAt} />,
},
{
header: _(msg`Title`),
accessorKey: 'title',
cell: ({ row }) => {
return (
<Link
href={`/admin/documents/${row.original.id}`}
className="block max-w-[5rem] truncate font-medium hover:underline md:max-w-[10rem]"
>
{row.original.title}
</Link>
);
},
},
{
header: _(msg`Status`),
accessorKey: 'status',
cell: ({ row }) => <DocumentStatus status={row.original.status} />,
},
{
header: _(msg`Owner`),
accessorKey: 'owner',
cell: ({ row }) => {
const avatarFallbackText = row.original.User.name
? extractInitials(row.original.User.name)
: row.original.User.email.slice(0, 1).toUpperCase();
return (
<Tooltip delayDuration={200}>
<TooltipTrigger>
<Link href={`/admin/users/${row.original.User.id}`}>
<Avatar className="dark:border-border h-12 w-12 border-2 border-solid border-white">
<AvatarFallback className="text-xs text-gray-400">
{avatarFallbackText}
</AvatarFallback>
</Avatar>
</Link>
</TooltipTrigger>
<TooltipContent className="flex max-w-xs items-center gap-2">
<Avatar className="dark:border-border h-12 w-12 border-2 border-solid border-white">
<AvatarFallback className="text-xs text-gray-400">
{avatarFallbackText}
</AvatarFallback>
</Avatar>
<div className="text-muted-foreground flex flex-col text-sm">
<span>{row.original.User.name}</span>
<span>{row.original.User.email}</span>
</div>
</TooltipContent>
</Tooltip>
);
},
},
{
header: 'Last updated',
accessorKey: 'updatedAt',
cell: ({ row }) => <LocaleDate date={row.original.updatedAt} />,
},
]}
data={findDocumentsData?.data ?? []}
perPage={findDocumentsData?.perPage ?? 20}
currentPage={findDocumentsData?.currentPage ?? 1}
totalPages={findDocumentsData?.totalPages ?? 1}
columns={columns}
data={results.data}
perPage={results.perPage ?? 20}
currentPage={results.currentPage ?? 1}
totalPages={results.totalPages ?? 1}
onPaginationChange={onPaginationChange}
>
{(table) => <DataTablePagination additionalInformation="VisibleCount" table={table} />}

View File

@ -1,6 +1,6 @@
'use client';
import { useEffect, useState, useTransition } from 'react';
import { useEffect, useMemo, useState, useTransition } from 'react';
import Link from 'next/link';
@ -12,6 +12,7 @@ import { useDebouncedValue } from '@documenso/lib/client-only/hooks/use-debounce
import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params';
import type { Document, Role, Subscription } from '@documenso/prisma/client';
import { Button } from '@documenso/ui/primitives/button';
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 { Input } from '@documenso/ui/primitives/input';
@ -54,6 +55,63 @@ export const UsersDataTable = ({
const [searchString, setSearchString] = useState('');
const debouncedSearchString = useDebouncedValue(searchString, 1000);
const columns = useMemo(() => {
return [
{
header: 'ID',
accessorKey: 'id',
cell: ({ row }) => <div>{row.original.id}</div>,
},
{
header: _(msg`Name`),
accessorKey: 'name',
cell: ({ row }) => <div>{row.original.name}</div>,
},
{
header: _(msg`Email`),
accessorKey: 'email',
cell: ({ row }) => <div>{row.original.email}</div>,
},
{
header: _(msg`Roles`),
accessorKey: 'roles',
cell: ({ row }) => row.original.roles.join(', '),
},
{
header: _(msg`Subscription`),
accessorKey: 'subscription',
cell: ({ row }) => {
const foundIndividualSubscription = (row.original.Subscription ?? []).find((sub) =>
individualPriceIds.includes(sub.priceId),
);
return foundIndividualSubscription?.status ?? 'NONE';
},
},
{
header: _(msg`Documents`),
accessorKey: 'documents',
cell: ({ row }) => {
return <div>{row.original.Document.length}</div>;
},
},
{
header: '',
accessorKey: 'edit',
cell: ({ row }) => {
return (
<Button className="w-24" asChild>
<Link href={`/admin/users/${row.original.id}`}>
<Edit className="-ml-1 mr-2 h-4 w-4" />
Edit
</Link>
</Button>
);
},
},
] satisfies DataTableColumnDef<(typeof users)[number]>[];
}, [individualPriceIds]);
useEffect(() => {
startTransition(() => {
updateSearchParams({
@ -88,60 +146,7 @@ export const UsersDataTable = ({
onChange={handleChange}
/>
<DataTable
columns={[
{
header: 'ID',
accessorKey: 'id',
cell: ({ row }) => <div>{row.original.id}</div>,
},
{
header: _(msg`Name`),
accessorKey: 'name',
cell: ({ row }) => <div>{row.original.name}</div>,
},
{
header: _(msg`Email`),
accessorKey: 'email',
cell: ({ row }) => <div>{row.original.email}</div>,
},
{
header: _(msg`Roles`),
accessorKey: 'roles',
cell: ({ row }) => row.original.roles.join(', '),
},
{
header: _(msg`Subscription`),
accessorKey: 'subscription',
cell: ({ row }) => {
const foundIndividualSubscription = (row.original.Subscription ?? []).find((sub) =>
individualPriceIds.includes(sub.priceId),
);
return foundIndividualSubscription?.status ?? 'NONE';
},
},
{
header: _(msg`Documents`),
accessorKey: 'documents',
cell: ({ row }) => {
return <div>{row.original.Document.length}</div>;
},
},
{
header: '',
accessorKey: 'edit',
cell: ({ row }) => {
return (
<Button className="w-24" asChild>
<Link href={`/admin/users/${row.original.id}`}>
<Edit className="-ml-1 mr-2 h-4 w-4" />
Edit
</Link>
</Button>
);
},
},
]}
columns={columns}
data={users}
perPage={perPage}
currentPage={page}

View File

@ -1,5 +1,7 @@
'use client';
import { useMemo } from 'react';
import { useSearchParams } from 'next/navigation';
import { msg } from '@lingui/macro';
@ -12,6 +14,7 @@ import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-upda
import { ZBaseTableSearchParamsSchema } from '@documenso/lib/types/search-params';
import { formatDocumentAuditLogAction } from '@documenso/lib/utils/document-audit-logs';
import { trpc } from '@documenso/trpc/react';
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';
@ -31,8 +34,6 @@ const dateFormat: DateTimeFormatOptions = {
export const DocumentLogsDataTable = ({ documentId }: DocumentLogsDataTableProps) => {
const { _ } = useLingui();
const parser = new UAParser();
const searchParams = useSearchParams();
const updateSearchParams = useUpdateSearchParams();
@ -70,64 +71,70 @@ export const DocumentLogsDataTable = ({ documentId }: DocumentLogsDataTableProps
totalPages: 1,
};
const columns = useMemo(() => {
const parser = new UAParser();
return [
{
header: _(msg`Time`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate format={dateFormat} date={row.original.createdAt} />,
},
{
header: _(msg`User`),
accessorKey: 'name',
cell: ({ row }) =>
row.original.name || row.original.email ? (
<div>
{row.original.name && (
<p className="truncate" title={row.original.name}>
{row.original.name}
</p>
)}
{row.original.email && (
<p className="truncate" title={row.original.email}>
{row.original.email}
</p>
)}
</div>
) : (
<p>N/A</p>
),
},
{
header: _(msg`Action`),
accessorKey: 'type',
cell: ({ row }) => (
<span>
{uppercaseFistLetter(formatDocumentAuditLogAction(row.original).description)}
</span>
),
},
{
header: 'IP Address',
accessorKey: 'ipAddress',
},
{
header: 'Browser',
cell: ({ row }) => {
if (!row.original.userAgent) {
return 'N/A';
}
parser.setUA(row.original.userAgent);
const result = parser.getResult();
return result.browser.name ?? 'N/A';
},
},
] satisfies DataTableColumnDef<(typeof results)['data'][number]>[];
}, []);
return (
<DataTable
columns={[
{
header: _(msg`Time`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate format={dateFormat} date={row.original.createdAt} />,
},
{
header: _(msg`User`),
accessorKey: 'name',
cell: ({ row }) =>
row.original.name || row.original.email ? (
<div>
{row.original.name && (
<p className="truncate" title={row.original.name}>
{row.original.name}
</p>
)}
{row.original.email && (
<p className="truncate" title={row.original.email}>
{row.original.email}
</p>
)}
</div>
) : (
<p>N/A</p>
),
},
{
header: _(msg`Action`),
accessorKey: 'type',
cell: ({ row }) => (
<span>
{uppercaseFistLetter(formatDocumentAuditLogAction(row.original).description)}
</span>
),
},
{
header: 'IP Address',
accessorKey: 'ipAddress',
},
{
header: 'Browser',
cell: ({ row }) => {
if (!row.original.userAgent) {
return 'N/A';
}
parser.setUA(row.original.userAgent);
const result = parser.getResult();
return result.browser.name ?? 'N/A';
},
},
]}
columns={columns}
data={results.data}
perPage={results.perPage}
currentPage={results.currentPage}

View File

@ -1,6 +1,6 @@
'use client';
import { useTransition } from 'react';
import { useMemo, useTransition } from 'react';
import { msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
@ -12,6 +12,7 @@ import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-upda
import type { FindResultSet } from '@documenso/lib/types/find-result-set';
import type { Document, Recipient, Team, User } from '@documenso/prisma/client';
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
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';
@ -47,6 +48,57 @@ export const DocumentsDataTable = ({
const updateSearchParams = useUpdateSearchParams();
const columns = useMemo(() => {
return [
{
header: _(msg`Created`),
accessorKey: 'createdAt',
cell: ({ row }) => (
<LocaleDate
date={row.original.createdAt}
format={{ ...DateTime.DATETIME_SHORT, hourCycle: 'h12' }}
/>
),
},
{
header: _(msg`Title`),
cell: ({ row }) => <DataTableTitle row={row.original} teamUrl={team?.url} />,
},
{
id: 'sender',
header: _(msg`Sender`),
cell: ({ row }) => row.original.User.name ?? row.original.User.email,
},
{
header: _(msg`Recipient`),
accessorKey: 'recipient',
cell: ({ row }) => (
<StackAvatarsWithTooltip
recipients={row.original.Recipient}
documentStatus={row.original.status}
/>
),
},
{
header: _(msg`Status`),
accessorKey: 'status',
cell: ({ row }) => <DocumentStatus status={row.getValue('status')} />,
size: 140,
},
{
header: _(msg`Actions`),
cell: ({ row }) =>
(!row.original.deletedAt ||
row.original.status === ExtendedDocumentStatus.COMPLETED) && (
<div className="flex items-center gap-x-4">
<DataTableActionButton team={team} row={row.original} />
<DataTableActionDropdown team={team} row={row.original} />
</div>
),
},
] satisfies DataTableColumnDef<(typeof results)['data'][number]>[];
}, [team]);
const onPaginationChange = (page: number, perPage: number) => {
startTransition(() => {
updateSearchParams({
@ -63,54 +115,7 @@ export const DocumentsDataTable = ({
return (
<div className="relative">
<DataTable
columns={[
{
header: _(msg`Created`),
accessorKey: 'createdAt',
cell: ({ row }) => (
<LocaleDate
date={row.original.createdAt}
format={{ ...DateTime.DATETIME_SHORT, hourCycle: 'h12' }}
/>
),
},
{
header: _(msg`Title`),
cell: ({ row }) => <DataTableTitle row={row.original} teamUrl={team?.url} />,
},
{
id: 'sender',
header: _(msg`Sender`),
cell: ({ row }) => row.original.User.name ?? row.original.User.email,
},
{
header: _(msg`Recipient`),
accessorKey: 'recipient',
cell: ({ row }) => (
<StackAvatarsWithTooltip
recipients={row.original.Recipient}
documentStatus={row.original.status}
/>
),
},
{
header: _(msg`Status`),
accessorKey: 'status',
cell: ({ row }) => <DocumentStatus status={row.getValue('status')} />,
size: 140,
},
{
header: _(msg`Actions`),
cell: ({ row }) =>
(!row.original.deletedAt ||
row.original.status === ExtendedDocumentStatus.COMPLETED) && (
<div className="flex items-center gap-x-4">
<DataTableActionButton team={team} row={row.original} />
<DataTableActionDropdown team={team} row={row.original} />
</div>
),
},
]}
columns={columns}
data={results.data}
perPage={results.perPage}
currentPage={results.currentPage}

View File

@ -1,5 +1,7 @@
'use client';
import { useMemo } from 'react';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import { msg } from '@lingui/macro';
@ -12,6 +14,7 @@ import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-upda
import { USER_SECURITY_AUDIT_LOG_MAP } from '@documenso/lib/constants/auth';
import { ZBaseTableSearchParamsSchema } from '@documenso/lib/types/search-params';
import { trpc } from '@documenso/trpc/react';
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';
@ -27,8 +30,6 @@ const dateFormat: DateTimeFormatOptions = {
export const UserSecurityActivityDataTable = () => {
const { _ } = useLingui();
const parser = new UAParser();
const pathname = usePathname();
const router = useRouter();
const searchParams = useSearchParams();
@ -63,63 +64,69 @@ export const UserSecurityActivityDataTable = () => {
totalPages: 1,
};
const columns = useMemo(() => {
const parser = new UAParser();
return [
{
header: _(msg`Date`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate format={dateFormat} date={row.original.createdAt} />,
},
{
header: _(msg`Device`),
cell: ({ row }) => {
if (!row.original.userAgent) {
return 'N/A';
}
parser.setUA(row.original.userAgent);
const result = parser.getResult();
let output = result.os.name;
if (!output) {
return 'N/A';
}
if (result.os.version) {
output += ` (${result.os.version})`;
}
return output;
},
},
{
header: _(msg`Browser`),
cell: ({ row }) => {
if (!row.original.userAgent) {
return 'N/A';
}
parser.setUA(row.original.userAgent);
const result = parser.getResult();
return result.browser.name ?? 'N/A';
},
},
{
header: 'IP Address',
accessorKey: 'ipAddress',
cell: ({ row }) => row.original.ipAddress ?? 'N/A',
},
{
header: _(msg`Action`),
accessorKey: 'type',
cell: ({ row }) => USER_SECURITY_AUDIT_LOG_MAP[row.original.type],
},
] satisfies DataTableColumnDef<(typeof results)['data'][number]>[];
}, []);
return (
<DataTable
columns={[
{
header: _(msg`Date`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate format={dateFormat} date={row.original.createdAt} />,
},
{
header: _(msg`Device`),
cell: ({ row }) => {
if (!row.original.userAgent) {
return 'N/A';
}
parser.setUA(row.original.userAgent);
const result = parser.getResult();
let output = result.os.name;
if (!output) {
return 'N/A';
}
if (result.os.version) {
output += ` (${result.os.version})`;
}
return output;
},
},
{
header: _(msg`Browser`),
cell: ({ row }) => {
if (!row.original.userAgent) {
return 'N/A';
}
parser.setUA(row.original.userAgent);
const result = parser.getResult();
return result.browser.name ?? 'N/A';
},
},
{
header: 'IP Address',
accessorKey: 'ipAddress',
cell: ({ row }) => row.original.ipAddress ?? 'N/A',
},
{
header: _(msg`Action`),
accessorKey: 'type',
cell: ({ row }) => USER_SECURITY_AUDIT_LOG_MAP[row.original.type],
},
]}
columns={columns}
data={results.data}
perPage={results.perPage}
currentPage={results.currentPage}

View File

@ -1,5 +1,7 @@
'use client';
import { useMemo } from 'react';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import { msg } from '@lingui/macro';
@ -9,6 +11,7 @@ import { DateTime } from 'luxon';
import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params';
import { ZBaseTableSearchParamsSchema } from '@documenso/lib/types/search-params';
import { trpc } from '@documenso/trpc/react';
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';
@ -52,38 +55,42 @@ export const UserPasskeysDataTable = () => {
totalPages: 1,
};
const columns = useMemo(() => {
return [
{
header: _(msg`Name`),
accessorKey: 'name',
},
{
header: _(msg`Created`),
accessorKey: 'createdAt',
cell: ({ row }) => DateTime.fromJSDate(row.original.createdAt).toRelative(),
},
{
header: _(msg`Last used`),
accessorKey: 'updatedAt',
cell: ({ row }) =>
row.original.lastUsedAt
? DateTime.fromJSDate(row.original.lastUsedAt).toRelative()
: msg`Never`,
},
{
id: 'actions',
cell: ({ row }) => (
<UserPasskeysDataTableActions
className="justify-end"
passkeyId={row.original.id}
passkeyName={row.original.name}
/>
),
},
] satisfies DataTableColumnDef<(typeof results)['data'][number]>[];
}, []);
return (
<DataTable
columns={[
{
header: _(msg`Name`),
accessorKey: 'name',
},
{
header: _(msg`Created`),
accessorKey: 'createdAt',
cell: ({ row }) => DateTime.fromJSDate(row.original.createdAt).toRelative(),
},
{
header: _(msg`Last used`),
accessorKey: 'updatedAt',
cell: ({ row }) =>
row.original.lastUsedAt
? DateTime.fromJSDate(row.original.lastUsedAt).toRelative()
: msg`Never`,
},
{
id: 'actions',
cell: ({ row }) => (
<UserPasskeysDataTableActions
className="justify-end"
passkeyId={row.original.id}
passkeyName={row.original.name}
/>
),
},
]}
columns={columns}
data={results.data}
perPage={results.perPage}
currentPage={results.currentPage}

View File

@ -1,6 +1,6 @@
'use client';
import { useTransition } from 'react';
import { useMemo, useTransition } from 'react';
import Link from 'next/link';
@ -12,6 +12,7 @@ import { useLimits } from '@documenso/ee/server-only/limits/provider/client';
import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params';
import type { FindTemplateRow } from '@documenso/lib/server-only/template/find-templates';
import { Alert, AlertDescription, AlertTitle } from '@documenso/ui/primitives/alert';
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 { Tooltip, TooltipContent, TooltipTrigger } from '@documenso/ui/primitives/tooltip';
@ -50,6 +51,116 @@ export const TemplatesDataTable = ({
const { _ } = useLingui();
const { remaining } = useLimits();
const columns = useMemo(() => {
return [
{
header: _(msg`Created`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate date={row.original.createdAt} />,
},
{
header: _(msg`Title`),
cell: ({ row }) => <DataTableTitle row={row.original} />,
},
{
header: () => (
<div className="flex flex-row items-center">
<Trans>Type</Trans>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="text-foreground max-w-md space-y-2 !p-0">
<ul className="text-muted-foreground space-y-0.5 divide-y [&>li]:p-4">
<li>
<h2 className="mb-2 flex flex-row items-center font-semibold">
<Globe2Icon className="mr-2 h-5 w-5 text-green-500 dark:text-green-300" />
<Trans>Public</Trans>
</h2>
<p>
<Trans>
Public templates are connected to your public profile. Any modifications
to public templates will also appear in your public profile.
</Trans>
</p>
</li>
<li>
<div className="mb-2 flex w-fit flex-row items-center rounded border border-neutral-300 bg-neutral-200 px-1.5 py-0.5 text-xs dark:border-neutral-500 dark:bg-neutral-600">
<Link2Icon className="mr-1 h-3 w-3" />
<Trans>direct link</Trans>
</div>
<p>
<Trans>
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.
</Trans>
</p>
</li>
<li>
<h2 className="mb-2 flex flex-row items-center font-semibold">
<LockIcon className="mr-2 h-5 w-5 text-blue-600 dark:text-blue-300" />
{teamId ? <Trans>Team Only</Trans> : <Trans>Private</Trans>}
</h2>
<p>
{teamId ? (
<Trans>
Team only templates are not linked anywhere and are visible only to
your team.
</Trans>
) : (
<Trans>Private templates can only be modified and viewed by you.</Trans>
)}
</p>
</li>
</ul>
</TooltipContent>
</Tooltip>
</div>
),
accessorKey: 'type',
cell: ({ row }) => (
<div className="flex flex-row items-center">
<TemplateType type="PRIVATE" />
{row.original.directLink?.token && (
<TemplateDirectLinkBadge
className="ml-2"
token={row.original.directLink.token}
enabled={row.original.directLink.enabled}
/>
)}
</div>
),
},
{
header: _(msg`Actions`),
accessorKey: 'actions',
cell: ({ row }) => {
return (
<div className="flex items-center gap-x-4">
<UseTemplateDialog
templateId={row.original.id}
recipients={row.original.Recipient}
documentRootPath={documentRootPath}
/>
<DataTableActionDropdown
row={row.original}
teamId={teamId}
templateRootPath={templateRootPath}
/>
</div>
);
},
},
] satisfies DataTableColumnDef<(typeof templates)[number]>[];
}, [documentRootPath, teamId, templateRootPath]);
const onPaginationChange = (page: number, perPage: number) => {
startTransition(() => {
updateSearchParams({
@ -79,113 +190,7 @@ export const TemplatesDataTable = ({
)}
<DataTable
columns={[
{
header: _(msg`Created`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate date={row.original.createdAt} />,
},
{
header: _(msg`Title`),
cell: ({ row }) => <DataTableTitle row={row.original} />,
},
{
header: () => (
<div className="flex flex-row items-center">
<Trans>Type</Trans>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="text-foreground max-w-md space-y-2 !p-0">
<ul className="text-muted-foreground space-y-0.5 divide-y [&>li]:p-4">
<li>
<h2 className="mb-2 flex flex-row items-center font-semibold">
<Globe2Icon className="mr-2 h-5 w-5 text-green-500 dark:text-green-300" />
<Trans>Public</Trans>
</h2>
<p>
<Trans>
Public templates are connected to your public profile. Any modifications
to public templates will also appear in your public profile.
</Trans>
</p>
</li>
<li>
<div className="mb-2 flex w-fit flex-row items-center rounded border border-neutral-300 bg-neutral-200 px-1.5 py-0.5 text-xs dark:border-neutral-500 dark:bg-neutral-600">
<Link2Icon className="mr-1 h-3 w-3" />
<Trans>direct link</Trans>
</div>
<p>
<Trans>
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.
</Trans>
</p>
</li>
<li>
<h2 className="mb-2 flex flex-row items-center font-semibold">
<LockIcon className="mr-2 h-5 w-5 text-blue-600 dark:text-blue-300" />
{teamId ? <Trans>Team Only</Trans> : <Trans>Private</Trans>}
</h2>
<p>
{teamId ? (
<Trans>
Team only templates are not linked anywhere and are visible only to
your team.
</Trans>
) : (
<Trans>Private templates can only be modified and viewed by you.</Trans>
)}
</p>
</li>
</ul>
</TooltipContent>
</Tooltip>
</div>
),
accessorKey: 'type',
cell: ({ row }) => (
<div className="flex flex-row items-center">
<TemplateType type="PRIVATE" />
{row.original.directLink?.token && (
<TemplateDirectLinkBadge
className="ml-2"
token={row.original.directLink.token}
enabled={row.original.directLink.enabled}
/>
)}
</div>
),
},
{
header: _(msg`Actions`),
accessorKey: 'actions',
cell: ({ row }) => {
return (
<div className="flex items-center gap-x-4">
<UseTemplateDialog
templateId={row.original.id}
recipients={row.original.Recipient}
documentRootPath={documentRootPath}
/>
<DataTableActionDropdown
row={row.original}
teamId={teamId}
templateRootPath={templateRootPath}
/>
</div>
);
},
},
]}
columns={columns}
data={templates}
perPage={perPage}
currentPage={page}

View File

@ -1,5 +1,7 @@
'use client';
import { useMemo } from 'react';
import Link from 'next/link';
import { useSearchParams } from 'next/navigation';
@ -14,6 +16,7 @@ import { canExecuteTeamAction } from '@documenso/lib/utils/teams';
import { trpc } from '@documenso/trpc/react';
import { AvatarWithText } from '@documenso/ui/primitives/avatar';
import { Button } from '@documenso/ui/primitives/button';
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';
@ -58,70 +61,74 @@ export const CurrentUserTeamsDataTable = () => {
totalPages: 1,
};
const columns = useMemo(() => {
return [
{
header: _(msg`Team`),
accessorKey: 'name',
cell: ({ row }) => (
<Link href={`/t/${row.original.url}`} scroll={false}>
<AvatarWithText
avatarSrc={`${NEXT_PUBLIC_WEBAPP_URL()}/api/avatar/${row.original.avatarImageId}`}
avatarClass="h-12 w-12"
avatarFallback={row.original.name.slice(0, 1).toUpperCase()}
primaryText={
<span className="text-foreground/80 font-semibold">{row.original.name}</span>
}
secondaryText={`${WEBAPP_BASE_URL}/t/${row.original.url}`}
/>
</Link>
),
},
{
header: _(msg`Role`),
accessorKey: 'role',
cell: ({ row }) =>
row.original.ownerUserId === row.original.currentTeamMember.userId
? 'Owner'
: _(TEAM_MEMBER_ROLE_MAP[row.original.currentTeamMember.role]),
},
{
header: _(msg`Member Since`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate date={row.original.createdAt} />,
},
{
id: 'actions',
cell: ({ row }) => (
<div className="flex justify-end space-x-2">
{canExecuteTeamAction('MANAGE_TEAM', row.original.currentTeamMember.role) && (
<Button variant="outline" asChild>
<Link href={`/t/${row.original.url}/settings`}>
<Trans>Manage</Trans>
</Link>
</Button>
)}
<LeaveTeamDialog
teamId={row.original.id}
teamName={row.original.name}
teamAvatarImageId={row.original.avatarImageId}
role={row.original.currentTeamMember.role}
trigger={
<Button
variant="destructive"
disabled={row.original.ownerUserId === row.original.currentTeamMember.userId}
onSelect={(e) => e.preventDefault()}
>
<Trans>Leave</Trans>
</Button>
}
/>
</div>
),
},
] satisfies DataTableColumnDef<(typeof results)['data'][number]>[];
}, []);
return (
<DataTable
columns={[
{
header: _(msg`Team`),
accessorKey: 'name',
cell: ({ row }) => (
<Link href={`/t/${row.original.url}`} scroll={false}>
<AvatarWithText
avatarSrc={`${NEXT_PUBLIC_WEBAPP_URL()}/api/avatar/${row.original.avatarImageId}`}
avatarClass="h-12 w-12"
avatarFallback={row.original.name.slice(0, 1).toUpperCase()}
primaryText={
<span className="text-foreground/80 font-semibold">{row.original.name}</span>
}
secondaryText={`${WEBAPP_BASE_URL}/t/${row.original.url}`}
/>
</Link>
),
},
{
header: _(msg`Role`),
accessorKey: 'role',
cell: ({ row }) =>
row.original.ownerUserId === row.original.currentTeamMember.userId
? 'Owner'
: _(TEAM_MEMBER_ROLE_MAP[row.original.currentTeamMember.role]),
},
{
header: _(msg`Member Since`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate date={row.original.createdAt} />,
},
{
id: 'actions',
cell: ({ row }) => (
<div className="flex justify-end space-x-2">
{canExecuteTeamAction('MANAGE_TEAM', row.original.currentTeamMember.role) && (
<Button variant="outline" asChild>
<Link href={`/t/${row.original.url}/settings`}>
<Trans>Manage</Trans>
</Link>
</Button>
)}
<LeaveTeamDialog
teamId={row.original.id}
teamName={row.original.name}
teamAvatarImageId={row.original.avatarImageId}
role={row.original.currentTeamMember.role}
trigger={
<Button
variant="destructive"
disabled={row.original.ownerUserId === row.original.currentTeamMember.userId}
onSelect={(e) => e.preventDefault()}
>
<Trans>Leave</Trans>
</Button>
}
/>
</div>
),
},
]}
columns={columns}
data={results.data}
perPage={results.perPage}
currentPage={results.currentPage}

View File

@ -1,6 +1,6 @@
'use client';
import { useEffect, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { useSearchParams } from 'next/navigation';
@ -12,6 +12,7 @@ import { WEBAPP_BASE_URL } from '@documenso/lib/constants/app';
import { ZBaseTableSearchParamsSchema } from '@documenso/lib/types/search-params';
import { trpc } from '@documenso/trpc/react';
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 { Skeleton } from '@documenso/ui/primitives/skeleton';
@ -59,6 +60,40 @@ export const PendingUserTeamsDataTable = () => {
totalPages: 1,
};
const columns = useMemo(() => {
return [
{
header: _(msg`Team`),
accessorKey: 'name',
cell: ({ row }) => (
<AvatarWithText
avatarClass="h-12 w-12"
avatarFallback={row.original.name.slice(0, 1).toUpperCase()}
primaryText={
<span className="text-foreground/80 font-semibold">{row.original.name}</span>
}
secondaryText={`${WEBAPP_BASE_URL}/t/${row.original.url}`}
/>
),
},
{
header: _(msg`Created on`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate date={row.original.createdAt} />,
},
{
id: 'actions',
cell: ({ row }) => (
<PendingUserTeamsDataTableActions
className="justify-end"
pendingTeamId={row.original.id}
onPayClick={setCheckoutPendingTeamId}
/>
),
},
] satisfies DataTableColumnDef<(typeof results)['data'][number]>[];
}, []);
useEffect(() => {
const searchParamCheckout = searchParams?.get('checkout');
@ -71,37 +106,7 @@ export const PendingUserTeamsDataTable = () => {
return (
<>
<DataTable
columns={[
{
header: _(msg`Team`),
accessorKey: 'name',
cell: ({ row }) => (
<AvatarWithText
avatarClass="h-12 w-12"
avatarFallback={row.original.name.slice(0, 1).toUpperCase()}
primaryText={
<span className="text-foreground/80 font-semibold">{row.original.name}</span>
}
secondaryText={`${WEBAPP_BASE_URL}/t/${row.original.url}`}
/>
),
},
{
header: _(msg`Created on`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate date={row.original.createdAt} />,
},
{
id: 'actions',
cell: ({ row }) => (
<PendingUserTeamsDataTableActions
className="justify-end"
pendingTeamId={row.original.id}
onPayClick={setCheckoutPendingTeamId}
/>
),
},
]}
columns={columns}
data={results.data}
perPage={results.perPage}
currentPage={results.currentPage}

View File

@ -1,5 +1,7 @@
'use client';
import { useMemo } from 'react';
import Link from 'next/link';
import { Plural, Trans, msg } from '@lingui/macro';
@ -9,6 +11,7 @@ import { DateTime } from 'luxon';
import { trpc } from '@documenso/trpc/react';
import { Button } from '@documenso/ui/primitives/button';
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';
@ -46,72 +49,76 @@ export const TeamBillingInvoicesDataTable = ({ teamId }: TeamBillingInvoicesData
totalPages: 1,
};
const columns = useMemo(() => {
return [
{
header: _(msg`Invoice`),
accessorKey: 'created',
cell: ({ row }) => (
<div className="flex max-w-xs items-center gap-2">
<File className="h-6 w-6" />
<div className="flex flex-col text-sm">
<span className="text-foreground/80 font-semibold">
{DateTime.fromSeconds(row.original.created).toFormat('MMMM yyyy')}
</span>
<span className="text-muted-foreground">
<Plural value={row.original.quantity} one="# Seat" other="# Seats" />
</span>
</div>
</div>
),
},
{
header: _(msg`Status`),
accessorKey: 'status',
cell: ({ row }) => {
const { status, paid } = row.original;
if (!status) {
return paid ? <Trans>Paid</Trans> : <Trans>Unpaid</Trans>;
}
return status.charAt(0).toUpperCase() + status.slice(1);
},
},
{
header: _(msg`Amount`),
accessorKey: 'total',
cell: ({ row }) => formatCurrency(row.original.currency, row.original.total / 100),
},
{
id: 'actions',
cell: ({ row }) => (
<div className="flex justify-end space-x-2">
<Button
variant="outline"
asChild
disabled={typeof row.original.hostedInvoicePdf !== 'string'}
>
<Link href={row.original.hostedInvoicePdf ?? ''} target="_blank">
<Trans>View</Trans>
</Link>
</Button>
<Button
variant="outline"
asChild
disabled={typeof row.original.hostedInvoicePdf !== 'string'}
>
<Link href={row.original.invoicePdf ?? ''} target="_blank">
<Trans>Download</Trans>
</Link>
</Button>
</div>
),
},
] satisfies DataTableColumnDef<(typeof results)['data'][number]>[];
}, []);
return (
<DataTable
columns={[
{
header: _(msg`Invoice`),
accessorKey: 'created',
cell: ({ row }) => (
<div className="flex max-w-xs items-center gap-2">
<File className="h-6 w-6" />
<div className="flex flex-col text-sm">
<span className="text-foreground/80 font-semibold">
{DateTime.fromSeconds(row.original.created).toFormat('MMMM yyyy')}
</span>
<span className="text-muted-foreground">
<Plural value={row.original.quantity} one="# Seat" other="# Seats" />
</span>
</div>
</div>
),
},
{
header: _(msg`Status`),
accessorKey: 'status',
cell: ({ row }) => {
const { status, paid } = row.original;
if (!status) {
return paid ? <Trans>Paid</Trans> : <Trans>Unpaid</Trans>;
}
return status.charAt(0).toUpperCase() + status.slice(1);
},
},
{
header: _(msg`Amount`),
accessorKey: 'total',
cell: ({ row }) => formatCurrency(row.original.currency, row.original.total / 100),
},
{
id: 'actions',
cell: ({ row }) => (
<div className="flex justify-end space-x-2">
<Button
variant="outline"
asChild
disabled={typeof row.original.hostedInvoicePdf !== 'string'}
>
<Link href={row.original.hostedInvoicePdf ?? ''} target="_blank">
<Trans>View</Trans>
</Link>
</Button>
<Button
variant="outline"
asChild
disabled={typeof row.original.hostedInvoicePdf !== 'string'}
>
<Link href={row.original.invoicePdf ?? ''} target="_blank">
<Trans>Download</Trans>
</Link>
</Button>
</div>
),
},
]}
columns={columns}
data={results.data}
perPage={results.perPage}
currentPage={results.currentPage}

View File

@ -1,5 +1,7 @@
'use client';
import { useMemo } from 'react';
import { useSearchParams } from 'next/navigation';
import { Trans, msg } from '@lingui/macro';
@ -11,6 +13,7 @@ import { TEAM_MEMBER_ROLE_MAP } from '@documenso/lib/constants/teams';
import { ZBaseTableSearchParamsSchema } from '@documenso/lib/types/search-params';
import { trpc } from '@documenso/trpc/react';
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 {
@ -102,74 +105,78 @@ export const TeamMemberInvitesDataTable = ({ teamId }: TeamMemberInvitesDataTabl
totalPages: 1,
};
const columns = useMemo(() => {
return [
{
header: _(msg`Team Member`),
cell: ({ row }) => {
return (
<AvatarWithText
avatarClass="h-12 w-12"
avatarFallback={row.original.email.slice(0, 1).toUpperCase()}
primaryText={
<span className="text-foreground/80 font-semibold">{row.original.email}</span>
}
/>
);
},
},
{
header: _(msg`Role`),
accessorKey: 'role',
cell: ({ row }) => _(TEAM_MEMBER_ROLE_MAP[row.original.role]) ?? row.original.role,
},
{
header: _(msg`Invited At`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate date={row.original.createdAt} />,
},
{
header: _(msg`Actions`),
cell: ({ row }) => (
<DropdownMenu>
<DropdownMenuTrigger>
<MoreHorizontal className="text-muted-foreground h-5 w-5" />
</DropdownMenuTrigger>
<DropdownMenuContent className="w-52" align="start" forceMount>
<DropdownMenuLabel>
<Trans>Actions</Trans>
</DropdownMenuLabel>
<DropdownMenuItem
onClick={async () =>
resendTeamMemberInvitation({
teamId,
invitationId: row.original.id,
})
}
>
<History className="mr-2 h-4 w-4" />
<Trans>Resend</Trans>
</DropdownMenuItem>
<DropdownMenuItem
onClick={async () =>
deleteTeamMemberInvitations({
teamId,
invitationIds: [row.original.id],
})
}
>
<Trash2 className="mr-2 h-4 w-4" />
<Trans>Remove</Trans>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
),
},
] satisfies DataTableColumnDef<(typeof results)['data'][number]>[];
}, []);
return (
<DataTable
columns={[
{
header: _(msg`Team Member`),
cell: ({ row }) => {
return (
<AvatarWithText
avatarClass="h-12 w-12"
avatarFallback={row.original.email.slice(0, 1).toUpperCase()}
primaryText={
<span className="text-foreground/80 font-semibold">{row.original.email}</span>
}
/>
);
},
},
{
header: _(msg`Role`),
accessorKey: 'role',
cell: ({ row }) => _(TEAM_MEMBER_ROLE_MAP[row.original.role]) ?? row.original.role,
},
{
header: _(msg`Invited At`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate date={row.original.createdAt} />,
},
{
header: _(msg`Actions`),
cell: ({ row }) => (
<DropdownMenu>
<DropdownMenuTrigger>
<MoreHorizontal className="text-muted-foreground h-5 w-5" />
</DropdownMenuTrigger>
<DropdownMenuContent className="w-52" align="start" forceMount>
<DropdownMenuLabel>
<Trans>Actions</Trans>
</DropdownMenuLabel>
<DropdownMenuItem
onClick={async () =>
resendTeamMemberInvitation({
teamId,
invitationId: row.original.id,
})
}
>
<History className="mr-2 h-4 w-4" />
<Trans>Resend</Trans>
</DropdownMenuItem>
<DropdownMenuItem
onClick={async () =>
deleteTeamMemberInvitations({
teamId,
invitationIds: [row.original.id],
})
}
>
<Trash2 className="mr-2 h-4 w-4" />
<Trans>Remove</Trans>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
),
},
]}
columns={columns}
data={results.data}
perPage={results.perPage}
currentPage={results.currentPage}

View File

@ -1,5 +1,7 @@
'use client';
import { useMemo } from 'react';
import { useSearchParams } from 'next/navigation';
import { Trans, msg } from '@lingui/macro';
@ -14,6 +16,7 @@ import { isTeamRoleWithinUserHierarchy } from '@documenso/lib/utils/teams';
import type { TeamMemberRole } from '@documenso/prisma/client';
import { trpc } from '@documenso/trpc/react';
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 {
@ -79,100 +82,104 @@ export const TeamMembersDataTable = ({
totalPages: 1,
};
const columns = useMemo(() => {
return [
{
header: _(msg`Team Member`),
cell: ({ row }) => {
const avatarFallbackText = row.original.user.name
? extractInitials(row.original.user.name)
: row.original.user.email.slice(0, 1).toUpperCase();
return (
<AvatarWithText
avatarClass="h-12 w-12"
avatarFallback={avatarFallbackText}
primaryText={
<span className="text-foreground/80 font-semibold">{row.original.user.name}</span>
}
secondaryText={row.original.user.email}
/>
);
},
},
{
header: _(msg`Role`),
accessorKey: 'role',
cell: ({ row }) =>
teamOwnerUserId === row.original.userId
? 'Owner'
: _(TEAM_MEMBER_ROLE_MAP[row.original.role]),
},
{
header: _(msg`Member Since`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate date={row.original.createdAt} />,
},
{
header: _(msg`Actions`),
cell: ({ row }) => (
<DropdownMenu>
<DropdownMenuTrigger>
<MoreHorizontal className="text-muted-foreground h-5 w-5" />
</DropdownMenuTrigger>
<DropdownMenuContent className="w-52" align="start" forceMount>
<DropdownMenuLabel>
<Trans>Actions</Trans>
</DropdownMenuLabel>
<UpdateTeamMemberDialog
currentUserTeamRole={currentUserTeamRole}
teamId={row.original.teamId}
teamMemberId={row.original.id}
teamMemberName={row.original.user.name ?? ''}
teamMemberRole={row.original.role}
trigger={
<DropdownMenuItem
disabled={
teamOwnerUserId === row.original.userId ||
!isTeamRoleWithinUserHierarchy(currentUserTeamRole, row.original.role)
}
onSelect={(e) => e.preventDefault()}
title="Update team member role"
>
<Edit className="mr-2 h-4 w-4" />
<Trans>Update role</Trans>
</DropdownMenuItem>
}
/>
<DeleteTeamMemberDialog
teamId={teamId}
teamName={teamName}
teamMemberId={row.original.id}
teamMemberName={row.original.user.name ?? ''}
teamMemberEmail={row.original.user.email}
trigger={
<DropdownMenuItem
onSelect={(e) => e.preventDefault()}
disabled={
teamOwnerUserId === row.original.userId ||
!isTeamRoleWithinUserHierarchy(currentUserTeamRole, row.original.role)
}
title={_(msg`Remove team member`)}
>
<Trash2 className="mr-2 h-4 w-4" />
<Trans>Remove</Trans>
</DropdownMenuItem>
}
/>
</DropdownMenuContent>
</DropdownMenu>
),
},
] satisfies DataTableColumnDef<(typeof results)['data'][number]>[];
}, []);
return (
<DataTable
columns={[
{
header: _(msg`Team Member`),
cell: ({ row }) => {
const avatarFallbackText = row.original.user.name
? extractInitials(row.original.user.name)
: row.original.user.email.slice(0, 1).toUpperCase();
return (
<AvatarWithText
avatarClass="h-12 w-12"
avatarFallback={avatarFallbackText}
primaryText={
<span className="text-foreground/80 font-semibold">{row.original.user.name}</span>
}
secondaryText={row.original.user.email}
/>
);
},
},
{
header: _(msg`Role`),
accessorKey: 'role',
cell: ({ row }) =>
teamOwnerUserId === row.original.userId
? 'Owner'
: _(TEAM_MEMBER_ROLE_MAP[row.original.role]),
},
{
header: _(msg`Member Since`),
accessorKey: 'createdAt',
cell: ({ row }) => <LocaleDate date={row.original.createdAt} />,
},
{
header: _(msg`Actions`),
cell: ({ row }) => (
<DropdownMenu>
<DropdownMenuTrigger>
<MoreHorizontal className="text-muted-foreground h-5 w-5" />
</DropdownMenuTrigger>
<DropdownMenuContent className="w-52" align="start" forceMount>
<DropdownMenuLabel>
<Trans>Actions</Trans>
</DropdownMenuLabel>
<UpdateTeamMemberDialog
currentUserTeamRole={currentUserTeamRole}
teamId={row.original.teamId}
teamMemberId={row.original.id}
teamMemberName={row.original.user.name ?? ''}
teamMemberRole={row.original.role}
trigger={
<DropdownMenuItem
disabled={
teamOwnerUserId === row.original.userId ||
!isTeamRoleWithinUserHierarchy(currentUserTeamRole, row.original.role)
}
onSelect={(e) => e.preventDefault()}
title="Update team member role"
>
<Edit className="mr-2 h-4 w-4" />
<Trans>Update role</Trans>
</DropdownMenuItem>
}
/>
<DeleteTeamMemberDialog
teamId={teamId}
teamName={teamName}
teamMemberId={row.original.id}
teamMemberName={row.original.user.name ?? ''}
teamMemberEmail={row.original.user.email}
trigger={
<DropdownMenuItem
onSelect={(e) => e.preventDefault()}
disabled={
teamOwnerUserId === row.original.userId ||
!isTeamRoleWithinUserHierarchy(currentUserTeamRole, row.original.role)
}
title={_(msg`Remove team member`)}
>
<Trash2 className="mr-2 h-4 w-4" />
<Trans>Remove</Trans>
</DropdownMenuItem>
}
/>
</DropdownMenuContent>
</DropdownMenu>
),
},
]}
columns={columns}
data={results.data}
perPage={results.perPage}
currentPage={results.currentPage}

View File

@ -32,8 +32,12 @@ test('[TEAMS]: update team member role', async ({ page }) => {
await page.getByRole('combobox').click();
await page.getByLabel('Manager').click();
await page.getByRole('button', { name: 'Update' }).click();
// TODO: Remove me, but i don't care for now
await page.reload();
await expect(
page.getByRole('row').filter({ hasText: teamMemberToUpdate.user.email }),
page.getByRole('row').filter({ hasText: teamMemberToUpdate.user.email }).first(),
).toContainText('Manager');
});

View File

@ -175,7 +175,7 @@ msgstr ""
msgid "Checkbox values"
msgstr ""
#: packages/ui/primitives/data-table.tsx:154
#: packages/ui/primitives/data-table.tsx:156
msgid "Clear filters"
msgstr ""
@ -398,7 +398,7 @@ msgstr ""
msgid "No restrictions"
msgstr ""
#: packages/ui/primitives/data-table.tsx:146
#: packages/ui/primitives/data-table.tsx:148
msgid "No results found"
msgstr ""
@ -572,7 +572,7 @@ msgstr ""
msgid "Something went wrong"
msgstr ""
#: packages/ui/primitives/data-table.tsx:134
#: packages/ui/primitives/data-table.tsx:136
msgid "Something went wrong."
msgstr ""

View File

@ -51,7 +51,7 @@ msgstr ""
msgid "{0, plural, one {# recipient} other {# recipients}}"
msgstr ""
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:64
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:66
msgid "{0, plural, one {# Seat} other {# Seats}}"
msgstr ""
@ -190,19 +190,19 @@ msgid "Account deleted"
msgstr ""
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:105
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:104
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:106
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:121
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:118
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:120
msgid "Action"
msgstr ""
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:103
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:168
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:133
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:142
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:118
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:127
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:89
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:141
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:135
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:144
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:120
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:129
msgid "Actions"
msgstr ""
@ -343,7 +343,7 @@ msgstr ""
msgid "Already have an account? <0>Sign in instead</0>"
msgstr ""
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:84
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:86
msgid "Amount"
msgstr ""
@ -632,7 +632,7 @@ msgstr ""
msgid "Billing"
msgstr ""
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:99
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:101
msgid "Browser"
msgstr ""
@ -953,11 +953,11 @@ msgstr ""
msgid "Create your account and start using state-of-the-art document signing. Open and beautiful signing is within your grasp."
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:72
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:63
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:48
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:68
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:63
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:84
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:54
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:65
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:57
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:276
msgid "Created"
msgstr ""
@ -971,7 +971,7 @@ msgid "Created by"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:49
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:90
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:80
msgid "Created on"
msgstr ""
@ -998,7 +998,7 @@ msgstr ""
msgid "Dark Mode"
msgstr ""
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:70
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:72
#: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:148
msgid "Date"
msgstr ""
@ -1096,11 +1096,11 @@ msgstr ""
#~ msgid "Deleting document"
#~ msgstr ""
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:75
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:77
msgid "Device"
msgstr ""
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:119
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:92
#: apps/web/src/app/(dashboard)/templates/template-direct-link-badge.tsx:46
msgid "direct link"
msgstr ""
@ -1125,7 +1125,7 @@ msgstr ""
msgid "Direct link signing has been enabled"
msgstr ""
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:123
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:96
msgid "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."
msgstr ""
@ -1227,7 +1227,7 @@ msgstr ""
msgid "Document inbox"
msgstr ""
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:68
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:179
msgid "Document Limit Exceeded!"
msgstr ""
@ -1292,7 +1292,7 @@ msgid "Document will be permanently deleted"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/nav.tsx:65
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:124
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:92
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:113
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:82
#: apps/web/src/app/(dashboard)/documents/[id]/loading.tsx:16
@ -1324,7 +1324,7 @@ msgstr ""
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:120
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:141
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:160
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:108
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:110
#: apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx:185
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:107
msgid "Download"
@ -1380,9 +1380,9 @@ msgstr ""
msgid "Edit webhook"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:119
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:166
#: apps/web/src/app/(dashboard)/admin/users/[id]/page.tsx:114
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:103
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:71
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:213
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:220
#: apps/web/src/app/(recipient)/d/[token]/configure-direct-template.tsx:118
@ -1532,7 +1532,7 @@ msgstr ""
msgid "Failed to reseal document"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:78
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:125
msgid "Failed to update recipient"
msgstr ""
@ -1541,7 +1541,7 @@ msgstr ""
msgid "Failed to update webhook"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:143
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:190
msgid "Fields"
msgstr ""
@ -1660,7 +1660,7 @@ msgstr ""
msgid "Information"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:160
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:78
msgid "Inserted"
msgstr ""
@ -1694,11 +1694,11 @@ msgstr ""
msgid "Invitation declined"
msgstr ""
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:79
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:82
msgid "Invitation has been deleted"
msgstr ""
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:62
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:65
msgid "Invitation has been resent"
msgstr ""
@ -1718,11 +1718,11 @@ msgstr ""
msgid "Invite team members"
msgstr ""
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:128
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:130
msgid "Invited At"
msgstr ""
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:53
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:55
msgid "Invoice"
msgstr ""
@ -1766,12 +1766,12 @@ msgstr ""
msgid "Last updated at"
msgstr ""
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:69
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:71
msgid "Last used"
msgstr ""
#: apps/web/src/components/(teams)/dialogs/leave-team-dialog.tsx:111
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:117
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:119
msgid "Leave"
msgstr ""
@ -1825,7 +1825,7 @@ msgstr ""
msgid "Login"
msgstr ""
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:101
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:103
msgid "Manage"
msgstr ""
@ -1905,8 +1905,8 @@ msgstr ""
msgid "MAU (had document completed)"
msgstr ""
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:90
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:113
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:92
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:115
msgid "Member Since"
msgstr ""
@ -1957,11 +1957,11 @@ msgstr ""
msgid "My templates"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:101
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:148
#: apps/web/src/app/(dashboard)/admin/users/[id]/page.tsx:99
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:98
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:66
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:144
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:59
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:61
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:235
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:242
#: apps/web/src/app/(signing)/sign/[token]/complete/claim-account.tsx:119
@ -1976,7 +1976,7 @@ msgstr ""
msgid "Need to sign documents?"
msgstr ""
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:74
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:76
msgid "Never"
msgstr ""
@ -2112,12 +2112,12 @@ msgstr ""
msgid "Otherwise, the document will be created as a draft."
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:96
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:87
#: apps/web/src/components/(dashboard)/layout/menu-switcher.tsx:76
msgid "Owner"
msgstr ""
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:77
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:79
msgid "Paid"
msgstr ""
@ -2304,12 +2304,12 @@ msgstr ""
msgid "Preview and configure template."
msgstr ""
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:133
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:106
#: apps/web/src/components/formatter/template-type.tsx:22
msgid "Private"
msgstr ""
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:143
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:116
msgid "Private templates can only be modified and viewed by you."
msgstr ""
@ -2333,7 +2333,7 @@ msgstr ""
msgid "Profile updated"
msgstr ""
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:106
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:79
#: apps/web/src/components/formatter/template-type.tsx:27
msgid "Public"
msgstr ""
@ -2354,7 +2354,7 @@ msgstr ""
msgid "Public profile username"
msgstr ""
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:110
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:83
msgid "Public templates are connected to your public profile. Any modifications to public templates will also appear in your public profile."
msgstr ""
@ -2375,12 +2375,12 @@ msgstr ""
msgid "Recent activity"
msgstr ""
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:87
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:73
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:280
msgid "Recipient"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:71
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:118
msgid "Recipient updated"
msgstr ""
@ -2422,8 +2422,8 @@ msgstr ""
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-email-dropdown.tsx:89
#: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:159
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:54
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:166
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:167
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:168
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:169
#: apps/web/src/components/forms/avatar-image.tsx:169
msgid "Remove"
msgstr ""
@ -2432,7 +2432,7 @@ msgstr ""
msgid "Remove team email"
msgstr ""
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:164
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:166
msgid "Remove team member"
msgstr ""
@ -2450,7 +2450,7 @@ msgid "Reseal document"
msgstr ""
#: apps/web/src/app/(dashboard)/documents/_action-items/resend-document.tsx:118
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:154
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:156
msgid "Resend"
msgstr ""
@ -2524,14 +2524,14 @@ msgstr ""
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:283
#: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:318
#: apps/web/src/components/(teams)/dialogs/update-team-member-dialog.tsx:163
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:82
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:123
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:105
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:84
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:125
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:107
msgid "Role"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/users/[id]/page.tsx:131
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:108
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:76
msgid "Roles"
msgstr ""
@ -2548,11 +2548,11 @@ msgstr ""
msgid "Search"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:63
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:141
msgid "Search by document title"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:86
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:144
msgid "Search by name or email"
msgstr ""
@ -2612,7 +2612,7 @@ msgstr ""
msgid "Send reminder"
msgstr ""
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:83
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:69
msgid "Sender"
msgstr ""
@ -2736,7 +2736,7 @@ msgstr ""
msgid "Sign Up with OIDC"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:170
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:88
#: apps/web/src/app/(recipient)/d/[token]/sign-direct-template.tsx:338
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:197
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:227
@ -2812,8 +2812,8 @@ msgstr ""
#: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:64
#: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:83
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:33
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:67
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:84
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:70
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:87
#: apps/web/src/components/(teams)/team-billing-portal-button.tsx:29
msgid "Something went wrong"
msgstr ""
@ -2855,10 +2855,10 @@ msgstr ""
msgid "Stats"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:91
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:82
#: apps/web/src/app/(dashboard)/admin/subscriptions/page.tsx:32
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:97
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:71
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:83
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:73
msgid "Status"
msgstr ""
@ -2866,7 +2866,7 @@ msgstr ""
msgid "Subscribe"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:113
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:81
msgid "Subscription"
msgstr ""
@ -2898,8 +2898,8 @@ msgstr ""
#: apps/web/src/components/(teams)/dialogs/update-team-member-dialog.tsx:92
#: apps/web/src/components/(teams)/forms/update-team-form.tsx:68
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:27
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:61
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:78
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:64
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:81
#: apps/web/src/components/forms/public-profile-form.tsx:80
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:135
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:172
@ -2914,8 +2914,8 @@ msgstr ""
msgid "System Theme"
msgstr ""
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:65
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:76
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:67
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:66
msgid "Team"
msgstr ""
@ -2957,8 +2957,8 @@ msgstr ""
msgid "Team invitations have been sent."
msgstr ""
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:109
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:86
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:111
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:88
msgid "Team Member"
msgstr ""
@ -2967,11 +2967,11 @@ msgstr ""
msgid "Team Name"
msgstr ""
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:133
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:106
msgid "Team Only"
msgstr ""
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:138
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:111
msgid "Team only templates are not linked anywhere and are visible only to your team."
msgstr ""
@ -3133,7 +3133,7 @@ msgstr ""
msgid "The public name for your template"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:72
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:119
msgid "The recipient has been updated successfully"
msgstr ""
@ -3307,7 +3307,7 @@ msgstr ""
msgid "This username is already taken"
msgstr ""
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:77
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:79
msgid "Time"
msgstr ""
@ -3315,9 +3315,9 @@ msgstr ""
msgid "Time zone"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:77
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:78
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:89
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:68
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:64
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:62
msgid "Title"
msgstr ""
@ -3450,8 +3450,8 @@ msgstr ""
msgid "Two-factor authentication has been disabled for your account. You will no longer be required to enter a code from your authenticator app when signing in."
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:155
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:95
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:73
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:68
msgid "Type"
msgstr ""
@ -3483,7 +3483,7 @@ msgstr ""
msgid "Unable to decline this team invitation at this time."
msgstr ""
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:85
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:88
msgid "Unable to delete invitation. Please try again."
msgstr ""
@ -3516,7 +3516,7 @@ msgstr ""
msgid "Unable to remove team email at this time. Please try again."
msgstr ""
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:68
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:71
msgid "Unable to resend invitation. Please try again."
msgstr ""
@ -3551,7 +3551,7 @@ msgstr ""
msgid "Unknown error"
msgstr ""
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:77
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:79
msgid "Unpaid"
msgstr ""
@ -3580,11 +3580,11 @@ msgstr ""
msgid "Update profile"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:133
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:180
msgid "Update Recipient"
msgstr ""
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:146
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:148
msgid "Update role"
msgstr ""
@ -3651,7 +3651,7 @@ msgstr ""
msgid "Use Template"
msgstr ""
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:82
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:84
msgid "User"
msgstr ""
@ -3671,7 +3671,7 @@ msgstr ""
msgid "Users"
msgstr ""
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:165
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:83
msgid "Value"
msgstr ""
@ -3703,7 +3703,7 @@ msgstr ""
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:126
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:135
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:130
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:98
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:100
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:168
msgid "View"
msgstr ""
@ -4161,7 +4161,7 @@ msgstr ""
msgid "You have reached your document limit."
msgstr ""
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:71
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:182
msgid "You have reached your document limit. <0>Upgrade your account to continue!</0>"
msgstr ""

View File

@ -170,7 +170,7 @@ msgstr "Checkbox"
msgid "Checkbox values"
msgstr "Checkbox values"
#: packages/ui/primitives/data-table.tsx:154
#: packages/ui/primitives/data-table.tsx:156
msgid "Clear filters"
msgstr "Clear filters"
@ -393,7 +393,7 @@ msgstr "No recipients with this role"
msgid "No restrictions"
msgstr "No restrictions"
#: packages/ui/primitives/data-table.tsx:146
#: packages/ui/primitives/data-table.tsx:148
msgid "No results found"
msgstr "No results found"
@ -567,7 +567,7 @@ msgstr "Some signers have not been assigned a signature field. Please assign at
msgid "Something went wrong"
msgstr "Something went wrong"
#: packages/ui/primitives/data-table.tsx:134
#: packages/ui/primitives/data-table.tsx:136
msgid "Something went wrong."
msgstr "Something went wrong."

View File

@ -46,7 +46,7 @@ msgstr "{0, plural, one {# character over the limit} other {# characters over th
msgid "{0, plural, one {# recipient} other {# recipients}}"
msgstr "{0, plural, one {# recipient} other {# recipients}}"
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:64
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:66
msgid "{0, plural, one {# Seat} other {# Seats}}"
msgstr "{0, plural, one {# Seat} other {# Seats}}"
@ -185,19 +185,19 @@ msgid "Account deleted"
msgstr "Account deleted"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:105
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:104
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:106
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:121
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:118
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:120
msgid "Action"
msgstr "Action"
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:103
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:168
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:133
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:142
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:118
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:127
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:89
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:141
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:135
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:144
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:120
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:129
msgid "Actions"
msgstr "Actions"
@ -338,7 +338,7 @@ msgstr "Allows authenticating using biometrics, password managers, hardware keys
msgid "Already have an account? <0>Sign in instead</0>"
msgstr "Already have an account? <0>Sign in instead</0>"
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:84
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:86
msgid "Amount"
msgstr "Amount"
@ -627,7 +627,7 @@ msgstr "Basic details"
msgid "Billing"
msgstr "Billing"
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:99
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:101
msgid "Browser"
msgstr "Browser"
@ -948,11 +948,11 @@ msgstr "Create your account and start using state-of-the-art document signing."
msgid "Create your account and start using state-of-the-art document signing. Open and beautiful signing is within your grasp."
msgstr "Create your account and start using state-of-the-art document signing. Open and beautiful signing is within your grasp."
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:72
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:63
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:48
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:68
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:63
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:84
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:54
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:65
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:57
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:276
msgid "Created"
msgstr "Created"
@ -966,7 +966,7 @@ msgid "Created by"
msgstr "Created by"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:49
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:90
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:80
msgid "Created on"
msgstr "Created on"
@ -993,7 +993,7 @@ msgstr "Daily"
msgid "Dark Mode"
msgstr "Dark Mode"
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:70
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:72
#: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:148
msgid "Date"
msgstr "Date"
@ -1091,11 +1091,11 @@ msgstr "Deleting account..."
#~ msgid "Deleting document"
#~ msgstr "Deleting document"
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:75
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:77
msgid "Device"
msgstr "Device"
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:119
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:92
#: apps/web/src/app/(dashboard)/templates/template-direct-link-badge.tsx:46
msgid "direct link"
msgstr "direct link"
@ -1120,7 +1120,7 @@ msgstr "Direct link signing has been disabled"
msgid "Direct link signing has been enabled"
msgstr "Direct link signing has been enabled"
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:123
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:96
msgid "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."
msgstr "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."
@ -1222,7 +1222,7 @@ msgstr "Document ID"
msgid "Document inbox"
msgstr "Document inbox"
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:68
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:179
msgid "Document Limit Exceeded!"
msgstr "Document Limit Exceeded!"
@ -1287,7 +1287,7 @@ msgid "Document will be permanently deleted"
msgstr "Document will be permanently deleted"
#: apps/web/src/app/(dashboard)/admin/nav.tsx:65
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:124
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:92
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view.tsx:113
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:82
#: apps/web/src/app/(dashboard)/documents/[id]/loading.tsx:16
@ -1319,7 +1319,7 @@ msgstr "Don't have an account? <0>Sign up</0>"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:120
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:141
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:160
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:108
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:110
#: apps/web/src/components/forms/2fa/enable-authenticator-app-dialog.tsx:185
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:107
msgid "Download"
@ -1375,9 +1375,9 @@ msgstr "Edit"
msgid "Edit webhook"
msgstr "Edit webhook"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:119
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:166
#: apps/web/src/app/(dashboard)/admin/users/[id]/page.tsx:114
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:103
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:71
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:213
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:220
#: apps/web/src/app/(recipient)/d/[token]/configure-direct-template.tsx:118
@ -1527,7 +1527,7 @@ msgstr "Expires on <0/>"
msgid "Failed to reseal document"
msgstr "Failed to reseal document"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:78
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:125
msgid "Failed to update recipient"
msgstr "Failed to update recipient"
@ -1536,7 +1536,7 @@ msgstr "Failed to update recipient"
msgid "Failed to update webhook"
msgstr "Failed to update webhook"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:143
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:190
msgid "Fields"
msgstr "Fields"
@ -1655,7 +1655,7 @@ msgstr "Inbox documents"
msgid "Information"
msgstr "Information"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:160
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:78
msgid "Inserted"
msgstr "Inserted"
@ -1689,11 +1689,11 @@ msgstr "Invitation accepted!"
msgid "Invitation declined"
msgstr "Invitation declined"
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:79
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:82
msgid "Invitation has been deleted"
msgstr "Invitation has been deleted"
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:62
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:65
msgid "Invitation has been resent"
msgstr "Invitation has been resent"
@ -1713,11 +1713,11 @@ msgstr "Invite Members"
msgid "Invite team members"
msgstr "Invite team members"
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:128
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:130
msgid "Invited At"
msgstr "Invited At"
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:53
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:55
msgid "Invoice"
msgstr "Invoice"
@ -1761,12 +1761,12 @@ msgstr "Last updated"
msgid "Last updated at"
msgstr "Last updated at"
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:69
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:71
msgid "Last used"
msgstr "Last used"
#: apps/web/src/components/(teams)/dialogs/leave-team-dialog.tsx:111
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:117
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:119
msgid "Leave"
msgstr "Leave"
@ -1820,7 +1820,7 @@ msgstr "Loading..."
msgid "Login"
msgstr "Login"
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:101
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:103
msgid "Manage"
msgstr "Manage"
@ -1900,8 +1900,8 @@ msgstr "MAU (created document)"
msgid "MAU (had document completed)"
msgstr "MAU (had document completed)"
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:90
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:113
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:92
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:115
msgid "Member Since"
msgstr "Member Since"
@ -1952,11 +1952,11 @@ msgstr "Moving..."
msgid "My templates"
msgstr "My templates"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:101
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:148
#: apps/web/src/app/(dashboard)/admin/users/[id]/page.tsx:99
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:98
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:66
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:144
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:59
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:61
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:235
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:242
#: apps/web/src/app/(signing)/sign/[token]/complete/claim-account.tsx:119
@ -1971,7 +1971,7 @@ msgstr "Name"
msgid "Need to sign documents?"
msgstr "Need to sign documents?"
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:74
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:76
msgid "Never"
msgstr "Never"
@ -2107,12 +2107,12 @@ msgstr "Or continue with"
msgid "Otherwise, the document will be created as a draft."
msgstr "Otherwise, the document will be created as a draft."
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:96
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:87
#: apps/web/src/components/(dashboard)/layout/menu-switcher.tsx:76
msgid "Owner"
msgstr "Owner"
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:77
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:79
msgid "Paid"
msgstr "Paid"
@ -2299,12 +2299,12 @@ msgstr "Preferences"
msgid "Preview and configure template."
msgstr "Preview and configure template."
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:133
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:106
#: apps/web/src/components/formatter/template-type.tsx:22
msgid "Private"
msgstr "Private"
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:143
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:116
msgid "Private templates can only be modified and viewed by you."
msgstr "Private templates can only be modified and viewed by you."
@ -2328,7 +2328,7 @@ msgstr "Profile is currently <0>visible</0>."
msgid "Profile updated"
msgstr "Profile updated"
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:106
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:79
#: apps/web/src/components/formatter/template-type.tsx:27
msgid "Public"
msgstr "Public"
@ -2349,7 +2349,7 @@ msgstr "Public profile URL"
msgid "Public profile username"
msgstr "Public profile username"
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:110
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:83
msgid "Public templates are connected to your public profile. Any modifications to public templates will also appear in your public profile."
msgstr "Public templates are connected to your public profile. Any modifications to public templates will also appear in your public profile."
@ -2370,12 +2370,12 @@ msgstr "Reauthentication is required to sign this field"
msgid "Recent activity"
msgstr "Recent activity"
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:87
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:73
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:280
msgid "Recipient"
msgstr "Recipient"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:71
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:118
msgid "Recipient updated"
msgstr "Recipient updated"
@ -2417,8 +2417,8 @@ msgstr "Remembered your password? <0>Sign In</0>"
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-email-dropdown.tsx:89
#: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:159
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:54
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:166
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:167
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:168
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:169
#: apps/web/src/components/forms/avatar-image.tsx:169
msgid "Remove"
msgstr "Remove"
@ -2427,7 +2427,7 @@ msgstr "Remove"
msgid "Remove team email"
msgstr "Remove team email"
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:164
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:166
msgid "Remove team member"
msgstr "Remove team member"
@ -2445,7 +2445,7 @@ msgid "Reseal document"
msgstr "Reseal document"
#: apps/web/src/app/(dashboard)/documents/_action-items/resend-document.tsx:118
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:154
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:156
msgid "Resend"
msgstr "Resend"
@ -2519,14 +2519,14 @@ msgstr "Revoke access"
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:283
#: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:318
#: apps/web/src/components/(teams)/dialogs/update-team-member-dialog.tsx:163
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:82
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:123
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:105
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:84
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:125
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:107
msgid "Role"
msgstr "Role"
#: apps/web/src/app/(dashboard)/admin/users/[id]/page.tsx:131
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:108
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:76
msgid "Roles"
msgstr "Roles"
@ -2543,11 +2543,11 @@ msgstr "Save"
msgid "Search"
msgstr "Search"
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:63
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:141
msgid "Search by document title"
msgstr "Search by document title"
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:86
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:144
msgid "Search by name or email"
msgstr "Search by name or email"
@ -2607,7 +2607,7 @@ msgstr "Send document"
msgid "Send reminder"
msgstr "Send reminder"
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:83
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:69
msgid "Sender"
msgstr "Sender"
@ -2731,7 +2731,7 @@ msgstr "Sign Up with Google"
msgid "Sign Up with OIDC"
msgstr "Sign Up with OIDC"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:170
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:88
#: apps/web/src/app/(recipient)/d/[token]/sign-direct-template.tsx:338
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:197
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:227
@ -2807,8 +2807,8 @@ msgstr "Site Settings"
#: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:64
#: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:83
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:33
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:67
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:84
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:70
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:87
#: apps/web/src/components/(teams)/team-billing-portal-button.tsx:29
msgid "Something went wrong"
msgstr "Something went wrong"
@ -2850,10 +2850,10 @@ msgstr "Sorry, we were unable to download the certificate. Please try again late
msgid "Stats"
msgstr "Stats"
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:91
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:82
#: apps/web/src/app/(dashboard)/admin/subscriptions/page.tsx:32
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:97
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:71
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:83
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:73
msgid "Status"
msgstr "Status"
@ -2861,7 +2861,7 @@ msgstr "Status"
msgid "Subscribe"
msgstr "Subscribe"
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:113
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:81
msgid "Subscription"
msgstr "Subscription"
@ -2893,8 +2893,8 @@ msgstr "Subscriptions"
#: apps/web/src/components/(teams)/dialogs/update-team-member-dialog.tsx:92
#: apps/web/src/components/(teams)/forms/update-team-form.tsx:68
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:27
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:61
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:78
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:64
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:81
#: apps/web/src/components/forms/public-profile-form.tsx:80
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:135
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:172
@ -2909,8 +2909,8 @@ msgstr "Successfully created passkey"
msgid "System Theme"
msgstr "System Theme"
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:65
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:76
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:67
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:66
msgid "Team"
msgstr "Team"
@ -2952,8 +2952,8 @@ msgstr "Team invitation"
msgid "Team invitations have been sent."
msgstr "Team invitations have been sent."
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:109
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:86
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:111
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:88
msgid "Team Member"
msgstr "Team Member"
@ -2962,11 +2962,11 @@ msgstr "Team Member"
msgid "Team Name"
msgstr "Team Name"
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:133
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:106
msgid "Team Only"
msgstr "Team Only"
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:138
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:111
msgid "Team only templates are not linked anywhere and are visible only to your team."
msgstr "Team only templates are not linked anywhere and are visible only to your team."
@ -3128,7 +3128,7 @@ msgstr "The public description that will be displayed with this template"
msgid "The public name for your template"
msgstr "The public name for your template"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:72
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:119
msgid "The recipient has been updated successfully"
msgstr "The recipient has been updated successfully"
@ -3302,7 +3302,7 @@ msgstr "This username has already been taken"
msgid "This username is already taken"
msgstr "This username is already taken"
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:77
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:79
msgid "Time"
msgstr "Time"
@ -3310,9 +3310,9 @@ msgstr "Time"
msgid "Time zone"
msgstr "Time zone"
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:77
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:78
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:89
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:68
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:64
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:62
msgid "Title"
msgstr "Title"
@ -3445,8 +3445,8 @@ msgstr "Two-factor authentication enabled"
msgid "Two-factor authentication has been disabled for your account. You will no longer be required to enter a code from your authenticator app when signing in."
msgstr "Two-factor authentication has been disabled for your account. You will no longer be required to enter a code from your authenticator app when signing in."
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:155
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:95
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:73
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:68
msgid "Type"
msgstr "Type"
@ -3478,7 +3478,7 @@ msgstr "Unable to create direct template access. Please try again later."
msgid "Unable to decline this team invitation at this time."
msgstr "Unable to decline this team invitation at this time."
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:85
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:88
msgid "Unable to delete invitation. Please try again."
msgstr "Unable to delete invitation. Please try again."
@ -3511,7 +3511,7 @@ msgstr "Unable to remove email verification at this time. Please try again."
msgid "Unable to remove team email at this time. Please try again."
msgstr "Unable to remove team email at this time. Please try again."
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:68
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:71
msgid "Unable to resend invitation. Please try again."
msgstr "Unable to resend invitation. Please try again."
@ -3546,7 +3546,7 @@ msgstr "Uncompleted"
msgid "Unknown error"
msgstr "Unknown error"
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:77
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:79
msgid "Unpaid"
msgstr "Unpaid"
@ -3575,11 +3575,11 @@ msgstr "Update password"
msgid "Update profile"
msgstr "Update profile"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:133
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:180
msgid "Update Recipient"
msgstr "Update Recipient"
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:146
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:148
msgid "Update role"
msgstr "Update role"
@ -3646,7 +3646,7 @@ msgstr "Use Backup Code"
msgid "Use Template"
msgstr "Use Template"
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:82
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:84
msgid "User"
msgstr "User"
@ -3666,7 +3666,7 @@ msgstr "User settings"
msgid "Users"
msgstr "Users"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:165
#: apps/web/src/app/(dashboard)/admin/documents/[id]/recipient-item.tsx:83
msgid "Value"
msgstr "Value"
@ -3698,7 +3698,7 @@ msgstr "Verify your email to upload documents."
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:126
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:135
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:130
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:98
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:100
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:168
msgid "View"
msgstr "View"
@ -4156,7 +4156,7 @@ msgstr "You have reached the maximum limit of {0} direct templates. <0>Upgrade y
msgid "You have reached your document limit."
msgstr "You have reached your document limit."
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:71
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:182
msgid "You have reached your document limit. <0>Upgrade your account to continue!</0>"
msgstr "You have reached your document limit. <0>Upgrade your account to continue!</0>"

View File

@ -17,6 +17,8 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '.
export type DataTableChildren<TData> = (_table: TTable<TData>) => React.ReactNode;
export type { ColumnDef as DataTableColumnDef } from '@tanstack/react-table';
export interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[];
columnVisibility?: VisibilityState;