Compare commits

...

34 Commits

Author SHA1 Message Date
David Nguyen
22665543c0 fix: refactor api routes 2024-12-30 21:01:03 +11:00
Catalin Pit
df33fbf91b feat: admin ui for disabling users (#1547) 2024-12-30 14:45:33 +11:00
Ephraim Duncan
ee6efc4cca fix: avoid having a drawn and typed signature at the same time (#1516) 2024-12-27 20:29:12 +11:00
Catalin Pit
6da15ab12b feat: open the advanced settings automatically (#1508) 2024-12-27 19:57:24 +11:00
Tom
7ef2a8769b chore: update French translations (#1555) 2024-12-27 19:39:57 +11:00
Catalin Pit
487f52e194 feat: enable optional fields (#1470) 2024-12-27 19:30:44 +11:00
Dunsin
39b1c5bbec feat: additional valid password (#1456) 2024-12-27 16:02:45 +11:00
Catalin Pit
32857bbfeb fix: make small fields draggable (#1551) 2024-12-27 15:22:56 +11:00
David Nguyen
41218e2585 chore: extract translations 2024-12-26 22:08:52 +11:00
Ephraim Duncan
a1a2d0801b feat: notify owner when a recipient signs (#1549) 2024-12-26 22:04:13 +11:00
SYNO®
c588c09b26 fix: remove unwanted semicolon (#1545) 2024-12-26 17:28:22 +11:00
David Nguyen
74382e21e7 feat: add get recipient route (#1553) 2024-12-26 17:25:14 +11:00
David Nguyen
8a7ec7e982 fix: billing page formatting (#1554) 2024-12-26 17:20:08 +11:00
David Nguyen
2948a33bf9 fix: tests (#1556) 2024-12-26 17:00:55 +11:00
Mythie
98b2da5018 v1.9.0-rc.5 2024-12-26 13:41:04 +11:00
Catalin Pit
fc1f76b543 fix: checkbox logic (#1537)
## Description

<!--- Describe the changes introduced by this pull request. -->
<!--- Explain what problem it solves or what feature/fix it adds. -->

## Related Issue

<!--- If this pull request is related to a specific issue, reference it
here using #issue_number. -->
<!--- For example, "Fixes #123" or "Addresses #456". -->

## Changes Made

<!--- Provide a summary of the changes made in this pull request. -->
<!--- Include any relevant technical details or architecture changes.
-->

- Change 1
- Change 2
- ...

## Testing Performed

<!--- Describe the testing that you have performed to validate these
changes. -->
<!--- Include information about test cases, testing environments, and
results. -->

- Tested feature X in scenario Y.
- Ran unit tests for component Z.
- Tested on browsers A, B, and C.
- ...

## Checklist

<!--- Please check the boxes that apply to this pull request. -->
<!--- You can add or remove items as needed. -->

- [ ] I have tested these changes locally and they work as expected.
- [ ] I have added/updated tests that prove the effectiveness of these
changes.
- [ ] I have updated the documentation to reflect these changes, if
applicable.
- [ ] I have followed the project's coding style guidelines.
- [ ] I have addressed the code review feedback from the previous
submission, if applicable.

## Additional Notes

<!--- Provide any additional context or notes for the reviewers. -->
<!--- This might include details about design decisions, potential
concerns, or anything else relevant. -->
2024-12-23 12:06:47 +02:00
Mythie
22c9fb777b fix: perf improvements 2024-12-18 15:01:57 +11:00
Mythie
2da051a7f9 v1.9.0-rc.4 2024-12-18 08:14:50 +11:00
Mythie
390a317bd3 fix: normalize pdf on the server 2024-12-18 08:14:14 +11:00
Catalin Pit
c161553d1d feat: add disabled property for user (#1546) 2024-12-17 22:35:59 +11:00
Ephraim Duncan
c960a48b4f fix: z-index of field settings (#1469) 2024-12-17 17:09:58 +11:00
Catalin Pit
9502f4361d fix: fieldtooltip blocking the field click (#1538)
## Before (error)


https://github.com/user-attachments/assets/525e6c04-fc03-41a7-8299-2a753e9e9fa6

## After (fixed)


https://github.com/user-attachments/assets/67f7e592-c5ca-47f4-962c-e4a848522d43
2024-12-17 17:04:20 +11:00
Catalin Pit
82deab41f4 fix: move permission check outside the document visibility component (#1543)
PR created because of this comment
https://github.com/documenso/documenso/pull/1521#discussion_r1881895305.
2024-12-17 17:03:08 +11:00
Catalin Pit
2245812f0b fix: document visibility logic (#1521)
Update the logic of document visibility logic and added some tests &
updated some existing ones.
2024-12-16 09:10:40 +02:00
Mythie
861e9c976b v1.9.0-rc.3 2024-12-16 09:35:33 +11:00
David Nguyen
f55808199b feat: make enterprise billing dynamic (#1539) 2024-12-14 13:44:25 +09:00
David Nguyen
b4a7f1887d feat: add trpc openapi (#1535) 2024-12-14 01:23:35 +09:00
Luca Hagel
f73441ee85 chore: prevent user selection within signature pad (#1530)
adds a `select-none` class to the signature pad in order to
prevent iPadOS from becoming too trigger happy with the context menu and
auto corrects. Please ensure this doesn't break anything by accident.
2024-12-13 16:02:26 +11:00
Doug Andrade
d7de3b08c1 fix: darkmode on radio button and checkbox labels (#1518)
Fixed Radio Button and Checkbox Appearance in Dark Mode
2024-12-13 15:55:40 +11:00
Ephraim Duncan
7d201f05d9 fix: admin leaderboard query (#1522)
Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
2024-12-13 15:50:52 +11:00
Mythie
a21ee2cea6 v1.9.0-rc.2 2024-12-13 15:16:26 +11:00
Ephraim Duncan
4ad46b81c9 fix: prevent hidden layers from being toggled in pdf viewers (#1528)
https://github.com/user-attachments/assets/e10194ca-212b-40ee-b9a1-85ef54829a40

---------

Co-authored-by: Mythie <me@lucasjamessmith.me>
2024-12-13 14:19:55 +11:00
Ephraim Duncan
10b8e785e0 fix: clear invalid drawn signature when switching to typed signature (#1536) 2024-12-13 10:40:22 +11:00
Lucas Smith
5fbed783fc feat: add controls for sending completion emails to document owners (#1534)
Adds a new `ownerDocumentCompleted` to the email settings that controls
whether a document will be sent to the owner upon completion.

This was previously the only email you couldn't disable and didn't
account for users integrating with just the API and Webhooks.

Also adds a flag to the public `sendDocument` endpoint which will adjust
this setting while sendint the document for users who aren't using
`emailSettings` on the `createDocument` endpoint.
2024-12-12 14:24:07 +11:00
218 changed files with 6926 additions and 4367 deletions

View File

@@ -8,7 +8,7 @@ jobs:
e2e_tests: e2e_tests:
name: 'E2E Tests' name: 'E2E Tests'
timeout-minutes: 60 timeout-minutes: 60
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View File

@@ -4,7 +4,7 @@ import '../styles.css';
export default function App({ Component, pageProps }) { export default function App({ Component, pageProps }) {
return ( return (
<PlausibleProvider> <PlausibleProvider>
<Component {...pageProps} />; <Component {...pageProps} />
</PlausibleProvider> </PlausibleProvider>
); );
} }

View File

@@ -17,23 +17,25 @@ The default document visibility option allows you to control who can view and ac
The default document visibility is set to "_EVERYONE_" by default. You can change this setting by going to the [team's general preferences page](/users/teams/preferences) and selecting a different visibility option. The default document visibility is set to "_EVERYONE_" by default. You can change this setting by going to the [team's general preferences page](/users/teams/preferences) and selecting a different visibility option.
<Callout type="warning">
If the team member uploading the document has a role lower than the default document visibility,
the document visibility will be set to a lower visibility level matching the team member's role.
</Callout>
Here's how it works: Here's how it works:
- If a user with the "_Member_" role creates a document and the default document visibility is set to "_Admin_" or "_Managers and above_", the document's visibility is set to "_Everyone_". - If a user with the "_Member_" role creates a document and the default document visibility is set to "_Everyone_", the document's visibility is set to "_EVERYONE_".
- If a user with the "_Manager_" role creates a document and the default document visibility is set to "_Admin_", the document's visibility is set to "_Managers and above_". - The user can't change the visibility of the document in the document editor.
- Otherwise, the document's visibility is set to the default document visibility. - If a user with the "_Member_" role creates a document and the default document visibility is set to "_Admin_" or "_Managers and above_", the document's visibility is set to the default document visibility ("_Admin_" or "_Managers and above_" in this case).
- The user can't change the visibility of the document in the document editor.
- If a user with the "_Manager_" role creates a document and the default document visibility is set to "_Everyone_" or "_Managers and above_", the document's visibility is set to the default document visibility ("_Everyone_" or "_Managers and above_" in this case).
- The user can change the visibility of the document to any of these options, except "_Admin_", in the document editor.
- If a user with the "_Manager_" role creates a document and the default document visibility is set to "_Admin_", the document's visibility is set to "_Admin_".
- The user can't change the visibility of the document in the document editor.
- If a user with the "_Admin_" role creates a document, and the default document visibility is set to "_Everyone_", "_Managers and above_", or "_Admin_", the document's visibility is set to the default document visibility.
- The user can change the visibility of the document to any of these options in the document editor.
You can change the visibility of a document at any time by editing the document and selecting a different visibility option. You can change the visibility of a document at any time by editing the document and selecting a different visibility option.
![A screenshot of the Documenso's document editor page where you can update the document visibility](/teams/document-visibility-settings.webp) ![A screenshot of the Documenso's document editor page where you can update the document visibility](/teams/document-visibility-settings.webp)
<Callout type="warning"> <Callout type="warning">
Updating the default document visibility in the team's general settings will not affect the Updating the default document visibility in the team's general preferences will not affect the
visibility of existing documents. You will need to update the visibility of each document visibility of existing documents. You will need to update the visibility of each document
individually. individually.
</Callout> </Callout>

View File

@@ -1,6 +1,6 @@
{ {
"name": "@documenso/marketing", "name": "@documenso/marketing",
"version": "1.9.0-rc.1", "version": "1.9.0-rc.5",
"private": true, "private": true,
"license": "AGPL-3.0", "license": "AGPL-3.0",
"scripts": { "scripts": {
@@ -47,7 +47,7 @@
"recharts": "^2.7.2", "recharts": "^2.7.2",
"sharp": "0.32.6", "sharp": "0.32.6",
"typescript": "5.2.2", "typescript": "5.2.2",
"zod": "^3.23.8" "zod": "3.24.1"
}, },
"devDependencies": { "devDependencies": {
"@lingui/loader": "^4.11.3", "@lingui/loader": "^4.11.3",

View File

@@ -10,16 +10,13 @@ import { msg } from '@lingui/macro';
import { useAnalytics } from '@documenso/lib/client-only/hooks/use-analytics'; import { useAnalytics } from '@documenso/lib/client-only/hooks/use-analytics';
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app'; import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
import { base64 } from '@documenso/lib/universal/base64'; import { base64 } from '@documenso/lib/universal/base64';
import { putPdfFile } from '@documenso/lib/universal/upload/put-file';
import type { Field, Recipient } from '@documenso/prisma/client'; import type { Field, Recipient } from '@documenso/prisma/client';
import { DocumentDataType, Prisma } from '@documenso/prisma/client'; import { DocumentDataType, Prisma } from '@documenso/prisma/client';
import { trpc } from '@documenso/trpc/react';
import { Card, CardContent } from '@documenso/ui/primitives/card'; import { Card, CardContent } from '@documenso/ui/primitives/card';
import { DocumentDropzone } from '@documenso/ui/primitives/document-dropzone'; import { DocumentDropzone } from '@documenso/ui/primitives/document-dropzone';
import { AddFieldsFormPartial } from '@documenso/ui/primitives/document-flow/add-fields'; import { AddFieldsFormPartial } from '@documenso/ui/primitives/document-flow/add-fields';
import type { TAddFieldsFormSchema } from '@documenso/ui/primitives/document-flow/add-fields.types'; import type { TAddFieldsFormSchema } from '@documenso/ui/primitives/document-flow/add-fields.types';
import { AddSignatureFormPartial } from '@documenso/ui/primitives/document-flow/add-signature'; import { AddSignatureFormPartial } from '@documenso/ui/primitives/document-flow/add-signature';
import type { TAddSignatureFormSchema } from '@documenso/ui/primitives/document-flow/add-signature.types';
import { DocumentFlowFormContainer } from '@documenso/ui/primitives/document-flow/document-flow-root'; import { DocumentFlowFormContainer } from '@documenso/ui/primitives/document-flow/document-flow-root';
import type { DocumentFlowStep } from '@documenso/ui/primitives/document-flow/types'; import type { DocumentFlowStep } from '@documenso/ui/primitives/document-flow/types';
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer'; import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
@@ -43,9 +40,6 @@ export const SinglePlayerClient = () => {
const [step, setStep] = useState<SinglePlayerModeStep>('fields'); const [step, setStep] = useState<SinglePlayerModeStep>('fields');
const [fields, setFields] = useState<Field[]>([]); const [fields, setFields] = useState<Field[]>([]);
const { mutateAsync: createSinglePlayerDocument } =
trpc.singleplayer.createSinglePlayerDocument.useMutation();
const documentFlow: Record<SinglePlayerModeStep, DocumentFlowStep> = { const documentFlow: Record<SinglePlayerModeStep, DocumentFlowStep> = {
fields: { fields: {
title: msg`Add document`, title: msg`Add document`,
@@ -112,38 +106,35 @@ export const SinglePlayerClient = () => {
/** /**
* Upload, create, sign and send the document. * Upload, create, sign and send the document.
*/ */
const onSignSubmit = async (data: TAddSignatureFormSchema) => { const onSignSubmit = (data: unknown) => {
if (!uploadedFile) { if (!uploadedFile) {
return; return;
} }
try { try {
const putFileData = await putPdfFile(uploadedFile.file); // const putFileData = await putPdfFile(uploadedFile.file);
// const documentToken = await createSinglePlayerDocument({
const documentToken = await createSinglePlayerDocument({ // documentData: {
documentData: { // type: putFileData.type,
type: putFileData.type, // data: putFileData.data,
data: putFileData.data, // },
}, // documentName: uploadedFile.file.name,
documentName: uploadedFile.file.name, // signer: data,
signer: data, // fields: fields.map((field) => ({
fields: fields.map((field) => ({ // page: field.page,
page: field.page, // type: field.type,
type: field.type, // positionX: field.positionX.toNumber(),
positionX: field.positionX.toNumber(), // positionY: field.positionY.toNumber(),
positionY: field.positionY.toNumber(), // width: field.width.toNumber(),
width: field.width.toNumber(), // height: field.height.toNumber(),
height: field.height.toNumber(), // fieldMeta: field.fieldMeta,
fieldMeta: field.fieldMeta, // })),
})), // fieldMeta: { type: undefined },
fieldMeta: { type: undefined }, // });
}); // analytics.capture('Marketing: SPM - Document signed', {
// signer: data.email,
analytics.capture('Marketing: SPM - Document signed', { // });
signer: data.email, // router.push(`/singleplayer/${documentToken}/success`);
});
router.push(`/singleplayer/${documentToken}/success`);
} catch { } catch {
toast({ toast({
title: 'Something went wrong', title: 'Something went wrong',

View File

@@ -2,7 +2,7 @@ import cors from '@/lib/cors';
import { getUserMonthlyGrowth } from '@/lib/growth/get-user-monthly-growth'; import { getUserMonthlyGrowth } from '@/lib/growth/get-user-monthly-growth';
export async function GET(request: Request) { export async function GET(request: Request) {
const totalUsers = await getUserMonthlyGrowth("cumulative"); const totalUsers = await getUserMonthlyGrowth('cumulative');
return cors( return cors(
request, request,

View File

@@ -1,6 +1,6 @@
{ {
"name": "@documenso/web", "name": "@documenso/web",
"version": "1.9.0-rc.1", "version": "1.9.0-rc.5",
"private": true, "private": true,
"license": "AGPL-3.0", "license": "AGPL-3.0",
"scripts": { "scripts": {
@@ -56,10 +56,11 @@
"recharts": "^2.7.2", "recharts": "^2.7.2",
"remeda": "^2.17.3", "remeda": "^2.17.3",
"sharp": "0.32.6", "sharp": "0.32.6",
"trpc-openapi": "^1.2.0",
"ts-pattern": "^5.0.5", "ts-pattern": "^5.0.5",
"ua-parser-js": "^1.0.37", "ua-parser-js": "^1.0.37",
"uqr": "^0.1.2", "uqr": "^0.1.2",
"zod": "^3.23.8" "zod": "3.24.1"
}, },
"devDependencies": { "devDependencies": {
"@documenso/tailwind-config": "*", "@documenso/tailwind-config": "*",

View File

@@ -134,7 +134,7 @@ export const LeaderboardTable = ({
startTransition(() => { startTransition(() => {
updateSearchParams({ updateSearchParams({
sortBy: column, sortBy: column,
sortOrder: sortOrder === 'asc' ? 'desc' : 'asc', sortOrder: sortBy === column && sortOrder === 'asc' ? 'desc' : 'asc',
}); });
}); });
}; };

View File

@@ -30,8 +30,8 @@ export type DeleteUserDialogProps = {
}; };
export const DeleteUserDialog = ({ className, user }: DeleteUserDialogProps) => { export const DeleteUserDialog = ({ className, user }: DeleteUserDialogProps) => {
const { toast } = useToast();
const { _ } = useLingui(); const { _ } = useLingui();
const { toast } = useToast();
const router = useRouter(); const router = useRouter();
@@ -44,7 +44,6 @@ export const DeleteUserDialog = ({ className, user }: DeleteUserDialogProps) =>
try { try {
await deleteUser({ await deleteUser({
id: user.id, id: user.id,
email,
}); });
toast({ toast({

View File

@@ -0,0 +1,141 @@
'use client';
import { useState } from 'react';
import { Trans, msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { match } from 'ts-pattern';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import type { User } from '@documenso/prisma/client';
import { trpc } from '@documenso/trpc/react';
import { Alert, AlertDescription, AlertTitle } from '@documenso/ui/primitives/alert';
import { Button } from '@documenso/ui/primitives/button';
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@documenso/ui/primitives/dialog';
import { Input } from '@documenso/ui/primitives/input';
import { useToast } from '@documenso/ui/primitives/use-toast';
export type DisableUserDialogProps = {
className?: string;
userToDisable: User;
};
export const DisableUserDialog = ({ className, userToDisable }: DisableUserDialogProps) => {
const { _ } = useLingui();
const { toast } = useToast();
const [email, setEmail] = useState('');
const { mutateAsync: disableUser, isLoading: isDisablingUser } =
trpc.admin.disableUser.useMutation();
const onDisableAccount = async () => {
try {
await disableUser({
id: userToDisable.id,
});
toast({
title: _(msg`Account disabled`),
description: _(msg`The account has been disabled successfully.`),
duration: 5000,
});
} catch (err) {
const error = AppError.parseError(err);
const errorMessage = match(error.code)
.with(AppErrorCode.NOT_FOUND, () => msg`User not found.`)
.with(AppErrorCode.UNAUTHORIZED, () => msg`You are not authorized to disable this user.`)
.otherwise(() => msg`An error occurred while disabling the user.`);
toast({
title: _(msg`Error`),
description: _(errorMessage),
variant: 'destructive',
duration: 7500,
});
}
};
return (
<div className={className}>
<Alert
className="flex flex-col items-center justify-between gap-4 p-6 md:flex-row"
variant="neutral"
>
<div>
<AlertTitle>Disable Account</AlertTitle>
<AlertDescription className="mr-2">
<Trans>
Disabling the user results in the user not being able to use the account. It also
disables all the related contents such as subscription, webhooks, teams, and API keys.
</Trans>
</AlertDescription>
</div>
<div className="flex-shrink-0">
<Dialog>
<DialogTrigger asChild>
<Button variant="destructive">
<Trans>Disable Account</Trans>
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader className="space-y-4">
<DialogTitle>
<Trans>Disable Account</Trans>
</DialogTitle>
<Alert variant="destructive">
<AlertDescription className="selection:bg-red-100">
<Trans>
This action is reversible, but please be careful as the account may be
affected permanently (e.g. their settings and contents not being restored
properly).
</Trans>
</AlertDescription>
</Alert>
</DialogHeader>
<div>
<DialogDescription>
<Trans>
To confirm, please enter the accounts email address <br />({userToDisable.email}
).
</Trans>
</DialogDescription>
<Input
className="mt-2"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<DialogFooter>
<Button
onClick={onDisableAccount}
loading={isDisablingUser}
variant="destructive"
disabled={email !== userToDisable.email}
>
<Trans>Disable account</Trans>
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
</Alert>
</div>
);
};

View File

@@ -0,0 +1,130 @@
'use client';
import { useState } from 'react';
import { Trans, msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { match } from 'ts-pattern';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import type { User } from '@documenso/prisma/client';
import { trpc } from '@documenso/trpc/react';
import { Alert, AlertDescription, AlertTitle } from '@documenso/ui/primitives/alert';
import { Button } from '@documenso/ui/primitives/button';
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@documenso/ui/primitives/dialog';
import { Input } from '@documenso/ui/primitives/input';
import { useToast } from '@documenso/ui/primitives/use-toast';
export type EnableUserDialogProps = {
className?: string;
userToEnable: User;
};
export const EnableUserDialog = ({ className, userToEnable }: EnableUserDialogProps) => {
const { toast } = useToast();
const { _ } = useLingui();
const [email, setEmail] = useState('');
const { mutateAsync: enableUser, isLoading: isEnablingUser } =
trpc.admin.enableUser.useMutation();
const onEnableAccount = async () => {
try {
await enableUser({
id: userToEnable.id,
});
toast({
title: _(msg`Account enabled`),
description: _(msg`The account has been enabled successfully.`),
duration: 5000,
});
} catch (err) {
const error = AppError.parseError(err);
const errorMessage = match(error.code)
.with(AppErrorCode.NOT_FOUND, () => msg`User not found.`)
.with(AppErrorCode.UNAUTHORIZED, () => msg`You are not authorized to enable this user.`)
.otherwise(() => msg`An error occurred while enabling the user.`);
toast({
title: _(msg`Error`),
description: _(errorMessage),
variant: 'destructive',
duration: 7500,
});
}
};
return (
<div className={className}>
<Alert
className="flex flex-col items-center justify-between gap-4 p-6 md:flex-row"
variant="neutral"
>
<div>
<AlertTitle>Enable Account</AlertTitle>
<AlertDescription className="mr-2">
<Trans>
Enabling the account results in the user being able to use the account again, and all
the related features such as webhooks, teams, and API keys for example.
</Trans>
</AlertDescription>
</div>
<div className="flex-shrink-0">
<Dialog>
<DialogTrigger asChild>
<Button>
<Trans>Enable Account</Trans>
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader className="space-y-4">
<DialogTitle>
<Trans>Enable Account</Trans>
</DialogTitle>
</DialogHeader>
<div>
<DialogDescription>
<Trans>
To confirm, please enter the accounts email address <br />({userToEnable.email}
).
</Trans>
</DialogDescription>
<Input
className="mt-2"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<DialogFooter>
<Button
onClick={onEnableAccount}
loading={isEnablingUser}
disabled={email !== userToEnable.email}
>
<Trans>Enable account</Trans>
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
</Alert>
</div>
);
};

View File

@@ -23,6 +23,8 @@ import { Input } from '@documenso/ui/primitives/input';
import { useToast } from '@documenso/ui/primitives/use-toast'; import { useToast } from '@documenso/ui/primitives/use-toast';
import { DeleteUserDialog } from './delete-user-dialog'; import { DeleteUserDialog } from './delete-user-dialog';
import { DisableUserDialog } from './disable-user-dialog';
import { EnableUserDialog } from './enable-user-dialog';
import { MultiSelectRoleCombobox } from './multiselect-role-combobox'; import { MultiSelectRoleCombobox } from './multiselect-role-combobox';
const ZUserFormSchema = ZAdminUpdateProfileMutationSchema.omit({ id: true }); const ZUserFormSchema = ZAdminUpdateProfileMutationSchema.omit({ id: true });
@@ -35,7 +37,7 @@ export default function UserPage({ params }: { params: { id: number } }) {
const router = useRouter(); const router = useRouter();
const { data: user } = trpc.profile.getUser.useQuery( const { data: user } = trpc.admin.getUser.useQuery(
{ {
id: Number(params.id), id: Number(params.id),
}, },
@@ -153,7 +155,11 @@ export default function UserPage({ params }: { params: { id: number } }) {
<hr className="my-4" /> <hr className="my-4" />
<div className="flex flex-col items-center gap-4">
{user && <DeleteUserDialog user={user} />} {user && <DeleteUserDialog user={user} />}
{user && user.disabled && <EnableUserDialog userToEnable={user} />}
{user && !user.disabled && <DisableUserDialog userToDisable={user} />}
</div>
</div> </div>
); );
} }

View File

@@ -37,10 +37,8 @@ export const DocumentPageViewRecentActivity = ({
{ {
documentId, documentId,
filterForRecentActivity: true, filterForRecentActivity: true,
orderBy: { orderByColumn: 'createdAt',
column: 'createdAt', orderByDirection: 'asc',
direction: 'asc',
},
perPage: 10, perPage: 10,
}, },
{ {

View File

@@ -12,8 +12,8 @@ import {
DO_NOT_INVALIDATE_QUERY_ON_MUTATION, DO_NOT_INVALIDATE_QUERY_ON_MUTATION,
SKIP_QUERY_BATCH_META, SKIP_QUERY_BATCH_META,
} from '@documenso/lib/constants/trpc'; } from '@documenso/lib/constants/trpc';
import type { TGetDocumentWithDetailsByIdResponse } from '@documenso/lib/server-only/document/get-document-with-details-by-id';
import { DocumentDistributionMethod, DocumentStatus } from '@documenso/prisma/client'; import { DocumentDistributionMethod, DocumentStatus } from '@documenso/prisma/client';
import type { DocumentWithDetails } from '@documenso/prisma/types/document';
import { trpc } from '@documenso/trpc/react'; import { trpc } from '@documenso/trpc/react';
import { cn } from '@documenso/ui/lib/utils'; import { cn } from '@documenso/ui/lib/utils';
import { Card, CardContent } from '@documenso/ui/primitives/card'; import { Card, CardContent } from '@documenso/ui/primitives/card';
@@ -35,7 +35,7 @@ import { useOptionalCurrentTeam } from '~/providers/team';
export type EditDocumentFormProps = { export type EditDocumentFormProps = {
className?: string; className?: string;
initialDocument: DocumentWithDetails; initialDocument: TGetDocumentWithDetailsByIdResponse;
documentRootPath: string; documentRootPath: string;
isDocumentEnterprise: boolean; isDocumentEnterprise: boolean;
}; };
@@ -103,7 +103,7 @@ export const EditDocumentForm = ({
const { mutateAsync: addFields } = trpc.field.addFields.useMutation({ const { mutateAsync: addFields } = trpc.field.addFields.useMutation({
...DO_NOT_INVALIDATE_QUERY_ON_MUTATION, ...DO_NOT_INVALIDATE_QUERY_ON_MUTATION,
onSuccess: (newFields) => { onSuccess: ({ fields: newFields }) => {
utils.document.getDocumentWithDetailsById.setData( utils.document.getDocumentWithDetailsById.setData(
{ {
documentId: initialDocument.id, documentId: initialDocument.id,
@@ -132,9 +132,9 @@ export const EditDocumentForm = ({
}, },
}); });
const { mutateAsync: addSigners } = trpc.recipient.addSigners.useMutation({ const { mutateAsync: addSigners } = trpc.recipient.setDocumentRecipients.useMutation({
...DO_NOT_INVALIDATE_QUERY_ON_MUTATION, ...DO_NOT_INVALIDATE_QUERY_ON_MUTATION,
onSuccess: (newRecipients) => { onSuccess: ({ recipients: newRecipients }) => {
utils.document.getDocumentWithDetailsById.setData( utils.document.getDocumentWithDetailsById.setData(
{ {
documentId: initialDocument.id, documentId: initialDocument.id,

View File

@@ -9,8 +9,8 @@ import { DateTime } from 'luxon';
import { useSession } from 'next-auth/react'; import { useSession } from 'next-auth/react';
import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params'; import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params';
import type { FindResultResponse } from '@documenso/lib/types/search-params'; import type { TFindDocumentsResponse } from '@documenso/lib/server-only/document/find-documents';
import type { Document, Recipient, Team, User } from '@documenso/prisma/client'; import type { Team } from '@documenso/prisma/client';
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status'; import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
import type { DataTableColumnDef } from '@documenso/ui/primitives/data-table'; import type { DataTableColumnDef } from '@documenso/ui/primitives/data-table';
import { DataTable } from '@documenso/ui/primitives/data-table'; import { DataTable } from '@documenso/ui/primitives/data-table';
@@ -24,13 +24,7 @@ import { DataTableActionDropdown } from './data-table-action-dropdown';
import { DataTableTitle } from './data-table-title'; import { DataTableTitle } from './data-table-title';
export type DocumentsDataTableProps = { export type DocumentsDataTableProps = {
results: FindResultResponse< results: TFindDocumentsResponse;
Document & {
Recipient: Recipient[];
User: Pick<User, 'id' | 'name' | 'email'>;
team: Pick<Team, 'id' | 'url'> | null;
}
>;
showSenderColumn?: boolean; showSenderColumn?: boolean;
team?: Pick<Team, 'id' | 'url'> & { teamEmail?: string }; team?: Pick<Team, 'id' | 'url'> & { teamEmail?: string };
}; };

View File

@@ -26,10 +26,8 @@ export const TemplatePageViewRecentActivity = ({
const { data, isLoading, isLoadingError, refetch } = trpc.document.findDocuments.useQuery({ const { data, isLoading, isLoadingError, refetch } = trpc.document.findDocuments.useQuery({
templateId, templateId,
teamId, teamId,
orderBy: { orderByColumn: 'createdAt',
column: 'createdAt', orderByDirection: 'asc',
direction: 'asc',
},
perPage: 5, perPage: 5,
}); });

View File

@@ -4,8 +4,10 @@ import { useRouter } from 'next/navigation';
import { Trans, msg } from '@lingui/macro'; import { Trans, msg } from '@lingui/macro';
import { useLingui } from '@lingui/react'; import { useLingui } from '@lingui/react';
import { match } from 'ts-pattern';
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app'; import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { trpc } from '@documenso/trpc/react'; import { trpc } from '@documenso/trpc/react';
import { Avatar, AvatarFallback, AvatarImage } from '@documenso/ui/primitives/avatar'; import { Avatar, AvatarFallback, AvatarImage } from '@documenso/ui/primitives/avatar';
import { Button } from '@documenso/ui/primitives/button'; import { Button } from '@documenso/ui/primitives/button';
@@ -51,10 +53,20 @@ export const MoveTemplateDialog = ({ templateId, open, onOpenChange }: MoveTempl
}); });
onOpenChange(false); onOpenChange(false);
}, },
onError: (error) => { onError: (err) => {
const error = AppError.parseError(err);
const errorMessage = match(error.code)
.with(
AppErrorCode.NOT_FOUND,
() => msg`Template not found or already associated with a team.`,
)
.with(AppErrorCode.UNAUTHORIZED, () => msg`You are not a member of this team.`)
.otherwise(() => msg`An error occurred while moving the template.`);
toast({ toast({
title: _(msg`Error`), title: _(msg`Error`),
description: error.message || _(msg`An error occurred while moving the template.`), description: _(errorMessage),
variant: 'destructive', variant: 'destructive',
duration: 7500, duration: 7500,
}); });

View File

@@ -12,6 +12,7 @@ import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION } from '@documenso/lib/constants/tr
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import type { TRecipientActionAuth } from '@documenso/lib/types/document-auth'; import type { TRecipientActionAuth } from '@documenso/lib/types/document-auth';
import { ZCheckboxFieldMeta } from '@documenso/lib/types/field-meta'; import { ZCheckboxFieldMeta } from '@documenso/lib/types/field-meta';
import { fromCheckboxValue, toCheckboxValue } from '@documenso/lib/universal/field-checkbox';
import type { Recipient } from '@documenso/prisma/client'; import type { Recipient } from '@documenso/prisma/client';
import type { FieldWithSignatureAndFieldMeta } from '@documenso/prisma/types/field-with-signature-and-fieldmeta'; import type { FieldWithSignatureAndFieldMeta } from '@documenso/prisma/types/field-with-signature-and-fieldmeta';
import { trpc } from '@documenso/trpc/react'; import { trpc } from '@documenso/trpc/react';
@@ -54,6 +55,7 @@ export const CheckboxField = ({
...item, ...item,
value: item.value.length > 0 ? item.value : `empty-value-${item.id}`, value: item.value.length > 0 ? item.value : `empty-value-${item.id}`,
})); }));
const [checkedValues, setCheckedValues] = useState( const [checkedValues, setCheckedValues] = useState(
values values
?.map((item) => ?.map((item) =>
@@ -97,7 +99,7 @@ export const CheckboxField = ({
const payload: TSignFieldWithTokenMutationSchema = { const payload: TSignFieldWithTokenMutationSchema = {
token: recipient.token, token: recipient.token,
fieldId: field.id, fieldId: field.id,
value: checkedValues.join(','), value: toCheckboxValue(checkedValues),
isBase64: true, isBase64: true,
authOptions, authOptions,
}; };
@@ -191,7 +193,7 @@ export const CheckboxField = ({
await signFieldWithToken({ await signFieldWithToken({
token: recipient.token, token: recipient.token,
fieldId: field.id, fieldId: field.id,
value: updatedValues.join(','), value: toCheckboxValue(checkedValues),
isBase64: true, isBase64: true,
}); });
} }
@@ -228,6 +230,11 @@ export const CheckboxField = ({
} }
}, [checkedValues, isLengthConditionMet, field.inserted]); }, [checkedValues, isLengthConditionMet, field.inserted]);
const parsedCheckedValues = useMemo(
() => fromCheckboxValue(field.customText),
[field.customText],
);
return ( return (
<SigningFieldContainer field={field} onSign={onSign} onRemove={onRemove} type="Checkbox"> <SigningFieldContainer field={field} onSign={onSign} onRemove={onRemove} type="Checkbox">
{isLoading && ( {isLoading && (
@@ -277,9 +284,7 @@ export const CheckboxField = ({
className="h-3 w-3" className="h-3 w-3"
checkClassName="text-white" checkClassName="text-white"
id={`checkbox-${index}`} id={`checkbox-${index}`}
checked={field.customText checked={parsedCheckedValues.includes(itemValue)}
.split(',')
.some((customValue) => customValue === itemValue)}
disabled={isLoading} disabled={isLoading}
onCheckedChange={() => void handleCheckboxOptionClick(item)} onCheckedChange={() => void handleCheckboxOptionClick(item)}
/> />

View File

@@ -11,6 +11,7 @@ import { useForm } from 'react-hook-form';
import { useAnalytics } from '@documenso/lib/client-only/hooks/use-analytics'; import { useAnalytics } from '@documenso/lib/client-only/hooks/use-analytics';
import type { DocumentAndSender } from '@documenso/lib/server-only/document/get-document-by-token'; import type { DocumentAndSender } from '@documenso/lib/server-only/document/get-document-by-token';
import type { TRecipientActionAuth } from '@documenso/lib/types/document-auth'; import type { TRecipientActionAuth } from '@documenso/lib/types/document-auth';
import { isFieldUnsignedAndRequired } from '@documenso/lib/utils/advanced-fields-helpers';
import { sortFieldsByPosition, validateFieldsInserted } from '@documenso/lib/utils/fields'; import { sortFieldsByPosition, validateFieldsInserted } from '@documenso/lib/utils/fields';
import { type Field, FieldType, type Recipient, RecipientRole } from '@documenso/prisma/client'; import { type Field, FieldType, type Recipient, RecipientRole } from '@documenso/prisma/client';
import { trpc } from '@documenso/trpc/react'; import { trpc } from '@documenso/trpc/react';
@@ -57,26 +58,31 @@ export const SigningForm = ({
// Keep the loading state going if successful since the redirect may take some time. // Keep the loading state going if successful since the redirect may take some time.
const isSubmitting = formState.isSubmitting || formState.isSubmitSuccessful; const isSubmitting = formState.isSubmitting || formState.isSubmitSuccessful;
const fieldsRequiringValidation = useMemo(
() => fields.filter(isFieldUnsignedAndRequired),
[fields],
);
const hasSignatureField = fields.some((field) => field.type === FieldType.SIGNATURE); const hasSignatureField = fields.some((field) => field.type === FieldType.SIGNATURE);
const uninsertedFields = useMemo(() => { const uninsertedFields = useMemo(() => {
return sortFieldsByPosition(fields.filter((field) => !field.inserted)); return sortFieldsByPosition(fieldsRequiringValidation.filter((field) => !field.inserted));
}, [fields]); }, [fields]);
const fieldsValidated = () => { const fieldsValidated = () => {
setValidateUninsertedFields(true); setValidateUninsertedFields(true);
validateFieldsInserted(fields); validateFieldsInserted(fieldsRequiringValidation);
}; };
const onFormSubmit = async () => { const onFormSubmit = async () => {
setValidateUninsertedFields(true); setValidateUninsertedFields(true);
const isFieldsValid = validateFieldsInserted(fieldsRequiringValidation);
if (hasSignatureField && !signatureValid) { if (hasSignatureField && !signatureValid) {
return; return;
} }
const isFieldsValid = validateFieldsInserted(fields);
if (!isFieldsValid) { if (!isFieldsValid) {
return; return;
} }

View File

@@ -1,7 +1,8 @@
import { useState } from 'react'; import { useMemo, useState } from 'react';
import { Trans } from '@lingui/macro'; import { Trans } from '@lingui/macro';
import { fieldsContainUnsignedRequiredField } from '@documenso/lib/utils/advanced-fields-helpers';
import type { Field } from '@documenso/prisma/client'; import type { Field } from '@documenso/prisma/client';
import { RecipientRole } from '@documenso/prisma/client'; import { RecipientRole } from '@documenso/prisma/client';
import { Button } from '@documenso/ui/primitives/button'; import { Button } from '@documenso/ui/primitives/button';
@@ -36,7 +37,7 @@ export const SignDialog = ({
}: SignDialogProps) => { }: SignDialogProps) => {
const [showDialog, setShowDialog] = useState(false); const [showDialog, setShowDialog] = useState(false);
const isComplete = fields.every((field) => field.inserted); const isComplete = useMemo(() => !fieldsContainUnsignedRequiredField(fields), [fields]);
const handleOpenChange = (open: boolean) => { const handleOpenChange = (open: boolean) => {
if (isSubmitting || !isComplete) { if (isSubmitting || !isComplete) {

View File

@@ -2,6 +2,7 @@ import { Plural, Trans, msg } from '@lingui/macro';
import { useLingui } from '@lingui/react'; import { useLingui } from '@lingui/react';
import { DateTime } from 'luxon'; import { DateTime } from 'luxon';
import type Stripe from 'stripe'; import type Stripe from 'stripe';
import { match } from 'ts-pattern';
import { setupI18nSSR } from '@documenso/lib/client-only/providers/i18n.server'; import { setupI18nSSR } from '@documenso/lib/client-only/providers/i18n.server';
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session'; import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
@@ -44,15 +45,24 @@ export default async function TeamsSettingBillingPage({ params }: TeamsSettingsB
const numberOfSeats = subscription.items.data[0].quantity ?? 0; const numberOfSeats = subscription.items.data[0].quantity ?? 0;
const formattedTeamMemberQuanity = (
<Plural value={numberOfSeats} one="# member" other="# members" />
);
const formattedDate = DateTime.fromSeconds(subscription.current_period_end).toFormat( const formattedDate = DateTime.fromSeconds(subscription.current_period_end).toFormat(
'LLL dd, yyyy', 'LLL dd, yyyy',
); );
return _(msg`${formattedTeamMemberQuanity} • Monthly • Renews: ${formattedDate}`); const subscriptionInterval = match(subscription?.items.data[0].plan.interval)
.with('year', () => _(msg`Yearly`))
.with('month', () => _(msg`Monthly`))
.otherwise(() => _(msg`Unknown`));
return (
<span>
<Plural value={numberOfSeats} one="# member" other="# members" />
{' • '}
<span>{subscriptionInterval}</span>
{' • '}
<Trans>Renews: {formattedDate}</Trans>
</span>
);
}; };
return ( return (
@@ -66,10 +76,6 @@ export default async function TeamsSettingBillingPage({ params }: TeamsSettingsB
<CardContent className="flex flex-row items-center justify-between p-4"> <CardContent className="flex flex-row items-center justify-between p-4">
<div className="flex flex-col text-sm"> <div className="flex flex-col text-sm">
<p className="text-foreground font-semibold"> <p className="text-foreground font-semibold">
<Trans>Current plan: {teamSubscription ? 'Team' : 'Early Adopter Team'}</Trans>
</p>
<p className="text-muted-foreground mt-0.5">
{formatTeamSubscriptionDetails(teamSubscription)} {formatTeamSubscriptionDetails(teamSubscription)}
</p> </p>
</div> </div>

View File

@@ -47,10 +47,7 @@ export const StackAvatar = ({ first, zIndex, fallbackText = '', type }: StackAva
return ( return (
<Avatar <Avatar
className={` className={` ${zIndexClass} ${firstClass} dark:border-border h-10 w-10 border-2 border-solid border-white`}
${zIndexClass}
${firstClass}
dark:border-border h-10 w-10 border-2 border-solid border-white`}
> >
<AvatarFallback className={classes}>{fallbackText}</AvatarFallback> <AvatarFallback className={classes}>{fallbackText}</AvatarFallback>
</Avatar> </Avatar>

View File

@@ -14,7 +14,7 @@ import type { z } from 'zod';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { trpc } from '@documenso/trpc/react'; import { trpc } from '@documenso/trpc/react';
import { ZCreateTeamEmailVerificationMutationSchema } from '@documenso/trpc/server/team-router/schema'; import { ZCreateTeamEmailVerificationRequestSchema } from '@documenso/trpc/server/team-router/create-team-email-verification-route';
import { Button } from '@documenso/ui/primitives/button'; import { Button } from '@documenso/ui/primitives/button';
import { import {
Dialog, Dialog,
@@ -41,7 +41,7 @@ export type AddTeamEmailDialogProps = {
trigger?: React.ReactNode; trigger?: React.ReactNode;
} & Omit<DialogPrimitive.DialogProps, 'children'>; } & Omit<DialogPrimitive.DialogProps, 'children'>;
const ZCreateTeamEmailFormSchema = ZCreateTeamEmailVerificationMutationSchema.pick({ const ZCreateTeamEmailFormSchema = ZCreateTeamEmailVerificationRequestSchema.pick({
name: true, name: true,
email: true, email: true,
}); });

View File

@@ -15,7 +15,7 @@ import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-upda
import { WEBAPP_BASE_URL } from '@documenso/lib/constants/app'; import { WEBAPP_BASE_URL } from '@documenso/lib/constants/app';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { trpc } from '@documenso/trpc/react'; import { trpc } from '@documenso/trpc/react';
import { ZCreateTeamMutationSchema } from '@documenso/trpc/server/team-router/schema'; import { ZCreateTeamRequestSchema } from '@documenso/trpc/server/team-router/create-team-route';
import { Button } from '@documenso/ui/primitives/button'; import { Button } from '@documenso/ui/primitives/button';
import { import {
Dialog, Dialog,
@@ -41,7 +41,7 @@ export type CreateTeamDialogProps = {
trigger?: React.ReactNode; trigger?: React.ReactNode;
} & Omit<DialogPrimitive.DialogProps, 'children'>; } & Omit<DialogPrimitive.DialogProps, 'children'>;
const ZCreateTeamFormSchema = ZCreateTeamMutationSchema.pick({ const ZCreateTeamFormSchema = ZCreateTeamRequestSchema.pick({
teamName: true, teamName: true,
teamUrl: true, teamUrl: true,
}); });

View File

@@ -15,7 +15,7 @@ import { downloadFile } from '@documenso/lib/client-only/download-file';
import { TEAM_MEMBER_ROLE_HIERARCHY, TEAM_MEMBER_ROLE_MAP } from '@documenso/lib/constants/teams'; import { TEAM_MEMBER_ROLE_HIERARCHY, TEAM_MEMBER_ROLE_MAP } from '@documenso/lib/constants/teams';
import { TeamMemberRole } from '@documenso/prisma/client'; import { TeamMemberRole } from '@documenso/prisma/client';
import { trpc } from '@documenso/trpc/react'; import { trpc } from '@documenso/trpc/react';
import { ZCreateTeamMemberInvitesMutationSchema } from '@documenso/trpc/server/team-router/schema'; import { ZCreateTeamMemberInvitesRequestSchema } from '@documenso/trpc/server/team-router/create-team-member-invites-route';
import { cn } from '@documenso/ui/lib/utils'; import { cn } from '@documenso/ui/lib/utils';
import { Button } from '@documenso/ui/primitives/button'; import { Button } from '@documenso/ui/primitives/button';
import { Card, CardContent } from '@documenso/ui/primitives/card'; import { Card, CardContent } from '@documenso/ui/primitives/card';
@@ -55,7 +55,7 @@ export type InviteTeamMembersDialogProps = {
const ZInviteTeamMembersFormSchema = z const ZInviteTeamMembersFormSchema = z
.object({ .object({
invitations: ZCreateTeamMemberInvitesMutationSchema.shape.invitations, invitations: ZCreateTeamMemberInvitesRequestSchema.shape.invitations,
}) })
// Display exactly which rows are duplicates. // Display exactly which rows are duplicates.
.superRefine((items, ctx) => { .superRefine((items, ctx) => {

View File

@@ -12,7 +12,7 @@ import type { z } from 'zod';
import { WEBAPP_BASE_URL } from '@documenso/lib/constants/app'; import { WEBAPP_BASE_URL } from '@documenso/lib/constants/app';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { trpc } from '@documenso/trpc/react'; import { trpc } from '@documenso/trpc/react';
import { ZUpdateTeamMutationSchema } from '@documenso/trpc/server/team-router/schema'; import { ZUpdateTeamRequestSchema } from '@documenso/trpc/server/team-router/update-team-route';
import { Button } from '@documenso/ui/primitives/button'; import { Button } from '@documenso/ui/primitives/button';
import { import {
Form, Form,
@@ -31,7 +31,7 @@ export type UpdateTeamDialogProps = {
teamUrl: string; teamUrl: string;
}; };
const ZUpdateTeamFormSchema = ZUpdateTeamMutationSchema.shape.data.pick({ const ZUpdateTeamFormSchema = ZUpdateTeamRequestSchema.shape.data.pick({
name: true, name: true,
url: true, url: true,
}); });

View File

@@ -17,8 +17,8 @@ import { formatUserProfilePath } from '@documenso/lib/utils/public-profiles';
import type { TeamProfile, UserProfile } from '@documenso/prisma/client'; import type { TeamProfile, UserProfile } from '@documenso/prisma/client';
import { import {
MAX_PROFILE_BIO_LENGTH, MAX_PROFILE_BIO_LENGTH,
ZUpdatePublicProfileMutationSchema, ZUpdatePublicProfileRequestSchema,
} from '@documenso/trpc/server/profile-router/schema'; } from '@documenso/trpc/server/profile-router/update-public-profile-route';
import { cn } from '@documenso/ui/lib/utils'; import { cn } from '@documenso/ui/lib/utils';
import { Button } from '@documenso/ui/primitives/button'; import { Button } from '@documenso/ui/primitives/button';
import { import {
@@ -33,7 +33,7 @@ import { Input } from '@documenso/ui/primitives/input';
import { Textarea } from '@documenso/ui/primitives/textarea'; import { Textarea } from '@documenso/ui/primitives/textarea';
import { useToast } from '@documenso/ui/primitives/use-toast'; import { useToast } from '@documenso/ui/primitives/use-toast';
export const ZPublicProfileFormSchema = ZUpdatePublicProfileMutationSchema.pick({ export const ZPublicProfileFormSchema = ZUpdatePublicProfileRequestSchema.pick({
bio: true, bio: true,
enabled: true, enabled: true,
url: true, url: true,

View File

@@ -53,6 +53,7 @@ const ERROR_MESSAGES: Partial<Record<keyof typeof ErrorCode, string>> = {
[ErrorCode.INCORRECT_TWO_FACTOR_BACKUP_CODE]: 'The backup code provided is incorrect', [ErrorCode.INCORRECT_TWO_FACTOR_BACKUP_CODE]: 'The backup code provided is incorrect',
[ErrorCode.UNVERIFIED_EMAIL]: [ErrorCode.UNVERIFIED_EMAIL]:
'This account has not been verified. Please verify your account before signing in.', 'This account has not been verified. Please verify your account before signing in.',
[ErrorCode.ACCOUNT_DISABLED]: 'This account has been disabled. Please contact support.',
}; };
const TwoFactorEnabledErrorCode = ErrorCode.TWO_FACTOR_MISSING_CREDENTIALS; const TwoFactorEnabledErrorCode = ErrorCode.TWO_FACTOR_MISSING_CREDENTIALS;

View File

@@ -70,6 +70,7 @@ export const ZSignUpFormV2Schema = z
}, },
{ {
message: msg`Password should not be common or based on personal information`.id, message: msg`Password should not be common or based on personal information`.id,
path: ['password'],
}, },
); );

View File

@@ -0,0 +1,47 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { createOpenApiNextHandler } from 'trpc-openapi';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { buildLogger } from '@documenso/lib/utils/logger';
import type { TRPCError } from '@documenso/trpc/server';
import { createTrpcContext } from '@documenso/trpc/server/context';
import { appRouter } from '@documenso/trpc/server/router';
const logger = buildLogger();
export default createOpenApiNextHandler<typeof appRouter>({
router: appRouter,
createContext: async ({ req, res }: { req: NextApiRequest; res: NextApiResponse }) =>
createTrpcContext({ req, res }),
onError: ({ error, path }: { error: TRPCError; path?: string }) => {
// Always log the error for now.
console.error(error.message);
const appError = AppError.parseError(error.cause || error);
const isAppError = error.cause instanceof AppError;
// Only log AppErrors that are explicitly set to 500 or the error code
// is in the errorCodesToAlertOn list.
const isLoggableAppError =
isAppError && (appError.statusCode === 500 || errorCodesToAlertOn.includes(appError.code));
// Only log TRPC errors that are in the `errorCodesToAlertOn` list and is
// not an AppError.
const isLoggableTrpcError = !isAppError && errorCodesToAlertOn.includes(error.code);
if (isLoggableAppError || isLoggableTrpcError) {
logger.error(error, {
method: path,
context: {
source: '/v2/api',
appError: AppError.toJSON(appError),
},
});
}
},
responseMeta: () => {},
});
const errorCodesToAlertOn = [AppErrorCode.UNKNOWN_ERROR, 'INTERNAL_SERVER_ERROR'];

View File

@@ -0,0 +1,9 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { openApiDocument } from '@documenso/trpc/server/open-api';
const handler = (_req: NextApiRequest, res: NextApiResponse) => {
res.status(200).send(openApiDocument);
};
export default handler;

View File

@@ -45,6 +45,7 @@ export default trpcNext.createNextApiHandler({
logger.error(error, { logger.error(error, {
method: path, method: path,
context: { context: {
source: 'trpc',
appError: AppError.toJSON(appError), appError: AppError.toJSON(appError),
}, },
}); });

388
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "@documenso/root", "name": "@documenso/root",
"version": "1.9.0-rc.1", "version": "1.9.0-rc.5",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@documenso/root", "name": "@documenso/root",
"version": "1.9.0-rc.1", "version": "1.9.0-rc.5",
"workspaces": [ "workspaces": [
"apps/*", "apps/*",
"packages/*" "packages/*"
@@ -17,8 +17,10 @@
"@lingui/core": "^4.11.3", "@lingui/core": "^4.11.3",
"inngest-cli": "^0.29.1", "inngest-cli": "^0.29.1",
"luxon": "^3.5.0", "luxon": "^3.5.0",
"mupdf": "^1.0.0",
"next-runtime-env": "^3.2.0", "next-runtime-env": "^3.2.0",
"react": "^18" "react": "^18",
"zod": "3.24.1"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^17.7.1", "@commitlint/cli": "^17.7.1",
@@ -79,7 +81,7 @@
}, },
"apps/marketing": { "apps/marketing": {
"name": "@documenso/marketing", "name": "@documenso/marketing",
"version": "1.9.0-rc.1", "version": "1.9.0-rc.5",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"dependencies": { "dependencies": {
"@documenso/assets": "*", "@documenso/assets": "*",
@@ -115,7 +117,7 @@
"recharts": "^2.7.2", "recharts": "^2.7.2",
"sharp": "0.32.6", "sharp": "0.32.6",
"typescript": "5.2.2", "typescript": "5.2.2",
"zod": "^3.23.8" "zod": "3.24.1"
}, },
"devDependencies": { "devDependencies": {
"@lingui/loader": "^4.11.3", "@lingui/loader": "^4.11.3",
@@ -492,7 +494,7 @@
}, },
"apps/web": { "apps/web": {
"name": "@documenso/web", "name": "@documenso/web",
"version": "1.9.0-rc.1", "version": "1.9.0-rc.5",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"dependencies": { "dependencies": {
"@documenso/api": "*", "@documenso/api": "*",
@@ -536,10 +538,11 @@
"recharts": "^2.7.2", "recharts": "^2.7.2",
"remeda": "^2.17.3", "remeda": "^2.17.3",
"sharp": "0.32.6", "sharp": "0.32.6",
"trpc-openapi": "^1.2.0",
"ts-pattern": "^5.0.5", "ts-pattern": "^5.0.5",
"ua-parser-js": "^1.0.37", "ua-parser-js": "^1.0.37",
"uqr": "^0.1.2", "uqr": "^0.1.2",
"zod": "^3.23.8" "zod": "3.24.1"
}, },
"devDependencies": { "devDependencies": {
"@documenso/tailwind-config": "*", "@documenso/tailwind-config": "*",
@@ -3494,6 +3497,11 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/@hapi/bourne": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-3.0.0.tgz",
"integrity": "sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w=="
},
"node_modules/@hapi/hoek": { "node_modules/@hapi/hoek": {
"version": "9.3.0", "version": "9.3.0",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
@@ -10717,15 +10725,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/@trigger.dev/cli/node_modules/zod": {
"version": "3.22.3",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz",
"integrity": "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/@trigger.dev/core": { "node_modules/@trigger.dev/core": {
"version": "2.3.18", "version": "2.3.18",
"resolved": "https://registry.npmjs.org/@trigger.dev/core/-/core-2.3.18.tgz", "resolved": "https://registry.npmjs.org/@trigger.dev/core/-/core-2.3.18.tgz",
@@ -10747,14 +10746,6 @@
"node": ">=18.0.0" "node": ">=18.0.0"
} }
}, },
"node_modules/@trigger.dev/core/node_modules/zod": {
"version": "3.22.3",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz",
"integrity": "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/@trigger.dev/nextjs": { "node_modules/@trigger.dev/nextjs": {
"version": "2.3.18", "version": "2.3.18",
"resolved": "https://registry.npmjs.org/@trigger.dev/nextjs/-/nextjs-2.3.18.tgz", "resolved": "https://registry.npmjs.org/@trigger.dev/nextjs/-/nextjs-2.3.18.tgz",
@@ -10818,14 +10809,6 @@
"uuid": "dist/bin/uuid" "uuid": "dist/bin/uuid"
} }
}, },
"node_modules/@trigger.dev/sdk/node_modules/zod": {
"version": "3.22.3",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz",
"integrity": "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/@trigger.dev/yalt": { "node_modules/@trigger.dev/yalt": {
"version": "2.3.18", "version": "2.3.18",
"resolved": "https://registry.npmjs.org/@trigger.dev/yalt/-/yalt-2.3.18.tgz", "resolved": "https://registry.npmjs.org/@trigger.dev/yalt/-/yalt-2.3.18.tgz",
@@ -10842,15 +10825,6 @@
"node": ">=18.0.0" "node": ">=18.0.0"
} }
}, },
"node_modules/@trigger.dev/yalt/node_modules/zod": {
"version": "3.22.3",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz",
"integrity": "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/@trivago/prettier-plugin-sort-imports": { "node_modules/@trivago/prettier-plugin-sort-imports": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.3.0.tgz", "resolved": "https://registry.npmjs.org/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.3.0.tgz",
@@ -12007,6 +11981,18 @@
"node": ">=6.5" "node": ">=6.5"
} }
}, },
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
"dependencies": {
"mime-types": "~2.1.34",
"negotiator": "0.6.3"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.11.3", "version": "8.11.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
@@ -14311,6 +14297,21 @@
} }
} }
}, },
"node_modules/co-body": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/co-body/-/co-body-6.2.0.tgz",
"integrity": "sha512-Kbpv2Yd1NdL1V/V4cwLVxraHDV6K8ayohr2rmH0J87Er8+zJjcTa6dAn9QMPC9CRgU8+aNajKbSf1TzDB1yKPA==",
"dependencies": {
"@hapi/bourne": "^3.0.0",
"inflation": "^2.0.0",
"qs": "^6.5.2",
"raw-body": "^2.3.3",
"type-is": "^1.6.16"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/code-block-writer": { "node_modules/code-block-writer": {
"version": "12.0.0", "version": "12.0.0",
"resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-12.0.0.tgz", "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-12.0.0.tgz",
@@ -14612,6 +14613,14 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/consola": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz",
"integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==",
"engines": {
"node": "^14.18.0 || >=16.10.0"
}
},
"node_modules/console-control-strings": { "node_modules/console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
@@ -14627,6 +14636,17 @@
"simple-wcswidth": "^1.0.1" "simple-wcswidth": "^1.0.1"
} }
}, },
"node_modules/content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
"dependencies": {
"safe-buffer": "5.2.1"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/content-type": { "node_modules/content-type": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
@@ -14712,9 +14732,9 @@
} }
}, },
"node_modules/cookie-es": { "node_modules/cookie-es": {
"version": "1.0.0", "version": "1.2.2",
"resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.0.0.tgz", "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz",
"integrity": "sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ==" "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg=="
}, },
"node_modules/copy-anything": { "node_modules/copy-anything": {
"version": "3.0.5", "version": "3.0.5",
@@ -14880,6 +14900,14 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/crossws": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.1.tgz",
"integrity": "sha512-HsZgeVYaG+b5zA+9PbIPGq4+J/CJynJuearykPsXx4V/eMhyQ5EDVg3Ak2FBZtVXCiOLu/U7IiwDHTr9MA+IKw==",
"dependencies": {
"uncrypto": "^0.1.3"
}
},
"node_modules/crypto-js": { "node_modules/crypto-js": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
@@ -15587,6 +15615,11 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/defu": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
"integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="
},
"node_modules/degenerator": { "node_modules/degenerator": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
@@ -15693,6 +15726,11 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/destr": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/destr/-/destr-2.0.3.tgz",
"integrity": "sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ=="
},
"node_modules/detect-indent": { "node_modules/detect-indent": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
@@ -18123,6 +18161,14 @@
} }
} }
}, },
"node_modules/fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/from": { "node_modules/from": {
"version": "0.1.7", "version": "0.1.7",
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
@@ -18793,6 +18839,23 @@
"js-yaml": "bin/js-yaml.js" "js-yaml": "bin/js-yaml.js"
} }
}, },
"node_modules/h3": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/h3/-/h3-1.13.0.tgz",
"integrity": "sha512-vFEAu/yf8UMUcB4s43OaDaigcqpQd14yanmOsn+NcRX3/guSKncyE2rOYhq8RIchgJrPSs/QiIddnTTR1ddiAg==",
"dependencies": {
"cookie-es": "^1.2.2",
"crossws": ">=0.2.0 <0.4.0",
"defu": "^6.1.4",
"destr": "^2.0.3",
"iron-webcrypto": "^1.2.1",
"ohash": "^1.1.4",
"radix3": "^1.1.2",
"ufo": "^1.5.4",
"uncrypto": "^0.1.3",
"unenv": "^1.10.0"
}
},
"node_modules/hard-rejection": { "node_modules/hard-rejection": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
@@ -19844,6 +19907,14 @@
"integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
"dev": true "dev": true
}, },
"node_modules/inflation": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/inflation/-/inflation-2.1.0.tgz",
"integrity": "sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==",
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/inflection": { "node_modules/inflection": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/inflection/-/inflection-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inflection/-/inflection-2.0.1.tgz",
@@ -20000,14 +20071,6 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/inngest/node_modules/zod": {
"version": "3.22.5",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.5.tgz",
"integrity": "sha512-HqnGsCdVZ2xc0qWPLdO25WnseXThh0kEYKIdV5F/hTHO75hNZFp8thxSeHhiPrHZKrFTo1SOgkAj9po5bexZlw==",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/input-otp": { "node_modules/input-otp": {
"version": "1.2.4", "version": "1.2.4",
"resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.2.4.tgz", "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.2.4.tgz",
@@ -20219,6 +20282,14 @@
"node": ">= 10" "node": ">= 10"
} }
}, },
"node_modules/iron-webcrypto": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz",
"integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==",
"funding": {
"url": "https://github.com/sponsors/brc-dd"
}
},
"node_modules/is-alphabetical": { "node_modules/is-alphabetical": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
@@ -22035,8 +22106,7 @@
"node_modules/lodash.clonedeep": { "node_modules/lodash.clonedeep": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
"dev": true
}, },
"node_modules/lodash.debounce": { "node_modules/lodash.debounce": {
"version": "4.0.8", "version": "4.0.8",
@@ -22863,6 +22933,14 @@
"esbuild": "0.*" "esbuild": "0.*"
} }
}, },
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/memfs": { "node_modules/memfs": {
"version": "3.5.3", "version": "3.5.3",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
@@ -22917,6 +22995,14 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/merge-descriptors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
"integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/merge-refs": { "node_modules/merge-refs": {
"version": "1.2.2", "version": "1.2.2",
"resolved": "https://registry.npmjs.org/merge-refs/-/merge-refs-1.2.2.tgz", "resolved": "https://registry.npmjs.org/merge-refs/-/merge-refs-1.2.2.tgz",
@@ -22990,6 +23076,14 @@
"uuid": "dist/bin/uuid" "uuid": "dist/bin/uuid"
} }
}, },
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/micro": { "node_modules/micro": {
"version": "10.0.1", "version": "10.0.1",
"resolved": "https://registry.npmjs.org/micro/-/micro-10.0.1.tgz", "resolved": "https://registry.npmjs.org/micro/-/micro-10.0.1.tgz",
@@ -23733,6 +23827,17 @@
"node": ">=8.6" "node": ">=8.6"
} }
}, },
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/mime-db": { "node_modules/mime-db": {
"version": "1.52.0", "version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -24139,6 +24244,12 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}, },
"node_modules/mupdf": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/mupdf/-/mupdf-1.0.0.tgz",
"integrity": "sha512-AWT27abYSX5gQmWs7+jDEtmGJpWyZrqdxROpYf5BDAJBA+iYqlNztk2EMlKvuRLBzajj00kf4PtFiergDSKDTg==",
"license": "AGPL-3.0-or-later"
},
"node_modules/mute-stream": { "node_modules/mute-stream": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz",
@@ -24196,7 +24307,6 @@
"version": "0.6.3", "version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
"dev": true,
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
} }
@@ -24665,6 +24775,11 @@
"url": "https://opencollective.com/node-fetch" "url": "https://opencollective.com/node-fetch"
} }
}, },
"node_modules/node-fetch-native": {
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz",
"integrity": "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ=="
},
"node_modules/node-gyp": { "node_modules/node-gyp": {
"version": "9.4.1", "version": "9.4.1",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz",
@@ -24993,6 +25108,38 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0" "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
} }
}, },
"node_modules/node-mocks-http": {
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/node-mocks-http/-/node-mocks-http-1.16.2.tgz",
"integrity": "sha512-2Sh6YItRp1oqewZNlck3LaFp5vbyW2u51HX2p1VLxQ9U/bG90XV8JY9O7Nk+HDd6OOn/oV3nA5Tx5k4Rki0qlg==",
"dependencies": {
"accepts": "^1.3.7",
"content-disposition": "^0.5.3",
"depd": "^1.1.0",
"fresh": "^0.5.2",
"merge-descriptors": "^1.0.1",
"methods": "^1.1.2",
"mime": "^1.3.4",
"parseurl": "^1.3.3",
"range-parser": "^1.2.0",
"type-is": "^1.6.18"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
"@types/express": "^4.17.21 || ^5.0.0",
"@types/node": "*"
},
"peerDependenciesMeta": {
"@types/express": {
"optional": true
},
"@types/node": {
"optional": true
}
}
},
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.14", "version": "2.0.14",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
@@ -25580,6 +25727,11 @@
"integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
"dev": true "dev": true
}, },
"node_modules/ohash": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz",
"integrity": "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g=="
},
"node_modules/oidc-token-hash": { "node_modules/oidc-token-hash": {
"version": "5.0.3", "version": "5.0.3",
"resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz",
@@ -25681,6 +25833,11 @@
} }
} }
}, },
"node_modules/openapi-types": {
"version": "12.1.3",
"resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz",
"integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="
},
"node_modules/openapi3-ts": { "node_modules/openapi3-ts": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/openapi3-ts/-/openapi3-ts-2.0.2.tgz", "resolved": "https://registry.npmjs.org/openapi3-ts/-/openapi3-ts-2.0.2.tgz",
@@ -26440,6 +26597,14 @@
"url": "https://ko-fi.com/killymxi" "url": "https://ko-fi.com/killymxi"
} }
}, },
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/partysocket": { "node_modules/partysocket": {
"version": "0.0.17", "version": "0.0.17",
"resolved": "https://registry.npmjs.org/partysocket/-/partysocket-0.0.17.tgz", "resolved": "https://registry.npmjs.org/partysocket/-/partysocket-0.0.17.tgz",
@@ -26595,8 +26760,7 @@
"node_modules/pathe": { "node_modules/pathe": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
"integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="
"dev": true
}, },
"node_modules/pathval": { "node_modules/pathval": {
"version": "1.1.1", "version": "1.1.1",
@@ -27908,6 +28072,11 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/radix3": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz",
"integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA=="
},
"node_modules/raf-schd": { "node_modules/raf-schd": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz",
@@ -27946,6 +28115,14 @@
"safe-buffer": "^5.1.0" "safe-buffer": "^5.1.0"
} }
}, },
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/raw-body": { "node_modules/raw-body": {
"version": "2.4.1", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz",
@@ -32782,6 +32959,32 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/trpc-openapi": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/trpc-openapi/-/trpc-openapi-1.2.0.tgz",
"integrity": "sha512-pfYoCd/3KYXWXvUPZBKJw455OOwngKN/6SIcj7Yit19OMLJ+8yVZkEvGEeg5wUSwfsiTdRsKuvqkRPXVSwV7ew==",
"workspaces": [
".",
"examples/with-nextjs",
"examples/with-express",
"examples/with-interop",
"examples/with-serverless",
"examples/with-fastify",
"examples/with-nuxtjs"
],
"dependencies": {
"co-body": "^6.1.0",
"h3": "^1.6.4",
"lodash.clonedeep": "^4.5.0",
"node-mocks-http": "^1.12.2",
"openapi-types": "^12.1.1",
"zod-to-json-schema": "^3.21.1"
},
"peerDependencies": {
"@trpc/server": "^10.0.0",
"zod": "^3.14.4"
}
},
"node_modules/ts-api-utils": { "node_modules/ts-api-utils": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
@@ -33547,6 +33750,18 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
"dependencies": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/typed-array-buffer": { "node_modules/typed-array-buffer": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
@@ -33665,10 +33880,9 @@
} }
}, },
"node_modules/ufo": { "node_modules/ufo": {
"version": "1.4.0", "version": "1.5.4",
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.4.0.tgz", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz",
"integrity": "sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==", "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ=="
"dev": true
}, },
"node_modules/ulid": { "node_modules/ulid": {
"version": "2.3.0", "version": "2.3.0",
@@ -33703,6 +33917,11 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/uncrypto": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz",
"integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="
},
"node_modules/undici": { "node_modules/undici": {
"version": "5.28.2", "version": "5.28.2",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.2.tgz", "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.2.tgz",
@@ -33720,6 +33939,29 @@
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"dev": true "dev": true
}, },
"node_modules/unenv": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/unenv/-/unenv-1.10.0.tgz",
"integrity": "sha512-wY5bskBQFL9n3Eca5XnhH6KbUo/tfvkwm9OpcdCvLaeA7piBNbavbOKJySEwQ1V0RH6HvNlSAFRTpvTqgKRQXQ==",
"dependencies": {
"consola": "^3.2.3",
"defu": "^6.1.4",
"mime": "^3.0.0",
"node-fetch-native": "^1.6.4",
"pathe": "^1.1.2"
}
},
"node_modules/unenv/node_modules/mime": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
"integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/unified": { "node_modules/unified": {
"version": "10.1.2", "version": "10.1.2",
"resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz",
@@ -35409,9 +35651,9 @@
} }
}, },
"node_modules/zod": { "node_modules/zod": {
"version": "3.23.8", "version": "3.24.1",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz",
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==",
"funding": { "funding": {
"url": "https://github.com/sponsors/colinhacks" "url": "https://github.com/sponsors/colinhacks"
} }
@@ -35454,6 +35696,14 @@
"@prisma/debug": "5.22.0" "@prisma/debug": "5.22.0"
} }
}, },
"node_modules/zod-to-json-schema": {
"version": "3.24.1",
"resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.1.tgz",
"integrity": "sha512-3h08nf3Vw3Wl3PK+q3ow/lIil81IT2Oa7YpQyUUDsEWbXveMesdfK1xBd2RhCkynwZndAxixji/7SYJJowr62w==",
"peerDependencies": {
"zod": "^3.24.1"
}
},
"node_modules/zwitch": { "node_modules/zwitch": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
@@ -35478,7 +35728,7 @@
"superjson": "^1.13.1", "superjson": "^1.13.1",
"swagger-ui-react": "^5.11.0", "swagger-ui-react": "^5.11.0",
"ts-pattern": "^5.0.5", "ts-pattern": "^5.0.5",
"zod": "^3.23.8" "zod": "3.24.1"
} }
}, },
"packages/api/node_modules/@ts-rest/next": { "packages/api/node_modules/@ts-rest/next": {
@@ -35543,7 +35793,7 @@
"next-auth": "4.24.5", "next-auth": "4.24.5",
"react": "^18", "react": "^18",
"ts-pattern": "^5.0.5", "ts-pattern": "^5.0.5",
"zod": "^3.23.8" "zod": "3.24.1"
} }
}, },
"packages/email": { "packages/email": {
@@ -36752,7 +37002,7 @@
"sharp": "0.32.6", "sharp": "0.32.6",
"stripe": "^12.7.0", "stripe": "^12.7.0",
"ts-pattern": "^5.0.5", "ts-pattern": "^5.0.5",
"zod": "^3.23.8" "zod": "3.24.1"
}, },
"devDependencies": { "devDependencies": {
"@playwright/browser-chromium": "1.43.0", "@playwright/browser-chromium": "1.43.0",
@@ -36890,7 +37140,7 @@
"luxon": "^3.4.0", "luxon": "^3.4.0",
"superjson": "^1.13.1", "superjson": "^1.13.1",
"ts-pattern": "^5.0.5", "ts-pattern": "^5.0.5",
"zod": "^3.23.8" "zod": "3.24.1"
} }
}, },
"packages/trpc/node_modules/@ts-rest/next": { "packages/trpc/node_modules/@ts-rest/next": {
@@ -36970,7 +37220,7 @@
"tailwind-merge": "^1.12.0", "tailwind-merge": "^1.12.0",
"tailwindcss-animate": "^1.0.5", "tailwindcss-animate": "^1.0.5",
"ts-pattern": "^5.0.5", "ts-pattern": "^5.0.5",
"zod": "^3.23.8" "zod": "3.24.1"
}, },
"devDependencies": { "devDependencies": {
"@documenso/tailwind-config": "*", "@documenso/tailwind-config": "*",

View File

@@ -1,6 +1,6 @@
{ {
"private": true, "private": true,
"version": "1.9.0-rc.1", "version": "1.9.0-rc.5",
"scripts": { "scripts": {
"build": "turbo run build", "build": "turbo run build",
"build:web": "turbo run build --filter=@documenso/web", "build:web": "turbo run build --filter=@documenso/web",
@@ -68,11 +68,14 @@
"@lingui/core": "^4.11.3", "@lingui/core": "^4.11.3",
"inngest-cli": "^0.29.1", "inngest-cli": "^0.29.1",
"luxon": "^3.5.0", "luxon": "^3.5.0",
"mupdf": "^1.0.0",
"next-runtime-env": "^3.2.0", "next-runtime-env": "^3.2.0",
"react": "^18" "react": "^18",
"zod": "3.24.1"
}, },
"overrides": { "overrides": {
"next": "14.2.6" "next": "14.2.6",
"zod": "3.24.1"
}, },
"trigger.dev": { "trigger.dev": {
"endpointId": "documenso-app" "endpointId": "documenso-app"

View File

@@ -25,6 +25,6 @@
"superjson": "^1.13.1", "superjson": "^1.13.1",
"swagger-ui-react": "^5.11.0", "swagger-ui-react": "^5.11.0",
"ts-pattern": "^5.0.5", "ts-pattern": "^5.0.5",
"zod": "^3.23.8" "zod": "3.24.1"
} }
} }

View File

@@ -23,18 +23,19 @@ import { getFieldsForDocument } from '@documenso/lib/server-only/field/get-field
import { updateField } from '@documenso/lib/server-only/field/update-field'; import { updateField } from '@documenso/lib/server-only/field/update-field';
import { insertFormValuesInPdf } from '@documenso/lib/server-only/pdf/insert-form-values-in-pdf'; import { insertFormValuesInPdf } from '@documenso/lib/server-only/pdf/insert-form-values-in-pdf';
import { deleteRecipient } from '@documenso/lib/server-only/recipient/delete-recipient'; import { deleteRecipient } from '@documenso/lib/server-only/recipient/delete-recipient';
import { getRecipientById } from '@documenso/lib/server-only/recipient/get-recipient-by-id'; import { getRecipientByIdV1Api } from '@documenso/lib/server-only/recipient/get-recipient-by-id-v1-api';
import { getRecipientsForDocument } from '@documenso/lib/server-only/recipient/get-recipients-for-document'; import { getRecipientsForDocument } from '@documenso/lib/server-only/recipient/get-recipients-for-document';
import { setRecipientsForDocument } from '@documenso/lib/server-only/recipient/set-recipients-for-document'; import { setRecipientsForDocument } from '@documenso/lib/server-only/recipient/set-recipients-for-document';
import { updateRecipient } from '@documenso/lib/server-only/recipient/update-recipient'; import { updateRecipient } from '@documenso/lib/server-only/recipient/update-recipient';
import { createTeamMemberInvites } from '@documenso/lib/server-only/team/create-team-member-invites'; import { createTeamMemberInvites } from '@documenso/lib/server-only/team/create-team-member-invites';
import { deleteTeamMembers } from '@documenso/lib/server-only/team/delete-team-members'; import { deleteTeamMembers } from '@documenso/lib/server-only/team/delete-team-members';
import type { CreateDocumentFromTemplateResponse } from '@documenso/lib/server-only/template/create-document-from-template'; import type { TCreateDocumentFromTemplateResponse } from '@documenso/lib/server-only/template/create-document-from-template';
import { createDocumentFromTemplate } from '@documenso/lib/server-only/template/create-document-from-template'; import { createDocumentFromTemplate } from '@documenso/lib/server-only/template/create-document-from-template';
import { createDocumentFromTemplateLegacy } from '@documenso/lib/server-only/template/create-document-from-template-legacy'; import { createDocumentFromTemplateLegacy } from '@documenso/lib/server-only/template/create-document-from-template-legacy';
import { deleteTemplate } from '@documenso/lib/server-only/template/delete-template'; import { deleteTemplate } from '@documenso/lib/server-only/template/delete-template';
import { findTemplates } from '@documenso/lib/server-only/template/find-templates'; import { findTemplates } from '@documenso/lib/server-only/template/find-templates';
import { getTemplateById } from '@documenso/lib/server-only/template/get-template-by-id'; import { getTemplateById } from '@documenso/lib/server-only/template/get-template-by-id';
import { extractDerivedDocumentEmailSettings } from '@documenso/lib/types/document-email';
import { ZFieldMetaSchema } from '@documenso/lib/types/field-meta'; import { ZFieldMetaSchema } from '@documenso/lib/types/field-meta';
import { import {
ZCheckboxFieldMeta, ZCheckboxFieldMeta,
@@ -344,7 +345,7 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
}); });
} }
const recipients = await setRecipientsForDocument({ const { recipients } = await setRecipientsForDocument({
userId: user.id, userId: user.id,
teamId: team?.id, teamId: team?.id,
documentId: document.id, documentId: document.id,
@@ -559,7 +560,7 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
const templateId = Number(params.templateId); const templateId = Number(params.templateId);
let document: CreateDocumentFromTemplateResponse | null = null; let document: TCreateDocumentFromTemplateResponse | null = null;
try { try {
document = await createDocumentFromTemplate({ document = await createDocumentFromTemplate({
@@ -629,7 +630,6 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
token: recipient.token, token: recipient.token,
role: recipient.role, role: recipient.role,
signingOrder: recipient.signingOrder, signingOrder: recipient.signingOrder,
signingUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/sign/${recipient.token}`, signingUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/sign/${recipient.token}`,
})), })),
}, },
@@ -637,11 +637,12 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
}), }),
sendDocument: authenticatedMiddleware(async (args, user, team) => { sendDocument: authenticatedMiddleware(async (args, user, team) => {
const { id } = args.params; const { id: documentId } = args.params;
const { sendEmail = true } = args.body ?? {}; const { sendEmail, sendCompletionEmails } = args.body;
try {
const document = await getDocumentById({ const document = await getDocumentById({
documentId: Number(id), documentId: Number(documentId),
userId: user.id, userId: user.id,
teamId: team?.id, teamId: team?.id,
}); });
@@ -664,42 +665,24 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
}; };
} }
try { const emailSettings = extractDerivedDocumentEmailSettings(document.documentMeta);
// await setRecipientsForDocument({
// userId: user.id,
// documentId: Number(id),
// recipients: [
// {
// email: body.signerEmail,
// name: body.signerName ?? '',
// },
// ],
// });
// await setFieldsForDocument({ // Update document email settings if sendCompletionEmails is provided
// documentId: Number(id), if (typeof sendCompletionEmails === 'boolean') {
// userId: user.id, await upsertDocumentMeta({
// fields: body.fields.map((field) => ({ documentId: document.id,
// signerEmail: body.signerEmail, userId: user.id,
// type: field.fieldType, emailSettings: {
// pageNumber: field.pageNumber, ...emailSettings,
// pageX: field.pageX, documentCompleted: sendCompletionEmails,
// pageY: field.pageY, ownerDocumentCompleted: sendCompletionEmails,
// pageWidth: field.pageWidth, },
// pageHeight: field.pageHeight, requestMetadata: extractNextApiRequestMetadata(args.req),
// })), });
// }); }
// if (body.emailBody || body.emailSubject) {
// await upsertDocumentMeta({
// documentId: Number(id),
// subject: body.emailSubject ?? '',
// message: body.emailBody ?? '',
// });
// }
const { Recipient: recipients, ...sentDocument } = await sendDocument({ const { Recipient: recipients, ...sentDocument } = await sendDocument({
documentId: Number(id), documentId: document.id,
userId: user.id, userId: user.id,
teamId: team?.id, teamId: team?.id,
sendEmail, sendEmail,
@@ -802,7 +785,7 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
} }
try { try {
const newRecipients = await setRecipientsForDocument({ const { recipients: newRecipients } = await setRecipientsForDocument({
documentId: Number(documentId), documentId: Number(documentId),
userId: user.id, userId: user.id,
teamId: team?.id, teamId: team?.id,
@@ -1016,7 +999,7 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
throw new Error('Invalid page number'); throw new Error('Invalid page number');
} }
const recipient = await getRecipientById({ const recipient = await getRecipientByIdV1Api({
id: Number(recipientId), id: Number(recipientId),
documentId: Number(documentId), documentId: Number(documentId),
}).catch(() => null); }).catch(() => null);
@@ -1161,7 +1144,7 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
}; };
} }
const recipient = await getRecipientById({ const recipient = await getRecipientByIdV1Api({
id: Number(recipientId), id: Number(recipientId),
documentId: Number(documentId), documentId: Number(documentId),
}).catch(() => null); }).catch(() => null);
@@ -1265,7 +1248,7 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
}; };
} }
const recipient = await getRecipientById({ const recipient = await getRecipientByIdV1Api({
id: Number(field.recipientId), id: Number(field.recipientId),
documentId: Number(documentId), documentId: Number(documentId),
}).catch(() => null); }).catch(() => null);

View File

@@ -1,5 +1,6 @@
import type { NextApiRequest } from 'next'; import type { NextApiRequest } from 'next';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { getApiTokenByToken } from '@documenso/lib/server-only/public-api/get-api-token-by-token'; import { getApiTokenByToken } from '@documenso/lib/server-only/public-api/get-api-token-by-token';
import type { Team, User } from '@documenso/prisma/client'; import type { Team, User } from '@documenso/prisma/client';
@@ -22,18 +23,33 @@ export const authenticatedMiddleware = <
const [token] = (authorization || '').split('Bearer ').filter((s) => s.length > 0); const [token] = (authorization || '').split('Bearer ').filter((s) => s.length > 0);
if (!token) { if (!token) {
throw new Error('Token was not provided for authenticated middleware'); throw new AppError(AppErrorCode.UNAUTHORIZED, {
message: 'API token was not provided',
});
} }
const apiToken = await getApiTokenByToken({ token }); const apiToken = await getApiTokenByToken({ token });
if (apiToken.user.disabled) {
throw new AppError(AppErrorCode.UNAUTHORIZED, {
message: 'User is disabled',
});
}
return await handler(args, apiToken.user, apiToken.team); return await handler(args, apiToken.user, apiToken.team);
} catch (_err) { } catch (err) {
console.log({ _err }); console.log({ err: err });
let message = 'Unauthorized';
if (err instanceof AppError) {
message = err.message;
}
return { return {
status: 401, status: 401,
body: { body: {
message: 'Unauthorized', message,
}, },
} as const; } as const;
} }

View File

@@ -88,8 +88,12 @@ export const ZSendDocumentForSigningMutationSchema = z
description: description:
'Whether to send an email to the recipients asking them to action the document. If you disable this, you will need to manually distribute the document to the recipients using the generated signing links.', 'Whether to send an email to the recipients asking them to action the document. If you disable this, you will need to manually distribute the document to the recipients using the generated signing links.',
}), }),
sendCompletionEmails: z.boolean().optional().openapi({
description:
'Whether to send completion emails when the document is fully signed. This will override the document email settings.',
}),
}) })
.or(z.literal('').transform(() => ({ sendEmail: true }))); .or(z.literal('').transform(() => ({ sendEmail: true, sendCompletionEmails: undefined })));
export type TSendDocumentForSigningMutationSchema = typeof ZSendDocumentForSigningMutationSchema; export type TSendDocumentForSigningMutationSchema = typeof ZSendDocumentForSigningMutationSchema;

View File

@@ -0,0 +1,137 @@
import { expect, test } from '@playwright/test';
import { WEBAPP_BASE_URL } from '@documenso/lib/constants/app';
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
import { prisma } from '@documenso/prisma';
import { seedPendingDocumentWithFullFields } from '@documenso/prisma/seed/documents';
import { seedUser } from '@documenso/prisma/seed/users';
test.describe('Document API', () => {
test('sendDocument: should respect sendCompletionEmails setting', async ({ request }) => {
const user = await seedUser();
const { document } = await seedPendingDocumentWithFullFields({
owner: user,
recipients: ['signer@example.com'],
});
const { token } = await createApiToken({
userId: user.id,
tokenName: 'test',
expiresIn: null,
});
// Test with sendCompletionEmails: false
const response = await request.post(`${WEBAPP_BASE_URL}/api/v1/documents/${document.id}/send`, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
data: {
sendCompletionEmails: false,
},
});
expect(response.ok()).toBeTruthy();
expect(response.status()).toBe(200);
// Verify email settings were updated
const updatedDocument = await prisma.document.findUnique({
where: { id: document.id },
include: { documentMeta: true },
});
expect(updatedDocument?.documentMeta?.emailSettings).toMatchObject({
documentCompleted: false,
ownerDocumentCompleted: false,
});
// Test with sendCompletionEmails: true
const response2 = await request.post(
`${WEBAPP_BASE_URL}/api/v1/documents/${document.id}/send`,
{
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
data: {
sendCompletionEmails: true,
},
},
);
expect(response2.ok()).toBeTruthy();
expect(response2.status()).toBe(200);
// Verify email settings were updated
const updatedDocument2 = await prisma.document.findUnique({
where: { id: document.id },
include: { documentMeta: true },
});
expect(updatedDocument2?.documentMeta?.emailSettings ?? {}).toMatchObject({
documentCompleted: true,
ownerDocumentCompleted: true,
});
});
test('sendDocument: should not modify email settings when sendCompletionEmails is not provided', async ({
request,
}) => {
const user = await seedUser();
const { document } = await seedPendingDocumentWithFullFields({
owner: user,
recipients: ['signer@example.com'],
});
// Set initial email settings
await prisma.documentMeta.upsert({
where: { documentId: document.id },
create: {
documentId: document.id,
emailSettings: {
documentCompleted: true,
ownerDocumentCompleted: false,
},
},
update: {
documentId: document.id,
emailSettings: {
documentCompleted: true,
ownerDocumentCompleted: false,
},
},
});
const { token } = await createApiToken({
userId: user.id,
tokenName: 'test',
expiresIn: null,
});
const response = await request.post(`${WEBAPP_BASE_URL}/api/v1/documents/${document.id}/send`, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
data: {
sendEmail: true,
},
});
expect(response.ok()).toBeTruthy();
expect(response.status()).toBe(200);
// Verify email settings were not modified
const updatedDocument = await prisma.document.findUnique({
where: { id: document.id },
include: { documentMeta: true },
});
expect(updatedDocument?.documentMeta?.emailSettings ?? {}).toMatchObject({
documentCompleted: true,
ownerDocumentCompleted: false,
});
});
});

View File

@@ -1,6 +1,7 @@
import { expect, test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import { DocumentStatus, TeamMemberRole } from '@documenso/prisma/client'; import { DocumentStatus, DocumentVisibility, TeamMemberRole } from '@documenso/prisma/client';
import { seedBlankDocument } from '@documenso/prisma/seed/documents';
import { seedDocuments, seedTeamDocuments } from '@documenso/prisma/seed/documents'; import { seedDocuments, seedTeamDocuments } from '@documenso/prisma/seed/documents';
import { seedTeam, seedTeamEmail, seedTeamMember } from '@documenso/prisma/seed/teams'; import { seedTeam, seedTeamEmail, seedTeamMember } from '@documenso/prisma/seed/teams';
import { seedUser } from '@documenso/prisma/seed/users'; import { seedUser } from '@documenso/prisma/seed/users';
@@ -538,7 +539,7 @@ test('[TEAMS]: ensure recipient can see document regardless of visibility', asyn
await apiSignout({ page }); await apiSignout({ page });
}); });
test('[TEAMS]: check that members cannot see ADMIN-only documents', async ({ page }) => { test('[TEAMS]: check that MEMBER role cannot see ADMIN-only documents', async ({ page }) => {
const team = await seedTeam(); const team = await seedTeam();
// Seed a member user // Seed a member user
@@ -575,7 +576,46 @@ test('[TEAMS]: check that members cannot see ADMIN-only documents', async ({ pag
await apiSignout({ page }); await apiSignout({ page });
}); });
test('[TEAMS]: check that managers cannot see ADMIN-only documents', async ({ page }) => { test('[TEAMS]: check that MEMBER role cannot see MANAGER_AND_ABOVE-only documents', async ({
page,
}) => {
const team = await seedTeam();
// Seed a member user
const memberUser = await seedTeamMember({
teamId: team.id,
role: TeamMemberRole.MEMBER,
});
// Seed an ADMIN-only document
await seedDocuments([
{
sender: team.owner,
recipients: [],
type: DocumentStatus.COMPLETED,
documentOptions: {
teamId: team.id,
visibility: 'MANAGER_AND_ABOVE',
title: 'Manager and Above Only Document',
},
},
]);
await apiSignin({
page,
email: memberUser.email,
redirectPath: `/t/${team.url}/documents?status=COMPLETED`,
});
// Check that the member user cannot see the ADMIN-only document
await expect(
page.getByRole('link', { name: 'Admin Only Document', exact: true }),
).not.toBeVisible();
await apiSignout({ page });
});
test('[TEAMS]: check that MANAGER role cannot see ADMIN-only documents', async ({ page }) => {
const team = await seedTeam(); const team = await seedTeam();
// Seed a manager user // Seed a manager user
@@ -612,7 +652,7 @@ test('[TEAMS]: check that managers cannot see ADMIN-only documents', async ({ pa
await apiSignout({ page }); await apiSignout({ page });
}); });
test('[TEAMS]: check that admin can see MANAGER_AND_ABOVE documents', async ({ page }) => { test('[TEAMS]: check that ADMIN role can see MANAGER_AND_ABOVE documents', async ({ page }) => {
const team = await seedTeam(); const team = await seedTeam();
// Seed an admin user // Seed an admin user
@@ -649,6 +689,187 @@ test('[TEAMS]: check that admin can see MANAGER_AND_ABOVE documents', async ({ p
await apiSignout({ page }); await apiSignout({ page });
}); });
test('[TEAMS]: check that ADMIN role can change document visibility', async ({ page }) => {
const team = await seedTeam({
createTeamOptions: {
teamGlobalSettings: {
create: {
documentVisibility: DocumentVisibility.MANAGER_AND_ABOVE,
},
},
},
});
const adminUser = await seedTeamMember({
teamId: team.id,
role: TeamMemberRole.ADMIN,
});
const document = await seedBlankDocument(adminUser, {
createDocumentOptions: {
teamId: team.id,
visibility: team.teamGlobalSettings?.documentVisibility,
},
});
await apiSignin({
page,
email: adminUser.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
});
await page.getByTestId('documentVisibilitySelectValue').click();
await page.getByLabel('Admins only').click();
await page.getByRole('button', { name: 'Continue' }).click();
await expect(page.getByRole('heading', { name: 'Add Signers' })).toBeVisible();
await page.getByRole('button', { name: 'Go Back' }).click();
await expect(page.getByRole('heading', { name: 'General' })).toBeVisible();
await expect(page.getByTestId('documentVisibilitySelectValue')).toContainText('Admins only');
});
test('[TEAMS]: check that MEMBER role cannot change visibility of EVERYONE documents', async ({
page,
}) => {
const team = await seedTeam({
createTeamOptions: {
teamGlobalSettings: {
create: {
documentVisibility: DocumentVisibility.EVERYONE,
},
},
},
});
const teamMember = await seedTeamMember({
teamId: team.id,
role: TeamMemberRole.MEMBER,
});
const document = await seedBlankDocument(teamMember, {
createDocumentOptions: {
teamId: team.id,
visibility: team.teamGlobalSettings?.documentVisibility,
},
});
await apiSignin({
page,
email: teamMember.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
});
await expect(page.getByTestId('documentVisibilitySelectValue')).toHaveText('Everyone');
await expect(page.getByTestId('documentVisibilitySelectValue')).toBeDisabled();
});
test('[TEAMS]: check that MEMBER role cannot change visibility of MANAGER_AND_ABOVE documents', async ({
page,
}) => {
const team = await seedTeam({
createTeamOptions: {
teamGlobalSettings: {
create: {
documentVisibility: DocumentVisibility.MANAGER_AND_ABOVE,
},
},
},
});
const teamMember = await seedTeamMember({
teamId: team.id,
role: TeamMemberRole.MEMBER,
});
const document = await seedBlankDocument(teamMember, {
createDocumentOptions: {
teamId: team.id,
visibility: team.teamGlobalSettings?.documentVisibility,
},
});
await apiSignin({
page,
email: teamMember.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
});
await expect(page.getByTestId('documentVisibilitySelectValue')).toHaveText('Managers and above');
await expect(page.getByTestId('documentVisibilitySelectValue')).toBeDisabled();
});
test('[TEAMS]: check that MEMBER role cannot change visibility of ADMIN documents', async ({
page,
}) => {
const team = await seedTeam({
createTeamOptions: {
teamGlobalSettings: {
create: {
documentVisibility: DocumentVisibility.ADMIN,
},
},
},
});
const teamMember = await seedTeamMember({
teamId: team.id,
role: TeamMemberRole.MEMBER,
});
const document = await seedBlankDocument(teamMember, {
createDocumentOptions: {
teamId: team.id,
visibility: team.teamGlobalSettings?.documentVisibility,
},
});
await apiSignin({
page,
email: teamMember.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
});
await expect(page.getByTestId('documentVisibilitySelectValue')).toHaveText('Admins only');
await expect(page.getByTestId('documentVisibilitySelectValue')).toBeDisabled();
});
test('[TEAMS]: check that MANAGER role cannot change visibility of ADMIN documents', async ({
page,
}) => {
const team = await seedTeam({
createTeamOptions: {
teamGlobalSettings: {
create: {
documentVisibility: DocumentVisibility.ADMIN,
},
},
},
});
const teamManager = await seedTeamMember({
teamId: team.id,
role: TeamMemberRole.MANAGER,
});
const document = await seedBlankDocument(teamManager, {
createDocumentOptions: {
teamId: team.id,
visibility: team.teamGlobalSettings?.documentVisibility,
},
});
await apiSignin({
page,
email: teamManager.email,
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
});
await expect(page.getByTestId('documentVisibilitySelectValue')).toHaveText('Admins only');
await expect(page.getByTestId('documentVisibilitySelectValue')).toBeDisabled();
});
test('[TEAMS]: users cannot see documents from other teams', async ({ page }) => { test('[TEAMS]: users cannot see documents from other teams', async ({ page }) => {
// Seed two teams with documents // Seed two teams with documents
const { team: teamA, teamMember2: teamAMember } = await seedTeamDocuments(); const { team: teamA, teamMember2: teamAMember } = await seedTeamDocuments();

View File

@@ -21,6 +21,6 @@
"next-auth": "4.24.5", "next-auth": "4.24.5",
"react": "^18", "react": "^18",
"ts-pattern": "^5.0.5", "ts-pattern": "^5.0.5",
"zod": "^3.23.8" "zod": "3.24.1"
} }
} }

View File

@@ -1,8 +1,10 @@
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app'; import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
import { subscriptionsContainActiveEnterprisePlan } from '@documenso/lib/utils/billing'; import { subscriptionsContainsActivePlan } from '@documenso/lib/utils/billing';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import type { Subscription } from '@documenso/prisma/client'; import type { Subscription } from '@documenso/prisma/client';
import { getEnterprisePlanPriceIds } from '../stripe/get-enterprise-plan-prices';
export type IsUserEnterpriseOptions = { export type IsUserEnterpriseOptions = {
userId: number; userId: number;
teamId?: number; teamId?: number;
@@ -52,5 +54,11 @@ export const isUserEnterprise = async ({
.then((user) => user.Subscription); .then((user) => user.Subscription);
} }
return subscriptionsContainActiveEnterprisePlan(subscriptions); if (subscriptions.length === 0) {
return false;
}
const enterprisePlanPriceIds = await getEnterprisePlanPriceIds();
return subscriptionsContainsActivePlan(subscriptions, enterprisePlanPriceIds, true);
}; };

View File

@@ -0,0 +1,56 @@
import { Trans } from '@lingui/macro';
import { Column, Img, Section, Text } from '../components';
import { TemplateDocumentImage } from './template-document-image';
export interface TemplateDocumentRecipientSignedProps {
documentName: string;
recipientName: string;
recipientEmail: string;
assetBaseUrl: string;
}
export const TemplateDocumentRecipientSigned = ({
documentName,
recipientName,
recipientEmail,
assetBaseUrl,
}: TemplateDocumentRecipientSignedProps) => {
const getAssetUrl = (path: string) => {
return new URL(path, assetBaseUrl).toString();
};
const recipientReference = recipientName || recipientEmail;
return (
<>
<TemplateDocumentImage className="mt-6" assetBaseUrl={assetBaseUrl} />
<Section>
<Section className="mb-4">
<Column align="center">
<Text className="text-base font-semibold text-[#7AC455]">
<Img
src={getAssetUrl('/static/completed.png')}
className="-mt-0.5 mr-2 inline h-7 w-7 align-middle"
/>
<Trans>Completed</Trans>
</Text>
</Column>
</Section>
<Text className="text-primary mb-0 text-center text-lg font-semibold">
<Trans>
{recipientReference} has signed "{documentName}"
</Trans>
</Text>
<Text className="mx-auto mb-6 mt-1 max-w-[80%] text-center text-base text-slate-400">
<Trans>{recipientReference} has completed signing the document.</Trans>
</Text>
</Section>
</>
);
};
export default TemplateDocumentRecipientSigned;

View File

@@ -0,0 +1,70 @@
import { msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { Body, Container, Head, Html, Img, Preview, Section } from '../components';
import { useBranding } from '../providers/branding';
import { TemplateDocumentRecipientSigned } from '../template-components/template-document-recipient-signed';
import { TemplateFooter } from '../template-components/template-footer';
export interface DocumentRecipientSignedEmailTemplateProps {
documentName?: string;
recipientName?: string;
recipientEmail?: string;
assetBaseUrl?: string;
}
export const DocumentRecipientSignedEmailTemplate = ({
documentName = 'Open Source Pledge.pdf',
recipientName = 'John Doe',
recipientEmail = 'lucas@documenso.com',
assetBaseUrl = 'http://localhost:3002',
}: DocumentRecipientSignedEmailTemplateProps) => {
const { _ } = useLingui();
const branding = useBranding();
const recipientReference = recipientName || recipientEmail;
const previewText = msg`${recipientReference} has signed ${documentName}`;
const getAssetUrl = (path: string) => {
return new URL(path, assetBaseUrl).toString();
};
return (
<Html>
<Head />
<Preview>{_(previewText)}</Preview>
<Body className="mx-auto my-auto font-sans">
<Section className="bg-white">
<Container className="mx-auto mb-2 mt-8 max-w-xl rounded-lg border border-solid border-slate-200 p-2 backdrop-blur-sm">
<Section className="p-2">
{branding.brandingEnabled && branding.brandingLogo ? (
<Img src={branding.brandingLogo} alt="Branding Logo" className="mb-4 h-6" />
) : (
<Img
src={getAssetUrl('/static/logo.png')}
alt="Documenso Logo"
className="mb-4 h-6"
/>
)}
<TemplateDocumentRecipientSigned
documentName={documentName}
recipientName={recipientName}
recipientEmail={recipientEmail}
assetBaseUrl={assetBaseUrl}
/>
</Section>
</Container>
<Container className="mx-auto max-w-xl">
<TemplateFooter />
</Container>
</Section>
</Body>
</Html>
);
};
export default DocumentRecipientSignedEmailTemplate;

View File

@@ -12,7 +12,7 @@ export function useCopyShareLink({ onSuccess, onError }: UseCopyShareLinkOptions
const [, copyToClipboard] = useCopyToClipboard(); const [, copyToClipboard] = useCopyToClipboard();
const { mutateAsync: createOrGetShareLink, isLoading: isCreatingShareLink } = const { mutateAsync: createOrGetShareLink, isLoading: isCreatingShareLink } =
trpc.shareLink.createOrGetShareLink.useMutation(); trpc.document.createOrGetShareLink.useMutation();
/** /**
* Copy a newly created, or pre-existing share link to the user's clipboard. * Copy a newly created, or pre-existing share link to the user's clipboard.

View File

@@ -1,5 +1,6 @@
import { JobClient } from './client/client'; import { JobClient } from './client/client';
import { SEND_CONFIRMATION_EMAIL_JOB_DEFINITION } from './definitions/emails/send-confirmation-email'; import { SEND_CONFIRMATION_EMAIL_JOB_DEFINITION } from './definitions/emails/send-confirmation-email';
import { SEND_RECIPIENT_SIGNED_EMAIL_JOB_DEFINITION } from './definitions/emails/send-recipient-signed-email';
import { SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION } from './definitions/emails/send-rejection-emails'; import { SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION } from './definitions/emails/send-rejection-emails';
import { SEND_SIGNING_EMAIL_JOB_DEFINITION } from './definitions/emails/send-signing-email'; import { SEND_SIGNING_EMAIL_JOB_DEFINITION } from './definitions/emails/send-signing-email';
import { SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION } from './definitions/emails/send-team-deleted-email'; import { SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION } from './definitions/emails/send-team-deleted-email';
@@ -19,6 +20,7 @@ export const jobsClient = new JobClient([
SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION, SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION,
SEAL_DOCUMENT_JOB_DEFINITION, SEAL_DOCUMENT_JOB_DEFINITION,
SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION, SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION,
SEND_RECIPIENT_SIGNED_EMAIL_JOB_DEFINITION,
] as const); ] as const);
export const jobs = jobsClient; export const jobs = jobsClient;

View File

@@ -0,0 +1,9 @@
import { sendConfirmationToken } from '../../../server-only/user/send-confirmation-token';
import type { TSendConfirmationEmailJobDefinition } from './send-confirmation-email';
export const run = async ({ payload }: { payload: TSendConfirmationEmailJobDefinition }) => {
await sendConfirmationToken({
email: payload.email,
force: payload.force,
});
};

View File

@@ -1,6 +1,5 @@
import { z } from 'zod'; import { z } from 'zod';
import { sendConfirmationToken } from '../../../server-only/user/send-confirmation-token';
import type { JobDefinition } from '../../client/_internal/job'; import type { JobDefinition } from '../../client/_internal/job';
const SEND_CONFIRMATION_EMAIL_JOB_DEFINITION_ID = 'send.signup.confirmation.email'; const SEND_CONFIRMATION_EMAIL_JOB_DEFINITION_ID = 'send.signup.confirmation.email';
@@ -10,6 +9,10 @@ const SEND_CONFIRMATION_EMAIL_JOB_DEFINITION_SCHEMA = z.object({
force: z.boolean().optional(), force: z.boolean().optional(),
}); });
export type TSendConfirmationEmailJobDefinition = z.infer<
typeof SEND_CONFIRMATION_EMAIL_JOB_DEFINITION_SCHEMA
>;
export const SEND_CONFIRMATION_EMAIL_JOB_DEFINITION = { export const SEND_CONFIRMATION_EMAIL_JOB_DEFINITION = {
id: SEND_CONFIRMATION_EMAIL_JOB_DEFINITION_ID, id: SEND_CONFIRMATION_EMAIL_JOB_DEFINITION_ID,
name: 'Send Confirmation Email', name: 'Send Confirmation Email',
@@ -19,12 +22,11 @@ export const SEND_CONFIRMATION_EMAIL_JOB_DEFINITION = {
schema: SEND_CONFIRMATION_EMAIL_JOB_DEFINITION_SCHEMA, schema: SEND_CONFIRMATION_EMAIL_JOB_DEFINITION_SCHEMA,
}, },
handler: async ({ payload }) => { handler: async ({ payload }) => {
await sendConfirmationToken({ const handler = await import('./send-confirmation-email.handler');
email: payload.email,
force: payload.force, await handler.run({ payload });
});
}, },
} as const satisfies JobDefinition< } as const satisfies JobDefinition<
typeof SEND_CONFIRMATION_EMAIL_JOB_DEFINITION_ID, typeof SEND_CONFIRMATION_EMAIL_JOB_DEFINITION_ID,
z.infer<typeof SEND_CONFIRMATION_EMAIL_JOB_DEFINITION_SCHEMA> TSendConfirmationEmailJobDefinition
>; >;

View File

@@ -0,0 +1,130 @@
import { createElement } from 'react';
import { msg } from '@lingui/macro';
import { z } from 'zod';
import { mailer } from '@documenso/email/mailer';
import { DocumentRecipientSignedEmailTemplate } from '@documenso/email/templates/document-recipient-signed';
import { prisma } from '@documenso/prisma';
import { getI18nInstance } from '../../../client-only/providers/i18n.server';
import { NEXT_PUBLIC_WEBAPP_URL } from '../../../constants/app';
import { FROM_ADDRESS, FROM_NAME } from '../../../constants/email';
import { extractDerivedDocumentEmailSettings } from '../../../types/document-email';
import { renderEmailWithI18N } from '../../../utils/render-email-with-i18n';
import { teamGlobalSettingsToBranding } from '../../../utils/team-global-settings-to-branding';
import { type JobDefinition } from '../../client/_internal/job';
const SEND_RECIPIENT_SIGNED_EMAIL_JOB_DEFINITION_ID = 'send.recipient.signed.email';
const SEND_RECIPIENT_SIGNED_EMAIL_JOB_DEFINITION_SCHEMA = z.object({
documentId: z.number(),
recipientId: z.number(),
});
export const SEND_RECIPIENT_SIGNED_EMAIL_JOB_DEFINITION = {
id: SEND_RECIPIENT_SIGNED_EMAIL_JOB_DEFINITION_ID,
name: 'Send Recipient Signed Email',
version: '1.0.0',
trigger: {
name: SEND_RECIPIENT_SIGNED_EMAIL_JOB_DEFINITION_ID,
schema: SEND_RECIPIENT_SIGNED_EMAIL_JOB_DEFINITION_SCHEMA,
},
handler: async ({ payload, io }) => {
const { documentId, recipientId } = payload;
const document = await prisma.document.findFirst({
where: {
id: documentId,
Recipient: {
some: {
id: recipientId,
},
},
},
include: {
Recipient: {
where: {
id: recipientId,
},
},
User: true,
documentMeta: true,
team: {
include: {
teamGlobalSettings: true,
},
},
},
});
if (!document) {
throw new Error('Document not found');
}
if (document.Recipient.length === 0) {
throw new Error('Document has no recipients');
}
const isRecipientSignedEmailEnabled = extractDerivedDocumentEmailSettings(
document.documentMeta,
).recipientSigned;
if (!isRecipientSignedEmailEnabled) {
return;
}
const [recipient] = document.Recipient;
const { email: recipientEmail, name: recipientName } = recipient;
const { User: owner } = document;
const recipientReference = recipientName || recipientEmail;
// Don't send notification if the owner is the one who signed
if (owner.email === recipientEmail) {
return;
}
const assetBaseUrl = NEXT_PUBLIC_WEBAPP_URL() || 'http://localhost:3000';
const i18n = await getI18nInstance(document.documentMeta?.language);
const template = createElement(DocumentRecipientSignedEmailTemplate, {
documentName: document.title,
recipientName,
recipientEmail,
assetBaseUrl,
});
await io.runTask('send-recipient-signed-email', async () => {
const branding = document.team?.teamGlobalSettings
? teamGlobalSettingsToBranding(document.team.teamGlobalSettings)
: undefined;
const [html, text] = await Promise.all([
renderEmailWithI18N(template, { lang: document.documentMeta?.language, branding }),
renderEmailWithI18N(template, {
lang: document.documentMeta?.language,
branding,
plainText: true,
}),
]);
await mailer.sendMail({
to: {
name: owner.name ?? '',
address: owner.email,
},
from: {
name: FROM_NAME,
address: FROM_ADDRESS,
},
subject: i18n._(msg`${recipientReference} has signed "${document.title}"`),
html,
text,
});
});
},
} as const satisfies JobDefinition<
typeof SEND_RECIPIENT_SIGNED_EMAIL_JOB_DEFINITION_ID,
z.infer<typeof SEND_RECIPIENT_SIGNED_EMAIL_JOB_DEFINITION_SCHEMA>
>;

View File

@@ -0,0 +1,156 @@
import { createElement } from 'react';
import { msg } from '@lingui/macro';
import { mailer } from '@documenso/email/mailer';
import DocumentRejectedEmail from '@documenso/email/templates/document-rejected';
import DocumentRejectionConfirmedEmail from '@documenso/email/templates/document-rejection-confirmed';
import { prisma } from '@documenso/prisma';
import { SendStatus, SigningStatus } from '@documenso/prisma/client';
import { getI18nInstance } from '../../../client-only/providers/i18n.server';
import { NEXT_PUBLIC_WEBAPP_URL } from '../../../constants/app';
import { FROM_ADDRESS, FROM_NAME } from '../../../constants/email';
import { extractDerivedDocumentEmailSettings } from '../../../types/document-email';
import { renderEmailWithI18N } from '../../../utils/render-email-with-i18n';
import { teamGlobalSettingsToBranding } from '../../../utils/team-global-settings-to-branding';
import { formatDocumentsPath } from '../../../utils/teams';
import type { JobRunIO } from '../../client/_internal/job';
import type { TSendSigningRejectionEmailsJobDefinition } from './send-rejection-emails';
export const run = async ({
payload,
io,
}: {
payload: TSendSigningRejectionEmailsJobDefinition;
io: JobRunIO;
}) => {
const { documentId, recipientId } = payload;
const [document, recipient] = await Promise.all([
prisma.document.findFirstOrThrow({
where: {
id: documentId,
},
include: {
User: true,
documentMeta: true,
team: {
select: {
teamEmail: true,
name: true,
url: true,
teamGlobalSettings: true,
},
},
},
}),
prisma.recipient.findFirstOrThrow({
where: {
id: recipientId,
signingStatus: SigningStatus.REJECTED,
},
}),
]);
const { documentMeta, team, User: documentOwner } = document;
const isEmailEnabled = extractDerivedDocumentEmailSettings(
document.documentMeta,
).recipientSigningRequest;
if (!isEmailEnabled) {
return;
}
const i18n = await getI18nInstance(documentMeta?.language);
// Send confirmation email to the recipient who rejected
await io.runTask('send-rejection-confirmation-email', async () => {
const recipientTemplate = createElement(DocumentRejectionConfirmedEmail, {
recipientName: recipient.name,
documentName: document.title,
documentOwnerName: document.User.name || document.User.email,
reason: recipient.rejectionReason || '',
assetBaseUrl: NEXT_PUBLIC_WEBAPP_URL(),
});
const branding = document.team?.teamGlobalSettings
? teamGlobalSettingsToBranding(document.team.teamGlobalSettings)
: undefined;
const [html, text] = await Promise.all([
renderEmailWithI18N(recipientTemplate, { lang: documentMeta?.language, branding }),
renderEmailWithI18N(recipientTemplate, {
lang: documentMeta?.language,
branding,
plainText: true,
}),
]);
await mailer.sendMail({
to: {
name: recipient.name,
address: recipient.email,
},
from: {
name: FROM_NAME,
address: FROM_ADDRESS,
},
subject: i18n._(msg`Document "${document.title}" - Rejection Confirmed`),
html,
text,
});
});
// Send notification email to document owner
await io.runTask('send-owner-notification-email', async () => {
const ownerTemplate = createElement(DocumentRejectedEmail, {
recipientName: recipient.name,
documentName: document.title,
documentUrl: `${NEXT_PUBLIC_WEBAPP_URL()}${formatDocumentsPath(document.team?.url)}/${
document.id
}`,
rejectionReason: recipient.rejectionReason || '',
assetBaseUrl: NEXT_PUBLIC_WEBAPP_URL(),
});
const branding = document.team?.teamGlobalSettings
? teamGlobalSettingsToBranding(document.team.teamGlobalSettings)
: undefined;
const [html, text] = await Promise.all([
renderEmailWithI18N(ownerTemplate, { lang: documentMeta?.language, branding }),
renderEmailWithI18N(ownerTemplate, {
lang: documentMeta?.language,
branding,
plainText: true,
}),
]);
await mailer.sendMail({
to: {
name: documentOwner.name || '',
address: documentOwner.email,
},
from: {
name: FROM_NAME,
address: FROM_ADDRESS,
},
subject: i18n._(msg`Document "${document.title}" - Rejected by ${recipient.name}`),
html,
text,
});
});
await io.runTask('update-recipient', async () => {
await prisma.recipient.update({
where: {
id: recipient.id,
},
data: {
sendStatus: SendStatus.SENT,
},
});
});
};

View File

@@ -1,21 +1,5 @@
import { createElement } from 'react';
import { msg } from '@lingui/macro';
import { z } from 'zod'; import { z } from 'zod';
import { mailer } from '@documenso/email/mailer';
import DocumentRejectedEmail from '@documenso/email/templates/document-rejected';
import DocumentRejectionConfirmedEmail from '@documenso/email/templates/document-rejection-confirmed';
import { prisma } from '@documenso/prisma';
import { SendStatus, SigningStatus } from '@documenso/prisma/client';
import { getI18nInstance } from '../../../client-only/providers/i18n.server';
import { NEXT_PUBLIC_WEBAPP_URL } from '../../../constants/app';
import { FROM_ADDRESS, FROM_NAME } from '../../../constants/email';
import { extractDerivedDocumentEmailSettings } from '../../../types/document-email';
import { renderEmailWithI18N } from '../../../utils/render-email-with-i18n';
import { teamGlobalSettingsToBranding } from '../../../utils/team-global-settings-to-branding';
import { formatDocumentsPath } from '../../../utils/teams';
import { type JobDefinition } from '../../client/_internal/job'; import { type JobDefinition } from '../../client/_internal/job';
const SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION_ID = 'send.signing.rejected.emails'; const SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION_ID = 'send.signing.rejected.emails';
@@ -25,6 +9,10 @@ const SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION_SCHEMA = z.object({
recipientId: z.number(), recipientId: z.number(),
}); });
export type TSendSigningRejectionEmailsJobDefinition = z.infer<
typeof SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION_SCHEMA
>;
export const SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION = { export const SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION = {
id: SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION_ID, id: SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION_ID,
name: 'Send Rejection Emails', name: 'Send Rejection Emails',
@@ -34,136 +22,11 @@ export const SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION = {
schema: SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION_SCHEMA, schema: SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION_SCHEMA,
}, },
handler: async ({ payload, io }) => { handler: async ({ payload, io }) => {
const { documentId, recipientId } = payload; const handler = await import('./send-rejection-emails.handler');
const [document, recipient] = await Promise.all([ await handler.run({ payload, io });
prisma.document.findFirstOrThrow({
where: {
id: documentId,
},
include: {
User: true,
documentMeta: true,
team: {
select: {
teamEmail: true,
name: true,
url: true,
teamGlobalSettings: true,
},
},
},
}),
prisma.recipient.findFirstOrThrow({
where: {
id: recipientId,
signingStatus: SigningStatus.REJECTED,
},
}),
]);
const { documentMeta, team, User: documentOwner } = document;
const isEmailEnabled = extractDerivedDocumentEmailSettings(
document.documentMeta,
).recipientSigningRequest;
if (!isEmailEnabled) {
return;
}
const i18n = await getI18nInstance(documentMeta?.language);
// Send confirmation email to the recipient who rejected
await io.runTask('send-rejection-confirmation-email', async () => {
const recipientTemplate = createElement(DocumentRejectionConfirmedEmail, {
recipientName: recipient.name,
documentName: document.title,
documentOwnerName: document.User.name || document.User.email,
reason: recipient.rejectionReason || '',
assetBaseUrl: NEXT_PUBLIC_WEBAPP_URL(),
});
const branding = document.team?.teamGlobalSettings
? teamGlobalSettingsToBranding(document.team.teamGlobalSettings)
: undefined;
const [html, text] = await Promise.all([
renderEmailWithI18N(recipientTemplate, { lang: documentMeta?.language, branding }),
renderEmailWithI18N(recipientTemplate, {
lang: documentMeta?.language,
branding,
plainText: true,
}),
]);
await mailer.sendMail({
to: {
name: recipient.name,
address: recipient.email,
},
from: {
name: FROM_NAME,
address: FROM_ADDRESS,
},
subject: i18n._(msg`Document "${document.title}" - Rejection Confirmed`),
html,
text,
});
});
// Send notification email to document owner
await io.runTask('send-owner-notification-email', async () => {
const ownerTemplate = createElement(DocumentRejectedEmail, {
recipientName: recipient.name,
documentName: document.title,
documentUrl: `${NEXT_PUBLIC_WEBAPP_URL()}${formatDocumentsPath(document.team?.url)}/${
document.id
}`,
rejectionReason: recipient.rejectionReason || '',
assetBaseUrl: NEXT_PUBLIC_WEBAPP_URL(),
});
const branding = document.team?.teamGlobalSettings
? teamGlobalSettingsToBranding(document.team.teamGlobalSettings)
: undefined;
const [html, text] = await Promise.all([
renderEmailWithI18N(ownerTemplate, { lang: documentMeta?.language, branding }),
renderEmailWithI18N(ownerTemplate, {
lang: documentMeta?.language,
branding,
plainText: true,
}),
]);
await mailer.sendMail({
to: {
name: documentOwner.name || '',
address: documentOwner.email,
},
from: {
name: FROM_NAME,
address: FROM_ADDRESS,
},
subject: i18n._(msg`Document "${document.title}" - Rejected by ${recipient.name}`),
html,
text,
});
});
await io.runTask('update-recipient', async () => {
await prisma.recipient.update({
where: {
id: recipient.id,
},
data: {
sendStatus: SendStatus.SENT,
},
});
});
}, },
} as const satisfies JobDefinition< } as const satisfies JobDefinition<
typeof SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION_ID, typeof SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION_ID,
z.infer<typeof SEND_SIGNING_REJECTION_EMAILS_JOB_DEFINITION_SCHEMA> TSendSigningRejectionEmailsJobDefinition
>; >;

View File

@@ -0,0 +1,215 @@
import { createElement } from 'react';
import { msg } from '@lingui/macro';
import { mailer } from '@documenso/email/mailer';
import DocumentInviteEmailTemplate from '@documenso/email/templates/document-invite';
import { prisma } from '@documenso/prisma';
import {
DocumentSource,
DocumentStatus,
RecipientRole,
SendStatus,
} from '@documenso/prisma/client';
import { getI18nInstance } from '../../../client-only/providers/i18n.server';
import { NEXT_PUBLIC_WEBAPP_URL } from '../../../constants/app';
import { FROM_ADDRESS, FROM_NAME } from '../../../constants/email';
import {
RECIPIENT_ROLES_DESCRIPTION,
RECIPIENT_ROLE_TO_EMAIL_TYPE,
} from '../../../constants/recipient-roles';
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../../types/document-audit-logs';
import { extractDerivedDocumentEmailSettings } from '../../../types/document-email';
import { createDocumentAuditLogData } from '../../../utils/document-audit-logs';
import { renderCustomEmailTemplate } from '../../../utils/render-custom-email-template';
import { renderEmailWithI18N } from '../../../utils/render-email-with-i18n';
import { teamGlobalSettingsToBranding } from '../../../utils/team-global-settings-to-branding';
import type { JobRunIO } from '../../client/_internal/job';
import type { TSendSigningEmailJobDefinition } from './send-signing-email';
export const run = async ({
payload,
io,
}: {
payload: TSendSigningEmailJobDefinition;
io: JobRunIO;
}) => {
const { userId, documentId, recipientId, requestMetadata } = payload;
const [user, document, recipient] = await Promise.all([
prisma.user.findFirstOrThrow({
where: {
id: userId,
},
}),
prisma.document.findFirstOrThrow({
where: {
id: documentId,
status: DocumentStatus.PENDING,
},
include: {
documentMeta: true,
team: {
select: {
teamEmail: true,
name: true,
teamGlobalSettings: true,
},
},
},
}),
prisma.recipient.findFirstOrThrow({
where: {
id: recipientId,
},
}),
]);
const { documentMeta, team } = document;
if (recipient.role === RecipientRole.CC) {
return;
}
const isRecipientSigningRequestEmailEnabled = extractDerivedDocumentEmailSettings(
document.documentMeta,
).recipientSigningRequest;
if (!isRecipientSigningRequestEmailEnabled) {
return;
}
const customEmail = document?.documentMeta;
const isDirectTemplate = document.source === DocumentSource.TEMPLATE_DIRECT_LINK;
const isTeamDocument = document.teamId !== null;
const recipientEmailType = RECIPIENT_ROLE_TO_EMAIL_TYPE[recipient.role];
const { email, name } = recipient;
const selfSigner = email === user.email;
const i18n = await getI18nInstance(documentMeta?.language);
const recipientActionVerb = i18n
._(RECIPIENT_ROLES_DESCRIPTION[recipient.role].actionVerb)
.toLowerCase();
let emailMessage = customEmail?.message || '';
let emailSubject = i18n._(msg`Please ${recipientActionVerb} this document`);
if (selfSigner) {
emailMessage = i18n._(
msg`You have initiated the document ${`"${document.title}"`} that requires you to ${recipientActionVerb} it.`,
);
emailSubject = i18n._(msg`Please ${recipientActionVerb} your document`);
}
if (isDirectTemplate) {
emailMessage = i18n._(
msg`A document was created by your direct template that requires you to ${recipientActionVerb} it.`,
);
emailSubject = i18n._(
msg`Please ${recipientActionVerb} this document created by your direct template`,
);
}
if (isTeamDocument && team) {
emailSubject = i18n._(msg`${team.name} invited you to ${recipientActionVerb} a document`);
emailMessage = customEmail?.message ?? '';
if (!emailMessage) {
emailMessage = i18n._(
team.teamGlobalSettings?.includeSenderDetails
? msg`${user.name} on behalf of "${team.name}" has invited you to ${recipientActionVerb} the document "${document.title}".`
: msg`${team.name} has invited you to ${recipientActionVerb} the document "${document.title}".`,
);
}
}
const customEmailTemplate = {
'signer.name': name,
'signer.email': email,
'document.name': document.title,
};
const assetBaseUrl = NEXT_PUBLIC_WEBAPP_URL() || 'http://localhost:3000';
const signDocumentLink = `${NEXT_PUBLIC_WEBAPP_URL()}/sign/${recipient.token}`;
const template = createElement(DocumentInviteEmailTemplate, {
documentName: document.title,
inviterName: user.name || undefined,
inviterEmail: isTeamDocument ? team?.teamEmail?.email || user.email : user.email,
assetBaseUrl,
signDocumentLink,
customBody: renderCustomEmailTemplate(emailMessage, customEmailTemplate),
role: recipient.role,
selfSigner,
isTeamInvite: isTeamDocument,
teamName: team?.name,
teamEmail: team?.teamEmail?.email,
includeSenderDetails: team?.teamGlobalSettings?.includeSenderDetails,
});
await io.runTask('send-signing-email', async () => {
const branding = document.team?.teamGlobalSettings
? teamGlobalSettingsToBranding(document.team.teamGlobalSettings)
: undefined;
const [html, text] = await Promise.all([
renderEmailWithI18N(template, { lang: documentMeta?.language, branding }),
renderEmailWithI18N(template, {
lang: documentMeta?.language,
branding,
plainText: true,
}),
]);
await mailer.sendMail({
to: {
name: recipient.name,
address: recipient.email,
},
from: {
name: FROM_NAME,
address: FROM_ADDRESS,
},
subject: renderCustomEmailTemplate(
documentMeta?.subject || emailSubject,
customEmailTemplate,
),
html,
text,
});
});
await io.runTask('update-recipient', async () => {
await prisma.recipient.update({
where: {
id: recipient.id,
},
data: {
sendStatus: SendStatus.SENT,
},
});
});
await io.runTask('store-audit-log', async () => {
await prisma.documentAuditLog.create({
data: createDocumentAuditLogData({
type: DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT,
documentId: document.id,
user,
requestMetadata,
data: {
emailType: recipientEmailType,
recipientId: recipient.id,
recipientName: recipient.name,
recipientEmail: recipient.email,
recipientRole: recipient.role,
isResending: false,
},
}),
});
});
};

View File

@@ -1,32 +1,6 @@
import { createElement } from 'react';
import { msg } from '@lingui/macro';
import { z } from 'zod'; import { z } from 'zod';
import { mailer } from '@documenso/email/mailer';
import DocumentInviteEmailTemplate from '@documenso/email/templates/document-invite';
import { prisma } from '@documenso/prisma';
import {
DocumentSource,
DocumentStatus,
RecipientRole,
SendStatus,
} from '@documenso/prisma/client';
import { getI18nInstance } from '../../../client-only/providers/i18n.server';
import { NEXT_PUBLIC_WEBAPP_URL } from '../../../constants/app';
import { FROM_ADDRESS, FROM_NAME } from '../../../constants/email';
import {
RECIPIENT_ROLES_DESCRIPTION,
RECIPIENT_ROLE_TO_EMAIL_TYPE,
} from '../../../constants/recipient-roles';
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../../types/document-audit-logs';
import { extractDerivedDocumentEmailSettings } from '../../../types/document-email';
import { ZRequestMetadataSchema } from '../../../universal/extract-request-metadata'; import { ZRequestMetadataSchema } from '../../../universal/extract-request-metadata';
import { createDocumentAuditLogData } from '../../../utils/document-audit-logs';
import { renderCustomEmailTemplate } from '../../../utils/render-custom-email-template';
import { renderEmailWithI18N } from '../../../utils/render-email-with-i18n';
import { teamGlobalSettingsToBranding } from '../../../utils/team-global-settings-to-branding';
import { type JobDefinition } from '../../client/_internal/job'; import { type JobDefinition } from '../../client/_internal/job';
const SEND_SIGNING_EMAIL_JOB_DEFINITION_ID = 'send.signing.requested.email'; const SEND_SIGNING_EMAIL_JOB_DEFINITION_ID = 'send.signing.requested.email';
@@ -38,6 +12,10 @@ const SEND_SIGNING_EMAIL_JOB_DEFINITION_SCHEMA = z.object({
requestMetadata: ZRequestMetadataSchema.optional(), requestMetadata: ZRequestMetadataSchema.optional(),
}); });
export type TSendSigningEmailJobDefinition = z.infer<
typeof SEND_SIGNING_EMAIL_JOB_DEFINITION_SCHEMA
>;
export const SEND_SIGNING_EMAIL_JOB_DEFINITION = { export const SEND_SIGNING_EMAIL_JOB_DEFINITION = {
id: SEND_SIGNING_EMAIL_JOB_DEFINITION_ID, id: SEND_SIGNING_EMAIL_JOB_DEFINITION_ID,
name: 'Send Signing Email', name: 'Send Signing Email',
@@ -47,185 +25,11 @@ export const SEND_SIGNING_EMAIL_JOB_DEFINITION = {
schema: SEND_SIGNING_EMAIL_JOB_DEFINITION_SCHEMA, schema: SEND_SIGNING_EMAIL_JOB_DEFINITION_SCHEMA,
}, },
handler: async ({ payload, io }) => { handler: async ({ payload, io }) => {
const { userId, documentId, recipientId, requestMetadata } = payload; const handler = await import('./send-signing-email.handler');
const [user, document, recipient] = await Promise.all([ await handler.run({ payload, io });
prisma.user.findFirstOrThrow({
where: {
id: userId,
},
}),
prisma.document.findFirstOrThrow({
where: {
id: documentId,
status: DocumentStatus.PENDING,
},
include: {
documentMeta: true,
team: {
select: {
teamEmail: true,
name: true,
teamGlobalSettings: true,
},
},
},
}),
prisma.recipient.findFirstOrThrow({
where: {
id: recipientId,
},
}),
]);
const { documentMeta, team } = document;
if (recipient.role === RecipientRole.CC) {
return;
}
const isRecipientSigningRequestEmailEnabled = extractDerivedDocumentEmailSettings(
document.documentMeta,
).recipientSigningRequest;
if (!isRecipientSigningRequestEmailEnabled) {
return;
}
const customEmail = document?.documentMeta;
const isDirectTemplate = document.source === DocumentSource.TEMPLATE_DIRECT_LINK;
const isTeamDocument = document.teamId !== null;
const recipientEmailType = RECIPIENT_ROLE_TO_EMAIL_TYPE[recipient.role];
const { email, name } = recipient;
const selfSigner = email === user.email;
const i18n = await getI18nInstance(documentMeta?.language);
const recipientActionVerb = i18n
._(RECIPIENT_ROLES_DESCRIPTION[recipient.role].actionVerb)
.toLowerCase();
let emailMessage = customEmail?.message || '';
let emailSubject = i18n._(msg`Please ${recipientActionVerb} this document`);
if (selfSigner) {
emailMessage = i18n._(
msg`You have initiated the document ${`"${document.title}"`} that requires you to ${recipientActionVerb} it.`,
);
emailSubject = i18n._(msg`Please ${recipientActionVerb} your document`);
}
if (isDirectTemplate) {
emailMessage = i18n._(
msg`A document was created by your direct template that requires you to ${recipientActionVerb} it.`,
);
emailSubject = i18n._(
msg`Please ${recipientActionVerb} this document created by your direct template`,
);
}
if (isTeamDocument && team) {
emailSubject = i18n._(msg`${team.name} invited you to ${recipientActionVerb} a document`);
emailMessage = customEmail?.message ?? '';
if (!emailMessage) {
emailMessage = i18n._(
team.teamGlobalSettings?.includeSenderDetails
? msg`${user.name} on behalf of "${team.name}" has invited you to ${recipientActionVerb} the document "${document.title}".`
: msg`${team.name} has invited you to ${recipientActionVerb} the document "${document.title}".`,
);
}
}
const customEmailTemplate = {
'signer.name': name,
'signer.email': email,
'document.name': document.title,
};
const assetBaseUrl = NEXT_PUBLIC_WEBAPP_URL() || 'http://localhost:3000';
const signDocumentLink = `${NEXT_PUBLIC_WEBAPP_URL()}/sign/${recipient.token}`;
const template = createElement(DocumentInviteEmailTemplate, {
documentName: document.title,
inviterName: user.name || undefined,
inviterEmail: isTeamDocument ? team?.teamEmail?.email || user.email : user.email,
assetBaseUrl,
signDocumentLink,
customBody: renderCustomEmailTemplate(emailMessage, customEmailTemplate),
role: recipient.role,
selfSigner,
isTeamInvite: isTeamDocument,
teamName: team?.name,
teamEmail: team?.teamEmail?.email,
includeSenderDetails: team?.teamGlobalSettings?.includeSenderDetails,
});
await io.runTask('send-signing-email', async () => {
const branding = document.team?.teamGlobalSettings
? teamGlobalSettingsToBranding(document.team.teamGlobalSettings)
: undefined;
const [html, text] = await Promise.all([
renderEmailWithI18N(template, { lang: documentMeta?.language, branding }),
renderEmailWithI18N(template, {
lang: documentMeta?.language,
branding,
plainText: true,
}),
]);
await mailer.sendMail({
to: {
name: recipient.name,
address: recipient.email,
},
from: {
name: FROM_NAME,
address: FROM_ADDRESS,
},
subject: renderCustomEmailTemplate(
documentMeta?.subject || emailSubject,
customEmailTemplate,
),
html,
text,
});
});
await io.runTask('update-recipient', async () => {
await prisma.recipient.update({
where: {
id: recipient.id,
},
data: {
sendStatus: SendStatus.SENT,
},
});
});
await io.runTask('store-audit-log', async () => {
await prisma.documentAuditLog.create({
data: createDocumentAuditLogData({
type: DOCUMENT_AUDIT_LOG_TYPE.EMAIL_SENT,
documentId: document.id,
user,
requestMetadata,
data: {
emailType: recipientEmailType,
recipientId: recipient.id,
recipientName: recipient.name,
recipientEmail: recipient.email,
recipientRole: recipient.role,
isResending: false,
},
}),
});
});
}, },
} as const satisfies JobDefinition< } as const satisfies JobDefinition<
typeof SEND_SIGNING_EMAIL_JOB_DEFINITION_ID, typeof SEND_SIGNING_EMAIL_JOB_DEFINITION_ID,
z.infer<typeof SEND_SIGNING_EMAIL_JOB_DEFINITION_SCHEMA> TSendSigningEmailJobDefinition
>; >;

View File

@@ -0,0 +1,23 @@
import { sendTeamDeleteEmail } from '../../../server-only/team/delete-team';
import type { JobRunIO } from '../../client/_internal/job';
import type { TSendTeamDeletedEmailJobDefinition } from './send-team-deleted-email';
export const run = async ({
payload,
io,
}: {
payload: TSendTeamDeletedEmailJobDefinition;
io: JobRunIO;
}) => {
const { team, members } = payload;
for (const member of members) {
await io.runTask(`send-team-deleted-email--${team.url}_${member.id}`, async () => {
await sendTeamDeleteEmail({
email: member.email,
team,
isOwner: member.id === team.ownerUserId,
});
});
}
};

View File

@@ -2,7 +2,6 @@ import { z } from 'zod';
import { DocumentVisibility } from '@documenso/prisma/client'; import { DocumentVisibility } from '@documenso/prisma/client';
import { sendTeamDeleteEmail } from '../../../server-only/team/delete-team';
import type { JobDefinition } from '../../client/_internal/job'; import type { JobDefinition } from '../../client/_internal/job';
const SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION_ID = 'send.team-deleted.email'; const SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION_ID = 'send.team-deleted.email';
@@ -37,6 +36,10 @@ const SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION_SCHEMA = z.object({
), ),
}); });
export type TSendTeamDeletedEmailJobDefinition = z.infer<
typeof SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION_SCHEMA
>;
export const SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION = { export const SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION = {
id: SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION_ID, id: SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION_ID,
name: 'Send Team Deleted Email', name: 'Send Team Deleted Email',
@@ -46,19 +49,11 @@ export const SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION = {
schema: SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION_SCHEMA, schema: SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION_SCHEMA,
}, },
handler: async ({ payload, io }) => { handler: async ({ payload, io }) => {
const { team, members } = payload; const handler = await import('./send-team-deleted-email.handler');
for (const member of members) { await handler.run({ payload, io });
await io.runTask(`send-team-deleted-email--${team.url}_${member.id}`, async () => {
await sendTeamDeleteEmail({
email: member.email,
team,
isOwner: member.id === team.ownerUserId,
});
});
}
}, },
} as const satisfies JobDefinition< } as const satisfies JobDefinition<
typeof SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION_ID, typeof SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION_ID,
z.infer<typeof SEND_TEAM_DELETED_EMAIL_JOB_DEFINITION_SCHEMA> TSendTeamDeletedEmailJobDefinition
>; >;

View File

@@ -0,0 +1,105 @@
import { createElement } from 'react';
import { msg } from '@lingui/macro';
import { mailer } from '@documenso/email/mailer';
import TeamJoinEmailTemplate from '@documenso/email/templates/team-join';
import { prisma } from '@documenso/prisma';
import { TeamMemberRole } from '@documenso/prisma/client';
import { getI18nInstance } from '../../../client-only/providers/i18n.server';
import { WEBAPP_BASE_URL } from '../../../constants/app';
import { FROM_ADDRESS, FROM_NAME } from '../../../constants/email';
import { renderEmailWithI18N } from '../../../utils/render-email-with-i18n';
import { teamGlobalSettingsToBranding } from '../../../utils/team-global-settings-to-branding';
import type { JobRunIO } from '../../client/_internal/job';
import type { TSendTeamMemberJoinedEmailJobDefinition } from './send-team-member-joined-email';
export const run = async ({
payload,
io,
}: {
payload: TSendTeamMemberJoinedEmailJobDefinition;
io: JobRunIO;
}) => {
const team = await prisma.team.findFirstOrThrow({
where: {
id: payload.teamId,
},
include: {
members: {
where: {
role: {
in: [TeamMemberRole.ADMIN, TeamMemberRole.MANAGER],
},
},
include: {
user: true,
},
},
teamGlobalSettings: true,
},
});
const invitedMember = await prisma.teamMember.findFirstOrThrow({
where: {
id: payload.memberId,
teamId: payload.teamId,
},
include: {
user: true,
},
});
for (const member of team.members) {
if (member.id === invitedMember.id) {
continue;
}
await io.runTask(
`send-team-member-joined-email--${invitedMember.id}_${member.id}`,
async () => {
const emailContent = createElement(TeamJoinEmailTemplate, {
assetBaseUrl: WEBAPP_BASE_URL,
baseUrl: WEBAPP_BASE_URL,
memberName: invitedMember.user.name || '',
memberEmail: invitedMember.user.email,
teamName: team.name,
teamUrl: team.url,
});
const branding = team.teamGlobalSettings
? teamGlobalSettingsToBranding(team.teamGlobalSettings)
: undefined;
const lang = team.teamGlobalSettings?.documentLanguage;
// !: Replace with the actual language of the recipient later
const [html, text] = await Promise.all([
renderEmailWithI18N(emailContent, {
lang,
branding,
}),
renderEmailWithI18N(emailContent, {
lang,
branding,
plainText: true,
}),
]);
const i18n = await getI18nInstance(lang);
await mailer.sendMail({
to: member.user.email,
from: {
name: FROM_NAME,
address: FROM_ADDRESS,
},
subject: i18n._(msg`A new member has joined your team`),
html,
text,
});
},
);
}
};

View File

@@ -1,18 +1,5 @@
import { createElement } from 'react';
import { msg } from '@lingui/macro';
import { z } from 'zod'; import { z } from 'zod';
import { mailer } from '@documenso/email/mailer';
import TeamJoinEmailTemplate from '@documenso/email/templates/team-join';
import { prisma } from '@documenso/prisma';
import { TeamMemberRole } from '@documenso/prisma/client';
import { getI18nInstance } from '../../../client-only/providers/i18n.server';
import { WEBAPP_BASE_URL } from '../../../constants/app';
import { FROM_ADDRESS, FROM_NAME } from '../../../constants/email';
import { renderEmailWithI18N } from '../../../utils/render-email-with-i18n';
import { teamGlobalSettingsToBranding } from '../../../utils/team-global-settings-to-branding';
import type { JobDefinition } from '../../client/_internal/job'; import type { JobDefinition } from '../../client/_internal/job';
const SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION_ID = 'send.team-member-joined.email'; const SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION_ID = 'send.team-member-joined.email';
@@ -22,6 +9,10 @@ const SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION_SCHEMA = z.object({
memberId: z.number(), memberId: z.number(),
}); });
export type TSendTeamMemberJoinedEmailJobDefinition = z.infer<
typeof SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION_SCHEMA
>;
export const SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION = { export const SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION = {
id: SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION_ID, id: SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION_ID,
name: 'Send Team Member Joined Email', name: 'Send Team Member Joined Email',
@@ -31,88 +22,11 @@ export const SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION = {
schema: SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION_SCHEMA, schema: SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION_SCHEMA,
}, },
handler: async ({ payload, io }) => { handler: async ({ payload, io }) => {
const team = await prisma.team.findFirstOrThrow({ const handler = await import('./send-team-member-joined-email.handler');
where: {
id: payload.teamId,
},
include: {
members: {
where: {
role: {
in: [TeamMemberRole.ADMIN, TeamMemberRole.MANAGER],
},
},
include: {
user: true,
},
},
teamGlobalSettings: true,
},
});
const invitedMember = await prisma.teamMember.findFirstOrThrow({ await handler.run({ payload, io });
where: {
id: payload.memberId,
teamId: payload.teamId,
},
include: {
user: true,
},
});
for (const member of team.members) {
if (member.id === invitedMember.id) {
continue;
}
await io.runTask(
`send-team-member-joined-email--${invitedMember.id}_${member.id}`,
async () => {
const emailContent = createElement(TeamJoinEmailTemplate, {
assetBaseUrl: WEBAPP_BASE_URL,
baseUrl: WEBAPP_BASE_URL,
memberName: invitedMember.user.name || '',
memberEmail: invitedMember.user.email,
teamName: team.name,
teamUrl: team.url,
});
const branding = team.teamGlobalSettings
? teamGlobalSettingsToBranding(team.teamGlobalSettings)
: undefined;
const lang = team.teamGlobalSettings?.documentLanguage;
// !: Replace with the actual language of the recipient later
const [html, text] = await Promise.all([
renderEmailWithI18N(emailContent, {
lang,
branding,
}),
renderEmailWithI18N(emailContent, {
lang,
branding,
plainText: true,
}),
]);
const i18n = await getI18nInstance(lang);
await mailer.sendMail({
to: member.user.email,
from: {
name: FROM_NAME,
address: FROM_ADDRESS,
},
subject: i18n._(msg`A new member has joined your team`),
html,
text,
});
},
);
}
}, },
} as const satisfies JobDefinition< } as const satisfies JobDefinition<
typeof SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION_ID, typeof SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION_ID,
z.infer<typeof SEND_TEAM_MEMBER_JOINED_EMAIL_JOB_DEFINITION_SCHEMA> TSendTeamMemberJoinedEmailJobDefinition
>; >;

View File

@@ -0,0 +1,93 @@
import { createElement } from 'react';
import { msg } from '@lingui/macro';
import { mailer } from '@documenso/email/mailer';
import TeamJoinEmailTemplate from '@documenso/email/templates/team-join';
import { prisma } from '@documenso/prisma';
import { TeamMemberRole } from '@documenso/prisma/client';
import { getI18nInstance } from '../../../client-only/providers/i18n.server';
import { WEBAPP_BASE_URL } from '../../../constants/app';
import { FROM_ADDRESS, FROM_NAME } from '../../../constants/email';
import { renderEmailWithI18N } from '../../../utils/render-email-with-i18n';
import { teamGlobalSettingsToBranding } from '../../../utils/team-global-settings-to-branding';
import type { JobRunIO } from '../../client/_internal/job';
import type { TSendTeamMemberLeftEmailJobDefinition } from './send-team-member-left-email';
export const run = async ({
payload,
io,
}: {
payload: TSendTeamMemberLeftEmailJobDefinition;
io: JobRunIO;
}) => {
const team = await prisma.team.findFirstOrThrow({
where: {
id: payload.teamId,
},
include: {
members: {
where: {
role: {
in: [TeamMemberRole.ADMIN, TeamMemberRole.MANAGER],
},
},
include: {
user: true,
},
},
teamGlobalSettings: true,
},
});
const oldMember = await prisma.user.findFirstOrThrow({
where: {
id: payload.memberUserId,
},
});
for (const member of team.members) {
await io.runTask(`send-team-member-left-email--${oldMember.id}_${member.id}`, async () => {
const emailContent = createElement(TeamJoinEmailTemplate, {
assetBaseUrl: WEBAPP_BASE_URL,
baseUrl: WEBAPP_BASE_URL,
memberName: oldMember.name || '',
memberEmail: oldMember.email,
teamName: team.name,
teamUrl: team.url,
});
const branding = team.teamGlobalSettings
? teamGlobalSettingsToBranding(team.teamGlobalSettings)
: undefined;
const lang = team.teamGlobalSettings?.documentLanguage;
const [html, text] = await Promise.all([
renderEmailWithI18N(emailContent, {
lang,
branding,
}),
renderEmailWithI18N(emailContent, {
lang,
branding,
plainText: true,
}),
]);
const i18n = await getI18nInstance(lang);
await mailer.sendMail({
to: member.user.email,
from: {
name: FROM_NAME,
address: FROM_ADDRESS,
},
subject: i18n._(msg`A team member has left ${team.name}`),
html,
text,
});
});
}
};

View File

@@ -1,18 +1,5 @@
import { createElement } from 'react';
import { msg } from '@lingui/macro';
import { z } from 'zod'; import { z } from 'zod';
import { mailer } from '@documenso/email/mailer';
import TeamJoinEmailTemplate from '@documenso/email/templates/team-join';
import { prisma } from '@documenso/prisma';
import { TeamMemberRole } from '@documenso/prisma/client';
import { getI18nInstance } from '../../../client-only/providers/i18n.server';
import { WEBAPP_BASE_URL } from '../../../constants/app';
import { FROM_ADDRESS, FROM_NAME } from '../../../constants/email';
import { renderEmailWithI18N } from '../../../utils/render-email-with-i18n';
import { teamGlobalSettingsToBranding } from '../../../utils/team-global-settings-to-branding';
import type { JobDefinition } from '../../client/_internal/job'; import type { JobDefinition } from '../../client/_internal/job';
const SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION_ID = 'send.team-member-left.email'; const SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION_ID = 'send.team-member-left.email';
@@ -22,6 +9,10 @@ const SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION_SCHEMA = z.object({
memberUserId: z.number(), memberUserId: z.number(),
}); });
export type TSendTeamMemberLeftEmailJobDefinition = z.infer<
typeof SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION_SCHEMA
>;
export const SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION = { export const SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION = {
id: SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION_ID, id: SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION_ID,
name: 'Send Team Member Left Email', name: 'Send Team Member Left Email',
@@ -31,76 +22,11 @@ export const SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION = {
schema: SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION_SCHEMA, schema: SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION_SCHEMA,
}, },
handler: async ({ payload, io }) => { handler: async ({ payload, io }) => {
const team = await prisma.team.findFirstOrThrow({ const handler = await import('./send-team-member-left-email.handler');
where: {
id: payload.teamId,
},
include: {
members: {
where: {
role: {
in: [TeamMemberRole.ADMIN, TeamMemberRole.MANAGER],
},
},
include: {
user: true,
},
},
teamGlobalSettings: true,
},
});
const oldMember = await prisma.user.findFirstOrThrow({ await handler.run({ payload, io });
where: {
id: payload.memberUserId,
},
});
for (const member of team.members) {
await io.runTask(`send-team-member-left-email--${oldMember.id}_${member.id}`, async () => {
const emailContent = createElement(TeamJoinEmailTemplate, {
assetBaseUrl: WEBAPP_BASE_URL,
baseUrl: WEBAPP_BASE_URL,
memberName: oldMember.name || '',
memberEmail: oldMember.email,
teamName: team.name,
teamUrl: team.url,
});
const branding = team.teamGlobalSettings
? teamGlobalSettingsToBranding(team.teamGlobalSettings)
: undefined;
const lang = team.teamGlobalSettings?.documentLanguage;
const [html, text] = await Promise.all([
renderEmailWithI18N(emailContent, {
lang,
branding,
}),
renderEmailWithI18N(emailContent, {
lang,
branding,
plainText: true,
}),
]);
const i18n = await getI18nInstance(lang);
await mailer.sendMail({
to: member.user.email,
from: {
name: FROM_NAME,
address: FROM_ADDRESS,
},
subject: i18n._(msg`A team member has left ${team.name}`),
html,
text,
});
});
}
}, },
} as const satisfies JobDefinition< } as const satisfies JobDefinition<
typeof SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION_ID, typeof SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION_ID,
z.infer<typeof SEND_TEAM_MEMBER_LEFT_EMAIL_JOB_DEFINITION_SCHEMA> TSendTeamMemberLeftEmailJobDefinition
>; >;

View File

@@ -0,0 +1,256 @@
import { nanoid } from 'nanoid';
import path from 'node:path';
import { PDFDocument } from 'pdf-lib';
import { prisma } from '@documenso/prisma';
import {
DocumentStatus,
RecipientRole,
SigningStatus,
WebhookTriggerEvents,
} from '@documenso/prisma/client';
import { signPdf } from '@documenso/signing';
import { sendCompletedEmail } from '../../../server-only/document/send-completed-email';
import PostHogServerClient from '../../../server-only/feature-flags/get-post-hog-server-client';
import { getCertificatePdf } from '../../../server-only/htmltopdf/get-certificate-pdf';
import { flattenAnnotations } from '../../../server-only/pdf/flatten-annotations';
import { flattenForm } from '../../../server-only/pdf/flatten-form';
import { insertFieldInPDF } from '../../../server-only/pdf/insert-field-in-pdf';
import { normalizeSignatureAppearances } from '../../../server-only/pdf/normalize-signature-appearances';
import { triggerWebhook } from '../../../server-only/webhooks/trigger/trigger-webhook';
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../../types/document-audit-logs';
import { ZWebhookDocumentSchema } from '../../../types/webhook-payload';
import { getFile } from '../../../universal/upload/get-file';
import { putPdfFile } from '../../../universal/upload/put-file';
import { fieldsContainUnsignedRequiredField } from '../../../utils/advanced-fields-helpers';
import { createDocumentAuditLogData } from '../../../utils/document-audit-logs';
import type { JobRunIO } from '../../client/_internal/job';
import type { TSealDocumentJobDefinition } from './seal-document';
export const run = async ({
payload,
io,
}: {
payload: TSealDocumentJobDefinition;
io: JobRunIO;
}) => {
const { documentId, sendEmail = true, isResealing = false, requestMetadata } = payload;
const document = await prisma.document.findFirstOrThrow({
where: {
id: documentId,
Recipient: {
every: {
signingStatus: SigningStatus.SIGNED,
},
},
},
include: {
documentMeta: true,
Recipient: true,
team: {
select: {
teamGlobalSettings: {
select: {
includeSigningCertificate: true,
},
},
},
},
},
});
// Seems silly but we need to do this in case the job is re-ran
// after it has already run through the update task further below.
// eslint-disable-next-line @typescript-eslint/require-await
const documentStatus = await io.runTask('get-document-status', async () => {
return document.status;
});
// This is the same case as above.
// eslint-disable-next-line @typescript-eslint/require-await
const documentDataId = await io.runTask('get-document-data-id', async () => {
return document.documentDataId;
});
const documentData = await prisma.documentData.findFirst({
where: {
id: documentDataId,
},
});
if (!documentData) {
throw new Error(`Document ${document.id} has no document data`);
}
const recipients = await prisma.recipient.findMany({
where: {
documentId: document.id,
role: {
not: RecipientRole.CC,
},
},
});
if (recipients.some((recipient) => recipient.signingStatus !== SigningStatus.SIGNED)) {
throw new Error(`Document ${document.id} has unsigned recipients`);
}
const fields = await prisma.field.findMany({
where: {
documentId: document.id,
},
include: {
Signature: true,
},
});
if (fieldsContainUnsignedRequiredField(fields)) {
throw new Error(`Document ${document.id} has unsigned required fields`);
}
if (isResealing) {
// If we're resealing we want to use the initial data for the document
// so we aren't placing fields on top of eachother.
documentData.data = documentData.initialData;
}
const pdfData = await getFile(documentData);
const certificateData =
(document.team?.teamGlobalSettings?.includeSigningCertificate ?? true)
? await getCertificatePdf({
documentId,
language: document.documentMeta?.language,
}).catch(() => null)
: null;
const newDataId = await io.runTask('decorate-and-sign-pdf', async () => {
const pdfDoc = await PDFDocument.load(pdfData);
// Normalize and flatten layers that could cause issues with the signature
normalizeSignatureAppearances(pdfDoc);
flattenForm(pdfDoc);
flattenAnnotations(pdfDoc);
if (certificateData) {
const certificateDoc = await PDFDocument.load(certificateData);
const certificatePages = await pdfDoc.copyPages(
certificateDoc,
certificateDoc.getPageIndices(),
);
certificatePages.forEach((page) => {
pdfDoc.addPage(page);
});
}
for (const field of fields) {
if (field.inserted) {
await insertFieldInPDF(pdfDoc, field);
}
}
// Re-flatten the form to handle our checkbox and radio fields that
// create native arcoFields
flattenForm(pdfDoc);
const pdfBytes = await pdfDoc.save();
const pdfBuffer = await signPdf({ pdf: Buffer.from(pdfBytes) });
const { name } = path.parse(document.title);
const documentData = await putPdfFile({
name: `${name}_signed.pdf`,
type: 'application/pdf',
arrayBuffer: async () => Promise.resolve(pdfBuffer),
});
return documentData.id;
});
const postHog = PostHogServerClient();
if (postHog) {
postHog.capture({
distinctId: nanoid(),
event: 'App: Document Sealed',
properties: {
documentId: document.id,
},
});
}
await io.runTask('update-document', async () => {
await prisma.$transaction(async (tx) => {
const newData = await tx.documentData.findFirstOrThrow({
where: {
id: newDataId,
},
});
await tx.document.update({
where: {
id: document.id,
},
data: {
status: DocumentStatus.COMPLETED,
completedAt: new Date(),
},
});
await tx.documentData.update({
where: {
id: documentData.id,
},
data: {
data: newData.data,
},
});
await tx.documentAuditLog.create({
data: createDocumentAuditLogData({
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_COMPLETED,
documentId: document.id,
requestMetadata,
user: null,
data: {
transactionId: nanoid(),
},
}),
});
});
});
await io.runTask('send-completed-email', async () => {
let shouldSendCompletedEmail = sendEmail && !isResealing;
if (isResealing && documentStatus !== DocumentStatus.COMPLETED) {
shouldSendCompletedEmail = sendEmail;
}
if (shouldSendCompletedEmail) {
await sendCompletedEmail({ documentId, requestMetadata });
}
});
const updatedDocument = await prisma.document.findFirstOrThrow({
where: {
id: document.id,
},
include: {
documentData: true,
documentMeta: true,
Recipient: true,
},
});
await triggerWebhook({
event: WebhookTriggerEvents.DOCUMENT_COMPLETED,
data: ZWebhookDocumentSchema.parse(updatedDocument),
userId: updatedDocument.userId,
teamId: updatedDocument.teamId ?? undefined,
});
};

View File

@@ -1,31 +1,6 @@
import { nanoid } from 'nanoid';
import path from 'node:path';
import { PDFDocument } from 'pdf-lib';
import { z } from 'zod'; import { z } from 'zod';
import { prisma } from '@documenso/prisma';
import {
DocumentStatus,
RecipientRole,
SigningStatus,
WebhookTriggerEvents,
} from '@documenso/prisma/client';
import { signPdf } from '@documenso/signing';
import { sendCompletedEmail } from '../../../server-only/document/send-completed-email';
import PostHogServerClient from '../../../server-only/feature-flags/get-post-hog-server-client';
import { getCertificatePdf } from '../../../server-only/htmltopdf/get-certificate-pdf';
import { flattenAnnotations } from '../../../server-only/pdf/flatten-annotations';
import { flattenForm } from '../../../server-only/pdf/flatten-form';
import { insertFieldInPDF } from '../../../server-only/pdf/insert-field-in-pdf';
import { normalizeSignatureAppearances } from '../../../server-only/pdf/normalize-signature-appearances';
import { triggerWebhook } from '../../../server-only/webhooks/trigger/trigger-webhook';
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../../types/document-audit-logs';
import { ZWebhookDocumentSchema } from '../../../types/webhook-payload';
import { ZRequestMetadataSchema } from '../../../universal/extract-request-metadata'; import { ZRequestMetadataSchema } from '../../../universal/extract-request-metadata';
import { getFile } from '../../../universal/upload/get-file';
import { putPdfFile } from '../../../universal/upload/put-file';
import { createDocumentAuditLogData } from '../../../utils/document-audit-logs';
import { type JobDefinition } from '../../client/_internal/job'; import { type JobDefinition } from '../../client/_internal/job';
const SEAL_DOCUMENT_JOB_DEFINITION_ID = 'internal.seal-document'; const SEAL_DOCUMENT_JOB_DEFINITION_ID = 'internal.seal-document';
@@ -37,6 +12,8 @@ const SEAL_DOCUMENT_JOB_DEFINITION_SCHEMA = z.object({
requestMetadata: ZRequestMetadataSchema.optional(), requestMetadata: ZRequestMetadataSchema.optional(),
}); });
export type TSealDocumentJobDefinition = z.infer<typeof SEAL_DOCUMENT_JOB_DEFINITION_SCHEMA>;
export const SEAL_DOCUMENT_JOB_DEFINITION = { export const SEAL_DOCUMENT_JOB_DEFINITION = {
id: SEAL_DOCUMENT_JOB_DEFINITION_ID, id: SEAL_DOCUMENT_JOB_DEFINITION_ID,
name: 'Seal Document', name: 'Seal Document',
@@ -46,223 +23,11 @@ export const SEAL_DOCUMENT_JOB_DEFINITION = {
schema: SEAL_DOCUMENT_JOB_DEFINITION_SCHEMA, schema: SEAL_DOCUMENT_JOB_DEFINITION_SCHEMA,
}, },
handler: async ({ payload, io }) => { handler: async ({ payload, io }) => {
const { documentId, sendEmail = true, isResealing = false, requestMetadata } = payload; const handler = await import('./seal-document.handler');
const document = await prisma.document.findFirstOrThrow({ await handler.run({ payload, io });
where: {
id: documentId,
Recipient: {
every: {
signingStatus: SigningStatus.SIGNED,
},
},
},
include: {
documentMeta: true,
Recipient: true,
team: {
select: {
teamGlobalSettings: {
select: {
includeSigningCertificate: true,
},
},
},
},
},
});
// Seems silly but we need to do this in case the job is re-ran
// after it has already run through the update task further below.
// eslint-disable-next-line @typescript-eslint/require-await
const documentStatus = await io.runTask('get-document-status', async () => {
return document.status;
});
// This is the same case as above.
// eslint-disable-next-line @typescript-eslint/require-await
const documentDataId = await io.runTask('get-document-data-id', async () => {
return document.documentDataId;
});
const documentData = await prisma.documentData.findFirst({
where: {
id: documentDataId,
},
});
if (!documentData) {
throw new Error(`Document ${document.id} has no document data`);
}
const recipients = await prisma.recipient.findMany({
where: {
documentId: document.id,
role: {
not: RecipientRole.CC,
},
},
});
if (recipients.some((recipient) => recipient.signingStatus !== SigningStatus.SIGNED)) {
throw new Error(`Document ${document.id} has unsigned recipients`);
}
const fields = await prisma.field.findMany({
where: {
documentId: document.id,
},
include: {
Signature: true,
},
});
if (fields.some((field) => !field.inserted)) {
throw new Error(`Document ${document.id} has unsigned fields`);
}
if (isResealing) {
// If we're resealing we want to use the initial data for the document
// so we aren't placing fields on top of eachother.
documentData.data = documentData.initialData;
}
const pdfData = await getFile(documentData);
const certificateData =
(document.team?.teamGlobalSettings?.includeSigningCertificate ?? true)
? await getCertificatePdf({
documentId,
language: document.documentMeta?.language,
}).catch(() => null)
: null;
const newDataId = await io.runTask('decorate-and-sign-pdf', async () => {
const pdfDoc = await PDFDocument.load(pdfData);
// Normalize and flatten layers that could cause issues with the signature
normalizeSignatureAppearances(pdfDoc);
flattenForm(pdfDoc);
flattenAnnotations(pdfDoc);
if (certificateData) {
const certificateDoc = await PDFDocument.load(certificateData);
const certificatePages = await pdfDoc.copyPages(
certificateDoc,
certificateDoc.getPageIndices(),
);
certificatePages.forEach((page) => {
pdfDoc.addPage(page);
});
}
for (const field of fields) {
await insertFieldInPDF(pdfDoc, field);
}
// Re-flatten the form to handle our checkbox and radio fields that
// create native arcoFields
flattenForm(pdfDoc);
const pdfBytes = await pdfDoc.save();
const pdfBuffer = await signPdf({ pdf: Buffer.from(pdfBytes) });
const { name } = path.parse(document.title);
const documentData = await putPdfFile({
name: `${name}_signed.pdf`,
type: 'application/pdf',
arrayBuffer: async () => Promise.resolve(pdfBuffer),
});
return documentData.id;
});
const postHog = PostHogServerClient();
if (postHog) {
postHog.capture({
distinctId: nanoid(),
event: 'App: Document Sealed',
properties: {
documentId: document.id,
},
});
}
await io.runTask('update-document', async () => {
await prisma.$transaction(async (tx) => {
const newData = await tx.documentData.findFirstOrThrow({
where: {
id: newDataId,
},
});
await tx.document.update({
where: {
id: document.id,
},
data: {
status: DocumentStatus.COMPLETED,
completedAt: new Date(),
},
});
await tx.documentData.update({
where: {
id: documentData.id,
},
data: {
data: newData.data,
},
});
await tx.documentAuditLog.create({
data: createDocumentAuditLogData({
type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_COMPLETED,
documentId: document.id,
requestMetadata,
user: null,
data: {
transactionId: nanoid(),
},
}),
});
});
});
await io.runTask('send-completed-email', async () => {
let shouldSendCompletedEmail = sendEmail && !isResealing;
if (isResealing && documentStatus !== DocumentStatus.COMPLETED) {
shouldSendCompletedEmail = sendEmail;
}
if (shouldSendCompletedEmail) {
await sendCompletedEmail({ documentId, requestMetadata });
}
});
const updatedDocument = await prisma.document.findFirstOrThrow({
where: {
id: document.id,
},
include: {
documentData: true,
documentMeta: true,
Recipient: true,
},
});
await triggerWebhook({
event: WebhookTriggerEvents.DOCUMENT_COMPLETED,
data: ZWebhookDocumentSchema.parse(updatedDocument),
userId: updatedDocument.userId,
teamId: updatedDocument.teamId ?? undefined,
});
}, },
} as const satisfies JobDefinition< } as const satisfies JobDefinition<
typeof SEAL_DOCUMENT_JOB_DEFINITION_ID, typeof SEAL_DOCUMENT_JOB_DEFINITION_ID,
z.infer<typeof SEAL_DOCUMENT_JOB_DEFINITION_SCHEMA> TSealDocumentJobDefinition
>; >;

View File

@@ -121,6 +121,10 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = {
throw new Error(ErrorCode.UNVERIFIED_EMAIL); throw new Error(ErrorCode.UNVERIFIED_EMAIL);
} }
if (user.disabled) {
throw new Error(ErrorCode.ACCOUNT_DISABLED);
}
return { return {
id: Number(user.id), id: Number(user.id),
email: user.email, email: user.email,

View File

@@ -20,4 +20,5 @@ export const ErrorCode = {
MISSING_ENCRYPTION_KEY: 'MISSING_ENCRYPTION_KEY', MISSING_ENCRYPTION_KEY: 'MISSING_ENCRYPTION_KEY',
MISSING_BACKUP_CODE: 'MISSING_BACKUP_CODE', MISSING_BACKUP_CODE: 'MISSING_BACKUP_CODE',
UNVERIFIED_EMAIL: 'UNVERIFIED_EMAIL', UNVERIFIED_EMAIL: 'UNVERIFIED_EMAIL',
ACCOUNT_DISABLED: 'ACCOUNT_DISABLED',
} as const; } as const;

View File

@@ -21,6 +21,10 @@ export const getServerComponentSession = cache(async () => {
}, },
}); });
if (user.disabled) {
return { user: null, session: null };
}
return { user, session }; return { user, session };
}); });

View File

@@ -56,7 +56,7 @@
"sharp": "0.32.6", "sharp": "0.32.6",
"stripe": "^12.7.0", "stripe": "^12.7.0",
"ts-pattern": "^5.0.5", "ts-pattern": "^5.0.5",
"zod": "^3.23.8" "zod": "3.24.1"
}, },
"devDependencies": { "devDependencies": {
"@playwright/browser-chromium": "1.43.0", "@playwright/browser-chromium": "1.43.0",

View File

@@ -1,5 +1,5 @@
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import { Prisma } from '@documenso/prisma/client'; import { DocumentStatus, Prisma } from '@documenso/prisma/client';
export type SigningVolume = { export type SigningVolume = {
id: number; id: number;
@@ -43,34 +43,41 @@ export async function getSigningVolume({
], ],
}); });
const orderByClause = getOrderByClause({ sortBy, sortOrder });
const [subscriptions, totalCount] = await Promise.all([ const [subscriptions, totalCount] = await Promise.all([
prisma.subscription.findMany({ prisma.subscription.findMany({
where: whereClause, where: whereClause,
include: { include: {
User: { User: {
include: { select: {
name: true,
email: true,
Document: { Document: {
where: { where: {
status: 'COMPLETED', status: DocumentStatus.COMPLETED,
deletedAt: null, deletedAt: null,
teamId: null,
}, },
}, },
}, },
}, },
team: { team: {
include: { select: {
name: true,
document: { document: {
where: { where: {
status: 'COMPLETED', status: DocumentStatus.COMPLETED,
deletedAt: null, deletedAt: null,
}, },
}, },
}, },
}, },
}, },
orderBy: orderByClause, orderBy:
sortBy === 'name'
? [{ User: { name: sortOrder } }, { team: { name: sortOrder } }, { createdAt: 'desc' }]
: sortBy === 'createdAt'
? [{ createdAt: sortOrder }]
: undefined,
skip: Math.max(page - 1, 0) * perPage, skip: Math.max(page - 1, 0) * perPage,
take: perPage, take: perPage,
}), }),
@@ -82,10 +89,8 @@ export async function getSigningVolume({
const leaderboardWithVolume: SigningVolume[] = subscriptions.map((subscription) => { const leaderboardWithVolume: SigningVolume[] = subscriptions.map((subscription) => {
const name = const name =
subscription.User?.name || subscription.team?.name || subscription.User?.email || 'Unknown'; subscription.User?.name || subscription.team?.name || subscription.User?.email || 'Unknown';
const userSignedDocs = subscription.User?.Document?.length || 0; const userSignedDocs = subscription.User?.Document?.length || 0;
const teamSignedDocs = subscription.team?.document?.length || 0; const teamSignedDocs = subscription.team?.document?.length || 0;
return { return {
id: subscription.id, id: subscription.id,
name, name,
@@ -95,54 +100,16 @@ export async function getSigningVolume({
}; };
}); });
if (sortBy === 'signingVolume') {
leaderboardWithVolume.sort((a, b) => {
return sortOrder === 'desc'
? b.signingVolume - a.signingVolume
: a.signingVolume - b.signingVolume;
});
}
return { return {
leaderboard: leaderboardWithVolume, leaderboard: leaderboardWithVolume,
totalPages: Math.ceil(totalCount / perPage), totalPages: Math.ceil(totalCount / perPage),
}; };
} }
function getOrderByClause(options: {
sortBy: string;
sortOrder: 'asc' | 'desc';
}): Prisma.SubscriptionOrderByWithRelationInput | Prisma.SubscriptionOrderByWithRelationInput[] {
const { sortBy, sortOrder } = options;
if (sortBy === 'name') {
return [
{
User: {
name: sortOrder,
},
},
{
team: {
name: sortOrder,
},
},
];
}
if (sortBy === 'createdAt') {
return {
createdAt: sortOrder,
};
}
// Default: sort by signing volume
return [
{
User: {
Document: {
_count: sortOrder,
},
},
},
{
team: {
document: {
_count: sortOrder,
},
},
},
];
}

View File

@@ -1,5 +1,6 @@
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs'; import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata'; import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
import { fieldsContainUnsignedRequiredField } from '@documenso/lib/utils/advanced-fields-helpers';
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs'; import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import { import {
@@ -8,8 +9,8 @@ import {
RecipientRole, RecipientRole,
SendStatus, SendStatus,
SigningStatus, SigningStatus,
WebhookTriggerEvents,
} from '@documenso/prisma/client'; } from '@documenso/prisma/client';
import { WebhookTriggerEvents } from '@documenso/prisma/client';
import { jobs } from '../../jobs/client'; import { jobs } from '../../jobs/client';
import type { TRecipientActionAuth } from '../../types/document-auth'; import type { TRecipientActionAuth } from '../../types/document-auth';
@@ -85,7 +86,7 @@ export const completeDocumentWithToken = async ({
}, },
}); });
if (fields.some((field) => !field.inserted)) { if (fieldsContainUnsignedRequiredField(fields)) {
throw new Error(`Recipient ${recipient.id} has unsigned fields`); throw new Error(`Recipient ${recipient.id} has unsigned fields`);
} }
@@ -139,6 +140,14 @@ export const completeDocumentWithToken = async ({
}); });
}); });
await jobs.triggerJob({
name: 'send.recipient.signed.email',
payload: {
documentId: document.id,
recipientId: recipient.id,
},
});
const pendingRecipients = await prisma.recipient.findMany({ const pendingRecipients = await prisma.recipient.findMany({
select: { select: {
id: true, id: true,

View File

@@ -1,6 +1,9 @@
'use server'; 'use server';
import type { z } from 'zod';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { normalizePdf as makeNormalizedPdf } from '@documenso/lib/server-only/pdf/normalize-pdf';
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs'; import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata'; import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs'; import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
@@ -8,8 +11,11 @@ import { prisma } from '@documenso/prisma';
import { DocumentSource, DocumentVisibility, WebhookTriggerEvents } from '@documenso/prisma/client'; import { DocumentSource, DocumentVisibility, WebhookTriggerEvents } from '@documenso/prisma/client';
import type { Team, TeamGlobalSettings } from '@documenso/prisma/client'; import type { Team, TeamGlobalSettings } from '@documenso/prisma/client';
import { TeamMemberRole } from '@documenso/prisma/client'; import { TeamMemberRole } from '@documenso/prisma/client';
import { DocumentSchema } from '@documenso/prisma/generated/zod';
import { ZWebhookDocumentSchema } from '../../types/webhook-payload'; import { ZWebhookDocumentSchema } from '../../types/webhook-payload';
import { getFile } from '../../universal/upload/get-file';
import { putPdfFile } from '../../universal/upload/put-file';
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook'; import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
export type CreateDocumentOptions = { export type CreateDocumentOptions = {
@@ -19,18 +25,24 @@ export type CreateDocumentOptions = {
teamId?: number; teamId?: number;
documentDataId: string; documentDataId: string;
formValues?: Record<string, string | number | boolean>; formValues?: Record<string, string | number | boolean>;
normalizePdf?: boolean;
requestMetadata?: RequestMetadata; requestMetadata?: RequestMetadata;
}; };
export const ZCreateDocumentResponseSchema = DocumentSchema;
export type TCreateDocumentResponse = z.infer<typeof ZCreateDocumentResponseSchema>;
export const createDocument = async ({ export const createDocument = async ({
userId, userId,
title, title,
externalId, externalId,
documentDataId, documentDataId,
teamId, teamId,
normalizePdf,
formValues, formValues,
requestMetadata, requestMetadata,
}: CreateDocumentOptions) => { }: CreateDocumentOptions): Promise<TCreateDocumentResponse> => {
const user = await prisma.user.findFirstOrThrow({ const user = await prisma.user.findFirstOrThrow({
where: { where: {
id: userId, id: userId,
@@ -82,22 +94,44 @@ export const createDocument = async ({
globalVisibility: DocumentVisibility | null | undefined, globalVisibility: DocumentVisibility | null | undefined,
userRole: TeamMemberRole, userRole: TeamMemberRole,
): DocumentVisibility => { ): DocumentVisibility => {
const defaultVisibility = globalVisibility ?? DocumentVisibility.EVERYONE; if (globalVisibility) {
return globalVisibility;
}
if (userRole === TeamMemberRole.ADMIN) { if (userRole === TeamMemberRole.ADMIN) {
return defaultVisibility; return DocumentVisibility.ADMIN;
} }
if (userRole === TeamMemberRole.MANAGER) { if (userRole === TeamMemberRole.MANAGER) {
if (defaultVisibility === DocumentVisibility.ADMIN) {
return DocumentVisibility.MANAGER_AND_ABOVE; return DocumentVisibility.MANAGER_AND_ABOVE;
} }
return defaultVisibility;
}
return DocumentVisibility.EVERYONE; return DocumentVisibility.EVERYONE;
}; };
if (normalizePdf) {
const documentData = await prisma.documentData.findFirst({
where: {
id: documentDataId,
},
});
if (documentData) {
const buffer = await getFile(documentData);
const normalizedPdf = await makeNormalizedPdf(Buffer.from(buffer));
const newDocumentData = await putPdfFile({
name: title.endsWith('.pdf') ? title : `${title}.pdf`,
type: 'application/pdf',
arrayBuffer: async () => Promise.resolve(normalizedPdf),
});
// eslint-disable-next-line require-atomic-updates
documentDataId = newDocumentData.id;
}
}
return await prisma.$transaction(async (tx) => { return await prisma.$transaction(async (tx) => {
const document = await tx.document.create({ const document = await tx.document.create({
data: { data: {

View File

@@ -1,19 +1,27 @@
import { z } from 'zod';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import { DocumentSource, type Prisma } from '@documenso/prisma/client'; import { DocumentSource, type Prisma } from '@documenso/prisma/client';
import { getDocumentWhereInput } from './get-document-by-id'; import { getDocumentWhereInput } from './get-document-by-id';
export interface DuplicateDocumentByIdOptions { export interface DuplicateDocumentOptions {
documentId: number; documentId: number;
userId: number; userId: number;
teamId?: number; teamId?: number;
} }
export const duplicateDocumentById = async ({ export const ZDuplicateDocumentResponseSchema = z.object({
documentId: z.number(),
});
export type TDuplicateDocumentResponse = z.infer<typeof ZDuplicateDocumentResponseSchema>;
export const duplicateDocument = async ({
documentId, documentId,
userId, userId,
teamId, teamId,
}: DuplicateDocumentByIdOptions) => { }: DuplicateDocumentOptions): Promise<TDuplicateDocumentResponse> => {
const documentWhereInput = await getDocumentWhereInput({ const documentWhereInput = await getDocumentWhereInput({
documentId, documentId,
userId, userId,
@@ -78,5 +86,7 @@ export const duplicateDocumentById = async ({
const createdDocument = await prisma.document.create(createDocumentArguments); const createdDocument = await prisma.document.create(createDocumentArguments);
return createdDocument.id; return {
documentId: createdDocument.id,
};
}; };

View File

@@ -1,5 +1,6 @@
import { DateTime } from 'luxon'; import { DateTime } from 'luxon';
import { match } from 'ts-pattern'; import { match } from 'ts-pattern';
import type { z } from 'zod';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import type { import type {
@@ -11,10 +12,16 @@ import type {
User, User,
} from '@documenso/prisma/client'; } from '@documenso/prisma/client';
import { RecipientRole, SigningStatus, TeamMemberRole } from '@documenso/prisma/client'; import { RecipientRole, SigningStatus, TeamMemberRole } from '@documenso/prisma/client';
import {
DocumentSchema,
RecipientSchema,
TeamSchema,
UserSchema,
} from '@documenso/prisma/generated/zod';
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status'; import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
import { DocumentVisibility } from '../../types/document-visibility'; import { DocumentVisibility } from '../../types/document-visibility';
import type { FindResultResponse } from '../../types/search-params'; import { type FindResultResponse, ZFindResultResponse } from '../../types/search-params';
import { maskRecipientTokensForDocument } from '../../utils/mask-recipient-tokens-for-document'; import { maskRecipientTokensForDocument } from '../../utils/mask-recipient-tokens-for-document';
export type PeriodSelectorValue = '' | '7d' | '14d' | '30d'; export type PeriodSelectorValue = '' | '7d' | '14d' | '30d';
@@ -36,6 +43,23 @@ export type FindDocumentsOptions = {
query?: string; query?: string;
}; };
export const ZFindDocumentsResponseSchema = ZFindResultResponse.extend({
data: DocumentSchema.extend({
User: UserSchema.pick({
id: true,
name: true,
email: true,
}),
Recipient: RecipientSchema.array(),
team: TeamSchema.pick({
id: true,
url: true,
}).nullable(),
}).array(), // Todo: openapi remap.
});
export type TFindDocumentsResponse = z.infer<typeof ZFindDocumentsResponseSchema>;
export const findDocuments = async ({ export const findDocuments = async ({
userId, userId,
teamId, teamId,
@@ -48,7 +72,7 @@ export const findDocuments = async ({
period, period,
senderIds, senderIds,
query, query,
}: FindDocumentsOptions) => { }: FindDocumentsOptions): Promise<TFindDocumentsResponse> => {
const user = await prisma.user.findFirstOrThrow({ const user = await prisma.user.findFirstOrThrow({
where: { where: {
id: userId, id: userId,

View File

@@ -1,6 +1,15 @@
import { prisma } from '@documenso/prisma'; import type { z } from 'zod';
import type { DocumentWithDetails } from '@documenso/prisma/types/document';
import { prisma } from '@documenso/prisma';
import {
DocumentDataSchema,
DocumentMetaSchema,
DocumentSchema,
FieldSchema,
RecipientSchema,
} from '@documenso/prisma/generated/zod';
import { AppError, AppErrorCode } from '../../errors/app-error';
import { getDocumentWhereInput } from './get-document-by-id'; import { getDocumentWhereInput } from './get-document-by-id';
export type GetDocumentWithDetailsByIdOptions = { export type GetDocumentWithDetailsByIdOptions = {
@@ -9,18 +18,29 @@ export type GetDocumentWithDetailsByIdOptions = {
teamId?: number; teamId?: number;
}; };
export const ZGetDocumentWithDetailsByIdResponseSchema = DocumentSchema.extend({
documentData: DocumentDataSchema,
documentMeta: DocumentMetaSchema.nullable(),
Recipient: RecipientSchema.array(),
Field: FieldSchema.array(),
});
export type TGetDocumentWithDetailsByIdResponse = z.infer<
typeof ZGetDocumentWithDetailsByIdResponseSchema
>;
export const getDocumentWithDetailsById = async ({ export const getDocumentWithDetailsById = async ({
documentId, documentId,
userId, userId,
teamId, teamId,
}: GetDocumentWithDetailsByIdOptions): Promise<DocumentWithDetails> => { }: GetDocumentWithDetailsByIdOptions): Promise<TGetDocumentWithDetailsByIdResponse> => {
const documentWhereInput = await getDocumentWhereInput({ const documentWhereInput = await getDocumentWhereInput({
documentId, documentId,
userId, userId,
teamId, teamId,
}); });
return await prisma.document.findFirstOrThrow({ const document = await prisma.document.findFirst({
where: documentWhereInput, where: documentWhereInput,
include: { include: {
documentData: true, documentData: true,
@@ -29,4 +49,12 @@ export const getDocumentWithDetailsById = async ({
Field: true, Field: true,
}, },
}); });
if (!document) {
throw new AppError(AppErrorCode.NOT_FOUND, {
message: 'Document not found',
});
}
return document;
}; };

View File

@@ -1,7 +1,9 @@
import { TRPCError } from '@trpc/server'; import { TRPCError } from '@trpc/server';
import type { z } from 'zod';
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata'; import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import { DocumentSchema } from '@documenso/prisma/generated/zod';
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs'; import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
import { createDocumentAuditLogData } from '../../utils/document-audit-logs'; import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
@@ -13,12 +15,16 @@ export type MoveDocumentToTeamOptions = {
requestMetadata?: RequestMetadata; requestMetadata?: RequestMetadata;
}; };
export const ZMoveDocumentToTeamResponseSchema = DocumentSchema;
export type TMoveDocumentToTeamResponse = z.infer<typeof ZMoveDocumentToTeamResponseSchema>;
export const moveDocumentToTeam = async ({ export const moveDocumentToTeam = async ({
documentId, documentId,
teamId, teamId,
userId, userId,
requestMetadata, requestMetadata,
}: MoveDocumentToTeamOptions) => { }: MoveDocumentToTeamOptions): Promise<TMoveDocumentToTeamResponse> => {
return await prisma.$transaction(async (tx) => { return await prisma.$transaction(async (tx) => {
const user = await tx.user.findUniqueOrThrow({ const user = await tx.user.findUniqueOrThrow({
where: { id: userId }, where: { id: userId },

View File

@@ -38,7 +38,7 @@ export const resendDocument = async ({
recipients, recipients,
teamId, teamId,
requestMetadata, requestMetadata,
}: ResendDocumentOptions) => { }: ResendDocumentOptions): Promise<void> => {
const user = await prisma.user.findFirstOrThrow({ const user = await prisma.user.findFirstOrThrow({
where: { where: {
id: userId, id: userId,

View File

@@ -6,14 +6,19 @@ import PostHogServerClient from '@documenso/lib/server-only/feature-flags/get-po
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs'; import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs'; import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import { DocumentStatus, RecipientRole, SigningStatus } from '@documenso/prisma/client'; import {
import { WebhookTriggerEvents } from '@documenso/prisma/client'; DocumentStatus,
RecipientRole,
SigningStatus,
WebhookTriggerEvents,
} from '@documenso/prisma/client';
import { signPdf } from '@documenso/signing'; import { signPdf } from '@documenso/signing';
import { ZWebhookDocumentSchema } from '../../types/webhook-payload'; import { ZWebhookDocumentSchema } from '../../types/webhook-payload';
import type { RequestMetadata } from '../../universal/extract-request-metadata'; import type { RequestMetadata } from '../../universal/extract-request-metadata';
import { getFile } from '../../universal/upload/get-file'; import { getFile } from '../../universal/upload/get-file';
import { putPdfFile } from '../../universal/upload/put-file'; import { putPdfFile } from '../../universal/upload/put-file';
import { fieldsContainUnsignedRequiredField } from '../../utils/advanced-fields-helpers';
import { getCertificatePdf } from '../htmltopdf/get-certificate-pdf'; import { getCertificatePdf } from '../htmltopdf/get-certificate-pdf';
import { flattenAnnotations } from '../pdf/flatten-annotations'; import { flattenAnnotations } from '../pdf/flatten-annotations';
import { flattenForm } from '../pdf/flatten-form'; import { flattenForm } from '../pdf/flatten-form';
@@ -88,8 +93,8 @@ export const sealDocument = async ({
}, },
}); });
if (fields.some((field) => !field.inserted)) { if (fieldsContainUnsignedRequiredField(fields)) {
throw new Error(`Document ${document.id} has unsigned fields`); throw new Error(`Document ${document.id} has unsigned required fields`);
} }
if (isResealing) { if (isResealing) {

View File

@@ -72,14 +72,19 @@ export const sendCompletedEmail = async ({ documentId, requestMetadata }: SendDo
const i18n = await getI18nInstance(document.documentMeta?.language); const i18n = await getI18nInstance(document.documentMeta?.language);
const isDocumentCompletedEmailEnabled = extractDerivedDocumentEmailSettings( const emailSettings = extractDerivedDocumentEmailSettings(document.documentMeta);
document.documentMeta, const isDocumentCompletedEmailEnabled = emailSettings.documentCompleted;
).documentCompleted; const isOwnerDocumentCompletedEmailEnabled = emailSettings.ownerDocumentCompleted;
// If the document owner is not a recipient, OR recipient emails are disabled, then send the email to them separately. // Send email to document owner if:
// 1. Owner document completed emails are enabled AND
// 2. Either:
// - The owner is not a recipient, OR
// - Recipient emails are disabled
if ( if (
!document.Recipient.find((recipient) => recipient.email === owner.email) || isOwnerDocumentCompletedEmailEnabled &&
!isDocumentCompletedEmailEnabled (!document.Recipient.find((recipient) => recipient.email === owner.email) ||
!isDocumentCompletedEmailEnabled)
) { ) {
const template = createElement(DocumentCompletedEmailTemplate, { const template = createElement(DocumentCompletedEmailTemplate, {
documentName: document.title, documentName: document.title,

View File

@@ -1,3 +1,5 @@
import type { z } from 'zod';
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs'; import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata'; import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
import { putPdfFile } from '@documenso/lib/universal/upload/put-file'; import { putPdfFile } from '@documenso/lib/universal/upload/put-file';
@@ -9,8 +11,13 @@ import {
RecipientRole, RecipientRole,
SendStatus, SendStatus,
SigningStatus, SigningStatus,
WebhookTriggerEvents,
} from '@documenso/prisma/client'; } from '@documenso/prisma/client';
import { WebhookTriggerEvents } from '@documenso/prisma/client'; import {
DocumentMetaSchema,
DocumentSchema,
RecipientSchema,
} from '@documenso/prisma/generated/zod';
import { jobs } from '../../jobs/client'; import { jobs } from '../../jobs/client';
import { extractDerivedDocumentEmailSettings } from '../../types/document-email'; import { extractDerivedDocumentEmailSettings } from '../../types/document-email';
@@ -27,13 +34,20 @@ export type SendDocumentOptions = {
requestMetadata?: RequestMetadata; requestMetadata?: RequestMetadata;
}; };
export const ZSendDocumentResponseSchema = DocumentSchema.extend({
documentMeta: DocumentMetaSchema.nullable(),
Recipient: RecipientSchema.array(),
});
export type TSendDocumentResponse = z.infer<typeof ZSendDocumentResponseSchema>;
export const sendDocument = async ({ export const sendDocument = async ({
documentId, documentId,
userId, userId,
teamId, teamId,
sendEmail, sendEmail,
requestMetadata, requestMetadata,
}: SendDocumentOptions) => { }: SendDocumentOptions): Promise<TSendDocumentResponse> => {
const user = await prisma.user.findFirstOrThrow({ const user = await prisma.user.findFirstOrThrow({
where: { where: {
id: userId, id: userId,
@@ -211,6 +225,7 @@ export const sendDocument = async ({
id: documentId, id: documentId,
}, },
include: { include: {
documentMeta: true,
Recipient: true, Recipient: true,
}, },
}); });

View File

@@ -1,6 +1,7 @@
'use server'; 'use server';
import { match } from 'ts-pattern'; import { match } from 'ts-pattern';
import type { z } from 'zod';
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise'; import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs'; import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
@@ -10,6 +11,7 @@ import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import { DocumentVisibility } from '@documenso/prisma/client'; import { DocumentVisibility } from '@documenso/prisma/client';
import { DocumentStatus, TeamMemberRole } from '@documenso/prisma/client'; import { DocumentStatus, TeamMemberRole } from '@documenso/prisma/client';
import { DocumentSchema } from '@documenso/prisma/generated/zod';
import { AppError, AppErrorCode } from '../../errors/app-error'; import { AppError, AppErrorCode } from '../../errors/app-error';
import type { TDocumentAccessAuthTypes, TDocumentActionAuthTypes } from '../../types/document-auth'; import type { TDocumentAccessAuthTypes, TDocumentActionAuthTypes } from '../../types/document-auth';
@@ -29,13 +31,17 @@ export type UpdateDocumentSettingsOptions = {
requestMetadata?: RequestMetadata; requestMetadata?: RequestMetadata;
}; };
export const ZUpdateDocumentSettingsResponseSchema = DocumentSchema;
export type TUpdateDocumentSettingsResponse = z.infer<typeof ZUpdateDocumentSettingsResponseSchema>;
export const updateDocumentSettings = async ({ export const updateDocumentSettings = async ({
userId, userId,
teamId, teamId,
documentId, documentId,
data, data,
requestMetadata, requestMetadata,
}: UpdateDocumentSettingsOptions) => { }: UpdateDocumentSettingsOptions): Promise<TUpdateDocumentSettingsResponse> => {
if (!data.title && !data.globalAccessAuth && !data.globalActionAuth) { if (!data.title && !data.globalAccessAuth && !data.globalActionAuth) {
throw new AppError(AppErrorCode.INVALID_BODY, { throw new AppError(AppErrorCode.INVALID_BODY, {
message: 'Missing data to update', message: 'Missing data to update',
@@ -85,7 +91,10 @@ export const updateDocumentSettings = async ({
if (teamId) { if (teamId) {
const currentUserRole = document.team?.members[0]?.role; const currentUserRole = document.team?.members[0]?.role;
const isDocumentOwner = document.userId === userId;
const requestedVisibility = data.visibility;
if (!isDocumentOwner) {
match(currentUserRole) match(currentUserRole)
.with(TeamMemberRole.ADMIN, () => true) .with(TeamMemberRole.ADMIN, () => true)
.with(TeamMemberRole.MANAGER, () => { .with(TeamMemberRole.MANAGER, () => {
@@ -96,7 +105,7 @@ export const updateDocumentSettings = async ({
if ( if (
!allowedVisibilities.includes(document.visibility) || !allowedVisibilities.includes(document.visibility) ||
(data.visibility && !allowedVisibilities.includes(data.visibility)) (requestedVisibility && !allowedVisibilities.includes(requestedVisibility))
) { ) {
throw new AppError(AppErrorCode.UNAUTHORIZED, { throw new AppError(AppErrorCode.UNAUTHORIZED, {
message: 'You do not have permission to update the document visibility', message: 'You do not have permission to update the document visibility',
@@ -106,7 +115,7 @@ export const updateDocumentSettings = async ({
.with(TeamMemberRole.MEMBER, () => { .with(TeamMemberRole.MEMBER, () => {
if ( if (
document.visibility !== DocumentVisibility.EVERYONE || document.visibility !== DocumentVisibility.EVERYONE ||
(data.visibility && data.visibility !== DocumentVisibility.EVERYONE) (requestedVisibility && requestedVisibility !== DocumentVisibility.EVERYONE)
) { ) {
throw new AppError(AppErrorCode.UNAUTHORIZED, { throw new AppError(AppErrorCode.UNAUTHORIZED, {
message: 'You do not have permission to update the document visibility', message: 'You do not have permission to update the document visibility',
@@ -119,6 +128,7 @@ export const updateDocumentSettings = async ({
}); });
}); });
} }
}
const { documentAuthOption } = extractDocumentAuthMethods({ const { documentAuthOption } = extractDocumentAuthMethods({
documentAuth: document.authOptions, documentAuth: document.authOptions,

View File

@@ -1,4 +1,9 @@
import type { z } from 'zod';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import { FieldSchema } from '@documenso/prisma/generated/zod';
import { AppError, AppErrorCode } from '../../errors/app-error';
export type GetFieldByIdOptions = { export type GetFieldByIdOptions = {
userId: number; userId: number;
@@ -8,13 +13,17 @@ export type GetFieldByIdOptions = {
templateId?: number; templateId?: number;
}; };
export const ZGetFieldByIdResponseSchema = FieldSchema;
export type TGetFieldByIdResponse = z.infer<typeof ZGetFieldByIdResponseSchema>;
export const getFieldById = async ({ export const getFieldById = async ({
userId, userId,
teamId, teamId,
fieldId, fieldId,
documentId, documentId,
templateId, templateId,
}: GetFieldByIdOptions) => { }: GetFieldByIdOptions): Promise<TGetFieldByIdResponse> => {
const field = await prisma.field.findFirst({ const field = await prisma.field.findFirst({
where: { where: {
id: fieldId, id: fieldId,
@@ -45,5 +54,11 @@ export const getFieldById = async ({
}, },
}); });
if (!field) {
throw new AppError(AppErrorCode.NOT_FOUND, {
message: 'Field not found',
});
}
return field; return field;
}; };

View File

@@ -1,4 +1,5 @@
import { isDeepEqual } from 'remeda'; import { isDeepEqual } from 'remeda';
import { z } from 'zod';
import { validateCheckboxField } from '@documenso/lib/advanced-fields-validation/validate-checkbox'; import { validateCheckboxField } from '@documenso/lib/advanced-fields-validation/validate-checkbox';
import { validateDropdownField } from '@documenso/lib/advanced-fields-validation/validate-dropdown'; import { validateDropdownField } from '@documenso/lib/advanced-fields-validation/validate-dropdown';
@@ -23,6 +24,7 @@ import {
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import type { Field } from '@documenso/prisma/client'; import type { Field } from '@documenso/prisma/client';
import { FieldType } from '@documenso/prisma/client'; import { FieldType } from '@documenso/prisma/client';
import { FieldSchema } from '@documenso/prisma/generated/zod';
import { AppError, AppErrorCode } from '../../errors/app-error'; import { AppError, AppErrorCode } from '../../errors/app-error';
import { canRecipientFieldsBeModified } from '../../utils/recipients'; import { canRecipientFieldsBeModified } from '../../utils/recipients';
@@ -34,12 +36,18 @@ export interface SetFieldsForDocumentOptions {
requestMetadata?: RequestMetadata; requestMetadata?: RequestMetadata;
} }
export const ZSetFieldsForDocumentResponseSchema = z.object({
fields: z.array(FieldSchema),
});
export type TSetFieldsForDocumentResponse = z.infer<typeof ZSetFieldsForDocumentResponseSchema>;
export const setFieldsForDocument = async ({ export const setFieldsForDocument = async ({
userId, userId,
documentId, documentId,
fields, fields,
requestMetadata, requestMetadata,
}: SetFieldsForDocumentOptions): Promise<Field[]> => { }: SetFieldsForDocumentOptions): Promise<TSetFieldsForDocumentResponse> => {
const document = await prisma.document.findFirst({ const document = await prisma.document.findFirst({
where: { where: {
id: documentId, id: documentId,
@@ -75,11 +83,15 @@ export const setFieldsForDocument = async ({
}); });
if (!document) { if (!document) {
throw new Error('Document not found'); throw new AppError(AppErrorCode.NOT_FOUND, {
message: 'Document not found',
});
} }
if (document.completedAt) { if (document.completedAt) {
throw new Error('Document already complete'); throw new AppError(AppErrorCode.INVALID_REQUEST, {
message: 'Document already complete',
});
} }
const existingFields = await prisma.field.findMany({ const existingFields = await prisma.field.findMany({
@@ -335,7 +347,9 @@ export const setFieldsForDocument = async ({
return !isRemoved && !isUpdated; return !isRemoved && !isUpdated;
}); });
return [...filteredFields, ...persistedFields]; return {
fields: [...filteredFields, ...persistedFields],
};
}; };
/** /**

View File

@@ -1,3 +1,5 @@
import { z } from 'zod';
import { validateCheckboxField } from '@documenso/lib/advanced-fields-validation/validate-checkbox'; import { validateCheckboxField } from '@documenso/lib/advanced-fields-validation/validate-checkbox';
import { validateDropdownField } from '@documenso/lib/advanced-fields-validation/validate-dropdown'; import { validateDropdownField } from '@documenso/lib/advanced-fields-validation/validate-dropdown';
import { validateNumberField } from '@documenso/lib/advanced-fields-validation/validate-number'; import { validateNumberField } from '@documenso/lib/advanced-fields-validation/validate-number';
@@ -14,6 +16,7 @@ import {
} from '@documenso/lib/types/field-meta'; } from '@documenso/lib/types/field-meta';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import { FieldType } from '@documenso/prisma/client'; import { FieldType } from '@documenso/prisma/client';
import { FieldSchema } from '@documenso/prisma/generated/zod';
export type SetFieldsForTemplateOptions = { export type SetFieldsForTemplateOptions = {
userId: number; userId: number;
@@ -31,11 +34,17 @@ export type SetFieldsForTemplateOptions = {
}[]; }[];
}; };
export const ZSetFieldsForTemplateResponseSchema = z.object({
fields: z.array(FieldSchema),
});
export type TSetFieldsForTemplateResponse = z.infer<typeof ZSetFieldsForTemplateResponseSchema>;
export const setFieldsForTemplate = async ({ export const setFieldsForTemplate = async ({
userId, userId,
templateId, templateId,
fields, fields,
}: SetFieldsForTemplateOptions) => { }: SetFieldsForTemplateOptions): Promise<TSetFieldsForTemplateResponse> => {
const template = await prisma.template.findFirst({ const template = await prisma.template.findFirst({
where: { where: {
id: templateId, id: templateId,
@@ -206,5 +215,7 @@ export const setFieldsForTemplate = async ({
return !isRemoved && !isUpdated; return !isRemoved && !isUpdated;
}); });
return [...filteredFields, ...persistedFields]; return {
fields: [...filteredFields, ...persistedFields],
};
}; };

View File

@@ -8,6 +8,7 @@ import { validateDropdownField } from '@documenso/lib/advanced-fields-validation
import { validateNumberField } from '@documenso/lib/advanced-fields-validation/validate-number'; import { validateNumberField } from '@documenso/lib/advanced-fields-validation/validate-number';
import { validateRadioField } from '@documenso/lib/advanced-fields-validation/validate-radio'; import { validateRadioField } from '@documenso/lib/advanced-fields-validation/validate-radio';
import { validateTextField } from '@documenso/lib/advanced-fields-validation/validate-text'; import { validateTextField } from '@documenso/lib/advanced-fields-validation/validate-text';
import { fromCheckboxValue } from '@documenso/lib/universal/field-checkbox';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import { DocumentStatus, FieldType, SigningStatus } from '@documenso/prisma/client'; import { DocumentStatus, FieldType, SigningStatus } from '@documenso/prisma/client';
@@ -119,7 +120,8 @@ export const signFieldWithToken = async ({
if (field.type === FieldType.CHECKBOX && field.fieldMeta) { if (field.type === FieldType.CHECKBOX && field.fieldMeta) {
const checkboxFieldParsedMeta = ZCheckboxFieldMeta.parse(field.fieldMeta); const checkboxFieldParsedMeta = ZCheckboxFieldMeta.parse(field.fieldMeta);
const checkboxFieldValues = value.split(','); const checkboxFieldValues: string[] = fromCheckboxValue(value);
const errors = validateCheckboxField(checkboxFieldValues, checkboxFieldParsedMeta, true); const errors = validateCheckboxField(checkboxFieldValues, checkboxFieldParsedMeta, true);
if (errors.length > 0) { if (errors.length > 0) {

View File

@@ -1,9 +1,11 @@
import type { PDFField, PDFWidgetAnnotation } from 'pdf-lib'; import type { PDFField, PDFWidgetAnnotation } from 'pdf-lib';
import { PDFCheckBox, PDFRadioGroup, PDFRef } from 'pdf-lib';
import { import {
PDFCheckBox,
PDFDict, PDFDict,
type PDFDocument, type PDFDocument,
PDFName, PDFName,
PDFRadioGroup,
PDFRef,
drawObject, drawObject,
popGraphicsState, popGraphicsState,
pushGraphicsState, pushGraphicsState,
@@ -11,7 +13,17 @@ import {
translate, translate,
} from 'pdf-lib'; } from 'pdf-lib';
export const removeOptionalContentGroups = (document: PDFDocument) => {
const context = document.context;
const catalog = context.lookup(context.trailerInfo.Root);
if (catalog instanceof PDFDict) {
catalog.delete(PDFName.of('OCProperties'));
}
};
export const flattenForm = (document: PDFDocument) => { export const flattenForm = (document: PDFDocument) => {
removeOptionalContentGroups(document);
const form = document.getForm(); const form = document.getForm();
form.updateFieldAppearances(); form.updateFieldAppearances();

View File

@@ -10,6 +10,7 @@ import {
MIN_HANDWRITING_FONT_SIZE, MIN_HANDWRITING_FONT_SIZE,
MIN_STANDARD_FONT_SIZE, MIN_STANDARD_FONT_SIZE,
} from '@documenso/lib/constants/pdf'; } from '@documenso/lib/constants/pdf';
import { fromCheckboxValue } from '@documenso/lib/universal/field-checkbox';
import { FieldType } from '@documenso/prisma/client'; import { FieldType } from '@documenso/prisma/client';
import { isSignatureFieldType } from '@documenso/prisma/guards/is-signature-field'; import { isSignatureFieldType } from '@documenso/prisma/guards/is-signature-field';
import type { FieldWithSignature } from '@documenso/prisma/types/field-with-signature'; import type { FieldWithSignature } from '@documenso/prisma/types/field-with-signature';
@@ -194,7 +195,7 @@ export const insertFieldInPDF = async (pdf: PDFDocument, field: FieldWithSignatu
value: item.value.length > 0 ? item.value : `empty-value-${item.id}`, value: item.value.length > 0 ? item.value : `empty-value-${item.id}`,
})); }));
const selected = field.customText.split(','); const selected: string[] = fromCheckboxValue(field.customText);
for (const [index, item] of (values ?? []).entries()) { for (const [index, item] of (values ?? []).entries()) {
const offsetY = index * 16; const offsetY = index * 16;

View File

@@ -0,0 +1,18 @@
import { PDFDocument } from 'pdf-lib';
import { flattenAnnotations } from './flatten-annotations';
import { flattenForm, removeOptionalContentGroups } from './flatten-form';
export const normalizePdf = async (pdf: Buffer) => {
const pdfDoc = await PDFDocument.load(pdf).catch(() => null);
if (!pdfDoc) {
return pdf;
}
removeOptionalContentGroups(pdfDoc);
flattenForm(pdfDoc);
flattenAnnotations(pdfDoc);
return Buffer.from(await pdfDoc.save());
};

View File

@@ -0,0 +1,21 @@
import { prisma } from '@documenso/prisma';
export type GetRecipientByIdOptions = {
id: number;
documentId: number;
};
export const getRecipientByIdV1Api = async ({ documentId, id }: GetRecipientByIdOptions) => {
const recipient = await prisma.recipient.findFirst({
where: {
documentId,
id,
},
});
if (!recipient) {
throw new Error('Recipient not found');
}
return recipient;
};

View File

@@ -1,20 +1,54 @@
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import { AppError, AppErrorCode } from '../../errors/app-error';
export type GetRecipientByIdOptions = { export type GetRecipientByIdOptions = {
id: number; recipientId: number;
documentId: number; userId: number;
teamId?: number;
}; };
export const getRecipientById = async ({ documentId, id }: GetRecipientByIdOptions) => { /**
* Get a recipient by ID. This will also return the recipient signing token so
* be careful when using this.
*/
export const getRecipientById = async ({
recipientId,
userId,
teamId,
}: GetRecipientByIdOptions) => {
const recipient = await prisma.recipient.findFirst({ const recipient = await prisma.recipient.findFirst({
where: { where: {
documentId, id: recipientId,
id, Document: {
OR: [
teamId === undefined
? {
userId,
teamId: null,
}
: {
teamId,
team: {
members: {
some: {
userId,
},
},
},
},
],
},
},
include: {
Field: true,
}, },
}); });
if (!recipient) { if (!recipient) {
throw new Error('Recipient not found'); throw new AppError(AppErrorCode.NOT_FOUND, {
message: 'Recipient not found',
});
} }
return recipient; return recipient;

View File

@@ -45,7 +45,7 @@ export const setRecipientsForDocument = async ({
documentId, documentId,
recipients, recipients,
requestMetadata, requestMetadata,
}: SetRecipientsForDocumentOptions): Promise<Recipient[]> => { }: SetRecipientsForDocumentOptions) => {
const document = await prisma.document.findFirst({ const document = await prisma.document.findFirst({
where: { where: {
id: documentId, id: documentId,
@@ -344,7 +344,9 @@ export const setRecipientsForDocument = async ({
return !isRemoved && !isUpdated; return !isRemoved && !isUpdated;
}); });
return [...filteredRecipients, ...persistedRecipients]; return {
recipients: [...filteredRecipients, ...persistedRecipients],
};
}; };
/** /**

View File

@@ -220,5 +220,7 @@ export const setRecipientsForTemplate = async ({
return !isRemoved && !isUpdated; return !isRemoved && !isUpdated;
}); });
return [...filteredRecipients, ...persistedRecipients]; return {
recipients: [...filteredRecipients, ...persistedRecipients],
};
}; };

View File

@@ -1,3 +1,5 @@
import type { z } from 'zod';
import { nanoid } from '@documenso/lib/universal/id'; import { nanoid } from '@documenso/lib/universal/id';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import type { DocumentDistributionMethod } from '@documenso/prisma/client'; import type { DocumentDistributionMethod } from '@documenso/prisma/client';
@@ -11,6 +13,11 @@ import {
SigningStatus, SigningStatus,
WebhookTriggerEvents, WebhookTriggerEvents,
} from '@documenso/prisma/client'; } from '@documenso/prisma/client';
import {
DocumentDataSchema,
DocumentSchema,
RecipientSchema,
} from '@documenso/prisma/generated/zod';
import type { SupportedLanguageCodes } from '../../constants/i18n'; import type { SupportedLanguageCodes } from '../../constants/i18n';
import { AppError, AppErrorCode } from '../../errors/app-error'; import { AppError, AppErrorCode } from '../../errors/app-error';
@@ -36,10 +43,6 @@ type FinalRecipient = Pick<
fields: Field[]; fields: Field[];
}; };
export type CreateDocumentFromTemplateResponse = Awaited<
ReturnType<typeof createDocumentFromTemplate>
>;
export type CreateDocumentFromTemplateOptions = { export type CreateDocumentFromTemplateOptions = {
templateId: number; templateId: number;
externalId?: string | null; externalId?: string | null;
@@ -72,6 +75,15 @@ export type CreateDocumentFromTemplateOptions = {
requestMetadata?: RequestMetadata; requestMetadata?: RequestMetadata;
}; };
export const ZCreateDocumentFromTemplateResponseSchema = DocumentSchema.extend({
documentData: DocumentDataSchema,
Recipient: RecipientSchema.array(),
});
export type TCreateDocumentFromTemplateResponse = z.infer<
typeof ZCreateDocumentFromTemplateResponseSchema
>;
export const createDocumentFromTemplate = async ({ export const createDocumentFromTemplate = async ({
templateId, templateId,
externalId, externalId,
@@ -80,7 +92,7 @@ export const createDocumentFromTemplate = async ({
recipients, recipients,
override, override,
requestMetadata, requestMetadata,
}: CreateDocumentFromTemplateOptions) => { }: CreateDocumentFromTemplateOptions): Promise<TCreateDocumentFromTemplateResponse> => {
const user = await prisma.user.findFirstOrThrow({ const user = await prisma.user.findFirstOrThrow({
where: { where: {
id: userId, id: userId,

View File

@@ -7,7 +7,7 @@ import {
DIRECT_TEMPLATE_RECIPIENT_NAME, DIRECT_TEMPLATE_RECIPIENT_NAME,
} from '@documenso/lib/constants/direct-templates'; } from '@documenso/lib/constants/direct-templates';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import type { Recipient, TemplateDirectLink } from '@documenso/prisma/client'; import type { Recipient } from '@documenso/prisma/client';
import { AppError, AppErrorCode } from '../../errors/app-error'; import { AppError, AppErrorCode } from '../../errors/app-error';
@@ -21,7 +21,7 @@ export const createTemplateDirectLink = async ({
templateId, templateId,
userId, userId,
directRecipientId, directRecipientId,
}: CreateTemplateDirectLinkOptions): Promise<TemplateDirectLink> => { }: CreateTemplateDirectLinkOptions) => {
const template = await prisma.template.findFirst({ const template = await prisma.template.findFirst({
where: { where: {
id: templateId, id: templateId,

View File

@@ -1,7 +1,7 @@
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import type { Prisma, Template } from '@documenso/prisma/client'; import type { Prisma, Template } from '@documenso/prisma/client';
import type { FindResultResponse } from '../../types/search-params'; import { type FindResultResponse } from '../../types/search-params';
export type FindTemplatesOptions = { export type FindTemplatesOptions = {
userId: number; userId: number;
@@ -11,9 +11,6 @@ export type FindTemplatesOptions = {
perPage?: number; perPage?: number;
}; };
export type FindTemplatesResponse = Awaited<ReturnType<typeof findTemplates>>;
export type FindTemplateRow = FindTemplatesResponse['data'][number];
export const findTemplates = async ({ export const findTemplates = async ({
userId, userId,
teamId, teamId,

View File

@@ -1,16 +1,5 @@
import type { z } from 'zod';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import type { Prisma } from '@documenso/prisma/client'; import type { Prisma } from '@documenso/prisma/client';
import {
DocumentDataSchema,
FieldSchema,
RecipientSchema,
TemplateDirectLinkSchema,
TemplateMetaSchema,
TemplateSchema,
UserSchema,
} from '@documenso/prisma/generated/zod';
import { AppError, AppErrorCode } from '../../errors/app-error'; import { AppError, AppErrorCode } from '../../errors/app-error';
@@ -20,26 +9,7 @@ export type GetTemplateByIdOptions = {
teamId?: number; teamId?: number;
}; };
export const ZGetTemplateByIdResponseSchema = TemplateSchema.extend({ export const getTemplateById = async ({ id, userId, teamId }: GetTemplateByIdOptions) => {
directLink: TemplateDirectLinkSchema.nullable(),
templateDocumentData: DocumentDataSchema,
templateMeta: TemplateMetaSchema.nullable(),
Recipient: RecipientSchema.array(),
Field: FieldSchema.array(),
User: UserSchema.pick({
id: true,
name: true,
email: true,
}),
});
export type TGetTemplateByIdResponse = z.infer<typeof ZGetTemplateByIdResponseSchema>;
export const getTemplateById = async ({
id,
userId,
teamId,
}: GetTemplateByIdOptions): Promise<TGetTemplateByIdResponse> => {
const whereFilter: Prisma.TemplateWhereInput = { const whereFilter: Prisma.TemplateWhereInput = {
id, id,
OR: OR:

View File

@@ -1,7 +1,7 @@
import { TRPCError } from '@trpc/server';
import { prisma } from '@documenso/prisma'; import { prisma } from '@documenso/prisma';
import { AppError, AppErrorCode } from '../../errors/app-error';
export type MoveTemplateToTeamOptions = { export type MoveTemplateToTeamOptions = {
templateId: number; templateId: number;
teamId: number; teamId: number;
@@ -23,8 +23,7 @@ export const moveTemplateToTeam = async ({
}); });
if (!template) { if (!template) {
throw new TRPCError({ throw new AppError(AppErrorCode.NOT_FOUND, {
code: 'NOT_FOUND',
message: 'Template not found or already associated with a team.', message: 'Template not found or already associated with a team.',
}); });
} }
@@ -41,9 +40,8 @@ export const moveTemplateToTeam = async ({
}); });
if (!team) { if (!team) {
throw new TRPCError({ throw new AppError(AppErrorCode.UNAUTHORIZED, {
code: 'FORBIDDEN', message: 'Team does not exist or you are not a member of this team.',
message: 'You are not a member of this team.',
}); });
} }

View File

@@ -0,0 +1,69 @@
import { AppError } from '@documenso/lib/errors/app-error';
import { prisma } from '@documenso/prisma';
export type DisableUserOptions = {
id: number;
};
export const disableUser = async ({ id }: DisableUserOptions) => {
const user = await prisma.user.findFirst({
where: {
id,
},
include: {
ApiToken: true,
Webhooks: true,
passkeys: true,
VerificationToken: true,
PasswordResetToken: true,
},
});
if (!user) {
throw new AppError('There was an error disabling the user');
}
try {
await prisma.$transaction(async (tx) => {
await tx.user.update({
where: { id },
data: { disabled: true },
});
await tx.apiToken.updateMany({
where: { userId: id },
data: {
expires: new Date(),
},
});
await tx.webhook.updateMany({
where: { userId: id },
data: {
enabled: false,
},
});
await tx.verificationToken.updateMany({
where: { userId: id },
data: {
expires: new Date(),
},
});
await tx.passwordResetToken.updateMany({
where: { userId: id },
data: {
expiry: new Date(),
},
});
await tx.passkey.deleteMany({
where: { userId: id },
});
});
} catch (error) {
console.error('Error disabling user', error);
throw error;
}
};

View File

@@ -0,0 +1,27 @@
import { AppError } from '@documenso/lib/errors/app-error';
import { prisma } from '@documenso/prisma';
export type EnableUserOptions = {
id: number;
};
export const enableUser = async ({ id }: EnableUserOptions) => {
const user = await prisma.user.findFirst({
where: {
id,
},
});
if (!user) {
throw new AppError('There was an error enabling the user');
}
await prisma.user.update({
where: {
id,
},
data: {
disabled: false,
},
});
};

View File

@@ -30,11 +30,11 @@ msgstr "„{documentName}“ wurde unterschrieben"
msgid "“{documentName}” was signed by all signers" msgid "“{documentName}” was signed by all signers"
msgstr "„{documentName}“ wurde von allen Unterzeichnern signiert" msgstr "„{documentName}“ wurde von allen Unterzeichnern signiert"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:137 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:125
msgid "{0} has invited you to {recipientActionVerb} the document \"{1}\"." msgid "{0} has invited you to {recipientActionVerb} the document \"{1}\"."
msgstr "{0} hat Sie eingeladen, das Dokument \"{1}\" {recipientActionVerb}." msgstr "{0} hat Sie eingeladen, das Dokument \"{1}\" {recipientActionVerb}."
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:130 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:118
msgid "{0} invited you to {recipientActionVerb} a document" msgid "{0} invited you to {recipientActionVerb} a document"
msgstr "{0} hat dich eingeladen, ein Dokument {recipientActionVerb}" msgstr "{0} hat dich eingeladen, ein Dokument {recipientActionVerb}"
@@ -50,7 +50,7 @@ msgstr "{0} hat das Team {teamName} bei Documenso verlassen"
msgid "{0} of {1} row(s) selected." msgid "{0} of {1} row(s) selected."
msgstr "{0} von {1} Zeile(n) ausgewählt." msgstr "{0} von {1} Zeile(n) ausgewählt."
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:136 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:124
#: packages/lib/server-only/document/resend-document.tsx:137 #: packages/lib/server-only/document/resend-document.tsx:137
msgid "{0} on behalf of \"{1}\" has invited you to {recipientActionVerb} the document \"{2}\"." msgid "{0} on behalf of \"{1}\" has invited you to {recipientActionVerb} the document \"{2}\"."
msgstr "" msgstr ""
@@ -195,6 +195,22 @@ msgstr "{recipientName} {action} ein Dokument, indem Sie einen Ihrer direkten Li
msgid "{recipientName} has rejected the document '{documentName}'" msgid "{recipientName} has rejected the document '{documentName}'"
msgstr "{recipientName} hat das Dokument '{documentName}' abgelehnt" msgstr "{recipientName} hat das Dokument '{documentName}' abgelehnt"
#: packages/email/template-components/template-document-recipient-signed.tsx:49
msgid "{recipientReference} has completed signing the document."
msgstr ""
#: packages/lib/jobs/definitions/emails/send-recipient-signed-email.ts:121
msgid "{recipientReference} has signed \"{0}\""
msgstr ""
#: packages/email/template-components/template-document-recipient-signed.tsx:43
msgid "{recipientReference} has signed \"{documentName}\""
msgstr ""
#: packages/email/templates/document-recipient-signed.tsx:27
msgid "{recipientReference} has signed {documentName}"
msgstr ""
#: packages/email/template-components/template-document-rejected.tsx:25 #: packages/email/template-components/template-document-rejected.tsx:25
msgid "{signerName} has rejected the document \"{documentName}\"." msgid "{signerName} has rejected the document \"{documentName}\"."
msgstr "{signerName} hat das Dokument \"{documentName}\" abgelehnt." msgstr "{signerName} hat das Dokument \"{documentName}\" abgelehnt."
@@ -289,7 +305,7 @@ msgstr "<0>Konto erforderlich</0> - Der Empfänger muss angemeldet sein, um das
msgid "<0>Require passkey</0> - The recipient must have an account and passkey configured via their settings" msgid "<0>Require passkey</0> - The recipient must have an account and passkey configured via their settings"
msgstr "<0>Passkey erforderlich</0> - Der Empfänger muss ein Konto haben und den Passkey über seine Einstellungen konfiguriert haben" msgstr "<0>Passkey erforderlich</0> - Der Empfänger muss ein Konto haben und den Passkey über seine Einstellungen konfiguriert haben"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:122 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:110
msgid "A document was created by your direct template that requires you to {recipientActionVerb} it." msgid "A document was created by your direct template that requires you to {recipientActionVerb} it."
msgstr "Ein Dokument wurde von deiner direkten Vorlage erstellt, das erfordert, dass du {recipientActionVerb}." msgstr "Ein Dokument wurde von deiner direkten Vorlage erstellt, das erfordert, dass du {recipientActionVerb}."
@@ -305,7 +321,7 @@ msgstr "Ein Feld wurde entfernt"
msgid "A field was updated" msgid "A field was updated"
msgstr "Ein Feld wurde aktualisiert" msgstr "Ein Feld wurde aktualisiert"
#: packages/lib/jobs/definitions/emails/send-team-member-joined-email.ts:107 #: packages/lib/jobs/definitions/emails/send-team-member-joined-email.handler.ts:98
msgid "A new member has joined your team" msgid "A new member has joined your team"
msgstr "Ein neues Mitglied ist deinem Team beigetreten" msgstr "Ein neues Mitglied ist deinem Team beigetreten"
@@ -329,7 +345,7 @@ msgstr "Eine Anfrage zur Verwendung Ihrer E-Mail wurde von {0} auf Documenso ini
msgid "A team member has joined a team on Documenso" msgid "A team member has joined a team on Documenso"
msgstr "Ein Teammitglied ist einem Team bei Documenso beigetreten" msgstr "Ein Teammitglied ist einem Team bei Documenso beigetreten"
#: packages/lib/jobs/definitions/emails/send-team-member-left-email.ts:96 #: packages/lib/jobs/definitions/emails/send-team-member-left-email.handler.ts:87
msgid "A team member has left {0}" msgid "A team member has left {0}"
msgstr "Ein Teammitglied hat {0} verlassen" msgstr "Ein Teammitglied hat {0} verlassen"
@@ -364,12 +380,12 @@ msgstr "Übertragungsanfrage des Teams auf Documenso annehmen"
msgid "Add a document" msgid "Add a document"
msgstr "Dokument hinzufügen" msgstr "Dokument hinzufügen"
#: packages/ui/primitives/document-flow/add-settings.tsx:378 #: packages/ui/primitives/document-flow/add-settings.tsx:390
#: packages/ui/primitives/template-flow/add-template-settings.tsx:468 #: packages/ui/primitives/template-flow/add-template-settings.tsx:468
msgid "Add a URL to redirect the user to once the document is signed" msgid "Add a URL to redirect the user to once the document is signed"
msgstr "Fügen Sie eine URL hinzu, um den Benutzer nach der Unterzeichnung des Dokuments weiterzuleiten" msgstr "Fügen Sie eine URL hinzu, um den Benutzer nach der Unterzeichnung des Dokuments weiterzuleiten"
#: packages/ui/primitives/document-flow/add-settings.tsx:290 #: packages/ui/primitives/document-flow/add-settings.tsx:302
msgid "Add an external ID to the document. This can be used to identify the document in external systems." msgid "Add an external ID to the document. This can be used to identify the document in external systems."
msgstr "Fügen Sie dem Dokument eine externe ID hinzu. Diese kann verwendet werden, um das Dokument in externen Systemen zu identifizieren." msgstr "Fügen Sie dem Dokument eine externe ID hinzu. Diese kann verwendet werden, um das Dokument in externen Systemen zu identifizieren."
@@ -414,13 +430,13 @@ msgstr "Text zum Feld hinzufügen"
msgid "Admin" msgid "Admin"
msgstr "Admin" msgstr "Admin"
#: packages/ui/primitives/document-flow/add-settings.tsx:272 #: packages/ui/primitives/document-flow/add-settings.tsx:284
#: packages/ui/primitives/template-flow/add-template-settings.tsx:367 #: packages/ui/primitives/template-flow/add-template-settings.tsx:367
msgid "Advanced Options" msgid "Advanced Options"
msgstr "Erweiterte Optionen" msgstr "Erweiterte Optionen"
#: packages/ui/primitives/document-flow/add-fields.tsx:576 #: packages/ui/primitives/document-flow/add-fields.tsx:577
#: packages/ui/primitives/template-flow/add-template-fields.tsx:414 #: packages/ui/primitives/template-flow/add-template-fields.tsx:415
msgid "Advanced settings" msgid "Advanced settings"
msgstr "Erweiterte Einstellungen" msgstr "Erweiterte Einstellungen"
@@ -472,11 +488,11 @@ msgstr "Genehmigung"
msgid "Before you get started, please confirm your email address by clicking the button below:" 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:" 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:524 #: packages/ui/primitives/signature-pad/signature-pad.tsx:531
msgid "Black" msgid "Black"
msgstr "Schwarz" msgstr "Schwarz"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:538 #: packages/ui/primitives/signature-pad/signature-pad.tsx:545
msgid "Blue" msgid "Blue"
msgstr "Blau" msgstr "Blau"
@@ -492,7 +508,7 @@ msgstr "Durch die Annahme dieser Anfrage gewähren Sie <0>{teamName}</0> Zugriff
msgid "By accepting this request, you will take responsibility for any billing items associated with this team." msgid "By accepting this request, you will take responsibility for any billing items associated with this team."
msgstr "Indem du diese Anfrage annimmst, übernimmst du die Verantwortung für alle Abrechnungspunkte, die mit diesem Team verbunden sind." msgstr "Indem du diese Anfrage annimmst, übernimmst du die Verantwortung für alle Abrechnungspunkte, die mit diesem Team verbunden sind."
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:356 #: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:357
#: packages/ui/primitives/document-flow/send-document-action-dialog.tsx:58 #: packages/ui/primitives/document-flow/send-document-action-dialog.tsx:58
msgid "Cancel" msgid "Cancel"
msgstr "Abbrechen" msgstr "Abbrechen"
@@ -534,7 +550,7 @@ msgstr "Checkbox-Werte"
msgid "Clear filters" msgid "Clear filters"
msgstr "Filter löschen" msgstr "Filter löschen"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:558 #: packages/ui/primitives/signature-pad/signature-pad.tsx:565
msgid "Clear Signature" msgid "Clear Signature"
msgstr "Unterschrift löschen" msgstr "Unterschrift löschen"
@@ -547,6 +563,7 @@ msgid "Close"
msgstr "Schließen" msgstr "Schließen"
#: packages/email/template-components/template-document-completed.tsx:35 #: packages/email/template-components/template-document-completed.tsx:35
#: packages/email/template-components/template-document-recipient-signed.tsx:37
#: packages/email/template-components/template-document-self-signed.tsx:36 #: packages/email/template-components/template-document-self-signed.tsx:36
#: packages/lib/constants/document.ts:10 #: packages/lib/constants/document.ts:10
msgid "Completed" msgid "Completed"
@@ -561,8 +578,8 @@ msgstr "Abgeschlossenes Dokument"
msgid "Configure Direct Recipient" msgid "Configure Direct Recipient"
msgstr "Direkten Empfänger konfigurieren" msgstr "Direkten Empfänger konfigurieren"
#: packages/ui/primitives/document-flow/add-fields.tsx:577 #: packages/ui/primitives/document-flow/add-fields.tsx:578
#: packages/ui/primitives/template-flow/add-template-fields.tsx:415 #: packages/ui/primitives/template-flow/add-template-fields.tsx:416
msgid "Configure the {0} field" msgid "Configure the {0} field"
msgstr "Konfigurieren Sie das Feld {0}" msgstr "Konfigurieren Sie das Feld {0}"
@@ -619,13 +636,13 @@ msgstr "Konto erstellen"
msgid "Custom Text" msgid "Custom Text"
msgstr "Benutzerdefinierter Text" msgstr "Benutzerdefinierter Text"
#: packages/ui/primitives/document-flow/add-fields.tsx:934 #: packages/ui/primitives/document-flow/add-fields.tsx:938
#: packages/ui/primitives/document-flow/types.ts:53 #: 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:733
msgid "Date" msgid "Date"
msgstr "Datum" msgstr "Datum"
#: packages/ui/primitives/document-flow/add-settings.tsx:313 #: packages/ui/primitives/document-flow/add-settings.tsx:325
#: packages/ui/primitives/template-flow/add-template-settings.tsx:408 #: packages/ui/primitives/template-flow/add-template-settings.tsx:408
msgid "Date Format" msgid "Date Format"
msgstr "Datumsformat" msgstr "Datumsformat"
@@ -642,16 +659,16 @@ msgstr "Hast du keinen Passwortwechsel angefordert? Wir helfen dir, dein Konto a
msgid "Direct link receiver" msgid "Direct link receiver"
msgstr "Empfänger des direkten Links" msgstr "Empfänger des direkten Links"
#: packages/lib/jobs/definitions/emails/send-rejection-emails.ts:149 #: packages/lib/jobs/definitions/emails/send-rejection-emails.handler.ts:140
msgid "Document \"{0}\" - Rejected by {1}" msgid "Document \"{0}\" - Rejected by {1}"
msgstr "Dokument \"{0}\" - Abgelehnt von {1}" msgstr "Dokument \"{0}\" - Abgelehnt von {1}"
#: packages/lib/jobs/definitions/emails/send-rejection-emails.ts:109 #: packages/lib/jobs/definitions/emails/send-rejection-emails.handler.ts:100
msgid "Document \"{0}\" - Rejection Confirmed" msgid "Document \"{0}\" - Rejection Confirmed"
msgstr "Dokument \"{0}\" - Ablehnung Bestätigt" msgstr "Dokument \"{0}\" - Ablehnung Bestätigt"
#: packages/ui/components/document/document-global-auth-access-select.tsx:62 #: packages/ui/components/document/document-global-auth-access-select.tsx:62
#: packages/ui/primitives/document-flow/add-settings.tsx:216 #: packages/ui/primitives/document-flow/add-settings.tsx:227
#: packages/ui/primitives/template-flow/add-template-settings.tsx:202 #: packages/ui/primitives/template-flow/add-template-settings.tsx:202
msgid "Document access" msgid "Document access"
msgstr "Dokumentenzugriff" msgstr "Dokumentenzugriff"
@@ -670,7 +687,8 @@ msgstr "Dokument storniert"
msgid "Document completed" msgid "Document completed"
msgstr "Dokument abgeschlossen" msgstr "Dokument abgeschlossen"
#: packages/ui/components/document/document-email-checkboxes.tsx:168 #: packages/ui/components/document/document-email-checkboxes.tsx:208
#: packages/ui/components/document/document-email-checkboxes.tsx:286
msgid "Document completed email" msgid "Document completed email"
msgstr "E-Mail zum Abschluss des Dokuments" msgstr "E-Mail zum Abschluss des Dokuments"
@@ -679,7 +697,7 @@ msgid "Document created"
msgstr "Dokument erstellt" msgstr "Dokument erstellt"
#: packages/email/templates/document-created-from-direct-template.tsx:32 #: packages/email/templates/document-created-from-direct-template.tsx:32
#: packages/lib/server-only/template/create-document-from-direct-template.ts:574 #: packages/lib/server-only/template/create-document-from-direct-template.ts:585
msgid "Document created from direct template" msgid "Document created from direct template"
msgstr "Dokument erstellt aus direkter Vorlage" msgstr "Dokument erstellt aus direkter Vorlage"
@@ -691,7 +709,7 @@ msgstr "Dokumenterstellung"
msgid "Document deleted" msgid "Document deleted"
msgstr "Dokument gelöscht" msgstr "Dokument gelöscht"
#: packages/ui/components/document/document-email-checkboxes.tsx:207 #: packages/ui/components/document/document-email-checkboxes.tsx:247
msgid "Document deleted email" msgid "Document deleted email"
msgstr "E-Mail zum Löschen des Dokuments" msgstr "E-Mail zum Löschen des Dokuments"
@@ -716,7 +734,7 @@ msgstr "Dokument ins Team verschoben"
msgid "Document opened" msgid "Document opened"
msgstr "Dokument geöffnet" msgstr "Dokument geöffnet"
#: packages/ui/components/document/document-email-checkboxes.tsx:128 #: packages/ui/components/document/document-email-checkboxes.tsx:168
msgid "Document pending email" msgid "Document pending email"
msgstr "E-Mail über ausstehende Dokumente" msgstr "E-Mail über ausstehende Dokumente"
@@ -757,8 +775,8 @@ msgstr "Entwurf"
msgid "Drag & drop your PDF here." msgid "Drag & drop your PDF here."
msgstr "Ziehen Sie Ihr PDF hierher." msgstr "Ziehen Sie Ihr PDF hierher."
#: packages/ui/primitives/document-flow/add-fields.tsx:1065 #: packages/ui/primitives/document-flow/add-fields.tsx:1069
#: packages/ui/primitives/template-flow/add-template-fields.tsx:860 #: packages/ui/primitives/template-flow/add-template-fields.tsx:864
msgid "Dropdown" msgid "Dropdown"
msgstr "Dropdown" msgstr "Dropdown"
@@ -767,12 +785,12 @@ msgid "Dropdown options"
msgstr "Dropdown-Optionen" msgstr "Dropdown-Optionen"
#: packages/lib/constants/document.ts:28 #: packages/lib/constants/document.ts:28
#: packages/ui/primitives/document-flow/add-fields.tsx:882 #: packages/ui/primitives/document-flow/add-fields.tsx:886
#: packages/ui/primitives/document-flow/add-signature.tsx:273 #: packages/ui/primitives/document-flow/add-signature.tsx:273
#: packages/ui/primitives/document-flow/add-signers.tsx:512 #: packages/ui/primitives/document-flow/add-signers.tsx:512
#: packages/ui/primitives/document-flow/add-signers.tsx:519 #: packages/ui/primitives/document-flow/add-signers.tsx:519
#: packages/ui/primitives/document-flow/types.ts:54 #: 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-fields.tsx:681
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:471 #: 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-placeholder-recipients.tsx:478
msgid "Email" msgid "Email"
@@ -794,7 +812,7 @@ msgstr "E-Mail erneut gesendet"
msgid "Email sent" msgid "Email sent"
msgstr "E-Mail gesendet" msgstr "E-Mail gesendet"
#: packages/ui/primitives/document-flow/add-fields.tsx:1130 #: packages/ui/primitives/document-flow/add-fields.tsx:1134
msgid "Empty field" msgid "Empty field"
msgstr "Leeres Feld" msgstr "Leeres Feld"
@@ -807,8 +825,8 @@ msgstr "Direktlink-Signierung aktivieren"
msgid "Enable signing order" msgid "Enable signing order"
msgstr "Aktiviere die Signaturreihenfolge" msgstr "Aktiviere die Signaturreihenfolge"
#: packages/ui/primitives/document-flow/add-fields.tsx:802 #: packages/ui/primitives/document-flow/add-fields.tsx:806
#: packages/ui/primitives/template-flow/add-template-fields.tsx:597 #: packages/ui/primitives/template-flow/add-template-fields.tsx:601
msgid "Enable Typed Signatures" msgid "Enable Typed Signatures"
msgstr "Aktivieren Sie getippte Unterschriften" msgstr "Aktivieren Sie getippte Unterschriften"
@@ -816,17 +834,17 @@ msgstr "Aktivieren Sie getippte Unterschriften"
msgid "Enter password" msgid "Enter password"
msgstr "Passwort eingeben" msgstr "Passwort eingeben"
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:257 #: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:258
#: packages/ui/primitives/pdf-viewer.tsx:166 #: packages/ui/primitives/pdf-viewer.tsx:166
msgid "Error" msgid "Error"
msgstr "Fehler" msgstr "Fehler"
#: packages/ui/primitives/document-flow/add-settings.tsx:283 #: packages/ui/primitives/document-flow/add-settings.tsx:295
#: packages/ui/primitives/template-flow/add-template-settings.tsx:378 #: packages/ui/primitives/template-flow/add-template-settings.tsx:378
msgid "External ID" msgid "External ID"
msgstr "Externe ID" msgstr "Externe ID"
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:258 #: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:259
msgid "Failed to save settings." msgid "Failed to save settings."
msgstr "Einstellungen konnten nicht gespeichert werden." msgstr "Einstellungen konnten nicht gespeichert werden."
@@ -896,7 +914,7 @@ msgstr "Globale Empfängerauthentifizierung"
msgid "Go Back" msgid "Go Back"
msgstr "Zurück" msgstr "Zurück"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:545 #: packages/ui/primitives/signature-pad/signature-pad.tsx:552
msgid "Green" msgid "Green"
msgstr "Grün" msgstr "Grün"
@@ -947,7 +965,7 @@ msgstr "Tritt {teamName} auf Documenso bei"
msgid "Label" msgid "Label"
msgstr "Beschriftung" msgstr "Beschriftung"
#: packages/ui/primitives/document-flow/add-settings.tsx:176 #: packages/ui/primitives/document-flow/add-settings.tsx:187
#: packages/ui/primitives/template-flow/add-template-settings.tsx:162 #: packages/ui/primitives/template-flow/add-template-settings.tsx:162
msgid "Language" msgid "Language"
msgstr "Sprache" msgstr "Sprache"
@@ -983,12 +1001,12 @@ msgstr "Nachricht <0>(Optional)</0>"
msgid "Min" msgid "Min"
msgstr "Min" msgstr "Min"
#: packages/ui/primitives/document-flow/add-fields.tsx:908 #: packages/ui/primitives/document-flow/add-fields.tsx:912
#: packages/ui/primitives/document-flow/add-signature.tsx:299 #: packages/ui/primitives/document-flow/add-signature.tsx:299
#: packages/ui/primitives/document-flow/add-signers.tsx:550 #: packages/ui/primitives/document-flow/add-signers.tsx:550
#: packages/ui/primitives/document-flow/add-signers.tsx:556 #: packages/ui/primitives/document-flow/add-signers.tsx:556
#: packages/ui/primitives/document-flow/types.ts:55 #: 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-fields.tsx:707
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:506 #: 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-placeholder-recipients.tsx:512
msgid "Name" msgid "Name"
@@ -1006,8 +1024,8 @@ msgstr "Muss unterzeichnen"
msgid "Needs to view" msgid "Needs to view"
msgstr "Muss sehen" msgstr "Muss sehen"
#: packages/ui/primitives/document-flow/add-fields.tsx:693 #: packages/ui/primitives/document-flow/add-fields.tsx:697
#: packages/ui/primitives/template-flow/add-template-fields.tsx:516 #: packages/ui/primitives/template-flow/add-template-fields.tsx:520
msgid "No recipient matching this description was found." msgid "No recipient matching this description was found."
msgstr "Kein passender Empfänger mit dieser Beschreibung gefunden." msgstr "Kein passender Empfänger mit dieser Beschreibung gefunden."
@@ -1015,8 +1033,8 @@ msgstr "Kein passender Empfänger mit dieser Beschreibung gefunden."
msgid "No recipients" msgid "No recipients"
msgstr "Keine Empfänger" msgstr "Keine Empfänger"
#: packages/ui/primitives/document-flow/add-fields.tsx:708 #: packages/ui/primitives/document-flow/add-fields.tsx:712
#: packages/ui/primitives/template-flow/add-template-fields.tsx:531 #: packages/ui/primitives/template-flow/add-template-fields.tsx:535
msgid "No recipients with this role" msgid "No recipients with this role"
msgstr "Keine Empfänger mit dieser Rolle" msgstr "Keine Empfänger mit dieser Rolle"
@@ -1044,9 +1062,9 @@ msgstr "Kein Wert gefunden."
msgid "None" msgid "None"
msgstr "Keine" msgstr "Keine"
#: packages/ui/primitives/document-flow/add-fields.tsx:986 #: packages/ui/primitives/document-flow/add-fields.tsx:990
#: packages/ui/primitives/document-flow/types.ts:56 #: 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:785
msgid "Number" msgid "Number"
msgstr "Nummer" msgstr "Nummer"
@@ -1112,15 +1130,15 @@ msgstr "Bitte {0} dein Dokument<0/>\"{documentName}\""
msgid "Please {action} your document {documentName}" msgid "Please {action} your document {documentName}"
msgstr "Bitte {action} dein Dokument {documentName}" msgstr "Bitte {action} dein Dokument {documentName}"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:111 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:99
msgid "Please {recipientActionVerb} this document" msgid "Please {recipientActionVerb} this document"
msgstr "Bitte {recipientActionVerb} dieses Dokument" msgstr "Bitte {recipientActionVerb} dieses Dokument"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:125 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:113
msgid "Please {recipientActionVerb} this document created by your direct template" msgid "Please {recipientActionVerb} this document created by your direct template"
msgstr "Bitte {recipientActionVerb} dieses Dokument, das von deiner direkten Vorlage erstellt wurde" msgstr "Bitte {recipientActionVerb} dieses Dokument, das von deiner direkten Vorlage erstellt wurde"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:117 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:105
msgid "Please {recipientActionVerb} your document" msgid "Please {recipientActionVerb} your document"
msgstr "Bitte {recipientActionVerb} dein Dokument" msgstr "Bitte {recipientActionVerb} dein Dokument"
@@ -1167,24 +1185,28 @@ msgid "Recipient"
msgstr "Empfänger" msgstr "Empfänger"
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:39 #: packages/ui/components/recipient/recipient-action-auth-select.tsx:39
#: packages/ui/primitives/document-flow/add-settings.tsx:257 #: packages/ui/primitives/document-flow/add-settings.tsx:269
#: packages/ui/primitives/template-flow/add-template-settings.tsx:291 #: packages/ui/primitives/template-flow/add-template-settings.tsx:291
msgid "Recipient action authentication" msgid "Recipient action authentication"
msgstr "Empfängeraktion Authentifizierung" msgstr "Empfängeraktion Authentifizierung"
#: packages/ui/components/document/document-email-checkboxes.tsx:89 #: packages/ui/components/document/document-email-checkboxes.tsx:129
msgid "Recipient removed email" msgid "Recipient removed email"
msgstr "E-Mail des entfernten Empfängers" msgstr "E-Mail des entfernten Empfängers"
#: packages/ui/components/document/document-email-checkboxes.tsx:50 #: packages/ui/components/document/document-email-checkboxes.tsx:51
msgid "Recipient signed email"
msgstr ""
#: packages/ui/components/document/document-email-checkboxes.tsx:90
msgid "Recipient signing request email" msgid "Recipient signing request email"
msgstr "E-Mail zur Unterzeichnungsanfrage des Empfängers" msgstr "E-Mail zur Unterzeichnungsanfrage des Empfängers"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:531 #: packages/ui/primitives/signature-pad/signature-pad.tsx:538
msgid "Red" msgid "Red"
msgstr "Rot" msgstr "Rot"
#: packages/ui/primitives/document-flow/add-settings.tsx:371 #: packages/ui/primitives/document-flow/add-settings.tsx:383
#: packages/ui/primitives/template-flow/add-template-settings.tsx:461 #: packages/ui/primitives/template-flow/add-template-settings.tsx:461
msgid "Redirect URL" msgid "Redirect URL"
msgstr "Weiterleitungs-URL" msgstr "Weiterleitungs-URL"
@@ -1217,7 +1239,7 @@ msgstr "Erinnerung: Bitte {recipientActionVerb} dieses Dokument"
msgid "Reminder: Please {recipientActionVerb} your document" msgid "Reminder: Please {recipientActionVerb} your document"
msgstr "Erinnerung: Bitte {recipientActionVerb} dein Dokument" msgstr "Erinnerung: Bitte {recipientActionVerb} dein Dokument"
#: packages/ui/primitives/document-flow/add-fields.tsx:1117 #: packages/ui/primitives/document-flow/add-fields.tsx:1121
msgid "Remove" msgid "Remove"
msgstr "Entfernen" msgstr "Entfernen"
@@ -1245,11 +1267,11 @@ msgstr "Seien Sie versichert, Ihr Dokument ist streng vertraulich und wird niema
msgid "Rows per page" msgid "Rows per page"
msgstr "Zeilen pro Seite" msgstr "Zeilen pro Seite"
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:355 #: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:356
msgid "Save" msgid "Save"
msgstr "Speichern" msgstr "Speichern"
#: packages/ui/primitives/template-flow/add-template-fields.tsx:893 #: packages/ui/primitives/template-flow/add-template-fields.tsx:897
msgid "Save Template" msgid "Save Template"
msgstr "Vorlage speichern" msgstr "Vorlage speichern"
@@ -1285,15 +1307,19 @@ msgstr "Senden"
msgid "Send Document" msgid "Send Document"
msgstr "Dokument senden" msgstr "Dokument senden"
#: packages/ui/components/document/document-email-checkboxes.tsx:158 #: packages/ui/components/document/document-email-checkboxes.tsx:198
msgid "Send document completed email" msgid "Send document completed email"
msgstr "E-Mail über den Abschluss des Dokuments senden" msgstr "E-Mail über den Abschluss des Dokuments senden"
#: packages/ui/components/document/document-email-checkboxes.tsx:197 #: packages/ui/components/document/document-email-checkboxes.tsx:276
msgid "Send document completed email to the owner"
msgstr ""
#: packages/ui/components/document/document-email-checkboxes.tsx:237
msgid "Send document deleted email" msgid "Send document deleted email"
msgstr "E-Mail über das Löschen des Dokuments senden" msgstr "E-Mail über das Löschen des Dokuments senden"
#: packages/ui/components/document/document-email-checkboxes.tsx:118 #: packages/ui/components/document/document-email-checkboxes.tsx:158
msgid "Send document pending email" msgid "Send document pending email"
msgstr "E-Mail über ausstehende Dokumente senden" msgstr "E-Mail über ausstehende Dokumente senden"
@@ -1301,11 +1327,15 @@ msgstr "E-Mail über ausstehende Dokumente senden"
msgid "Send documents on behalf of the team using the email address" msgid "Send documents on behalf of the team using the email address"
msgstr "Dokumente im Namen des Teams über die E-Mail-Adresse senden" msgstr "Dokumente im Namen des Teams über die E-Mail-Adresse senden"
#: packages/ui/components/document/document-email-checkboxes.tsx:79 #: packages/ui/components/document/document-email-checkboxes.tsx:119
msgid "Send recipient removed email" msgid "Send recipient removed email"
msgstr "E-Mail über entfernten Empfänger senden" msgstr "E-Mail über entfernten Empfänger senden"
#: packages/ui/components/document/document-email-checkboxes.tsx:40 #: packages/ui/components/document/document-email-checkboxes.tsx:41
msgid "Send recipient signed email"
msgstr ""
#: packages/ui/components/document/document-email-checkboxes.tsx:80
msgid "Send recipient signing request email" msgid "Send recipient signing request email"
msgstr "E-Mail über Unterzeichnungsanfrage des Empfängers senden" msgstr "E-Mail über Unterzeichnungsanfrage des Empfängers senden"
@@ -1338,11 +1368,11 @@ msgstr "Dokument signieren"
msgid "Sign In" msgid "Sign In"
msgstr "Anmelden" msgstr "Anmelden"
#: packages/ui/primitives/document-flow/add-fields.tsx:830 #: packages/ui/primitives/document-flow/add-fields.tsx:834
#: packages/ui/primitives/document-flow/add-signature.tsx:324 #: packages/ui/primitives/document-flow/add-signature.tsx:324
#: packages/ui/primitives/document-flow/field-icon.tsx:52 #: packages/ui/primitives/document-flow/field-icon.tsx:52
#: packages/ui/primitives/document-flow/types.ts:49 #: 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:629
msgid "Signature" msgid "Signature"
msgstr "Unterschrift" msgstr "Unterschrift"
@@ -1366,8 +1396,8 @@ msgstr "Unterzeichner müssen eindeutige E-Mails haben"
msgid "Signing" msgid "Signing"
msgstr "Unterzeichnung" msgstr "Unterzeichnung"
#: packages/lib/server-only/document/send-completed-email.ts:114 #: packages/lib/server-only/document/send-completed-email.ts:119
#: packages/lib/server-only/document/send-completed-email.ts:194 #: packages/lib/server-only/document/send-completed-email.ts:199
msgid "Signing Complete!" msgid "Signing Complete!"
msgstr "Unterzeichnung abgeschlossen!" msgstr "Unterzeichnung abgeschlossen!"
@@ -1421,9 +1451,9 @@ msgstr "Team-E-Mail für {teamName} auf Documenso entfernt"
msgid "Template title" msgid "Template title"
msgstr "Vorlagentitel" msgstr "Vorlagentitel"
#: packages/ui/primitives/document-flow/add-fields.tsx:960 #: packages/ui/primitives/document-flow/add-fields.tsx:964
#: packages/ui/primitives/document-flow/types.ts:52 #: 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:759
msgid "Text" msgid "Text"
msgstr "Text" msgstr "Text"
@@ -1515,7 +1545,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." 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." 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:768
msgid "This document has already been sent to this recipient. You can no longer edit this recipient." 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." msgstr "Dieses Dokument wurde bereits an diesen Empfänger gesendet. Sie können diesen Empfänger nicht mehr bearbeiten."
@@ -1531,15 +1561,19 @@ msgstr "Dieses Dokument wurde mit <0>Documenso.</0> gesendet"
msgid "This email confirms that you have rejected the document <0>\"{documentName}\"</0> sent by {documentOwnerName}." msgid "This email confirms that you have rejected the document <0>\"{documentName}\"</0> sent by {documentOwnerName}."
msgstr "Diese E-Mail bestätigt, dass Sie das Dokument <0>\"{documentName}\"</0> abgelehnt haben, das von {documentOwnerName} gesendet wurde." msgstr "Diese E-Mail bestätigt, dass Sie das Dokument <0>\"{documentName}\"</0> abgelehnt haben, das von {documentOwnerName} gesendet wurde."
#: packages/ui/components/document/document-email-checkboxes.tsx:94 #: packages/ui/components/document/document-email-checkboxes.tsx:56
msgid "This email is sent to the document owner when a recipient has signed the document."
msgstr ""
#: packages/ui/components/document/document-email-checkboxes.tsx:134
msgid "This email is sent to the recipient if they are removed from a pending document." msgid "This email is sent to the recipient if they are removed from a pending document."
msgstr "Diese E-Mail wird an den Empfänger gesendet, wenn er von einem ausstehenden Dokument entfernt wird." msgstr "Diese E-Mail wird an den Empfänger gesendet, wenn er von einem ausstehenden Dokument entfernt wird."
#: packages/ui/components/document/document-email-checkboxes.tsx:55 #: packages/ui/components/document/document-email-checkboxes.tsx:95
msgid "This email is sent to the recipient requesting them to sign the document." msgid "This email is sent to the recipient requesting them to sign the document."
msgstr "Diese E-Mail wird an den Empfänger gesendet und fordert ihn auf, das Dokument zu unterschreiben." msgstr "Diese E-Mail wird an den Empfänger gesendet und fordert ihn auf, das Dokument zu unterschreiben."
#: packages/ui/components/document/document-email-checkboxes.tsx:133 #: packages/ui/components/document/document-email-checkboxes.tsx:173
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." 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." 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."
@@ -1551,7 +1585,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." 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." 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:1101
msgid "This recipient can no longer be modified as they have signed a field, or completed the document." 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." msgstr "Dieser Empfänger kann nicht mehr bearbeitet werden, da er ein Feld unterschrieben oder das Dokument abgeschlossen hat."
@@ -1559,29 +1593,33 @@ msgstr "Dieser Empfänger kann nicht mehr bearbeitet werden, da er ein Feld unte
msgid "This signer has already signed the document." msgid "This signer has already signed the document."
msgstr "Dieser Unterzeichner hat das Dokument bereits unterschrieben." msgstr "Dieser Unterzeichner hat das Dokument bereits unterschrieben."
#: packages/ui/components/document/document-email-checkboxes.tsx:212 #: packages/ui/components/document/document-email-checkboxes.tsx:252
msgid "This will be sent to all recipients if a pending document has been deleted." msgid "This will be sent to all recipients if a pending document has been deleted."
msgstr "Dies wird an alle Empfänger gesendet, wenn ein ausstehendes Dokument gelöscht wurde." msgstr "Dies wird an alle Empfänger gesendet, wenn ein ausstehendes Dokument gelöscht wurde."
#: packages/ui/components/document/document-email-checkboxes.tsx:173 #: packages/ui/components/document/document-email-checkboxes.tsx:213
msgid "This will be sent to all recipients once the document has been fully completed." msgid "This will be sent to all recipients once the document has been fully completed."
msgstr "Dies wird an alle Empfänger gesendet, sobald das Dokument vollständig abgeschlossen ist." msgstr "Dies wird an alle Empfänger gesendet, sobald das Dokument vollständig abgeschlossen ist."
#: packages/ui/components/document/document-email-checkboxes.tsx:291
msgid "This will be sent to the document owner once the document has been fully completed."
msgstr ""
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:48 #: packages/ui/components/recipient/recipient-action-auth-select.tsx:48
msgid "This will override any global settings." msgid "This will override any global settings."
msgstr "Dies überschreibt alle globalen Einstellungen." msgstr "Dies überschreibt alle globalen Einstellungen."
#: packages/ui/primitives/document-flow/add-settings.tsx:347 #: packages/ui/primitives/document-flow/add-settings.tsx:359
#: packages/ui/primitives/template-flow/add-template-settings.tsx:438 #: packages/ui/primitives/template-flow/add-template-settings.tsx:438
msgid "Time Zone" msgid "Time Zone"
msgstr "Zeitzone" msgstr "Zeitzone"
#: packages/ui/primitives/document-flow/add-settings.tsx:155 #: packages/ui/primitives/document-flow/add-settings.tsx:166
msgid "Title" msgid "Title"
msgstr "Titel" msgstr "Titel"
#: packages/ui/primitives/document-flow/add-fields.tsx:1080 #: packages/ui/primitives/document-flow/add-fields.tsx:1084
#: packages/ui/primitives/template-flow/add-template-fields.tsx:873 #: packages/ui/primitives/template-flow/add-template-fields.tsx:877
msgid "To proceed further, please set at least one value for the {0} field." 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." msgstr "Um fortzufahren, legen Sie bitte mindestens einen Wert für das Feld {0} fest."
@@ -1597,7 +1635,7 @@ msgstr "Aktualisieren Sie die Rolle und fügen Sie Felder nach Bedarf für den d
msgid "Upgrade" msgid "Upgrade"
msgstr "Upgrade" msgstr "Upgrade"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:509 #: packages/ui/primitives/signature-pad/signature-pad.tsx:516
msgid "Upload Signature" msgid "Upload Signature"
msgstr "" msgstr ""
@@ -1726,7 +1764,7 @@ msgstr "Du wurdest eingeladen, {0} auf Documenso beizutreten"
msgid "You have been invited to join the following team" msgid "You have been invited to join the following team"
msgstr "Du wurdest eingeladen, dem folgenden Team beizutreten" msgstr "Du wurdest eingeladen, dem folgenden Team beizutreten"
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:327 #: packages/lib/server-only/recipient/set-recipients-for-document.ts:337
msgid "You have been removed from a document" msgid "You have been removed from a document"
msgstr "Du wurdest von einem Dokument entfernt" msgstr "Du wurdest von einem Dokument entfernt"
@@ -1734,7 +1772,7 @@ msgstr "Du wurdest von einem Dokument entfernt"
msgid "You have been requested to take ownership of team {0} on Documenso" msgid "You have been requested to take ownership of team {0} on Documenso"
msgstr "Du wurdest gebeten, das Team {0} auf Documenso zu übernehmen" msgstr "Du wurdest gebeten, das Team {0} auf Documenso zu übernehmen"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:115 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:103
#: packages/lib/server-only/document/resend-document.tsx:125 #: packages/lib/server-only/document/resend-document.tsx:125
msgid "You have initiated the document {0} that requires you to {recipientActionVerb} it." msgid "You have initiated the document {0} that requires you to {recipientActionVerb} it."
msgstr "Du hast das Dokument {0} initiiert, das erfordert, dass du {recipientActionVerb}." msgstr "Du hast das Dokument {0} initiiert, das erfordert, dass du {recipientActionVerb}."

View File

@@ -92,11 +92,7 @@ msgstr "{0} Empfänger(in)"
msgid "{charactersRemaining, plural, one {1 character remaining} other {{charactersRemaining} characters remaining}}" msgid "{charactersRemaining, plural, one {1 character remaining} other {{charactersRemaining} characters remaining}}"
msgstr "{charactersRemaining, plural, one {1 Zeichen verbleibend} other {{charactersRemaining} Zeichen verbleibend}}" msgstr "{charactersRemaining, plural, one {1 Zeichen verbleibend} other {{charactersRemaining} Zeichen verbleibend}}"
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:55 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:59
msgid "{formattedTeamMemberQuanity} • Monthly • Renews: {formattedDate}"
msgstr "{formattedTeamMemberQuanity} • Monatlich • Erneuert: {formattedDate}"
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:48
msgid "{numberOfSeats, plural, one {# member} other {# members}}" msgid "{numberOfSeats, plural, one {# member} other {# members}}"
msgstr "{numberOfSeats, plural, one {# Mitglied} other {# Mitglieder}}" msgstr "{numberOfSeats, plural, one {# Mitglied} other {# Mitglieder}}"
@@ -254,21 +250,21 @@ msgid "Acknowledgment"
msgstr "Bestätigung" msgstr "Bestätigung"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:108 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:108
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:100 #: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:98
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:123 #: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:123
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164 #: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:118 #: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:116
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:46 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:46
msgid "Action" msgid "Action"
msgstr "Aktion" msgstr "Aktion"
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:85 #: apps/web/src/app/(dashboard)/documents/data-table.tsx:79
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:181 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:177
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:140 #: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:140
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:133 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:131
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:142 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:140
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:118 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:116
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:127 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:125
msgid "Actions" msgid "Actions"
msgstr "Aktionen" msgstr "Aktionen"
@@ -491,7 +487,7 @@ msgstr "Ein Fehler ist aufgetreten, während die Teammitglieder geladen wurden.
msgid "An error occurred while moving the document." msgid "An error occurred while moving the document."
msgstr "Ein Fehler ist aufgetreten, während das Dokument verschoben wurde." msgstr "Ein Fehler ist aufgetreten, während das Dokument verschoben wurde."
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:57 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:65
msgid "An error occurred while moving the template." msgid "An error occurred while moving the template."
msgstr "Ein Fehler ist aufgetreten, während die Vorlage verschoben wurde." msgstr "Ein Fehler ist aufgetreten, während die Vorlage verschoben wurde."
@@ -499,7 +495,7 @@ msgstr "Ein Fehler ist aufgetreten, während die Vorlage verschoben wurde."
msgid "An error occurred while removing the field." msgid "An error occurred while removing the field."
msgstr "Ein Fehler ist beim Entfernen des Feldes aufgetreten." msgstr "Ein Fehler ist beim Entfernen des Feldes aufgetreten."
#: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:152 #: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:154
#: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:126 #: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:126
#: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:137 #: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:137
#: apps/web/src/app/(signing)/sign/[token]/email-field.tsx:110 #: apps/web/src/app/(signing)/sign/[token]/email-field.tsx:110
@@ -522,7 +518,7 @@ msgstr "Ein Fehler ist aufgetreten, während das Dokument gesendet wurde."
msgid "An error occurred while sending your confirmation email" msgid "An error occurred while sending your confirmation email"
msgstr "Beim Senden Ihrer Bestätigungs-E-Mail ist ein Fehler aufgetreten" msgstr "Beim Senden Ihrer Bestätigungs-E-Mail ist ein Fehler aufgetreten"
#: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:123 #: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:125
#: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:100 #: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:100
#: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:106 #: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:106
#: apps/web/src/app/(signing)/sign/[token]/email-field.tsx:84 #: apps/web/src/app/(signing)/sign/[token]/email-field.tsx:84
@@ -544,7 +540,7 @@ msgstr "Ein Fehler ist aufgetreten, während versucht wurde, eine Checkout-Sitzu
msgid "An error occurred while updating the document settings." msgid "An error occurred while updating the document settings."
msgstr "Ein Fehler ist aufgetreten, während die Dokumenteinstellungen aktualisiert wurden." msgstr "Ein Fehler ist aufgetreten, während die Dokumenteinstellungen aktualisiert wurden."
#: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:213 #: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:215
msgid "An error occurred while updating the signature." msgid "An error occurred while updating the signature."
msgstr "Ein Fehler ist aufgetreten, während die Unterschrift aktualisiert wurde." msgstr "Ein Fehler ist aufgetreten, während die Unterschrift aktualisiert wurde."
@@ -578,11 +574,11 @@ msgstr "Ein Fehler ist aufgetreten, während dein Dokument hochgeladen wurde."
#: apps/web/src/components/forms/profile.tsx:87 #: apps/web/src/components/forms/profile.tsx:87
#: apps/web/src/components/forms/public-profile-claim-dialog.tsx:113 #: apps/web/src/components/forms/public-profile-claim-dialog.tsx:113
#: apps/web/src/components/forms/public-profile-form.tsx:104 #: apps/web/src/components/forms/public-profile-form.tsx:104
#: apps/web/src/components/forms/signin.tsx:248 #: apps/web/src/components/forms/signin.tsx:249
#: apps/web/src/components/forms/signin.tsx:256 #: apps/web/src/components/forms/signin.tsx:257
#: apps/web/src/components/forms/signin.tsx:270 #: apps/web/src/components/forms/signin.tsx:271
#: apps/web/src/components/forms/signin.tsx:285 #: apps/web/src/components/forms/signin.tsx:286
#: apps/web/src/components/forms/signin.tsx:301 #: apps/web/src/components/forms/signin.tsx:302
#: apps/web/src/components/forms/signup.tsx:124 #: apps/web/src/components/forms/signup.tsx:124
#: apps/web/src/components/forms/signup.tsx:138 #: apps/web/src/components/forms/signup.tsx:138
#: apps/web/src/components/forms/token.tsx:143 #: apps/web/src/components/forms/token.tsx:143
@@ -597,11 +593,11 @@ msgstr "Es ist ein unbekannter Fehler aufgetreten"
msgid "Any payment methods attached to this team will remain attached to this team. Please contact us if you need to update this information." msgid "Any payment methods attached to this team will remain attached to this team. Please contact us if you need to update this information."
msgstr "Alle Zahlungsmethoden, die mit diesem Team verbunden sind, bleiben diesem Team zugeordnet. Bitte kontaktiere uns, wenn du diese Informationen aktualisieren möchtest." msgstr "Alle Zahlungsmethoden, die mit diesem Team verbunden sind, bleiben diesem Team zugeordnet. Bitte kontaktiere uns, wenn du diese Informationen aktualisieren möchtest."
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:225 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:221
msgid "Any Source" msgid "Any Source"
msgstr "Jede Quelle" msgstr "Jede Quelle"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:205 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:201
msgid "Any Status" msgid "Any Status"
msgstr "Jeder Status" msgstr "Jeder Status"
@@ -704,7 +700,7 @@ msgid "Background Color"
msgstr "Hintergrundfarbe" msgstr "Hintergrundfarbe"
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:167 #: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:167
#: apps/web/src/components/forms/signin.tsx:485 #: apps/web/src/components/forms/signin.tsx:486
msgid "Backup Code" msgid "Backup Code"
msgstr "Backup-Code" msgstr "Backup-Code"
@@ -721,7 +717,7 @@ msgid "Basic details"
msgstr "Basisdetails" msgstr "Basisdetails"
#: apps/web/src/app/(dashboard)/settings/billing/page.tsx:74 #: apps/web/src/app/(dashboard)/settings/billing/page.tsx:74
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:61 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:71
#: apps/web/src/components/(dashboard)/settings/layout/desktop-nav.tsx:117 #: apps/web/src/components/(dashboard)/settings/layout/desktop-nav.tsx:117
#: apps/web/src/components/(dashboard)/settings/layout/mobile-nav.tsx:120 #: apps/web/src/components/(dashboard)/settings/layout/mobile-nav.tsx:120
#: apps/web/src/components/(teams)/settings/layout/desktop-nav.tsx:123 #: apps/web/src/components/(teams)/settings/layout/desktop-nav.tsx:123
@@ -737,7 +733,7 @@ msgstr "Markenpräferenzen"
msgid "Branding preferences updated" msgid "Branding preferences updated"
msgstr "Markenpräferenzen aktualisiert" msgstr "Markenpräferenzen aktualisiert"
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:99 #: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:97
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:48 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:48
msgid "Browser" msgid "Browser"
msgstr "Browser" msgstr "Browser"
@@ -780,7 +776,7 @@ msgstr "Durch die Verwendung der elektronischen Unterschriftsfunktion stimmen Si
#: apps/web/src/app/(dashboard)/settings/teams/team-email-usage.tsx:109 #: apps/web/src/app/(dashboard)/settings/teams/team-email-usage.tsx:109
#: apps/web/src/app/(dashboard)/templates/delete-template-dialog.tsx:81 #: apps/web/src/app/(dashboard)/templates/delete-template-dialog.tsx:81
#: apps/web/src/app/(dashboard)/templates/duplicate-template-dialog.tsx:78 #: 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/move-template-dialog.tsx:131
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:472 #: 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]/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-2fa.tsx:178
@@ -864,9 +860,9 @@ msgstr "Benutzername jetzt beanspruchen"
msgid "Click here to get started" msgid "Click here to get started"
msgstr "Klicken Sie hier, um zu beginnen" msgstr "Klicken Sie hier, um zu beginnen"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:78 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:76
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:118 #: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:118
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:68 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:66
#: apps/web/src/components/document/document-history-sheet.tsx:133 #: apps/web/src/components/document/document-history-sheet.tsx:133
msgid "Click here to retry" msgid "Click here to retry"
msgstr "Klicken Sie hier, um es erneut zu versuchen" msgstr "Klicken Sie hier, um es erneut zu versuchen"
@@ -919,7 +915,7 @@ msgstr "Unterzeichnung abschließen"
msgid "Complete Viewing" msgid "Complete Viewing"
msgstr "Betrachten abschließen" msgstr "Betrachten abschließen"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:208 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:204
#: apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx:77 #: apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx:77
#: apps/web/src/components/formatter/document-status.tsx:28 #: apps/web/src/components/formatter/document-status.tsx:28
msgid "Completed" msgid "Completed"
@@ -1149,9 +1145,9 @@ msgstr "Erstellen Sie Ihr Konto und beginnen Sie mit dem modernen Dokumentensign
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:62 #: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:62
#: apps/web/src/app/(dashboard)/admin/leaderboard/data-table-leaderboard.tsx:96 #: apps/web/src/app/(dashboard)/admin/leaderboard/data-table-leaderboard.tsx:96
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:35 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:35
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:54 #: apps/web/src/app/(dashboard)/documents/data-table.tsx:48
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:65 #: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:63
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:109 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:105
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-information.tsx:34 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-information.tsx:34
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:56 #: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:56
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:274 #: apps/web/src/components/templates/manage-public-template-dialog.tsx:274
@@ -1168,7 +1164,7 @@ msgid "Created by"
msgstr "Erstellt von" msgstr "Erstellt von"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:48 #: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:48
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:78 #: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:76
msgid "Created on" msgid "Created on"
msgstr "Erstellt am" msgstr "Erstellt am"
@@ -1187,10 +1183,6 @@ msgstr "Aktuelles Passwort"
msgid "Current password is incorrect." msgid "Current password is incorrect."
msgstr "" msgstr ""
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:69
msgid "Current plan: {0}"
msgstr "Aktueller Plan: {0}"
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:28 #: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:28
msgid "Daily" msgid "Daily"
msgstr "Täglich" msgstr "Täglich"
@@ -1199,7 +1191,7 @@ msgstr "Täglich"
msgid "Dark Mode" msgid "Dark Mode"
msgstr "Dunkelmodus" msgstr "Dunkelmodus"
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:70 #: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:68
#: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:148 #: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:148
msgid "Date" msgid "Date"
msgstr "Datum" msgstr "Datum"
@@ -1319,7 +1311,7 @@ msgstr "Konto wird gelöscht..."
msgid "Details" msgid "Details"
msgstr "Einzelheiten" msgstr "Einzelheiten"
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:75 #: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:73
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:242 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:242
msgid "Device" msgid "Device"
msgstr "Gerät" msgstr "Gerät"
@@ -1334,8 +1326,8 @@ msgstr "Direkter Link"
msgid "Direct link" msgid "Direct link"
msgstr "Direkter Link" msgstr "Direkter Link"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:160 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:156
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:231 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:227
msgid "Direct Link" msgid "Direct Link"
msgstr "Direkter Link" msgstr "Direkter Link"
@@ -1439,11 +1431,11 @@ msgstr "Dokument abgeschlossen!"
msgid "Document created" msgid "Document created"
msgstr "Dokument erstellt" msgstr "Dokument erstellt"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:129 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:127
msgid "Document created by <0>{0}</0>" msgid "Document created by <0>{0}</0>"
msgstr "Dokument erstellt von <0>{0}</0>" msgstr "Dokument erstellt von <0>{0}</0>"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:134 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:132
msgid "Document created using a <0>direct link</0>" msgid "Document created using a <0>direct link</0>"
msgstr "Dokument erstellt mit einem <0>direkten Link</0>" msgstr "Dokument erstellt mit einem <0>direkten Link</0>"
@@ -1598,7 +1590,7 @@ msgstr "Auditprotokolle herunterladen"
msgid "Download Certificate" msgid "Download Certificate"
msgstr "Zertifikat herunterladen" msgstr "Zertifikat herunterladen"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:214 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:210
#: apps/web/src/components/formatter/document-status.tsx:34 #: apps/web/src/components/formatter/document-status.tsx:34
msgid "Draft" msgid "Draft"
msgstr "Entwurf" msgstr "Entwurf"
@@ -1668,7 +1660,7 @@ msgstr "Offenlegung der elektronischen Unterschrift"
#: apps/web/src/components/(teams)/dialogs/update-team-email-dialog.tsx:153 #: apps/web/src/components/(teams)/dialogs/update-team-email-dialog.tsx:153
#: apps/web/src/components/forms/forgot-password.tsx:81 #: apps/web/src/components/forms/forgot-password.tsx:81
#: apps/web/src/components/forms/profile.tsx:122 #: apps/web/src/components/forms/profile.tsx:122
#: apps/web/src/components/forms/signin.tsx:338 #: apps/web/src/components/forms/signin.tsx:339
#: apps/web/src/components/forms/signup.tsx:176 #: apps/web/src/components/forms/signup.tsx:176
msgid "Email" msgid "Email"
msgstr "E-Mail" msgstr "E-Mail"
@@ -1778,12 +1770,12 @@ msgstr "Geben Sie hier Ihren Text ein"
#: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:217 #: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:217
#: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:256 #: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:256
#: apps/web/src/app/(dashboard)/templates/duplicate-template-dialog.tsx:51 #: 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/move-template-dialog.tsx:68
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:175 #: 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]/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:124
#: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:151 #: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:153
#: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:212 #: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:214
#: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:99 #: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:99
#: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:125 #: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:125
#: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:105 #: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:105
@@ -1859,7 +1851,7 @@ msgid "For any questions regarding this disclosure, electronic signatures, or an
msgstr "Für Fragen zu dieser Offenlegung, elektronischen Unterschriften oder einem verwandten Verfahren kontaktieren Sie uns bitte unter: <0>{SUPPORT_EMAIL}</0>" msgstr "Für Fragen zu dieser Offenlegung, elektronischen Unterschriften oder einem verwandten Verfahren kontaktieren Sie uns bitte unter: <0>{SUPPORT_EMAIL}</0>"
#: apps/web/src/app/(unauthenticated)/forgot-password/page.tsx:21 #: apps/web/src/app/(unauthenticated)/forgot-password/page.tsx:21
#: apps/web/src/components/forms/signin.tsx:370 #: apps/web/src/components/forms/signin.tsx:371
msgid "Forgot your password?" msgid "Forgot your password?"
msgstr "Haben Sie Ihr Passwort vergessen?" msgstr "Haben Sie Ihr Passwort vergessen?"
@@ -2039,11 +2031,11 @@ msgstr "Einladung akzeptiert!"
msgid "Invitation declined" msgid "Invitation declined"
msgstr "Einladung abgelehnt" msgstr "Einladung abgelehnt"
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:80 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:78
msgid "Invitation has been deleted" msgid "Invitation has been deleted"
msgstr "Einladung wurde gelöscht" msgstr "Einladung wurde gelöscht"
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:63 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:61
msgid "Invitation has been resent" msgid "Invitation has been resent"
msgstr "Einladung wurde erneut gesendet" msgstr "Einladung wurde erneut gesendet"
@@ -2063,7 +2055,7 @@ msgstr "Mitglieder einladen"
msgid "Invite team members" msgid "Invite team members"
msgstr "Teammitglieder einladen" msgstr "Teammitglieder einladen"
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:128 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:126
msgid "Invited At" msgid "Invited At"
msgstr "Eingeladen am" msgstr "Eingeladen am"
@@ -2133,7 +2125,7 @@ msgstr "Zuletzt aktualisiert"
msgid "Last updated at" msgid "Last updated at"
msgstr "Zuletzt aktualisiert am" msgstr "Zuletzt aktualisiert am"
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:71 #: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:69
msgid "Last used" msgid "Last used"
msgstr "Zuletzt verwendet" msgstr "Zuletzt verwendet"
@@ -2142,7 +2134,7 @@ msgid "Leaderboard"
msgstr "" msgstr ""
#: apps/web/src/components/(teams)/dialogs/leave-team-dialog.tsx:111 #: apps/web/src/components/(teams)/dialogs/leave-team-dialog.tsx:111
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:117 #: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:115
msgid "Leave" msgid "Leave"
msgstr "Verlassen" msgstr "Verlassen"
@@ -2175,7 +2167,7 @@ msgstr "Links generiert"
msgid "Listening to {0}" msgid "Listening to {0}"
msgstr "Anhören von {0}" msgstr "Anhören von {0}"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:100 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:98
msgid "Load older activity" msgid "Load older activity"
msgstr "Ältere Aktivitäten laden" msgstr "Ältere Aktivitäten laden"
@@ -2190,11 +2182,11 @@ msgid "Loading Document..."
msgstr "Dokument wird geladen..." msgstr "Dokument wird geladen..."
#: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:92 #: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:92
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:91 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:103
msgid "Loading teams..." msgid "Loading teams..."
msgstr "Teams werden geladen..." msgstr "Teams werden geladen..."
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:100 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:98
msgid "Loading..." msgid "Loading..."
msgstr "Wird geladen..." msgstr "Wird geladen..."
@@ -2204,7 +2196,7 @@ msgstr "Wird geladen..."
msgid "Login" msgid "Login"
msgstr "Anmelden" msgstr "Anmelden"
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:101 #: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:99
msgid "Manage" msgid "Manage"
msgstr "Verwalten" msgstr "Verwalten"
@@ -2252,7 +2244,7 @@ msgstr "Abonnement verwalten"
msgid "Manage subscriptions" msgid "Manage subscriptions"
msgstr "Abonnements verwalten" msgstr "Abonnements verwalten"
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:81 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:87
msgid "Manage team subscription." msgid "Manage team subscription."
msgstr "Teamabonnement verwalten." msgstr "Teamabonnement verwalten."
@@ -2292,8 +2284,8 @@ msgstr "MAU (erstellt Dokument)"
msgid "MAU (had document completed)" msgid "MAU (had document completed)"
msgstr "MAU (hat Dokument abgeschlossen)" msgstr "MAU (hat Dokument abgeschlossen)"
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:90 #: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:88
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:113 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:111
msgid "Member Since" msgid "Member Since"
msgstr "Mitglied seit" msgstr "Mitglied seit"
@@ -2309,6 +2301,7 @@ msgid "Modify recipients"
msgstr "Empfänger ändern" msgstr "Empfänger ändern"
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:30 #: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:30
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:54
msgid "Monthly" msgid "Monthly"
msgstr "Monatlich" msgstr "Monatlich"
@@ -2321,7 +2314,7 @@ msgid "Monthly Active Users: Users that had at least one of their documents comp
msgstr "Monatlich aktive Benutzer: Benutzer, die mindestens eines ihrer Dokumente abgeschlossen haben" msgstr "Monatlich aktive Benutzer: Benutzer, die mindestens eines ihrer Dokumente abgeschlossen haben"
#: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:123 #: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:123
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:122 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:134
msgid "Move" msgid "Move"
msgstr "Verschieben" msgstr "Verschieben"
@@ -2329,7 +2322,7 @@ msgstr "Verschieben"
msgid "Move Document to Team" msgid "Move Document to Team"
msgstr "Dokument in Team verschieben" msgstr "Dokument in Team verschieben"
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:77 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:89
msgid "Move Template to Team" msgid "Move Template to Team"
msgstr "Vorlage in Team verschieben" msgstr "Vorlage in Team verschieben"
@@ -2339,7 +2332,7 @@ msgid "Move to Team"
msgstr "In Team verschieben" msgstr "In Team verschieben"
#: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:123 #: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:123
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:122 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:134
msgid "Moving..." msgid "Moving..."
msgstr "Verschieben..." msgstr "Verschieben..."
@@ -2352,7 +2345,7 @@ msgstr "Meine Vorlagen"
#: apps/web/src/app/(dashboard)/admin/users/[id]/page.tsx:99 #: apps/web/src/app/(dashboard)/admin/users/[id]/page.tsx:99
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:66 #: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:66
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:144 #: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:144
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:61 #: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:59
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:287 #: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:287
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:294 #: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:294
#: apps/web/src/app/(signing)/sign/[token]/complete/claim-account.tsx:118 #: apps/web/src/app/(signing)/sign/[token]/complete/claim-account.tsx:118
@@ -2367,7 +2360,7 @@ msgstr "Name"
msgid "Need to sign documents?" msgid "Need to sign documents?"
msgstr "Müssen Dokumente signieren?" msgstr "Müssen Dokumente signieren?"
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:76 #: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:74
msgid "Never" msgid "Never"
msgstr "Niemals" msgstr "Niemals"
@@ -2402,7 +2395,7 @@ msgstr "Keine aktiven Entwürfe"
msgid "No further action is required from you at this time." msgid "No further action is required from you at this time."
msgstr "Es sind derzeit keine weiteren Maßnahmen Ihrerseits erforderlich." msgstr "Es sind derzeit keine weiteren Maßnahmen Ihrerseits erforderlich."
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:42 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:43
msgid "No payment required" msgid "No payment required"
msgstr "Keine Zahlung erforderlich" msgstr "Keine Zahlung erforderlich"
@@ -2410,11 +2403,11 @@ msgstr "Keine Zahlung erforderlich"
msgid "No public profile templates found" msgid "No public profile templates found"
msgstr "Keine Vorlagen für das öffentliche Profil gefunden" msgstr "Keine Vorlagen für das öffentliche Profil gefunden"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:108 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:106
msgid "No recent activity" msgid "No recent activity"
msgstr "Keine aktuellen Aktivitäten" msgstr "Keine aktuellen Aktivitäten"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:103 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:101
msgid "No recent documents" msgid "No recent documents"
msgstr "Keine aktuellen Dokumente" msgstr "Keine aktuellen Dokumente"
@@ -2449,7 +2442,7 @@ msgstr "Kein Wert gefunden."
msgid "No worries, it happens! Enter your email and we'll email you a special link to reset your password." msgid "No worries, it happens! Enter your email and we'll email you a special link to reset your password."
msgstr "Keine Sorge, das passiert! Geben Sie Ihre E-Mail ein, und wir senden Ihnen einen speziellen Link zum Zurücksetzen Ihres Passworts." msgstr "Keine Sorge, das passiert! Geben Sie Ihre E-Mail ein, und wir senden Ihnen einen speziellen Link zum Zurücksetzen Ihres Passworts."
#: apps/web/src/components/forms/signin.tsx:160 #: apps/web/src/components/forms/signin.tsx:161
msgid "Not supported" msgid "Not supported"
msgstr "Nicht unterstützt" msgstr "Nicht unterstützt"
@@ -2535,7 +2528,7 @@ msgstr "Geöffnet"
msgid "Or" msgid "Or"
msgstr "Oder" msgstr "Oder"
#: apps/web/src/components/forms/signin.tsx:390 #: apps/web/src/components/forms/signin.tsx:391
msgid "Or continue with" msgid "Or continue with"
msgstr "Oder fahren Sie fort mit" msgstr "Oder fahren Sie fort mit"
@@ -2546,8 +2539,8 @@ msgstr "Andernfalls wird das Dokument als Entwurf erstellt."
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:86 #: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:86
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:103 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:103
#: apps/web/src/components/(dashboard)/layout/menu-switcher.tsx:81 #: apps/web/src/components/(dashboard)/layout/menu-switcher.tsx:81
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:86 #: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:84
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:109 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:107
msgid "Owner" msgid "Owner"
msgstr "Besitzer" msgstr "Besitzer"
@@ -2555,7 +2548,7 @@ msgstr "Besitzer"
msgid "Paid" msgid "Paid"
msgstr "Bezahlt" msgstr "Bezahlt"
#: apps/web/src/components/forms/signin.tsx:435 #: apps/web/src/components/forms/signin.tsx:436
msgid "Passkey" msgid "Passkey"
msgstr "Passkey" msgstr "Passkey"
@@ -2592,14 +2585,14 @@ msgstr "Passkeys"
msgid "Passkeys allow you to sign in and authenticate using biometrics, password managers, etc." msgid "Passkeys allow you to sign in and authenticate using biometrics, password managers, etc."
msgstr "Passkeys ermöglichen das Anmelden und die Authentifizierung mit biometrischen Daten, Passwortmanagern usw." msgstr "Passkeys ermöglichen das Anmelden und die Authentifizierung mit biometrischen Daten, Passwortmanagern usw."
#: apps/web/src/components/forms/signin.tsx:161 #: apps/web/src/components/forms/signin.tsx:162
msgid "Passkeys are not supported on this browser" msgid "Passkeys are not supported on this browser"
msgstr "Passkeys werden von diesem Browser nicht unterstützt" msgstr "Passkeys werden von diesem Browser nicht unterstützt"
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:70 #: apps/web/src/components/(dashboard)/common/command-menu.tsx:70
#: apps/web/src/components/forms/password.tsx:128 #: apps/web/src/components/forms/password.tsx:128
#: apps/web/src/components/forms/reset-password.tsx:115 #: apps/web/src/components/forms/reset-password.tsx:115
#: apps/web/src/components/forms/signin.tsx:356 #: apps/web/src/components/forms/signin.tsx:357
#: apps/web/src/components/forms/signup.tsx:192 #: apps/web/src/components/forms/signup.tsx:192
#: apps/web/src/components/forms/v2/signup.tsx:347 #: apps/web/src/components/forms/v2/signup.tsx:347
msgid "Password" msgid "Password"
@@ -2629,7 +2622,7 @@ msgid "Payment overdue"
msgstr "Zahlung überfällig" msgstr "Zahlung überfällig"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recipients.tsx:131 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recipients.tsx:131
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:211 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:207
#: apps/web/src/components/(teams)/tables/teams-member-page-data-table.tsx:82 #: apps/web/src/components/(teams)/tables/teams-member-page-data-table.tsx:82
#: apps/web/src/components/(teams)/tables/user-settings-teams-page-data-table.tsx:77 #: apps/web/src/components/(teams)/tables/user-settings-teams-page-data-table.tsx:77
#: apps/web/src/components/document/document-read-only-fields.tsx:89 #: apps/web/src/components/document/document-read-only-fields.tsx:89
@@ -2746,7 +2739,7 @@ msgstr "Bitte überprüfen Sie das Dokument vor der Unterzeichnung."
msgid "Please try again and make sure you enter the correct email address." msgid "Please try again and make sure you enter the correct email address."
msgstr "Bitte versuchen Sie es erneut und stellen Sie sicher, dass Sie die korrekte E-Mail-Adresse eingeben." msgstr "Bitte versuchen Sie es erneut und stellen Sie sicher, dass Sie die korrekte E-Mail-Adresse eingeben."
#: apps/web/src/components/forms/signin.tsx:203 #: apps/web/src/components/forms/signin.tsx:204
msgid "Please try again later or login using your normal details" msgid "Please try again later or login using your normal details"
msgstr "Bitte versuchen Sie es später erneut oder melden Sie sich mit Ihren normalen Daten an" msgstr "Bitte versuchen Sie es später erneut oder melden Sie sich mit Ihren normalen Daten an"
@@ -2858,17 +2851,17 @@ msgstr "Der Grund muss weniger als 500 Zeichen lang sein"
msgid "Reauthentication is required to sign this field" msgid "Reauthentication is required to sign this field"
msgstr "Eine erneute Authentifizierung ist erforderlich, um dieses Feld zu unterschreiben" msgstr "Eine erneute Authentifizierung ist erforderlich, um dieses Feld zu unterschreiben"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:57 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:55
#: apps/web/src/app/(dashboard)/settings/security/page.tsx:130 #: apps/web/src/app/(dashboard)/settings/security/page.tsx:130
msgid "Recent activity" msgid "Recent activity"
msgstr "Aktuelle Aktivitäten" msgstr "Aktuelle Aktivitäten"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:47 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:45
msgid "Recent documents" msgid "Recent documents"
msgstr "Neueste Dokumente" msgstr "Neueste Dokumente"
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:69 #: apps/web/src/app/(dashboard)/documents/data-table.tsx:63
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:120 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:116
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:280 #: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:280
msgid "Recipient" msgid "Recipient"
msgstr "Empfänger" msgstr "Empfänger"
@@ -2929,8 +2922,8 @@ msgstr "Haben Sie Ihr Passwort vergessen? <0>Einloggen</0>"
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-email-dropdown.tsx:89 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-email-dropdown.tsx:89
#: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:159 #: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:159
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:54 #: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:54
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:166 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:164
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:167 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:165
#: apps/web/src/components/forms/avatar-image.tsx:166 #: apps/web/src/components/forms/avatar-image.tsx:166
msgid "Remove" msgid "Remove"
msgstr "Entfernen" msgstr "Entfernen"
@@ -2939,10 +2932,14 @@ msgstr "Entfernen"
msgid "Remove team email" msgid "Remove team email"
msgstr "Team-E-Mail entfernen" msgstr "Team-E-Mail entfernen"
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:164 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:162
msgid "Remove team member" msgid "Remove team member"
msgstr "Teammitglied entfernen" msgstr "Teammitglied entfernen"
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:63
msgid "Renews: {formattedDate}"
msgstr ""
#: apps/web/src/components/forms/password.tsx:144 #: apps/web/src/components/forms/password.tsx:144
#: apps/web/src/components/forms/reset-password.tsx:131 #: apps/web/src/components/forms/reset-password.tsx:131
msgid "Repeat Password" msgid "Repeat Password"
@@ -2957,7 +2954,7 @@ msgid "Reseal document"
msgstr "Dokument wieder versiegeln" msgstr "Dokument wieder versiegeln"
#: apps/web/src/app/(dashboard)/documents/_action-items/resend-document.tsx:118 #: apps/web/src/app/(dashboard)/documents/_action-items/resend-document.tsx:118
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:154 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:152
msgid "Resend" msgid "Resend"
msgstr "Erneut senden" msgstr "Erneut senden"
@@ -3035,9 +3032,9 @@ msgstr "Zugriff widerrufen"
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:283 #: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:283
#: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:318 #: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:318
#: apps/web/src/components/(teams)/dialogs/update-team-member-dialog.tsx:163 #: apps/web/src/components/(teams)/dialogs/update-team-member-dialog.tsx:163
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:82 #: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:80
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:123 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:121
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:105 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:103
msgid "Role" msgid "Role"
msgstr "Rolle" msgstr "Rolle"
@@ -3094,7 +3091,7 @@ msgid "Select"
msgstr "Auswählen" msgstr "Auswählen"
#: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:87 #: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:87
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:86 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:98
msgid "Select a team" msgid "Select a team"
msgstr "Wählen Sie ein Team aus" msgstr "Wählen Sie ein Team aus"
@@ -3102,7 +3099,7 @@ msgstr "Wählen Sie ein Team aus"
msgid "Select a team to move this document to. This action cannot be undone." msgid "Select a team to move this document to. This action cannot be undone."
msgstr "Wählen Sie ein Team aus, um dieses Dokument dorthin zu verschieben. Diese Aktion kann nicht rückgängig gemacht werden." msgstr "Wählen Sie ein Team aus, um dieses Dokument dorthin zu verschieben. Diese Aktion kann nicht rückgängig gemacht werden."
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:80 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:92
msgid "Select a team to move this template to. This action cannot be undone." msgid "Select a team to move this template to. This action cannot be undone."
msgstr "Wählen Sie ein Team aus, um diese Vorlage dorthin zu verschieben. Diese Aktion kann nicht rückgängig gemacht werden." msgstr "Wählen Sie ein Team aus, um diese Vorlage dorthin zu verschieben. Diese Aktion kann nicht rückgängig gemacht werden."
@@ -3134,7 +3131,7 @@ msgstr "Im Namen des Teams senden"
msgid "Send reminder" msgid "Send reminder"
msgstr "Erinnerung senden" msgstr "Erinnerung senden"
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:65 #: apps/web/src/app/(dashboard)/documents/data-table.tsx:59
msgid "Sender" msgid "Sender"
msgstr "Absender" msgstr "Absender"
@@ -3233,8 +3230,8 @@ msgid "Sign Here"
msgstr "Hier unterzeichnen" msgstr "Hier unterzeichnen"
#: apps/web/src/app/not-found.tsx:29 #: apps/web/src/app/not-found.tsx:29
#: apps/web/src/components/forms/signin.tsx:383 #: apps/web/src/components/forms/signin.tsx:384
#: apps/web/src/components/forms/signin.tsx:510 #: apps/web/src/components/forms/signin.tsx:511
msgid "Sign In" msgid "Sign In"
msgstr "Einloggen" msgstr "Einloggen"
@@ -3319,8 +3316,8 @@ msgstr "Unterzeichnungszertifikat"
msgid "Signing certificate provided by" msgid "Signing certificate provided by"
msgstr "Unterzeichnungszertifikat bereitgestellt von" msgstr "Unterzeichnungszertifikat bereitgestellt von"
#: apps/web/src/components/forms/signin.tsx:383 #: apps/web/src/components/forms/signin.tsx:384
#: apps/web/src/components/forms/signin.tsx:510 #: apps/web/src/components/forms/signin.tsx:511
msgid "Signing in..." msgid "Signing in..."
msgstr "Anmeldung..." msgstr "Anmeldung..."
@@ -3396,8 +3393,8 @@ msgstr "Website Einstellungen"
#: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:64 #: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:64
#: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:83 #: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:83
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:33 #: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:33
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:68 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:66
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:85 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:83
#: apps/web/src/components/(teams)/team-billing-portal-button.tsx:29 #: apps/web/src/components/(teams)/team-billing-portal-button.tsx:29
msgid "Something went wrong" msgid "Something went wrong"
msgstr "Etwas ist schiefgelaufen" msgstr "Etwas ist schiefgelaufen"
@@ -3439,7 +3436,7 @@ msgstr "Entschuldigung, wir konnten die Prüfprotokolle nicht herunterladen. Bit
msgid "Sorry, we were unable to download the certificate. Please try again later." msgid "Sorry, we were unable to download the certificate. Please try again later."
msgstr "Entschuldigung, wir konnten das Zertifikat nicht herunterladen. Bitte versuchen Sie es später erneut." msgstr "Entschuldigung, wir konnten das Zertifikat nicht herunterladen. Bitte versuchen Sie es später erneut."
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:138 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:134
msgid "Source" msgid "Source"
msgstr "Quelle" msgstr "Quelle"
@@ -3449,8 +3446,8 @@ msgstr "Statistiken"
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:81 #: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:81
#: apps/web/src/app/(dashboard)/admin/subscriptions/page.tsx:32 #: apps/web/src/app/(dashboard)/admin/subscriptions/page.tsx:32
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:79 #: apps/web/src/app/(dashboard)/documents/data-table.tsx:73
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:130 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:126
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:93 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:93
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:73 #: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:73
msgid "Status" msgid "Status"
@@ -3492,8 +3489,8 @@ msgstr "Abonnements"
#: apps/web/src/components/(teams)/dialogs/update-team-member-dialog.tsx:92 #: apps/web/src/components/(teams)/dialogs/update-team-member-dialog.tsx:92
#: apps/web/src/components/(teams)/forms/update-team-form.tsx:67 #: apps/web/src/components/(teams)/forms/update-team-form.tsx:67
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:27 #: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:27
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:62 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:60
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:79 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:77
#: apps/web/src/components/forms/public-profile-form.tsx:80 #: apps/web/src/components/forms/public-profile-form.tsx:80
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:133 #: apps/web/src/components/templates/manage-public-template-dialog.tsx:133
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:170 #: apps/web/src/components/templates/manage-public-template-dialog.tsx:170
@@ -3512,8 +3509,8 @@ msgstr "Systemanforderungen"
msgid "System Theme" msgid "System Theme"
msgstr "Systemthema" msgstr "Systemthema"
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:65 #: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:63
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:64 #: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:62
msgid "Team" msgid "Team"
msgstr "Team" msgstr "Team"
@@ -3559,8 +3556,8 @@ msgstr "Teameinladung"
msgid "Team invitations have been sent." msgid "Team invitations have been sent."
msgstr "Teameinladungen wurden gesendet." msgstr "Teameinladungen wurden gesendet."
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:109 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:107
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:86 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:84
msgid "Team Member" msgid "Team Member"
msgstr "Teammitglied" msgstr "Teammitglied"
@@ -3634,10 +3631,10 @@ msgstr "Teams"
msgid "Teams restricted" msgid "Teams restricted"
msgstr "Teams beschränkt" msgstr "Teams beschränkt"
#: apps/web/src/app/(dashboard)/templates/[id]/edit/template-edit-page-view.tsx:63 #: apps/web/src/app/(dashboard)/templates/[id]/edit/template-edit-page-view.tsx:64
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:39 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:39
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:148 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:144
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:228 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:224
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:148 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:148
#: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:408 #: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:408
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:271 #: apps/web/src/components/templates/manage-public-template-dialog.tsx:271
@@ -3664,10 +3661,14 @@ msgstr "Vorlage ist von Deinem öffentlichen Profil entfernt worden."
msgid "Template has been updated." msgid "Template has been updated."
msgstr "Vorlage wurde aktualisiert." msgstr "Vorlage wurde aktualisiert."
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:48 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:50
msgid "Template moved" msgid "Template moved"
msgstr "Vorlage verschoben" msgstr "Vorlage verschoben"
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:62
msgid "Template not found or already associated with a team."
msgstr ""
#: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:246 #: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:246
msgid "Template saved" msgid "Template saved"
msgstr "Vorlage gespeichert" msgstr "Vorlage gespeichert"
@@ -3795,7 +3796,7 @@ msgstr "Die Teamübertragungsanfrage an <0>{0}</0> ist abgelaufen."
msgid "The team you are looking for may have been removed, renamed or may have never existed." msgid "The team you are looking for may have been removed, renamed or may have never existed."
msgstr "Das Team, das Sie suchen, wurde möglicherweise entfernt, umbenannt oder hat möglicherweise nie existiert." msgstr "Das Team, das Sie suchen, wurde möglicherweise entfernt, umbenannt oder hat möglicherweise nie existiert."
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:49 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:51
msgid "The template has been successfully moved to the selected team." msgid "The template has been successfully moved to the selected team."
msgstr "Die Vorlage wurde erfolgreich in das ausgewählte Team verschoben." msgstr "Die Vorlage wurde erfolgreich in das ausgewählte Team verschoben."
@@ -3884,11 +3885,11 @@ msgstr "Dieses Dokument wurde von allen Empfängern unterschrieben"
msgid "This document is currently a draft and has not been sent" msgid "This document is currently a draft and has not been sent"
msgstr "Dieses Dokument ist momentan ein Entwurf und wurde nicht gesendet" msgstr "Dieses Dokument ist momentan ein Entwurf und wurde nicht gesendet"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:152 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:148
msgid "This document was created by you or a team member using the template above." msgid "This document was created by you or a team member using the template above."
msgstr "Dieses Dokument wurde von Ihnen oder einem Teammitglied unter Verwendung der oben genannten Vorlage erstellt." msgstr "Dieses Dokument wurde von Ihnen oder einem Teammitglied unter Verwendung der oben genannten Vorlage erstellt."
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:164 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:160
msgid "This document was created using a direct link." msgid "This document was created using a direct link."
msgstr "Dieses Dokument wurde mit einem direkten Link erstellt." msgstr "Dieses Dokument wurde mit einem direkten Link erstellt."
@@ -3908,7 +3909,7 @@ msgstr "Dieser Link ist ungültig oder abgelaufen. Bitte kontaktieren Sie Ihr Te
msgid "This passkey has already been registered." msgid "This passkey has already been registered."
msgstr "Dieser Zugangsschlüssel wurde bereits registriert." msgstr "Dieser Zugangsschlüssel wurde bereits registriert."
#: apps/web/src/components/forms/signin.tsx:200 #: apps/web/src/components/forms/signin.tsx:201
msgid "This passkey is not configured for this application. Please login and add one in the user settings." msgid "This passkey is not configured for this application. Please login and add one in the user settings."
msgstr "Dieser Passkey ist für diese Anwendung nicht konfiguriert. Bitte melden Sie sich an und fügen Sie einen in den Benutzereinstellungen hinzu." msgstr "Dieser Passkey ist für diese Anwendung nicht konfiguriert. Bitte melden Sie sich an und fügen Sie einen in den Benutzereinstellungen hinzu."
@@ -3916,7 +3917,7 @@ msgstr "Dieser Passkey ist für diese Anwendung nicht konfiguriert. Bitte melden
msgid "This price includes minimum 5 seats." msgid "This price includes minimum 5 seats."
msgstr "Dieser Preis beinhaltet mindestens 5 Plätze." msgstr "Dieser Preis beinhaltet mindestens 5 Plätze."
#: apps/web/src/components/forms/signin.tsx:202 #: apps/web/src/components/forms/signin.tsx:203
msgid "This session has expired. Please try again." msgid "This session has expired. Please try again."
msgstr "Diese Sitzung ist abgelaufen. Bitte versuchen Sie es erneut." msgstr "Diese Sitzung ist abgelaufen. Bitte versuchen Sie es erneut."
@@ -3949,7 +3950,7 @@ msgstr "Dieser Benutzername ist bereits vergeben"
msgid "This username is already taken" msgid "This username is already taken"
msgstr "Dieser Benutzername ist bereits vergeben" msgstr "Dieser Benutzername ist bereits vergeben"
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:73 #: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:71
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:44 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:44
msgid "Time" msgid "Time"
msgstr "Zeit" msgstr "Zeit"
@@ -3963,8 +3964,8 @@ msgid "Time Zone"
msgstr "Zeitzone" msgstr "Zeitzone"
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:67 #: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:67
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:60 #: apps/web/src/app/(dashboard)/documents/data-table.tsx:54
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:115 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:111
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:61 #: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:61
msgid "Title" msgid "Title"
msgstr "Titel" msgstr "Titel"
@@ -4098,7 +4099,7 @@ msgstr "Zwei-Faktor-Authentifizierung"
msgid "Two factor authentication recovery codes are used to access your account in the event that you lose access to your authenticator app." msgid "Two factor authentication recovery codes are used to access your account in the event that you lose access to your authenticator app."
msgstr "Wiederherstellungscodes für die Zwei-Faktor-Authentifizierung werden verwendet, um auf Ihr Konto zuzugreifen, falls Sie den Zugang zu Ihrer Authentifizierungs-App verlieren." msgstr "Wiederherstellungscodes für die Zwei-Faktor-Authentifizierung werden verwendet, um auf Ihr Konto zuzugreifen, falls Sie den Zugang zu Ihrer Authentifizierungs-App verlieren."
#: apps/web/src/components/forms/signin.tsx:448 #: apps/web/src/components/forms/signin.tsx:449
msgid "Two-Factor Authentication" msgid "Two-Factor Authentication"
msgstr "Zwei-Faktor-Authentifizierung" msgstr "Zwei-Faktor-Authentifizierung"
@@ -4155,7 +4156,7 @@ msgstr "Direkter Zugriff auf die Vorlage kann nicht erstellt werden. Bitte versu
msgid "Unable to decline this team invitation at this time." msgid "Unable to decline this team invitation at this time."
msgstr "Zurzeit kann diese Teameinladung nicht abgelehnt werden." msgstr "Zurzeit kann diese Teameinladung nicht abgelehnt werden."
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:86 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:84
msgid "Unable to delete invitation. Please try again." msgid "Unable to delete invitation. Please try again."
msgstr "Einladung kann nicht gelöscht werden. Bitte versuchen Sie es erneut." msgstr "Einladung kann nicht gelöscht werden. Bitte versuchen Sie es erneut."
@@ -4171,12 +4172,12 @@ msgstr "Zwei-Faktor-Authentifizierung kann nicht deaktiviert werden"
msgid "Unable to join this team at this time." msgid "Unable to join this team at this time."
msgstr "Zurzeit kann diesem Team nicht beigetreten werden." msgstr "Zurzeit kann diesem Team nicht beigetreten werden."
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:72 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:70
#: apps/web/src/components/document/document-history-sheet.tsx:127 #: apps/web/src/components/document/document-history-sheet.tsx:127
msgid "Unable to load document history" msgid "Unable to load document history"
msgstr "Kann den Dokumentverlauf nicht laden" msgstr "Kann den Dokumentverlauf nicht laden"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:62 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:60
msgid "Unable to load documents" msgid "Unable to load documents"
msgstr "Dokumente können nicht geladen werden" msgstr "Dokumente können nicht geladen werden"
@@ -4192,7 +4193,7 @@ msgstr "Derzeit ist es nicht möglich, die E-Mail-Verifizierung zu entfernen. Bi
msgid "Unable to remove team email at this time. Please try again." msgid "Unable to remove team email at this time. Please try again."
msgstr "Das Team-E-Mail kann zurzeit nicht entfernt werden. Bitte versuchen Sie es erneut." msgstr "Das Team-E-Mail kann zurzeit nicht entfernt werden. Bitte versuchen Sie es erneut."
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:69 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:67
msgid "Unable to resend invitation. Please try again." msgid "Unable to resend invitation. Please try again."
msgstr "Einladung kann nicht erneut gesendet werden. Bitte versuchen Sie es erneut." msgstr "Einladung kann nicht erneut gesendet werden. Bitte versuchen Sie es erneut."
@@ -4209,8 +4210,8 @@ msgstr "Passwort kann nicht zurückgesetzt werden"
msgid "Unable to setup two-factor authentication" msgid "Unable to setup two-factor authentication"
msgstr "Zwei-Faktor-Authentifizierung kann nicht eingerichtet werden" msgstr "Zwei-Faktor-Authentifizierung kann nicht eingerichtet werden"
#: apps/web/src/components/forms/signin.tsx:247 #: apps/web/src/components/forms/signin.tsx:248
#: apps/web/src/components/forms/signin.tsx:255 #: apps/web/src/components/forms/signin.tsx:256
msgid "Unable to sign in" msgid "Unable to sign in"
msgstr "Anmeldung nicht möglich" msgstr "Anmeldung nicht möglich"
@@ -4227,6 +4228,7 @@ msgstr "Unvollendet"
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:262 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:262
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:273 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:273
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:284 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:284
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:55
msgid "Unknown" msgid "Unknown"
msgstr "Unbekannt" msgstr "Unbekannt"
@@ -4267,7 +4269,7 @@ msgstr "Profil aktualisieren"
msgid "Update Recipient" msgid "Update Recipient"
msgstr "Empfänger aktualisieren" msgstr "Empfänger aktualisieren"
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:146 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:144
msgid "Update role" msgid "Update role"
msgstr "Rolle aktualisieren" msgstr "Rolle aktualisieren"
@@ -4336,12 +4338,12 @@ msgid "Use"
msgstr "Verwenden" msgstr "Verwenden"
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:187 #: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:187
#: apps/web/src/components/forms/signin.tsx:505 #: apps/web/src/components/forms/signin.tsx:506
msgid "Use Authenticator" msgid "Use Authenticator"
msgstr "Authenticator verwenden" msgstr "Authenticator verwenden"
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:185 #: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:185
#: apps/web/src/components/forms/signin.tsx:503 #: apps/web/src/components/forms/signin.tsx:504
msgid "Use Backup Code" msgid "Use Backup Code"
msgstr "Backup-Code verwenden" msgstr "Backup-Code verwenden"
@@ -4349,7 +4351,7 @@ msgstr "Backup-Code verwenden"
msgid "Use Template" msgid "Use Template"
msgstr "Vorlage verwenden" msgstr "Vorlage verwenden"
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:78 #: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:76
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:45 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:45
msgid "User" msgid "User"
msgstr "Benutzer" msgstr "Benutzer"
@@ -4435,7 +4437,7 @@ msgstr "Alle Dokumente anzeigen, die an Ihr Konto gesendet wurden"
msgid "View all recent security activity related to your account." msgid "View all recent security activity related to your account."
msgstr "Sehen Sie sich alle aktuellen Sicherheitsaktivitäten in Ihrem Konto an." msgstr "Sehen Sie sich alle aktuellen Sicherheitsaktivitäten in Ihrem Konto an."
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:157 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:155
msgid "View all related documents" msgid "View all related documents"
msgstr "Alle verwandten Dokumente anzeigen" msgstr "Alle verwandten Dokumente anzeigen"
@@ -4459,7 +4461,7 @@ msgstr "Dokumente ansehen, die mit dieser E-Mail verknüpft sind"
msgid "View invites" msgid "View invites"
msgstr "Einladungen ansehen" msgstr "Einladungen ansehen"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:95 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:93
msgid "View more" msgid "View more"
msgstr "Mehr anzeigen" msgstr "Mehr anzeigen"
@@ -4594,9 +4596,9 @@ msgid "We encountered an unknown error while attempting to save your details. Pl
msgstr "Wir sind auf einen unbekannten Fehler gestoßen, während wir versucht haben, Ihre Daten zu speichern. Bitte versuchen Sie es später erneut." msgstr "Wir sind auf einen unbekannten Fehler gestoßen, während wir versucht haben, Ihre Daten zu speichern. Bitte versuchen Sie es später erneut."
#: apps/web/src/components/forms/profile.tsx:89 #: apps/web/src/components/forms/profile.tsx:89
#: apps/web/src/components/forms/signin.tsx:272 #: apps/web/src/components/forms/signin.tsx:273
#: apps/web/src/components/forms/signin.tsx:287 #: apps/web/src/components/forms/signin.tsx:288
#: apps/web/src/components/forms/signin.tsx:303 #: apps/web/src/components/forms/signin.tsx:304
msgid "We encountered an unknown error while attempting to sign you In. Please try again later." msgid "We encountered an unknown error while attempting to sign you In. Please try again later."
msgstr "Wir sind auf einen unbekannten Fehler gestoßen, während wir versucht haben, Sie anzumelden. Bitte versuchen Sie es später erneut." msgstr "Wir sind auf einen unbekannten Fehler gestoßen, während wir versucht haben, Sie anzumelden. Bitte versuchen Sie es später erneut."
@@ -4797,6 +4799,7 @@ msgid "Write about yourself"
msgstr "Schreiben Sie über sich selbst" msgstr "Schreiben Sie über sich selbst"
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:31 #: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:31
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:53
msgid "Yearly" msgid "Yearly"
msgstr "Jährlich" msgstr "Jährlich"
@@ -4841,6 +4844,10 @@ msgstr "Sie aktualisieren derzeit <0>{teamMemberName}.</0>"
msgid "You are currently updating the <0>{passkeyName}</0> passkey." msgid "You are currently updating the <0>{passkeyName}</0> passkey."
msgstr "Sie aktualisieren derzeit den <0>{passkeyName}</0> Passkey." msgstr "Sie aktualisieren derzeit den <0>{passkeyName}</0> Passkey."
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:64
msgid "You are not a member of this team."
msgstr ""
#: apps/web/src/app/(teams)/t/[teamUrl]/error.tsx:28 #: apps/web/src/app/(teams)/t/[teamUrl]/error.tsx:28
msgid "You are not authorized to view this page." msgid "You are not authorized to view this page."
msgstr "Sie sind nicht berechtigt, diese Seite anzuzeigen." msgstr "Sie sind nicht berechtigt, diese Seite anzuzeigen."
@@ -4965,7 +4972,7 @@ msgstr "Sie haben {teamMemberName} aktualisiert."
msgid "You have verified your email address for <0>{0}</0>." msgid "You have verified your email address for <0>{0}</0>."
msgstr "Sie haben Ihre E-Mail-Adresse für <0>{0}</0> bestätigt." msgstr "Sie haben Ihre E-Mail-Adresse für <0>{0}</0> bestätigt."
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:82 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:88
msgid "You must be an admin of this team to manage billing." msgid "You must be an admin of this team to manage billing."
msgstr "Sie müssen Administrator dieses Teams sein, um die Abrechnung zu verwalten." msgstr "Sie müssen Administrator dieses Teams sein, um die Abrechnung zu verwalten."
@@ -5119,7 +5126,7 @@ msgstr "Ihr Wiederherstellungscode wurde in die Zwischenablage kopiert."
msgid "Your recovery codes are listed below. Please store them in a safe place." msgid "Your recovery codes are listed below. Please store them in a safe place."
msgstr "Ihre Wiederherstellungscodes sind unten aufgeführt. Bitte bewahren Sie sie an einem sicheren Ort auf." msgstr "Ihre Wiederherstellungscodes sind unten aufgeführt. Bitte bewahren Sie sie an einem sicheren Ort auf."
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:62 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:72
msgid "Your subscription is currently active." msgid "Your subscription is currently active."
msgstr "Ihr Abonnement ist derzeit aktiv." msgstr "Ihr Abonnement ist derzeit aktiv."

View File

@@ -25,11 +25,11 @@ msgstr "“{documentName}” has been signed"
msgid "“{documentName}” was signed by all signers" msgid "“{documentName}” was signed by all signers"
msgstr "“{documentName}” was signed by all signers" msgstr "“{documentName}” was signed by all signers"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:137 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:125
msgid "{0} has invited you to {recipientActionVerb} the document \"{1}\"." msgid "{0} has invited you to {recipientActionVerb} the document \"{1}\"."
msgstr "{0} has invited you to {recipientActionVerb} the document \"{1}\"." msgstr "{0} has invited you to {recipientActionVerb} the document \"{1}\"."
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:130 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:118
msgid "{0} invited you to {recipientActionVerb} a document" msgid "{0} invited you to {recipientActionVerb} a document"
msgstr "{0} invited you to {recipientActionVerb} a document" msgstr "{0} invited you to {recipientActionVerb} a document"
@@ -45,7 +45,7 @@ msgstr "{0} left the team {teamName} on Documenso"
msgid "{0} of {1} row(s) selected." msgid "{0} of {1} row(s) selected."
msgstr "{0} of {1} row(s) selected." msgstr "{0} of {1} row(s) selected."
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:136 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:124
#: packages/lib/server-only/document/resend-document.tsx:137 #: packages/lib/server-only/document/resend-document.tsx:137
msgid "{0} on behalf of \"{1}\" has invited you to {recipientActionVerb} the document \"{2}\"." msgid "{0} on behalf of \"{1}\" has invited you to {recipientActionVerb} the document \"{2}\"."
msgstr "{0} on behalf of \"{1}\" has invited you to {recipientActionVerb} the document \"{2}\"." msgstr "{0} on behalf of \"{1}\" has invited you to {recipientActionVerb} the document \"{2}\"."
@@ -190,6 +190,22 @@ msgstr "{recipientName} {action} a document by using one of your direct links"
msgid "{recipientName} has rejected the document '{documentName}'" msgid "{recipientName} has rejected the document '{documentName}'"
msgstr "{recipientName} has rejected the document '{documentName}'" msgstr "{recipientName} has rejected the document '{documentName}'"
#: packages/email/template-components/template-document-recipient-signed.tsx:49
msgid "{recipientReference} has completed signing the document."
msgstr "{recipientReference} has completed signing the document."
#: packages/lib/jobs/definitions/emails/send-recipient-signed-email.ts:121
msgid "{recipientReference} has signed \"{0}\""
msgstr "{recipientReference} has signed \"{0}\""
#: packages/email/template-components/template-document-recipient-signed.tsx:43
msgid "{recipientReference} has signed \"{documentName}\""
msgstr "{recipientReference} has signed \"{documentName}\""
#: packages/email/templates/document-recipient-signed.tsx:27
msgid "{recipientReference} has signed {documentName}"
msgstr "{recipientReference} has signed {documentName}"
#: packages/email/template-components/template-document-rejected.tsx:25 #: packages/email/template-components/template-document-rejected.tsx:25
msgid "{signerName} has rejected the document \"{documentName}\"." msgid "{signerName} has rejected the document \"{documentName}\"."
msgstr "{signerName} has rejected the document \"{documentName}\"." msgstr "{signerName} has rejected the document \"{documentName}\"."
@@ -284,7 +300,7 @@ msgstr "<0>Require account</0> - The recipient must be signed in to view the doc
msgid "<0>Require passkey</0> - The recipient must have an account and passkey configured via their settings" msgid "<0>Require passkey</0> - The recipient must have an account and passkey configured via their settings"
msgstr "<0>Require passkey</0> - The recipient must have an account and passkey configured via their settings" msgstr "<0>Require passkey</0> - The recipient must have an account and passkey configured via their settings"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:122 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:110
msgid "A document was created by your direct template that requires you to {recipientActionVerb} it." msgid "A document was created by your direct template that requires you to {recipientActionVerb} it."
msgstr "A document was created by your direct template that requires you to {recipientActionVerb} it." msgstr "A document was created by your direct template that requires you to {recipientActionVerb} it."
@@ -300,7 +316,7 @@ msgstr "A field was removed"
msgid "A field was updated" msgid "A field was updated"
msgstr "A field was updated" msgstr "A field was updated"
#: packages/lib/jobs/definitions/emails/send-team-member-joined-email.ts:107 #: packages/lib/jobs/definitions/emails/send-team-member-joined-email.handler.ts:98
msgid "A new member has joined your team" msgid "A new member has joined your team"
msgstr "A new member has joined your team" msgstr "A new member has joined your team"
@@ -324,7 +340,7 @@ msgstr "A request to use your email has been initiated by {0} on Documenso"
msgid "A team member has joined a team on Documenso" msgid "A team member has joined a team on Documenso"
msgstr "A team member has joined a team on Documenso" msgstr "A team member has joined a team on Documenso"
#: packages/lib/jobs/definitions/emails/send-team-member-left-email.ts:96 #: packages/lib/jobs/definitions/emails/send-team-member-left-email.handler.ts:87
msgid "A team member has left {0}" msgid "A team member has left {0}"
msgstr "A team member has left {0}" msgstr "A team member has left {0}"
@@ -359,12 +375,12 @@ msgstr "Accept team transfer request on Documenso"
msgid "Add a document" msgid "Add a document"
msgstr "Add a document" msgstr "Add a document"
#: packages/ui/primitives/document-flow/add-settings.tsx:378 #: packages/ui/primitives/document-flow/add-settings.tsx:390
#: packages/ui/primitives/template-flow/add-template-settings.tsx:468 #: packages/ui/primitives/template-flow/add-template-settings.tsx:468
msgid "Add a URL to redirect the user to once the document is signed" msgid "Add a URL to redirect the user to once the document is signed"
msgstr "Add a URL to redirect the user to once the document is signed" msgstr "Add a URL to redirect the user to once the document is signed"
#: packages/ui/primitives/document-flow/add-settings.tsx:290 #: packages/ui/primitives/document-flow/add-settings.tsx:302
msgid "Add an external ID to the document. This can be used to identify the document in external systems." msgid "Add an external ID to the document. This can be used to identify the document in external systems."
msgstr "Add an external ID to the document. This can be used to identify the document in external systems." msgstr "Add an external ID to the document. This can be used to identify the document in external systems."
@@ -409,13 +425,13 @@ msgstr "Add text to the field"
msgid "Admin" msgid "Admin"
msgstr "Admin" msgstr "Admin"
#: packages/ui/primitives/document-flow/add-settings.tsx:272 #: packages/ui/primitives/document-flow/add-settings.tsx:284
#: packages/ui/primitives/template-flow/add-template-settings.tsx:367 #: packages/ui/primitives/template-flow/add-template-settings.tsx:367
msgid "Advanced Options" msgid "Advanced Options"
msgstr "Advanced Options" msgstr "Advanced Options"
#: packages/ui/primitives/document-flow/add-fields.tsx:576 #: packages/ui/primitives/document-flow/add-fields.tsx:577
#: packages/ui/primitives/template-flow/add-template-fields.tsx:414 #: packages/ui/primitives/template-flow/add-template-fields.tsx:415
msgid "Advanced settings" msgid "Advanced settings"
msgstr "Advanced settings" msgstr "Advanced settings"
@@ -467,11 +483,11 @@ msgstr "Approving"
msgid "Before you get started, please confirm your email address by clicking the button below:" 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:" msgstr "Before you get started, please confirm your email address by clicking the button below:"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:524 #: packages/ui/primitives/signature-pad/signature-pad.tsx:531
msgid "Black" msgid "Black"
msgstr "Black" msgstr "Black"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:538 #: packages/ui/primitives/signature-pad/signature-pad.tsx:545
msgid "Blue" msgid "Blue"
msgstr "Blue" msgstr "Blue"
@@ -487,7 +503,7 @@ msgstr "By accepting this request, you will be granting <0>{teamName}</0> access
msgid "By accepting this request, you will take responsibility for any billing items associated with this team." msgid "By accepting this request, you will take responsibility for any billing items associated with this team."
msgstr "By accepting this request, you will take responsibility for any billing items associated with this team." msgstr "By accepting this request, you will take responsibility for any billing items associated with this team."
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:356 #: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:357
#: packages/ui/primitives/document-flow/send-document-action-dialog.tsx:58 #: packages/ui/primitives/document-flow/send-document-action-dialog.tsx:58
msgid "Cancel" msgid "Cancel"
msgstr "Cancel" msgstr "Cancel"
@@ -529,7 +545,7 @@ msgstr "Checkbox values"
msgid "Clear filters" msgid "Clear filters"
msgstr "Clear filters" msgstr "Clear filters"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:558 #: packages/ui/primitives/signature-pad/signature-pad.tsx:565
msgid "Clear Signature" msgid "Clear Signature"
msgstr "Clear Signature" msgstr "Clear Signature"
@@ -542,6 +558,7 @@ msgid "Close"
msgstr "Close" msgstr "Close"
#: packages/email/template-components/template-document-completed.tsx:35 #: packages/email/template-components/template-document-completed.tsx:35
#: packages/email/template-components/template-document-recipient-signed.tsx:37
#: packages/email/template-components/template-document-self-signed.tsx:36 #: packages/email/template-components/template-document-self-signed.tsx:36
#: packages/lib/constants/document.ts:10 #: packages/lib/constants/document.ts:10
msgid "Completed" msgid "Completed"
@@ -556,8 +573,8 @@ msgstr "Completed Document"
msgid "Configure Direct Recipient" msgid "Configure Direct Recipient"
msgstr "Configure Direct Recipient" msgstr "Configure Direct Recipient"
#: packages/ui/primitives/document-flow/add-fields.tsx:577 #: packages/ui/primitives/document-flow/add-fields.tsx:578
#: packages/ui/primitives/template-flow/add-template-fields.tsx:415 #: packages/ui/primitives/template-flow/add-template-fields.tsx:416
msgid "Configure the {0} field" msgid "Configure the {0} field"
msgstr "Configure the {0} field" msgstr "Configure the {0} field"
@@ -614,13 +631,13 @@ msgstr "Create account"
msgid "Custom Text" msgid "Custom Text"
msgstr "Custom Text" msgstr "Custom Text"
#: packages/ui/primitives/document-flow/add-fields.tsx:934 #: packages/ui/primitives/document-flow/add-fields.tsx:938
#: packages/ui/primitives/document-flow/types.ts:53 #: 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:733
msgid "Date" msgid "Date"
msgstr "Date" msgstr "Date"
#: packages/ui/primitives/document-flow/add-settings.tsx:313 #: packages/ui/primitives/document-flow/add-settings.tsx:325
#: packages/ui/primitives/template-flow/add-template-settings.tsx:408 #: packages/ui/primitives/template-flow/add-template-settings.tsx:408
msgid "Date Format" msgid "Date Format"
msgstr "Date Format" msgstr "Date Format"
@@ -637,16 +654,16 @@ msgstr "Didn't request a password change? We are here to help you secure your ac
msgid "Direct link receiver" msgid "Direct link receiver"
msgstr "Direct link receiver" msgstr "Direct link receiver"
#: packages/lib/jobs/definitions/emails/send-rejection-emails.ts:149 #: packages/lib/jobs/definitions/emails/send-rejection-emails.handler.ts:140
msgid "Document \"{0}\" - Rejected by {1}" msgid "Document \"{0}\" - Rejected by {1}"
msgstr "Document \"{0}\" - Rejected by {1}" msgstr "Document \"{0}\" - Rejected by {1}"
#: packages/lib/jobs/definitions/emails/send-rejection-emails.ts:109 #: packages/lib/jobs/definitions/emails/send-rejection-emails.handler.ts:100
msgid "Document \"{0}\" - Rejection Confirmed" msgid "Document \"{0}\" - Rejection Confirmed"
msgstr "Document \"{0}\" - Rejection Confirmed" msgstr "Document \"{0}\" - Rejection Confirmed"
#: packages/ui/components/document/document-global-auth-access-select.tsx:62 #: packages/ui/components/document/document-global-auth-access-select.tsx:62
#: packages/ui/primitives/document-flow/add-settings.tsx:216 #: packages/ui/primitives/document-flow/add-settings.tsx:227
#: packages/ui/primitives/template-flow/add-template-settings.tsx:202 #: packages/ui/primitives/template-flow/add-template-settings.tsx:202
msgid "Document access" msgid "Document access"
msgstr "Document access" msgstr "Document access"
@@ -665,7 +682,8 @@ msgstr "Document Cancelled"
msgid "Document completed" msgid "Document completed"
msgstr "Document completed" msgstr "Document completed"
#: packages/ui/components/document/document-email-checkboxes.tsx:168 #: packages/ui/components/document/document-email-checkboxes.tsx:208
#: packages/ui/components/document/document-email-checkboxes.tsx:286
msgid "Document completed email" msgid "Document completed email"
msgstr "Document completed email" msgstr "Document completed email"
@@ -674,7 +692,7 @@ msgid "Document created"
msgstr "Document created" msgstr "Document created"
#: packages/email/templates/document-created-from-direct-template.tsx:32 #: packages/email/templates/document-created-from-direct-template.tsx:32
#: packages/lib/server-only/template/create-document-from-direct-template.ts:574 #: packages/lib/server-only/template/create-document-from-direct-template.ts:585
msgid "Document created from direct template" msgid "Document created from direct template"
msgstr "Document created from direct template" msgstr "Document created from direct template"
@@ -686,7 +704,7 @@ msgstr "Document Creation"
msgid "Document deleted" msgid "Document deleted"
msgstr "Document deleted" msgstr "Document deleted"
#: packages/ui/components/document/document-email-checkboxes.tsx:207 #: packages/ui/components/document/document-email-checkboxes.tsx:247
msgid "Document deleted email" msgid "Document deleted email"
msgstr "Document deleted email" msgstr "Document deleted email"
@@ -711,7 +729,7 @@ msgstr "Document moved to team"
msgid "Document opened" msgid "Document opened"
msgstr "Document opened" msgstr "Document opened"
#: packages/ui/components/document/document-email-checkboxes.tsx:128 #: packages/ui/components/document/document-email-checkboxes.tsx:168
msgid "Document pending email" msgid "Document pending email"
msgstr "Document pending email" msgstr "Document pending email"
@@ -752,8 +770,8 @@ msgstr "Draft"
msgid "Drag & drop your PDF here." msgid "Drag & drop your PDF here."
msgstr "Drag & drop your PDF here." msgstr "Drag & drop your PDF here."
#: packages/ui/primitives/document-flow/add-fields.tsx:1065 #: packages/ui/primitives/document-flow/add-fields.tsx:1069
#: packages/ui/primitives/template-flow/add-template-fields.tsx:860 #: packages/ui/primitives/template-flow/add-template-fields.tsx:864
msgid "Dropdown" msgid "Dropdown"
msgstr "Dropdown" msgstr "Dropdown"
@@ -762,12 +780,12 @@ msgid "Dropdown options"
msgstr "Dropdown options" msgstr "Dropdown options"
#: packages/lib/constants/document.ts:28 #: packages/lib/constants/document.ts:28
#: packages/ui/primitives/document-flow/add-fields.tsx:882 #: packages/ui/primitives/document-flow/add-fields.tsx:886
#: packages/ui/primitives/document-flow/add-signature.tsx:273 #: packages/ui/primitives/document-flow/add-signature.tsx:273
#: packages/ui/primitives/document-flow/add-signers.tsx:512 #: packages/ui/primitives/document-flow/add-signers.tsx:512
#: packages/ui/primitives/document-flow/add-signers.tsx:519 #: packages/ui/primitives/document-flow/add-signers.tsx:519
#: packages/ui/primitives/document-flow/types.ts:54 #: 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-fields.tsx:681
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:471 #: 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-placeholder-recipients.tsx:478
msgid "Email" msgid "Email"
@@ -789,7 +807,7 @@ msgstr "Email resent"
msgid "Email sent" msgid "Email sent"
msgstr "Email sent" msgstr "Email sent"
#: packages/ui/primitives/document-flow/add-fields.tsx:1130 #: packages/ui/primitives/document-flow/add-fields.tsx:1134
msgid "Empty field" msgid "Empty field"
msgstr "Empty field" msgstr "Empty field"
@@ -802,8 +820,8 @@ msgstr "Enable Direct Link Signing"
msgid "Enable signing order" msgid "Enable signing order"
msgstr "Enable signing order" msgstr "Enable signing order"
#: packages/ui/primitives/document-flow/add-fields.tsx:802 #: packages/ui/primitives/document-flow/add-fields.tsx:806
#: packages/ui/primitives/template-flow/add-template-fields.tsx:597 #: packages/ui/primitives/template-flow/add-template-fields.tsx:601
msgid "Enable Typed Signatures" msgid "Enable Typed Signatures"
msgstr "Enable Typed Signatures" msgstr "Enable Typed Signatures"
@@ -811,17 +829,17 @@ msgstr "Enable Typed Signatures"
msgid "Enter password" msgid "Enter password"
msgstr "Enter password" msgstr "Enter password"
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:257 #: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:258
#: packages/ui/primitives/pdf-viewer.tsx:166 #: packages/ui/primitives/pdf-viewer.tsx:166
msgid "Error" msgid "Error"
msgstr "Error" msgstr "Error"
#: packages/ui/primitives/document-flow/add-settings.tsx:283 #: packages/ui/primitives/document-flow/add-settings.tsx:295
#: packages/ui/primitives/template-flow/add-template-settings.tsx:378 #: packages/ui/primitives/template-flow/add-template-settings.tsx:378
msgid "External ID" msgid "External ID"
msgstr "External ID" msgstr "External ID"
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:258 #: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:259
msgid "Failed to save settings." msgid "Failed to save settings."
msgstr "Failed to save settings." msgstr "Failed to save settings."
@@ -891,7 +909,7 @@ msgstr "Global recipient action authentication"
msgid "Go Back" msgid "Go Back"
msgstr "Go Back" msgstr "Go Back"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:545 #: packages/ui/primitives/signature-pad/signature-pad.tsx:552
msgid "Green" msgid "Green"
msgstr "Green" msgstr "Green"
@@ -942,7 +960,7 @@ msgstr "Join {teamName} on Documenso"
msgid "Label" msgid "Label"
msgstr "Label" msgstr "Label"
#: packages/ui/primitives/document-flow/add-settings.tsx:176 #: packages/ui/primitives/document-flow/add-settings.tsx:187
#: packages/ui/primitives/template-flow/add-template-settings.tsx:162 #: packages/ui/primitives/template-flow/add-template-settings.tsx:162
msgid "Language" msgid "Language"
msgstr "Language" msgstr "Language"
@@ -978,12 +996,12 @@ msgstr "Message <0>(Optional)</0>"
msgid "Min" msgid "Min"
msgstr "Min" msgstr "Min"
#: packages/ui/primitives/document-flow/add-fields.tsx:908 #: packages/ui/primitives/document-flow/add-fields.tsx:912
#: packages/ui/primitives/document-flow/add-signature.tsx:299 #: packages/ui/primitives/document-flow/add-signature.tsx:299
#: packages/ui/primitives/document-flow/add-signers.tsx:550 #: packages/ui/primitives/document-flow/add-signers.tsx:550
#: packages/ui/primitives/document-flow/add-signers.tsx:556 #: packages/ui/primitives/document-flow/add-signers.tsx:556
#: packages/ui/primitives/document-flow/types.ts:55 #: 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-fields.tsx:707
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:506 #: 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-placeholder-recipients.tsx:512
msgid "Name" msgid "Name"
@@ -1001,8 +1019,8 @@ msgstr "Needs to sign"
msgid "Needs to view" msgid "Needs to view"
msgstr "Needs to view" msgstr "Needs to view"
#: packages/ui/primitives/document-flow/add-fields.tsx:693 #: packages/ui/primitives/document-flow/add-fields.tsx:697
#: packages/ui/primitives/template-flow/add-template-fields.tsx:516 #: packages/ui/primitives/template-flow/add-template-fields.tsx:520
msgid "No recipient matching this description was found." msgid "No recipient matching this description was found."
msgstr "No recipient matching this description was found." msgstr "No recipient matching this description was found."
@@ -1010,8 +1028,8 @@ msgstr "No recipient matching this description was found."
msgid "No recipients" msgid "No recipients"
msgstr "No recipients" msgstr "No recipients"
#: packages/ui/primitives/document-flow/add-fields.tsx:708 #: packages/ui/primitives/document-flow/add-fields.tsx:712
#: packages/ui/primitives/template-flow/add-template-fields.tsx:531 #: packages/ui/primitives/template-flow/add-template-fields.tsx:535
msgid "No recipients with this role" msgid "No recipients with this role"
msgstr "No recipients with this role" msgstr "No recipients with this role"
@@ -1039,9 +1057,9 @@ msgstr "No value found."
msgid "None" msgid "None"
msgstr "None" msgstr "None"
#: packages/ui/primitives/document-flow/add-fields.tsx:986 #: packages/ui/primitives/document-flow/add-fields.tsx:990
#: packages/ui/primitives/document-flow/types.ts:56 #: 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:785
msgid "Number" msgid "Number"
msgstr "Number" msgstr "Number"
@@ -1107,15 +1125,15 @@ msgstr "Please {0} your document<0/>\"{documentName}\""
msgid "Please {action} your document {documentName}" msgid "Please {action} your document {documentName}"
msgstr "Please {action} your document {documentName}" msgstr "Please {action} your document {documentName}"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:111 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:99
msgid "Please {recipientActionVerb} this document" msgid "Please {recipientActionVerb} this document"
msgstr "Please {recipientActionVerb} this document" msgstr "Please {recipientActionVerb} this document"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:125 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:113
msgid "Please {recipientActionVerb} this document created by your direct template" msgid "Please {recipientActionVerb} this document created by your direct template"
msgstr "Please {recipientActionVerb} this document created by your direct template" msgstr "Please {recipientActionVerb} this document created by your direct template"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:117 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:105
msgid "Please {recipientActionVerb} your document" msgid "Please {recipientActionVerb} your document"
msgstr "Please {recipientActionVerb} your document" msgstr "Please {recipientActionVerb} your document"
@@ -1162,24 +1180,28 @@ msgid "Recipient"
msgstr "Recipient" msgstr "Recipient"
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:39 #: packages/ui/components/recipient/recipient-action-auth-select.tsx:39
#: packages/ui/primitives/document-flow/add-settings.tsx:257 #: packages/ui/primitives/document-flow/add-settings.tsx:269
#: packages/ui/primitives/template-flow/add-template-settings.tsx:291 #: packages/ui/primitives/template-flow/add-template-settings.tsx:291
msgid "Recipient action authentication" msgid "Recipient action authentication"
msgstr "Recipient action authentication" msgstr "Recipient action authentication"
#: packages/ui/components/document/document-email-checkboxes.tsx:89 #: packages/ui/components/document/document-email-checkboxes.tsx:129
msgid "Recipient removed email" msgid "Recipient removed email"
msgstr "Recipient removed email" msgstr "Recipient removed email"
#: packages/ui/components/document/document-email-checkboxes.tsx:50 #: packages/ui/components/document/document-email-checkboxes.tsx:51
msgid "Recipient signed email"
msgstr "Recipient signed email"
#: packages/ui/components/document/document-email-checkboxes.tsx:90
msgid "Recipient signing request email" msgid "Recipient signing request email"
msgstr "Recipient signing request email" msgstr "Recipient signing request email"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:531 #: packages/ui/primitives/signature-pad/signature-pad.tsx:538
msgid "Red" msgid "Red"
msgstr "Red" msgstr "Red"
#: packages/ui/primitives/document-flow/add-settings.tsx:371 #: packages/ui/primitives/document-flow/add-settings.tsx:383
#: packages/ui/primitives/template-flow/add-template-settings.tsx:461 #: packages/ui/primitives/template-flow/add-template-settings.tsx:461
msgid "Redirect URL" msgid "Redirect URL"
msgstr "Redirect URL" msgstr "Redirect URL"
@@ -1212,7 +1234,7 @@ msgstr "Reminder: Please {recipientActionVerb} this document"
msgid "Reminder: Please {recipientActionVerb} your document" msgid "Reminder: Please {recipientActionVerb} your document"
msgstr "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:1121
msgid "Remove" msgid "Remove"
msgstr "Remove" msgstr "Remove"
@@ -1240,11 +1262,11 @@ msgstr "Rest assured, your document is strictly confidential and will never be s
msgid "Rows per page" msgid "Rows per page"
msgstr "Rows per page" msgstr "Rows per page"
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:355 #: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:356
msgid "Save" msgid "Save"
msgstr "Save" msgstr "Save"
#: packages/ui/primitives/template-flow/add-template-fields.tsx:893 #: packages/ui/primitives/template-flow/add-template-fields.tsx:897
msgid "Save Template" msgid "Save Template"
msgstr "Save Template" msgstr "Save Template"
@@ -1280,15 +1302,19 @@ msgstr "Send"
msgid "Send Document" msgid "Send Document"
msgstr "Send Document" msgstr "Send Document"
#: packages/ui/components/document/document-email-checkboxes.tsx:158 #: packages/ui/components/document/document-email-checkboxes.tsx:198
msgid "Send document completed email" msgid "Send document completed email"
msgstr "Send document completed email" msgstr "Send document completed email"
#: packages/ui/components/document/document-email-checkboxes.tsx:197 #: packages/ui/components/document/document-email-checkboxes.tsx:276
msgid "Send document completed email to the owner"
msgstr "Send document completed email to the owner"
#: packages/ui/components/document/document-email-checkboxes.tsx:237
msgid "Send document deleted email" msgid "Send document deleted email"
msgstr "Send document deleted email" msgstr "Send document deleted email"
#: packages/ui/components/document/document-email-checkboxes.tsx:118 #: packages/ui/components/document/document-email-checkboxes.tsx:158
msgid "Send document pending email" msgid "Send document pending email"
msgstr "Send document pending email" msgstr "Send document pending email"
@@ -1296,11 +1322,15 @@ msgstr "Send document pending email"
msgid "Send documents on behalf of the team using the email address" msgid "Send documents on behalf of the team using the email address"
msgstr "Send documents on behalf of the team using the email address" msgstr "Send documents on behalf of the team using the email address"
#: packages/ui/components/document/document-email-checkboxes.tsx:79 #: packages/ui/components/document/document-email-checkboxes.tsx:119
msgid "Send recipient removed email" msgid "Send recipient removed email"
msgstr "Send recipient removed email" msgstr "Send recipient removed email"
#: packages/ui/components/document/document-email-checkboxes.tsx:40 #: packages/ui/components/document/document-email-checkboxes.tsx:41
msgid "Send recipient signed email"
msgstr "Send recipient signed email"
#: packages/ui/components/document/document-email-checkboxes.tsx:80
msgid "Send recipient signing request email" msgid "Send recipient signing request email"
msgstr "Send recipient signing request email" msgstr "Send recipient signing request email"
@@ -1333,11 +1363,11 @@ msgstr "Sign Document"
msgid "Sign In" msgid "Sign In"
msgstr "Sign In" msgstr "Sign In"
#: packages/ui/primitives/document-flow/add-fields.tsx:830 #: packages/ui/primitives/document-flow/add-fields.tsx:834
#: packages/ui/primitives/document-flow/add-signature.tsx:324 #: packages/ui/primitives/document-flow/add-signature.tsx:324
#: packages/ui/primitives/document-flow/field-icon.tsx:52 #: packages/ui/primitives/document-flow/field-icon.tsx:52
#: packages/ui/primitives/document-flow/types.ts:49 #: 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:629
msgid "Signature" msgid "Signature"
msgstr "Signature" msgstr "Signature"
@@ -1361,8 +1391,8 @@ msgstr "Signers must have unique emails"
msgid "Signing" msgid "Signing"
msgstr "Signing" msgstr "Signing"
#: packages/lib/server-only/document/send-completed-email.ts:114 #: packages/lib/server-only/document/send-completed-email.ts:119
#: packages/lib/server-only/document/send-completed-email.ts:194 #: packages/lib/server-only/document/send-completed-email.ts:199
msgid "Signing Complete!" msgid "Signing Complete!"
msgstr "Signing Complete!" msgstr "Signing Complete!"
@@ -1416,9 +1446,9 @@ msgstr "Team email removed for {teamName} on Documenso"
msgid "Template title" msgid "Template title"
msgstr "Template title" msgstr "Template title"
#: packages/ui/primitives/document-flow/add-fields.tsx:960 #: packages/ui/primitives/document-flow/add-fields.tsx:964
#: packages/ui/primitives/document-flow/types.ts:52 #: 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:759
msgid "Text" msgid "Text"
msgstr "Text" msgstr "Text"
@@ -1510,7 +1540,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." 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." 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:768
msgid "This document has already been sent to this recipient. You can no longer edit this recipient." 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." msgstr "This document has already been sent to this recipient. You can no longer edit this recipient."
@@ -1526,15 +1556,19 @@ msgstr "This document was sent using <0>Documenso.</0>"
msgid "This email confirms that you have rejected the document <0>\"{documentName}\"</0> sent by {documentOwnerName}." msgid "This email confirms that you have rejected the document <0>\"{documentName}\"</0> sent by {documentOwnerName}."
msgstr "This email confirms that you have rejected the document <0>\"{documentName}\"</0> sent by {documentOwnerName}." msgstr "This email confirms that you have rejected the document <0>\"{documentName}\"</0> sent by {documentOwnerName}."
#: packages/ui/components/document/document-email-checkboxes.tsx:94 #: packages/ui/components/document/document-email-checkboxes.tsx:56
msgid "This email is sent to the document owner when a recipient has signed the document."
msgstr "This email is sent to the document owner when a recipient has signed the document."
#: packages/ui/components/document/document-email-checkboxes.tsx:134
msgid "This email is sent to the recipient if they are removed from a pending document." msgid "This email is sent to the recipient if they are removed from a pending document."
msgstr "This email is sent to the recipient if they are removed from a pending document." msgstr "This email is sent to the recipient if they are removed from a pending document."
#: packages/ui/components/document/document-email-checkboxes.tsx:55 #: packages/ui/components/document/document-email-checkboxes.tsx:95
msgid "This email is sent to the recipient requesting them to sign the document." msgid "This email is sent to the recipient requesting them to sign the document."
msgstr "This email is sent to the recipient requesting them to sign the document." msgstr "This email is sent to the recipient requesting them to sign the document."
#: packages/ui/components/document/document-email-checkboxes.tsx:133 #: packages/ui/components/document/document-email-checkboxes.tsx:173
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." 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." 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."
@@ -1546,7 +1580,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." 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." 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:1101
msgid "This recipient can no longer be modified as they have signed a field, or completed the document." 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." msgstr "This recipient can no longer be modified as they have signed a field, or completed the document."
@@ -1554,29 +1588,33 @@ msgstr "This recipient can no longer be modified as they have signed a field, or
msgid "This signer has already signed the document." msgid "This signer has already signed the document."
msgstr "This signer has already signed the document." msgstr "This signer has already signed the document."
#: packages/ui/components/document/document-email-checkboxes.tsx:212 #: packages/ui/components/document/document-email-checkboxes.tsx:252
msgid "This will be sent to all recipients if a pending document has been deleted." msgid "This will be sent to all recipients if a pending document has been deleted."
msgstr "This will be sent to all recipients if a pending document has been deleted." msgstr "This will be sent to all recipients if a pending document has been deleted."
#: packages/ui/components/document/document-email-checkboxes.tsx:173 #: packages/ui/components/document/document-email-checkboxes.tsx:213
msgid "This will be sent to all recipients once the document has been fully completed." msgid "This will be sent to all recipients once the document has been fully completed."
msgstr "This will be sent to all recipients once the document has been fully completed." msgstr "This will be sent to all recipients once the document has been fully completed."
#: packages/ui/components/document/document-email-checkboxes.tsx:291
msgid "This will be sent to the document owner once the document has been fully completed."
msgstr "This will be sent to the document owner once the document has been fully completed."
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:48 #: packages/ui/components/recipient/recipient-action-auth-select.tsx:48
msgid "This will override any global settings." msgid "This will override any global settings."
msgstr "This will override any global settings." msgstr "This will override any global settings."
#: packages/ui/primitives/document-flow/add-settings.tsx:347 #: packages/ui/primitives/document-flow/add-settings.tsx:359
#: packages/ui/primitives/template-flow/add-template-settings.tsx:438 #: packages/ui/primitives/template-flow/add-template-settings.tsx:438
msgid "Time Zone" msgid "Time Zone"
msgstr "Time Zone" msgstr "Time Zone"
#: packages/ui/primitives/document-flow/add-settings.tsx:155 #: packages/ui/primitives/document-flow/add-settings.tsx:166
msgid "Title" msgid "Title"
msgstr "Title" msgstr "Title"
#: packages/ui/primitives/document-flow/add-fields.tsx:1080 #: packages/ui/primitives/document-flow/add-fields.tsx:1084
#: packages/ui/primitives/template-flow/add-template-fields.tsx:873 #: packages/ui/primitives/template-flow/add-template-fields.tsx:877
msgid "To proceed further, please set at least one value for the {0} field." 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." msgstr "To proceed further, please set at least one value for the {0} field."
@@ -1592,7 +1630,7 @@ msgstr "Update the role and add fields as required for the direct recipient. The
msgid "Upgrade" msgid "Upgrade"
msgstr "Upgrade" msgstr "Upgrade"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:509 #: packages/ui/primitives/signature-pad/signature-pad.tsx:516
msgid "Upload Signature" msgid "Upload Signature"
msgstr "Upload Signature" msgstr "Upload Signature"
@@ -1721,7 +1759,7 @@ msgstr "You have been invited to join {0} on Documenso"
msgid "You have been invited to join the following team" msgid "You have been invited to join the following team"
msgstr "You have been invited to join the following team" msgstr "You have been invited to join the following team"
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:327 #: packages/lib/server-only/recipient/set-recipients-for-document.ts:337
msgid "You have been removed from a document" msgid "You have been removed from a document"
msgstr "You have been removed from a document" msgstr "You have been removed from a document"
@@ -1729,7 +1767,7 @@ msgstr "You have been removed from a document"
msgid "You have been requested to take ownership of team {0} on Documenso" msgid "You have been requested to take ownership of team {0} on Documenso"
msgstr "You have been requested to take ownership of team {0} on Documenso" msgstr "You have been requested to take ownership of team {0} on Documenso"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:115 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:103
#: packages/lib/server-only/document/resend-document.tsx:125 #: packages/lib/server-only/document/resend-document.tsx:125
msgid "You have initiated the document {0} that requires you to {recipientActionVerb} it." msgid "You have initiated the document {0} that requires you to {recipientActionVerb} it."
msgstr "You have initiated the document {0} that requires you to {recipientActionVerb} it." msgstr "You have initiated the document {0} that requires you to {recipientActionVerb} it."

View File

@@ -87,11 +87,7 @@ msgstr "{0} Recipient(s)"
msgid "{charactersRemaining, plural, one {1 character remaining} other {{charactersRemaining} characters remaining}}" msgid "{charactersRemaining, plural, one {1 character remaining} other {{charactersRemaining} characters remaining}}"
msgstr "{charactersRemaining, plural, one {1 character remaining} other {{charactersRemaining} characters remaining}}" msgstr "{charactersRemaining, plural, one {1 character remaining} other {{charactersRemaining} characters remaining}}"
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:55 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:59
msgid "{formattedTeamMemberQuanity} • Monthly • Renews: {formattedDate}"
msgstr "{formattedTeamMemberQuanity} • Monthly • Renews: {formattedDate}"
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:48
msgid "{numberOfSeats, plural, one {# member} other {# members}}" msgid "{numberOfSeats, plural, one {# member} other {# members}}"
msgstr "{numberOfSeats, plural, one {# member} other {# members}}" msgstr "{numberOfSeats, plural, one {# member} other {# members}}"
@@ -249,21 +245,21 @@ msgid "Acknowledgment"
msgstr "Acknowledgment" msgstr "Acknowledgment"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:108 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-dropdown.tsx:108
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:100 #: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:98
#: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:123 #: apps/web/src/app/(dashboard)/documents/data-table-action-dropdown.tsx:123
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164 #: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:164
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:118 #: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:116
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:46 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:46
msgid "Action" msgid "Action"
msgstr "Action" msgstr "Action"
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:85 #: apps/web/src/app/(dashboard)/documents/data-table.tsx:79
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:181 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:177
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:140 #: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:140
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:133 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:131
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:142 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:140
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:118 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:116
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:127 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:125
msgid "Actions" msgid "Actions"
msgstr "Actions" msgstr "Actions"
@@ -486,7 +482,7 @@ msgstr "An error occurred while loading team members. Please try again later."
msgid "An error occurred while moving the document." msgid "An error occurred while moving the document."
msgstr "An error occurred while moving the document." msgstr "An error occurred while moving the document."
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:57 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:65
msgid "An error occurred while moving the template." msgid "An error occurred while moving the template."
msgstr "An error occurred while moving the template." msgstr "An error occurred while moving the template."
@@ -494,7 +490,7 @@ msgstr "An error occurred while moving the template."
msgid "An error occurred while removing the field." msgid "An error occurred while removing the field."
msgstr "An error occurred while removing the field." msgstr "An error occurred while removing the field."
#: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:152 #: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:154
#: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:126 #: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:126
#: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:137 #: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:137
#: apps/web/src/app/(signing)/sign/[token]/email-field.tsx:110 #: apps/web/src/app/(signing)/sign/[token]/email-field.tsx:110
@@ -517,7 +513,7 @@ msgstr "An error occurred while sending the document."
msgid "An error occurred while sending your confirmation email" msgid "An error occurred while sending your confirmation email"
msgstr "An error occurred while sending your confirmation email" msgstr "An error occurred while sending your confirmation email"
#: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:123 #: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:125
#: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:100 #: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:100
#: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:106 #: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:106
#: apps/web/src/app/(signing)/sign/[token]/email-field.tsx:84 #: apps/web/src/app/(signing)/sign/[token]/email-field.tsx:84
@@ -539,7 +535,7 @@ msgstr "An error occurred while trying to create a checkout session."
msgid "An error occurred while updating the document settings." msgid "An error occurred while updating the document settings."
msgstr "An error occurred while updating the document settings." msgstr "An error occurred while updating the document settings."
#: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:213 #: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:215
msgid "An error occurred while updating the signature." msgid "An error occurred while updating the signature."
msgstr "An error occurred while updating the signature." msgstr "An error occurred while updating the signature."
@@ -573,11 +569,11 @@ msgstr "An error occurred while uploading your document."
#: apps/web/src/components/forms/profile.tsx:87 #: apps/web/src/components/forms/profile.tsx:87
#: apps/web/src/components/forms/public-profile-claim-dialog.tsx:113 #: apps/web/src/components/forms/public-profile-claim-dialog.tsx:113
#: apps/web/src/components/forms/public-profile-form.tsx:104 #: apps/web/src/components/forms/public-profile-form.tsx:104
#: apps/web/src/components/forms/signin.tsx:248 #: apps/web/src/components/forms/signin.tsx:249
#: apps/web/src/components/forms/signin.tsx:256 #: apps/web/src/components/forms/signin.tsx:257
#: apps/web/src/components/forms/signin.tsx:270 #: apps/web/src/components/forms/signin.tsx:271
#: apps/web/src/components/forms/signin.tsx:285 #: apps/web/src/components/forms/signin.tsx:286
#: apps/web/src/components/forms/signin.tsx:301 #: apps/web/src/components/forms/signin.tsx:302
#: apps/web/src/components/forms/signup.tsx:124 #: apps/web/src/components/forms/signup.tsx:124
#: apps/web/src/components/forms/signup.tsx:138 #: apps/web/src/components/forms/signup.tsx:138
#: apps/web/src/components/forms/token.tsx:143 #: apps/web/src/components/forms/token.tsx:143
@@ -592,11 +588,11 @@ msgstr "An unknown error occurred"
msgid "Any payment methods attached to this team will remain attached to this team. Please contact us if you need to update this information." msgid "Any payment methods attached to this team will remain attached to this team. Please contact us if you need to update this information."
msgstr "Any payment methods attached to this team will remain attached to this team. Please contact us if you need to update this information." msgstr "Any payment methods attached to this team will remain attached to this team. Please contact us if you need to update this information."
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:225 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:221
msgid "Any Source" msgid "Any Source"
msgstr "Any Source" msgstr "Any Source"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:205 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:201
msgid "Any Status" msgid "Any Status"
msgstr "Any Status" msgstr "Any Status"
@@ -699,7 +695,7 @@ msgid "Background Color"
msgstr "Background Color" msgstr "Background Color"
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:167 #: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:167
#: apps/web/src/components/forms/signin.tsx:485 #: apps/web/src/components/forms/signin.tsx:486
msgid "Backup Code" msgid "Backup Code"
msgstr "Backup Code" msgstr "Backup Code"
@@ -716,7 +712,7 @@ msgid "Basic details"
msgstr "Basic details" msgstr "Basic details"
#: apps/web/src/app/(dashboard)/settings/billing/page.tsx:74 #: apps/web/src/app/(dashboard)/settings/billing/page.tsx:74
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:61 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:71
#: apps/web/src/components/(dashboard)/settings/layout/desktop-nav.tsx:117 #: apps/web/src/components/(dashboard)/settings/layout/desktop-nav.tsx:117
#: apps/web/src/components/(dashboard)/settings/layout/mobile-nav.tsx:120 #: apps/web/src/components/(dashboard)/settings/layout/mobile-nav.tsx:120
#: apps/web/src/components/(teams)/settings/layout/desktop-nav.tsx:123 #: apps/web/src/components/(teams)/settings/layout/desktop-nav.tsx:123
@@ -732,7 +728,7 @@ msgstr "Branding Preferences"
msgid "Branding preferences updated" msgid "Branding preferences updated"
msgstr "Branding preferences updated" msgstr "Branding preferences updated"
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:99 #: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:97
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:48 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:48
msgid "Browser" msgid "Browser"
msgstr "Browser" msgstr "Browser"
@@ -775,7 +771,7 @@ msgstr "By using the electronic signature feature, you are consenting to conduct
#: apps/web/src/app/(dashboard)/settings/teams/team-email-usage.tsx:109 #: apps/web/src/app/(dashboard)/settings/teams/team-email-usage.tsx:109
#: apps/web/src/app/(dashboard)/templates/delete-template-dialog.tsx:81 #: apps/web/src/app/(dashboard)/templates/delete-template-dialog.tsx:81
#: apps/web/src/app/(dashboard)/templates/duplicate-template-dialog.tsx:78 #: 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/move-template-dialog.tsx:131
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:472 #: 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]/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-2fa.tsx:178
@@ -859,9 +855,9 @@ msgstr "Claim your username now"
msgid "Click here to get started" msgid "Click here to get started"
msgstr "Click here to get started" msgstr "Click here to get started"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:78 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:76
#: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:118 #: apps/web/src/app/(dashboard)/settings/public-profile/public-templates-data-table.tsx:118
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:68 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:66
#: apps/web/src/components/document/document-history-sheet.tsx:133 #: apps/web/src/components/document/document-history-sheet.tsx:133
msgid "Click here to retry" msgid "Click here to retry"
msgstr "Click here to retry" msgstr "Click here to retry"
@@ -914,7 +910,7 @@ msgstr "Complete Signing"
msgid "Complete Viewing" msgid "Complete Viewing"
msgstr "Complete Viewing" msgstr "Complete Viewing"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:208 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:204
#: apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx:77 #: apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx:77
#: apps/web/src/components/formatter/document-status.tsx:28 #: apps/web/src/components/formatter/document-status.tsx:28
msgid "Completed" msgid "Completed"
@@ -1144,9 +1140,9 @@ msgstr "Create your account and start using state-of-the-art document signing. O
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:62 #: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:62
#: apps/web/src/app/(dashboard)/admin/leaderboard/data-table-leaderboard.tsx:96 #: apps/web/src/app/(dashboard)/admin/leaderboard/data-table-leaderboard.tsx:96
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:35 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-information.tsx:35
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:54 #: apps/web/src/app/(dashboard)/documents/data-table.tsx:48
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:65 #: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:63
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:109 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:105
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-information.tsx:34 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-information.tsx:34
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:56 #: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:56
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:274 #: apps/web/src/components/templates/manage-public-template-dialog.tsx:274
@@ -1163,7 +1159,7 @@ msgid "Created by"
msgstr "Created by" msgstr "Created by"
#: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:48 #: apps/web/src/app/(dashboard)/admin/documents/[id]/page.tsx:48
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:78 #: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:76
msgid "Created on" msgid "Created on"
msgstr "Created on" msgstr "Created on"
@@ -1182,10 +1178,6 @@ msgstr "Current Password"
msgid "Current password is incorrect." msgid "Current password is incorrect."
msgstr "Current password is incorrect." msgstr "Current password is incorrect."
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:69
msgid "Current plan: {0}"
msgstr "Current plan: {0}"
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:28 #: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:28
msgid "Daily" msgid "Daily"
msgstr "Daily" msgstr "Daily"
@@ -1194,7 +1186,7 @@ msgstr "Daily"
msgid "Dark Mode" msgid "Dark Mode"
msgstr "Dark Mode" msgstr "Dark Mode"
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:70 #: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:68
#: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:148 #: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:148
msgid "Date" msgid "Date"
msgstr "Date" msgstr "Date"
@@ -1314,7 +1306,7 @@ msgstr "Deleting account..."
msgid "Details" msgid "Details"
msgstr "Details" msgstr "Details"
#: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:75 #: apps/web/src/app/(dashboard)/settings/security/activity/user-security-activity-data-table.tsx:73
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:242 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:242
msgid "Device" msgid "Device"
msgstr "Device" msgstr "Device"
@@ -1329,8 +1321,8 @@ msgstr "direct link"
msgid "Direct link" msgid "Direct link"
msgstr "Direct link" msgstr "Direct link"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:160 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:156
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:231 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:227
msgid "Direct Link" msgid "Direct Link"
msgstr "Direct Link" msgstr "Direct Link"
@@ -1434,11 +1426,11 @@ msgstr "Document Completed!"
msgid "Document created" msgid "Document created"
msgstr "Document created" msgstr "Document created"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:129 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:127
msgid "Document created by <0>{0}</0>" msgid "Document created by <0>{0}</0>"
msgstr "Document created by <0>{0}</0>" msgstr "Document created by <0>{0}</0>"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:134 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:132
msgid "Document created using a <0>direct link</0>" msgid "Document created using a <0>direct link</0>"
msgstr "Document created using a <0>direct link</0>" msgstr "Document created using a <0>direct link</0>"
@@ -1593,7 +1585,7 @@ msgstr "Download Audit Logs"
msgid "Download Certificate" msgid "Download Certificate"
msgstr "Download Certificate" msgstr "Download Certificate"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:214 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:210
#: apps/web/src/components/formatter/document-status.tsx:34 #: apps/web/src/components/formatter/document-status.tsx:34
msgid "Draft" msgid "Draft"
msgstr "Draft" msgstr "Draft"
@@ -1663,7 +1655,7 @@ msgstr "Electronic Signature Disclosure"
#: apps/web/src/components/(teams)/dialogs/update-team-email-dialog.tsx:153 #: apps/web/src/components/(teams)/dialogs/update-team-email-dialog.tsx:153
#: apps/web/src/components/forms/forgot-password.tsx:81 #: apps/web/src/components/forms/forgot-password.tsx:81
#: apps/web/src/components/forms/profile.tsx:122 #: apps/web/src/components/forms/profile.tsx:122
#: apps/web/src/components/forms/signin.tsx:338 #: apps/web/src/components/forms/signin.tsx:339
#: apps/web/src/components/forms/signup.tsx:176 #: apps/web/src/components/forms/signup.tsx:176
msgid "Email" msgid "Email"
msgstr "Email" msgstr "Email"
@@ -1773,12 +1765,12 @@ msgstr "Enter your text here"
#: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:217 #: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:217
#: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:256 #: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:256
#: apps/web/src/app/(dashboard)/templates/duplicate-template-dialog.tsx:51 #: 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/move-template-dialog.tsx:68
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:175 #: 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]/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:124
#: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:151 #: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:153
#: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:212 #: apps/web/src/app/(signing)/sign/[token]/checkbox-field.tsx:214
#: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:99 #: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:99
#: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:125 #: apps/web/src/app/(signing)/sign/[token]/date-field.tsx:125
#: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:105 #: apps/web/src/app/(signing)/sign/[token]/dropdown-field.tsx:105
@@ -1854,7 +1846,7 @@ msgid "For any questions regarding this disclosure, electronic signatures, or an
msgstr "For any questions regarding this disclosure, electronic signatures, or any related process, please contact us at: <0>{SUPPORT_EMAIL}</0>" msgstr "For any questions regarding this disclosure, electronic signatures, or any related process, please contact us at: <0>{SUPPORT_EMAIL}</0>"
#: apps/web/src/app/(unauthenticated)/forgot-password/page.tsx:21 #: apps/web/src/app/(unauthenticated)/forgot-password/page.tsx:21
#: apps/web/src/components/forms/signin.tsx:370 #: apps/web/src/components/forms/signin.tsx:371
msgid "Forgot your password?" msgid "Forgot your password?"
msgstr "Forgot your password?" msgstr "Forgot your password?"
@@ -2034,11 +2026,11 @@ msgstr "Invitation accepted!"
msgid "Invitation declined" msgid "Invitation declined"
msgstr "Invitation declined" msgstr "Invitation declined"
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:80 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:78
msgid "Invitation has been deleted" msgid "Invitation has been deleted"
msgstr "Invitation has been deleted" msgstr "Invitation has been deleted"
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:63 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:61
msgid "Invitation has been resent" msgid "Invitation has been resent"
msgstr "Invitation has been resent" msgstr "Invitation has been resent"
@@ -2058,7 +2050,7 @@ msgstr "Invite Members"
msgid "Invite team members" msgid "Invite team members"
msgstr "Invite team members" msgstr "Invite team members"
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:128 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:126
msgid "Invited At" msgid "Invited At"
msgstr "Invited At" msgstr "Invited At"
@@ -2128,7 +2120,7 @@ msgstr "Last Updated"
msgid "Last updated at" msgid "Last updated at"
msgstr "Last updated at" msgstr "Last updated at"
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:71 #: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:69
msgid "Last used" msgid "Last used"
msgstr "Last used" msgstr "Last used"
@@ -2137,7 +2129,7 @@ msgid "Leaderboard"
msgstr "Leaderboard" msgstr "Leaderboard"
#: apps/web/src/components/(teams)/dialogs/leave-team-dialog.tsx:111 #: apps/web/src/components/(teams)/dialogs/leave-team-dialog.tsx:111
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:117 #: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:115
msgid "Leave" msgid "Leave"
msgstr "Leave" msgstr "Leave"
@@ -2170,7 +2162,7 @@ msgstr "Links Generated"
msgid "Listening to {0}" msgid "Listening to {0}"
msgstr "Listening to {0}" msgstr "Listening to {0}"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:100 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:98
msgid "Load older activity" msgid "Load older activity"
msgstr "Load older activity" msgstr "Load older activity"
@@ -2185,11 +2177,11 @@ msgid "Loading Document..."
msgstr "Loading Document..." msgstr "Loading Document..."
#: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:92 #: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:92
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:91 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:103
msgid "Loading teams..." msgid "Loading teams..."
msgstr "Loading teams..." msgstr "Loading teams..."
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:100 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:98
msgid "Loading..." msgid "Loading..."
msgstr "Loading..." msgstr "Loading..."
@@ -2199,7 +2191,7 @@ msgstr "Loading..."
msgid "Login" msgid "Login"
msgstr "Login" msgstr "Login"
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:101 #: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:99
msgid "Manage" msgid "Manage"
msgstr "Manage" msgstr "Manage"
@@ -2247,7 +2239,7 @@ msgstr "Manage Subscription"
msgid "Manage subscriptions" msgid "Manage subscriptions"
msgstr "Manage subscriptions" msgstr "Manage subscriptions"
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:81 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:87
msgid "Manage team subscription." msgid "Manage team subscription."
msgstr "Manage team subscription." msgstr "Manage team subscription."
@@ -2287,8 +2279,8 @@ msgstr "MAU (created document)"
msgid "MAU (had document completed)" msgid "MAU (had document completed)"
msgstr "MAU (had document completed)" msgstr "MAU (had document completed)"
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:90 #: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:88
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:113 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:111
msgid "Member Since" msgid "Member Since"
msgstr "Member Since" msgstr "Member Since"
@@ -2304,6 +2296,7 @@ msgid "Modify recipients"
msgstr "Modify recipients" msgstr "Modify recipients"
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:30 #: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:30
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:54
msgid "Monthly" msgid "Monthly"
msgstr "Monthly" msgstr "Monthly"
@@ -2316,7 +2309,7 @@ msgid "Monthly Active Users: Users that had at least one of their documents comp
msgstr "Monthly Active Users: Users that had at least one of their documents completed" msgstr "Monthly Active Users: Users that had at least one of their documents completed"
#: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:123 #: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:123
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:122 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:134
msgid "Move" msgid "Move"
msgstr "Move" msgstr "Move"
@@ -2324,7 +2317,7 @@ msgstr "Move"
msgid "Move Document to Team" msgid "Move Document to Team"
msgstr "Move Document to Team" msgstr "Move Document to Team"
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:77 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:89
msgid "Move Template to Team" msgid "Move Template to Team"
msgstr "Move Template to Team" msgstr "Move Template to Team"
@@ -2334,7 +2327,7 @@ msgid "Move to Team"
msgstr "Move to Team" msgstr "Move to Team"
#: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:123 #: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:123
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:122 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:134
msgid "Moving..." msgid "Moving..."
msgstr "Moving..." msgstr "Moving..."
@@ -2347,7 +2340,7 @@ msgstr "My templates"
#: apps/web/src/app/(dashboard)/admin/users/[id]/page.tsx:99 #: apps/web/src/app/(dashboard)/admin/users/[id]/page.tsx:99
#: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:66 #: apps/web/src/app/(dashboard)/admin/users/data-table-users.tsx:66
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:144 #: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table-actions.tsx:144
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:61 #: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:59
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:287 #: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:287
#: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:294 #: apps/web/src/app/(dashboard)/templates/use-template-dialog.tsx:294
#: apps/web/src/app/(signing)/sign/[token]/complete/claim-account.tsx:118 #: apps/web/src/app/(signing)/sign/[token]/complete/claim-account.tsx:118
@@ -2362,7 +2355,7 @@ msgstr "Name"
msgid "Need to sign documents?" msgid "Need to sign documents?"
msgstr "Need to sign documents?" msgstr "Need to sign documents?"
#: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:76 #: apps/web/src/app/(dashboard)/settings/security/passkeys/user-passkeys-data-table.tsx:74
msgid "Never" msgid "Never"
msgstr "Never" msgstr "Never"
@@ -2397,7 +2390,7 @@ msgstr "No active drafts"
msgid "No further action is required from you at this time." msgid "No further action is required from you at this time."
msgstr "No further action is required from you at this time." msgstr "No further action is required from you at this time."
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:42 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:43
msgid "No payment required" msgid "No payment required"
msgstr "No payment required" msgstr "No payment required"
@@ -2405,11 +2398,11 @@ msgstr "No payment required"
msgid "No public profile templates found" msgid "No public profile templates found"
msgstr "No public profile templates found" msgstr "No public profile templates found"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:108 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:106
msgid "No recent activity" msgid "No recent activity"
msgstr "No recent activity" msgstr "No recent activity"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:103 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:101
msgid "No recent documents" msgid "No recent documents"
msgstr "No recent documents" msgstr "No recent documents"
@@ -2444,7 +2437,7 @@ msgstr "No value found."
msgid "No worries, it happens! Enter your email and we'll email you a special link to reset your password." msgid "No worries, it happens! Enter your email and we'll email you a special link to reset your password."
msgstr "No worries, it happens! Enter your email and we'll email you a special link to reset your password." msgstr "No worries, it happens! Enter your email and we'll email you a special link to reset your password."
#: apps/web/src/components/forms/signin.tsx:160 #: apps/web/src/components/forms/signin.tsx:161
msgid "Not supported" msgid "Not supported"
msgstr "Not supported" msgstr "Not supported"
@@ -2530,7 +2523,7 @@ msgstr "Opened"
msgid "Or" msgid "Or"
msgstr "Or" msgstr "Or"
#: apps/web/src/components/forms/signin.tsx:390 #: apps/web/src/components/forms/signin.tsx:391
msgid "Or continue with" msgid "Or continue with"
msgstr "Or continue with" msgstr "Or continue with"
@@ -2541,8 +2534,8 @@ msgstr "Otherwise, the document will be created as a draft."
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:86 #: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:86
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:103 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:103
#: apps/web/src/components/(dashboard)/layout/menu-switcher.tsx:81 #: apps/web/src/components/(dashboard)/layout/menu-switcher.tsx:81
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:86 #: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:84
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:109 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:107
msgid "Owner" msgid "Owner"
msgstr "Owner" msgstr "Owner"
@@ -2550,7 +2543,7 @@ msgstr "Owner"
msgid "Paid" msgid "Paid"
msgstr "Paid" msgstr "Paid"
#: apps/web/src/components/forms/signin.tsx:435 #: apps/web/src/components/forms/signin.tsx:436
msgid "Passkey" msgid "Passkey"
msgstr "Passkey" msgstr "Passkey"
@@ -2587,14 +2580,14 @@ msgstr "Passkeys"
msgid "Passkeys allow you to sign in and authenticate using biometrics, password managers, etc." msgid "Passkeys allow you to sign in and authenticate using biometrics, password managers, etc."
msgstr "Passkeys allow you to sign in and authenticate using biometrics, password managers, etc." msgstr "Passkeys allow you to sign in and authenticate using biometrics, password managers, etc."
#: apps/web/src/components/forms/signin.tsx:161 #: apps/web/src/components/forms/signin.tsx:162
msgid "Passkeys are not supported on this browser" msgid "Passkeys are not supported on this browser"
msgstr "Passkeys are not supported on this browser" msgstr "Passkeys are not supported on this browser"
#: apps/web/src/components/(dashboard)/common/command-menu.tsx:70 #: apps/web/src/components/(dashboard)/common/command-menu.tsx:70
#: apps/web/src/components/forms/password.tsx:128 #: apps/web/src/components/forms/password.tsx:128
#: apps/web/src/components/forms/reset-password.tsx:115 #: apps/web/src/components/forms/reset-password.tsx:115
#: apps/web/src/components/forms/signin.tsx:356 #: apps/web/src/components/forms/signin.tsx:357
#: apps/web/src/components/forms/signup.tsx:192 #: apps/web/src/components/forms/signup.tsx:192
#: apps/web/src/components/forms/v2/signup.tsx:347 #: apps/web/src/components/forms/v2/signup.tsx:347
msgid "Password" msgid "Password"
@@ -2624,7 +2617,7 @@ msgid "Payment overdue"
msgstr "Payment overdue" msgstr "Payment overdue"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recipients.tsx:131 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recipients.tsx:131
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:211 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:207
#: apps/web/src/components/(teams)/tables/teams-member-page-data-table.tsx:82 #: apps/web/src/components/(teams)/tables/teams-member-page-data-table.tsx:82
#: apps/web/src/components/(teams)/tables/user-settings-teams-page-data-table.tsx:77 #: apps/web/src/components/(teams)/tables/user-settings-teams-page-data-table.tsx:77
#: apps/web/src/components/document/document-read-only-fields.tsx:89 #: apps/web/src/components/document/document-read-only-fields.tsx:89
@@ -2741,7 +2734,7 @@ msgstr "Please review the document before signing."
msgid "Please try again and make sure you enter the correct email address." msgid "Please try again and make sure you enter the correct email address."
msgstr "Please try again and make sure you enter the correct email address." msgstr "Please try again and make sure you enter the correct email address."
#: apps/web/src/components/forms/signin.tsx:203 #: apps/web/src/components/forms/signin.tsx:204
msgid "Please try again later or login using your normal details" msgid "Please try again later or login using your normal details"
msgstr "Please try again later or login using your normal details" msgstr "Please try again later or login using your normal details"
@@ -2853,17 +2846,17 @@ msgstr "Reason must be less than 500 characters"
msgid "Reauthentication is required to sign this field" msgid "Reauthentication is required to sign this field"
msgstr "Reauthentication is required to sign this field" msgstr "Reauthentication is required to sign this field"
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:57 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:55
#: apps/web/src/app/(dashboard)/settings/security/page.tsx:130 #: apps/web/src/app/(dashboard)/settings/security/page.tsx:130
msgid "Recent activity" msgid "Recent activity"
msgstr "Recent activity" msgstr "Recent activity"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:47 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:45
msgid "Recent documents" msgid "Recent documents"
msgstr "Recent documents" msgstr "Recent documents"
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:69 #: apps/web/src/app/(dashboard)/documents/data-table.tsx:63
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:120 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:116
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:280 #: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:280
msgid "Recipient" msgid "Recipient"
msgstr "Recipient" msgstr "Recipient"
@@ -2924,8 +2917,8 @@ msgstr "Remembered your password? <0>Sign In</0>"
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-email-dropdown.tsx:89 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/team-email-dropdown.tsx:89
#: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:159 #: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:159
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:54 #: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:54
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:166 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:164
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:167 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:165
#: apps/web/src/components/forms/avatar-image.tsx:166 #: apps/web/src/components/forms/avatar-image.tsx:166
msgid "Remove" msgid "Remove"
msgstr "Remove" msgstr "Remove"
@@ -2934,10 +2927,14 @@ msgstr "Remove"
msgid "Remove team email" msgid "Remove team email"
msgstr "Remove team email" msgstr "Remove team email"
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:164 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:162
msgid "Remove team member" msgid "Remove team member"
msgstr "Remove team member" msgstr "Remove team member"
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:63
msgid "Renews: {formattedDate}"
msgstr "Renews: {formattedDate}"
#: apps/web/src/components/forms/password.tsx:144 #: apps/web/src/components/forms/password.tsx:144
#: apps/web/src/components/forms/reset-password.tsx:131 #: apps/web/src/components/forms/reset-password.tsx:131
msgid "Repeat Password" msgid "Repeat Password"
@@ -2952,7 +2949,7 @@ msgid "Reseal document"
msgstr "Reseal document" msgstr "Reseal document"
#: apps/web/src/app/(dashboard)/documents/_action-items/resend-document.tsx:118 #: apps/web/src/app/(dashboard)/documents/_action-items/resend-document.tsx:118
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:154 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:152
msgid "Resend" msgid "Resend"
msgstr "Resend" msgstr "Resend"
@@ -3030,9 +3027,9 @@ msgstr "Revoke access"
#: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:283 #: apps/web/src/app/(dashboard)/templates/template-direct-link-dialog.tsx:283
#: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:318 #: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:318
#: apps/web/src/components/(teams)/dialogs/update-team-member-dialog.tsx:163 #: apps/web/src/components/(teams)/dialogs/update-team-member-dialog.tsx:163
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:82 #: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:80
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:123 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:121
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:105 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:103
msgid "Role" msgid "Role"
msgstr "Role" msgstr "Role"
@@ -3089,7 +3086,7 @@ msgid "Select"
msgstr "Select" msgstr "Select"
#: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:87 #: apps/web/src/app/(dashboard)/documents/move-document-dialog.tsx:87
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:86 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:98
msgid "Select a team" msgid "Select a team"
msgstr "Select a team" msgstr "Select a team"
@@ -3097,7 +3094,7 @@ msgstr "Select a team"
msgid "Select a team to move this document to. This action cannot be undone." msgid "Select a team to move this document to. This action cannot be undone."
msgstr "Select a team to move this document to. This action cannot be undone." msgstr "Select a team to move this document to. This action cannot be undone."
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:80 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:92
msgid "Select a team to move this template to. This action cannot be undone." msgid "Select a team to move this template to. This action cannot be undone."
msgstr "Select a team to move this template to. This action cannot be undone." msgstr "Select a team to move this template to. This action cannot be undone."
@@ -3129,7 +3126,7 @@ msgstr "Send on Behalf of Team"
msgid "Send reminder" msgid "Send reminder"
msgstr "Send reminder" msgstr "Send reminder"
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:65 #: apps/web/src/app/(dashboard)/documents/data-table.tsx:59
msgid "Sender" msgid "Sender"
msgstr "Sender" msgstr "Sender"
@@ -3228,8 +3225,8 @@ msgid "Sign Here"
msgstr "Sign Here" msgstr "Sign Here"
#: apps/web/src/app/not-found.tsx:29 #: apps/web/src/app/not-found.tsx:29
#: apps/web/src/components/forms/signin.tsx:383 #: apps/web/src/components/forms/signin.tsx:384
#: apps/web/src/components/forms/signin.tsx:510 #: apps/web/src/components/forms/signin.tsx:511
msgid "Sign In" msgid "Sign In"
msgstr "Sign In" msgstr "Sign In"
@@ -3314,8 +3311,8 @@ msgstr "Signing Certificate"
msgid "Signing certificate provided by" msgid "Signing certificate provided by"
msgstr "Signing certificate provided by" msgstr "Signing certificate provided by"
#: apps/web/src/components/forms/signin.tsx:383 #: apps/web/src/components/forms/signin.tsx:384
#: apps/web/src/components/forms/signin.tsx:510 #: apps/web/src/components/forms/signin.tsx:511
msgid "Signing in..." msgid "Signing in..."
msgstr "Signing in..." msgstr "Signing in..."
@@ -3391,8 +3388,8 @@ msgstr "Site Settings"
#: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:64 #: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:64
#: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:83 #: apps/web/src/components/(teams)/dialogs/remove-team-email-dialog.tsx:83
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:33 #: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:33
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:68 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:66
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:85 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:83
#: apps/web/src/components/(teams)/team-billing-portal-button.tsx:29 #: apps/web/src/components/(teams)/team-billing-portal-button.tsx:29
msgid "Something went wrong" msgid "Something went wrong"
msgstr "Something went wrong" msgstr "Something went wrong"
@@ -3434,7 +3431,7 @@ msgstr "Sorry, we were unable to download the audit logs. Please try again later
msgid "Sorry, we were unable to download the certificate. Please try again later." msgid "Sorry, we were unable to download the certificate. Please try again later."
msgstr "Sorry, we were unable to download the certificate. Please try again later." msgstr "Sorry, we were unable to download the certificate. Please try again later."
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:138 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:134
msgid "Source" msgid "Source"
msgstr "Source" msgstr "Source"
@@ -3444,8 +3441,8 @@ msgstr "Stats"
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:81 #: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:81
#: apps/web/src/app/(dashboard)/admin/subscriptions/page.tsx:32 #: apps/web/src/app/(dashboard)/admin/subscriptions/page.tsx:32
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:79 #: apps/web/src/app/(dashboard)/documents/data-table.tsx:73
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:130 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:126
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:93 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/page.tsx:93
#: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:73 #: apps/web/src/components/(teams)/tables/team-billing-invoices-data-table.tsx:73
msgid "Status" msgid "Status"
@@ -3487,8 +3484,8 @@ msgstr "Subscriptions"
#: apps/web/src/components/(teams)/dialogs/update-team-member-dialog.tsx:92 #: apps/web/src/components/(teams)/dialogs/update-team-member-dialog.tsx:92
#: apps/web/src/components/(teams)/forms/update-team-form.tsx:67 #: apps/web/src/components/(teams)/forms/update-team-form.tsx:67
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:27 #: apps/web/src/components/(teams)/tables/pending-user-teams-data-table-actions.tsx:27
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:62 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:60
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:79 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:77
#: apps/web/src/components/forms/public-profile-form.tsx:80 #: apps/web/src/components/forms/public-profile-form.tsx:80
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:133 #: apps/web/src/components/templates/manage-public-template-dialog.tsx:133
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:170 #: apps/web/src/components/templates/manage-public-template-dialog.tsx:170
@@ -3507,8 +3504,8 @@ msgstr "System Requirements"
msgid "System Theme" msgid "System Theme"
msgstr "System Theme" msgstr "System Theme"
#: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:65 #: apps/web/src/components/(teams)/tables/current-user-teams-data-table.tsx:63
#: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:64 #: apps/web/src/components/(teams)/tables/pending-user-teams-data-table.tsx:62
msgid "Team" msgid "Team"
msgstr "Team" msgstr "Team"
@@ -3554,8 +3551,8 @@ msgstr "Team invitation"
msgid "Team invitations have been sent." msgid "Team invitations have been sent."
msgstr "Team invitations have been sent." msgstr "Team invitations have been sent."
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:109 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:107
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:86 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:84
msgid "Team Member" msgid "Team Member"
msgstr "Team Member" msgstr "Team Member"
@@ -3629,10 +3626,10 @@ msgstr "Teams"
msgid "Teams restricted" msgid "Teams restricted"
msgstr "Teams restricted" msgstr "Teams restricted"
#: apps/web/src/app/(dashboard)/templates/[id]/edit/template-edit-page-view.tsx:63 #: apps/web/src/app/(dashboard)/templates/[id]/edit/template-edit-page-view.tsx:64
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:39 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:39
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:148 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:144
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:228 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:224
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:148 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view.tsx:148
#: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:408 #: apps/web/src/components/(teams)/dialogs/invite-team-member-dialog.tsx:408
#: apps/web/src/components/templates/manage-public-template-dialog.tsx:271 #: apps/web/src/components/templates/manage-public-template-dialog.tsx:271
@@ -3659,10 +3656,14 @@ msgstr "Template has been removed from your public profile."
msgid "Template has been updated." msgid "Template has been updated."
msgstr "Template has been updated." msgstr "Template has been updated."
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:48 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:50
msgid "Template moved" msgid "Template moved"
msgstr "Template moved" msgstr "Template moved"
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:62
msgid "Template not found or already associated with a team."
msgstr "Template not found or already associated with a team."
#: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:246 #: apps/web/src/app/(dashboard)/templates/[id]/edit/edit-template.tsx:246
msgid "Template saved" msgid "Template saved"
msgstr "Template saved" msgstr "Template saved"
@@ -3790,7 +3791,7 @@ msgstr "The team transfer request to <0>{0}</0> has expired."
msgid "The team you are looking for may have been removed, renamed or may have never existed." msgid "The team you are looking for may have been removed, renamed or may have never existed."
msgstr "The team you are looking for may have been removed, renamed or may have never existed." msgstr "The team you are looking for may have been removed, renamed or may have never existed."
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:49 #: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:51
msgid "The template has been successfully moved to the selected team." msgid "The template has been successfully moved to the selected team."
msgstr "The template has been successfully moved to the selected team." msgstr "The template has been successfully moved to the selected team."
@@ -3879,11 +3880,11 @@ msgstr "This document has been signed by all recipients"
msgid "This document is currently a draft and has not been sent" msgid "This document is currently a draft and has not been sent"
msgstr "This document is currently a draft and has not been sent" msgstr "This document is currently a draft and has not been sent"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:152 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:148
msgid "This document was created by you or a team member using the template above." msgid "This document was created by you or a team member using the template above."
msgstr "This document was created by you or a team member using the template above." msgstr "This document was created by you or a team member using the template above."
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:164 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:160
msgid "This document was created using a direct link." msgid "This document was created using a direct link."
msgstr "This document was created using a direct link." msgstr "This document was created using a direct link."
@@ -3903,7 +3904,7 @@ msgstr "This link is invalid or has expired. Please contact your team to resend
msgid "This passkey has already been registered." msgid "This passkey has already been registered."
msgstr "This passkey has already been registered." msgstr "This passkey has already been registered."
#: apps/web/src/components/forms/signin.tsx:200 #: apps/web/src/components/forms/signin.tsx:201
msgid "This passkey is not configured for this application. Please login and add one in the user settings." msgid "This passkey is not configured for this application. Please login and add one in the user settings."
msgstr "This passkey is not configured for this application. Please login and add one in the user settings." msgstr "This passkey is not configured for this application. Please login and add one in the user settings."
@@ -3911,7 +3912,7 @@ msgstr "This passkey is not configured for this application. Please login and ad
msgid "This price includes minimum 5 seats." msgid "This price includes minimum 5 seats."
msgstr "This price includes minimum 5 seats." msgstr "This price includes minimum 5 seats."
#: apps/web/src/components/forms/signin.tsx:202 #: apps/web/src/components/forms/signin.tsx:203
msgid "This session has expired. Please try again." msgid "This session has expired. Please try again."
msgstr "This session has expired. Please try again." msgstr "This session has expired. Please try again."
@@ -3944,7 +3945,7 @@ msgstr "This username has already been taken"
msgid "This username is already taken" msgid "This username is already taken"
msgstr "This username is already taken" msgstr "This username is already taken"
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:73 #: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:71
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:44 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:44
msgid "Time" msgid "Time"
msgstr "Time" msgstr "Time"
@@ -3958,8 +3959,8 @@ msgid "Time Zone"
msgstr "Time Zone" msgstr "Time Zone"
#: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:67 #: apps/web/src/app/(dashboard)/admin/documents/document-results.tsx:67
#: apps/web/src/app/(dashboard)/documents/data-table.tsx:60 #: apps/web/src/app/(dashboard)/documents/data-table.tsx:54
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:115 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-documents-table.tsx:111
#: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:61 #: apps/web/src/app/(dashboard)/templates/data-table-templates.tsx:61
msgid "Title" msgid "Title"
msgstr "Title" msgstr "Title"
@@ -4093,7 +4094,7 @@ msgstr "Two factor authentication"
msgid "Two factor authentication recovery codes are used to access your account in the event that you lose access to your authenticator app." msgid "Two factor authentication recovery codes are used to access your account in the event that you lose access to your authenticator app."
msgstr "Two factor authentication recovery codes are used to access your account in the event that you lose access to your authenticator app." msgstr "Two factor authentication recovery codes are used to access your account in the event that you lose access to your authenticator app."
#: apps/web/src/components/forms/signin.tsx:448 #: apps/web/src/components/forms/signin.tsx:449
msgid "Two-Factor Authentication" msgid "Two-Factor Authentication"
msgstr "Two-Factor Authentication" msgstr "Two-Factor Authentication"
@@ -4150,7 +4151,7 @@ msgstr "Unable to create direct template access. Please try again later."
msgid "Unable to decline this team invitation at this time." msgid "Unable to decline this team invitation at this time."
msgstr "Unable to decline this team invitation at this time." msgstr "Unable to decline this team invitation at this time."
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:86 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:84
msgid "Unable to delete invitation. Please try again." msgid "Unable to delete invitation. Please try again."
msgstr "Unable to delete invitation. Please try again." msgstr "Unable to delete invitation. Please try again."
@@ -4166,12 +4167,12 @@ msgstr "Unable to disable two-factor authentication"
msgid "Unable to join this team at this time." msgid "Unable to join this team at this time."
msgstr "Unable to join this team at this time." msgstr "Unable to join this team at this time."
#: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:72 #: apps/web/src/app/(dashboard)/documents/[id]/document-page-view-recent-activity.tsx:70
#: apps/web/src/components/document/document-history-sheet.tsx:127 #: apps/web/src/components/document/document-history-sheet.tsx:127
msgid "Unable to load document history" msgid "Unable to load document history"
msgstr "Unable to load document history" msgstr "Unable to load document history"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:62 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:60
msgid "Unable to load documents" msgid "Unable to load documents"
msgstr "Unable to load documents" msgstr "Unable to load documents"
@@ -4187,7 +4188,7 @@ msgstr "Unable to remove email verification at this time. Please try again."
msgid "Unable to remove team email at this time. Please try again." msgid "Unable to remove team email at this time. Please try again."
msgstr "Unable to remove team email at this time. Please try again." msgstr "Unable to remove team email at this time. Please try again."
#: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:69 #: apps/web/src/components/(teams)/tables/team-member-invites-data-table.tsx:67
msgid "Unable to resend invitation. Please try again." msgid "Unable to resend invitation. Please try again."
msgstr "Unable to resend invitation. Please try again." msgstr "Unable to resend invitation. Please try again."
@@ -4204,8 +4205,8 @@ msgstr "Unable to reset password"
msgid "Unable to setup two-factor authentication" msgid "Unable to setup two-factor authentication"
msgstr "Unable to setup two-factor authentication" msgstr "Unable to setup two-factor authentication"
#: apps/web/src/components/forms/signin.tsx:247 #: apps/web/src/components/forms/signin.tsx:248
#: apps/web/src/components/forms/signin.tsx:255 #: apps/web/src/components/forms/signin.tsx:256
msgid "Unable to sign in" msgid "Unable to sign in"
msgstr "Unable to sign in" msgstr "Unable to sign in"
@@ -4222,6 +4223,7 @@ msgstr "Uncompleted"
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:262 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:262
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:273 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:273
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:284 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/certificate/page.tsx:284
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:55
msgid "Unknown" msgid "Unknown"
msgstr "Unknown" msgstr "Unknown"
@@ -4262,7 +4264,7 @@ msgstr "Update profile"
msgid "Update Recipient" msgid "Update Recipient"
msgstr "Update Recipient" msgstr "Update Recipient"
#: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:146 #: apps/web/src/components/(teams)/tables/team-members-data-table.tsx:144
msgid "Update role" msgid "Update role"
msgstr "Update role" msgstr "Update role"
@@ -4331,12 +4333,12 @@ msgid "Use"
msgstr "Use" msgstr "Use"
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:187 #: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:187
#: apps/web/src/components/forms/signin.tsx:505 #: apps/web/src/components/forms/signin.tsx:506
msgid "Use Authenticator" msgid "Use Authenticator"
msgstr "Use Authenticator" msgstr "Use Authenticator"
#: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:185 #: apps/web/src/components/forms/2fa/disable-authenticator-app-dialog.tsx:185
#: apps/web/src/components/forms/signin.tsx:503 #: apps/web/src/components/forms/signin.tsx:504
msgid "Use Backup Code" msgid "Use Backup Code"
msgstr "Use Backup Code" msgstr "Use Backup Code"
@@ -4344,7 +4346,7 @@ msgstr "Use Backup Code"
msgid "Use Template" msgid "Use Template"
msgstr "Use Template" msgstr "Use Template"
#: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:78 #: apps/web/src/app/(dashboard)/documents/[id]/logs/document-logs-data-table.tsx:76
#: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:45 #: apps/web/src/app/(internal)/%5F%5Fhtmltopdf/audit-log/data-table.tsx:45
msgid "User" msgid "User"
msgstr "User" msgstr "User"
@@ -4430,7 +4432,7 @@ msgstr "View all documents sent to your account"
msgid "View all recent security activity related to your account." msgid "View all recent security activity related to your account."
msgstr "View all recent security activity related to your account." msgstr "View all recent security activity related to your account."
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:157 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:155
msgid "View all related documents" msgid "View all related documents"
msgstr "View all related documents" msgstr "View all related documents"
@@ -4454,7 +4456,7 @@ msgstr "View documents associated with this email"
msgid "View invites" msgid "View invites"
msgstr "View invites" msgstr "View invites"
#: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:95 #: apps/web/src/app/(dashboard)/templates/[id]/template-page-view-recent-activity.tsx:93
msgid "View more" msgid "View more"
msgstr "View more" msgstr "View more"
@@ -4589,9 +4591,9 @@ msgid "We encountered an unknown error while attempting to save your details. Pl
msgstr "We encountered an unknown error while attempting to save your details. Please try again later." msgstr "We encountered an unknown error while attempting to save your details. Please try again later."
#: apps/web/src/components/forms/profile.tsx:89 #: apps/web/src/components/forms/profile.tsx:89
#: apps/web/src/components/forms/signin.tsx:272 #: apps/web/src/components/forms/signin.tsx:273
#: apps/web/src/components/forms/signin.tsx:287 #: apps/web/src/components/forms/signin.tsx:288
#: apps/web/src/components/forms/signin.tsx:303 #: apps/web/src/components/forms/signin.tsx:304
msgid "We encountered an unknown error while attempting to sign you In. Please try again later." msgid "We encountered an unknown error while attempting to sign you In. Please try again later."
msgstr "We encountered an unknown error while attempting to sign you In. Please try again later." msgstr "We encountered an unknown error while attempting to sign you In. Please try again later."
@@ -4792,6 +4794,7 @@ msgid "Write about yourself"
msgstr "Write about yourself" msgstr "Write about yourself"
#: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:31 #: apps/web/src/app/(dashboard)/settings/billing/billing-plans.tsx:31
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:53
msgid "Yearly" msgid "Yearly"
msgstr "Yearly" msgstr "Yearly"
@@ -4836,6 +4839,10 @@ msgstr "You are currently updating <0>{teamMemberName}.</0>"
msgid "You are currently updating the <0>{passkeyName}</0> passkey." msgid "You are currently updating the <0>{passkeyName}</0> passkey."
msgstr "You are currently updating the <0>{passkeyName}</0> passkey." msgstr "You are currently updating the <0>{passkeyName}</0> passkey."
#: apps/web/src/app/(dashboard)/templates/move-template-dialog.tsx:64
msgid "You are not a member of this team."
msgstr "You are not a member of this team."
#: apps/web/src/app/(teams)/t/[teamUrl]/error.tsx:28 #: apps/web/src/app/(teams)/t/[teamUrl]/error.tsx:28
msgid "You are not authorized to view this page." msgid "You are not authorized to view this page."
msgstr "You are not authorized to view this page." msgstr "You are not authorized to view this page."
@@ -4960,7 +4967,7 @@ msgstr "You have updated {teamMemberName}."
msgid "You have verified your email address for <0>{0}</0>." msgid "You have verified your email address for <0>{0}</0>."
msgstr "You have verified your email address for <0>{0}</0>." msgstr "You have verified your email address for <0>{0}</0>."
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:82 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:88
msgid "You must be an admin of this team to manage billing." msgid "You must be an admin of this team to manage billing."
msgstr "You must be an admin of this team to manage billing." msgstr "You must be an admin of this team to manage billing."
@@ -5114,7 +5121,7 @@ msgstr "Your recovery code has been copied to your clipboard."
msgid "Your recovery codes are listed below. Please store them in a safe place." msgid "Your recovery codes are listed below. Please store them in a safe place."
msgstr "Your recovery codes are listed below. Please store them in a safe place." msgstr "Your recovery codes are listed below. Please store them in a safe place."
#: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:62 #: apps/web/src/app/(teams)/t/[teamUrl]/settings/billing/page.tsx:72
msgid "Your subscription is currently active." msgid "Your subscription is currently active."
msgstr "Your subscription is currently active." msgstr "Your subscription is currently active."

View File

@@ -30,11 +30,11 @@ msgstr "“{documentName}” ha sido firmado"
msgid "“{documentName}” was signed by all signers" msgid "“{documentName}” was signed by all signers"
msgstr "\"{documentName}\" fue firmado por todos los firmantes" msgstr "\"{documentName}\" fue firmado por todos los firmantes"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:137 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:125
msgid "{0} has invited you to {recipientActionVerb} the document \"{1}\"." msgid "{0} has invited you to {recipientActionVerb} the document \"{1}\"."
msgstr "{0} te ha invitado a {recipientActionVerb} el documento \"{1}\"." msgstr "{0} te ha invitado a {recipientActionVerb} el documento \"{1}\"."
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:130 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:118
msgid "{0} invited you to {recipientActionVerb} a document" msgid "{0} invited you to {recipientActionVerb} a document"
msgstr "{0} te invitó a {recipientActionVerb} un documento" msgstr "{0} te invitó a {recipientActionVerb} un documento"
@@ -50,7 +50,7 @@ msgstr "{0} dejó el equipo {teamName} en Documenso"
msgid "{0} of {1} row(s) selected." msgid "{0} of {1} row(s) selected."
msgstr "{0} de {1} fila(s) seleccionada." msgstr "{0} de {1} fila(s) seleccionada."
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:136 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:124
#: packages/lib/server-only/document/resend-document.tsx:137 #: packages/lib/server-only/document/resend-document.tsx:137
msgid "{0} on behalf of \"{1}\" has invited you to {recipientActionVerb} the document \"{2}\"." msgid "{0} on behalf of \"{1}\" has invited you to {recipientActionVerb} the document \"{2}\"."
msgstr "" msgstr ""
@@ -195,6 +195,22 @@ msgstr "{recipientName} {action} un documento utilizando uno de tus enlaces dire
msgid "{recipientName} has rejected the document '{documentName}'" msgid "{recipientName} has rejected the document '{documentName}'"
msgstr "{recipientName} ha rechazado el documento '{documentName}'" msgstr "{recipientName} ha rechazado el documento '{documentName}'"
#: packages/email/template-components/template-document-recipient-signed.tsx:49
msgid "{recipientReference} has completed signing the document."
msgstr ""
#: packages/lib/jobs/definitions/emails/send-recipient-signed-email.ts:121
msgid "{recipientReference} has signed \"{0}\""
msgstr ""
#: packages/email/template-components/template-document-recipient-signed.tsx:43
msgid "{recipientReference} has signed \"{documentName}\""
msgstr ""
#: packages/email/templates/document-recipient-signed.tsx:27
msgid "{recipientReference} has signed {documentName}"
msgstr ""
#: packages/email/template-components/template-document-rejected.tsx:25 #: packages/email/template-components/template-document-rejected.tsx:25
msgid "{signerName} has rejected the document \"{documentName}\"." msgid "{signerName} has rejected the document \"{documentName}\"."
msgstr "{signerName} ha rechazado el documento \"{documentName}\"." msgstr "{signerName} ha rechazado el documento \"{documentName}\"."
@@ -289,7 +305,7 @@ msgstr "<0>Requerir cuenta</0> - El destinatario debe haber iniciado sesión par
msgid "<0>Require passkey</0> - The recipient must have an account and passkey configured via their settings" msgid "<0>Require passkey</0> - The recipient must have an account and passkey configured via their settings"
msgstr "<0>Requerir clave de acceso</0> - El destinatario debe tener una cuenta y clave de acceso configurada a través de sus configuraciones" msgstr "<0>Requerir clave de acceso</0> - El destinatario debe tener una cuenta y clave de acceso configurada a través de sus configuraciones"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:122 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:110
msgid "A document was created by your direct template that requires you to {recipientActionVerb} it." msgid "A document was created by your direct template that requires you to {recipientActionVerb} it."
msgstr "Se creó un documento a partir de tu plantilla directa que requiere que {recipientActionVerb}." msgstr "Se creó un documento a partir de tu plantilla directa que requiere que {recipientActionVerb}."
@@ -305,7 +321,7 @@ msgstr "Se eliminó un campo"
msgid "A field was updated" msgid "A field was updated"
msgstr "Se actualizó un campo" msgstr "Se actualizó un campo"
#: packages/lib/jobs/definitions/emails/send-team-member-joined-email.ts:107 #: packages/lib/jobs/definitions/emails/send-team-member-joined-email.handler.ts:98
msgid "A new member has joined your team" msgid "A new member has joined your team"
msgstr "Un nuevo miembro se ha unido a tu equipo" msgstr "Un nuevo miembro se ha unido a tu equipo"
@@ -329,7 +345,7 @@ msgstr "Se ha iniciado una solicitud para usar tu correo electrónico por {0} en
msgid "A team member has joined a team on Documenso" msgid "A team member has joined a team on Documenso"
msgstr "Un miembro del equipo se ha unido a un equipo en Documenso" msgstr "Un miembro del equipo se ha unido a un equipo en Documenso"
#: packages/lib/jobs/definitions/emails/send-team-member-left-email.ts:96 #: packages/lib/jobs/definitions/emails/send-team-member-left-email.handler.ts:87
msgid "A team member has left {0}" msgid "A team member has left {0}"
msgstr "Un miembro del equipo ha dejado {0}" msgstr "Un miembro del equipo ha dejado {0}"
@@ -364,12 +380,12 @@ msgstr "Aceptar solicitud de transferencia de equipo en Documenso"
msgid "Add a document" msgid "Add a document"
msgstr "Agregar un documento" msgstr "Agregar un documento"
#: packages/ui/primitives/document-flow/add-settings.tsx:378 #: packages/ui/primitives/document-flow/add-settings.tsx:390
#: packages/ui/primitives/template-flow/add-template-settings.tsx:468 #: packages/ui/primitives/template-flow/add-template-settings.tsx:468
msgid "Add a URL to redirect the user to once the document is signed" msgid "Add a URL to redirect the user to once the document is signed"
msgstr "Agregue una URL para redirigir al usuario una vez que se firme el documento" msgstr "Agregue una URL para redirigir al usuario una vez que se firme el documento"
#: packages/ui/primitives/document-flow/add-settings.tsx:290 #: packages/ui/primitives/document-flow/add-settings.tsx:302
msgid "Add an external ID to the document. This can be used to identify the document in external systems." msgid "Add an external ID to the document. This can be used to identify the document in external systems."
msgstr "Agregue un ID externo al documento. Esto se puede usar para identificar el documento en sistemas externos." msgstr "Agregue un ID externo al documento. Esto se puede usar para identificar el documento en sistemas externos."
@@ -414,13 +430,13 @@ msgstr "Agregar texto al campo"
msgid "Admin" msgid "Admin"
msgstr "Admin" msgstr "Admin"
#: packages/ui/primitives/document-flow/add-settings.tsx:272 #: packages/ui/primitives/document-flow/add-settings.tsx:284
#: packages/ui/primitives/template-flow/add-template-settings.tsx:367 #: packages/ui/primitives/template-flow/add-template-settings.tsx:367
msgid "Advanced Options" msgid "Advanced Options"
msgstr "Opciones avanzadas" msgstr "Opciones avanzadas"
#: packages/ui/primitives/document-flow/add-fields.tsx:576 #: packages/ui/primitives/document-flow/add-fields.tsx:577
#: packages/ui/primitives/template-flow/add-template-fields.tsx:414 #: packages/ui/primitives/template-flow/add-template-fields.tsx:415
msgid "Advanced settings" msgid "Advanced settings"
msgstr "Configuraciones avanzadas" msgstr "Configuraciones avanzadas"
@@ -472,11 +488,11 @@ msgstr "Aprobando"
msgid "Before you get started, please confirm your email address by clicking the button below:" 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:" 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:524 #: packages/ui/primitives/signature-pad/signature-pad.tsx:531
msgid "Black" msgid "Black"
msgstr "Negro" msgstr "Negro"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:538 #: packages/ui/primitives/signature-pad/signature-pad.tsx:545
msgid "Blue" msgid "Blue"
msgstr "Azul" msgstr "Azul"
@@ -492,7 +508,7 @@ msgstr "Al aceptar esta solicitud, estarás concediendo a <0>{teamName}</0> acce
msgid "By accepting this request, you will take responsibility for any billing items associated with this team." msgid "By accepting this request, you will take responsibility for any billing items associated with this team."
msgstr "Al aceptar esta solicitud, asumirás la responsabilidad de cualquier ítem de facturación asociado con este equipo." msgstr "Al aceptar esta solicitud, asumirás la responsabilidad de cualquier ítem de facturación asociado con este equipo."
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:356 #: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:357
#: packages/ui/primitives/document-flow/send-document-action-dialog.tsx:58 #: packages/ui/primitives/document-flow/send-document-action-dialog.tsx:58
msgid "Cancel" msgid "Cancel"
msgstr "Cancelar" msgstr "Cancelar"
@@ -534,7 +550,7 @@ msgstr "Valores de Checkbox"
msgid "Clear filters" msgid "Clear filters"
msgstr "Limpiar filtros" msgstr "Limpiar filtros"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:558 #: packages/ui/primitives/signature-pad/signature-pad.tsx:565
msgid "Clear Signature" msgid "Clear Signature"
msgstr "Limpiar firma" msgstr "Limpiar firma"
@@ -547,6 +563,7 @@ msgid "Close"
msgstr "Cerrar" msgstr "Cerrar"
#: packages/email/template-components/template-document-completed.tsx:35 #: packages/email/template-components/template-document-completed.tsx:35
#: packages/email/template-components/template-document-recipient-signed.tsx:37
#: packages/email/template-components/template-document-self-signed.tsx:36 #: packages/email/template-components/template-document-self-signed.tsx:36
#: packages/lib/constants/document.ts:10 #: packages/lib/constants/document.ts:10
msgid "Completed" msgid "Completed"
@@ -561,8 +578,8 @@ msgstr "Documento completado"
msgid "Configure Direct Recipient" msgid "Configure Direct Recipient"
msgstr "Configurar destinatario directo" msgstr "Configurar destinatario directo"
#: packages/ui/primitives/document-flow/add-fields.tsx:577 #: packages/ui/primitives/document-flow/add-fields.tsx:578
#: packages/ui/primitives/template-flow/add-template-fields.tsx:415 #: packages/ui/primitives/template-flow/add-template-fields.tsx:416
msgid "Configure the {0} field" msgid "Configure the {0} field"
msgstr "Configurar el campo {0}" msgstr "Configurar el campo {0}"
@@ -619,13 +636,13 @@ msgstr "Crear cuenta"
msgid "Custom Text" msgid "Custom Text"
msgstr "Texto personalizado" msgstr "Texto personalizado"
#: packages/ui/primitives/document-flow/add-fields.tsx:934 #: packages/ui/primitives/document-flow/add-fields.tsx:938
#: packages/ui/primitives/document-flow/types.ts:53 #: 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:733
msgid "Date" msgid "Date"
msgstr "Fecha" msgstr "Fecha"
#: packages/ui/primitives/document-flow/add-settings.tsx:313 #: packages/ui/primitives/document-flow/add-settings.tsx:325
#: packages/ui/primitives/template-flow/add-template-settings.tsx:408 #: packages/ui/primitives/template-flow/add-template-settings.tsx:408
msgid "Date Format" msgid "Date Format"
msgstr "Formato de fecha" msgstr "Formato de fecha"
@@ -642,16 +659,16 @@ msgstr "¿No solicitaste un cambio de contraseña? Estamos aquí para ayudarte a
msgid "Direct link receiver" msgid "Direct link receiver"
msgstr "Receptor de enlace directo" msgstr "Receptor de enlace directo"
#: packages/lib/jobs/definitions/emails/send-rejection-emails.ts:149 #: packages/lib/jobs/definitions/emails/send-rejection-emails.handler.ts:140
msgid "Document \"{0}\" - Rejected by {1}" msgid "Document \"{0}\" - Rejected by {1}"
msgstr "Documento \"{0}\" - Rechazado por {1}" msgstr "Documento \"{0}\" - Rechazado por {1}"
#: packages/lib/jobs/definitions/emails/send-rejection-emails.ts:109 #: packages/lib/jobs/definitions/emails/send-rejection-emails.handler.ts:100
msgid "Document \"{0}\" - Rejection Confirmed" msgid "Document \"{0}\" - Rejection Confirmed"
msgstr "Documento \"{0}\" - Rechazo confirmado" msgstr "Documento \"{0}\" - Rechazo confirmado"
#: packages/ui/components/document/document-global-auth-access-select.tsx:62 #: packages/ui/components/document/document-global-auth-access-select.tsx:62
#: packages/ui/primitives/document-flow/add-settings.tsx:216 #: packages/ui/primitives/document-flow/add-settings.tsx:227
#: packages/ui/primitives/template-flow/add-template-settings.tsx:202 #: packages/ui/primitives/template-flow/add-template-settings.tsx:202
msgid "Document access" msgid "Document access"
msgstr "Acceso al documento" msgstr "Acceso al documento"
@@ -670,7 +687,8 @@ msgstr "Documento cancelado"
msgid "Document completed" msgid "Document completed"
msgstr "Documento completado" msgstr "Documento completado"
#: packages/ui/components/document/document-email-checkboxes.tsx:168 #: packages/ui/components/document/document-email-checkboxes.tsx:208
#: packages/ui/components/document/document-email-checkboxes.tsx:286
msgid "Document completed email" msgid "Document completed email"
msgstr "Correo electrónico de documento completado" msgstr "Correo electrónico de documento completado"
@@ -679,7 +697,7 @@ msgid "Document created"
msgstr "Documento creado" msgstr "Documento creado"
#: packages/email/templates/document-created-from-direct-template.tsx:32 #: packages/email/templates/document-created-from-direct-template.tsx:32
#: packages/lib/server-only/template/create-document-from-direct-template.ts:574 #: packages/lib/server-only/template/create-document-from-direct-template.ts:585
msgid "Document created from direct template" msgid "Document created from direct template"
msgstr "Documento creado a partir de plantilla directa" msgstr "Documento creado a partir de plantilla directa"
@@ -691,7 +709,7 @@ msgstr "Creación de documento"
msgid "Document deleted" msgid "Document deleted"
msgstr "Documento eliminado" msgstr "Documento eliminado"
#: packages/ui/components/document/document-email-checkboxes.tsx:207 #: packages/ui/components/document/document-email-checkboxes.tsx:247
msgid "Document deleted email" msgid "Document deleted email"
msgstr "Correo electrónico de documento eliminado" msgstr "Correo electrónico de documento eliminado"
@@ -716,7 +734,7 @@ msgstr "Documento movido al equipo"
msgid "Document opened" msgid "Document opened"
msgstr "Documento abierto" msgstr "Documento abierto"
#: packages/ui/components/document/document-email-checkboxes.tsx:128 #: packages/ui/components/document/document-email-checkboxes.tsx:168
msgid "Document pending email" msgid "Document pending email"
msgstr "Correo electrónico de documento pendiente" msgstr "Correo electrónico de documento pendiente"
@@ -757,8 +775,8 @@ msgstr "Borrador"
msgid "Drag & drop your PDF here." msgid "Drag & drop your PDF here."
msgstr "Arrastre y suelte su PDF aquí." msgstr "Arrastre y suelte su PDF aquí."
#: packages/ui/primitives/document-flow/add-fields.tsx:1065 #: packages/ui/primitives/document-flow/add-fields.tsx:1069
#: packages/ui/primitives/template-flow/add-template-fields.tsx:860 #: packages/ui/primitives/template-flow/add-template-fields.tsx:864
msgid "Dropdown" msgid "Dropdown"
msgstr "Menú desplegable" msgstr "Menú desplegable"
@@ -767,12 +785,12 @@ msgid "Dropdown options"
msgstr "Opciones de menú desplegable" msgstr "Opciones de menú desplegable"
#: packages/lib/constants/document.ts:28 #: packages/lib/constants/document.ts:28
#: packages/ui/primitives/document-flow/add-fields.tsx:882 #: packages/ui/primitives/document-flow/add-fields.tsx:886
#: packages/ui/primitives/document-flow/add-signature.tsx:273 #: packages/ui/primitives/document-flow/add-signature.tsx:273
#: packages/ui/primitives/document-flow/add-signers.tsx:512 #: packages/ui/primitives/document-flow/add-signers.tsx:512
#: packages/ui/primitives/document-flow/add-signers.tsx:519 #: packages/ui/primitives/document-flow/add-signers.tsx:519
#: packages/ui/primitives/document-flow/types.ts:54 #: 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-fields.tsx:681
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:471 #: 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-placeholder-recipients.tsx:478
msgid "Email" msgid "Email"
@@ -794,7 +812,7 @@ msgstr "Correo electrónico reeenviado"
msgid "Email sent" msgid "Email sent"
msgstr "Correo electrónico enviado" msgstr "Correo electrónico enviado"
#: packages/ui/primitives/document-flow/add-fields.tsx:1130 #: packages/ui/primitives/document-flow/add-fields.tsx:1134
msgid "Empty field" msgid "Empty field"
msgstr "Campo vacío" msgstr "Campo vacío"
@@ -807,8 +825,8 @@ msgstr "Habilitar firma de enlace directo"
msgid "Enable signing order" msgid "Enable signing order"
msgstr "Habilitar orden de firma" msgstr "Habilitar orden de firma"
#: packages/ui/primitives/document-flow/add-fields.tsx:802 #: packages/ui/primitives/document-flow/add-fields.tsx:806
#: packages/ui/primitives/template-flow/add-template-fields.tsx:597 #: packages/ui/primitives/template-flow/add-template-fields.tsx:601
msgid "Enable Typed Signatures" msgid "Enable Typed Signatures"
msgstr "Habilitar firmas escritas" msgstr "Habilitar firmas escritas"
@@ -816,17 +834,17 @@ msgstr "Habilitar firmas escritas"
msgid "Enter password" msgid "Enter password"
msgstr "Ingrese la contraseña" msgstr "Ingrese la contraseña"
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:257 #: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:258
#: packages/ui/primitives/pdf-viewer.tsx:166 #: packages/ui/primitives/pdf-viewer.tsx:166
msgid "Error" msgid "Error"
msgstr "Error" msgstr "Error"
#: packages/ui/primitives/document-flow/add-settings.tsx:283 #: packages/ui/primitives/document-flow/add-settings.tsx:295
#: packages/ui/primitives/template-flow/add-template-settings.tsx:378 #: packages/ui/primitives/template-flow/add-template-settings.tsx:378
msgid "External ID" msgid "External ID"
msgstr "ID externo" msgstr "ID externo"
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:258 #: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:259
msgid "Failed to save settings." msgid "Failed to save settings."
msgstr "Fallo al guardar configuraciones." msgstr "Fallo al guardar configuraciones."
@@ -896,7 +914,7 @@ msgstr "Autenticación de acción de destinatario global"
msgid "Go Back" msgid "Go Back"
msgstr "Regresar" msgstr "Regresar"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:545 #: packages/ui/primitives/signature-pad/signature-pad.tsx:552
msgid "Green" msgid "Green"
msgstr "Verde" msgstr "Verde"
@@ -947,7 +965,7 @@ msgstr "Únete a {teamName} en Documenso"
msgid "Label" msgid "Label"
msgstr "Etiqueta" msgstr "Etiqueta"
#: packages/ui/primitives/document-flow/add-settings.tsx:176 #: packages/ui/primitives/document-flow/add-settings.tsx:187
#: packages/ui/primitives/template-flow/add-template-settings.tsx:162 #: packages/ui/primitives/template-flow/add-template-settings.tsx:162
msgid "Language" msgid "Language"
msgstr "Idioma" msgstr "Idioma"
@@ -983,12 +1001,12 @@ msgstr "Mensaje <0>(Opcional)</0>"
msgid "Min" msgid "Min"
msgstr "Mín" msgstr "Mín"
#: packages/ui/primitives/document-flow/add-fields.tsx:908 #: packages/ui/primitives/document-flow/add-fields.tsx:912
#: packages/ui/primitives/document-flow/add-signature.tsx:299 #: packages/ui/primitives/document-flow/add-signature.tsx:299
#: packages/ui/primitives/document-flow/add-signers.tsx:550 #: packages/ui/primitives/document-flow/add-signers.tsx:550
#: packages/ui/primitives/document-flow/add-signers.tsx:556 #: packages/ui/primitives/document-flow/add-signers.tsx:556
#: packages/ui/primitives/document-flow/types.ts:55 #: 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-fields.tsx:707
#: packages/ui/primitives/template-flow/add-template-placeholder-recipients.tsx:506 #: 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-placeholder-recipients.tsx:512
msgid "Name" msgid "Name"
@@ -1006,8 +1024,8 @@ msgstr "Necesita firmar"
msgid "Needs to view" msgid "Needs to view"
msgstr "Necesita ver" msgstr "Necesita ver"
#: packages/ui/primitives/document-flow/add-fields.tsx:693 #: packages/ui/primitives/document-flow/add-fields.tsx:697
#: packages/ui/primitives/template-flow/add-template-fields.tsx:516 #: packages/ui/primitives/template-flow/add-template-fields.tsx:520
msgid "No recipient matching this description was found." msgid "No recipient matching this description was found."
msgstr "No se encontró ningún destinatario que coincidiera con esta descripción." msgstr "No se encontró ningún destinatario que coincidiera con esta descripción."
@@ -1015,8 +1033,8 @@ msgstr "No se encontró ningún destinatario que coincidiera con esta descripci
msgid "No recipients" msgid "No recipients"
msgstr "Sin destinatarios" msgstr "Sin destinatarios"
#: packages/ui/primitives/document-flow/add-fields.tsx:708 #: packages/ui/primitives/document-flow/add-fields.tsx:712
#: packages/ui/primitives/template-flow/add-template-fields.tsx:531 #: packages/ui/primitives/template-flow/add-template-fields.tsx:535
msgid "No recipients with this role" msgid "No recipients with this role"
msgstr "No hay destinatarios con este rol" msgstr "No hay destinatarios con este rol"
@@ -1044,9 +1062,9 @@ msgstr "No se encontró valor."
msgid "None" msgid "None"
msgstr "Ninguno" msgstr "Ninguno"
#: packages/ui/primitives/document-flow/add-fields.tsx:986 #: packages/ui/primitives/document-flow/add-fields.tsx:990
#: packages/ui/primitives/document-flow/types.ts:56 #: 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:785
msgid "Number" msgid "Number"
msgstr "Número" msgstr "Número"
@@ -1112,15 +1130,15 @@ msgstr "Por favor {0} tu documento<0/>\"{documentName}\""
msgid "Please {action} your document {documentName}" msgid "Please {action} your document {documentName}"
msgstr "Por favor {action} tu documento {documentName}" msgstr "Por favor {action} tu documento {documentName}"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:111 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:99
msgid "Please {recipientActionVerb} this document" msgid "Please {recipientActionVerb} this document"
msgstr "Por favor {recipientActionVerb} este documento" msgstr "Por favor {recipientActionVerb} este documento"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:125 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:113
msgid "Please {recipientActionVerb} this document created by your direct template" msgid "Please {recipientActionVerb} this document created by your direct template"
msgstr "Por favor {recipientActionVerb} este documento creado a partir de tu plantilla directa" msgstr "Por favor {recipientActionVerb} este documento creado a partir de tu plantilla directa"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:117 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:105
msgid "Please {recipientActionVerb} your document" msgid "Please {recipientActionVerb} your document"
msgstr "Por favor {recipientActionVerb} tu documento" msgstr "Por favor {recipientActionVerb} tu documento"
@@ -1167,24 +1185,28 @@ msgid "Recipient"
msgstr "Destinatario" msgstr "Destinatario"
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:39 #: packages/ui/components/recipient/recipient-action-auth-select.tsx:39
#: packages/ui/primitives/document-flow/add-settings.tsx:257 #: packages/ui/primitives/document-flow/add-settings.tsx:269
#: packages/ui/primitives/template-flow/add-template-settings.tsx:291 #: packages/ui/primitives/template-flow/add-template-settings.tsx:291
msgid "Recipient action authentication" msgid "Recipient action authentication"
msgstr "Autenticación de acción de destinatario" msgstr "Autenticación de acción de destinatario"
#: packages/ui/components/document/document-email-checkboxes.tsx:89 #: packages/ui/components/document/document-email-checkboxes.tsx:129
msgid "Recipient removed email" msgid "Recipient removed email"
msgstr "Correo electrónico de destinatario eliminado" msgstr "Correo electrónico de destinatario eliminado"
#: packages/ui/components/document/document-email-checkboxes.tsx:50 #: packages/ui/components/document/document-email-checkboxes.tsx:51
msgid "Recipient signed email"
msgstr ""
#: packages/ui/components/document/document-email-checkboxes.tsx:90
msgid "Recipient signing request email" msgid "Recipient signing request email"
msgstr "Correo electrónico de solicitud de firma de destinatario" msgstr "Correo electrónico de solicitud de firma de destinatario"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:531 #: packages/ui/primitives/signature-pad/signature-pad.tsx:538
msgid "Red" msgid "Red"
msgstr "Rojo" msgstr "Rojo"
#: packages/ui/primitives/document-flow/add-settings.tsx:371 #: packages/ui/primitives/document-flow/add-settings.tsx:383
#: packages/ui/primitives/template-flow/add-template-settings.tsx:461 #: packages/ui/primitives/template-flow/add-template-settings.tsx:461
msgid "Redirect URL" msgid "Redirect URL"
msgstr "URL de redirección" msgstr "URL de redirección"
@@ -1217,7 +1239,7 @@ msgstr "Recordatorio: Por favor {recipientActionVerb} este documento"
msgid "Reminder: Please {recipientActionVerb} your document" msgid "Reminder: Please {recipientActionVerb} your document"
msgstr "Recordatorio: Por favor {recipientActionVerb} tu documento" msgstr "Recordatorio: Por favor {recipientActionVerb} tu documento"
#: packages/ui/primitives/document-flow/add-fields.tsx:1117 #: packages/ui/primitives/document-flow/add-fields.tsx:1121
msgid "Remove" msgid "Remove"
msgstr "Eliminar" msgstr "Eliminar"
@@ -1245,11 +1267,11 @@ msgstr "Ten la seguridad de que tu documento es estrictamente confidencial y nun
msgid "Rows per page" msgid "Rows per page"
msgstr "Filas por página" msgstr "Filas por página"
#: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:355 #: packages/ui/primitives/document-flow/field-item-advanced-settings.tsx:356
msgid "Save" msgid "Save"
msgstr "Guardar" msgstr "Guardar"
#: packages/ui/primitives/template-flow/add-template-fields.tsx:893 #: packages/ui/primitives/template-flow/add-template-fields.tsx:897
msgid "Save Template" msgid "Save Template"
msgstr "Guardar plantilla" msgstr "Guardar plantilla"
@@ -1285,15 +1307,19 @@ msgstr "Enviar"
msgid "Send Document" msgid "Send Document"
msgstr "Enviar documento" msgstr "Enviar documento"
#: packages/ui/components/document/document-email-checkboxes.tsx:158 #: packages/ui/components/document/document-email-checkboxes.tsx:198
msgid "Send document completed email" msgid "Send document completed email"
msgstr "Enviar correo electrónico de documento completado" msgstr "Enviar correo electrónico de documento completado"
#: packages/ui/components/document/document-email-checkboxes.tsx:197 #: packages/ui/components/document/document-email-checkboxes.tsx:276
msgid "Send document completed email to the owner"
msgstr ""
#: packages/ui/components/document/document-email-checkboxes.tsx:237
msgid "Send document deleted email" msgid "Send document deleted email"
msgstr "Enviar correo electrónico de documento eliminado" msgstr "Enviar correo electrónico de documento eliminado"
#: packages/ui/components/document/document-email-checkboxes.tsx:118 #: packages/ui/components/document/document-email-checkboxes.tsx:158
msgid "Send document pending email" msgid "Send document pending email"
msgstr "Enviar correo electrónico de documento pendiente" msgstr "Enviar correo electrónico de documento pendiente"
@@ -1301,11 +1327,15 @@ msgstr "Enviar correo electrónico de documento pendiente"
msgid "Send documents on behalf of the team using the email address" msgid "Send documents on behalf of the team using the email address"
msgstr "Enviar documentos en nombre del equipo usando la dirección de correo electrónico" msgstr "Enviar documentos en nombre del equipo usando la dirección de correo electrónico"
#: packages/ui/components/document/document-email-checkboxes.tsx:79 #: packages/ui/components/document/document-email-checkboxes.tsx:119
msgid "Send recipient removed email" msgid "Send recipient removed email"
msgstr "Enviar correo electrónico de destinatario eliminado" msgstr "Enviar correo electrónico de destinatario eliminado"
#: packages/ui/components/document/document-email-checkboxes.tsx:40 #: packages/ui/components/document/document-email-checkboxes.tsx:41
msgid "Send recipient signed email"
msgstr ""
#: packages/ui/components/document/document-email-checkboxes.tsx:80
msgid "Send recipient signing request email" msgid "Send recipient signing request email"
msgstr "Enviar correo electrónico de solicitud de firma de destinatario" msgstr "Enviar correo electrónico de solicitud de firma de destinatario"
@@ -1338,11 +1368,11 @@ msgstr "Firmar Documento"
msgid "Sign In" msgid "Sign In"
msgstr "Iniciar sesión" msgstr "Iniciar sesión"
#: packages/ui/primitives/document-flow/add-fields.tsx:830 #: packages/ui/primitives/document-flow/add-fields.tsx:834
#: packages/ui/primitives/document-flow/add-signature.tsx:324 #: packages/ui/primitives/document-flow/add-signature.tsx:324
#: packages/ui/primitives/document-flow/field-icon.tsx:52 #: packages/ui/primitives/document-flow/field-icon.tsx:52
#: packages/ui/primitives/document-flow/types.ts:49 #: 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:629
msgid "Signature" msgid "Signature"
msgstr "Firma" msgstr "Firma"
@@ -1366,8 +1396,8 @@ msgstr "Los firmantes deben tener correos electrónicos únicos"
msgid "Signing" msgid "Signing"
msgstr "Firmando" msgstr "Firmando"
#: packages/lib/server-only/document/send-completed-email.ts:114 #: packages/lib/server-only/document/send-completed-email.ts:119
#: packages/lib/server-only/document/send-completed-email.ts:194 #: packages/lib/server-only/document/send-completed-email.ts:199
msgid "Signing Complete!" msgid "Signing Complete!"
msgstr "¡Firma completa!" msgstr "¡Firma completa!"
@@ -1421,9 +1451,9 @@ msgstr "Correo electrónico del equipo eliminado para {teamName} en Documenso"
msgid "Template title" msgid "Template title"
msgstr "Título de plantilla" msgstr "Título de plantilla"
#: packages/ui/primitives/document-flow/add-fields.tsx:960 #: packages/ui/primitives/document-flow/add-fields.tsx:964
#: packages/ui/primitives/document-flow/types.ts:52 #: 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:759
msgid "Text" msgid "Text"
msgstr "Texto" msgstr "Texto"
@@ -1515,7 +1545,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." 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." 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:768
msgid "This document has already been sent to this recipient. You can no longer edit this recipient." 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." msgstr "Este documento ya ha sido enviado a este destinatario. Ya no puede editar a este destinatario."
@@ -1531,15 +1561,19 @@ msgstr "Este documento fue enviado usando <0>Documenso.</0>"
msgid "This email confirms that you have rejected the document <0>\"{documentName}\"</0> sent by {documentOwnerName}." msgid "This email confirms that you have rejected the document <0>\"{documentName}\"</0> sent by {documentOwnerName}."
msgstr "Este correo electrónico confirma que ha rechazado el documento <0>\"{documentName}\"</0> enviado por {documentOwnerName}." msgstr "Este correo electrónico confirma que ha rechazado el documento <0>\"{documentName}\"</0> enviado por {documentOwnerName}."
#: packages/ui/components/document/document-email-checkboxes.tsx:94 #: packages/ui/components/document/document-email-checkboxes.tsx:56
msgid "This email is sent to the document owner when a recipient has signed the document."
msgstr ""
#: packages/ui/components/document/document-email-checkboxes.tsx:134
msgid "This email is sent to the recipient if they are removed from a pending document." msgid "This email is sent to the recipient if they are removed from a pending document."
msgstr "Este correo electrónico se envía al destinatario si es eliminado de un documento pendiente." msgstr "Este correo electrónico se envía al destinatario si es eliminado de un documento pendiente."
#: packages/ui/components/document/document-email-checkboxes.tsx:55 #: packages/ui/components/document/document-email-checkboxes.tsx:95
msgid "This email is sent to the recipient requesting them to sign the document." msgid "This email is sent to the recipient requesting them to sign the document."
msgstr "Este correo electrónico se envía al destinatario solicitando que firme el documento." msgstr "Este correo electrónico se envía al destinatario solicitando que firme el documento."
#: packages/ui/components/document/document-email-checkboxes.tsx:133 #: packages/ui/components/document/document-email-checkboxes.tsx:173
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." 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." 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."
@@ -1551,7 +1585,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." 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." 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:1101
msgid "This recipient can no longer be modified as they have signed a field, or completed the document." 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." msgstr "Este destinatario ya no puede ser modificado ya que ha firmado un campo o completado el documento."
@@ -1559,29 +1593,33 @@ msgstr "Este destinatario ya no puede ser modificado ya que ha firmado un campo
msgid "This signer has already signed the document." msgid "This signer has already signed the document."
msgstr "Este firmante ya ha firmado el documento." msgstr "Este firmante ya ha firmado el documento."
#: packages/ui/components/document/document-email-checkboxes.tsx:212 #: packages/ui/components/document/document-email-checkboxes.tsx:252
msgid "This will be sent to all recipients if a pending document has been deleted." msgid "This will be sent to all recipients if a pending document has been deleted."
msgstr "Esto se enviará a todos los destinatarios si un documento pendiente ha sido eliminado." msgstr "Esto se enviará a todos los destinatarios si un documento pendiente ha sido eliminado."
#: packages/ui/components/document/document-email-checkboxes.tsx:173 #: packages/ui/components/document/document-email-checkboxes.tsx:213
msgid "This will be sent to all recipients once the document has been fully completed." msgid "This will be sent to all recipients once the document has been fully completed."
msgstr "Esto se enviará a todos los destinatarios una vez que el documento esté completamente completado." msgstr "Esto se enviará a todos los destinatarios una vez que el documento esté completamente completado."
#: packages/ui/components/document/document-email-checkboxes.tsx:291
msgid "This will be sent to the document owner once the document has been fully completed."
msgstr ""
#: packages/ui/components/recipient/recipient-action-auth-select.tsx:48 #: packages/ui/components/recipient/recipient-action-auth-select.tsx:48
msgid "This will override any global settings." msgid "This will override any global settings."
msgstr "Esto anulará cualquier configuración global." msgstr "Esto anulará cualquier configuración global."
#: packages/ui/primitives/document-flow/add-settings.tsx:347 #: packages/ui/primitives/document-flow/add-settings.tsx:359
#: packages/ui/primitives/template-flow/add-template-settings.tsx:438 #: packages/ui/primitives/template-flow/add-template-settings.tsx:438
msgid "Time Zone" msgid "Time Zone"
msgstr "Zona horaria" msgstr "Zona horaria"
#: packages/ui/primitives/document-flow/add-settings.tsx:155 #: packages/ui/primitives/document-flow/add-settings.tsx:166
msgid "Title" msgid "Title"
msgstr "Título" msgstr "Título"
#: packages/ui/primitives/document-flow/add-fields.tsx:1080 #: packages/ui/primitives/document-flow/add-fields.tsx:1084
#: packages/ui/primitives/template-flow/add-template-fields.tsx:873 #: packages/ui/primitives/template-flow/add-template-fields.tsx:877
msgid "To proceed further, please set at least one value for the {0} field." 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}." msgstr "Para continuar, por favor establezca al menos un valor para el campo {0}."
@@ -1597,7 +1635,7 @@ msgstr "Actualizar el rol y agregar campos según sea necesario para el destinat
msgid "Upgrade" msgid "Upgrade"
msgstr "Actualizar" msgstr "Actualizar"
#: packages/ui/primitives/signature-pad/signature-pad.tsx:509 #: packages/ui/primitives/signature-pad/signature-pad.tsx:516
msgid "Upload Signature" msgid "Upload Signature"
msgstr "" msgstr ""
@@ -1726,7 +1764,7 @@ msgstr "Te han invitado a unirte a {0} en Documenso"
msgid "You have been invited to join the following team" msgid "You have been invited to join the following team"
msgstr "Te han invitado a unirte al siguiente equipo" msgstr "Te han invitado a unirte al siguiente equipo"
#: packages/lib/server-only/recipient/set-recipients-for-document.ts:327 #: packages/lib/server-only/recipient/set-recipients-for-document.ts:337
msgid "You have been removed from a document" msgid "You have been removed from a document"
msgstr "Te han eliminado de un documento" msgstr "Te han eliminado de un documento"
@@ -1734,7 +1772,7 @@ msgstr "Te han eliminado de un documento"
msgid "You have been requested to take ownership of team {0} on Documenso" msgid "You have been requested to take ownership of team {0} on Documenso"
msgstr "Se te ha solicitado asumir la propiedad del equipo {0} en Documenso" msgstr "Se te ha solicitado asumir la propiedad del equipo {0} en Documenso"
#: packages/lib/jobs/definitions/emails/send-signing-email.ts:115 #: packages/lib/jobs/definitions/emails/send-signing-email.handler.ts:103
#: packages/lib/server-only/document/resend-document.tsx:125 #: packages/lib/server-only/document/resend-document.tsx:125
msgid "You have initiated the document {0} that requires you to {recipientActionVerb} it." msgid "You have initiated the document {0} that requires you to {recipientActionVerb} it."
msgstr "Has iniciado el documento {0} que requiere que {recipientActionVerb}." msgstr "Has iniciado el documento {0} que requiere que {recipientActionVerb}."

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