Compare commits

..

12 Commits

Author SHA1 Message Date
Mythie 5adc198bcd Merge branch 'main' into feat/automated-fields-signature 2024-11-18 10:56:16 +11:00
github-actions 78bad608cc chore: extract translations 2024-09-05 07:29:51 +00:00
Catalin Pit 0c8df9a948 Merge branch 'main' into feat/automated-fields-signature 2024-09-05 10:29:08 +03:00
Catalin Pit 4a7bab912f chore: merge main 2024-08-29 12:46:06 +03:00
Catalin Pit 3783452031 fix: variable name 2024-08-19 14:46:56 +03:00
Catalin Pit 29bc770332 fix: auto-sign after value change 2024-08-19 14:19:15 +03:00
Catalin Pit 75c05bf82b feat: some refactoring 2024-08-19 13:19:16 +03:00
Catalin Pit a0788656f5 Merge branch 'main' into feat/automated-fields-signature 2024-08-19 13:18:50 +03:00
Catalin Pit f74a239474 feat: rework the initials field 2024-08-14 10:03:46 +03:00
Catalin Pit 6505a40067 feat: rework the name field 2024-08-13 16:03:35 +03:00
Catalin Pit d6e51ce5e6 feat: disable remove button for date field 2024-08-13 14:39:26 +03:00
Catalin Pit b15d9019e3 feat: auto-sign fields 2024-08-13 10:33:30 +03:00
130 changed files with 2766 additions and 4841 deletions
+3
View File
@@ -27,6 +27,9 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"typescript": "^5"
}
}
-53
View File
@@ -8,59 +8,6 @@ Check out what's new in the latest version and read our thoughts on it. For more
---
# Documenso v1.8.0: Team Preferences, Signature Rejection, and Document Distribution
We're excited to announce the release of Documenso v1.8.0! This update brings powerful new features to enhance your document signing process. Here's what's new:
## 🌟 Key New Features
### 1. Team Preferences
Introducing **Team Preferences**, allowing administrators to configure settings and preferences that apply to documents across the entire team. This feature ensures consistency and simplifies management by letting you set default options, permissions, and preferences that automatically apply to all team members.
![Team Preferences](/changelog/v1_8_0/team-global-settings.jpeg)
### 2. Signature Rejection
Recipients now have the option to **reject signatures**. This feature enhances communication by allowing recipients to decline signing, providing feedback or requesting changes before the document is finalized.
<video
src="/changelog/v1_8_0/reject-document.mp4"
className="aspect-video w-full"
autoPlay
loop
controls
/>
### 3. Document Distribution Settings
With the new **Document Distribution Settings**, you have greater control over how your documents are shared. Distribute communications via our automated emails and templates or take full control using our API and your own notifications infrastructure.
## 🔧 Other Improvements
- **Support for Gmail SMTP Service**: Adds support for using Gmail as your SMTP service provider.
- **Certificate and Email Translations**: Added support for multiple languages in document certificates and emails, enhancing the experience for international users.
- **Field Movement Fixes**: Resolved issues related to moving fields within documents, improving the document preparation experience.
- **Docker Environment Update**: Improved Docker setup for smoother deployments and better environment consistency.
- **Billing Access Improvements**: Users now have uninterrupted access to billing information, simplifying account management.
- **Support Time Windows for 2FA Tokens**: Enhanced two-factor authentication by supporting time windows in 2FA tokens, improving flexibility.
## 💡 Recent Features
Don't forget to take advantage of these powerful features from our recent releases:
- **Signing Order**: Define the sequence in which recipients sign your documents for a structured signing process.
- **Document Visibility Controls**: Manage who can view your documents and at what stages, offering greater privacy and control.
- **Embedded Signing Experience**: Integrate the signing process directly into your own applications for a seamless user experience.
**👏 Thank You**
As always, we're grateful for the community's contributions and feedback. Your support helps us improve Documenso and deliver a top-notch open-source document signing solution.
We hope you enjoy the new features in Documenso v1.8.0. Happy signing!
---
# Documenso v1.7.1: Signing order and document visibility
We're excited to introduce Documenso v1.7.1, bringing you improved control over your document signing process. Here are the key updates:
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@documenso/marketing",
"version": "1.8.1-rc.1",
"version": "1.8.0-rc.3",
"private": true,
"license": "AGPL-3.0",
"scripts": {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

+2 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@documenso/web",
"version": "1.8.1-rc.1",
"version": "1.8.0-rc.3",
"private": true,
"license": "AGPL-3.0",
"scripts": {
@@ -28,7 +28,6 @@
"@simplewebauthn/browser": "^9.0.1",
"@simplewebauthn/server": "^9.0.3",
"@tanstack/react-query": "^4.29.5",
"colord": "^2.9.3",
"cookie-es": "^1.0.0",
"formidable": "^2.1.1",
"framer-motion": "^10.12.8",
@@ -54,7 +53,7 @@
"react-icons": "^4.11.0",
"react-rnd": "^10.4.1",
"recharts": "^2.7.2",
"remeda": "^2.17.3",
"remeda": "^2.12.1",
"sharp": "0.32.6",
"ts-pattern": "^5.0.5",
"ua-parser-js": "^1.0.37",
@@ -26,7 +26,7 @@ export const DocumentPageViewInformation = ({
const { _, i18n } = useLingui();
const documentInformation = useMemo(() => {
const info = [
return [
{
description: msg`Uploaded by`,
value: userId === document.userId ? _(msg`You`) : document.User.name ?? document.User.email,
@@ -44,20 +44,8 @@ export const DocumentPageViewInformation = ({
.toRelative(),
},
];
if (document.deletedAt) {
info.push({
description: msg`Deleted`,
value:
document.deletedAt &&
DateTime.fromJSDate(document.deletedAt)
.setLocale(i18n.locales?.[0] || i18n.locale)
.toFormat('MMMM d, yyyy'),
});
}
return info;
}, [isMounted, document, i18n.locales?.[0] || i18n.locale, userId]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isMounted, document, userId]);
return (
<section className="dark:bg-background text-foreground border-border bg-widget flex flex-col rounded-xl border">
@@ -146,10 +146,7 @@ export const DocumentPageView = async ({ params, team }: DocumentPageViewProps)
<div className="flex flex-row justify-between truncate">
<div>
<h1
className="mt-4 block max-w-[20rem] truncate text-2xl font-semibold md:max-w-[30rem] md:text-3xl"
title={document.title}
>
<h1 className="mt-4 truncate text-2xl font-semibold md:text-3xl" title={document.title}>
{document.title}
</h1>
@@ -221,7 +218,7 @@ export const DocumentPageView = async ({ params, team }: DocumentPageViewProps)
<DocumentPageViewDropdown document={documentWithRecipients} team={team} />
</div>
<p className="text-muted-foreground mt-2 px-4 text-sm">
<p className="text-muted-foreground mt-2 px-4 text-sm ">
{match(document.status)
.with(DocumentStatus.COMPLETED, () => (
<Trans>This document has been signed by all recipients</Trans>
@@ -109,10 +109,7 @@ export const DocumentEditPageView = async ({ params, team }: DocumentEditPageVie
<Trans>Documents</Trans>
</Link>
<h1
className="mt-4 block max-w-[20rem] truncate text-2xl font-semibold md:max-w-[30rem] md:text-3xl"
title={document.title}
>
<h1 className="mt-4 truncate text-2xl font-semibold md:text-3xl" title={document.title}>
{document.title}
</h1>
@@ -99,7 +99,9 @@ export const DocumentLogsDataTable = ({ documentId }: DocumentLogsDataTableProps
{
header: _(msg`Action`),
accessorKey: 'type',
cell: ({ row }) => <span>{formatDocumentAuditLogAction(_, row.original).description}</span>,
cell: ({ row }) => (
<span>{uppercaseFistLetter(formatDocumentAuditLogAction(row.original).description)}</span>
),
},
{
header: 'IP Address',
@@ -121,10 +121,7 @@ export const DocumentLogsPageView = async ({ params, team }: DocumentLogsPageVie
<div className="flex flex-col justify-between truncate sm:flex-row">
<div>
<h1
className="mt-4 block max-w-[20rem] truncate text-2xl font-semibold md:max-w-[30rem] md:text-3xl"
title={document.title}
>
<h1 className="mt-4 truncate text-2xl font-semibold md:text-3xl" title={document.title}>
{document.title}
</h1>
@@ -7,7 +7,6 @@ import Link from 'next/link';
import { Trans, msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import {
ArchiveRestore,
CheckCircle,
Copy,
Download,
@@ -24,8 +23,8 @@ import { useSession } from 'next-auth/react';
import { downloadPDF } from '@documenso/lib/client-only/download-pdf';
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
import type { Document, Recipient, Team, User } from '@documenso/prisma/client';
import { DocumentStatus, RecipientRole } from '@documenso/prisma/client';
import type { Document, Recipient, Team, User } from '@documenso/prisma/client';
import type { DocumentWithData } from '@documenso/prisma/types/document-with-data';
import { trpc as trpcClient } from '@documenso/trpc/client';
import { DocumentShareButton } from '@documenso/ui/components/document/document-share-button';
@@ -44,7 +43,6 @@ import { ResendDocumentActionItem } from './_action-items/resend-document';
import { DeleteDocumentDialog } from './delete-document-dialog';
import { DuplicateDocumentDialog } from './duplicate-document-dialog';
import { MoveDocumentDialog } from './move-document-dialog';
import { RestoreDocumentDialog } from './restore-document-dialog';
export type DataTableActionDropdownProps = {
row: Document & {
@@ -63,7 +61,6 @@ export const DataTableActionDropdown = ({ row, team }: DataTableActionDropdownPr
const [isDeleteDialogOpen, setDeleteDialogOpen] = useState(false);
const [isDuplicateDialogOpen, setDuplicateDialogOpen] = useState(false);
const [isMoveDialogOpen, setMoveDialogOpen] = useState(false);
const [isRestoreDialogOpen, setRestoreDialogOpen] = useState(false);
if (!session) {
return null;
@@ -79,7 +76,6 @@ export const DataTableActionDropdown = ({ row, team }: DataTableActionDropdownPr
// const isSigned = recipient?.signingStatus === SigningStatus.SIGNED;
const isCurrentTeamDocument = team && row.team?.url === team.url;
const canManageDocument = Boolean(isOwner || isCurrentTeamDocument);
const isDeletedDocument = row.deletedAt !== null;
const documentsPath = formatDocumentsPath(team?.url);
@@ -185,23 +181,13 @@ export const DataTableActionDropdown = ({ row, team }: DataTableActionDropdownPr
Void
</DropdownMenuItem> */}
{isDeletedDocument ? (
<DropdownMenuItem
onClick={() => setRestoreDialogOpen(true)}
disabled={Boolean(!canManageDocument)}
>
<ArchiveRestore className="mr-2 h-4 w-4" />
Restore
</DropdownMenuItem>
) : (
<DropdownMenuItem
onClick={() => setDeleteDialogOpen(true)}
disabled={Boolean(!canManageDocument && team?.teamEmail)}
>
<Trash2 className="mr-2 h-4 w-4" />
{canManageDocument ? 'Delete' : 'Hide'}
</DropdownMenuItem>
)}
<DropdownMenuItem
onClick={() => setDeleteDialogOpen(true)}
disabled={Boolean(!canManageDocument && team?.teamEmail)}
>
<Trash2 className="mr-2 h-4 w-4" />
{canManageDocument ? _(msg`Delete`) : _(msg`Hide`)}
</DropdownMenuItem>
<DropdownMenuLabel>
<Trans>Share</Trans>
@@ -253,16 +239,6 @@ export const DataTableActionDropdown = ({ row, team }: DataTableActionDropdownPr
onOpenChange={setMoveDialogOpen}
/>
<RestoreDocumentDialog
id={row.id}
status={row.status}
documentTitle={row.title}
open={isRestoreDialogOpen}
onOpenChange={setRestoreDialogOpen}
teamId={team?.id}
canManageDocument={canManageDocument}
/>
{isDuplicateDialogOpen && (
<DuplicateDocumentDialog
id={row.id}
@@ -47,8 +47,6 @@ export const DeleteDocumentDialog = ({
const { refreshLimits } = useLimits();
const { _ } = useLingui();
const deleteMessage = msg`delete`;
const [inputValue, setInputValue] = useState('');
const [isDeleteEnabled, setIsDeleteEnabled] = useState(status === DocumentStatus.DRAFT);
@@ -89,7 +87,7 @@ export const DeleteDocumentDialog = ({
const onInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(event.target.value);
setIsDeleteEnabled(event.target.value === _(deleteMessage));
setIsDeleteEnabled(event.target.value === _(msg`delete`));
};
return (
@@ -183,7 +181,7 @@ export const DeleteDocumentDialog = ({
type="text"
value={inputValue}
onChange={onInputChange}
placeholder={_(msg`Please type ${`'${_(deleteMessage)}'`} to confirm`)}
placeholder={_(msg`Type 'delete' to confirm`)}
/>
)}
@@ -4,10 +4,10 @@ import { Trans } from '@lingui/macro';
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
import type { PeriodSelectorValue } from '@documenso/lib/server-only/document/find-documents';
import { findDocuments } from '@documenso/lib/server-only/document/find-documents';
import type { GetStatsInput } from '@documenso/lib/server-only/document/get-stats-new';
import { getStats } from '@documenso/lib/server-only/document/get-stats-new';
import type { PeriodSelectorValue } from '@documenso/lib/server-only/document/find-documents';
import type { GetStatsInput } from '@documenso/lib/server-only/document/get-stats';
import { getStats } from '@documenso/lib/server-only/document/get-stats';
import { parseToIntegerArray } from '@documenso/lib/utils/params';
import { formatDocumentsPath } from '@documenso/lib/utils/teams';
import type { Team, TeamEmail, TeamMemberRole } from '@documenso/prisma/client';
@@ -35,7 +35,7 @@ export interface DocumentsPageViewProps {
senderIds?: string;
search?: string;
};
team?: Team & { teamEmail: TeamEmail | null } & { currentTeamMember?: { role: TeamMemberRole } };
team?: Team & { teamEmail?: TeamEmail | null } & { currentTeamMember?: { role: TeamMemberRole } };
}
export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPageViewProps) => {
@@ -50,14 +50,25 @@ export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPa
const currentTeam = team
? { id: team.id, url: team.url, teamEmail: team.teamEmail?.email }
: undefined;
const currentTeamMemberRole = team?.currentTeamMember?.role;
const getStatOptions: GetStatsInput = {
user,
period,
team,
search,
};
if (team) {
getStatOptions.team = {
teamId: team.id,
teamEmail: team.teamEmail?.email,
senderIds,
currentTeamMemberRole,
currentUserEmail: user.email,
userId: user.id,
};
}
const stats = await getStats(getStatOptions);
const results = await findDocuments({
@@ -117,7 +128,6 @@ export const DocumentsPageView = async ({ searchParams = {}, team }: DocumentsPa
ExtendedDocumentStatus.PENDING,
ExtendedDocumentStatus.COMPLETED,
ExtendedDocumentStatus.DRAFT,
ExtendedDocumentStatus.BIN,
ExtendedDocumentStatus.ALL,
].map((value) => (
<TabsTrigger
@@ -1,6 +1,6 @@
import { msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { Bird, CheckCircle2, Trash } from 'lucide-react';
import { Bird, CheckCircle2 } from 'lucide-react';
import { match } from 'ts-pattern';
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
@@ -30,11 +30,6 @@ export const EmptyDocumentState = ({ status }: EmptyDocumentProps) => {
message: msg`You have not yet created or received any documents. To create a document please upload one.`,
icon: Bird,
}))
.with(ExtendedDocumentStatus.BIN, () => ({
title: msg`No documents in the bin`,
message: msg`There are no documents in the bin.`,
icon: Trash,
}))
.otherwise(() => ({
title: msg`Nothing to do`,
message: msg`All documents have been processed. Any new documents that are sent or received will show here.`,
@@ -47,6 +42,7 @@ export const EmptyDocumentState = ({ status }: EmptyDocumentProps) => {
data-testid="empty-document-state"
>
<Icon className="h-12 w-12" strokeWidth={1.5} />
<div className="text-center">
<h3 className="text-lg font-semibold">{_(title)}</h3>
@@ -1,90 +0,0 @@
import { useRouter } from 'next/navigation';
import type { DocumentStatus } from '@documenso/prisma/client';
import { trpc as trpcReact } from '@documenso/trpc/react';
import {
AlertDialog,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@documenso/ui/primitives/alert-dialog';
import { Button } from '@documenso/ui/primitives/button';
import { useToast } from '@documenso/ui/primitives/use-toast';
type RestoreDocumentDialogProps = {
id: number;
open: boolean;
onOpenChange: (_open: boolean) => void;
status: DocumentStatus;
documentTitle: string;
teamId?: number;
canManageDocument: boolean;
};
export function RestoreDocumentDialog({
id,
teamId,
open,
onOpenChange,
documentTitle,
canManageDocument,
}: RestoreDocumentDialogProps) {
const router = useRouter();
const { toast } = useToast();
const { mutateAsync: restoreDocument, isLoading } =
trpcReact.document.restoreDocument.useMutation({
onSuccess: () => {
router.refresh();
toast({
title: 'Document restored',
description: `"${documentTitle}" has been successfully restored`,
duration: 5000,
});
onOpenChange(false);
},
});
const onRestore = async () => {
try {
await restoreDocument({ id, teamId });
} catch {
toast({
title: 'Something went wrong',
description: 'This document could not be restored at this time. Please try again.',
variant: 'destructive',
duration: 7500,
});
}
};
return (
<AlertDialog open={open} onOpenChange={(value) => !isLoading && onOpenChange(value)}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription>
You are about to restore the document <strong>"{documentTitle}"</strong>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<Button
type="button"
loading={isLoading}
onClick={onRestore}
disabled={!canManageDocument}
>
Restore
</Button>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}
@@ -141,23 +141,6 @@ export const EditTemplateForm = ({
},
});
const { mutateAsync: updateTypedSignature } =
trpc.template.updateTemplateTypedSignatureSettings.useMutation({
...DO_NOT_INVALIDATE_QUERY_ON_MUTATION,
onSuccess: (newData) => {
utils.template.getTemplateWithDetailsById.setData(
{
id: initialTemplate.id,
},
(oldData) => ({
...(oldData || initialTemplate),
...newData,
id: Number(newData.id),
}),
);
},
});
const onAddSettingsFormSubmit = async (data: TAddTemplateSettingsFormSchema) => {
try {
await updateTemplateSettings({
@@ -228,12 +211,6 @@ export const EditTemplateForm = ({
fields: data.fields,
});
await updateTypedSignature({
templateId: template.id,
teamId: team?.id,
typedSignatureEnabled: data.typedSignatureEnabled,
});
// Clear all field data from localStorage
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
@@ -248,13 +225,14 @@ export const EditTemplateForm = ({
duration: 5000,
});
// Router refresh is here to clear the router cache for when navigating to /documents.
router.refresh();
router.push(templateRootPath);
} catch (err) {
console.error(err);
toast({
title: _(msg`Error`),
description: _(msg`An error occurred while adding fields.`),
description: _(msg`An error occurred while adding signers.`),
variant: 'destructive',
});
}
@@ -323,7 +301,6 @@ export const EditTemplateForm = ({
fields={fields}
onSubmit={onAddFieldsFormSubmit}
teamId={team?.id}
typedSignatureEnabled={template.templateMeta?.typedSignatureEnabled}
/>
</Stepper>
</DocumentFlowFormContainer>
@@ -63,10 +63,7 @@ export const TemplateEditPageView = async ({ params, team }: TemplateEditPageVie
<Trans>Template</Trans>
</Link>
<h1
className="mt-4 block max-w-[20rem] truncate text-2xl font-semibold md:max-w-[30rem] md:text-3xl"
title={template.title}
>
<h1 className="mt-4 truncate text-2xl font-semibold md:text-3xl" title={template.title}>
{template.title}
</h1>
@@ -73,6 +73,7 @@ export const TemplatePageView = async ({ params, team }: TemplatePageViewProps)
const mockedDocumentMeta = templateMeta
? {
typedSignatureEnabled: false,
...templateMeta,
signingOrder: templateMeta.signingOrder || DocumentSigningOrder.SEQUENTIAL,
documentId: 0,
@@ -88,10 +89,7 @@ export const TemplatePageView = async ({ params, team }: TemplatePageViewProps)
<div className="flex flex-row justify-between truncate">
<div>
<h1
className="mt-4 block max-w-[20rem] truncate text-2xl font-semibold md:max-w-[30rem] md:text-3xl"
title={template.title}
>
<h1 className="mt-4 truncate text-2xl font-semibold md:text-3xl" title={template.title}>
{template.title}
</h1>
@@ -157,7 +155,7 @@ export const TemplatePageView = async ({ params, team }: TemplatePageViewProps)
</div>
</div>
<p className="text-muted-foreground mt-2 px-4 text-sm">
<p className="text-muted-foreground mt-2 px-4 text-sm ">
<Trans>Manage and view template</Trans>
</p>
@@ -209,19 +209,11 @@ export default async function SigningCertificate({ searchParams }: SigningCertif
boxShadow: `0px 0px 0px 4.88px rgba(122, 196, 85, 0.1), 0px 0px 0px 1.22px rgba(122, 196, 85, 0.6), 0px 0px 0px 0.61px rgba(122, 196, 85, 1)`,
}}
>
{signature.Signature?.signatureImageAsBase64 && (
<img
src={`${signature.Signature?.signatureImageAsBase64}`}
alt="Signature"
className="max-h-12 max-w-full"
/>
)}
{signature.Signature?.typedSignature && (
<p className="font-signature text-center text-sm">
{signature.Signature?.typedSignature}
</p>
)}
<img
src={`${signature.Signature?.signatureImageAsBase64}`}
alt="Signature"
className="max-h-12 max-w-full"
/>
</div>
<p className="text-muted-foreground mt-2 text-sm print:text-xs">
@@ -12,6 +12,7 @@ import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
import { DocumentAuthProvider } from '~/app/(signing)/sign/[token]/document-auth-provider';
import { SigningProvider } from '~/app/(signing)/sign/[token]/provider';
import { truncateTitle } from '~/helpers/truncate-title';
import { DirectTemplatePageView } from './direct-template';
import { DirectTemplateAuthPageView } from './signing-auth-page';
@@ -71,11 +72,8 @@ export default async function TemplatesDirectPage({ params }: TemplatesDirectPag
user={user}
>
<div className="mx-auto -mt-4 w-full max-w-screen-xl px-4 md:px-8">
<h1
className="mt-4 block max-w-[20rem] truncate text-2xl font-semibold md:max-w-[30rem] md:text-3xl"
title={template.title}
>
{template.title}
<h1 className="mt-4 truncate text-2xl font-semibold md:text-3xl" title={template.title}>
{truncateTitle(template.title)}
</h1>
<div className="text-muted-foreground mb-8 mt-2.5 flex items-center gap-x-2">
@@ -102,9 +102,9 @@ export const SignDirectTemplateForm = ({
created: new Date(),
recipientId: 1,
fieldId: 1,
signatureImageAsBase64: value.value.startsWith('data:') ? value.value : null,
typedSignature: value.value.startsWith('data:') ? null : value.value,
} satisfies Signature;
signatureImageAsBase64: value.value,
typedSignature: null,
};
}
if (field.type === FieldType.DATE) {
@@ -193,7 +193,6 @@ export const SignDirectTemplateForm = ({
field={field}
recipient={directRecipient}
onSignField={onSignField}
onUnsignField={onUnsignField}
/>
))
.with(FieldType.NAME, () => (
@@ -202,7 +201,6 @@ export const SignDirectTemplateForm = ({
field={field}
recipient={directRecipient}
onSignField={onSignField}
onUnsignField={onUnsignField}
/>
))
.with(FieldType.DATE, () => (
@@ -213,7 +211,6 @@ export const SignDirectTemplateForm = ({
dateFormat={template.templateMeta?.dateFormat ?? DEFAULT_DOCUMENT_DATE_FORMAT}
timezone={template.templateMeta?.timezone ?? DEFAULT_DOCUMENT_TIME_ZONE}
onSignField={onSignField}
onUnsignField={onUnsignField}
/>
))
.with(FieldType.EMAIL, () => (
@@ -222,7 +219,6 @@ export const SignDirectTemplateForm = ({
field={field}
recipient={directRecipient}
onSignField={onSignField}
onUnsignField={onUnsignField}
/>
))
.with(FieldType.TEXT, () => {
@@ -1,237 +0,0 @@
'use client';
import { useState, useTransition } from 'react';
import { useRouter } from 'next/navigation';
import { Plural, Trans, msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { useForm } from 'react-hook-form';
import { P, match } from 'ts-pattern';
import { unsafe_useEffectOnce } from '@documenso/lib/client-only/hooks/use-effect-once';
import { DocumentAuth } from '@documenso/lib/types/document-auth';
import { extractInitials } from '@documenso/lib/utils/recipient-formatter';
import type { Field, Recipient } from '@documenso/prisma/client';
import { FieldType } from '@documenso/prisma/client';
import { trpc } from '@documenso/trpc/react';
import { Button } from '@documenso/ui/primitives/button';
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@documenso/ui/primitives/dialog';
import { FRIENDLY_FIELD_TYPE } from '@documenso/ui/primitives/document-flow/types';
import { Form } from '@documenso/ui/primitives/form/form';
import { useToast } from '@documenso/ui/primitives/use-toast';
import { SigningDisclosure } from '~/components/general/signing-disclosure';
import { useRequiredDocumentAuthContext } from './document-auth-provider';
import { useRequiredSigningContext } from './provider';
const AUTO_SIGNABLE_FIELD_TYPES: string[] = [
FieldType.NAME,
FieldType.INITIALS,
FieldType.EMAIL,
FieldType.DATE,
];
// The action auth types that are not allowed to be auto signed
//
// Reasoning: If the action auth is a passkey or 2FA, it's likely that the owner of the document
// intends on having the user manually sign due to the additional security measures employed for
// other field types.
const NON_AUTO_SIGNABLE_ACTION_AUTH_TYPES: string[] = [
DocumentAuth.PASSKEY,
DocumentAuth.TWO_FACTOR_AUTH,
];
// The threshold for the number of fields that could be autosigned before displaying the dialog
//
// Reasoning: If there aren't that many fields, it's likely going to be easier to manually sign each one
// while for larger documents with many fields it will be beneficial to sign away the boilerplate fields.
const AUTO_SIGN_THRESHOLD = 5;
export type AutoSignProps = {
recipient: Pick<Recipient, 'id' | 'token'>;
fields: Field[];
};
export const AutoSign = ({ recipient, fields }: AutoSignProps) => {
const { _ } = useLingui();
const { toast } = useToast();
const router = useRouter();
const { email, fullName } = useRequiredSigningContext();
const { derivedRecipientActionAuth } = useRequiredDocumentAuthContext();
const [open, setOpen] = useState(false);
const [isPending, startTransition] = useTransition();
const form = useForm();
const { mutateAsync: signFieldWithToken } = trpc.field.signFieldWithToken.useMutation();
const autoSignableFields = fields.filter((field) => {
if (field.inserted) {
return false;
}
if (!AUTO_SIGNABLE_FIELD_TYPES.includes(field.type)) {
return false;
}
if (field.type === FieldType.NAME && !fullName) {
return false;
}
if (field.type === FieldType.INITIALS && !fullName) {
return false;
}
if (field.type === FieldType.EMAIL && !email) {
return false;
}
return true;
});
const actionAuthAllowsAutoSign = !NON_AUTO_SIGNABLE_ACTION_AUTH_TYPES.includes(
derivedRecipientActionAuth ?? '',
);
const onSubmit = async () => {
const results = await Promise.allSettled(
autoSignableFields.map(async (field) => {
const value = match(field.type)
.with(FieldType.NAME, () => fullName)
.with(FieldType.INITIALS, () => extractInitials(fullName))
.with(FieldType.EMAIL, () => email)
.with(FieldType.DATE, () => new Date().toISOString())
.otherwise(() => '');
const authOptions = match(derivedRecipientActionAuth)
.with(DocumentAuth.ACCOUNT, () => ({
type: DocumentAuth.ACCOUNT,
}))
.with(DocumentAuth.EXPLICIT_NONE, () => ({
type: DocumentAuth.EXPLICIT_NONE,
}))
.with(null, () => undefined)
.with(
P.union(DocumentAuth.PASSKEY, DocumentAuth.TWO_FACTOR_AUTH),
// This is a bit dirty, but the sentinel value used here is incredibly short-lived.
() => 'NOT_SUPPORTED' as const,
)
.exhaustive();
if (authOptions === 'NOT_SUPPORTED') {
throw new Error('Action auth is not supported for auto signing');
}
if (!value) {
throw new Error('No value to sign');
}
return await signFieldWithToken({
token: recipient.token,
fieldId: field.id,
value,
isBase64: false,
authOptions,
});
}),
);
if (results.some((result) => result.status === 'rejected')) {
toast({
title: _(msg`Error`),
description: _(
msg`An error occurred while auto-signing the document, some fields may not be signed. Please review and manually sign any remaining fields.`,
),
duration: 5000,
variant: 'destructive',
});
}
startTransition(() => {
router.refresh();
setOpen(false);
});
};
unsafe_useEffectOnce(() => {
if (actionAuthAllowsAutoSign && autoSignableFields.length > AUTO_SIGN_THRESHOLD) {
setOpen(true);
}
});
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>Automatically sign fields</DialogTitle>
</DialogHeader>
<div className="text-muted-foreground max-w-[50ch]">
<p>
<Trans>
When you sign a document, we can automatically fill in and sign the following fields
using information that has already been provided. You can also manually sign or remove
any automatically signed fields afterwards if you desire.
</Trans>
</p>
<ul className="mt-4 flex list-inside list-disc flex-col gap-y-0.5">
{AUTO_SIGNABLE_FIELD_TYPES.map((fieldType) => (
<li key={fieldType}>
<Trans>{_(FRIENDLY_FIELD_TYPE[fieldType as FieldType])}</Trans>
<span className="pl-2 text-sm">
(
<Plural
value={autoSignableFields.filter((f) => f.type === fieldType).length}
one="1 matching field"
other="# matching fields"
/>
)
</span>
</li>
))}
</ul>
</div>
<SigningDisclosure className="mt-4" />
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<DialogFooter className="flex w-full flex-1 flex-nowrap gap-2">
<Button
type="button"
variant="secondary"
onClick={() => {
setOpen(false);
}}
>
<Trans>Cancel</Trans>
</Button>
<Button
type="submit"
className="min-w-[6rem]"
loading={form.formState.isSubmitting || isPending}
disabled={!autoSignableFields.length}
>
<Trans>Sign</Trans>
</Button>
</DialogFooter>
</form>
</Form>
</DialogContent>
</Dialog>
);
};
@@ -24,6 +24,8 @@ import { SigningCard3D } from '@documenso/ui/components/signing-card';
import { cn } from '@documenso/ui/lib/utils';
import { Badge } from '@documenso/ui/primitives/badge';
import { truncateTitle } from '~/helpers/truncate-title';
import { SigningAuthPageView } from '../signing-auth-page';
import { ClaimAccount } from './claim-account';
import { DocumentPreviewButton } from './document-preview-button';
@@ -59,6 +61,8 @@ export default async function CompletedSigningPage({
return notFound();
}
const truncatedTitle = truncateTitle(document.title);
const { documentData } = document;
const [fields, recipient] = await Promise.all([
@@ -114,9 +118,7 @@ export default async function CompletedSigningPage({
})}
>
<Badge variant="neutral" size="default" className="mb-6 rounded-xl border bg-transparent">
<span className="block max-w-[10rem] truncate font-medium hover:underline md:max-w-[20rem]">
{document.title}
</span>
{truncatedTitle}
</Badge>
{/* Card with recipient */}
@@ -1,6 +1,6 @@
'use client';
import { useTransition } from 'react';
import { useEffect, useTransition } from 'react';
import { useRouter } from 'next/navigation';
@@ -25,6 +25,7 @@ import type {
} from '@documenso/trpc/server/field-router/schema';
import { useToast } from '@documenso/ui/primitives/use-toast';
import { useRequiredDocumentAuthContext } from './document-auth-provider';
import { SigningFieldContainer } from './signing-field-container';
export type DateFieldProps = {
@@ -42,7 +43,6 @@ export const DateField = ({
dateFormat = DEFAULT_DOCUMENT_DATE_FORMAT,
timezone = DEFAULT_DOCUMENT_TIME_ZONE,
onSignField,
onUnsignField,
}: DateFieldProps) => {
const router = useRouter();
@@ -54,13 +54,13 @@ export const DateField = ({
const { mutateAsync: signFieldWithToken, isLoading: isSignFieldWithTokenLoading } =
trpc.field.signFieldWithToken.useMutation(DO_NOT_INVALIDATE_QUERY_ON_MUTATION);
const {
mutateAsync: removeSignedFieldWithToken,
isLoading: isRemoveSignedFieldWithTokenLoading,
} = trpc.field.removeSignedFieldWithToken.useMutation(DO_NOT_INVALIDATE_QUERY_ON_MUTATION);
const { isLoading: isRemoveSignedFieldWithTokenLoading } =
trpc.field.removeSignedFieldWithToken.useMutation(DO_NOT_INVALIDATE_QUERY_ON_MUTATION);
const isLoading = isSignFieldWithTokenLoading || isRemoveSignedFieldWithTokenLoading || isPending;
const { executeActionAuthProcedure } = useRequiredDocumentAuthContext();
const localDateString = convertToLocalSystemFormat(field.customText, dateFormat, timezone);
const isDifferentTime = field.inserted && localDateString !== field.customText;
@@ -103,37 +103,18 @@ export const DateField = ({
}
};
const onRemove = async () => {
try {
const payload: TRemovedSignedFieldWithTokenMutationSchema = {
token: recipient.token,
fieldId: field.id,
};
if (onUnsignField) {
await onUnsignField(payload);
return;
}
await removeSignedFieldWithToken(payload);
startTransition(() => router.refresh());
} catch (err) {
console.error(err);
toast({
title: _(msg`Error`),
description: _(msg`An error occurred while removing the signature.`),
variant: 'destructive',
useEffect(() => {
if (!field.inserted) {
void executeActionAuthProcedure({
onReauthFormSubmit: async (authOptions) => await onSign(authOptions),
actionTarget: field.type,
});
}
};
}, [field]);
return (
<SigningFieldContainer
field={field}
onSign={onSign}
onRemove={onRemove}
type="Date"
tooltipText={isDifferentTime ? tooltipText : undefined}
>
@@ -144,13 +125,13 @@ export const DateField = ({
)}
{!field.inserted && (
<p className="group-hover:text-primary text-muted-foreground text-[clamp(0.425rem,25cqw,0.825rem)] duration-200 group-hover:text-yellow-300">
<p className="group-hover:text-primary text-muted-foreground duration-200 group-hover:text-yellow-300">
<Trans>Date</Trans>
</p>
)}
{field.inserted && (
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.425rem,25cqw,0.825rem)] duration-200">
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.625rem,1cqw,0.825rem)] duration-200">
{localDateString}
</p>
)}
@@ -178,7 +178,7 @@ export const DropdownField = ({
)}
{!field.inserted && (
<p className="group-hover:text-primary text-muted-foreground flex flex-col items-center justify-center duration-200 ">
<p className="group-hover:text-primary text-muted-foreground flex flex-col items-center justify-center duration-200">
<Select value={localChoice} onValueChange={handleSelectItem}>
<SelectTrigger
className={cn(
@@ -190,7 +190,7 @@ export const DropdownField = ({
)}
>
<SelectValue
className="text-[clamp(0.425rem,25cqw,0.825rem)]"
className="text-[clamp(0.625rem,1cqw,0.825rem)]"
placeholder={`${_(msg`Select`)}`}
/>
</SelectTrigger>
@@ -206,7 +206,7 @@ export const DropdownField = ({
)}
{field.inserted && (
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.425rem,25cqw,0.825rem)] duration-200">
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.625rem,1cqw,0.825rem)] duration-200">
{field.customText}
</p>
)}
@@ -1,6 +1,6 @@
'use client';
import { useTransition } from 'react';
import { useEffect, useTransition } from 'react';
import { useRouter } from 'next/navigation';
@@ -14,12 +14,10 @@ import type { TRecipientActionAuth } from '@documenso/lib/types/document-auth';
import type { Recipient } from '@documenso/prisma/client';
import type { FieldWithSignature } from '@documenso/prisma/types/field-with-signature';
import { trpc } from '@documenso/trpc/react';
import type {
TRemovedSignedFieldWithTokenMutationSchema,
TSignFieldWithTokenMutationSchema,
} from '@documenso/trpc/server/field-router/schema';
import type { TSignFieldWithTokenMutationSchema } from '@documenso/trpc/server/field-router/schema';
import { useToast } from '@documenso/ui/primitives/use-toast';
import { useRequiredDocumentAuthContext } from './document-auth-provider';
import { useRequiredSigningContext } from './provider';
import { SigningFieldContainer } from './signing-field-container';
@@ -27,10 +25,9 @@ export type EmailFieldProps = {
field: FieldWithSignature;
recipient: Recipient;
onSignField?: (value: TSignFieldWithTokenMutationSchema) => Promise<void> | void;
onUnsignField?: (value: TRemovedSignedFieldWithTokenMutationSchema) => Promise<void> | void;
};
export const EmailField = ({ field, recipient, onSignField, onUnsignField }: EmailFieldProps) => {
export const EmailField = ({ field, recipient, onSignField }: EmailFieldProps) => {
const router = useRouter();
const { _ } = useLingui();
@@ -43,13 +40,13 @@ export const EmailField = ({ field, recipient, onSignField, onUnsignField }: Ema
const { mutateAsync: signFieldWithToken, isLoading: isSignFieldWithTokenLoading } =
trpc.field.signFieldWithToken.useMutation(DO_NOT_INVALIDATE_QUERY_ON_MUTATION);
const {
mutateAsync: removeSignedFieldWithToken,
isLoading: isRemoveSignedFieldWithTokenLoading,
} = trpc.field.removeSignedFieldWithToken.useMutation(DO_NOT_INVALIDATE_QUERY_ON_MUTATION);
const { isLoading: isRemoveSignedFieldWithTokenLoading } =
trpc.field.removeSignedFieldWithToken.useMutation(DO_NOT_INVALIDATE_QUERY_ON_MUTATION);
const isLoading = isSignFieldWithTokenLoading || isRemoveSignedFieldWithTokenLoading || isPending;
const { executeActionAuthProcedure } = useRequiredDocumentAuthContext();
const onSign = async (authOptions?: TRecipientActionAuth) => {
try {
const value = providedEmail ?? '';
@@ -87,34 +84,17 @@ export const EmailField = ({ field, recipient, onSignField, onUnsignField }: Ema
}
};
const onRemove = async () => {
try {
const payload: TRemovedSignedFieldWithTokenMutationSchema = {
token: recipient.token,
fieldId: field.id,
};
if (onUnsignField) {
await onUnsignField(payload);
return;
}
await removeSignedFieldWithToken(payload);
startTransition(() => router.refresh());
} catch (err) {
console.error(err);
toast({
title: _(msg`Error`),
description: _(msg`An error occurred while removing the signature.`),
variant: 'destructive',
useEffect(() => {
if (!field.inserted) {
void executeActionAuthProcedure({
onReauthFormSubmit: async (authOptions) => await onSign(authOptions),
actionTarget: field.type,
});
}
};
}, [field]);
return (
<SigningFieldContainer field={field} onSign={onSign} onRemove={onRemove} type="Email">
<SigningFieldContainer field={field} type="Email">
{isLoading && (
<div className="bg-background absolute inset-0 flex items-center justify-center rounded-md">
<Loader className="text-primary h-5 w-5 animate-spin md:h-8 md:w-8" />
@@ -122,13 +102,13 @@ export const EmailField = ({ field, recipient, onSignField, onUnsignField }: Ema
)}
{!field.inserted && (
<p className="group-hover:text-primary text-muted-foreground text-[clamp(0.425rem,25cqw,0.825rem)] duration-200 group-hover:text-yellow-300">
<p className="group-hover:text-primary text-muted-foreground duration-200 group-hover:text-yellow-300">
<Trans>Email</Trans>
</p>
)}
{field.inserted && (
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.425rem,25cqw,0.825rem)] duration-200">
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.625rem,1cqw,0.825rem)] duration-200">
{field.customText}
</p>
)}
@@ -1,6 +1,6 @@
'use client';
import { useTransition } from 'react';
import { useEffect, useTransition } from 'react';
import { useRouter } from 'next/navigation';
@@ -8,6 +8,7 @@ import { Trans, msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { Loader } from 'lucide-react';
import { useDebouncedValue } from '@documenso/lib/client-only/hooks/use-debounced-value';
import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION } from '@documenso/lib/constants/trpc';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import type { TRecipientActionAuth } from '@documenso/lib/types/document-auth';
@@ -21,6 +22,7 @@ import type {
} from '@documenso/trpc/server/field-router/schema';
import { useToast } from '@documenso/ui/primitives/use-toast';
import { useRequiredDocumentAuthContext } from './document-auth-provider';
import { useRequiredSigningContext } from './provider';
import { SigningFieldContainer } from './signing-field-container';
@@ -44,8 +46,12 @@ export const InitialsField = ({
const { fullName } = useRequiredSigningContext();
const initials = extractInitials(fullName);
const debouncedInitials = useDebouncedValue(initials, 2000);
const [isPending, startTransition] = useTransition();
const { executeActionAuthProcedure } = useRequiredDocumentAuthContext();
const { mutateAsync: signFieldWithToken, isLoading: isSignFieldWithTokenLoading } =
trpc.field.signFieldWithToken.useMutation(DO_NOT_INVALIDATE_QUERY_ON_MUTATION);
@@ -58,7 +64,7 @@ export const InitialsField = ({
const onSign = async (authOptions?: TRecipientActionAuth) => {
try {
const value = initials ?? '';
const value = debouncedInitials ?? '';
const payload: TSignFieldWithTokenMutationSchema = {
token: recipient.token,
@@ -119,6 +125,15 @@ export const InitialsField = ({
}
};
useEffect(() => {
if (!field.inserted && debouncedInitials) {
void executeActionAuthProcedure({
onReauthFormSubmit: async (authOptions) => await onSign(authOptions),
actionTarget: field.type,
});
}
}, [field, debouncedInitials, field.inserted]);
return (
<SigningFieldContainer field={field} onSign={onSign} onRemove={onRemove} type="Initials">
{isLoading && (
@@ -128,13 +143,13 @@ export const InitialsField = ({
)}
{!field.inserted && (
<p className="group-hover:text-primary text-muted-foreground text-[clamp(0.425rem,25cqw,0.825rem)] duration-200 group-hover:text-yellow-300">
<p className="group-hover:text-primary text-muted-foreground duration-200 group-hover:text-yellow-300">
<Trans>Initials</Trans>
</p>
)}
{field.inserted && (
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.425rem,25cqw,0.825rem)] duration-200">
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.625rem,1cqw,0.825rem)] duration-200">
{field.customText}
</p>
)}
@@ -1,6 +1,6 @@
'use client';
import { useState, useTransition } from 'react';
import { useEffect, useState, useTransition } from 'react';
import { useRouter } from 'next/navigation';
@@ -8,6 +8,7 @@ import { Trans, msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { Loader } from 'lucide-react';
import { useDebouncedValue } from '@documenso/lib/client-only/hooks/use-debounced-value';
import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION } from '@documenso/lib/constants/trpc';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import type { TRecipientActionAuth } from '@documenso/lib/types/document-auth';
@@ -44,6 +45,8 @@ export const NameField = ({ field, recipient, onSignField, onUnsignField }: Name
const { fullName: providedFullName, setFullName: setProvidedFullName } =
useRequiredSigningContext();
const debouncedProvidedFullName = useDebouncedValue(providedFullName, 2000);
const { executeActionAuthProcedure } = useRequiredDocumentAuthContext();
const [isPending, startTransition] = useTransition();
@@ -151,6 +154,15 @@ export const NameField = ({ field, recipient, onSignField, onUnsignField }: Name
}
};
useEffect(() => {
if (!field.inserted && providedFullName) {
void executeActionAuthProcedure({
onReauthFormSubmit: async (authOptions) => await onSign(authOptions),
actionTarget: field.type,
});
}
}, [field, debouncedProvidedFullName]);
return (
<SigningFieldContainer
field={field}
@@ -172,7 +184,7 @@ export const NameField = ({ field, recipient, onSignField, onUnsignField }: Name
)}
{field.inserted && (
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.425rem,25cqw,0.825rem)] duration-200">
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.625rem,1cqw,0.825rem)] duration-200">
{field.customText}
</p>
)}
@@ -252,15 +252,14 @@ export const NumberField = ({ field, recipient, onSignField, onUnsignField }: Nu
},
)}
>
<span className="flex items-center justify-center gap-x-1">
<Hash className="h-[clamp(0.625rem,20cqw,0.925rem)] w-[clamp(0.625rem,20cqw,0.925rem)]" />{' '}
<span className="text-[clamp(0.425rem,25cqw,0.825rem)]">{fieldDisplayName}</span>
<span className="flex items-center justify-center gap-x-1 text-sm">
<Hash className="h-4 w-4" /> {fieldDisplayName}
</span>
</p>
)}
{field.inserted && (
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.425rem,25cqw,0.825rem)] duration-200">
<p className="text-muted-foreground dark:text-background/80 text-[clamp(0.625rem,1cqw,0.825rem)] duration-200">
{field.customText}
</p>
)}
@@ -1,6 +1,6 @@
'use client';
import { createContext, useContext, useEffect, useState } from 'react';
import { createContext, useContext, useState } from 'react';
export type SigningContextValue = {
fullName: string;
@@ -44,12 +44,6 @@ export const SigningProvider = ({
const [email, setEmail] = useState(initialEmail || '');
const [signature, setSignature] = useState(initialSignature || null);
useEffect(() => {
if (initialSignature) {
setSignature(initialSignature);
}
}, [initialSignature]);
return (
<SigningContext.Provider
value={{
@@ -14,6 +14,7 @@ import {
} from '@documenso/ui/primitives/dialog';
import { SigningDisclosure } from '~/components/general/signing-disclosure';
import { truncateTitle } from '~/helpers/truncate-title';
export type SignDialogProps = {
isSubmitting: boolean;
@@ -35,7 +36,7 @@ export const SignDialog = ({
disabled = false,
}: SignDialogProps) => {
const [showDialog, setShowDialog] = useState(false);
const truncatedTitle = truncateTitle(documentTitle);
const isComplete = fields.every((field) => field.inserted);
const handleOpenChange = (open: boolean) => {
@@ -74,13 +75,7 @@ export const SignDialog = ({
{role === RecipientRole.VIEWER && (
<span>
<Trans>
<span className="inline-flex flex-wrap">
You are about to complete viewing "
<span className="inline-block max-w-[11rem] truncate align-baseline">
{documentTitle}
</span>
".
</span>
You are about to complete viewing "{truncatedTitle}".
<br /> Are you sure?
</Trans>
</span>
@@ -88,13 +83,7 @@ export const SignDialog = ({
{role === RecipientRole.SIGNER && (
<span>
<Trans>
<span className="inline-flex flex-wrap">
You are about to complete signing "
<span className="inline-block max-w-[11rem] truncate align-baseline">
{documentTitle}
</span>
".
</span>
You are about to complete signing "{truncatedTitle}".
<br /> Are you sure?
</Trans>
</span>
@@ -102,13 +91,7 @@ export const SignDialog = ({
{role === RecipientRole.APPROVER && (
<span>
<Trans>
<span className="inline-flex flex-wrap">
You are about to complete approving{' '}
<span className="inline-block max-w-[11rem] truncate align-baseline">
"{documentTitle}"
</span>
.
</span>
You are about to complete approving "{truncatedTitle}".
<br /> Are you sure?
</Trans>
</span>
@@ -1,6 +1,6 @@
'use client';
import { useLayoutEffect, useMemo, useRef, useState, useTransition } from 'react';
import { useMemo, useState, useTransition } from 'react';
import { useRouter } from 'next/navigation';
@@ -51,10 +51,6 @@ export const SignatureField = ({
const { _ } = useLingui();
const { toast } = useToast();
const signatureRef = useRef<HTMLParagraphElement>(null);
const containerRef = useRef<HTMLDivElement>(null);
const [fontSize, setFontSize] = useState(2);
const { signature: providedSignature, setSignature: setProvidedSignature } =
useRequiredSigningContext();
@@ -112,7 +108,6 @@ export const SignatureField = ({
actionTarget: field.type,
});
};
const onSign = async (authOptions?: TRecipientActionAuth, signature?: string) => {
try {
const value = signature || providedSignature;
@@ -122,23 +117,11 @@ export const SignatureField = ({
return;
}
const isTypedSignature = !value.startsWith('data:image');
if (isTypedSignature && !typedSignatureEnabled) {
toast({
title: _(msg`Error`),
description: _(msg`Typed signatures are not allowed. Please draw your signature.`),
variant: 'destructive',
});
return;
}
const payload: TSignFieldWithTokenMutationSchema = {
token: recipient.token,
fieldId: field.id,
value,
isBase64: !isTypedSignature,
isBase64: true,
authOptions,
};
@@ -193,41 +176,6 @@ export const SignatureField = ({
}
};
useLayoutEffect(() => {
if (!signatureRef.current || !containerRef.current || !signature?.typedSignature) {
return;
}
const adjustTextSize = () => {
const container = containerRef.current;
const text = signatureRef.current;
if (!container || !text) {
return;
}
let size = 2;
text.style.fontSize = `${size}rem`;
while (
(text.scrollWidth > container.clientWidth || text.scrollHeight > container.clientHeight) &&
size > 0.8
) {
size -= 0.1;
text.style.fontSize = `${size}rem`;
}
setFontSize(size);
};
const resizeObserver = new ResizeObserver(adjustTextSize);
resizeObserver.observe(containerRef.current);
adjustTextSize();
return () => resizeObserver.disconnect();
}, [signature?.typedSignature]);
return (
<SigningFieldContainer
field={field}
@@ -243,7 +191,7 @@ export const SignatureField = ({
)}
{state === 'empty' && (
<p className="group-hover:text-primary font-signature text-muted-foreground text-[clamp(0.575rem,25cqw,1.2rem)] text-xl duration-200 group-hover:text-yellow-300">
<p className="group-hover:text-primary font-signature text-muted-foreground text-xl duration-200 group-hover:text-yellow-300">
<Trans>Signature</Trans>
</p>
)}
@@ -257,15 +205,10 @@ export const SignatureField = ({
)}
{state === 'signed-text' && (
<div ref={containerRef} className="flex h-full w-full items-center justify-center p-2">
<p
ref={signatureRef}
className="font-signature text-muted-foreground dark:text-background w-full overflow-hidden break-all text-center leading-tight duration-200"
style={{ fontSize: `${fontSize}rem` }}
>
{signature?.typedSignature}
</p>
</div>
<p className="font-signature text-muted-foreground dark:text-background text-lg duration-200 sm:text-xl md:text-2xl lg:text-3xl">
{/* This optional chaining is intentional, we don't want to move the check into the condition above */}
{signature?.typedSignature}
</p>
)}
<Dialog open={showSignatureModal} onOpenChange={setShowSignatureModal}>
@@ -68,6 +68,8 @@ export const SigningFieldContainer = ({
const parsedFieldMeta = field.fieldMeta ? ZFieldMetaSchema.parse(field.fieldMeta) : undefined;
const readOnlyField = parsedFieldMeta?.readOnly || false;
const automatedFields = ['Email', 'Date'].includes(type ?? '');
const handleInsertField = async () => {
if (field.inserted || !onSign) {
return;
@@ -146,7 +148,7 @@ export const SigningFieldContainer = ({
</button>
)}
{type === 'Date' && field.inserted && !loading && !readOnlyField && (
{field.inserted && !automatedFields && !loading && !readOnlyField && (
<Tooltip delayDuration={0}>
<TooltipTrigger asChild>
<button
@@ -172,14 +174,18 @@ export const SigningFieldContainer = ({
</button>
)}
{type !== 'Date' && type !== 'Checkbox' && field.inserted && !loading && !readOnlyField && (
<button
className="text-destructive bg-background/50 absolute inset-0 z-10 flex h-full w-full items-center justify-center rounded-md text-sm opacity-0 duration-200 group-hover:opacity-100"
onClick={onRemoveSignedFieldClick}
>
<Trans>Remove</Trans>
</button>
)}
{type !== 'Checkbox' &&
!automatedFields &&
field.inserted &&
!loading &&
!readOnlyField && (
<button
className="text-destructive bg-background/50 absolute inset-0 z-10 flex h-full w-full items-center justify-center rounded-md text-sm opacity-0 duration-200 group-hover:opacity-100"
onClick={onRemoveSignedFieldClick}
>
Remove
</button>
)}
{children}
</FieldRootContainer>
@@ -22,7 +22,6 @@ import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
import { DocumentReadOnlyFields } from '~/components/document/document-read-only-fields';
import { AutoSign } from './auto-sign';
import { CheckboxField } from './checkbox-field';
import { DateField } from './date-field';
import { DropdownField } from './dropdown-field';
@@ -55,10 +54,7 @@ export const SigningPageView = ({
return (
<div className="mx-auto w-full max-w-screen-xl">
<h1
className="mt-4 block max-w-[20rem] truncate text-2xl font-semibold md:max-w-[30rem] md:text-3xl"
title={document.title}
>
<h1 className="mt-4 truncate text-2xl font-semibold md:text-3xl" title={document.title}>
{document.title}
</h1>
@@ -117,8 +113,6 @@ export const SigningPageView = ({
<DocumentReadOnlyFields fields={completedFields} />
<AutoSign recipient={recipient} fields={fields} />
<ElementVisible target={PDF_VIEWER_PAGE_SELECTOR}>
{fields.map((field) =>
match(field.type)
@@ -252,16 +252,14 @@ export const TextField = ({ field, recipient, onSignField, onUnsignField }: Text
)}
>
<span className="flex items-center justify-center gap-x-1">
<Type className="h-[clamp(0.625rem,20cqw,0.925rem)] w-[clamp(0.625rem,20cqw,0.925rem)]" />
<span className="text-[clamp(0.425rem,25cqw,0.825rem)]">
{fieldDisplayName || <Trans>Text</Trans>}
</span>
<Type />
{fieldDisplayName || <Trans>Text</Trans>}
</span>
</p>
)}
{field.inserted && (
<p className="text-muted-foreground dark:text-background/80 flex items-center justify-center gap-x-1 text-[clamp(0.425rem,25cqw,0.825rem)] duration-200">
<p className="text-muted-foreground dark:text-background/80 flex items-center justify-center gap-x-1 duration-200">
{field.customText.length < 20
? field.customText
: field.customText.substring(0, 15) + '...'}
@@ -52,7 +52,13 @@ export default async function TeamsSettingsPage({ params }: TeamsSettingsPagePro
<AvatarImageForm className="mb-8" team={team} user={session.user} />
<UpdateTeamForm teamId={team.id} teamName={team.name} teamUrl={team.url} />
<UpdateTeamForm
teamId={team.id}
teamName={team.name}
teamUrl={team.url}
documentVisibility={team.teamGlobalSettings?.documentVisibility}
includeSenderDetails={team.teamGlobalSettings?.includeSenderDetails}
/>
<section className="mt-6 space-y-6">
{(team.teamEmail || team.emailVerification) && (
@@ -39,8 +39,6 @@ const ZTeamDocumentPreferencesFormSchema = z.object({
documentVisibility: z.nativeEnum(DocumentVisibility),
documentLanguage: z.enum(SUPPORTED_LANGUAGE_CODES),
includeSenderDetails: z.boolean(),
typedSignatureEnabled: z.boolean(),
includeSigningCertificate: z.boolean(),
});
type TTeamDocumentPreferencesFormSchema = z.infer<typeof ZTeamDocumentPreferencesFormSchema>;
@@ -70,8 +68,6 @@ export const TeamDocumentPreferencesForm = ({
? settings?.documentLanguage
: 'en',
includeSenderDetails: settings?.includeSenderDetails ?? false,
typedSignatureEnabled: settings?.typedSignatureEnabled ?? true,
includeSigningCertificate: settings?.includeSigningCertificate ?? true,
},
resolver: zodResolver(ZTeamDocumentPreferencesFormSchema),
});
@@ -80,13 +76,7 @@ export const TeamDocumentPreferencesForm = ({
const onSubmit = async (data: TTeamDocumentPreferencesFormSchema) => {
try {
const {
documentVisibility,
documentLanguage,
includeSenderDetails,
includeSigningCertificate,
typedSignatureEnabled,
} = data;
const { documentVisibility, documentLanguage, includeSenderDetails } = data;
await updateTeamDocumentPreferences({
teamId: team.id,
@@ -94,8 +84,6 @@ export const TeamDocumentPreferencesForm = ({
documentVisibility,
documentLanguage,
includeSenderDetails,
typedSignatureEnabled,
includeSigningCertificate,
},
});
@@ -117,7 +105,7 @@ export const TeamDocumentPreferencesForm = ({
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<fieldset
className="flex h-full max-w-xl flex-col gap-y-6"
className="flex h-full max-w-xl flex-col gap-y-4"
disabled={form.formState.isSubmitting}
>
<FormField
@@ -239,67 +227,6 @@ export const TeamDocumentPreferencesForm = ({
)}
/>
<FormField
control={form.control}
name="typedSignatureEnabled"
render={({ field }) => (
<FormItem className="flex-1">
<FormLabel>
<Trans>Enable Typed Signature</Trans>
</FormLabel>
<div>
<FormControl className="block">
<Switch
ref={field.ref}
name={field.name}
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
</div>
<FormDescription>
<Trans>
Controls whether the recipients can sign the documents using a typed signature.
Enable or disable the typed signature globally.
</Trans>
</FormDescription>
</FormItem>
)}
/>
<FormField
control={form.control}
name="includeSigningCertificate"
render={({ field }) => (
<FormItem className="flex-1">
<FormLabel>
<Trans>Include the Signing Certificate in the Document</Trans>
</FormLabel>
<div>
<FormControl className="block">
<Switch
ref={field.ref}
name={field.name}
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
</div>
<FormDescription>
<Trans>
Controls whether the signing certificate will be included in the document when
it is downloaded. The signing certificate can still be downloaded from the logs
page separately.
</Trans>
</FormDescription>
</FormItem>
)}
/>
<div className="flex flex-row justify-end space-x-4">
<Button type="submit" loading={form.formState.isSubmitting}>
<Trans>Save</Trans>
-4
View File
@@ -1,12 +1,8 @@
import { z } from 'zod';
import { ZCssVarsSchema } from './css-vars';
export const ZBaseEmbedDataSchema = z.object({
darkModeDisabled: z.boolean().optional().default(false),
css: z
.string()
.optional()
.transform((value) => value || undefined),
cssVars: ZCssVarsSchema.optional().default({}),
});
-1
View File
@@ -10,7 +10,6 @@ export type EmbedDocumentCompletedPageProps = {
};
export const EmbedDocumentCompleted = ({ name, signature }: EmbedDocumentCompletedPageProps) => {
console.log({ signature });
return (
<div className="relative mx-auto flex min-h-[100dvh] max-w-screen-lg flex-col items-center justify-center p-6">
<h3 className="text-foreground text-2xl font-semibold">
-59
View File
@@ -1,59 +0,0 @@
import { colord } from 'colord';
import { toSnakeCase } from 'remeda';
import { z } from 'zod';
export const ZCssVarsSchema = z
.object({
background: z.string().optional().describe('Base background color'),
foreground: z.string().optional().describe('Base text color'),
muted: z.string().optional().describe('Muted/subtle background color'),
mutedForeground: z.string().optional().describe('Muted/subtle text color'),
popover: z.string().optional().describe('Popover/dropdown background color'),
popoverForeground: z.string().optional().describe('Popover/dropdown text color'),
card: z.string().optional().describe('Card background color'),
cardBorder: z.string().optional().describe('Card border color'),
cardBorderTint: z.string().optional().describe('Card border tint/highlight color'),
cardForeground: z.string().optional().describe('Card text color'),
fieldCard: z.string().optional().describe('Field card background color'),
fieldCardBorder: z.string().optional().describe('Field card border color'),
fieldCardForeground: z.string().optional().describe('Field card text color'),
widget: z.string().optional().describe('Widget background color'),
widgetForeground: z.string().optional().describe('Widget text color'),
border: z.string().optional().describe('Default border color'),
input: z.string().optional().describe('Input field border color'),
primary: z.string().optional().describe('Primary action/button color'),
primaryForeground: z.string().optional().describe('Primary action/button text color'),
secondary: z.string().optional().describe('Secondary action/button color'),
secondaryForeground: z.string().optional().describe('Secondary action/button text color'),
accent: z.string().optional().describe('Accent/highlight color'),
accentForeground: z.string().optional().describe('Accent/highlight text color'),
destructive: z.string().optional().describe('Destructive/danger action color'),
destructiveForeground: z.string().optional().describe('Destructive/danger text color'),
ring: z.string().optional().describe('Focus ring color'),
radius: z.string().optional().describe('Border radius size in REM units'),
warning: z.string().optional().describe('Warning/alert color'),
})
.describe('Custom CSS variables for theming');
export type TCssVarsSchema = z.infer<typeof ZCssVarsSchema>;
export const toNativeCssVars = (vars: TCssVarsSchema) => {
const cssVars: Record<string, string> = {};
const { radius, ...colorVars } = vars;
for (const [key, value] of Object.entries(colorVars)) {
if (value) {
const color = colord(value);
const { h, s, l } = color.toHsl();
cssVars[`--${toSnakeCase(key)}`] = `${h} ${s} ${l}`;
}
}
if (radius) {
cssVars[`--radius`] = `${radius}`;
}
return cssVars;
};
@@ -1,6 +1,6 @@
'use client';
import { useEffect, useLayoutEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import { useSearchParams } from 'next/navigation';
@@ -14,7 +14,7 @@ import { DEFAULT_DOCUMENT_DATE_FORMAT } from '@documenso/lib/constants/date-form
import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer';
import { DEFAULT_DOCUMENT_TIME_ZONE } from '@documenso/lib/constants/time-zones';
import { validateFieldsInserted } from '@documenso/lib/utils/fields';
import type { DocumentMeta, Recipient, Signature, TemplateMeta } from '@documenso/prisma/client';
import type { DocumentMeta, Recipient, TemplateMeta } from '@documenso/prisma/client';
import { type DocumentData, type Field, FieldType } from '@documenso/prisma/client';
import { trpc } from '@documenso/trpc/react';
import type {
@@ -38,7 +38,6 @@ import { Logo } from '~/components/branding/logo';
import { EmbedClientLoading } from '../../client-loading';
import { EmbedDocumentCompleted } from '../../completed';
import { EmbedDocumentFields } from '../../document-fields';
import { injectCss } from '../../util';
import { ZDirectTemplateEmbedDataSchema } from './schema';
export type EmbedDirectTemplateClientPageProps = {
@@ -48,8 +47,6 @@ export type EmbedDirectTemplateClientPageProps = {
recipient: Recipient;
fields: Field[];
metadata?: DocumentMeta | TemplateMeta | null;
hidePoweredBy?: boolean;
isPlatformOrEnterprise?: boolean;
};
export const EmbedDirectTemplateClientPage = ({
@@ -59,8 +56,6 @@ export const EmbedDirectTemplateClientPage = ({
recipient,
fields,
metadata,
hidePoweredBy = false,
isPlatformOrEnterprise = false,
}: EmbedDirectTemplateClientPageProps) => {
const { _ } = useLingui();
const { toast } = useToast();
@@ -113,9 +108,9 @@ export const EmbedDirectTemplateClientPage = ({
created: new Date(),
recipientId: 1,
fieldId: 1,
signatureImageAsBase64: payload.value.startsWith('data:') ? payload.value : null,
typedSignature: payload.value.startsWith('data:') ? null : payload.value,
} satisfies Signature;
signatureImageAsBase64: payload.value,
typedSignature: null,
};
}
if (field.type === FieldType.DATE) {
@@ -254,7 +249,7 @@ export const EmbedDirectTemplateClientPage = ({
}
};
useLayoutEffect(() => {
useEffect(() => {
const hash = window.location.hash.slice(1);
try {
@@ -269,17 +264,6 @@ export const EmbedDirectTemplateClientPage = ({
setFullName(data.name);
setIsNameLocked(!!data.lockName);
}
if (data.darkModeDisabled) {
document.documentElement.classList.add('dark-mode-disabled');
}
if (isPlatformOrEnterprise) {
injectCss({
css: data.css,
cssVars: data.cssVars,
});
}
} catch (err) {
console.error(err);
}
@@ -312,8 +296,8 @@ export const EmbedDirectTemplateClientPage = ({
fieldId: 1,
recipientId: 1,
created: new Date(),
signatureImageAsBase64: signature?.startsWith('data:') ? signature : null,
typedSignature: signature?.startsWith('data:') ? null : signature,
typedSignature: null,
signatureImageAsBase64: signature,
}}
/>
);
@@ -468,12 +452,10 @@ export const EmbedDirectTemplateClientPage = ({
/>
</div>
{!hidePoweredBy && (
<div className="bg-primary text-primary-foreground fixed bottom-0 left-0 z-40 rounded-tr px-2 py-1 text-xs font-medium opacity-60 hover:opacity-100">
<span>Powered by</span>
<Logo className="ml-2 inline-block h-[14px]" />
</div>
)}
<div className="bg-primary text-primary-foreground fixed bottom-0 left-0 z-40 rounded-tr px-2 py-1 text-xs font-medium opacity-60 hover:opacity-100">
<span>Powered by</span>
<Logo className="ml-2 inline-block h-[14px]" />
</div>
</div>
);
};
@@ -2,11 +2,8 @@ import { notFound } from 'next/navigation';
import { match } from 'ts-pattern';
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
import { isDocumentPlatform } from '@documenso/ee/server-only/util/is-document-platform';
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
import { getServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
import { getTeamById } from '@documenso/lib/server-only/team/get-team';
import { getTemplateByDirectLinkToken } from '@documenso/lib/server-only/template/get-template-by-direct-link-token';
import { DocumentAccessAuth } from '@documenso/lib/types/document-auth';
import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
@@ -54,14 +51,6 @@ export default async function EmbedDirectTemplatePage({ params }: EmbedDirectTem
documentAuth: template.authOptions,
});
const [isPlatformDocument, isEnterpriseDocument] = await Promise.all([
isDocumentPlatform(template),
isUserEnterprise({
userId: template.userId,
teamId: template.teamId ?? undefined,
}),
]);
const isAccessAuthValid = match(derivedRecipientAccessAuth)
.with(DocumentAccessAuth.ACCOUNT, () => user !== null)
.with(null, () => true)
@@ -83,12 +72,6 @@ export default async function EmbedDirectTemplatePage({ params }: EmbedDirectTem
const fields = template.Field.filter((field) => field.recipientId === directTemplateRecipientId);
const team = template.teamId
? await getTeamById({ teamId: template.teamId, userId: template.userId }).catch(() => null)
: null;
const hidePoweredBy = team?.teamGlobalSettings?.brandingHidePoweredBy ?? false;
return (
<SigningProvider email={user?.email} fullName={user?.name} signature={user?.signature}>
<DocumentAuthProvider
@@ -103,8 +86,6 @@ export default async function EmbedDirectTemplatePage({ params }: EmbedDirectTem
recipient={recipient}
fields={fields}
metadata={template.templateMeta}
hidePoweredBy={isPlatformDocument || isEnterpriseDocument || hidePoweredBy}
isPlatformOrEnterprise={isPlatformDocument || isEnterpriseDocument}
/>
</DocumentAuthProvider>
</SigningProvider>
@@ -58,7 +58,6 @@ export const EmbedDocumentFields = ({
recipient={recipient}
onSignField={onSignField}
onUnsignField={onUnsignField}
typedSignatureEnabled={metadata?.typedSignatureEnabled}
/>
))
.with(FieldType.INITIALS, () => (
@@ -1,6 +1,6 @@
'use client';
import { useEffect, useLayoutEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import { Trans, msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
@@ -28,7 +28,6 @@ import { Logo } from '~/components/branding/logo';
import { EmbedClientLoading } from '../../client-loading';
import { EmbedDocumentCompleted } from '../../completed';
import { EmbedDocumentFields } from '../../document-fields';
import { injectCss } from '../../util';
import { ZSignDocumentEmbedDataSchema } from './schema';
export type EmbedSignDocumentClientPageProps = {
@@ -39,8 +38,6 @@ export type EmbedSignDocumentClientPageProps = {
fields: Field[];
metadata?: DocumentMeta | TemplateMeta | null;
isCompleted?: boolean;
hidePoweredBy?: boolean;
isPlatformOrEnterprise?: boolean;
};
export const EmbedSignDocumentClientPage = ({
@@ -51,8 +48,6 @@ export const EmbedSignDocumentClientPage = ({
fields,
metadata,
isCompleted,
hidePoweredBy = false,
isPlatformOrEnterprise = false,
}: EmbedSignDocumentClientPageProps) => {
const { _ } = useLingui();
const { toast } = useToast();
@@ -136,7 +131,7 @@ export const EmbedSignDocumentClientPage = ({
}
};
useLayoutEffect(() => {
useEffect(() => {
const hash = window.location.hash.slice(1);
try {
@@ -149,17 +144,6 @@ export const EmbedSignDocumentClientPage = ({
// Since a recipient can be provided a name we can lock it without requiring
// a to be provided by the parent application, unlike direct templates.
setIsNameLocked(!!data.lockName);
if (data.darkModeDisabled) {
document.documentElement.classList.add('dark-mode-disabled');
}
if (isPlatformOrEnterprise) {
injectCss({
css: data.css,
cssVars: data.cssVars,
});
}
} catch (err) {
console.error(err);
}
@@ -192,8 +176,8 @@ export const EmbedSignDocumentClientPage = ({
fieldId: 1,
recipientId: 1,
created: new Date(),
signatureImageAsBase64: signature?.startsWith('data:') ? signature : null,
typedSignature: signature?.startsWith('data:') ? null : signature,
typedSignature: null,
signatureImageAsBase64: signature,
}}
/>
);
@@ -218,7 +202,7 @@ export const EmbedSignDocumentClientPage = ({
className="group/document-widget fixed bottom-8 left-0 z-50 h-fit w-full flex-shrink-0 px-6 md:sticky md:top-4 md:z-auto md:w-[350px] md:px-0"
data-expanded={isExpanded || undefined}
>
<div className="border-border bg-widget flex w-full flex-col rounded-xl border px-4 py-4 md:py-6">
<div className="border-border bg-widget flex w-full flex-col rounded-xl border px-4 py-4 md:py-6">
{/* Header */}
<div>
<div className="flex items-center justify-between gap-x-2">
@@ -341,12 +325,10 @@ export const EmbedSignDocumentClientPage = ({
<EmbedDocumentFields recipient={recipient} fields={fields} metadata={metadata} />
</div>
{!hidePoweredBy && (
<div className="bg-primary text-primary-foreground fixed bottom-0 left-0 z-40 rounded-tr px-2 py-1 text-xs font-medium opacity-60 hover:opacity-100">
<span>Powered by</span>
<Logo className="ml-2 inline-block h-[14px]" />
</div>
)}
<div className="bg-primary text-primary-foreground fixed bottom-0 left-0 z-40 rounded-tr px-2 py-1 text-xs font-medium opacity-60 hover:opacity-100">
<span>Powered by</span>
<Logo className="ml-2 inline-block h-[14px]" />
</div>
</div>
);
};
@@ -2,14 +2,11 @@ import { notFound } from 'next/navigation';
import { match } from 'ts-pattern';
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
import { isDocumentPlatform } from '@documenso/ee/server-only/util/is-document-platform';
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
import { getServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
import { getDocumentAndSenderByToken } from '@documenso/lib/server-only/document/get-document-by-token';
import { getFieldsForToken } from '@documenso/lib/server-only/field/get-fields-for-token';
import { getRecipientByToken } from '@documenso/lib/server-only/recipient/get-recipient-by-token';
import { getTeamById } from '@documenso/lib/server-only/team/get-team';
import { DocumentAccessAuth } from '@documenso/lib/types/document-auth';
import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
import { DocumentStatus } from '@documenso/prisma/client';
@@ -59,14 +56,6 @@ export default async function EmbedSignDocumentPage({ params }: EmbedSignDocumen
return <EmbedPaywall />;
}
const [isPlatformDocument, isEnterpriseDocument] = await Promise.all([
isDocumentPlatform(document),
isUserEnterprise({
userId: document.userId,
teamId: document.teamId ?? undefined,
}),
]);
const { derivedRecipientAccessAuth } = extractDocumentAuthMethods({
documentAuth: document.authOptions,
});
@@ -85,12 +74,6 @@ export default async function EmbedSignDocumentPage({ params }: EmbedSignDocumen
);
}
const team = document.teamId
? await getTeamById({ teamId: document.teamId, userId: document.userId }).catch(() => null)
: null;
const hidePoweredBy = team?.teamGlobalSettings?.brandingHidePoweredBy ?? false;
return (
<SigningProvider
email={recipient.email}
@@ -110,8 +93,6 @@ export default async function EmbedSignDocumentPage({ params }: EmbedSignDocumen
fields={fields}
metadata={document.documentMeta}
isCompleted={document.status === DocumentStatus.COMPLETED}
hidePoweredBy={isPlatformDocument || isEnterpriseDocument || hidePoweredBy}
isPlatformOrEnterprise={isPlatformDocument || isEnterpriseDocument}
/>
</DocumentAuthProvider>
</SigningProvider>
-20
View File
@@ -1,20 +0,0 @@
import { type TCssVarsSchema, toNativeCssVars } from './css-vars';
export const injectCss = (options: { css?: string; cssVars?: TCssVarsSchema }) => {
const { css, cssVars } = options;
if (css) {
const style = document.createElement('style');
style.innerHTML = css;
document.head.appendChild(style);
}
if (cssVars) {
const nativeVars = toNativeCssVars(cssVars);
for (const [key, value] of Object.entries(nativeVars)) {
document.documentElement.style.setProperty(key, value);
}
}
};
@@ -25,6 +25,8 @@ export const StackAvatar = ({ first, zIndex, fallbackText = '', type }: StackAva
zIndexClass = ZIndexes[zIndex] ?? '';
}
console.log({ type, fallbackText });
switch (type) {
case RecipientStatusType.UNSIGNED:
classes = 'bg-dawn-200 text-dawn-900';
@@ -6,14 +6,22 @@ import { zodResolver } from '@hookform/resolvers/zod';
import { Trans, msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { AnimatePresence, motion } from 'framer-motion';
import { useSession } from 'next-auth/react';
import { useForm } from 'react-hook-form';
import { match } from 'ts-pattern';
import type { z } from 'zod';
import { WEBAPP_BASE_URL } from '@documenso/lib/constants/app';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { DocumentVisibility } from '@documenso/prisma/client';
import { trpc } from '@documenso/trpc/react';
import { ZUpdateTeamMutationSchema } from '@documenso/trpc/server/team-router/schema';
import {
DocumentVisibilitySelect,
DocumentVisibilityTooltip,
} from '@documenso/ui/components/document/document-visibility-select';
import { Button } from '@documenso/ui/primitives/button';
import { Checkbox } from '@documenso/ui/primitives/checkbox';
import {
Form,
FormControl,
@@ -29,17 +37,29 @@ export type UpdateTeamDialogProps = {
teamId: number;
teamName: string;
teamUrl: string;
documentVisibility?: DocumentVisibility;
includeSenderDetails?: boolean;
};
const ZUpdateTeamFormSchema = ZUpdateTeamMutationSchema.shape.data.pick({
name: true,
url: true,
documentVisibility: true,
includeSenderDetails: true,
});
type TUpdateTeamFormSchema = z.infer<typeof ZUpdateTeamFormSchema>;
export const UpdateTeamForm = ({ teamId, teamName, teamUrl }: UpdateTeamDialogProps) => {
export const UpdateTeamForm = ({
teamId,
teamName,
teamUrl,
documentVisibility,
includeSenderDetails,
}: UpdateTeamDialogProps) => {
const router = useRouter();
const { data: session } = useSession();
const email = session?.user?.email;
const { _ } = useLingui();
const { toast } = useToast();
@@ -48,17 +68,36 @@ export const UpdateTeamForm = ({ teamId, teamName, teamUrl }: UpdateTeamDialogPr
defaultValues: {
name: teamName,
url: teamUrl,
documentVisibility,
includeSenderDetails,
},
});
const { mutateAsync: updateTeam } = trpc.team.updateTeam.useMutation();
const includeSenderDetailsCheck = form.watch('includeSenderDetails');
const onFormSubmit = async ({ name, url }: TUpdateTeamFormSchema) => {
const mapVisibilityToRole = (visibility: DocumentVisibility): DocumentVisibility =>
match(visibility)
.with(DocumentVisibility.ADMIN, () => DocumentVisibility.ADMIN)
.with(DocumentVisibility.MANAGER_AND_ABOVE, () => DocumentVisibility.MANAGER_AND_ABOVE)
.otherwise(() => DocumentVisibility.EVERYONE);
const currentVisibilityRole = mapVisibilityToRole(
documentVisibility ?? DocumentVisibility.EVERYONE,
);
const onFormSubmit = async ({
name,
url,
documentVisibility,
includeSenderDetails,
}: TUpdateTeamFormSchema) => {
try {
await updateTeam({
data: {
name,
url,
documentVisibility,
includeSenderDetails,
},
teamId,
});
@@ -72,6 +111,8 @@ export const UpdateTeamForm = ({ teamId, teamName, teamUrl }: UpdateTeamDialogPr
form.reset({
name,
url,
documentVisibility,
includeSenderDetails,
});
if (url !== teamUrl) {
@@ -145,6 +186,68 @@ export const UpdateTeamForm = ({ teamId, teamName, teamUrl }: UpdateTeamDialogPr
)}
/>
<FormField
control={form.control}
name="documentVisibility"
render={({ field }) => (
<FormItem>
<FormLabel className="mt-4 flex flex-row items-center">
<Trans>Default Document Visibility</Trans>
<DocumentVisibilityTooltip />
</FormLabel>
<FormControl>
<DocumentVisibilitySelect
currentMemberRole={currentVisibilityRole}
isTeamSettings={true}
{...field}
onValueChange={field.onChange}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="mb-4">
<FormField
control={form.control}
name="includeSenderDetails"
render={({ field }) => (
<FormItem>
<div className="mt-6 flex flex-row items-center gap-4">
<FormLabel>
<Trans>Send on Behalf of Team</Trans>
</FormLabel>
<FormControl>
<Checkbox
className="h-5 w-5"
checkClassName="text-white"
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
</div>
{includeSenderDetailsCheck ? (
<blockquote className="text-foreground/50 text-xs italic">
<Trans>
"{email}" on behalf of "{teamName}" has invited you to sign "example
document".
</Trans>
</blockquote>
) : (
<blockquote className="text-foreground/50 text-xs italic">
<Trans>"{teamUrl}" has invited you to sign "example document".</Trans>
</blockquote>
)}
<FormMessage />
</FormItem>
)}
/>
</div>
<div className="flex flex-row justify-end space-x-4">
<AnimatePresence>
{form.formState.isDirty && (
@@ -167,7 +167,6 @@ export const DocumentHistorySheet = ({
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_CREATED },
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_COMPLETED },
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED },
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RESTORED },
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED },
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED },
{ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_REJECTED },
@@ -3,7 +3,7 @@ import type { HTMLAttributes } from 'react';
import type { MessageDescriptor } from '@lingui/core';
import { msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { CheckCircle2, Clock, File, TrashIcon } from 'lucide-react';
import { CheckCircle2, Clock, File } from 'lucide-react';
import type { LucideIcon } from 'lucide-react/dist/lucide-react';
import type { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
@@ -47,12 +47,6 @@ export const FRIENDLY_STATUS_MAP: Record<ExtendedDocumentStatus, FriendlyStatus>
labelExtended: msg`Document All`,
color: 'text-muted-foreground',
},
BIN: {
label: msg`Bin`,
labelExtended: msg`Document Bin`,
icon: TrashIcon,
color: 'text-red-500 dark:text-red-200',
},
};
export type DocumentStatusProps = HTMLAttributes<HTMLSpanElement> & {
@@ -138,7 +138,6 @@ export const ProfileForm = ({ className, user }: ProfileFormProps) => {
containerClassName={cn('rounded-lg border bg-background')}
defaultValue={user.signature ?? undefined}
onChange={(v) => onChange(v ?? '')}
allowTypedSignature={true}
/>
</FormControl>
<FormMessage />
+560 -236
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,6 +1,6 @@
{
"private": true,
"version": "1.8.1-rc.1",
"version": "1.8.0-rc.3",
"scripts": {
"build": "turbo run build",
"build:web": "turbo run build --filter=@documenso/web",
@@ -52,7 +52,7 @@
"husky": "^9.0.11",
"lint-staged": "^15.2.2",
"playwright": "1.43.0",
"prettier": "^3.3.3",
"prettier": "^2.5.1",
"rimraf": "^5.0.1",
"turbo": "^1.9.3"
},
-1
View File
@@ -302,7 +302,6 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
redirectUrl: body.meta.redirectUrl,
signingOrder: body.meta.signingOrder,
language: body.meta.language,
typedSignatureEnabled: body.meta.typedSignatureEnabled,
requestMetadata: extractNextApiRequestMetadata(args.req),
});
+6 -9
View File
@@ -3,6 +3,7 @@ import { z } from 'zod';
import { DATE_FORMATS, DEFAULT_DOCUMENT_DATE_FORMAT } from '@documenso/lib/constants/date-formats';
import { SUPPORTED_LANGUAGE_CODES } from '@documenso/lib/constants/i18n';
import '@documenso/lib/constants/time-zones';
import { DEFAULT_DOCUMENT_TIME_ZONE, TIME_ZONES } from '@documenso/lib/constants/time-zones';
import { ZUrlSchema } from '@documenso/lib/schemas/common';
import {
@@ -13,7 +14,6 @@ import {
import { ZFieldMetaSchema } from '@documenso/lib/types/field-meta';
import {
DocumentDataType,
DocumentDistributionMethod,
DocumentSigningOrder,
FieldType,
ReadStatus,
@@ -132,7 +132,6 @@ export const ZCreateDocumentMutationSchema = z.object({
redirectUrl: z.string(),
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
language: z.enum(SUPPORTED_LANGUAGE_CODES).optional(),
typedSignatureEnabled: z.boolean().optional().default(true),
})
.partial(),
authOptions: z
@@ -227,14 +226,14 @@ export type TCreateDocumentFromTemplateMutationResponseSchema = z.infer<
export const ZGenerateDocumentFromTemplateMutationSchema = z.object({
title: z.string().optional(),
externalId: z.string().optional(),
externalId: z.string().nullish(),
recipients: z
.array(
z.object({
id: z.number(),
email: z.string().email(),
name: z.string().optional(),
signingOrder: z.number().optional(),
email: z.string().email().min(1),
signingOrder: z.number().nullish(),
}),
)
.refine(
@@ -253,10 +252,8 @@ export const ZGenerateDocumentFromTemplateMutationSchema = z.object({
timezone: z.string(),
dateFormat: z.string(),
redirectUrl: ZUrlSchema,
signingOrder: z.nativeEnum(DocumentSigningOrder),
language: z.enum(SUPPORTED_LANGUAGE_CODES),
distributionMethod: z.nativeEnum(DocumentDistributionMethod),
typedSignatureEnabled: z.boolean(),
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
language: z.enum(SUPPORTED_LANGUAGE_CODES).optional(),
})
.partial()
.optional(),
@@ -1,271 +0,0 @@
import { expect, test } from '@playwright/test';
import { PDFDocument } from 'pdf-lib';
import { getDocumentByToken } from '@documenso/lib/server-only/document/get-document-by-token';
import { getFile } from '@documenso/lib/universal/upload/get-file';
import { prisma } from '@documenso/prisma';
import { DocumentStatus, FieldType } from '@documenso/prisma/client';
import { seedPendingDocumentWithFullFields } from '@documenso/prisma/seed/documents';
import { seedTeam } from '@documenso/prisma/seed/teams';
import { seedUser } from '@documenso/prisma/seed/users';
import { apiSignin } from '../fixtures/authentication';
test.describe('Signing Certificate Tests', () => {
test('individual document should always include signing certificate', async ({ page }) => {
const user = await seedUser();
const { document, recipients } = await seedPendingDocumentWithFullFields({
owner: user,
recipients: ['signer@example.com'],
fields: [FieldType.SIGNATURE],
});
const documentData = await prisma.documentData
.findFirstOrThrow({
where: {
id: document.documentDataId,
},
})
.then(async (data) => getFile(data));
const originalPdf = await PDFDocument.load(documentData);
const recipient = recipients[0];
// Sign the document
await page.goto(`/sign/${recipient.token}`);
const canvas = page.locator('canvas');
const box = await canvas.boundingBox();
if (box) {
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
await page.mouse.down();
await page.mouse.move(box.x + box.width / 4, box.y + box.height / 4);
await page.mouse.up();
}
for (const field of recipient.Field) {
await page.locator(`#field-${field.id}`).getByRole('button').click();
await expect(page.locator(`#field-${field.id}`)).toHaveAttribute('data-inserted', 'true');
}
await page.getByRole('button', { name: 'Complete' }).click();
await page.getByRole('button', { name: 'Sign' }).click();
await page.waitForURL(`/sign/${recipient.token}/complete`);
await expect(async () => {
const { status } = await getDocumentByToken({
token: recipient.token,
});
expect(status).toBe(DocumentStatus.COMPLETED);
}).toPass();
// Get the completed document
const completedDocument = await prisma.document.findFirstOrThrow({
where: { id: document.id },
include: { documentData: true },
});
const completedDocumentData = await getFile(completedDocument.documentData);
// Load the PDF and check number of pages
const pdfDoc = await PDFDocument.load(completedDocumentData);
expect(pdfDoc.getPageCount()).toBe(originalPdf.getPageCount() + 1); // Original + Certificate
});
test('team document with signing certificate enabled should include certificate', async ({
page,
}) => {
const team = await seedTeam();
const { document, recipients } = await seedPendingDocumentWithFullFields({
owner: team.owner,
recipients: ['signer@example.com'],
fields: [FieldType.SIGNATURE],
updateDocumentOptions: {
teamId: team.id,
},
});
await prisma.teamGlobalSettings.create({
data: {
teamId: team.id,
includeSigningCertificate: true,
},
});
const documentData = await prisma.documentData
.findFirstOrThrow({
where: {
id: document.documentDataId,
},
})
.then(async (data) => getFile(data));
const originalPdf = await PDFDocument.load(documentData);
const recipient = recipients[0];
// Sign the document
await page.goto(`/sign/${recipient.token}`);
const canvas = page.locator('canvas');
const box = await canvas.boundingBox();
if (box) {
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
await page.mouse.down();
await page.mouse.move(box.x + box.width / 4, box.y + box.height / 4);
await page.mouse.up();
}
for (const field of recipient.Field) {
await page.locator(`#field-${field.id}`).getByRole('button').click();
await expect(page.locator(`#field-${field.id}`)).toHaveAttribute('data-inserted', 'true');
}
await page.getByRole('button', { name: 'Complete' }).click();
await page.getByRole('button', { name: 'Sign' }).click();
await page.waitForURL(`/sign/${recipient.token}/complete`);
await expect(async () => {
const { status } = await getDocumentByToken({
token: recipient.token,
});
expect(status).toBe(DocumentStatus.COMPLETED);
}).toPass();
// Get the completed document
const completedDocument = await prisma.document.findFirstOrThrow({
where: { id: document.id },
include: { documentData: true },
});
const completedDocumentData = await getFile(completedDocument.documentData);
// Load the PDF and check number of pages
const completedPdf = await PDFDocument.load(completedDocumentData);
expect(completedPdf.getPageCount()).toBe(originalPdf.getPageCount() + 1); // Original + Certificate
});
test('team document with signing certificate disabled should not include certificate', async ({
page,
}) => {
const team = await seedTeam();
const { document, recipients } = await seedPendingDocumentWithFullFields({
owner: team.owner,
recipients: ['signer@example.com'],
fields: [FieldType.SIGNATURE],
updateDocumentOptions: {
teamId: team.id,
},
});
await prisma.teamGlobalSettings.create({
data: {
teamId: team.id,
includeSigningCertificate: false,
},
});
const documentData = await prisma.documentData
.findFirstOrThrow({
where: {
id: document.documentDataId,
},
})
.then(async (data) => getFile(data));
const originalPdf = await PDFDocument.load(documentData);
const recipient = recipients[0];
// Sign the document
await page.goto(`/sign/${recipient.token}`);
const canvas = page.locator('canvas');
const box = await canvas.boundingBox();
if (box) {
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
await page.mouse.down();
await page.mouse.move(box.x + box.width / 4, box.y + box.height / 4);
await page.mouse.up();
}
for (const field of recipient.Field) {
await page.locator(`#field-${field.id}`).getByRole('button').click();
await expect(page.locator(`#field-${field.id}`)).toHaveAttribute('data-inserted', 'true');
}
await page.getByRole('button', { name: 'Complete' }).click();
await page.getByRole('button', { name: 'Sign' }).click();
await page.waitForURL(`/sign/${recipient.token}/complete`);
await expect(async () => {
const { status } = await getDocumentByToken({
token: recipient.token,
});
expect(status).toBe(DocumentStatus.COMPLETED);
}).toPass();
// Get the completed document
const completedDocument = await prisma.document.findFirstOrThrow({
where: { id: document.id },
include: { documentData: true },
});
const completedDocumentData = await getFile(completedDocument.documentData);
// Load the PDF and check number of pages
const completedPdf = await PDFDocument.load(completedDocumentData);
expect(completedPdf.getPageCount()).toBe(originalPdf.getPageCount());
});
test('team can toggle signing certificate setting', async ({ page }) => {
const team = await seedTeam();
await apiSignin({
page,
email: team.owner.email,
redirectPath: `/t/${team.url}/settings/preferences`,
});
// Toggle signing certificate setting
await page.getByLabel('Include the Signing Certificate in the Document').click();
await page.getByRole('button', { name: /Save/ }).first().click();
await page.waitForTimeout(1000);
// Verify the setting was saved
const updatedTeam = await prisma.team.findFirstOrThrow({
where: { id: team.id },
include: { teamGlobalSettings: true },
});
expect(updatedTeam.teamGlobalSettings?.includeSigningCertificate).toBe(false);
// Toggle the setting back to true
await page.getByLabel('Include the Signing Certificate in the Document').click();
await page.getByRole('button', { name: /Save/ }).first().click();
await page.waitForTimeout(1000);
// Verify the setting was saved
const updatedTeam2 = await prisma.team.findFirstOrThrow({
where: { id: team.id },
include: { teamGlobalSettings: true },
});
expect(updatedTeam2.teamGlobalSettings?.includeSigningCertificate).toBe(true);
});
});
@@ -17,17 +17,19 @@ test('[TEAMS]: update the default document visibility in the team global setting
page,
email: team.owner.email,
password: 'password',
redirectPath: `/t/${team.url}/settings/preferences`,
redirectPath: `/t/${team.url}/settings`,
});
// !: Brittle selector
await page.getByRole('combobox').first().click();
await page.getByRole('combobox').click();
await page.getByRole('option', { name: 'Admin' }).click();
await page.getByRole('button', { name: 'Save' }).first().click();
await page.getByRole('button', { name: 'Update team' }).click();
const toast = page.locator('li[role="status"][data-state="open"]').first();
await expect(toast).toBeVisible();
await expect(toast.getByText('Document preferences updated', { exact: true })).toBeVisible();
await expect(toast.getByText('Success', { exact: true })).toBeVisible();
await expect(
toast.getByText('Your team has been successfully updated.', { exact: true }),
).toBeVisible();
});
test('[TEAMS]: update the sender details in the team global settings', async ({ page }) => {
@@ -39,7 +41,7 @@ test('[TEAMS]: update the sender details in the team global settings', async ({
page,
email: team.owner.email,
password: 'password',
redirectPath: `/t/${team.url}/settings/preferences`,
redirectPath: `/t/${team.url}/settings`,
});
const checkbox = page.getByLabel('Send on Behalf of Team');
@@ -47,11 +49,14 @@ test('[TEAMS]: update the sender details in the team global settings', async ({
await expect(checkbox).toBeChecked();
await page.getByRole('button', { name: 'Save' }).first().click();
await page.getByRole('button', { name: 'Update team' }).click();
const toast = page.locator('li[role="status"][data-state="open"]').first();
await expect(toast).toBeVisible();
await expect(toast.getByText('Document preferences updated', { exact: true })).toBeVisible();
await expect(toast.getByText('Success', { exact: true })).toBeVisible();
await expect(
toast.getByText('Your team has been successfully updated.', { exact: true }),
).toBeVisible();
await expect(checkbox).toBeChecked();
});
+2 -4
View File
@@ -7,17 +7,15 @@
"scripts": {
"test:dev": "NODE_OPTIONS=--experimental-require-module playwright test",
"test-ui:dev": "NODE_OPTIONS=--experimental-require-module playwright test --ui",
"test:e2e": "NODE_OPTIONS=--experimental-require-module start-server-and-test \"npm run start -w @documenso/web\" http://localhost:3000 \"playwright test $E2E_TEST_PATH\""
"test:e2e": "NODE_OPTIONS=--experimental-require-module start-server-and-test \"npm run start -w @documenso/web\" http://localhost:3000 \"playwright test\""
},
"keywords": [],
"author": "",
"devDependencies": {
"@playwright/test": "^1.18.1",
"@types/node": "^20.8.2",
"@documenso/lib": "*",
"@documenso/prisma": "*",
"@documenso/web": "*",
"pdf-lib": "^1.17.1"
"@documenso/web": "*"
},
"dependencies": {
"start-server-and-test": "^2.0.1"
@@ -9,7 +9,6 @@ export const getDocumentRelatedPrices = async () => {
return await getPricesByPlan([
STRIPE_PLAN_TYPE.REGULAR,
STRIPE_PLAN_TYPE.COMMUNITY,
STRIPE_PLAN_TYPE.PLATFORM,
STRIPE_PLAN_TYPE.ENTERPRISE,
]);
};
@@ -1,13 +0,0 @@
import { STRIPE_PLAN_TYPE } from '@documenso/lib/constants/billing';
import { getPricesByPlan } from './get-prices-by-plan';
export const getPlatformPlanPrices = async () => {
return await getPricesByPlan(STRIPE_PLAN_TYPE.PLATFORM);
};
export const getPlatformPlanPriceIds = async () => {
const prices = await getPlatformPlanPrices();
return prices.map((price) => price.id);
};
@@ -9,7 +9,6 @@ export const getPrimaryAccountPlanPrices = async () => {
return await getPricesByPlan([
STRIPE_PLAN_TYPE.REGULAR,
STRIPE_PLAN_TYPE.COMMUNITY,
STRIPE_PLAN_TYPE.PLATFORM,
STRIPE_PLAN_TYPE.ENTERPRISE,
]);
};
@@ -6,11 +6,7 @@ import { getPricesByPlan } from './get-prices-by-plan';
* Returns the Stripe prices of items that affect the amount of teams a user can create.
*/
export const getTeamRelatedPrices = async () => {
return await getPricesByPlan([
STRIPE_PLAN_TYPE.COMMUNITY,
STRIPE_PLAN_TYPE.PLATFORM,
STRIPE_PLAN_TYPE.ENTERPRISE,
]);
return await getPricesByPlan([STRIPE_PLAN_TYPE.COMMUNITY, STRIPE_PLAN_TYPE.ENTERPRISE]);
};
/**
@@ -1,61 +0,0 @@
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
import { subscriptionsContainsActivePlan } from '@documenso/lib/utils/billing';
import { prisma } from '@documenso/prisma';
import type { Document, Subscription } from '@documenso/prisma/client';
import { getPlatformPlanPriceIds } from '../stripe/get-platform-plan-prices';
export type IsDocumentPlatformOptions = Pick<Document, 'id' | 'userId' | 'teamId'>;
/**
* Whether the user is platform, or has permission to use platform features on
* behalf of their team.
*
* It is assumed that the provided user is part of the provided team.
*/
export const isDocumentPlatform = async ({
userId,
teamId,
}: IsDocumentPlatformOptions): Promise<boolean> => {
let subscriptions: Subscription[] = [];
if (!IS_BILLING_ENABLED()) {
return true;
}
if (teamId) {
subscriptions = await prisma.team
.findFirstOrThrow({
where: {
id: teamId,
},
select: {
owner: {
include: {
Subscription: true,
},
},
},
})
.then((team) => team.owner.Subscription);
} else {
subscriptions = await prisma.user
.findFirstOrThrow({
where: {
id: userId,
},
select: {
Subscription: true,
},
})
.then((user) => user.Subscription);
}
if (subscriptions.length === 0) {
return false;
}
const platformPlanPriceIds = await getPlatformPlanPriceIds();
return subscriptionsContainsActivePlan(subscriptions, platformPlanPriceIds);
};
-1
View File
@@ -7,6 +7,5 @@ export enum STRIPE_PLAN_TYPE {
REGULAR = 'regular',
TEAM = 'team',
COMMUNITY = 'community',
PLATFORM = 'platform',
ENTERPRISE = 'enterprise',
}
@@ -17,14 +17,12 @@ const SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION_SCHEMA = z.object({
documentVisibility: z.nativeEnum(DocumentVisibility),
documentLanguage: z.string(),
includeSenderDetails: z.boolean(),
includeSigningCertificate: z.boolean(),
brandingEnabled: z.boolean(),
brandingLogo: z.string(),
brandingUrl: z.string(),
brandingCompanyDetails: z.string(),
brandingHidePoweredBy: z.boolean(),
teamId: z.number(),
typedSignatureEnabled: z.boolean(),
})
.nullish(),
}),
@@ -57,17 +57,7 @@ export const SEAL_DOCUMENT_JOB_DEFINITION = {
},
},
include: {
documentMeta: true,
Recipient: true,
team: {
select: {
teamGlobalSettings: {
select: {
includeSigningCertificate: true,
},
},
},
},
},
});
@@ -127,13 +117,7 @@ export const SEAL_DOCUMENT_JOB_DEFINITION = {
}
const pdfData = await getFile(documentData);
const certificateData =
(document.team?.teamGlobalSettings?.includeSigningCertificate ?? true)
? await getCertificatePdf({
documentId,
language: document.documentMeta?.language,
}).catch(() => null)
: null;
const certificateData = await getCertificatePdf({ documentId }).catch(() => null);
const newDataId = await io.runTask('decorate-and-sign-pdf', async () => {
const pdfDoc = await PDFDocument.load(pdfData);
+1 -1
View File
@@ -51,7 +51,7 @@
"pg": "^8.11.3",
"playwright": "1.43.0",
"react": "^18",
"remeda": "^2.17.3",
"remeda": "^2.12.1",
"sharp": "0.32.6",
"stripe": "^12.7.0",
"ts-pattern": "^5.0.5",
@@ -13,7 +13,6 @@ export const getDocumentStats = async () => {
[ExtendedDocumentStatus.DRAFT]: 0,
[ExtendedDocumentStatus.PENDING]: 0,
[ExtendedDocumentStatus.COMPLETED]: 0,
[ExtendedDocumentStatus.BIN]: 0,
[ExtendedDocumentStatus.ALL]: 0,
};
@@ -112,7 +112,6 @@ export const createDocument = async ({
documentMeta: {
create: {
language: team?.teamGlobalSettings?.documentLanguage,
typedSignatureEnabled: team?.teamGlobalSettings?.typedSignatureEnabled,
},
},
},
@@ -158,16 +158,6 @@ const handleDocumentOwnerDelete = async ({
}),
});
// Soft delete for document recipients since the owner is deleting it
await tx.recipient.updateMany({
where: {
documentId: document.id,
},
data: {
documentDeletedAt: new Date().toISOString(),
},
});
return await tx.document.update({
where: {
id: document.id,
@@ -64,7 +64,6 @@ export const findDocumentAuditLogs = async ({
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_COMPLETED,
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_CREATED,
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_DELETED,
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RESTORED,
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED,
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED,
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_REJECTED,
@@ -2,8 +2,15 @@ import { DateTime } from 'luxon';
import { P, match } from 'ts-pattern';
import { prisma } from '@documenso/prisma';
import type { Document, DocumentSource, Team, TeamEmail, User } from '@documenso/prisma/client';
import { Prisma, RecipientRole, SigningStatus, TeamMemberRole } from '@documenso/prisma/client';
import { RecipientRole, SigningStatus, TeamMemberRole } from '@documenso/prisma/client';
import type {
Document,
DocumentSource,
Prisma,
Team,
TeamEmail,
User,
} from '@documenso/prisma/client';
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
import { DocumentVisibility } from '../../types/document-visibility';
@@ -81,12 +88,14 @@ export const findDocuments = async ({
const teamMemberRole = team?.members[0].role ?? null;
const termFilters = match(term)
.with(P.string.minLength(1), () => ({
title: {
contains: term,
mode: Prisma.QueryMode.insensitive,
},
}))
.with(P.string.minLength(1), () => {
return {
title: {
contains: term,
mode: 'insensitive',
},
} as const;
})
.otherwise(() => undefined);
const searchFilter: Prisma.DocumentWhereInput = {
@@ -132,8 +141,6 @@ export const findDocuments = async ({
let filters: Prisma.DocumentWhereInput | null = findDocumentsFilter(status, user);
console.log('find documets team', team);
if (team) {
filters = findTeamDocumentsFilter(status, team, visibilityFilters);
}
@@ -286,21 +293,19 @@ export const findDocuments = async ({
} satisfies FindResultSet<typeof data>;
};
export const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
return match<ExtendedDocumentStatus, Prisma.DocumentWhereInput>(status)
.with(ExtendedDocumentStatus.ALL, () => ({
OR: [
{
userId: user.id,
teamId: null,
deletedAt: null,
},
{
status: ExtendedDocumentStatus.COMPLETED,
Recipient: {
some: {
email: user.email,
documentDeletedAt: null,
},
},
},
@@ -309,7 +314,6 @@ export const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User)
Recipient: {
some: {
email: user.email,
documentDeletedAt: null,
},
},
},
@@ -326,7 +330,6 @@ export const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User)
role: {
not: RecipientRole.CC,
},
documentDeletedAt: null,
},
},
}))
@@ -341,7 +344,6 @@ export const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User)
userId: user.id,
teamId: null,
status: ExtendedDocumentStatus.PENDING,
deletedAt: null,
},
{
status: ExtendedDocumentStatus.PENDING,
@@ -352,7 +354,6 @@ export const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User)
role: {
not: RecipientRole.CC,
},
documentDeletedAt: null,
},
},
},
@@ -364,49 +365,12 @@ export const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User)
userId: user.id,
teamId: null,
status: ExtendedDocumentStatus.COMPLETED,
deletedAt: null,
},
{
status: ExtendedDocumentStatus.COMPLETED,
Recipient: {
some: {
email: user.email,
documentDeletedAt: null,
},
},
},
],
}))
.with(ExtendedDocumentStatus.BIN, () => ({
OR: [
{
userId: user.id,
teamId: null,
deletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
{
status: ExtendedDocumentStatus.PENDING,
Recipient: {
some: {
email: user.email,
signingStatus: SigningStatus.SIGNED,
documentDeletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
},
},
{
status: ExtendedDocumentStatus.COMPLETED,
Recipient: {
some: {
email: user.email,
signingStatus: SigningStatus.SIGNED,
documentDeletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
},
},
@@ -444,7 +408,7 @@ export const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User)
* @param team The team to find the documents for.
* @returns A filter which can be applied to the Prisma Document schema.
*/
export const findTeamDocumentsFilter = (
const findTeamDocumentsFilter = (
status: ExtendedDocumentStatus,
team: Team & { teamEmail: TeamEmail | null },
visibilityFilters: Prisma.DocumentWhereInput[],
@@ -454,16 +418,17 @@ export const findTeamDocumentsFilter = (
return match<ExtendedDocumentStatus, Prisma.DocumentWhereInput | null>(status)
.with(ExtendedDocumentStatus.ALL, () => {
const filter: Prisma.DocumentWhereInput = {
// Filter to display all documents that belong to the team.
OR: [
{
teamId: team.id,
deletedAt: null,
OR: visibilityFilters,
},
],
};
if (teamEmail && filter.OR) {
// Filter to display all documents received by the team email that are not draft.
filter.OR.push({
status: {
not: ExtendedDocumentStatus.DRAFT,
@@ -473,15 +438,14 @@ export const findTeamDocumentsFilter = (
email: teamEmail,
},
},
deletedAt: null,
OR: visibilityFilters,
});
// Filter to display all documents that have been sent by the team email.
filter.OR.push({
User: {
email: teamEmail,
},
deletedAt: null,
OR: visibilityFilters,
});
}
@@ -489,6 +453,7 @@ export const findTeamDocumentsFilter = (
return filter;
})
.with(ExtendedDocumentStatus.INBOX, () => {
// Return a filter that will return nothing.
if (!teamEmail) {
return null;
}
@@ -506,7 +471,6 @@ export const findTeamDocumentsFilter = (
},
},
},
deletedAt: null,
OR: visibilityFilters,
};
})
@@ -516,7 +480,6 @@ export const findTeamDocumentsFilter = (
{
teamId: team.id,
status: ExtendedDocumentStatus.DRAFT,
deletedAt: null,
OR: visibilityFilters,
},
],
@@ -528,7 +491,6 @@ export const findTeamDocumentsFilter = (
User: {
email: teamEmail,
},
deletedAt: null,
OR: visibilityFilters,
});
}
@@ -541,7 +503,6 @@ export const findTeamDocumentsFilter = (
{
teamId: team.id,
status: ExtendedDocumentStatus.PENDING,
deletedAt: null,
OR: visibilityFilters,
},
],
@@ -570,7 +531,6 @@ export const findTeamDocumentsFilter = (
OR: visibilityFilters,
},
],
deletedAt: null,
});
}
@@ -579,7 +539,6 @@ export const findTeamDocumentsFilter = (
.with(ExtendedDocumentStatus.COMPLETED, () => {
const filter: Prisma.DocumentWhereInput = {
status: ExtendedDocumentStatus.COMPLETED,
deletedAt: null,
OR: [
{
teamId: team.id,
@@ -609,42 +568,5 @@ export const findTeamDocumentsFilter = (
return filter;
})
.with(ExtendedDocumentStatus.BIN, () => {
const filters: Prisma.DocumentWhereInput[] = [
{
teamId: team.id,
deletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
];
if (teamEmail) {
filters.push(
{
User: {
email: teamEmail,
},
deletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
{
Recipient: {
some: {
email: teamEmail,
documentDeletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
},
},
);
}
return {
OR: filters,
};
})
.exhaustive();
};
@@ -1,118 +0,0 @@
import { DateTime } from 'luxon';
import { match } from 'ts-pattern';
import {
type PeriodSelectorValue,
findDocumentsFilter,
findTeamDocumentsFilter,
} from '@documenso/lib/server-only/document/find-documents';
import { prisma } from '@documenso/prisma';
import type { Prisma, Team, TeamEmail, User } from '@documenso/prisma/client';
import { DocumentVisibility, TeamMemberRole } from '@documenso/prisma/client';
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
export type GetStatsInput = {
user: User;
team?: Team & { teamEmail: TeamEmail | null } & { currentTeamMember?: { role: TeamMemberRole } };
period?: PeriodSelectorValue;
search?: string;
};
export const getStats = async ({ user, period, search, ...options }: GetStatsInput) => {
let createdAt: Prisma.DocumentWhereInput['createdAt'];
if (period) {
const daysAgo = parseInt(period.replace(/d$/, ''), 10);
const startOfPeriod = DateTime.now().minus({ days: daysAgo }).startOf('day');
createdAt = {
gte: startOfPeriod.toJSDate(),
};
}
const stats: Record<ExtendedDocumentStatus, number> = {
[ExtendedDocumentStatus.DRAFT]: 0,
[ExtendedDocumentStatus.PENDING]: 0,
[ExtendedDocumentStatus.COMPLETED]: 0,
[ExtendedDocumentStatus.INBOX]: 0,
[ExtendedDocumentStatus.ALL]: 0,
[ExtendedDocumentStatus.BIN]: 0,
};
const searchFilter: Prisma.DocumentWhereInput = search
? {
OR: [
{ title: { contains: search, mode: 'insensitive' } },
{ Recipient: { some: { name: { contains: search, mode: 'insensitive' } } } },
{ Recipient: { some: { email: { contains: search, mode: 'insensitive' } } } },
],
}
: {};
const visibilityFilters = [
match(options.team?.currentTeamMember?.role)
.with(TeamMemberRole.ADMIN, () => ({
visibility: {
in: [
DocumentVisibility.EVERYONE,
DocumentVisibility.MANAGER_AND_ABOVE,
DocumentVisibility.ADMIN,
],
},
}))
.with(TeamMemberRole.MANAGER, () => ({
visibility: {
in: [DocumentVisibility.EVERYONE, DocumentVisibility.MANAGER_AND_ABOVE],
},
}))
.otherwise(() => ({ visibility: DocumentVisibility.EVERYONE })),
];
const statusCounts = await Promise.all(
Object.values(ExtendedDocumentStatus).map(async (status) => {
if (status === ExtendedDocumentStatus.ALL) {
return;
}
const filter = options.team
? findTeamDocumentsFilter(status, options.team, visibilityFilters)
: findDocumentsFilter(status, user);
if (filter === null) {
return { status, count: 0 };
}
const whereClause = {
...filter,
...(createdAt && { createdAt }),
...searchFilter,
};
const count = await prisma.document.count({
where: whereClause,
});
return { status, count };
}),
);
statusCounts.forEach((result) => {
if (result) {
stats[result.status] = result.count;
if (
result.status !== ExtendedDocumentStatus.BIN &&
[
ExtendedDocumentStatus.DRAFT,
ExtendedDocumentStatus.PENDING,
ExtendedDocumentStatus.COMPLETED,
ExtendedDocumentStatus.INBOX,
].includes(result.status)
) {
stats[ExtendedDocumentStatus.ALL] += result.count;
}
}
});
return stats;
};
+134 -290
View File
@@ -1,16 +1,12 @@
import { DateTime } from 'luxon';
import { match } from 'ts-pattern';
// eslint-disable-next-line import/no-extraneous-dependencies
import type { PeriodSelectorValue } from '@documenso/lib/server-only/document/find-documents';
import { prisma } from '@documenso/prisma';
import { TeamMemberRole } from '@documenso/prisma/client';
import type { Prisma, User } from '@documenso/prisma/client';
import {
DocumentVisibility,
RecipientRole,
SigningStatus,
TeamMemberRole,
} from '@documenso/prisma/client';
import { SigningStatus } from '@documenso/prisma/client';
import { DocumentVisibility } from '@documenso/prisma/client';
import { isExtendedDocumentStatus } from '@documenso/prisma/guards/is-extended-document-status';
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
@@ -34,7 +30,7 @@ export const getStats = async ({ user, period, search, ...options }: GetStatsInp
};
}
const [ownerCounts, notSignedCounts, hasSignedCounts, deletedCounts] = await (options.team
const [ownerCounts, notSignedCounts, hasSignedCounts] = await (options.team
? getTeamCounts({
...options.team,
createdAt,
@@ -50,7 +46,6 @@ export const getStats = async ({ user, period, search, ...options }: GetStatsInp
[ExtendedDocumentStatus.COMPLETED]: 0,
[ExtendedDocumentStatus.INBOX]: 0,
[ExtendedDocumentStatus.ALL]: 0,
[ExtendedDocumentStatus.BIN]: 0,
};
ownerCounts.forEach((stat) => {
@@ -71,10 +66,6 @@ export const getStats = async ({ user, period, search, ...options }: GetStatsInp
}
});
deletedCounts.forEach((stat) => {
stats[ExtendedDocumentStatus.BIN] += stat._count._all;
});
Object.keys(stats).forEach((key) => {
if (key !== ExtendedDocumentStatus.ALL && isExtendedDocumentStatus(key)) {
stats[ExtendedDocumentStatus.ALL] += stats[key];
@@ -107,45 +98,25 @@ const getCounts = async ({ user, createdAt, search }: GetCountsOption) => {
_all: true,
},
where: {
OR: [
{
userId: user.id,
teamId: null,
deletedAt: null,
},
{
status: {
not: ExtendedDocumentStatus.DRAFT,
},
Recipient: {
some: {
email: user.email,
documentDeletedAt: null,
},
},
},
],
userId: user.id,
createdAt,
teamId: null,
deletedAt: null,
AND: [searchFilter],
},
}),
// Not signed counts (Inbox).
// Not signed counts.
prisma.document.groupBy({
by: ['status'],
_count: {
_all: true,
},
where: {
status: {
not: ExtendedDocumentStatus.DRAFT,
},
status: ExtendedDocumentStatus.PENDING,
Recipient: {
some: {
email: user.email,
signingStatus: SigningStatus.NOT_SIGNED,
role: {
not: RecipientRole.CC,
},
documentDeletedAt: null,
},
},
@@ -160,70 +131,20 @@ const getCounts = async ({ user, createdAt, search }: GetCountsOption) => {
_all: true,
},
where: {
OR: [
{
userId: user.id,
teamId: null,
status: ExtendedDocumentStatus.PENDING,
deletedAt: null,
},
{
status: ExtendedDocumentStatus.PENDING,
Recipient: {
some: {
email: user.email,
signingStatus: SigningStatus.SIGNED,
role: {
not: RecipientRole.CC,
},
documentDeletedAt: null,
},
},
},
{
userId: user.id,
teamId: null,
status: ExtendedDocumentStatus.COMPLETED,
deletedAt: null,
},
{
status: ExtendedDocumentStatus.COMPLETED,
Recipient: {
some: {
email: user.email,
documentDeletedAt: null,
},
},
},
],
createdAt,
AND: [searchFilter],
},
}),
// Deleted counts.
prisma.document.groupBy({
by: ['status'],
_count: {
_all: true,
},
where: {
OR: [
{
userId: user.id,
teamId: null,
deletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
User: {
email: {
not: user.email,
},
},
OR: [
{
status: ExtendedDocumentStatus.PENDING,
Recipient: {
some: {
email: user.email,
signingStatus: SigningStatus.SIGNED,
documentDeletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
documentDeletedAt: null,
},
},
},
@@ -232,9 +153,8 @@ const getCounts = async ({ user, createdAt, search }: GetCountsOption) => {
Recipient: {
some: {
email: user.email,
documentDeletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
signingStatus: SigningStatus.SIGNED,
documentDeletedAt: null,
},
},
},
@@ -257,7 +177,9 @@ type GetTeamCountsOption = {
};
const getTeamCounts = async (options: GetTeamCountsOption) => {
const { createdAt, teamId, teamEmail, senderIds = [], currentTeamMemberRole, search } = options;
const { createdAt, teamId, teamEmail } = options;
const senderIds = options.senderIds ?? [];
const userIdWhereClause: Prisma.DocumentWhereInput['userId'] =
senderIds.length > 0
@@ -266,226 +188,148 @@ const getTeamCounts = async (options: GetTeamCountsOption) => {
}
: undefined;
const searchFilter: Prisma.DocumentWhereInput = search
? {
OR: [
{ title: { contains: search, mode: 'insensitive' } },
{ Recipient: { some: { name: { contains: search, mode: 'insensitive' } } } },
{ Recipient: { some: { email: { contains: search, mode: 'insensitive' } } } },
],
}
: {};
const searchFilter: Prisma.DocumentWhereInput = {
OR: [
{ title: { contains: options.search, mode: 'insensitive' } },
{ Recipient: { some: { name: { contains: options.search, mode: 'insensitive' } } } },
{ Recipient: { some: { email: { contains: options.search, mode: 'insensitive' } } } },
],
};
const visibilityFilters = [
match(currentTeamMemberRole)
.with(TeamMemberRole.ADMIN, () => ({
visibility: {
in: [
DocumentVisibility.EVERYONE,
DocumentVisibility.MANAGER_AND_ABOVE,
DocumentVisibility.ADMIN,
],
},
}))
.with(TeamMemberRole.MANAGER, () => ({
visibility: {
in: [DocumentVisibility.EVERYONE, DocumentVisibility.MANAGER_AND_ABOVE],
},
}))
.otherwise(() => ({ visibility: DocumentVisibility.EVERYONE })),
];
let ownerCountsWhereInput: Prisma.DocumentWhereInput = {
userId: userIdWhereClause,
createdAt,
teamId,
deletedAt: null,
};
return Promise.all([
// Owner counts (ALL)
prisma.document.groupBy({
by: ['status'],
_count: { _all: true },
where: {
let notSignedCountsGroupByArgs = null;
let hasSignedCountsGroupByArgs = null;
const visibilityFiltersWhereInput: Prisma.DocumentWhereInput = {
AND: [
{ deletedAt: null },
{
OR: [
match(options.currentTeamMemberRole)
.with(TeamMemberRole.ADMIN, () => ({
visibility: {
in: [
DocumentVisibility.EVERYONE,
DocumentVisibility.MANAGER_AND_ABOVE,
DocumentVisibility.ADMIN,
],
},
}))
.with(TeamMemberRole.MANAGER, () => ({
visibility: {
in: [DocumentVisibility.EVERYONE, DocumentVisibility.MANAGER_AND_ABOVE],
},
}))
.otherwise(() => ({
visibility: {
equals: DocumentVisibility.EVERYONE,
},
})),
{
teamId,
deletedAt: null,
OR: visibilityFilters,
OR: [
{ userId: options.userId },
{ Recipient: { some: { email: options.currentUserEmail } } },
],
},
...(teamEmail
? [
{
status: {
not: ExtendedDocumentStatus.DRAFT,
},
Recipient: {
some: {
email: teamEmail,
documentDeletedAt: null,
},
},
deletedAt: null,
OR: visibilityFilters,
},
{
User: {
email: teamEmail,
},
deletedAt: null,
OR: visibilityFilters,
},
]
: []),
],
},
],
};
ownerCountsWhereInput = {
...ownerCountsWhereInput,
...visibilityFiltersWhereInput,
...searchFilter,
};
if (teamEmail) {
ownerCountsWhereInput = {
userId: userIdWhereClause,
createdAt,
OR: [
{
teamId,
},
{
User: {
email: teamEmail,
},
},
],
deletedAt: null,
};
notSignedCountsGroupByArgs = {
by: ['status'],
_count: {
_all: true,
},
where: {
userId: userIdWhereClause,
createdAt,
...searchFilter,
status: ExtendedDocumentStatus.PENDING,
Recipient: {
some: {
email: teamEmail,
signingStatus: SigningStatus.NOT_SIGNED,
documentDeletedAt: null,
},
},
deletedAt: null,
},
}),
} satisfies Prisma.DocumentGroupByArgs;
// Not signed counts (INBOX)
prisma.document.groupBy({
hasSignedCountsGroupByArgs = {
by: ['status'],
_count: { _all: true },
where: teamEmail
? {
userId: userIdWhereClause,
createdAt,
status: {
not: ExtendedDocumentStatus.DRAFT,
},
_count: {
_all: true,
},
where: {
userId: userIdWhereClause,
createdAt,
OR: [
{
status: ExtendedDocumentStatus.PENDING,
Recipient: {
some: {
email: teamEmail,
signingStatus: SigningStatus.NOT_SIGNED,
role: {
not: RecipientRole.CC,
},
signingStatus: SigningStatus.SIGNED,
documentDeletedAt: null,
},
},
deletedAt: null,
OR: visibilityFilters,
...searchFilter,
}
: {
userId: userIdWhereClause,
createdAt,
AND: [
{
OR: [{ id: -1 }], // Empty set if no team email
},
searchFilter,
],
},
}),
// Has signed counts (PENDING + COMPLETED)
prisma.document.groupBy({
by: ['status'],
_count: { _all: true },
where: {
userId: userIdWhereClause,
createdAt,
OR: [
{
teamId,
status: ExtendedDocumentStatus.PENDING,
deletedAt: null,
OR: visibilityFilters,
},
{
teamId,
status: ExtendedDocumentStatus.COMPLETED,
Recipient: {
some: {
email: teamEmail,
signingStatus: SigningStatus.SIGNED,
documentDeletedAt: null,
},
},
deletedAt: null,
OR: visibilityFilters,
},
...(teamEmail
? [
{
status: ExtendedDocumentStatus.PENDING,
OR: [
{
Recipient: {
some: {
email: teamEmail,
signingStatus: SigningStatus.SIGNED,
role: {
not: RecipientRole.CC,
},
documentDeletedAt: null,
},
},
OR: visibilityFilters,
},
{
User: {
email: teamEmail,
},
OR: visibilityFilters,
},
],
deletedAt: null,
},
{
status: ExtendedDocumentStatus.COMPLETED,
OR: [
{
Recipient: {
some: {
email: teamEmail,
documentDeletedAt: null,
},
},
OR: visibilityFilters,
},
{
User: {
email: teamEmail,
},
OR: visibilityFilters,
},
],
deletedAt: null,
},
]
: []),
],
...searchFilter,
},
}),
} satisfies Prisma.DocumentGroupByArgs;
}
// Deleted counts (BIN)
return Promise.all([
prisma.document.groupBy({
by: ['status'],
_count: { _all: true },
where: {
OR: [
{
teamId,
deletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
...(teamEmail
? [
{
User: {
email: teamEmail,
},
deletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
{
Recipient: {
some: {
email: teamEmail,
documentDeletedAt: {
gte: DateTime.now().minus({ days: 30 }).startOf('day').toJSDate(),
},
},
},
},
]
: []),
],
...searchFilter,
_count: {
_all: true,
},
where: ownerCountsWhereInput,
}),
notSignedCountsGroupByArgs ? prisma.document.groupBy(notSignedCountsGroupByArgs) : [],
hasSignedCountsGroupByArgs ? prisma.document.groupBy(hasSignedCountsGroupByArgs) : [],
]);
};
@@ -1,149 +0,0 @@
'use server';
import { prisma } from '@documenso/prisma';
import type { Document, DocumentMeta, Recipient, User } from '@documenso/prisma/client';
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
import type { RequestMetadata } from '../../universal/extract-request-metadata';
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
export type RestoreDocumentOptions = {
id: number;
userId: number;
teamId?: number;
requestMetadata?: RequestMetadata;
};
export const restoreDocument = async ({
id,
userId,
teamId,
requestMetadata,
}: RestoreDocumentOptions) => {
const user = await prisma.user.findUnique({
where: {
id: userId,
},
});
if (!user) {
throw new Error('User not found');
}
const document = await prisma.document.findUnique({
where: {
id,
},
include: {
Recipient: true,
documentMeta: true,
team: {
select: {
members: true,
},
},
},
});
if (!document || (teamId !== undefined && teamId !== document.teamId)) {
throw new Error('Document not found');
}
const isUserOwner = document.userId === userId;
const isUserTeamMember = document.team?.members.some((member) => member.userId === userId);
const userRecipient = document.Recipient.find((recipient) => recipient.email === user.email);
if (!isUserOwner && !isUserTeamMember && !userRecipient) {
throw new Error('Not allowed');
}
// Handle restoring the actual document if user has permission.
if (isUserOwner || isUserTeamMember) {
await handleDocumentOwnerRestore({
document,
user,
requestMetadata,
});
}
// Continue to show the document to the user if they are a recipient.
if (userRecipient?.documentDeletedAt !== null) {
await prisma.recipient
.update({
where: {
id: userRecipient?.id,
},
data: {
documentDeletedAt: null,
},
})
.catch(() => {
// Do nothing.
});
}
// Return partial document for API v1 response.
return {
id: document.id,
userId: document.userId,
teamId: document.teamId,
title: document.title,
status: document.status,
documentDataId: document.documentDataId,
createdAt: document.createdAt,
updatedAt: document.updatedAt,
completedAt: document.completedAt,
};
};
type HandleDocumentOwnerRestoreOptions = {
document: Document & {
Recipient: Recipient[];
documentMeta: DocumentMeta | null;
};
user: User;
requestMetadata?: RequestMetadata;
};
const handleDocumentOwnerRestore = async ({
document,
user,
requestMetadata,
}: HandleDocumentOwnerRestoreOptions) => {
if (!document.deletedAt) {
return;
}
// Restore soft-deleted documents.
return await prisma.$transaction(async (tx) => {
await tx.documentAuditLog.create({
data: createDocumentAuditLogData({
documentId: document.id,
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RESTORED,
user,
requestMetadata,
data: {
type: 'RESTORE',
},
}),
});
await tx.recipient.updateMany({
where: {
documentId: document.id,
},
data: {
documentDeletedAt: null,
},
});
return await tx.document.update({
where: {
id: document.id,
},
data: {
deletedAt: null,
},
});
});
};
@@ -10,6 +10,7 @@ import { DocumentStatus, RecipientRole, SigningStatus } from '@documenso/prisma/
import { WebhookTriggerEvents } from '@documenso/prisma/client';
import { signPdf } from '@documenso/signing';
import { ZSupportedLanguageCodeSchema } from '../../constants/i18n';
import type { RequestMetadata } from '../../universal/extract-request-metadata';
import { getFile } from '../../universal/upload/get-file';
import { putPdfFile } from '../../universal/upload/put-file';
@@ -47,15 +48,6 @@ export const sealDocument = async ({
documentData: true,
documentMeta: true,
Recipient: true,
team: {
select: {
teamGlobalSettings: {
select: {
includeSigningCertificate: true,
},
},
},
},
},
});
@@ -100,13 +92,11 @@ export const sealDocument = async ({
// !: Need to write the fields onto the document as a hard copy
const pdfData = await getFile(documentData);
const certificateData =
(document.team?.teamGlobalSettings?.includeSigningCertificate ?? true)
? await getCertificatePdf({
documentId,
language: document.documentMeta?.language,
}).catch(() => null)
: null;
const documentLanguage = ZSupportedLanguageCodeSchema.parse(document.documentMeta?.language);
const certificate = await getCertificatePdf({ documentId, language: documentLanguage })
.then(async (doc) => PDFDocument.load(doc))
.catch(() => null);
const doc = await PDFDocument.load(pdfData);
@@ -115,9 +105,7 @@ export const sealDocument = async ({
flattenForm(doc);
flattenAnnotations(doc);
if (certificateData) {
const certificate = await PDFDocument.load(certificateData);
if (certificate) {
const certificatePages = await doc.copyPages(certificate, certificate.getPageIndices());
certificatePages.forEach((page) => {
@@ -177,10 +177,6 @@ export const signFieldWithToken = async ({
throw new Error('Signature field must have a signature');
}
if (isSignatureField && !documentMeta?.typedSignatureEnabled && typedSignature) {
throw new Error('Typed signatures are not allowed. Please draw your signature');
}
return await prisma.$transaction(async (tx) => {
const updatedField = await tx.field.update({
where: {
@@ -2,13 +2,12 @@ import { DateTime } from 'luxon';
import type { Browser } from 'playwright';
import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app';
import { type SupportedLanguageCodes, isValidLanguageCode } from '../../constants/i18n';
import type { SupportedLanguageCodes } from '../../constants/i18n';
import { encryptSecondaryData } from '../crypto/encrypt';
export type GetCertificatePdfOptions = {
documentId: number;
// eslint-disable-next-line @typescript-eslint/ban-types
language?: SupportedLanguageCodes | (string & {});
language?: SupportedLanguageCodes;
};
export const getCertificatePdf = async ({ documentId, language }: GetCertificatePdfOptions) => {
@@ -39,15 +38,15 @@ export const getCertificatePdf = async ({ documentId, language }: GetCertificate
const page = await browserContext.newPage();
const lang = isValidLanguageCode(language) ? language : 'en';
await page.context().addCookies([
{
name: 'language',
value: lang,
url: NEXT_PUBLIC_WEBAPP_URL(),
},
]);
if (language) {
await page.context().addCookies([
{
name: 'language',
value: language,
url: NEXT_PUBLIC_WEBAPP_URL(),
},
]);
}
await page.goto(`${NEXT_PUBLIC_WEBAPP_URL()}/__htmltopdf/certificate?d=${encryptedId}`, {
waitUntil: 'networkidle',
@@ -82,10 +82,7 @@ export const insertFieldInPDF = async (pdf: PDFDocument, field: FieldWithSignatu
const fieldX = pageWidth * (Number(field.positionX) / 100);
const fieldY = pageHeight * (Number(field.positionY) / 100);
const font = await pdf.embedFont(
isSignatureField ? fontCaveat : fontNoto,
isSignatureField ? { features: { calt: false } } : undefined,
);
const font = await pdf.embedFont(isSignatureField ? fontCaveat : fontNoto);
if (field.type === FieldType.SIGNATURE || field.type === FieldType.FREE_SIGNATURE) {
await pdf.embedFont(fontCaveat);
@@ -95,89 +92,45 @@ export const insertFieldInPDF = async (pdf: PDFDocument, field: FieldWithSignatu
.with(
{
type: P.union(FieldType.SIGNATURE, FieldType.FREE_SIGNATURE),
Signature: { signatureImageAsBase64: P.string },
},
async (field) => {
if (field.Signature?.signatureImageAsBase64) {
const image = await pdf.embedPng(field.Signature?.signatureImageAsBase64 ?? '');
const image = await pdf.embedPng(field.Signature?.signatureImageAsBase64 ?? '');
let imageWidth = image.width;
let imageHeight = image.height;
let imageWidth = image.width;
let imageHeight = image.height;
const scalingFactor = Math.min(fieldWidth / imageWidth, fieldHeight / imageHeight, 1);
const scalingFactor = Math.min(fieldWidth / imageWidth, fieldHeight / imageHeight, 1);
imageWidth = imageWidth * scalingFactor;
imageHeight = imageHeight * scalingFactor;
imageWidth = imageWidth * scalingFactor;
imageHeight = imageHeight * scalingFactor;
let imageX = fieldX + (fieldWidth - imageWidth) / 2;
let imageY = fieldY + (fieldHeight - imageHeight) / 2;
let imageX = fieldX + (fieldWidth - imageWidth) / 2;
let imageY = fieldY + (fieldHeight - imageHeight) / 2;
// Invert the Y axis since PDFs use a bottom-left coordinate system
imageY = pageHeight - imageY - imageHeight;
// Invert the Y axis since PDFs use a bottom-left coordinate system
imageY = pageHeight - imageY - imageHeight;
if (pageRotationInDegrees !== 0) {
const adjustedPosition = adjustPositionForRotation(
pageWidth,
pageHeight,
imageX,
imageY,
pageRotationInDegrees,
);
if (pageRotationInDegrees !== 0) {
const adjustedPosition = adjustPositionForRotation(
pageWidth,
pageHeight,
imageX,
imageY,
pageRotationInDegrees,
);
imageX = adjustedPosition.xPos;
imageY = adjustedPosition.yPos;
}
page.drawImage(image, {
x: imageX,
y: imageY,
width: imageWidth,
height: imageHeight,
rotate: degrees(pageRotationInDegrees),
});
} else {
const signatureText = field.Signature?.typedSignature ?? '';
const longestLineInTextForWidth = signatureText
.split('\n')
.sort((a, b) => b.length - a.length)[0];
let fontSize = maxFontSize;
let textWidth = font.widthOfTextAtSize(longestLineInTextForWidth, fontSize);
let textHeight = font.heightAtSize(fontSize);
const scalingFactor = Math.min(fieldWidth / textWidth, fieldHeight / textHeight, 1);
fontSize = Math.max(Math.min(fontSize * scalingFactor, maxFontSize), minFontSize);
textWidth = font.widthOfTextAtSize(longestLineInTextForWidth, fontSize);
textHeight = font.heightAtSize(fontSize);
let textX = fieldX + (fieldWidth - textWidth) / 2;
let textY = fieldY + (fieldHeight - textHeight) / 2;
// Invert the Y axis since PDFs use a bottom-left coordinate system
textY = pageHeight - textY - textHeight;
if (pageRotationInDegrees !== 0) {
const adjustedPosition = adjustPositionForRotation(
pageWidth,
pageHeight,
textX,
textY,
pageRotationInDegrees,
);
textX = adjustedPosition.xPos;
textY = adjustedPosition.yPos;
}
page.drawText(signatureText, {
x: textX,
y: textY,
size: fontSize,
font,
rotate: degrees(pageRotationInDegrees),
});
imageX = adjustedPosition.xPos;
imageY = adjustedPosition.yPos;
}
page.drawImage(image, {
x: imageX,
y: imageY,
width: imageWidth,
height: imageHeight,
rotate: degrees(pageRotationInDegrees),
});
},
)
.with({ type: FieldType.CHECKBOX }, (field) => {
@@ -12,8 +12,6 @@ export type UpdateTeamDocumentSettingsOptions = {
documentVisibility: DocumentVisibility;
documentLanguage: SupportedLanguageCodes;
includeSenderDetails: boolean;
typedSignatureEnabled: boolean;
includeSigningCertificate: boolean;
};
};
@@ -22,13 +20,7 @@ export const updateTeamDocumentSettings = async ({
teamId,
settings,
}: UpdateTeamDocumentSettingsOptions) => {
const {
documentVisibility,
documentLanguage,
includeSenderDetails,
includeSigningCertificate,
typedSignatureEnabled,
} = settings;
const { documentVisibility, documentLanguage, includeSenderDetails } = settings;
const member = await prisma.teamMember.findFirst({
where: {
@@ -50,15 +42,11 @@ export const updateTeamDocumentSettings = async ({
documentVisibility,
documentLanguage,
includeSenderDetails,
typedSignatureEnabled,
includeSigningCertificate,
},
update: {
documentVisibility,
documentLanguage,
includeSenderDetails,
typedSignatureEnabled,
includeSigningCertificate,
},
});
};
@@ -4,6 +4,7 @@ import { TEAM_MEMBER_ROLE_PERMISSIONS_MAP } from '@documenso/lib/constants/teams
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { prisma } from '@documenso/prisma';
import { Prisma } from '@documenso/prisma/client';
import type { DocumentVisibility } from '@documenso/prisma/client';
export type UpdateTeamOptions = {
userId: number;
@@ -11,6 +12,8 @@ export type UpdateTeamOptions = {
data: {
name?: string;
url?: string;
documentVisibility?: DocumentVisibility;
includeSenderDetails?: boolean;
};
};
@@ -42,6 +45,18 @@ export const updateTeam = async ({ userId, teamId, data }: UpdateTeamOptions) =>
data: {
url: data.url,
name: data.name,
teamGlobalSettings: {
upsert: {
create: {
documentVisibility: data.documentVisibility,
includeSenderDetails: data.includeSenderDetails,
},
update: {
documentVisibility: data.documentVisibility,
includeSenderDetails: data.includeSenderDetails,
},
},
},
},
});
@@ -64,7 +64,6 @@ export type CreateDocumentFromTemplateOptions = {
signingOrder?: DocumentSigningOrder;
language?: SupportedLanguageCodes;
distributionMethod?: DocumentDistributionMethod;
typedSignatureEnabled?: boolean;
};
requestMetadata?: RequestMetadata;
};
@@ -147,7 +146,7 @@ export const createDocumentFromTemplate = async ({
return {
templateRecipientId: templateRecipient.id,
fields: templateRecipient.Field,
name: foundRecipient ? (foundRecipient.name ?? '') : templateRecipient.name,
name: foundRecipient ? foundRecipient.name ?? '' : templateRecipient.name,
email: foundRecipient ? foundRecipient.email : templateRecipient.email,
role: templateRecipient.role,
signingOrder: foundRecipient?.signingOrder ?? templateRecipient.signingOrder,
@@ -197,8 +196,6 @@ export const createDocumentFromTemplate = async ({
override?.language ||
template.templateMeta?.language ||
template.team?.teamGlobalSettings?.documentLanguage,
typedSignatureEnabled:
override?.typedSignatureEnabled ?? template.templateMeta?.typedSignatureEnabled,
},
},
Recipient: {
+85 -98
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: de\n"
"Project-Id-Version: documenso-app\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-11-20 11:56\n"
"PO-Revision-Date: 2024-11-14 12:05\n"
"Last-Translator: \n"
"Language-Team: German\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -135,11 +135,11 @@ msgstr "{prefix} hat das Dokument erstellt"
msgid "{prefix} deleted the document"
msgstr "{prefix} hat das Dokument gelöscht"
#: packages/lib/utils/document-audit-logs.ts:339
#: packages/lib/utils/document-audit-logs.ts:335
msgid "{prefix} moved the document to team"
msgstr "{prefix} hat das Dokument ins Team verschoben"
#: packages/lib/utils/document-audit-logs.ts:323
#: packages/lib/utils/document-audit-logs.ts:319
msgid "{prefix} opened the document"
msgstr "{prefix} hat das Dokument geöffnet"
@@ -151,27 +151,23 @@ msgstr "{prefix} hat ein Feld entfernt"
msgid "{prefix} removed a recipient"
msgstr "{prefix} hat einen Empfänger entfernt"
#: packages/lib/utils/document-audit-logs.ts:369
#: packages/lib/utils/document-audit-logs.ts:365
msgid "{prefix} resent an email to {0}"
msgstr "{prefix} hat eine E-Mail an {0} erneut gesendet"
#: packages/lib/utils/document-audit-logs.ts:295
msgid "{prefix} restored the document"
msgstr ""
#: packages/lib/utils/document-audit-logs.ts:370
#: packages/lib/utils/document-audit-logs.ts:366
msgid "{prefix} sent an email to {0}"
msgstr "{prefix} hat eine E-Mail an {0} gesendet"
#: packages/lib/utils/document-audit-logs.ts:335
#: packages/lib/utils/document-audit-logs.ts:331
msgid "{prefix} sent the document"
msgstr "{prefix} hat das Dokument gesendet"
#: packages/lib/utils/document-audit-logs.ts:299
#: packages/lib/utils/document-audit-logs.ts:295
msgid "{prefix} signed a field"
msgstr "{prefix} hat ein Feld unterschrieben"
#: packages/lib/utils/document-audit-logs.ts:303
#: packages/lib/utils/document-audit-logs.ts:299
msgid "{prefix} unsigned a field"
msgstr "{prefix} hat ein Feld ungültig gemacht"
@@ -183,27 +179,27 @@ msgstr "{prefix} hat ein Feld aktualisiert"
msgid "{prefix} updated a recipient"
msgstr "{prefix} hat einen Empfänger aktualisiert"
#: packages/lib/utils/document-audit-logs.ts:319
#: packages/lib/utils/document-audit-logs.ts:315
msgid "{prefix} updated the document"
msgstr "{prefix} hat das Dokument aktualisiert"
#: packages/lib/utils/document-audit-logs.ts:311
#: packages/lib/utils/document-audit-logs.ts:307
msgid "{prefix} updated the document access auth requirements"
msgstr "{prefix} hat die Anforderungen an die Dokumentenzugriffsautorisierung aktualisiert"
#: packages/lib/utils/document-audit-logs.ts:331
#: packages/lib/utils/document-audit-logs.ts:327
msgid "{prefix} updated the document external ID"
msgstr "{prefix} hat die externe ID des Dokuments aktualisiert"
#: packages/lib/utils/document-audit-logs.ts:315
#: packages/lib/utils/document-audit-logs.ts:311
msgid "{prefix} updated the document signing auth requirements"
msgstr "{prefix} hat die Authentifizierungsanforderungen für die Dokumentenunterzeichnung aktualisiert"
#: packages/lib/utils/document-audit-logs.ts:327
#: packages/lib/utils/document-audit-logs.ts:323
msgid "{prefix} updated the document title"
msgstr "{prefix} hat den Titel des Dokuments aktualisiert"
#: packages/lib/utils/document-audit-logs.ts:307
#: packages/lib/utils/document-audit-logs.ts:303
msgid "{prefix} updated the document visibility"
msgstr "{prefix} hat die Sichtbarkeit des Dokuments aktualisiert"
@@ -231,27 +227,27 @@ msgstr "{teamName} hat Sie eingeladen, {action} {documentName}"
msgid "{teamName} ownership transfer request"
msgstr "Anfrage zur Übertragung des Eigentums von {teamName}"
#: packages/lib/utils/document-audit-logs.ts:347
#: packages/lib/utils/document-audit-logs.ts:343
msgid "{userName} approved the document"
msgstr "{userName} hat das Dokument genehmigt"
#: packages/lib/utils/document-audit-logs.ts:348
#: packages/lib/utils/document-audit-logs.ts:344
msgid "{userName} CC'd the document"
msgstr "{userName} hat das Dokument in CC gesetzt"
#: packages/lib/utils/document-audit-logs.ts:349
#: packages/lib/utils/document-audit-logs.ts:345
msgid "{userName} completed their task"
msgstr "{userName} hat ihre Aufgabe abgeschlossen"
#: packages/lib/utils/document-audit-logs.ts:359
#: packages/lib/utils/document-audit-logs.ts:355
msgid "{userName} rejected the document"
msgstr "{userName} hat das Dokument abgelehnt"
#: packages/lib/utils/document-audit-logs.ts:345
#: packages/lib/utils/document-audit-logs.ts:341
msgid "{userName} signed the document"
msgstr "{userName} hat das Dokument unterschrieben"
#: packages/lib/utils/document-audit-logs.ts:346
#: packages/lib/utils/document-audit-logs.ts:342
msgid "{userName} viewed the document"
msgstr "{userName} hat das Dokument angesehen"
@@ -418,11 +414,11 @@ msgstr "Weiteren Wert hinzufügen"
msgid "Add myself"
msgstr "Mich selbst hinzufügen"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:645
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:637
msgid "Add Myself"
msgstr "Mich hinzufügen"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:631
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:623
msgid "Add Placeholder Recipient"
msgstr "Platzhalterempfänger hinzufügen"
@@ -447,8 +443,8 @@ msgstr "Admin"
msgid "Advanced Options"
msgstr "Erweiterte Optionen"
#: packages/ui/primitives/document-flow/add-fields.tsx:576
#: packages/ui/primitives/template-flow/add-template-fields.tsx:414
#: packages/ui/primitives/document-flow/add-fields.tsx:573
#: packages/ui/primitives/template-flow/add-template-fields.tsx:406
msgid "Advanced settings"
msgstr "Erweiterte Einstellungen"
@@ -504,11 +500,11 @@ msgstr "Genehmigung"
msgid "Before you get started, please confirm your email address by clicking the button below:"
msgstr "Bitte bestätige vor dem Start deine E-Mail-Adresse, indem du auf den Button unten klickst:"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:383
#: packages/ui/primitives/signature-pad/signature-pad.tsx:377
msgid "Black"
msgstr "Schwarz"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:397
#: packages/ui/primitives/signature-pad/signature-pad.tsx:391
msgid "Blue"
msgstr "Blau"
@@ -554,10 +550,6 @@ msgstr "Ccers"
msgid "Character Limit"
msgstr "Zeichenbeschränkung"
#: packages/ui/primitives/document-flow/types.ts:58
msgid "Checkbox"
msgstr "Checkbox"
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx:197
msgid "Checkbox values"
msgstr "Checkbox-Werte"
@@ -566,7 +558,7 @@ msgstr "Checkbox-Werte"
msgid "Clear filters"
msgstr "Filter löschen"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:417
#: packages/ui/primitives/signature-pad/signature-pad.tsx:411
msgid "Clear Signature"
msgstr "Unterschrift löschen"
@@ -593,8 +585,8 @@ msgstr "Abgeschlossenes Dokument"
msgid "Configure Direct Recipient"
msgstr "Direkten Empfänger konfigurieren"
#: packages/ui/primitives/document-flow/add-fields.tsx:577
#: packages/ui/primitives/template-flow/add-template-fields.tsx:415
#: packages/ui/primitives/document-flow/add-fields.tsx:574
#: packages/ui/primitives/template-flow/add-template-fields.tsx:407
msgid "Configure the {0} field"
msgstr "Konfigurieren Sie das Feld {0}"
@@ -655,9 +647,9 @@ msgstr "Konto erstellen"
msgid "Custom Text"
msgstr "Benutzerdefinierter Text"
#: packages/ui/primitives/document-flow/add-fields.tsx:934
#: packages/ui/primitives/document-flow/add-fields.tsx:927
#: packages/ui/primitives/document-flow/types.ts:53
#: packages/ui/primitives/template-flow/add-template-fields.tsx:729
#: packages/ui/primitives/template-flow/add-template-fields.tsx:690
msgid "Date"
msgstr "Datum"
@@ -674,7 +666,7 @@ msgstr "Ablehnen"
msgid "Didn't request a password change? We are here to help you secure your account, just <0>contact us.</0>"
msgstr "Hast du keinen Passwortwechsel angefordert? Wir helfen dir, dein Konto abzusichern, kontaktiere uns einfach <0>hier.</0>"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:578
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:570
msgid "Direct link receiver"
msgstr "Empfänger des direkten Links"
@@ -692,17 +684,17 @@ msgstr "Dokument \"{0}\" - Ablehnung Bestätigt"
msgid "Document access"
msgstr "Dokumentenzugriff"
#: packages/lib/utils/document-audit-logs.ts:310
#: packages/lib/utils/document-audit-logs.ts:306
msgid "Document access auth updated"
msgstr "Die Authentifizierung für den Dokumentenzugriff wurde aktualisiert"
#: packages/lib/server-only/document/delete-document.ts:256
#: packages/lib/server-only/document/delete-document.ts:246
#: packages/lib/server-only/document/super-delete-document.ts:98
msgid "Document Cancelled"
msgstr "Dokument storniert"
#: packages/lib/utils/document-audit-logs.ts:373
#: packages/lib/utils/document-audit-logs.ts:374
#: packages/lib/utils/document-audit-logs.ts:369
#: packages/lib/utils/document-audit-logs.ts:370
msgid "Document completed"
msgstr "Dokument abgeschlossen"
@@ -740,15 +732,15 @@ msgstr "Dokument gelöscht!"
msgid "Document Distribution Method"
msgstr "Verteilungsmethode für Dokumente"
#: packages/lib/utils/document-audit-logs.ts:330
#: packages/lib/utils/document-audit-logs.ts:326
msgid "Document external ID updated"
msgstr "Externe ID des Dokuments aktualisiert"
#: packages/lib/utils/document-audit-logs.ts:338
#: packages/lib/utils/document-audit-logs.ts:334
msgid "Document moved to team"
msgstr "Dokument ins Team verschoben"
#: packages/lib/utils/document-audit-logs.ts:322
#: packages/lib/utils/document-audit-logs.ts:318
msgid "Document opened"
msgstr "Dokument geöffnet"
@@ -763,27 +755,23 @@ msgstr "Dokument Abgelehnt"
#~ msgid "Document Rejection Confirmed"
#~ msgstr "Document Rejection Confirmed"
#: packages/lib/utils/document-audit-logs.ts:294
msgid "Document restored"
msgstr ""
#: packages/lib/utils/document-audit-logs.ts:334
#: packages/lib/utils/document-audit-logs.ts:330
msgid "Document sent"
msgstr "Dokument gesendet"
#: packages/lib/utils/document-audit-logs.ts:314
#: packages/lib/utils/document-audit-logs.ts:310
msgid "Document signing auth updated"
msgstr "Dokument unterzeichnen Authentifizierung aktualisiert"
#: packages/lib/utils/document-audit-logs.ts:326
#: packages/lib/utils/document-audit-logs.ts:322
msgid "Document title updated"
msgstr "Dokumenttitel aktualisiert"
#: packages/lib/utils/document-audit-logs.ts:318
#: packages/lib/utils/document-audit-logs.ts:314
msgid "Document updated"
msgstr "Dokument aktualisiert"
#: packages/lib/utils/document-audit-logs.ts:306
#: packages/lib/utils/document-audit-logs.ts:302
msgid "Document visibility updated"
msgstr "Sichtbarkeit des Dokuments aktualisiert"
@@ -800,8 +788,8 @@ msgstr "Entwurf"
msgid "Drag & drop your PDF here."
msgstr "Ziehen Sie Ihr PDF hierher."
#: packages/ui/primitives/document-flow/add-fields.tsx:1065
#: packages/ui/primitives/template-flow/add-template-fields.tsx:860
#: packages/ui/primitives/document-flow/add-fields.tsx:1058
#: packages/ui/primitives/template-flow/add-template-fields.tsx:820
msgid "Dropdown"
msgstr "Dropdown"
@@ -810,14 +798,14 @@ msgid "Dropdown options"
msgstr "Dropdown-Optionen"
#: packages/lib/constants/document.ts:28
#: packages/ui/primitives/document-flow/add-fields.tsx:882
#: packages/ui/primitives/document-flow/add-fields.tsx:875
#: packages/ui/primitives/document-flow/add-signature.tsx:272
#: packages/ui/primitives/document-flow/add-signers.tsx:512
#: packages/ui/primitives/document-flow/add-signers.tsx:519
#: packages/ui/primitives/document-flow/types.ts:54
#: packages/ui/primitives/template-flow/add-template-fields.tsx:677
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:471
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:478
#: packages/ui/primitives/template-flow/add-template-fields.tsx:638
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:463
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:470
msgid "Email"
msgstr "E-Mail"
@@ -829,15 +817,15 @@ msgstr "E-Mail ist erforderlich"
msgid "Email Options"
msgstr "E-Mail-Optionen"
#: packages/lib/utils/document-audit-logs.ts:367
#: packages/lib/utils/document-audit-logs.ts:363
msgid "Email resent"
msgstr "E-Mail erneut gesendet"
#: packages/lib/utils/document-audit-logs.ts:367
#: packages/lib/utils/document-audit-logs.ts:363
msgid "Email sent"
msgstr "E-Mail gesendet"
#: packages/ui/primitives/document-flow/add-fields.tsx:1130
#: packages/ui/primitives/document-flow/add-fields.tsx:1123
msgid "Empty field"
msgstr "Leeres Feld"
@@ -846,12 +834,11 @@ msgid "Enable Direct Link Signing"
msgstr "Direktlink-Signierung aktivieren"
#: packages/ui/primitives/document-flow/add-signers.tsx:401
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:370
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:362
msgid "Enable signing order"
msgstr "Aktiviere die Signaturreihenfolge"
#: packages/ui/primitives/document-flow/add-fields.tsx:802
#: packages/ui/primitives/template-flow/add-template-fields.tsx:597
#: packages/ui/primitives/document-flow/add-fields.tsx:795
msgid "Enable Typed Signatures"
msgstr "Aktivieren Sie getippte Unterschriften"
@@ -898,11 +885,11 @@ msgstr "Feldbeschriftung"
msgid "Field placeholder"
msgstr "Feldplatzhalter"
#: packages/lib/utils/document-audit-logs.ts:298
#: packages/lib/utils/document-audit-logs.ts:294
msgid "Field signed"
msgstr "Feld unterschrieben"
#: packages/lib/utils/document-audit-logs.ts:302
#: packages/lib/utils/document-audit-logs.ts:298
msgid "Field unsigned"
msgstr "Feld nicht unterschrieben"
@@ -939,7 +926,7 @@ msgstr "Globale Empfängerauthentifizierung"
msgid "Go Back"
msgstr "Zurück"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:404
#: packages/ui/primitives/signature-pad/signature-pad.tsx:398
msgid "Green"
msgstr "Grün"
@@ -1029,14 +1016,14 @@ msgstr "Nachricht <0>(Optional)</0>"
msgid "Min"
msgstr "Min"
#: packages/ui/primitives/document-flow/add-fields.tsx:908
#: packages/ui/primitives/document-flow/add-fields.tsx:901
#: packages/ui/primitives/document-flow/add-signature.tsx:298
#: packages/ui/primitives/document-flow/add-signers.tsx:550
#: packages/ui/primitives/document-flow/add-signers.tsx:556
#: packages/ui/primitives/document-flow/types.ts:55
#: packages/ui/primitives/template-flow/add-template-fields.tsx:703
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:506
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:512
#: packages/ui/primitives/template-flow/add-template-fields.tsx:664
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:498
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:504
msgid "Name"
msgstr "Name"
@@ -1052,8 +1039,8 @@ msgstr "Muss unterzeichnen"
msgid "Needs to view"
msgstr "Muss sehen"
#: packages/ui/primitives/document-flow/add-fields.tsx:693
#: packages/ui/primitives/template-flow/add-template-fields.tsx:516
#: packages/ui/primitives/document-flow/add-fields.tsx:686
#: packages/ui/primitives/template-flow/add-template-fields.tsx:504
msgid "No recipient matching this description was found."
msgstr "Kein passender Empfänger mit dieser Beschreibung gefunden."
@@ -1061,8 +1048,8 @@ msgstr "Kein passender Empfänger mit dieser Beschreibung gefunden."
msgid "No recipients"
msgstr "Keine Empfänger"
#: packages/ui/primitives/document-flow/add-fields.tsx:708
#: packages/ui/primitives/template-flow/add-template-fields.tsx:531
#: packages/ui/primitives/document-flow/add-fields.tsx:701
#: packages/ui/primitives/template-flow/add-template-fields.tsx:519
msgid "No recipients with this role"
msgstr "Keine Empfänger mit dieser Rolle"
@@ -1090,9 +1077,9 @@ msgstr "Kein Wert gefunden."
msgid "None"
msgstr "Keine"
#: packages/ui/primitives/document-flow/add-fields.tsx:986
#: packages/ui/primitives/document-flow/add-fields.tsx:979
#: packages/ui/primitives/document-flow/types.ts:56
#: packages/ui/primitives/template-flow/add-template-fields.tsx:781
#: packages/ui/primitives/template-flow/add-template-fields.tsx:742
msgid "Number"
msgstr "Nummer"
@@ -1183,7 +1170,7 @@ msgstr "Bitte bestätige deine E-Mail-Adresse"
msgid "Please try again or contact our support."
msgstr "Bitte versuchen Sie es erneut oder kontaktieren Sie unseren Support."
#: packages/ui/primitives/document-flow/types.ts:57
#: packages/ui/primitives/template-flow/add-template-fields.tsx:768
msgid "Radio"
msgstr "Radio"
@@ -1207,8 +1194,8 @@ msgstr "Grund für die Ablehnung: {rejectionReason}"
msgid "Receives copy"
msgstr "Erhält Kopie"
#: packages/lib/utils/document-audit-logs.ts:342
#: packages/lib/utils/document-audit-logs.ts:357
#: packages/lib/utils/document-audit-logs.ts:338
#: packages/lib/utils/document-audit-logs.ts:353
msgid "Recipient"
msgstr "Empfänger"
@@ -1226,7 +1213,7 @@ msgstr "E-Mail des entfernten Empfängers"
msgid "Recipient signing request email"
msgstr "E-Mail zur Unterzeichnungsanfrage des Empfängers"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:390
#: packages/ui/primitives/signature-pad/signature-pad.tsx:384
msgid "Red"
msgstr "Rot"
@@ -1263,7 +1250,7 @@ msgstr "Erinnerung: Bitte {recipientActionVerb} dieses Dokument"
msgid "Reminder: Please {recipientActionVerb} your document"
msgstr "Erinnerung: Bitte {recipientActionVerb} dein Dokument"
#: packages/ui/primitives/document-flow/add-fields.tsx:1117
#: packages/ui/primitives/document-flow/add-fields.tsx:1110
msgid "Remove"
msgstr "Entfernen"
@@ -1295,7 +1282,7 @@ msgstr "Zeilen pro Seite"
msgid "Save"
msgstr "Speichern"
#: packages/ui/primitives/template-flow/add-template-fields.tsx:893
#: packages/ui/primitives/template-flow/add-template-fields.tsx:854
msgid "Save Template"
msgstr "Vorlage speichern"
@@ -1304,7 +1291,6 @@ msgid "Search languages..."
msgstr "Sprachen suchen..."
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx:115
#: packages/ui/primitives/document-flow/types.ts:59
msgid "Select"
msgstr "Auswählen"
@@ -1368,7 +1354,7 @@ msgid "Share your signing experience!"
msgstr "Teilen Sie Ihre Unterzeichnungserfahrung!"
#: packages/ui/primitives/document-flow/add-signers.tsx:709
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:663
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:655
msgid "Show advanced settings"
msgstr "Erweiterte Einstellungen anzeigen"
@@ -1384,11 +1370,11 @@ msgstr "Dokument signieren"
msgid "Sign In"
msgstr "Anmelden"
#: packages/ui/primitives/document-flow/add-fields.tsx:830
#: packages/ui/primitives/document-flow/add-fields.tsx:823
#: packages/ui/primitives/document-flow/add-signature.tsx:323
#: packages/ui/primitives/document-flow/field-icon.tsx:52
#: packages/ui/primitives/document-flow/types.ts:49
#: packages/ui/primitives/template-flow/add-template-fields.tsx:625
#: packages/ui/primitives/template-flow/add-template-fields.tsx:586
msgid "Signature"
msgstr "Unterschrift"
@@ -1471,9 +1457,9 @@ msgstr "Team-E-Mail für {teamName} auf Documenso entfernt"
msgid "Template title"
msgstr "Vorlagentitel"
#: packages/ui/primitives/document-flow/add-fields.tsx:960
#: packages/ui/primitives/document-flow/add-fields.tsx:953
#: packages/ui/primitives/document-flow/types.ts:52
#: packages/ui/primitives/template-flow/add-template-fields.tsx:755
#: packages/ui/primitives/template-flow/add-template-fields.tsx:716
msgid "Text"
msgstr "Text"
@@ -1568,7 +1554,7 @@ msgstr "Dies kann überschrieben werden, indem die Authentifizierungsanforderung
msgid "This document can not be recovered, if you would like to dispute the reason for future documents please contact support."
msgstr "Dieses Dokument kann nicht wiederhergestellt werden. Wenn du den Grund für zukünftige Dokumente anfechten möchtest, kontaktiere bitte den Support."
#: packages/ui/primitives/document-flow/add-fields.tsx:764
#: packages/ui/primitives/document-flow/add-fields.tsx:757
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
msgstr "Dieses Dokument wurde bereits an diesen Empfänger gesendet. Sie können diesen Empfänger nicht mehr bearbeiten."
@@ -1599,7 +1585,7 @@ msgstr "Diese E-Mail wird an den Empfänger gesendet und fordert ihn auf, das Do
msgid "This email will be sent to the recipient who has just signed the document, if there are still other recipients who have not signed yet."
msgstr "Diese E-Mail wird an den Empfänger gesendet, der das Dokument gerade unterschrieben hat, wenn es noch andere Empfänger gibt, die noch nicht unterschrieben haben."
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:581
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:573
msgid "This field cannot be modified or deleted. When you share this template's direct link or add it to your public profile, anyone who accesses it can input their name and email, and fill in the fields assigned to them."
msgstr "Dieses Feld kann nicht geändert oder gelöscht werden. Wenn Sie den direkten Link dieser Vorlage teilen oder zu Ihrem öffentlichen Profil hinzufügen, kann jeder, der darauf zugreift, seinen Namen und seine E-Mail-Adresse eingeben und die ihm zugewiesenen Felder ausfüllen."
@@ -1607,7 +1593,7 @@ msgstr "Dieses Feld kann nicht geändert oder gelöscht werden. Wenn Sie den dir
msgid "This is how the document will reach the recipients once the document is ready for signing."
msgstr "So wird das Dokument die Empfänger erreichen, sobald es zum Unterschreiben bereit ist."
#: packages/ui/primitives/document-flow/add-fields.tsx:1097
#: packages/ui/primitives/document-flow/add-fields.tsx:1090
msgid "This recipient can no longer be modified as they have signed a field, or completed the document."
msgstr "Dieser Empfänger kann nicht mehr bearbeitet werden, da er ein Feld unterschrieben oder das Dokument abgeschlossen hat."
@@ -1636,8 +1622,8 @@ msgstr "Zeitzone"
msgid "Title"
msgstr "Titel"
#: packages/ui/primitives/document-flow/add-fields.tsx:1080
#: packages/ui/primitives/template-flow/add-template-fields.tsx:873
#: packages/ui/primitives/document-flow/add-fields.tsx:1073
#: packages/ui/primitives/template-flow/add-template-fields.tsx:834
msgid "To proceed further, please set at least one value for the {0} field."
msgstr "Um fortzufahren, legen Sie bitte mindestens einen Wert für das Feld {0} fest."
@@ -1822,3 +1808,4 @@ msgstr "Dein Passwort wurde aktualisiert."
#: packages/email/templates/team-delete.tsx:32
msgid "Your team has been deleted"
msgstr "Dein Team wurde gelöscht"
+2 -1
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: de\n"
"Project-Id-Version: documenso-app\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-11-20 11:56\n"
"PO-Revision-Date: 2024-11-14 12:05\n"
"Last-Translator: \n"
"Language-Team: German\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -602,3 +602,4 @@ msgstr "Sie können Documenso kostenlos selbst hosten oder unsere sofort einsatz
#: apps/marketing/src/components/(marketing)/carousel.tsx:272
msgid "Your browser does not support the video tag."
msgstr "Ihr Browser unterstützt das Video-Tag nicht."
File diff suppressed because it is too large Load Diff
+83 -97
View File
@@ -130,11 +130,11 @@ msgstr "{prefix} created the document"
msgid "{prefix} deleted the document"
msgstr "{prefix} deleted the document"
#: packages/lib/utils/document-audit-logs.ts:339
#: packages/lib/utils/document-audit-logs.ts:335
msgid "{prefix} moved the document to team"
msgstr "{prefix} moved the document to team"
#: packages/lib/utils/document-audit-logs.ts:323
#: packages/lib/utils/document-audit-logs.ts:319
msgid "{prefix} opened the document"
msgstr "{prefix} opened the document"
@@ -146,27 +146,23 @@ msgstr "{prefix} removed a field"
msgid "{prefix} removed a recipient"
msgstr "{prefix} removed a recipient"
#: packages/lib/utils/document-audit-logs.ts:369
#: packages/lib/utils/document-audit-logs.ts:365
msgid "{prefix} resent an email to {0}"
msgstr "{prefix} resent an email to {0}"
#: packages/lib/utils/document-audit-logs.ts:295
msgid "{prefix} restored the document"
msgstr "{prefix} restored the document"
#: packages/lib/utils/document-audit-logs.ts:370
#: packages/lib/utils/document-audit-logs.ts:366
msgid "{prefix} sent an email to {0}"
msgstr "{prefix} sent an email to {0}"
#: packages/lib/utils/document-audit-logs.ts:335
#: packages/lib/utils/document-audit-logs.ts:331
msgid "{prefix} sent the document"
msgstr "{prefix} sent the document"
#: packages/lib/utils/document-audit-logs.ts:299
#: packages/lib/utils/document-audit-logs.ts:295
msgid "{prefix} signed a field"
msgstr "{prefix} signed a field"
#: packages/lib/utils/document-audit-logs.ts:303
#: packages/lib/utils/document-audit-logs.ts:299
msgid "{prefix} unsigned a field"
msgstr "{prefix} unsigned a field"
@@ -178,27 +174,27 @@ msgstr "{prefix} updated a field"
msgid "{prefix} updated a recipient"
msgstr "{prefix} updated a recipient"
#: packages/lib/utils/document-audit-logs.ts:319
#: packages/lib/utils/document-audit-logs.ts:315
msgid "{prefix} updated the document"
msgstr "{prefix} updated the document"
#: packages/lib/utils/document-audit-logs.ts:311
#: packages/lib/utils/document-audit-logs.ts:307
msgid "{prefix} updated the document access auth requirements"
msgstr "{prefix} updated the document access auth requirements"
#: packages/lib/utils/document-audit-logs.ts:331
#: packages/lib/utils/document-audit-logs.ts:327
msgid "{prefix} updated the document external ID"
msgstr "{prefix} updated the document external ID"
#: packages/lib/utils/document-audit-logs.ts:315
#: packages/lib/utils/document-audit-logs.ts:311
msgid "{prefix} updated the document signing auth requirements"
msgstr "{prefix} updated the document signing auth requirements"
#: packages/lib/utils/document-audit-logs.ts:327
#: packages/lib/utils/document-audit-logs.ts:323
msgid "{prefix} updated the document title"
msgstr "{prefix} updated the document title"
#: packages/lib/utils/document-audit-logs.ts:307
#: packages/lib/utils/document-audit-logs.ts:303
msgid "{prefix} updated the document visibility"
msgstr "{prefix} updated the document visibility"
@@ -226,27 +222,27 @@ msgstr "{teamName} has invited you to {action} {documentName}"
msgid "{teamName} ownership transfer request"
msgstr "{teamName} ownership transfer request"
#: packages/lib/utils/document-audit-logs.ts:347
#: packages/lib/utils/document-audit-logs.ts:343
msgid "{userName} approved the document"
msgstr "{userName} approved the document"
#: packages/lib/utils/document-audit-logs.ts:348
#: packages/lib/utils/document-audit-logs.ts:344
msgid "{userName} CC'd the document"
msgstr "{userName} CC'd the document"
#: packages/lib/utils/document-audit-logs.ts:349
#: packages/lib/utils/document-audit-logs.ts:345
msgid "{userName} completed their task"
msgstr "{userName} completed their task"
#: packages/lib/utils/document-audit-logs.ts:359
#: packages/lib/utils/document-audit-logs.ts:355
msgid "{userName} rejected the document"
msgstr "{userName} rejected the document"
#: packages/lib/utils/document-audit-logs.ts:345
#: packages/lib/utils/document-audit-logs.ts:341
msgid "{userName} signed the document"
msgstr "{userName} signed the document"
#: packages/lib/utils/document-audit-logs.ts:346
#: packages/lib/utils/document-audit-logs.ts:342
msgid "{userName} viewed the document"
msgstr "{userName} viewed the document"
@@ -413,11 +409,11 @@ msgstr "Add another value"
msgid "Add myself"
msgstr "Add myself"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:645
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:637
msgid "Add Myself"
msgstr "Add Myself"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:631
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:623
msgid "Add Placeholder Recipient"
msgstr "Add Placeholder Recipient"
@@ -442,8 +438,8 @@ msgstr "Admin"
msgid "Advanced Options"
msgstr "Advanced Options"
#: packages/ui/primitives/document-flow/add-fields.tsx:576
#: packages/ui/primitives/template-flow/add-template-fields.tsx:414
#: packages/ui/primitives/document-flow/add-fields.tsx:573
#: packages/ui/primitives/template-flow/add-template-fields.tsx:406
msgid "Advanced settings"
msgstr "Advanced settings"
@@ -499,11 +495,11 @@ msgstr "Approving"
msgid "Before you get started, please confirm your email address by clicking the button below:"
msgstr "Before you get started, please confirm your email address by clicking the button below:"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:383
#: packages/ui/primitives/signature-pad/signature-pad.tsx:377
msgid "Black"
msgstr "Black"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:397
#: packages/ui/primitives/signature-pad/signature-pad.tsx:391
msgid "Blue"
msgstr "Blue"
@@ -549,10 +545,6 @@ msgstr "Ccers"
msgid "Character Limit"
msgstr "Character Limit"
#: packages/ui/primitives/document-flow/types.ts:58
msgid "Checkbox"
msgstr "Checkbox"
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx:197
msgid "Checkbox values"
msgstr "Checkbox values"
@@ -561,7 +553,7 @@ msgstr "Checkbox values"
msgid "Clear filters"
msgstr "Clear filters"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:417
#: packages/ui/primitives/signature-pad/signature-pad.tsx:411
msgid "Clear Signature"
msgstr "Clear Signature"
@@ -588,8 +580,8 @@ msgstr "Completed Document"
msgid "Configure Direct Recipient"
msgstr "Configure Direct Recipient"
#: packages/ui/primitives/document-flow/add-fields.tsx:577
#: packages/ui/primitives/template-flow/add-template-fields.tsx:415
#: packages/ui/primitives/document-flow/add-fields.tsx:574
#: packages/ui/primitives/template-flow/add-template-fields.tsx:407
msgid "Configure the {0} field"
msgstr "Configure the {0} field"
@@ -650,9 +642,9 @@ msgstr "Create account"
msgid "Custom Text"
msgstr "Custom Text"
#: packages/ui/primitives/document-flow/add-fields.tsx:934
#: packages/ui/primitives/document-flow/add-fields.tsx:927
#: packages/ui/primitives/document-flow/types.ts:53
#: packages/ui/primitives/template-flow/add-template-fields.tsx:729
#: packages/ui/primitives/template-flow/add-template-fields.tsx:690
msgid "Date"
msgstr "Date"
@@ -669,7 +661,7 @@ msgstr "Decline"
msgid "Didn't request a password change? We are here to help you secure your account, just <0>contact us.</0>"
msgstr "Didn't request a password change? We are here to help you secure your account, just <0>contact us.</0>"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:578
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:570
msgid "Direct link receiver"
msgstr "Direct link receiver"
@@ -687,17 +679,17 @@ msgstr "Document \"{0}\" - Rejection Confirmed"
msgid "Document access"
msgstr "Document access"
#: packages/lib/utils/document-audit-logs.ts:310
#: packages/lib/utils/document-audit-logs.ts:306
msgid "Document access auth updated"
msgstr "Document access auth updated"
#: packages/lib/server-only/document/delete-document.ts:256
#: packages/lib/server-only/document/delete-document.ts:246
#: packages/lib/server-only/document/super-delete-document.ts:98
msgid "Document Cancelled"
msgstr "Document Cancelled"
#: packages/lib/utils/document-audit-logs.ts:373
#: packages/lib/utils/document-audit-logs.ts:374
#: packages/lib/utils/document-audit-logs.ts:369
#: packages/lib/utils/document-audit-logs.ts:370
msgid "Document completed"
msgstr "Document completed"
@@ -735,15 +727,15 @@ msgstr "Document Deleted!"
msgid "Document Distribution Method"
msgstr "Document Distribution Method"
#: packages/lib/utils/document-audit-logs.ts:330
#: packages/lib/utils/document-audit-logs.ts:326
msgid "Document external ID updated"
msgstr "Document external ID updated"
#: packages/lib/utils/document-audit-logs.ts:338
#: packages/lib/utils/document-audit-logs.ts:334
msgid "Document moved to team"
msgstr "Document moved to team"
#: packages/lib/utils/document-audit-logs.ts:322
#: packages/lib/utils/document-audit-logs.ts:318
msgid "Document opened"
msgstr "Document opened"
@@ -758,27 +750,23 @@ msgstr "Document Rejected"
#~ msgid "Document Rejection Confirmed"
#~ msgstr "Document Rejection Confirmed"
#: packages/lib/utils/document-audit-logs.ts:294
msgid "Document restored"
msgstr "Document restored"
#: packages/lib/utils/document-audit-logs.ts:334
#: packages/lib/utils/document-audit-logs.ts:330
msgid "Document sent"
msgstr "Document sent"
#: packages/lib/utils/document-audit-logs.ts:314
#: packages/lib/utils/document-audit-logs.ts:310
msgid "Document signing auth updated"
msgstr "Document signing auth updated"
#: packages/lib/utils/document-audit-logs.ts:326
#: packages/lib/utils/document-audit-logs.ts:322
msgid "Document title updated"
msgstr "Document title updated"
#: packages/lib/utils/document-audit-logs.ts:318
#: packages/lib/utils/document-audit-logs.ts:314
msgid "Document updated"
msgstr "Document updated"
#: packages/lib/utils/document-audit-logs.ts:306
#: packages/lib/utils/document-audit-logs.ts:302
msgid "Document visibility updated"
msgstr "Document visibility updated"
@@ -795,8 +783,8 @@ msgstr "Draft"
msgid "Drag & drop your PDF here."
msgstr "Drag & drop your PDF here."
#: packages/ui/primitives/document-flow/add-fields.tsx:1065
#: packages/ui/primitives/template-flow/add-template-fields.tsx:860
#: packages/ui/primitives/document-flow/add-fields.tsx:1058
#: packages/ui/primitives/template-flow/add-template-fields.tsx:820
msgid "Dropdown"
msgstr "Dropdown"
@@ -805,14 +793,14 @@ msgid "Dropdown options"
msgstr "Dropdown options"
#: packages/lib/constants/document.ts:28
#: packages/ui/primitives/document-flow/add-fields.tsx:882
#: packages/ui/primitives/document-flow/add-fields.tsx:875
#: packages/ui/primitives/document-flow/add-signature.tsx:272
#: packages/ui/primitives/document-flow/add-signers.tsx:512
#: packages/ui/primitives/document-flow/add-signers.tsx:519
#: packages/ui/primitives/document-flow/types.ts:54
#: packages/ui/primitives/template-flow/add-template-fields.tsx:677
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:471
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:478
#: packages/ui/primitives/template-flow/add-template-fields.tsx:638
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:463
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:470
msgid "Email"
msgstr "Email"
@@ -824,15 +812,15 @@ msgstr "Email is required"
msgid "Email Options"
msgstr "Email Options"
#: packages/lib/utils/document-audit-logs.ts:367
#: packages/lib/utils/document-audit-logs.ts:363
msgid "Email resent"
msgstr "Email resent"
#: packages/lib/utils/document-audit-logs.ts:367
#: packages/lib/utils/document-audit-logs.ts:363
msgid "Email sent"
msgstr "Email sent"
#: packages/ui/primitives/document-flow/add-fields.tsx:1130
#: packages/ui/primitives/document-flow/add-fields.tsx:1123
msgid "Empty field"
msgstr "Empty field"
@@ -841,12 +829,11 @@ msgid "Enable Direct Link Signing"
msgstr "Enable Direct Link Signing"
#: packages/ui/primitives/document-flow/add-signers.tsx:401
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:370
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:362
msgid "Enable signing order"
msgstr "Enable signing order"
#: packages/ui/primitives/document-flow/add-fields.tsx:802
#: packages/ui/primitives/template-flow/add-template-fields.tsx:597
#: packages/ui/primitives/document-flow/add-fields.tsx:795
msgid "Enable Typed Signatures"
msgstr "Enable Typed Signatures"
@@ -893,11 +880,11 @@ msgstr "Field label"
msgid "Field placeholder"
msgstr "Field placeholder"
#: packages/lib/utils/document-audit-logs.ts:298
#: packages/lib/utils/document-audit-logs.ts:294
msgid "Field signed"
msgstr "Field signed"
#: packages/lib/utils/document-audit-logs.ts:302
#: packages/lib/utils/document-audit-logs.ts:298
msgid "Field unsigned"
msgstr "Field unsigned"
@@ -934,7 +921,7 @@ msgstr "Global recipient action authentication"
msgid "Go Back"
msgstr "Go Back"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:404
#: packages/ui/primitives/signature-pad/signature-pad.tsx:398
msgid "Green"
msgstr "Green"
@@ -1024,14 +1011,14 @@ msgstr "Message <0>(Optional)</0>"
msgid "Min"
msgstr "Min"
#: packages/ui/primitives/document-flow/add-fields.tsx:908
#: packages/ui/primitives/document-flow/add-fields.tsx:901
#: packages/ui/primitives/document-flow/add-signature.tsx:298
#: packages/ui/primitives/document-flow/add-signers.tsx:550
#: packages/ui/primitives/document-flow/add-signers.tsx:556
#: packages/ui/primitives/document-flow/types.ts:55
#: packages/ui/primitives/template-flow/add-template-fields.tsx:703
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:506
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:512
#: packages/ui/primitives/template-flow/add-template-fields.tsx:664
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:498
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:504
msgid "Name"
msgstr "Name"
@@ -1047,8 +1034,8 @@ msgstr "Needs to sign"
msgid "Needs to view"
msgstr "Needs to view"
#: packages/ui/primitives/document-flow/add-fields.tsx:693
#: packages/ui/primitives/template-flow/add-template-fields.tsx:516
#: packages/ui/primitives/document-flow/add-fields.tsx:686
#: packages/ui/primitives/template-flow/add-template-fields.tsx:504
msgid "No recipient matching this description was found."
msgstr "No recipient matching this description was found."
@@ -1056,8 +1043,8 @@ msgstr "No recipient matching this description was found."
msgid "No recipients"
msgstr "No recipients"
#: packages/ui/primitives/document-flow/add-fields.tsx:708
#: packages/ui/primitives/template-flow/add-template-fields.tsx:531
#: packages/ui/primitives/document-flow/add-fields.tsx:701
#: packages/ui/primitives/template-flow/add-template-fields.tsx:519
msgid "No recipients with this role"
msgstr "No recipients with this role"
@@ -1085,9 +1072,9 @@ msgstr "No value found."
msgid "None"
msgstr "None"
#: packages/ui/primitives/document-flow/add-fields.tsx:986
#: packages/ui/primitives/document-flow/add-fields.tsx:979
#: packages/ui/primitives/document-flow/types.ts:56
#: packages/ui/primitives/template-flow/add-template-fields.tsx:781
#: packages/ui/primitives/template-flow/add-template-fields.tsx:742
msgid "Number"
msgstr "Number"
@@ -1178,7 +1165,7 @@ msgstr "Please confirm your email address"
msgid "Please try again or contact our support."
msgstr "Please try again or contact our support."
#: packages/ui/primitives/document-flow/types.ts:57
#: packages/ui/primitives/template-flow/add-template-fields.tsx:768
msgid "Radio"
msgstr "Radio"
@@ -1202,8 +1189,8 @@ msgstr "Reason for rejection: {rejectionReason}"
msgid "Receives copy"
msgstr "Receives copy"
#: packages/lib/utils/document-audit-logs.ts:342
#: packages/lib/utils/document-audit-logs.ts:357
#: packages/lib/utils/document-audit-logs.ts:338
#: packages/lib/utils/document-audit-logs.ts:353
msgid "Recipient"
msgstr "Recipient"
@@ -1221,7 +1208,7 @@ msgstr "Recipient removed email"
msgid "Recipient signing request email"
msgstr "Recipient signing request email"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:390
#: packages/ui/primitives/signature-pad/signature-pad.tsx:384
msgid "Red"
msgstr "Red"
@@ -1258,7 +1245,7 @@ msgstr "Reminder: Please {recipientActionVerb} this document"
msgid "Reminder: Please {recipientActionVerb} your document"
msgstr "Reminder: Please {recipientActionVerb} your document"
#: packages/ui/primitives/document-flow/add-fields.tsx:1117
#: packages/ui/primitives/document-flow/add-fields.tsx:1110
msgid "Remove"
msgstr "Remove"
@@ -1290,7 +1277,7 @@ msgstr "Rows per page"
msgid "Save"
msgstr "Save"
#: packages/ui/primitives/template-flow/add-template-fields.tsx:893
#: packages/ui/primitives/template-flow/add-template-fields.tsx:854
msgid "Save Template"
msgstr "Save Template"
@@ -1299,7 +1286,6 @@ msgid "Search languages..."
msgstr "Search languages..."
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx:115
#: packages/ui/primitives/document-flow/types.ts:59
msgid "Select"
msgstr "Select"
@@ -1363,7 +1349,7 @@ msgid "Share your signing experience!"
msgstr "Share your signing experience!"
#: packages/ui/primitives/document-flow/add-signers.tsx:709
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:663
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:655
msgid "Show advanced settings"
msgstr "Show advanced settings"
@@ -1379,11 +1365,11 @@ msgstr "Sign Document"
msgid "Sign In"
msgstr "Sign In"
#: packages/ui/primitives/document-flow/add-fields.tsx:830
#: packages/ui/primitives/document-flow/add-fields.tsx:823
#: packages/ui/primitives/document-flow/add-signature.tsx:323
#: packages/ui/primitives/document-flow/field-icon.tsx:52
#: packages/ui/primitives/document-flow/types.ts:49
#: packages/ui/primitives/template-flow/add-template-fields.tsx:625
#: packages/ui/primitives/template-flow/add-template-fields.tsx:586
msgid "Signature"
msgstr "Signature"
@@ -1466,9 +1452,9 @@ msgstr "Team email removed for {teamName} on Documenso"
msgid "Template title"
msgstr "Template title"
#: packages/ui/primitives/document-flow/add-fields.tsx:960
#: packages/ui/primitives/document-flow/add-fields.tsx:953
#: packages/ui/primitives/document-flow/types.ts:52
#: packages/ui/primitives/template-flow/add-template-fields.tsx:755
#: packages/ui/primitives/template-flow/add-template-fields.tsx:716
msgid "Text"
msgstr "Text"
@@ -1563,7 +1549,7 @@ msgstr "This can be overriden by setting the authentication requirements directl
msgid "This document can not be recovered, if you would like to dispute the reason for future documents please contact support."
msgstr "This document can not be recovered, if you would like to dispute the reason for future documents please contact support."
#: packages/ui/primitives/document-flow/add-fields.tsx:764
#: packages/ui/primitives/document-flow/add-fields.tsx:757
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
msgstr "This document has already been sent to this recipient. You can no longer edit this recipient."
@@ -1594,7 +1580,7 @@ msgstr "This email is sent to the recipient requesting them to sign the document
msgid "This email will be sent to the recipient who has just signed the document, if there are still other recipients who have not signed yet."
msgstr "This email will be sent to the recipient who has just signed the document, if there are still other recipients who have not signed yet."
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:581
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:573
msgid "This field cannot be modified or deleted. When you share this template's direct link or add it to your public profile, anyone who accesses it can input their name and email, and fill in the fields assigned to them."
msgstr "This field cannot be modified or deleted. When you share this template's direct link or add it to your public profile, anyone who accesses it can input their name and email, and fill in the fields assigned to them."
@@ -1602,7 +1588,7 @@ msgstr "This field cannot be modified or deleted. When you share this template's
msgid "This is how the document will reach the recipients once the document is ready for signing."
msgstr "This is how the document will reach the recipients once the document is ready for signing."
#: packages/ui/primitives/document-flow/add-fields.tsx:1097
#: packages/ui/primitives/document-flow/add-fields.tsx:1090
msgid "This recipient can no longer be modified as they have signed a field, or completed the document."
msgstr "This recipient can no longer be modified as they have signed a field, or completed the document."
@@ -1631,8 +1617,8 @@ msgstr "Time Zone"
msgid "Title"
msgstr "Title"
#: packages/ui/primitives/document-flow/add-fields.tsx:1080
#: packages/ui/primitives/template-flow/add-template-fields.tsx:873
#: packages/ui/primitives/document-flow/add-fields.tsx:1073
#: packages/ui/primitives/template-flow/add-template-fields.tsx:834
msgid "To proceed further, please set at least one value for the {0} field."
msgstr "To proceed further, please set at least one value for the {0} field."
File diff suppressed because it is too large Load Diff
+85 -98
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: es\n"
"Project-Id-Version: documenso-app\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-11-20 11:56\n"
"PO-Revision-Date: 2024-11-14 12:05\n"
"Last-Translator: \n"
"Language-Team: Spanish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -135,11 +135,11 @@ msgstr "{prefix} creó el documento"
msgid "{prefix} deleted the document"
msgstr "{prefix} eliminó el documento"
#: packages/lib/utils/document-audit-logs.ts:339
#: packages/lib/utils/document-audit-logs.ts:335
msgid "{prefix} moved the document to team"
msgstr "{prefix} movió el documento al equipo"
#: packages/lib/utils/document-audit-logs.ts:323
#: packages/lib/utils/document-audit-logs.ts:319
msgid "{prefix} opened the document"
msgstr "{prefix} abrió el documento"
@@ -151,27 +151,23 @@ msgstr "{prefix} eliminó un campo"
msgid "{prefix} removed a recipient"
msgstr "{prefix} eliminó un destinatario"
#: packages/lib/utils/document-audit-logs.ts:369
#: packages/lib/utils/document-audit-logs.ts:365
msgid "{prefix} resent an email to {0}"
msgstr "{prefix} reenviaron un correo electrónico a {0}"
#: packages/lib/utils/document-audit-logs.ts:295
msgid "{prefix} restored the document"
msgstr ""
#: packages/lib/utils/document-audit-logs.ts:370
#: packages/lib/utils/document-audit-logs.ts:366
msgid "{prefix} sent an email to {0}"
msgstr "{prefix} envió un correo electrónico a {0}"
#: packages/lib/utils/document-audit-logs.ts:335
#: packages/lib/utils/document-audit-logs.ts:331
msgid "{prefix} sent the document"
msgstr "{prefix} envió el documento"
#: packages/lib/utils/document-audit-logs.ts:299
#: packages/lib/utils/document-audit-logs.ts:295
msgid "{prefix} signed a field"
msgstr "{prefix} firmó un campo"
#: packages/lib/utils/document-audit-logs.ts:303
#: packages/lib/utils/document-audit-logs.ts:299
msgid "{prefix} unsigned a field"
msgstr "{prefix} no firmó un campo"
@@ -183,27 +179,27 @@ msgstr "{prefix} actualizó un campo"
msgid "{prefix} updated a recipient"
msgstr "{prefix} actualizó un destinatario"
#: packages/lib/utils/document-audit-logs.ts:319
#: packages/lib/utils/document-audit-logs.ts:315
msgid "{prefix} updated the document"
msgstr "{prefix} actualizó el documento"
#: packages/lib/utils/document-audit-logs.ts:311
#: packages/lib/utils/document-audit-logs.ts:307
msgid "{prefix} updated the document access auth requirements"
msgstr "{prefix} actualizó los requisitos de autorización de acceso al documento"
#: packages/lib/utils/document-audit-logs.ts:331
#: packages/lib/utils/document-audit-logs.ts:327
msgid "{prefix} updated the document external ID"
msgstr "{prefix} actualizó el ID externo del documento"
#: packages/lib/utils/document-audit-logs.ts:315
#: packages/lib/utils/document-audit-logs.ts:311
msgid "{prefix} updated the document signing auth requirements"
msgstr "{prefix} actualizó los requisitos de autenticación para la firma del documento"
#: packages/lib/utils/document-audit-logs.ts:327
#: packages/lib/utils/document-audit-logs.ts:323
msgid "{prefix} updated the document title"
msgstr "{prefix} actualizó el título del documento"
#: packages/lib/utils/document-audit-logs.ts:307
#: packages/lib/utils/document-audit-logs.ts:303
msgid "{prefix} updated the document visibility"
msgstr "{prefix} actualizó la visibilidad del documento"
@@ -231,27 +227,27 @@ msgstr "{teamName} te ha invitado a {action} {documentName}"
msgid "{teamName} ownership transfer request"
msgstr "solicitud de transferencia de propiedad de {teamName}"
#: packages/lib/utils/document-audit-logs.ts:347
#: packages/lib/utils/document-audit-logs.ts:343
msgid "{userName} approved the document"
msgstr "{userName} aprobó el documento"
#: packages/lib/utils/document-audit-logs.ts:348
#: packages/lib/utils/document-audit-logs.ts:344
msgid "{userName} CC'd the document"
msgstr "{userName} envió una copia del documento"
#: packages/lib/utils/document-audit-logs.ts:349
#: packages/lib/utils/document-audit-logs.ts:345
msgid "{userName} completed their task"
msgstr "{userName} completó su tarea"
#: packages/lib/utils/document-audit-logs.ts:359
#: packages/lib/utils/document-audit-logs.ts:355
msgid "{userName} rejected the document"
msgstr "{userName} rechazó el documento"
#: packages/lib/utils/document-audit-logs.ts:345
#: packages/lib/utils/document-audit-logs.ts:341
msgid "{userName} signed the document"
msgstr "{userName} firmó el documento"
#: packages/lib/utils/document-audit-logs.ts:346
#: packages/lib/utils/document-audit-logs.ts:342
msgid "{userName} viewed the document"
msgstr "{userName} vio el documento"
@@ -418,11 +414,11 @@ msgstr "Agregar otro valor"
msgid "Add myself"
msgstr "Agregame"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:645
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:637
msgid "Add Myself"
msgstr "Agregame"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:631
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:623
msgid "Add Placeholder Recipient"
msgstr "Agregar destinatario de marcador de posición"
@@ -447,8 +443,8 @@ msgstr "Admin"
msgid "Advanced Options"
msgstr "Opciones avanzadas"
#: packages/ui/primitives/document-flow/add-fields.tsx:576
#: packages/ui/primitives/template-flow/add-template-fields.tsx:414
#: packages/ui/primitives/document-flow/add-fields.tsx:573
#: packages/ui/primitives/template-flow/add-template-fields.tsx:406
msgid "Advanced settings"
msgstr "Configuraciones avanzadas"
@@ -504,11 +500,11 @@ msgstr "Aprobando"
msgid "Before you get started, please confirm your email address by clicking the button below:"
msgstr "Antes de comenzar, por favor confirma tu dirección de correo electrónico haciendo clic en el botón de abajo:"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:383
#: packages/ui/primitives/signature-pad/signature-pad.tsx:377
msgid "Black"
msgstr "Negro"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:397
#: packages/ui/primitives/signature-pad/signature-pad.tsx:391
msgid "Blue"
msgstr "Azul"
@@ -554,10 +550,6 @@ msgstr "Ccers"
msgid "Character Limit"
msgstr "Límite de caracteres"
#: packages/ui/primitives/document-flow/types.ts:58
msgid "Checkbox"
msgstr "Checkbox"
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx:197
msgid "Checkbox values"
msgstr "Valores de Checkbox"
@@ -566,7 +558,7 @@ msgstr "Valores de Checkbox"
msgid "Clear filters"
msgstr "Limpiar filtros"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:417
#: packages/ui/primitives/signature-pad/signature-pad.tsx:411
msgid "Clear Signature"
msgstr "Limpiar firma"
@@ -593,8 +585,8 @@ msgstr "Documento completado"
msgid "Configure Direct Recipient"
msgstr "Configurar destinatario directo"
#: packages/ui/primitives/document-flow/add-fields.tsx:577
#: packages/ui/primitives/template-flow/add-template-fields.tsx:415
#: packages/ui/primitives/document-flow/add-fields.tsx:574
#: packages/ui/primitives/template-flow/add-template-fields.tsx:407
msgid "Configure the {0} field"
msgstr "Configurar el campo {0}"
@@ -655,9 +647,9 @@ msgstr "Crear cuenta"
msgid "Custom Text"
msgstr "Texto personalizado"
#: packages/ui/primitives/document-flow/add-fields.tsx:934
#: packages/ui/primitives/document-flow/add-fields.tsx:927
#: packages/ui/primitives/document-flow/types.ts:53
#: packages/ui/primitives/template-flow/add-template-fields.tsx:729
#: packages/ui/primitives/template-flow/add-template-fields.tsx:690
msgid "Date"
msgstr "Fecha"
@@ -674,7 +666,7 @@ msgstr "Rechazar"
msgid "Didn't request a password change? We are here to help you secure your account, just <0>contact us.</0>"
msgstr "¿No solicitaste un cambio de contraseña? Estamos aquí para ayudarte a asegurar tu cuenta, solo <0>contáctanos.</0>"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:578
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:570
msgid "Direct link receiver"
msgstr "Receptor de enlace directo"
@@ -692,17 +684,17 @@ msgstr "Documento \"{0}\" - Rechazo confirmado"
msgid "Document access"
msgstr "Acceso al documento"
#: packages/lib/utils/document-audit-logs.ts:310
#: packages/lib/utils/document-audit-logs.ts:306
msgid "Document access auth updated"
msgstr "Se actualizó la autenticación de acceso al documento"
#: packages/lib/server-only/document/delete-document.ts:256
#: packages/lib/server-only/document/delete-document.ts:246
#: packages/lib/server-only/document/super-delete-document.ts:98
msgid "Document Cancelled"
msgstr "Documento cancelado"
#: packages/lib/utils/document-audit-logs.ts:373
#: packages/lib/utils/document-audit-logs.ts:374
#: packages/lib/utils/document-audit-logs.ts:369
#: packages/lib/utils/document-audit-logs.ts:370
msgid "Document completed"
msgstr "Documento completado"
@@ -740,15 +732,15 @@ msgstr "¡Documento eliminado!"
msgid "Document Distribution Method"
msgstr "Método de distribución de documentos"
#: packages/lib/utils/document-audit-logs.ts:330
#: packages/lib/utils/document-audit-logs.ts:326
msgid "Document external ID updated"
msgstr "ID externo del documento actualizado"
#: packages/lib/utils/document-audit-logs.ts:338
#: packages/lib/utils/document-audit-logs.ts:334
msgid "Document moved to team"
msgstr "Documento movido al equipo"
#: packages/lib/utils/document-audit-logs.ts:322
#: packages/lib/utils/document-audit-logs.ts:318
msgid "Document opened"
msgstr "Documento abierto"
@@ -763,27 +755,23 @@ msgstr "Documento Rechazado"
#~ msgid "Document Rejection Confirmed"
#~ msgstr "Document Rejection Confirmed"
#: packages/lib/utils/document-audit-logs.ts:294
msgid "Document restored"
msgstr ""
#: packages/lib/utils/document-audit-logs.ts:334
#: packages/lib/utils/document-audit-logs.ts:330
msgid "Document sent"
msgstr "Documento enviado"
#: packages/lib/utils/document-audit-logs.ts:314
#: packages/lib/utils/document-audit-logs.ts:310
msgid "Document signing auth updated"
msgstr "Se actualizó la autenticación de firma del documento"
#: packages/lib/utils/document-audit-logs.ts:326
#: packages/lib/utils/document-audit-logs.ts:322
msgid "Document title updated"
msgstr "Título del documento actualizado"
#: packages/lib/utils/document-audit-logs.ts:318
#: packages/lib/utils/document-audit-logs.ts:314
msgid "Document updated"
msgstr "Documento actualizado"
#: packages/lib/utils/document-audit-logs.ts:306
#: packages/lib/utils/document-audit-logs.ts:302
msgid "Document visibility updated"
msgstr "Visibilidad del documento actualizada"
@@ -800,8 +788,8 @@ msgstr "Borrador"
msgid "Drag & drop your PDF here."
msgstr "Arrastre y suelte su PDF aquí."
#: packages/ui/primitives/document-flow/add-fields.tsx:1065
#: packages/ui/primitives/template-flow/add-template-fields.tsx:860
#: packages/ui/primitives/document-flow/add-fields.tsx:1058
#: packages/ui/primitives/template-flow/add-template-fields.tsx:820
msgid "Dropdown"
msgstr "Menú desplegable"
@@ -810,14 +798,14 @@ msgid "Dropdown options"
msgstr "Opciones de menú desplegable"
#: packages/lib/constants/document.ts:28
#: packages/ui/primitives/document-flow/add-fields.tsx:882
#: packages/ui/primitives/document-flow/add-fields.tsx:875
#: packages/ui/primitives/document-flow/add-signature.tsx:272
#: packages/ui/primitives/document-flow/add-signers.tsx:512
#: packages/ui/primitives/document-flow/add-signers.tsx:519
#: packages/ui/primitives/document-flow/types.ts:54
#: packages/ui/primitives/template-flow/add-template-fields.tsx:677
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:471
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:478
#: packages/ui/primitives/template-flow/add-template-fields.tsx:638
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:463
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:470
msgid "Email"
msgstr "Correo electrónico"
@@ -829,15 +817,15 @@ msgstr "Se requiere email"
msgid "Email Options"
msgstr "Opciones de correo electrónico"
#: packages/lib/utils/document-audit-logs.ts:367
#: packages/lib/utils/document-audit-logs.ts:363
msgid "Email resent"
msgstr "Correo electrónico reeenviado"
#: packages/lib/utils/document-audit-logs.ts:367
#: packages/lib/utils/document-audit-logs.ts:363
msgid "Email sent"
msgstr "Correo electrónico enviado"
#: packages/ui/primitives/document-flow/add-fields.tsx:1130
#: packages/ui/primitives/document-flow/add-fields.tsx:1123
msgid "Empty field"
msgstr "Campo vacío"
@@ -846,12 +834,11 @@ msgid "Enable Direct Link Signing"
msgstr "Habilitar firma de enlace directo"
#: packages/ui/primitives/document-flow/add-signers.tsx:401
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:370
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:362
msgid "Enable signing order"
msgstr "Habilitar orden de firma"
#: packages/ui/primitives/document-flow/add-fields.tsx:802
#: packages/ui/primitives/template-flow/add-template-fields.tsx:597
#: packages/ui/primitives/document-flow/add-fields.tsx:795
msgid "Enable Typed Signatures"
msgstr "Habilitar firmas escritas"
@@ -898,11 +885,11 @@ msgstr "Etiqueta de campo"
msgid "Field placeholder"
msgstr "Marcador de posición de campo"
#: packages/lib/utils/document-audit-logs.ts:298
#: packages/lib/utils/document-audit-logs.ts:294
msgid "Field signed"
msgstr "Campo firmado"
#: packages/lib/utils/document-audit-logs.ts:302
#: packages/lib/utils/document-audit-logs.ts:298
msgid "Field unsigned"
msgstr "Campo no firmado"
@@ -939,7 +926,7 @@ msgstr "Autenticación de acción de destinatario global"
msgid "Go Back"
msgstr "Regresar"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:404
#: packages/ui/primitives/signature-pad/signature-pad.tsx:398
msgid "Green"
msgstr "Verde"
@@ -1029,14 +1016,14 @@ msgstr "Mensaje <0>(Opcional)</0>"
msgid "Min"
msgstr "Mín"
#: packages/ui/primitives/document-flow/add-fields.tsx:908
#: packages/ui/primitives/document-flow/add-fields.tsx:901
#: packages/ui/primitives/document-flow/add-signature.tsx:298
#: packages/ui/primitives/document-flow/add-signers.tsx:550
#: packages/ui/primitives/document-flow/add-signers.tsx:556
#: packages/ui/primitives/document-flow/types.ts:55
#: packages/ui/primitives/template-flow/add-template-fields.tsx:703
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:506
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:512
#: packages/ui/primitives/template-flow/add-template-fields.tsx:664
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:498
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:504
msgid "Name"
msgstr "Nombre"
@@ -1052,8 +1039,8 @@ msgstr "Necesita firmar"
msgid "Needs to view"
msgstr "Necesita ver"
#: packages/ui/primitives/document-flow/add-fields.tsx:693
#: packages/ui/primitives/template-flow/add-template-fields.tsx:516
#: packages/ui/primitives/document-flow/add-fields.tsx:686
#: packages/ui/primitives/template-flow/add-template-fields.tsx:504
msgid "No recipient matching this description was found."
msgstr "No se encontró ningún destinatario que coincidiera con esta descripción."
@@ -1061,8 +1048,8 @@ msgstr "No se encontró ningún destinatario que coincidiera con esta descripci
msgid "No recipients"
msgstr "Sin destinatarios"
#: packages/ui/primitives/document-flow/add-fields.tsx:708
#: packages/ui/primitives/template-flow/add-template-fields.tsx:531
#: packages/ui/primitives/document-flow/add-fields.tsx:701
#: packages/ui/primitives/template-flow/add-template-fields.tsx:519
msgid "No recipients with this role"
msgstr "No hay destinatarios con este rol"
@@ -1090,9 +1077,9 @@ msgstr "No se encontró valor."
msgid "None"
msgstr "Ninguno"
#: packages/ui/primitives/document-flow/add-fields.tsx:986
#: packages/ui/primitives/document-flow/add-fields.tsx:979
#: packages/ui/primitives/document-flow/types.ts:56
#: packages/ui/primitives/template-flow/add-template-fields.tsx:781
#: packages/ui/primitives/template-flow/add-template-fields.tsx:742
msgid "Number"
msgstr "Número"
@@ -1183,7 +1170,7 @@ msgstr "Por favor confirma tu dirección de correo electrónico"
msgid "Please try again or contact our support."
msgstr "Por favor, inténtalo de nuevo o contacta a nuestro soporte."
#: packages/ui/primitives/document-flow/types.ts:57
#: packages/ui/primitives/template-flow/add-template-fields.tsx:768
msgid "Radio"
msgstr "Radio"
@@ -1207,8 +1194,8 @@ msgstr "Razón del rechazo: {rejectionReason}"
msgid "Receives copy"
msgstr "Recibe copia"
#: packages/lib/utils/document-audit-logs.ts:342
#: packages/lib/utils/document-audit-logs.ts:357
#: packages/lib/utils/document-audit-logs.ts:338
#: packages/lib/utils/document-audit-logs.ts:353
msgid "Recipient"
msgstr "Destinatario"
@@ -1226,7 +1213,7 @@ msgstr "Correo electrónico de destinatario eliminado"
msgid "Recipient signing request email"
msgstr "Correo electrónico de solicitud de firma de destinatario"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:390
#: packages/ui/primitives/signature-pad/signature-pad.tsx:384
msgid "Red"
msgstr "Rojo"
@@ -1263,7 +1250,7 @@ msgstr "Recordatorio: Por favor {recipientActionVerb} este documento"
msgid "Reminder: Please {recipientActionVerb} your document"
msgstr "Recordatorio: Por favor {recipientActionVerb} tu documento"
#: packages/ui/primitives/document-flow/add-fields.tsx:1117
#: packages/ui/primitives/document-flow/add-fields.tsx:1110
msgid "Remove"
msgstr "Eliminar"
@@ -1295,7 +1282,7 @@ msgstr "Filas por página"
msgid "Save"
msgstr "Guardar"
#: packages/ui/primitives/template-flow/add-template-fields.tsx:893
#: packages/ui/primitives/template-flow/add-template-fields.tsx:854
msgid "Save Template"
msgstr "Guardar plantilla"
@@ -1304,7 +1291,6 @@ msgid "Search languages..."
msgstr "Buscar idiomas..."
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx:115
#: packages/ui/primitives/document-flow/types.ts:59
msgid "Select"
msgstr "Seleccionar"
@@ -1368,7 +1354,7 @@ msgid "Share your signing experience!"
msgstr "¡Comparte tu experiencia de firma!"
#: packages/ui/primitives/document-flow/add-signers.tsx:709
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:663
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:655
msgid "Show advanced settings"
msgstr "Mostrar configuraciones avanzadas"
@@ -1384,11 +1370,11 @@ msgstr "Firmar Documento"
msgid "Sign In"
msgstr "Iniciar sesión"
#: packages/ui/primitives/document-flow/add-fields.tsx:830
#: packages/ui/primitives/document-flow/add-fields.tsx:823
#: packages/ui/primitives/document-flow/add-signature.tsx:323
#: packages/ui/primitives/document-flow/field-icon.tsx:52
#: packages/ui/primitives/document-flow/types.ts:49
#: packages/ui/primitives/template-flow/add-template-fields.tsx:625
#: packages/ui/primitives/template-flow/add-template-fields.tsx:586
msgid "Signature"
msgstr "Firma"
@@ -1471,9 +1457,9 @@ msgstr "Correo electrónico del equipo eliminado para {teamName} en Documenso"
msgid "Template title"
msgstr "Título de plantilla"
#: packages/ui/primitives/document-flow/add-fields.tsx:960
#: packages/ui/primitives/document-flow/add-fields.tsx:953
#: packages/ui/primitives/document-flow/types.ts:52
#: packages/ui/primitives/template-flow/add-template-fields.tsx:755
#: packages/ui/primitives/template-flow/add-template-fields.tsx:716
msgid "Text"
msgstr "Texto"
@@ -1568,7 +1554,7 @@ msgstr "Esto se puede anular configurando los requisitos de autenticación direc
msgid "This document can not be recovered, if you would like to dispute the reason for future documents please contact support."
msgstr "Este documento no se puede recuperar, si deseas impugnar la razón para documentos futuros, por favor contacta con el soporte."
#: packages/ui/primitives/document-flow/add-fields.tsx:764
#: packages/ui/primitives/document-flow/add-fields.tsx:757
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
msgstr "Este documento ya ha sido enviado a este destinatario. Ya no puede editar a este destinatario."
@@ -1599,7 +1585,7 @@ msgstr "Este correo electrónico se envía al destinatario solicitando que firme
msgid "This email will be sent to the recipient who has just signed the document, if there are still other recipients who have not signed yet."
msgstr "Este correo electrónico se enviará al destinatario que acaba de firmar el documento, si todavía hay otros destinatarios que no han firmado."
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:581
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:573
msgid "This field cannot be modified or deleted. When you share this template's direct link or add it to your public profile, anyone who accesses it can input their name and email, and fill in the fields assigned to them."
msgstr "Este campo no se puede modificar ni eliminar. Cuando comparta el enlace directo de esta plantilla o lo agregue a su perfil público, cualquiera que acceda podrá ingresar su nombre y correo electrónico, y completar los campos que se le hayan asignado."
@@ -1607,7 +1593,7 @@ msgstr "Este campo no se puede modificar ni eliminar. Cuando comparta el enlace
msgid "This is how the document will reach the recipients once the document is ready for signing."
msgstr "Así es como el documento llegará a los destinatarios una vez que esté listo para firmarse."
#: packages/ui/primitives/document-flow/add-fields.tsx:1097
#: packages/ui/primitives/document-flow/add-fields.tsx:1090
msgid "This recipient can no longer be modified as they have signed a field, or completed the document."
msgstr "Este destinatario ya no puede ser modificado ya que ha firmado un campo o completado el documento."
@@ -1636,8 +1622,8 @@ msgstr "Zona horaria"
msgid "Title"
msgstr "Título"
#: packages/ui/primitives/document-flow/add-fields.tsx:1080
#: packages/ui/primitives/template-flow/add-template-fields.tsx:873
#: packages/ui/primitives/document-flow/add-fields.tsx:1073
#: packages/ui/primitives/template-flow/add-template-fields.tsx:834
msgid "To proceed further, please set at least one value for the {0} field."
msgstr "Para continuar, por favor establezca al menos un valor para el campo {0}."
@@ -1822,3 +1808,4 @@ msgstr "Tu contraseña ha sido actualizada."
#: packages/email/templates/team-delete.tsx:32
msgid "Your team has been deleted"
msgstr "Tu equipo ha sido eliminado"
+2 -1
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: es\n"
"Project-Id-Version: documenso-app\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-11-20 11:56\n"
"PO-Revision-Date: 2024-11-14 12:05\n"
"Last-Translator: \n"
"Language-Team: Spanish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -602,3 +602,4 @@ msgstr "Puedes autoalojar Documenso de forma gratuita o usar nuestra versión al
#: apps/marketing/src/components/(marketing)/carousel.tsx:272
msgid "Your browser does not support the video tag."
msgstr "Tu navegador no soporta la etiqueta de video."
File diff suppressed because it is too large Load Diff
+85 -98
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: fr\n"
"Project-Id-Version: documenso-app\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-11-20 11:56\n"
"PO-Revision-Date: 2024-11-14 12:05\n"
"Last-Translator: \n"
"Language-Team: French\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
@@ -135,11 +135,11 @@ msgstr "{prefix} a créé le document"
msgid "{prefix} deleted the document"
msgstr "{prefix} a supprimé le document"
#: packages/lib/utils/document-audit-logs.ts:339
#: packages/lib/utils/document-audit-logs.ts:335
msgid "{prefix} moved the document to team"
msgstr "{prefix} a déplacé le document vers l'équipe"
#: packages/lib/utils/document-audit-logs.ts:323
#: packages/lib/utils/document-audit-logs.ts:319
msgid "{prefix} opened the document"
msgstr "{prefix} a ouvert le document"
@@ -151,27 +151,23 @@ msgstr "{prefix} a supprimé un champ"
msgid "{prefix} removed a recipient"
msgstr "{prefix} a supprimé un destinataire"
#: packages/lib/utils/document-audit-logs.ts:369
#: packages/lib/utils/document-audit-logs.ts:365
msgid "{prefix} resent an email to {0}"
msgstr "{prefix} a renvoyé un e-mail à {0}"
#: packages/lib/utils/document-audit-logs.ts:295
msgid "{prefix} restored the document"
msgstr ""
#: packages/lib/utils/document-audit-logs.ts:370
#: packages/lib/utils/document-audit-logs.ts:366
msgid "{prefix} sent an email to {0}"
msgstr "{prefix} a envoyé un email à {0}"
#: packages/lib/utils/document-audit-logs.ts:335
#: packages/lib/utils/document-audit-logs.ts:331
msgid "{prefix} sent the document"
msgstr "{prefix} a envoyé le document"
#: packages/lib/utils/document-audit-logs.ts:299
#: packages/lib/utils/document-audit-logs.ts:295
msgid "{prefix} signed a field"
msgstr "{prefix} a signé un champ"
#: packages/lib/utils/document-audit-logs.ts:303
#: packages/lib/utils/document-audit-logs.ts:299
msgid "{prefix} unsigned a field"
msgstr "{prefix} n'a pas signé un champ"
@@ -183,27 +179,27 @@ msgstr "{prefix} a mis à jour un champ"
msgid "{prefix} updated a recipient"
msgstr "{prefix} a mis à jour un destinataire"
#: packages/lib/utils/document-audit-logs.ts:319
#: packages/lib/utils/document-audit-logs.ts:315
msgid "{prefix} updated the document"
msgstr "{prefix} a mis à jour le document"
#: packages/lib/utils/document-audit-logs.ts:311
#: packages/lib/utils/document-audit-logs.ts:307
msgid "{prefix} updated the document access auth requirements"
msgstr "{prefix} a mis à jour les exigences d'authentification d'accès au document"
#: packages/lib/utils/document-audit-logs.ts:331
#: packages/lib/utils/document-audit-logs.ts:327
msgid "{prefix} updated the document external ID"
msgstr "{prefix} a mis à jour l'ID externe du document"
#: packages/lib/utils/document-audit-logs.ts:315
#: packages/lib/utils/document-audit-logs.ts:311
msgid "{prefix} updated the document signing auth requirements"
msgstr "{prefix} a mis à jour les exigences d'authentification pour la signature du document"
#: packages/lib/utils/document-audit-logs.ts:327
#: packages/lib/utils/document-audit-logs.ts:323
msgid "{prefix} updated the document title"
msgstr "{prefix} a mis à jour le titre du document"
#: packages/lib/utils/document-audit-logs.ts:307
#: packages/lib/utils/document-audit-logs.ts:303
msgid "{prefix} updated the document visibility"
msgstr "{prefix} a mis à jour la visibilité du document"
@@ -231,27 +227,27 @@ msgstr "{teamName} vous a invité à {action} {documentName}"
msgid "{teamName} ownership transfer request"
msgstr "Demande de transfert de propriété de {teamName}"
#: packages/lib/utils/document-audit-logs.ts:347
#: packages/lib/utils/document-audit-logs.ts:343
msgid "{userName} approved the document"
msgstr "{userName} a approuvé le document"
#: packages/lib/utils/document-audit-logs.ts:348
#: packages/lib/utils/document-audit-logs.ts:344
msgid "{userName} CC'd the document"
msgstr "{userName} a mis en copie le document"
#: packages/lib/utils/document-audit-logs.ts:349
#: packages/lib/utils/document-audit-logs.ts:345
msgid "{userName} completed their task"
msgstr "{userName} a complété sa tâche"
#: packages/lib/utils/document-audit-logs.ts:359
#: packages/lib/utils/document-audit-logs.ts:355
msgid "{userName} rejected the document"
msgstr "{userName} a rejeté le document"
#: packages/lib/utils/document-audit-logs.ts:345
#: packages/lib/utils/document-audit-logs.ts:341
msgid "{userName} signed the document"
msgstr "{userName} a signé le document"
#: packages/lib/utils/document-audit-logs.ts:346
#: packages/lib/utils/document-audit-logs.ts:342
msgid "{userName} viewed the document"
msgstr "{userName} a consulté le document"
@@ -418,11 +414,11 @@ msgstr "Ajouter une autre valeur"
msgid "Add myself"
msgstr "Ajoutez-moi"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:645
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:637
msgid "Add Myself"
msgstr "Ajoutez-moi"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:631
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:623
msgid "Add Placeholder Recipient"
msgstr "Ajouter un destinataire de substitution"
@@ -447,8 +443,8 @@ msgstr "Administrateur"
msgid "Advanced Options"
msgstr "Options avancées"
#: packages/ui/primitives/document-flow/add-fields.tsx:576
#: packages/ui/primitives/template-flow/add-template-fields.tsx:414
#: packages/ui/primitives/document-flow/add-fields.tsx:573
#: packages/ui/primitives/template-flow/add-template-fields.tsx:406
msgid "Advanced settings"
msgstr "Paramètres avancés"
@@ -504,11 +500,11 @@ msgstr "En attente d'approbation"
msgid "Before you get started, please confirm your email address by clicking the button below:"
msgstr "Avant de commencer, veuillez confirmer votre adresse email en cliquant sur le bouton ci-dessous :"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:383
#: packages/ui/primitives/signature-pad/signature-pad.tsx:377
msgid "Black"
msgstr "Noir"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:397
#: packages/ui/primitives/signature-pad/signature-pad.tsx:391
msgid "Blue"
msgstr "Bleu"
@@ -554,10 +550,6 @@ msgstr "Ccers"
msgid "Character Limit"
msgstr "Limite de caractères"
#: packages/ui/primitives/document-flow/types.ts:58
msgid "Checkbox"
msgstr "Case à cocher"
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx:197
msgid "Checkbox values"
msgstr "Valeurs de case à cocher"
@@ -566,7 +558,7 @@ msgstr "Valeurs de case à cocher"
msgid "Clear filters"
msgstr "Effacer les filtres"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:417
#: packages/ui/primitives/signature-pad/signature-pad.tsx:411
msgid "Clear Signature"
msgstr "Effacer la signature"
@@ -593,8 +585,8 @@ msgstr "Document Terminé"
msgid "Configure Direct Recipient"
msgstr "Configurer le destinataire direct"
#: packages/ui/primitives/document-flow/add-fields.tsx:577
#: packages/ui/primitives/template-flow/add-template-fields.tsx:415
#: packages/ui/primitives/document-flow/add-fields.tsx:574
#: packages/ui/primitives/template-flow/add-template-fields.tsx:407
msgid "Configure the {0} field"
msgstr "Configurer le champ {0}"
@@ -655,9 +647,9 @@ msgstr "Créer un compte"
msgid "Custom Text"
msgstr "Texte personnalisé"
#: packages/ui/primitives/document-flow/add-fields.tsx:934
#: packages/ui/primitives/document-flow/add-fields.tsx:927
#: packages/ui/primitives/document-flow/types.ts:53
#: packages/ui/primitives/template-flow/add-template-fields.tsx:729
#: packages/ui/primitives/template-flow/add-template-fields.tsx:690
msgid "Date"
msgstr "Date"
@@ -674,7 +666,7 @@ msgstr "Décliner"
msgid "Didn't request a password change? We are here to help you secure your account, just <0>contact us.</0>"
msgstr "Vous n'avez pas demandé de changement de mot de passe ? Nous sommes ici pour vous aider à sécuriser votre compte, il suffit de <0>nous contacter.</0>"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:578
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:570
msgid "Direct link receiver"
msgstr "Receveur de lien direct"
@@ -692,17 +684,17 @@ msgstr "Document \"{0}\" - Rejet Confirmé"
msgid "Document access"
msgstr "Accès au document"
#: packages/lib/utils/document-audit-logs.ts:310
#: packages/lib/utils/document-audit-logs.ts:306
msgid "Document access auth updated"
msgstr "L'authentification d'accès au document a été mise à jour"
#: packages/lib/server-only/document/delete-document.ts:256
#: packages/lib/server-only/document/delete-document.ts:246
#: packages/lib/server-only/document/super-delete-document.ts:98
msgid "Document Cancelled"
msgstr "Document Annulé"
#: packages/lib/utils/document-audit-logs.ts:373
#: packages/lib/utils/document-audit-logs.ts:374
#: packages/lib/utils/document-audit-logs.ts:369
#: packages/lib/utils/document-audit-logs.ts:370
msgid "Document completed"
msgstr "Document terminé"
@@ -740,15 +732,15 @@ msgstr "Document Supprimé !"
msgid "Document Distribution Method"
msgstr "Méthode de distribution du document"
#: packages/lib/utils/document-audit-logs.ts:330
#: packages/lib/utils/document-audit-logs.ts:326
msgid "Document external ID updated"
msgstr "ID externe du document mis à jour"
#: packages/lib/utils/document-audit-logs.ts:338
#: packages/lib/utils/document-audit-logs.ts:334
msgid "Document moved to team"
msgstr "Document déplacé vers l'équipe"
#: packages/lib/utils/document-audit-logs.ts:322
#: packages/lib/utils/document-audit-logs.ts:318
msgid "Document opened"
msgstr "Document ouvert"
@@ -763,27 +755,23 @@ msgstr "Document Rejeté"
#~ msgid "Document Rejection Confirmed"
#~ msgstr "Document Rejection Confirmed"
#: packages/lib/utils/document-audit-logs.ts:294
msgid "Document restored"
msgstr ""
#: packages/lib/utils/document-audit-logs.ts:334
#: packages/lib/utils/document-audit-logs.ts:330
msgid "Document sent"
msgstr "Document envoyé"
#: packages/lib/utils/document-audit-logs.ts:314
#: packages/lib/utils/document-audit-logs.ts:310
msgid "Document signing auth updated"
msgstr "Authentification de signature de document mise à jour"
#: packages/lib/utils/document-audit-logs.ts:326
#: packages/lib/utils/document-audit-logs.ts:322
msgid "Document title updated"
msgstr "Titre du document mis à jour"
#: packages/lib/utils/document-audit-logs.ts:318
#: packages/lib/utils/document-audit-logs.ts:314
msgid "Document updated"
msgstr "Document mis à jour"
#: packages/lib/utils/document-audit-logs.ts:306
#: packages/lib/utils/document-audit-logs.ts:302
msgid "Document visibility updated"
msgstr "Visibilité du document mise à jour"
@@ -800,8 +788,8 @@ msgstr "Brouillon"
msgid "Drag & drop your PDF here."
msgstr "Faites glisser et déposez votre PDF ici."
#: packages/ui/primitives/document-flow/add-fields.tsx:1065
#: packages/ui/primitives/template-flow/add-template-fields.tsx:860
#: packages/ui/primitives/document-flow/add-fields.tsx:1058
#: packages/ui/primitives/template-flow/add-template-fields.tsx:820
msgid "Dropdown"
msgstr "Liste déroulante"
@@ -810,14 +798,14 @@ msgid "Dropdown options"
msgstr "Options de liste déroulante"
#: packages/lib/constants/document.ts:28
#: packages/ui/primitives/document-flow/add-fields.tsx:882
#: packages/ui/primitives/document-flow/add-fields.tsx:875
#: packages/ui/primitives/document-flow/add-signature.tsx:272
#: packages/ui/primitives/document-flow/add-signers.tsx:512
#: packages/ui/primitives/document-flow/add-signers.tsx:519
#: packages/ui/primitives/document-flow/types.ts:54
#: packages/ui/primitives/template-flow/add-template-fields.tsx:677
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:471
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:478
#: packages/ui/primitives/template-flow/add-template-fields.tsx:638
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:463
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:470
msgid "Email"
msgstr "Email"
@@ -829,15 +817,15 @@ msgstr "L'email est requis"
msgid "Email Options"
msgstr "Options d'email"
#: packages/lib/utils/document-audit-logs.ts:367
#: packages/lib/utils/document-audit-logs.ts:363
msgid "Email resent"
msgstr "Email renvoyé"
#: packages/lib/utils/document-audit-logs.ts:367
#: packages/lib/utils/document-audit-logs.ts:363
msgid "Email sent"
msgstr "Email envoyé"
#: packages/ui/primitives/document-flow/add-fields.tsx:1130
#: packages/ui/primitives/document-flow/add-fields.tsx:1123
msgid "Empty field"
msgstr "Champ vide"
@@ -846,12 +834,11 @@ msgid "Enable Direct Link Signing"
msgstr "Activer la signature de lien direct"
#: packages/ui/primitives/document-flow/add-signers.tsx:401
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:370
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:362
msgid "Enable signing order"
msgstr "Activer l'ordre de signature"
#: packages/ui/primitives/document-flow/add-fields.tsx:802
#: packages/ui/primitives/template-flow/add-template-fields.tsx:597
#: packages/ui/primitives/document-flow/add-fields.tsx:795
msgid "Enable Typed Signatures"
msgstr "Activer les signatures tapées"
@@ -898,11 +885,11 @@ msgstr "Étiquette du champ"
msgid "Field placeholder"
msgstr "Espace réservé du champ"
#: packages/lib/utils/document-audit-logs.ts:298
#: packages/lib/utils/document-audit-logs.ts:294
msgid "Field signed"
msgstr "Champ signé"
#: packages/lib/utils/document-audit-logs.ts:302
#: packages/lib/utils/document-audit-logs.ts:298
msgid "Field unsigned"
msgstr "Champ non signé"
@@ -939,7 +926,7 @@ msgstr "Authentification d'action de destinataire globale"
msgid "Go Back"
msgstr "Retourner"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:404
#: packages/ui/primitives/signature-pad/signature-pad.tsx:398
msgid "Green"
msgstr "Vert"
@@ -1029,14 +1016,14 @@ msgstr "Message <0>(Optionnel)</0>"
msgid "Min"
msgstr "Min"
#: packages/ui/primitives/document-flow/add-fields.tsx:908
#: packages/ui/primitives/document-flow/add-fields.tsx:901
#: packages/ui/primitives/document-flow/add-signature.tsx:298
#: packages/ui/primitives/document-flow/add-signers.tsx:550
#: packages/ui/primitives/document-flow/add-signers.tsx:556
#: packages/ui/primitives/document-flow/types.ts:55
#: packages/ui/primitives/template-flow/add-template-fields.tsx:703
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:506
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:512
#: packages/ui/primitives/template-flow/add-template-fields.tsx:664
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:498
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:504
msgid "Name"
msgstr "Nom"
@@ -1052,8 +1039,8 @@ msgstr "Nécessite une signature"
msgid "Needs to view"
msgstr "Nécessite une visualisation"
#: packages/ui/primitives/document-flow/add-fields.tsx:693
#: packages/ui/primitives/template-flow/add-template-fields.tsx:516
#: packages/ui/primitives/document-flow/add-fields.tsx:686
#: packages/ui/primitives/template-flow/add-template-fields.tsx:504
msgid "No recipient matching this description was found."
msgstr "Aucun destinataire correspondant à cette description n'a été trouvé."
@@ -1061,8 +1048,8 @@ msgstr "Aucun destinataire correspondant à cette description n'a été trouvé.
msgid "No recipients"
msgstr "Aucun destinataire"
#: packages/ui/primitives/document-flow/add-fields.tsx:708
#: packages/ui/primitives/template-flow/add-template-fields.tsx:531
#: packages/ui/primitives/document-flow/add-fields.tsx:701
#: packages/ui/primitives/template-flow/add-template-fields.tsx:519
msgid "No recipients with this role"
msgstr "Aucun destinataire avec ce rôle"
@@ -1090,9 +1077,9 @@ msgstr "Aucune valeur trouvée."
msgid "None"
msgstr "Aucun"
#: packages/ui/primitives/document-flow/add-fields.tsx:986
#: packages/ui/primitives/document-flow/add-fields.tsx:979
#: packages/ui/primitives/document-flow/types.ts:56
#: packages/ui/primitives/template-flow/add-template-fields.tsx:781
#: packages/ui/primitives/template-flow/add-template-fields.tsx:742
msgid "Number"
msgstr "Numéro"
@@ -1183,7 +1170,7 @@ msgstr "Veuillez confirmer votre adresse email"
msgid "Please try again or contact our support."
msgstr "Veuillez réessayer ou contacter notre support."
#: packages/ui/primitives/document-flow/types.ts:57
#: packages/ui/primitives/template-flow/add-template-fields.tsx:768
msgid "Radio"
msgstr "Radio"
@@ -1207,8 +1194,8 @@ msgstr "Raison du rejet : {rejectionReason}"
msgid "Receives copy"
msgstr "Recevoir une copie"
#: packages/lib/utils/document-audit-logs.ts:342
#: packages/lib/utils/document-audit-logs.ts:357
#: packages/lib/utils/document-audit-logs.ts:338
#: packages/lib/utils/document-audit-logs.ts:353
msgid "Recipient"
msgstr "Destinataire"
@@ -1226,7 +1213,7 @@ msgstr "E-mail de destinataire supprimé"
msgid "Recipient signing request email"
msgstr "E-mail de demande de signature de destinataire"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:390
#: packages/ui/primitives/signature-pad/signature-pad.tsx:384
msgid "Red"
msgstr "Rouge"
@@ -1263,7 +1250,7 @@ msgstr "Rappel : Veuillez {recipientActionVerb} ce document"
msgid "Reminder: Please {recipientActionVerb} your document"
msgstr "Rappel : Veuillez {recipientActionVerb} votre document"
#: packages/ui/primitives/document-flow/add-fields.tsx:1117
#: packages/ui/primitives/document-flow/add-fields.tsx:1110
msgid "Remove"
msgstr "Retirer"
@@ -1295,7 +1282,7 @@ msgstr "Lignes par page"
msgid "Save"
msgstr "Sauvegarder"
#: packages/ui/primitives/template-flow/add-template-fields.tsx:893
#: packages/ui/primitives/template-flow/add-template-fields.tsx:854
msgid "Save Template"
msgstr "Sauvegarder le modèle"
@@ -1304,7 +1291,6 @@ msgid "Search languages..."
msgstr "Rechercher des langues..."
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx:115
#: packages/ui/primitives/document-flow/types.ts:59
msgid "Select"
msgstr "Sélectionner"
@@ -1368,7 +1354,7 @@ msgid "Share your signing experience!"
msgstr "Partagez votre expérience de signature !"
#: packages/ui/primitives/document-flow/add-signers.tsx:709
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:663
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:655
msgid "Show advanced settings"
msgstr "Afficher les paramètres avancés"
@@ -1384,11 +1370,11 @@ msgstr "Signer le document"
msgid "Sign In"
msgstr "Se connecter"
#: packages/ui/primitives/document-flow/add-fields.tsx:830
#: packages/ui/primitives/document-flow/add-fields.tsx:823
#: packages/ui/primitives/document-flow/add-signature.tsx:323
#: packages/ui/primitives/document-flow/field-icon.tsx:52
#: packages/ui/primitives/document-flow/types.ts:49
#: packages/ui/primitives/template-flow/add-template-fields.tsx:625
#: packages/ui/primitives/template-flow/add-template-fields.tsx:586
msgid "Signature"
msgstr "Signature"
@@ -1471,9 +1457,9 @@ msgstr "Email d'équipe supprimé pour {teamName} sur Documenso"
msgid "Template title"
msgstr "Titre du modèle"
#: packages/ui/primitives/document-flow/add-fields.tsx:960
#: packages/ui/primitives/document-flow/add-fields.tsx:953
#: packages/ui/primitives/document-flow/types.ts:52
#: packages/ui/primitives/template-flow/add-template-fields.tsx:755
#: packages/ui/primitives/template-flow/add-template-fields.tsx:716
msgid "Text"
msgstr "Texte"
@@ -1568,7 +1554,7 @@ msgstr "Cela peut être remplacé par le paramétrage direct des exigences d'aut
msgid "This document can not be recovered, if you would like to dispute the reason for future documents please contact support."
msgstr "Ce document ne peut pas être récupéré, si vous souhaitez contester la raison des documents futurs, veuillez contacter le support."
#: packages/ui/primitives/document-flow/add-fields.tsx:764
#: packages/ui/primitives/document-flow/add-fields.tsx:757
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
msgstr "Ce document a déjà été envoyé à ce destinataire. Vous ne pouvez plus modifier ce destinataire."
@@ -1599,7 +1585,7 @@ msgstr "Cet e-mail est envoyé au destinataire lui demandant de signer le docume
msgid "This email will be sent to the recipient who has just signed the document, if there are still other recipients who have not signed yet."
msgstr "Cet e-mail sera envoyé au destinataire qui vient de signer le document, s'il y a encore d'autres destinataires qui n'ont pas signé."
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:581
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:573
msgid "This field cannot be modified or deleted. When you share this template's direct link or add it to your public profile, anyone who accesses it can input their name and email, and fill in the fields assigned to them."
msgstr "Ce champ ne peut pas être modifié ou supprimé. Lorsque vous partagez le lien direct de ce modèle ou l'ajoutez à votre profil public, toute personne qui y accède peut saisir son nom et son email, et remplir les champs qui lui sont attribués."
@@ -1607,7 +1593,7 @@ msgstr "Ce champ ne peut pas être modifié ou supprimé. Lorsque vous partagez
msgid "This is how the document will reach the recipients once the document is ready for signing."
msgstr "Voici comment le document atteindra les destinataires une fois qu'il sera prêt à être signé."
#: packages/ui/primitives/document-flow/add-fields.tsx:1097
#: packages/ui/primitives/document-flow/add-fields.tsx:1090
msgid "This recipient can no longer be modified as they have signed a field, or completed the document."
msgstr "Ce destinataire ne peut plus être modifié car il a signé un champ ou complété le document."
@@ -1636,8 +1622,8 @@ msgstr "Fuseau horaire"
msgid "Title"
msgstr "Titre"
#: packages/ui/primitives/document-flow/add-fields.tsx:1080
#: packages/ui/primitives/template-flow/add-template-fields.tsx:873
#: packages/ui/primitives/document-flow/add-fields.tsx:1073
#: packages/ui/primitives/template-flow/add-template-fields.tsx:834
msgid "To proceed further, please set at least one value for the {0} field."
msgstr "Pour continuer, veuillez définir au moins une valeur pour le champ {0}."
@@ -1822,3 +1808,4 @@ msgstr "Votre mot de passe a été mis à jour."
#: packages/email/templates/team-delete.tsx:32
msgid "Your team has been deleted"
msgstr "Votre équipe a été supprimée"
+2 -1
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: fr\n"
"Project-Id-Version: documenso-app\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-11-20 11:56\n"
"PO-Revision-Date: 2024-11-14 12:05\n"
"Last-Translator: \n"
"Language-Team: French\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
@@ -602,3 +602,4 @@ msgstr "Vous pouvez auto-héberger Documenso gratuitement ou utiliser notre vers
#: apps/marketing/src/components/(marketing)/carousel.tsx:272
msgid "Your browser does not support the video tag."
msgstr "Votre navigateur ne prend pas en charge la balise vidéo."
File diff suppressed because it is too large Load Diff
+42 -48
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: pl\n"
"Project-Id-Version: documenso-app\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-11-20 11:56\n"
"PO-Revision-Date: 2024-11-14 12:05\n"
"Last-Translator: \n"
"Language-Team: Polish\n"
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
@@ -414,11 +414,11 @@ msgstr "Dodaj kolejną wartość"
msgid "Add myself"
msgstr "Dodaj siebie"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:645
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:637
msgid "Add Myself"
msgstr "Dodaj siebie"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:631
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:623
msgid "Add Placeholder Recipient"
msgstr "Dodaj odbiorcę zastępczego"
@@ -443,8 +443,8 @@ msgstr "Administrator"
msgid "Advanced Options"
msgstr "Opcje zaawansowane"
#: packages/ui/primitives/document-flow/add-fields.tsx:576
#: packages/ui/primitives/template-flow/add-template-fields.tsx:409
#: packages/ui/primitives/document-flow/add-fields.tsx:573
#: packages/ui/primitives/template-flow/add-template-fields.tsx:406
msgid "Advanced settings"
msgstr "Ustawienia zaawansowane"
@@ -550,10 +550,6 @@ msgstr "Kserokopie"
msgid "Character Limit"
msgstr "Limit znaków"
#: packages/ui/primitives/document-flow/types.ts:58
msgid "Checkbox"
msgstr "Checkbox"
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx:197
msgid "Checkbox values"
msgstr "Wartości checkboxa"
@@ -589,8 +585,8 @@ msgstr "Dokument zakończony"
msgid "Configure Direct Recipient"
msgstr "Skonfiguruj bezpośredniego odbiorcę"
#: packages/ui/primitives/document-flow/add-fields.tsx:577
#: packages/ui/primitives/template-flow/add-template-fields.tsx:410
#: packages/ui/primitives/document-flow/add-fields.tsx:574
#: packages/ui/primitives/template-flow/add-template-fields.tsx:407
msgid "Configure the {0} field"
msgstr "Skonfiguruj pole {0}"
@@ -651,9 +647,9 @@ msgstr "Utwórz konto"
msgid "Custom Text"
msgstr "Tekst niestandardowy"
#: packages/ui/primitives/document-flow/add-fields.tsx:934
#: packages/ui/primitives/document-flow/add-fields.tsx:927
#: packages/ui/primitives/document-flow/types.ts:53
#: packages/ui/primitives/template-flow/add-template-fields.tsx:697
#: packages/ui/primitives/template-flow/add-template-fields.tsx:690
msgid "Date"
msgstr "Data"
@@ -670,7 +666,7 @@ msgstr "Odmów"
msgid "Didn't request a password change? We are here to help you secure your account, just <0>contact us.</0>"
msgstr "Nie prosiłeś o zmianę hasła? Jesteśmy tutaj, aby pomóc Ci zabezpieczyć swoje konto, po prostu <0>skontaktuj się z nami.</0>"
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:578
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:570
msgid "Direct link receiver"
msgstr "Odbiorca linku bezpośredniego"
@@ -792,8 +788,8 @@ msgstr "Robocza wersja"
msgid "Drag & drop your PDF here."
msgstr "Przeciągnij i upuść swój PDF tutaj."
#: packages/ui/primitives/document-flow/add-fields.tsx:1065
#: packages/ui/primitives/template-flow/add-template-fields.tsx:827
#: packages/ui/primitives/document-flow/add-fields.tsx:1058
#: packages/ui/primitives/template-flow/add-template-fields.tsx:820
msgid "Dropdown"
msgstr "Lista rozwijana"
@@ -802,14 +798,14 @@ msgid "Dropdown options"
msgstr "Opcje rozwijane"
#: packages/lib/constants/document.ts:28
#: packages/ui/primitives/document-flow/add-fields.tsx:882
#: packages/ui/primitives/document-flow/add-fields.tsx:875
#: packages/ui/primitives/document-flow/add-signature.tsx:272
#: packages/ui/primitives/document-flow/add-signers.tsx:512
#: packages/ui/primitives/document-flow/add-signers.tsx:519
#: packages/ui/primitives/document-flow/types.ts:54
#: packages/ui/primitives/template-flow/add-template-fields.tsx:645
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:471
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:478
#: packages/ui/primitives/template-flow/add-template-fields.tsx:638
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:463
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:470
msgid "Email"
msgstr "Email"
@@ -829,7 +825,7 @@ msgstr "E-mail wysłany ponownie"
msgid "Email sent"
msgstr "E-mail wysłany"
#: packages/ui/primitives/document-flow/add-fields.tsx:1130
#: packages/ui/primitives/document-flow/add-fields.tsx:1123
msgid "Empty field"
msgstr "Puste pole"
@@ -838,11 +834,11 @@ msgid "Enable Direct Link Signing"
msgstr "Włącz podpisywanie linku bezpośredniego"
#: packages/ui/primitives/document-flow/add-signers.tsx:401
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:370
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:362
msgid "Enable signing order"
msgstr "Włącz kolejność podpisów"
#: packages/ui/primitives/document-flow/add-fields.tsx:802
#: packages/ui/primitives/document-flow/add-fields.tsx:795
msgid "Enable Typed Signatures"
msgstr "Włącz podpisy typu pisanego"
@@ -1020,14 +1016,14 @@ msgstr "Wiadomość <0>(Opcjonalnie)</0>"
msgid "Min"
msgstr "Min"
#: packages/ui/primitives/document-flow/add-fields.tsx:908
#: packages/ui/primitives/document-flow/add-fields.tsx:901
#: packages/ui/primitives/document-flow/add-signature.tsx:298
#: packages/ui/primitives/document-flow/add-signers.tsx:550
#: packages/ui/primitives/document-flow/add-signers.tsx:556
#: packages/ui/primitives/document-flow/types.ts:55
#: packages/ui/primitives/template-flow/add-template-fields.tsx:671
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:506
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:512
#: packages/ui/primitives/template-flow/add-template-fields.tsx:664
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:498
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:504
msgid "Name"
msgstr "Nazwa"
@@ -1043,8 +1039,8 @@ msgstr "Wymaga podpisania"
msgid "Needs to view"
msgstr "Wymaga obejrzenia"
#: packages/ui/primitives/document-flow/add-fields.tsx:693
#: packages/ui/primitives/template-flow/add-template-fields.tsx:511
#: packages/ui/primitives/document-flow/add-fields.tsx:686
#: packages/ui/primitives/template-flow/add-template-fields.tsx:504
msgid "No recipient matching this description was found."
msgstr "Nie znaleziono odbiorcy pasującego do tego opisu."
@@ -1052,8 +1048,8 @@ msgstr "Nie znaleziono odbiorcy pasującego do tego opisu."
msgid "No recipients"
msgstr "Brak odbiorców"
#: packages/ui/primitives/document-flow/add-fields.tsx:708
#: packages/ui/primitives/template-flow/add-template-fields.tsx:526
#: packages/ui/primitives/document-flow/add-fields.tsx:701
#: packages/ui/primitives/template-flow/add-template-fields.tsx:519
msgid "No recipients with this role"
msgstr "Brak odbiorców z tą rolą"
@@ -1081,9 +1077,9 @@ msgstr "Nie znaleziono wartości."
msgid "None"
msgstr "Brak"
#: packages/ui/primitives/document-flow/add-fields.tsx:986
#: packages/ui/primitives/document-flow/add-fields.tsx:979
#: packages/ui/primitives/document-flow/types.ts:56
#: packages/ui/primitives/template-flow/add-template-fields.tsx:749
#: packages/ui/primitives/template-flow/add-template-fields.tsx:742
msgid "Number"
msgstr "Numer"
@@ -1174,8 +1170,7 @@ msgstr "Proszę potwierdzić swój adres email"
msgid "Please try again or contact our support."
msgstr "Spróbuj ponownie lub skontaktuj się z naszym wsparciem."
#: packages/ui/primitives/document-flow/types.ts:57
#: packages/ui/primitives/template-flow/add-template-fields.tsx:775
#: packages/ui/primitives/template-flow/add-template-fields.tsx:768
msgid "Radio"
msgstr "Radio"
@@ -1255,7 +1250,7 @@ msgstr "Przypomnienie: Proszę {recipientActionVerb} ten dokument"
msgid "Reminder: Please {recipientActionVerb} your document"
msgstr "Przypomnienie: Proszę {recipientActionVerb} Twój dokument"
#: packages/ui/primitives/document-flow/add-fields.tsx:1117
#: packages/ui/primitives/document-flow/add-fields.tsx:1110
msgid "Remove"
msgstr "Usuń"
@@ -1287,7 +1282,7 @@ msgstr "Wiersze na stronę"
msgid "Save"
msgstr "Zapisz"
#: packages/ui/primitives/template-flow/add-template-fields.tsx:861
#: packages/ui/primitives/template-flow/add-template-fields.tsx:854
msgid "Save Template"
msgstr "Zapisz szablon"
@@ -1296,7 +1291,6 @@ msgid "Search languages..."
msgstr "Szukaj języków..."
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx:115
#: packages/ui/primitives/document-flow/types.ts:59
msgid "Select"
msgstr "Wybierz"
@@ -1360,7 +1354,7 @@ msgid "Share your signing experience!"
msgstr "Podziel się swoim doświadczeniem podpisywania!"
#: packages/ui/primitives/document-flow/add-signers.tsx:709
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:663
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:655
msgid "Show advanced settings"
msgstr "Pokaż ustawienia zaawansowane"
@@ -1376,11 +1370,11 @@ msgstr "Podpisz dokument"
msgid "Sign In"
msgstr "Zaloguj się"
#: packages/ui/primitives/document-flow/add-fields.tsx:830
#: packages/ui/primitives/document-flow/add-fields.tsx:823
#: packages/ui/primitives/document-flow/add-signature.tsx:323
#: packages/ui/primitives/document-flow/field-icon.tsx:52
#: packages/ui/primitives/document-flow/types.ts:49
#: packages/ui/primitives/template-flow/add-template-fields.tsx:593
#: packages/ui/primitives/template-flow/add-template-fields.tsx:586
msgid "Signature"
msgstr "Podpis"
@@ -1463,9 +1457,9 @@ msgstr "Email zespołowy usunięty dla {teamName} na Documenso"
msgid "Template title"
msgstr "Tytuł szablonu"
#: packages/ui/primitives/document-flow/add-fields.tsx:960
#: packages/ui/primitives/document-flow/add-fields.tsx:953
#: packages/ui/primitives/document-flow/types.ts:52
#: packages/ui/primitives/template-flow/add-template-fields.tsx:723
#: packages/ui/primitives/template-flow/add-template-fields.tsx:716
msgid "Text"
msgstr "Tekst"
@@ -1560,7 +1554,7 @@ msgstr "To można nadpisać, ustawiając wymagania dotyczące uwierzytelniania b
msgid "This document can not be recovered, if you would like to dispute the reason for future documents please contact support."
msgstr "Dokument ten nie może być odzyskany. Jeśli chcesz zakwestionować przyczynę przyszłych dokumentów, skontaktuj się z administracją."
#: packages/ui/primitives/document-flow/add-fields.tsx:764
#: packages/ui/primitives/document-flow/add-fields.tsx:757
msgid "This document has already been sent to this recipient. You can no longer edit this recipient."
msgstr "Ten dokument został już wysłany do tego odbiorcy. Nie można już edytować tego odbiorcy."
@@ -1591,7 +1585,7 @@ msgstr "Ten e-mail jest wysyłany do odbiorcy, prosząc go o podpisanie dokument
msgid "This email will be sent to the recipient who has just signed the document, if there are still other recipients who have not signed yet."
msgstr "Ten e-mail zostanie wysłany do odbiorcy, który właśnie podpisał dokument, jeśli są jeszcze inni odbiorcy, którzy nie podpisali."
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:581
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:573
msgid "This field cannot be modified or deleted. When you share this template's direct link or add it to your public profile, anyone who accesses it can input their name and email, and fill in the fields assigned to them."
msgstr "To pole nie może być modyfikowane ani usuwane. Po udostępnieniu bezpośredniego linku do tego szablonu lub dodaniu go do swojego publicznego profilu, każdy, kto się w nim dostanie, może wpisać swoje imię i email oraz wypełnić przypisane mu pola."
@@ -1599,7 +1593,7 @@ msgstr "To pole nie może być modyfikowane ani usuwane. Po udostępnieniu bezpo
msgid "This is how the document will reach the recipients once the document is ready for signing."
msgstr "W ten sposób dokument dotrze do odbiorców, gdy tylko dokument będzie gotowy do podpisania."
#: packages/ui/primitives/document-flow/add-fields.tsx:1097
#: packages/ui/primitives/document-flow/add-fields.tsx:1090
msgid "This recipient can no longer be modified as they have signed a field, or completed the document."
msgstr "Ten odbiorca nie może być już modyfikowany, ponieważ podpisał pole lub ukończył dokument."
@@ -1628,8 +1622,8 @@ msgstr "Strefa czasowa"
msgid "Title"
msgstr "Tytuł"
#: packages/ui/primitives/document-flow/add-fields.tsx:1080
#: packages/ui/primitives/template-flow/add-template-fields.tsx:841
#: packages/ui/primitives/document-flow/add-fields.tsx:1073
#: packages/ui/primitives/template-flow/add-template-fields.tsx:834
msgid "To proceed further, please set at least one value for the {0} field."
msgstr "Aby kontynuować, ustaw przynajmniej jedną wartość dla pola {0}."
+1 -1
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: pl\n"
"Project-Id-Version: documenso-app\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-11-20 11:56\n"
"PO-Revision-Date: 2024-11-14 12:05\n"
"Last-Translator: \n"
"Language-Team: Polish\n"
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
+73 -96
View File
@@ -8,7 +8,7 @@ msgstr ""
"Language: pl\n"
"Project-Id-Version: documenso-app\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-11-20 11:56\n"
"PO-Revision-Date: 2024-11-14 12:05\n"
"Last-Translator: \n"
"Language-Team: Polish\n"
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
@@ -50,19 +50,19 @@ msgstr "\"{placeholderEmail}\" w imieniu \"{0}\" zaprosił Cię do podpisania \"
msgid "\"{teamUrl}\" has invited you to sign \"example document\"."
msgstr "\"{teamUrl}\" zaprosił Cię do podpisania \"przykładowego dokumentu\"."
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:80
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:79
msgid "({0}) has invited you to approve this document"
msgstr "({0}) zaprosił Cię do zatwierdzenia tego dokumentu"
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:77
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:76
msgid "({0}) has invited you to sign this document"
msgstr "({0}) zaprosił Cię do podpisania tego dokumentu"
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:74
#: apps/web/src/app/(signing)/sign/[token]/signing-page-view.tsx:73
msgid "({0}) has invited you to view this document"
msgstr "({0}) zaprosił Cię do przeglądania tego dokumentu"
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:313
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:311
msgid "{0, plural, one {(1 character over)} other {(# characters over)}}"
msgstr "{0, plural, one {(1 znak przekroczony)} other {(# znaków przekroczonych)}}"
@@ -84,10 +84,6 @@ msgstr "{0, plural, one {# miejsce} other {# miejsc}}"
msgid "{0, plural, one {<0>You have <1>1</1> pending team invitation</0>} other {<2>You have <3>#</3> pending team invitations</2>}}"
msgstr "{0, plural, one {<0>Masz <1>1</1> oczekujące zaproszenie do zespołu</0>} other {<2>Masz <3>#</3> oczekujących zaproszeń do zespołu</2>}}"
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:196
msgid "{0, plural, one {1 matching field} other {# matching fields}}"
msgstr "{0, plural, one {1 pasujące pole} other {# pasujących pól}}"
#: apps/web/src/app/(dashboard)/documents/[id]/edit/document-edit-page-view.tsx:129
msgid "{0, plural, one {1 Recipient} other {# Recipients}}"
msgstr "{0, plural, one {1 Odbiorca} other {# Odbiorców}}"
@@ -100,10 +96,6 @@ msgstr "{0, plural, one {Czekam na 1 odbiorcę} other {Czekam na # odbiorców}}"
msgid "{0, plural, zero {Select values} other {# selected...}}"
msgstr "{0, plural, zero {Wybierz wartości} other {# wybranych...}}"
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:193
msgid "{0}"
msgstr "{0}"
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:249
msgid "{0} direct signing templates"
msgstr "{0} bezpośrednich szablonów podpisu"
@@ -124,7 +116,7 @@ msgstr "{0} Odbiorca (ów)"
#~ msgid "{0} the document to complete the process."
#~ msgstr "{0} the document to complete the process."
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:294
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:292
msgid "{charactersRemaining, plural, one {1 character remaining} other {{charactersRemaining} characters remaining}}"
msgstr "{charactersRemaining, plural, one {1 znak pozostały} other {{charactersRemaining} znaki pozostałe}}"
@@ -262,7 +254,7 @@ msgstr "Akceptowane zaproszenie do zespołu"
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:128
msgid "Account Authentication"
msgstr "Uwierzytelnianie konta"
msgstr "Autoryzacja konta"
#: apps/web/src/app/(dashboard)/admin/users/[id]/delete-user-dialog.tsx:51
#: apps/web/src/app/(dashboard)/settings/profile/delete-account-dialog.tsx:48
@@ -271,7 +263,7 @@ msgstr "Konto usunięte"
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:119
msgid "Account Re-Authentication"
msgstr "Ponowna Autoryzacja Konta"
msgstr "Ponowna autoryzacja konta"
#: apps/web/src/app/(unauthenticated)/articles/signature-disclosure/page.tsx:139
msgid "Acknowledgment"
@@ -304,7 +296,7 @@ msgstr "Aktywny"
#: apps/web/src/app/(dashboard)/admin/stats/page.tsx:68
msgid "Active Subscriptions"
msgstr "Aktywne Subskrypcje"
msgstr "Aktywne subskrypcje"
#: apps/web/src/components/(teams)/dialogs/add-team-email-dialog.tsx:189
msgid "Add"
@@ -317,7 +309,7 @@ msgstr "Dodaj wszystkie istotne pola dla każdego odbiorcy."
#: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:83
msgid "Add all relevant placeholders for each recipient."
msgstr "Dodaj wszystkie odpowiednie symbole zastępcze dla każdego odbiorcy."
msgstr "Dodaj wszystkie istotne znaczniki dla każdego odbiorcy."
#: apps/web/src/app/(dashboard)/settings/security/page.tsx:62
msgid "Add an authenticator to serve as a secondary authentication method for signing documents."
@@ -343,7 +335,7 @@ msgstr "Dodaj więcej"
#: apps/web/src/app/(dashboard)/settings/security/passkeys/create-passkey-dialog.tsx:146
#: apps/web/src/app/(dashboard)/settings/security/passkeys/create-passkey-dialog.tsx:154
msgid "Add passkey"
msgstr "Dodaj hasło"
msgstr "Dodaj klucz hasła"
#: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:82
msgid "Add Placeholders"
@@ -367,7 +359,7 @@ msgstr "Dodaj osoby, które podpiszą dokument."
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:220
msgid "Add the recipients to create the document with"
msgstr "Dodaj odbiorców, aby utworzyć dokument"
msgstr "Dodaj odbiorców, aby stworzyć dokument"
#: apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx:181
#~ msgid "Add the subject and message you wish to send to signers."
@@ -482,10 +474,6 @@ msgstr "Wystąpił błąd podczas dodawania sygnatariuszy."
msgid "An error occurred while adding the fields."
msgstr "Wystąpił błąd podczas dodawania pól."
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:154
msgid "An error occurred while auto-signing the document, some fields may not be signed. Please review and manually sign any remaining fields."
msgstr "Wystąpił błąd podczas automatycznego podpisywania dokumentu, niektóre pola mogą nie być podpisane. Proszę sprawdzić i ręcznie podpisać wszystkie pozostałe pola."
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:176
msgid "An error occurred while creating document from template."
msgstr "Wystąpił błąd podczas tworzenia dokumentu z szablonu."
@@ -760,7 +748,7 @@ msgstr "Baner zaktualizowany"
msgid "Basic details"
msgstr "Podstawowe szczegóły"
#: apps/web/src/app/(dashboard)/settings/billing/page.tsx:74
#: apps/web/src/app/(dashboard)/settings/billing/page.tsx:72
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:61
#: apps/web/src/components/(dashboard)/settings/layout/desktop-nav.tsx:117
#: apps/web/src/components/(dashboard)/settings/layout/mobile-nav.tsx:120
@@ -822,7 +810,6 @@ msgstr "Korzystając z funkcji podpisu elektronicznego, wyrażasz zgodę na prze
#: apps/web/src/app/(dashboard)/templates/duplicate-template-dialog.tsx:78
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:119
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:472
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:220
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:178
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-account.tsx:71
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-passkey.tsx:164
@@ -830,11 +817,11 @@ msgstr "Korzystając z funkcji podpisu elektronicznego, wyrażasz zgodę na prze
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:151
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:220
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:215
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:328
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:327
#: apps/web/src/app/(signing)/sign/[token]/reject-document-dialog.tsx:153
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:113
#: apps/web/src/app/(signing)/sign/[token]/signature-field.tsx:248
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:335
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:333
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-transfer-status.tsx:121
#: apps/web/src/components/(dashboard)/settings/token/delete-token-dialog.tsx:176
#: apps/web/src/components/(dashboard)/settings/webhooks/create-webhook-dialog.tsx:242
@@ -1793,7 +1780,7 @@ msgstr "Wprowadź swój adres e-mail, aby otrzymać ukończony dokument."
msgid "Enter your name"
msgstr "Wprowadź swoje imię"
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:280
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:278
msgid "Enter your text here"
msgstr "Wprowadź swój tekst tutaj"
@@ -1812,7 +1799,6 @@ msgstr "Wprowadź swój tekst tutaj"
#: apps/web/src/app/(dashboard)/templates/duplicate-template-dialog.tsx:51
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:56
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:175
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:152
#: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:122
#: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:151
#: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:212
@@ -2244,10 +2230,6 @@ msgstr "Zarządzaj wszystkimi zespołami, z którymi jesteś obecnie związany."
msgid "Manage and view template"
msgstr "Zarządzaj i przeglądaj szablon"
#: apps/web/src/app/(dashboard)/settings/billing/page.tsx:136
msgid "Manage billing"
msgstr "Zarządzaj fakturowaniem"
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:341
msgid "Manage details for this public template"
msgstr "Zarządzaj szczegółami tego publicznego szablonu"
@@ -2268,7 +2250,7 @@ msgstr "Zarządzaj kluczami dostępu"
msgid "Manage subscription"
msgstr "Zarządzaj subskrypcją"
#: apps/web/src/app/(dashboard)/settings/billing/billing-portal-button.tsx:67
#: apps/web/src/app/(dashboard)/settings/billing/billing-portal-button.tsx:66
msgid "Manage Subscription"
msgstr "Zarządzaj Subskrypcją"
@@ -2481,7 +2463,7 @@ msgstr "Nieobsługiwane"
msgid "Nothing to do"
msgstr "Nic do zrobienia"
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:271
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:270
msgid "Number"
msgstr "Numer"
@@ -2588,7 +2570,7 @@ msgstr "Nazwa klucza dostępu"
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:121
msgid "Passkey Re-Authentication"
msgstr "Ponowna Autoryzacja Klucza Dostępu"
msgstr "Ponowna autoryzacja za pomocą klucza"
#: apps/web/src/app/(dashboard)/settings/security/page.tsx:106
#: apps/web/src/app/(dashboard)/settings/security/passkeys/page.tsx:32
@@ -2645,7 +2627,7 @@ msgstr "Oczekujące Dokumenty"
#: apps/web/src/app/(dashboard)/admin/stats/page.tsx:89
msgid "Pending Documents"
msgstr "Oczekujące dokumenty"
msgstr "Oczekujące zaproszenia"
#: apps/web/src/app/(dashboard)/settings/teams/team-invitations.tsx:62
msgid "Pending invitations"
@@ -2657,71 +2639,71 @@ msgstr "Oczekujący zespół usunięty."
#: apps/web/src/components/(dashboard)/layout/menu-switcher.tsx:134
msgid "Personal"
msgstr "Osobiste"
msgstr "Konto osobiste"
#: apps/web/src/components/(dashboard)/layout/menu-switcher.tsx:77
msgid "Personal Account"
msgstr "Konto osobiste"
msgstr "Wybierz hasło"
#: apps/web/src/app/(signing)/sign/[token]/complete/claim-account.tsx:152
msgid "Pick a password"
msgstr "Wybierz hasło"
msgstr "Wybierz jedną z poniższych umów i zacznij podpisywać, aby się zarejestrować"
#: apps/web/src/components/ui/user-profile-timur.tsx:53
msgid "Pick any of the following agreements below and start signing to get started"
msgstr "Wybierz dowolną z poniższych umów i zacznij podpisywanie, aby rozpocząć"
msgstr "Pick any of the following agreements below and start signing to get started"
#: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:212
msgid "Please check the CSV file and make sure it is according to our format"
msgstr "Proszę sprawdzić plik CSV i upewnić się, że jest zgodny z naszym formatem"
msgstr "Proszę wybrać nowe hasło"
#: apps/web/src/app/(signing)/sign/[token]/waiting/page.tsx:81
msgid "Please check your email for updates."
msgstr "Proszę sprawdzić swój email w celu aktualizacji."
msgstr "Proszę sprawdź swój e-mail w celu uzyskania aktualizacji."
#: apps/web/src/app/(unauthenticated)/reset-password/[token]/page.tsx:34
msgid "Please choose your new password"
msgstr "Proszę wybrać nowe hasło"
msgstr "Please choose your new password"
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:174
msgid "Please contact support if you would like to revert this action."
msgstr "Proszę skontaktować się z pomocą techniczną, jeśli chcesz cofnąć tę akcję."
msgstr "Proszę podać znaczącą nazwę dla swojego tokena. To pomoże Ci zidentyfikować go później."
#: apps/web/src/components/forms/token.tsx:175
msgid "Please enter a meaningful name for your token. This will help you identify it later."
msgstr "Proszę podać wartościową nazwę dla swojego tokena. Pomoże to później w jego identyfikacji."
msgstr "Please enter a meaningful name for your token. This will help you identify it later."
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:135
msgid "Please mark as viewed to complete"
msgstr "Proszę zaznaczyć jako obejrzane, aby zakończyć"
msgstr "Please mark as viewed to complete"
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:459
msgid "Please note that proceeding will remove direct linking recipient and turn it into a placeholder."
msgstr "Proszę zauważyć, że kontynuowanie usunie bezpośrednio łączącego odbiorcę i zamieni go w symbol zastępczy."
msgstr "Please note that proceeding will remove direct linking recipient and turn it into a placeholder."
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:128
msgid "Please note that this action is <0>irreversible</0>."
msgstr "Proszę zauważyć, że ta czynność jest <0>nieodwracalna</0>."
msgstr "Proszę pamiętać, że ta akcja jest <0>nieodwracalna</0>. Po zatwierdzeniu ten dokument zostanie trwale usunięty."
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:119
msgid "Please note that this action is <0>irreversible</0>. Once confirmed, this document will be permanently deleted."
msgstr "Proszę pamiętać, że ta czynność jest <0>nieodwracalna</0>. Po potwierdzeniu, ten dokument zostanie trwale usunięty."
msgstr "Please note that this action is <0>irreversible</0>. Once confirmed, this document will be permanently deleted."
#: apps/web/src/app/(dashboard)/templates/delete-template-dialog.tsx:67
msgid "Please note that this action is irreversible. Once confirmed, your template will be permanently deleted."
msgstr "Proszę pamiętać, że ta czynność jest nieodwracalna. Po potwierdzeniu, Twój szablon zostanie trwale usunięty."
msgstr "Proszę pamiętać, że ta akcja jest nieodwracalna. Po zatwierdzeniu Twój token zostanie trwale usunięty."
#: apps/web/src/components/(dashboard)/settings/token/delete-token-dialog.tsx:133
msgid "Please note that this action is irreversible. Once confirmed, your token will be permanently deleted."
msgstr "Proszę zauważyć, że ta czynność jest nieodwracalna. Po potwierdzeniu, twój token zostanie trwale usunięty."
msgstr "Proszę pamiętać, że ta akcja jest nieodwracalna. Po zatwierdzeniu Twój webhook zostanie trwale usunięty."
#: apps/web/src/components/(dashboard)/settings/webhooks/delete-webhook-dialog.tsx:121
msgid "Please note that this action is irreversible. Once confirmed, your webhook will be permanently deleted."
msgstr "Proszę pamiętać, że ta czynność jest nieodwracalna. Po potwierdzeniu, Twój webhook zostanie trwale usunięty."
msgstr "Please note that this action is irreversible. Once confirmed, your webhook will be permanently deleted."
#: apps/web/src/components/(teams)/dialogs/delete-team-dialog.tsx:130
msgid "Please note that you will lose access to all documents associated with this team & all the members will be removed and notified"
msgstr "Proszę pamiętać, że stracisz dostęp do wszystkich dokumentów powiązanych z tym zespołem i wszyscy członkowie zostaną usunięci oraz powiadomieni"
msgstr "Please note that you will lose access to all documents associated with this team & all the members will be removed and notified"
#: apps/web/src/app/(signing)/sign/[token]/reject-document-dialog.tsx:37
msgid "Please provide a reason"
@@ -2729,11 +2711,11 @@ msgstr "Proszę podać powód"
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:127
msgid "Please provide a token from the authenticator, or a backup code. If you do not have a backup code available, please contact support."
msgstr "Proszę podać token z aplikacji uwierzytelniającej lub kod zapasowy. Jeśli nie masz dostępnego kodu zapasowego, skontaktuj się z pomocą techniczną."
msgstr "Proszę podać token z swojego autoryzatora lub kod zapasowy."
#: apps/web/src/components/forms/2fa/view-recovery-codes-dialog.tsx:120
msgid "Please provide a token from your authenticator, or a backup code."
msgstr "Proszę podać token z Twojego uwierzytelniacza lub kod zapasowy."
msgstr "Proszę spróbować ponownie i upewnić się, że wprowadzasz poprawny adres e-mail."
#: apps/web/src/app/(signing)/sign/[token]/form.tsx:169
msgid "Please review the document before signing."
@@ -2741,25 +2723,25 @@ msgstr "Proszę przejrzeć dokument przed podpisaniem."
#: apps/web/src/components/forms/send-confirmation-email.tsx:64
msgid "Please try again and make sure you enter the correct email address."
msgstr "Spróbuj ponownie i upewnij się, że wprowadzasz poprawny adres email."
msgstr "Please try again and make sure you enter the correct email address."
#: apps/web/src/components/forms/signin.tsx:203
msgid "Please try again later or login using your normal details"
msgstr "Spróbuj ponownie później lub zaloguj się, używając swoich normalnych danych"
msgstr "Please try again later or login using your normal details"
#: apps/web/src/app/(dashboard)/templates/new-template-dialog.tsx:80
msgid "Please try again later."
msgstr "Proszę spróbować ponownie później."
msgstr "Please try again later."
#: apps/web/src/app/(dashboard)/settings/profile/delete-account-dialog.tsx:134
msgid "Please type <0>{0}</0> to confirm."
msgstr "Proszę wpisać <0>{0}</0> aby potwierdzić."
msgstr "Please type <0>{0}</0> to confirm."
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:214
#: apps/web/src/components/(teams)/settings/layout/desktop-nav.tsx:58
#: apps/web/src/components/(teams)/settings/layout/mobile-nav.tsx:67
msgid "Preferences"
msgstr "Preferencje"
msgstr "Preferences"
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:204
msgid "Preview"
@@ -2767,7 +2749,7 @@ msgstr "Podgląd"
#: apps/web/src/app/(recipient)/d/[token]/direct-template.tsx:63
msgid "Preview and configure template."
msgstr "Podgląd i konfiguracja szablonu."
msgstr "Preview and configure template."
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:130
#~ msgid "Preview: {0}"
@@ -2776,36 +2758,36 @@ msgstr "Podgląd i konfiguracja szablonu."
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:105
#: apps/web/src/components/formatter/template-type.tsx:22
msgid "Private"
msgstr "Prywatne"
msgstr "Private"
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:115
msgid "Private templates can only be modified and viewed by you."
msgstr "Prywatne szablony mogą być modyfikowane i przeglądane tylko przez Ciebie."
msgstr "Private templates can only be modified and viewed by you."
#: apps/web/src/app/(dashboard)/settings/profile/page.tsx:28
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:69
#: apps/web/src/components/(dashboard)/settings/layout/desktop-nav.tsx:36
#: apps/web/src/components/(dashboard)/settings/layout/mobile-nav.tsx:39
msgid "Profile"
msgstr "Profil"
msgstr "Profile"
#: apps/web/src/app/(dashboard)/settings/public-profile/public-profile-page-view.tsx:184
msgid "Profile is currently <0>hidden</0>."
msgstr "Profil jest obecnie <0>ukryty</0>."
msgstr "Profil jest obecnie <0>widoczny</0>."
#: apps/web/src/app/(dashboard)/settings/public-profile/public-profile-page-view.tsx:172
msgid "Profile is currently <0>visible</0>."
msgstr "Profil jest obecnie <0>widoczny</0>."
msgstr "Profile is currently <0>visible</0>."
#: apps/web/src/app/(dashboard)/admin/users/[id]/page.tsx:72
#: apps/web/src/components/forms/profile.tsx:72
msgid "Profile updated"
msgstr "Profil zaktualizowano"
msgstr "Publiczny"
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:78
#: apps/web/src/components/formatter/template-type.tsx:27
msgid "Public"
msgstr "Publiczny"
msgstr "Publiczny profil"
#: apps/web/src/app/(dashboard)/settings/public-profile/public-profile-page-view.tsx:42
#: apps/web/src/components/(dashboard)/settings/layout/desktop-nav.tsx:50
@@ -2813,23 +2795,23 @@ msgstr "Publiczny"
#: apps/web/src/components/(teams)/settings/layout/desktop-nav.tsx:72
#: apps/web/src/components/(teams)/settings/layout/mobile-nav.tsx:81
msgid "Public Profile"
msgstr "Profil publiczny"
msgstr "Public Profile"
#: apps/web/src/components/forms/public-profile-form.tsx:146
msgid "Public profile URL"
msgstr "URL publicznego profilu"
msgstr "Nazwa użytkownika publicznego profilu"
#: apps/web/src/components/forms/v2/signup.tsx:450
msgid "Public profile username"
msgstr "Nazwa użytkownika profilu publicznego"
msgstr "Public profile username"
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:82
msgid "Public templates are connected to your public profile. Any modifications to public templates will also appear in your public profile."
msgstr "Szablony publiczne są powiązane z Twoim publicznym profilem. Wszelkie modyfikacje szablonów publicznych również pojawią się w Twoim publicznym profilu."
msgstr "Public templates are connected to your public profile. Any modifications to public templates will also appear in your public profile."
#: apps/web/src/app/(signing)/sign/[token]/signing-field-container.tsx:144
msgid "Read only field"
msgstr "Pole tylko do odczytu"
msgstr "Gotowe"
#: apps/web/src/components/general/signing-disclosure.tsx:21
msgid "Read the full <0>signature disclosure</0>."
@@ -2837,7 +2819,7 @@ msgstr "Przeczytaj pełne <0>ujawnienie podpisu</0>."
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recipients.tsx:106
msgid "Ready"
msgstr "Gotowy"
msgstr "Wymagana ponowna autoryzacja, aby podpisać to pole"
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:281
msgid "Reason"
@@ -2853,12 +2835,12 @@ msgstr "Powód musi mieć mniej niż 500 znaków"
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-dialog.tsx:62
msgid "Reauthentication is required to sign this field"
msgstr "Wymagana jest ponowna autoryzacja, aby podpisać to pole"
msgstr "Ostatnia aktywność"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:57
#: apps/web/src/app/(dashboard)/settings/security/page.tsx:130
msgid "Recent activity"
msgstr "Ostatnia aktywność"
msgstr "Odbiorca"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:47
msgid "Recent documents"
@@ -2916,7 +2898,7 @@ msgstr "Odrzucony"
#: apps/web/src/app/(unauthenticated)/forgot-password/page.tsx:34
msgid "Remembered your password? <0>Sign In</0>"
msgstr "Zapamiętałeś hasło? <0>Zaloguj się</0>"
msgstr "Pamiętasz swoje hasło? <0>Zaloguj się</0>"
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:193
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:431
@@ -2947,11 +2929,11 @@ msgstr "Powtórz hasło"
#: apps/web/src/components/(teams)/dialogs/transfer-team-dialog.tsx:282
msgid "Request transfer"
msgstr "Zleć przeniesienie"
msgstr "Poproś o transfer"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/admin-actions.tsx:61
msgid "Reseal document"
msgstr "Zapieczętuj ponownie dokument"
msgstr "Zamknij dokument"
#: 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
@@ -3010,7 +2992,7 @@ msgstr "Zwróć"
#: apps/web/src/app/(unauthenticated)/team/decline/[token]/page.tsx:130
msgid "Return to Dashboard"
msgstr "Powrót do pulpitu"
msgstr "Powrót do pulpitu nawigacyjnego"
#: apps/web/src/app/(unauthenticated)/team/decline/[token]/page.tsx:136
msgid "Return to Home"
@@ -3044,8 +3026,8 @@ msgid "Roles"
msgstr "Role"
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:446
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:337
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:344
#: apps/web/src/app/(signing)/sign/[token]/number-field.tsx:336
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:342
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/branding-preferences.tsx:312
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/preferences/document-preferences.tsx:232
msgid "Save"
@@ -3193,7 +3175,6 @@ msgstr "Pokaż szablony w profilu publicznym zespołu dla swojej publiczności,
#: apps/web/src/app/(dashboard)/documents/data-table-action-button.tsx:114
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:139
#: apps/web/src/app/(profile)/p/[url]/page.tsx:192
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:229
#: apps/web/src/app/(signing)/sign/[token]/document-action-auth-2fa.tsx:182
#: apps/web/src/app/(signing)/sign/[token]/name-field.tsx:224
#: apps/web/src/app/(signing)/sign/[token]/sign-dialog.tsx:124
@@ -3350,7 +3331,7 @@ msgstr "Ustawienia strony"
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:80
#: apps/web/src/app/(dashboard)/documents/duplicate-document-dialog.tsx:72
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:62
#: apps/web/src/app/(dashboard)/settings/billing/billing-portal-button.tsx:51
#: apps/web/src/app/(dashboard)/settings/billing/billing-portal-button.tsx:50
#: apps/web/src/app/(dashboard)/settings/public-profile/public-profile-page-view.tsx:124
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:73
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:93
@@ -3665,8 +3646,8 @@ msgstr "Szablony"
msgid "Templates allow you to quickly generate documents with pre-filled recipients and fields."
msgstr "Szablony pozwalają na szybkie generowanie dokumentów z wypełnionymi odbiorcami i polami."
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:257
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:274
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:256
#: apps/web/src/app/(signing)/sign/[token]/text-field.tsx:272
msgid "Text"
msgstr "Tekst"
@@ -4470,7 +4451,7 @@ msgstr "Chcesz wysłać eleganckie linki do podpisywania, takie jak ten? <0>Spra
msgid "Want your own public profile?"
msgstr "Chcesz swój własny profil publiczny?"
#: apps/web/src/app/(dashboard)/settings/billing/billing-portal-button.tsx:41
#: apps/web/src/app/(dashboard)/settings/billing/billing-portal-button.tsx:40
#: apps/web/src/app/(teams)/t/[teamUrl]/layout-billing-banner.tsx:55
#: apps/web/src/components/(teams)/team-billing-portal-button.tsx:31
msgid "We are unable to proceed to the billing portal at this time. Please try again, or contact support."
@@ -4734,10 +4715,6 @@ msgstr "Czy próbowałeś raczej edytować ten dokument?"
msgid "When you click continue, you will be prompted to add the first available authenticator on your system."
msgstr "Kiedy klikniesz kontynuuj, zostaniesz poproszony o dodanie pierwszego dostępnego autoryzatora w swoim systemie."
#: apps/web/src/app/(signing)/sign/[token]/auto-sign.tsx:183
msgid "When you sign a document, we can automatically fill in and sign the following fields using information that has already been provided. You can also manually sign or remove any automatically signed fields afterwards if you desire."
msgstr "Podczas podpisywania dokumentu możemy automatycznie wypełnić i podpisać następujące pola, używając informacji, które zostały już podane. Możesz również ręcznie podpisać lub usunąć każde automatycznie podpisane pole później, jeśli chcesz."
#: apps/web/src/app/(unauthenticated)/articles/signature-disclosure/page.tsx:36
msgid "When you use our platform to affix your electronic signature to documents, you are consenting to do so under the Electronic Signatures in Global and National Commerce Act (E-Sign Act) and other applicable laws. This action indicates your agreement to use electronic means to sign documents and receive notifications."
msgstr "Kiedy korzystasz z naszej platformy, aby przyczepić swój podpis elektroniczny do dokumentów, wyrażasz zgodę na dokonanie tego zgodnie z Ustawą o podpisach elektronicznych w handlu globalnym i krajowym (Ustawa E-Sign) oraz innymi obowiązującymi przepisami. Ta czynność wskazuje na twoją zgodę na korzystanie z elektronicznych środków do podpisywania dokumentów i otrzymywania powiadomień."
@@ -4807,7 +4784,7 @@ msgstr "Zaraz usuniesz następującego użytkownika z <0>{teamName}</0>."
msgid "You are about to revoke access for team <0>{0}</0> ({1}) to use your email."
msgstr "Zaraz cofniesz dostęp dla zespołu <0>{0}</0> ({1}) do korzystania z twojego e-maila."
#: apps/web/src/app/(dashboard)/settings/billing/page.tsx:80
#: apps/web/src/app/(dashboard)/settings/billing/page.tsx:78
msgid "You are currently on the <0>Free Plan</0>."
msgstr "Obecnie jesteś na <0>Planie darmowym</0>."
@@ -4859,7 +4836,7 @@ msgstr "Nie możesz modyfikować członka zespołu, który ma wyższą rolę ni
msgid "You cannot upload encrypted PDFs"
msgstr "Nie możesz przesyłać zaszyfrowanych plików PDF"
#: apps/web/src/app/(dashboard)/settings/billing/billing-portal-button.tsx:46
#: apps/web/src/app/(dashboard)/settings/billing/billing-portal-button.tsx:45
msgid "You do not currently have a customer record, this should not happen. Please contact support for assistance."
msgstr "Obecnie nie masz rekordu klienta, nie powinno tak się dziać. Proszę skontaktuj się z pomocą techniczną."
@@ -5005,7 +4982,7 @@ msgstr "Adres URL witryny Twojej marki"
msgid "Your branding preferences have been updated"
msgstr "Preferencje dotyczące marki zostały zaktualizowane"
#: apps/web/src/app/(dashboard)/settings/billing/page.tsx:125
#: apps/web/src/app/(dashboard)/settings/billing/page.tsx:119
msgid "Your current plan is past due. Please update your payment information."
msgstr "Twój obecny plan jest przeterminowany. Zaktualizuj swoje informacje płatnicze."
-12
View File
@@ -26,7 +26,6 @@ export const ZDocumentAuditLogTypeSchema = z.enum([
'DOCUMENT_COMPLETED', // When the document is sealed and fully completed.
'DOCUMENT_CREATED', // When the document is created.
'DOCUMENT_DELETED', // When the document is soft deleted.
'DOCUMENT_RESTORED', // When the document is restored.
'DOCUMENT_FIELD_INSERTED', // When a field is inserted (signed/approved/etc) by a recipient.
'DOCUMENT_FIELD_UNINSERTED', // When a field is uninserted by a recipient.
'DOCUMENT_VISIBILITY_UPDATED', // When the document visibility scope is updated
@@ -226,16 +225,6 @@ export const ZDocumentAuditLogEventDocumentDeletedSchema = z.object({
}),
});
/**
* Event: Document restored.
*/
export const ZDocumentAuditLogEventDocumentRestoredSchema = z.object({
type: z.literal(DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RESTORED),
data: z.object({
type: z.enum(['RESTORE']),
}),
});
/**
* Event: Document field inserted.
*/
@@ -501,7 +490,6 @@ export const ZDocumentAuditLogSchema = ZDocumentAuditLogBaseSchema.and(
ZDocumentAuditLogEventDocumentCreatedSchema,
ZDocumentAuditLogEventDocumentDeletedSchema,
ZDocumentAuditLogEventDocumentMovedToTeamSchema,
ZDocumentAuditLogEventDocumentRestoredSchema,
ZDocumentAuditLogEventDocumentFieldInsertedSchema,
ZDocumentAuditLogEventDocumentFieldUninsertedSchema,
ZDocumentAuditLogEventDocumentVisibilitySchema,
@@ -290,10 +290,6 @@ export const formatDocumentAuditLogAction = (
anonymous: msg`Document deleted`,
identified: msg`${prefix} deleted the document`,
}))
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RESTORED }, () => ({
anonymous: msg`Document restored`,
identified: msg`${prefix} restored the document`,
}))
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_INSERTED }, () => ({
anonymous: msg`Field signed`,
identified: msg`${prefix} signed a field`,
+1 -2
View File
@@ -24,8 +24,7 @@ module.exports = {
plugins: [
'@trivago/prettier-plugin-sort-imports',
// !: Disabled until Prettier 3.x is supported.
// 'prettier-plugin-sql',
'prettier-plugin-sql',
'prettier-plugin-tailwindcss',
],

Some files were not shown because too many files have changed in this diff Show More