mirror of
https://github.com/documenso/documenso.git
synced 2026-06-23 04:42:09 +10:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b041c23b4 | |||
| 7b6e948aa2 | |||
| f6d81b22bd | |||
| c861dd2ee2 | |||
| 7eabae4b4b | |||
| ae4272a6b6 | |||
| fd672943d1 | |||
| c2ea5e5859 | |||
| c1217c5a58 | |||
| 27eb2d65d4 | |||
| ef407cb0b4 |
@@ -5,14 +5,22 @@ description: Learn how to get the coordinates of a field in a document.
|
||||
|
||||
## Field Coordinates
|
||||
|
||||
Field coordinates represent the position of a field in a document. They are returned in the `pageX` and `pageY` properties of the field.
|
||||
Field coordinates represent the position of a field in a document. They are returned in the `pageX`, `pageY`, `width` and `height` properties of the field.
|
||||
|
||||
To enable field coordinates, you can use the `devmode` query parameter.
|
||||
|
||||
```bash
|
||||
https://app.documenso.com/documents/<document-id>/edit?devmode=true
|
||||
# Legacy editor
|
||||
|
||||
https://app.documenso.com/t/<team-url>/documents/<envelope-id>/legacy_editor?devmode=true
|
||||
```
|
||||
|
||||
You should then see the coordinates on top of each field.
|
||||

|
||||
|
||||

|
||||
```bash
|
||||
# New editor
|
||||
|
||||
https://app.documenso.com/t/<team-url>/documents/<envelope-id>/edit?step=addFields&devmode=true
|
||||
```
|
||||
|
||||

|
||||
|
||||
@@ -148,6 +148,7 @@ This method avoids file permission issues by creating the certificate directly i
|
||||
|
||||
# Generate certificate inside container using environment variable
|
||||
docker exec -e CERT_PASS="$CERT_PASS" -it documenso-production-documenso-1 bash -c "
|
||||
mkdir -p /app/certs && \
|
||||
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
||||
-keyout /tmp/private.key \
|
||||
-out /tmp/certificate.crt \
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 596 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 571 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 31 KiB |
@@ -212,12 +212,12 @@ export const ApiTokenForm = ({ className, tokens }: ApiTokenFormProps) => {
|
||||
/>
|
||||
|
||||
<div>
|
||||
<FormLabel className="text-muted-foreground mt-2">
|
||||
<FormLabel className="mt-2 text-muted-foreground">
|
||||
<Trans>Never expire</Trans>
|
||||
</FormLabel>
|
||||
<div className="block md:py-1.5">
|
||||
<Switch
|
||||
className="bg-background mt-2"
|
||||
className="mt-2 bg-background"
|
||||
checked={noExpirationDate}
|
||||
onCheckedChange={setNoExpirationDate}
|
||||
/>
|
||||
@@ -254,14 +254,14 @@ export const ApiTokenForm = ({ className, tokens }: ApiTokenFormProps) => {
|
||||
>
|
||||
<Card gradient>
|
||||
<CardContent className="p-4">
|
||||
<p className="text-muted-foreground mt-2 text-sm">
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
<Trans>
|
||||
Your token was created successfully! Make sure to copy it because you won't be
|
||||
able to see it again!
|
||||
</Trans>
|
||||
</p>
|
||||
|
||||
<p className="bg-muted-foreground/10 my-4 rounded-md px-2.5 py-1 font-mono text-sm">
|
||||
<p className="my-4 rounded-md bg-muted-foreground/10 px-2.5 py-1 font-mono text-sm">
|
||||
{newlyCreatedToken.token}
|
||||
</p>
|
||||
|
||||
|
||||
+2
-16
@@ -1,6 +1,4 @@
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import type { Recipient } from '@prisma/client';
|
||||
import type { Field } from '@prisma/client';
|
||||
@@ -57,8 +55,6 @@ export const DirectTemplateConfigureForm = ({
|
||||
initialEmail,
|
||||
onSubmit,
|
||||
}: DirectTemplateConfigureFormProps) => {
|
||||
const { _ } = useLingui();
|
||||
|
||||
const { sessionData } = useOptionalSession();
|
||||
const user = sessionData?.user;
|
||||
|
||||
@@ -77,17 +73,7 @@ export const DirectTemplateConfigureForm = ({
|
||||
});
|
||||
|
||||
const form = useForm<TDirectTemplateConfigureFormSchema>({
|
||||
resolver: zodResolver(
|
||||
ZDirectTemplateConfigureFormSchema.superRefine((items, ctx) => {
|
||||
if (template.recipients.map((recipient) => recipient.email).includes(items.email)) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: _(msg`Email cannot already exist in the template`),
|
||||
path: ['email'],
|
||||
});
|
||||
}
|
||||
}),
|
||||
),
|
||||
resolver: zodResolver(ZDirectTemplateConfigureFormSchema),
|
||||
defaultValues: {
|
||||
email: initialEmail || '',
|
||||
},
|
||||
@@ -138,7 +124,7 @@ export const DirectTemplateConfigureForm = ({
|
||||
</FormControl>
|
||||
|
||||
{!fieldState.error && (
|
||||
<p className="text-muted-foreground text-xs">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<Trans>Enter your email address to receive the completed document.</Trans>
|
||||
</p>
|
||||
)}
|
||||
|
||||
+9
-9
@@ -35,7 +35,7 @@ export const DocumentSigningMobileWidget = () => {
|
||||
return (
|
||||
<div className="pointer-events-none fixed bottom-0 left-0 right-0 z-50 flex justify-center px-2 pb-2 sm:px-4 sm:pb-6">
|
||||
<div className="pointer-events-auto w-full max-w-[760px]">
|
||||
<div className="bg-card border-border overflow-hidden rounded-xl border shadow-2xl">
|
||||
<div className="overflow-hidden rounded-xl border border-border bg-card shadow-2xl">
|
||||
{/* Main Header Bar */}
|
||||
<div className="flex items-center justify-between gap-4 p-4">
|
||||
<div className="flex-1">
|
||||
@@ -48,15 +48,15 @@ export const DocumentSigningMobileWidget = () => {
|
||||
aria-label={isExpanded ? 'Collapse' : 'Expand'}
|
||||
>
|
||||
{isExpanded ? (
|
||||
<LucideChevronDown className="text-muted-foreground h-5 w-5 flex-shrink-0" />
|
||||
<LucideChevronDown className="h-5 w-5 flex-shrink-0 text-muted-foreground" />
|
||||
) : (
|
||||
<LucideChevronUp className="text-muted-foreground h-5 w-5 flex-shrink-0" />
|
||||
<LucideChevronUp className="h-5 w-5 flex-shrink-0 text-muted-foreground" />
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<h2 className="text-foreground text-lg font-semibold">
|
||||
<h2 className="text-lg font-semibold text-foreground">
|
||||
{match(recipient.role)
|
||||
.with(RecipientRole.VIEWER, () => <Trans>View Document</Trans>)
|
||||
.with(RecipientRole.SIGNER, () => <Trans>Sign Document</Trans>)
|
||||
@@ -65,7 +65,7 @@ export const DocumentSigningMobileWidget = () => {
|
||||
.otherwise(() => null)}
|
||||
</h2>
|
||||
|
||||
<p className="text-muted-foreground -mt-0.5 text-sm">
|
||||
<p className="-mt-0.5 text-sm text-muted-foreground">
|
||||
{recipientFieldsRemaining.length === 0 ? (
|
||||
match(recipient.role)
|
||||
.with(RecipientRole.VIEWER, () => (
|
||||
@@ -102,11 +102,11 @@ export const DocumentSigningMobileWidget = () => {
|
||||
{recipient.role !== RecipientRole.VIEWER &&
|
||||
recipient.role !== RecipientRole.ASSISTANT && (
|
||||
<div className="px-4 pb-3">
|
||||
<div className="bg-muted relative h-[4px] rounded-md">
|
||||
<div className="relative h-[4px] rounded-md bg-muted">
|
||||
<motion.div
|
||||
layout="size"
|
||||
layoutId="document-signing-mobile-widget-progress-bar"
|
||||
className="bg-primary absolute inset-y-0 left-0"
|
||||
className="absolute inset-y-0 left-0 bg-primary"
|
||||
style={{
|
||||
width: `${100 - (100 / requiredRecipientFields.length) * (recipientFieldsRemaining.length ?? 0)}%`,
|
||||
}}
|
||||
@@ -117,11 +117,11 @@ export const DocumentSigningMobileWidget = () => {
|
||||
|
||||
{/* Expandable Content */}
|
||||
{isExpanded && (
|
||||
<div className="border-border animate-in slide-in-from-bottom-2 border-t p-4 duration-200">
|
||||
<div className="border-t border-border p-4 duration-200 animate-in slide-in-from-bottom-2">
|
||||
<EnvelopeSignerForm />
|
||||
|
||||
{!hidePoweredBy && (
|
||||
<div className="bg-primary text-primary-foreground mt-2 inline-block rounded px-2 py-1 text-xs font-medium opacity-60 hover:opacity-100 lg:hidden">
|
||||
<div className="mt-2 inline-block rounded bg-primary px-2 py-1 text-xs font-medium text-primary-foreground opacity-60 hover:opacity-100 lg:hidden">
|
||||
<span>Powered by</span>
|
||||
<BrandingLogo className="ml-2 inline-block h-[14px]" />
|
||||
</div>
|
||||
|
||||
@@ -22,7 +22,7 @@ export const DocumentPageViewRecentActivity = ({
|
||||
documentId,
|
||||
userId,
|
||||
}: DocumentPageViewRecentActivityProps) => {
|
||||
const { _ } = useLingui();
|
||||
const { _, i18n } = useLingui();
|
||||
|
||||
const {
|
||||
data,
|
||||
@@ -48,9 +48,9 @@ export const DocumentPageViewRecentActivity = ({
|
||||
const documentAuditLogs = useMemo(() => (data?.pages ?? []).flatMap((page) => page.data), [data]);
|
||||
|
||||
return (
|
||||
<section className="dark:bg-background border-border bg-widget flex flex-col rounded-xl border">
|
||||
<section className="flex flex-col rounded-xl border border-border bg-widget dark:bg-background">
|
||||
<div className="flex flex-row items-center justify-between border-b px-4 py-3">
|
||||
<h1 className="text-foreground font-medium">
|
||||
<h1 className="font-medium text-foreground">
|
||||
<Trans>Recent activity</Trans>
|
||||
</h1>
|
||||
|
||||
@@ -59,18 +59,18 @@ export const DocumentPageViewRecentActivity = ({
|
||||
|
||||
{isLoading && (
|
||||
<div className="flex h-full items-center justify-center py-16">
|
||||
<Loader className="text-muted-foreground h-6 w-6 animate-spin" />
|
||||
<Loader className="h-6 w-6 animate-spin text-muted-foreground" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isLoadingError && (
|
||||
<div className="flex h-full flex-col items-center justify-center py-16">
|
||||
<p className="text-foreground/80 text-sm">
|
||||
<p className="text-sm text-foreground/80">
|
||||
<Trans>Unable to load document history</Trans>
|
||||
</p>
|
||||
<button
|
||||
onClick={async () => refetch()}
|
||||
className="text-foreground/70 hover:text-muted-foreground mt-2 text-sm"
|
||||
className="mt-2 text-sm text-foreground/70 hover:text-muted-foreground"
|
||||
>
|
||||
<Trans>Click here to retry</Trans>
|
||||
</button>
|
||||
@@ -83,16 +83,16 @@ export const DocumentPageViewRecentActivity = ({
|
||||
{hasNextPage && (
|
||||
<li className="relative flex gap-x-4">
|
||||
<div className="absolute -bottom-6 left-0 top-0 flex w-6 justify-center">
|
||||
<div className="bg-border w-px" />
|
||||
<div className="w-px bg-border" />
|
||||
</div>
|
||||
|
||||
<div className="bg-widget relative flex h-6 w-6 flex-none items-center justify-center">
|
||||
<div className="bg-widget h-1.5 w-1.5 rounded-full ring-1 ring-gray-300 dark:ring-neutral-600" />
|
||||
<div className="relative flex h-6 w-6 flex-none items-center justify-center bg-widget">
|
||||
<div className="h-1.5 w-1.5 rounded-full bg-widget ring-1 ring-gray-300 dark:ring-neutral-600" />
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={async () => fetchNextPage()}
|
||||
className="text-foreground/70 hover:text-muted-foreground text-xs"
|
||||
className="text-xs text-foreground/70 hover:text-muted-foreground"
|
||||
>
|
||||
{isFetchingNextPage ? _(msg`Loading...`) : _(msg`Load older activity`)}
|
||||
</button>
|
||||
@@ -101,7 +101,7 @@ export const DocumentPageViewRecentActivity = ({
|
||||
|
||||
{documentAuditLogs.length === 0 && (
|
||||
<div className="flex items-center justify-center py-4">
|
||||
<p className="text-muted-foreground/70 text-sm">
|
||||
<p className="text-sm text-muted-foreground/70">
|
||||
<Trans>No recent activity</Trans>
|
||||
</p>
|
||||
</div>
|
||||
@@ -115,44 +115,44 @@ export const DocumentPageViewRecentActivity = ({
|
||||
'absolute left-0 top-0 flex w-6 justify-center',
|
||||
)}
|
||||
>
|
||||
<div className="bg-border w-px" />
|
||||
<div className="w-px bg-border" />
|
||||
</div>
|
||||
|
||||
<div className="bg-widget text-foreground/40 relative flex h-6 w-6 flex-none items-center justify-center">
|
||||
<div className="relative flex h-6 w-6 flex-none items-center justify-center bg-widget text-foreground/40">
|
||||
{match(auditLog.type)
|
||||
.with(DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_COMPLETED, () => (
|
||||
<div className="bg-widget rounded-full border border-gray-300 p-1 dark:border-neutral-600">
|
||||
<div className="rounded-full border border-gray-300 bg-widget p-1 dark:border-neutral-600">
|
||||
<CheckCheckIcon className="h-3 w-3" aria-hidden="true" />
|
||||
</div>
|
||||
))
|
||||
.with(DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED, () => (
|
||||
<div className="bg-widget rounded-full border border-gray-300 p-1 dark:border-neutral-600">
|
||||
<div className="rounded-full border border-gray-300 bg-widget p-1 dark:border-neutral-600">
|
||||
<CheckIcon className="h-3 w-3" aria-hidden="true" />
|
||||
</div>
|
||||
))
|
||||
.with(DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_REJECTED, () => (
|
||||
<div className="bg-widget rounded-full border border-gray-300 p-1 dark:border-neutral-600">
|
||||
<div className="rounded-full border border-gray-300 bg-widget p-1 dark:border-neutral-600">
|
||||
<AlertTriangle className="h-3 w-3" aria-hidden="true" />
|
||||
</div>
|
||||
))
|
||||
.with(DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_OPENED, () => (
|
||||
<div className="bg-widget rounded-full border border-gray-300 p-1 dark:border-neutral-600">
|
||||
<div className="rounded-full border border-gray-300 bg-widget p-1 dark:border-neutral-600">
|
||||
<MailOpen className="h-3 w-3" aria-hidden="true" />
|
||||
</div>
|
||||
))
|
||||
.otherwise(() => (
|
||||
<div className="bg-widget h-1.5 w-1.5 rounded-full ring-1 ring-gray-300 dark:ring-neutral-600" />
|
||||
<div className="h-1.5 w-1.5 rounded-full bg-widget ring-1 ring-gray-300 dark:ring-neutral-600" />
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p
|
||||
className="text-muted-foreground dark:text-muted-foreground/70 flex-auto truncate py-0.5 text-xs leading-5"
|
||||
title={formatDocumentAuditLogAction(_, auditLog, userId).description}
|
||||
className="flex-auto truncate py-0.5 text-xs leading-5 text-muted-foreground dark:text-muted-foreground/70"
|
||||
title={formatDocumentAuditLogAction(i18n, auditLog, userId).description}
|
||||
>
|
||||
{formatDocumentAuditLogAction(_, auditLog, userId).description}
|
||||
{formatDocumentAuditLogAction(i18n, auditLog, userId).description}
|
||||
</p>
|
||||
|
||||
<time className="text-muted-foreground dark:text-muted-foreground/70 flex-none py-0.5 text-xs leading-5">
|
||||
<time className="flex-none py-0.5 text-xs leading-5 text-muted-foreground dark:text-muted-foreground/70">
|
||||
{DateTime.fromJSDate(auditLog.createdAt).toRelative({ style: 'short' })}
|
||||
</time>
|
||||
</li>
|
||||
|
||||
+8
-8
@@ -339,7 +339,7 @@ export const EnvelopeEditorSettingsDialog = ({
|
||||
|
||||
<DialogContent className="flex w-full !max-w-5xl flex-row gap-0 p-0">
|
||||
{/* Sidebar. */}
|
||||
<div className="bg-accent/20 flex w-80 flex-col border-r">
|
||||
<div className="flex w-80 flex-col border-r bg-accent/20">
|
||||
<DialogHeader className="p-6 pb-4">
|
||||
<DialogTitle>Document Settings</DialogTitle>
|
||||
</DialogHeader>
|
||||
@@ -390,7 +390,7 @@ export const EnvelopeEditorSettingsDialog = ({
|
||||
<InfoIcon className="mx-2 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
|
||||
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
|
||||
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
|
||||
<Trans>
|
||||
Controls the language for the document, including the language
|
||||
to be used for email notifications, and the final certificate
|
||||
@@ -441,7 +441,7 @@ export const EnvelopeEditorSettingsDialog = ({
|
||||
}))}
|
||||
selectedValues={field.value}
|
||||
onChange={field.onChange}
|
||||
className="bg-background w-full"
|
||||
className="w-full bg-background"
|
||||
emptySelectionPlaceholder="Select signature types"
|
||||
/>
|
||||
</FormControl>
|
||||
@@ -518,7 +518,7 @@ export const EnvelopeEditorSettingsDialog = ({
|
||||
<InfoIcon className="mx-2 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
|
||||
<TooltipContent className="text-muted-foreground max-w-xs">
|
||||
<TooltipContent className="max-w-xs text-muted-foreground">
|
||||
<Trans>
|
||||
Add an external ID to the document. This can be used to identify
|
||||
the document in external systems.
|
||||
@@ -548,7 +548,7 @@ export const EnvelopeEditorSettingsDialog = ({
|
||||
<InfoIcon className="mx-2 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
|
||||
<TooltipContent className="text-muted-foreground max-w-xs">
|
||||
<TooltipContent className="max-w-xs text-muted-foreground">
|
||||
<Trans>
|
||||
Add a URL to redirect the user to once the document is signed
|
||||
</Trans>
|
||||
@@ -576,7 +576,7 @@ export const EnvelopeEditorSettingsDialog = ({
|
||||
<InfoIcon className="mx-2 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
|
||||
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
|
||||
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
|
||||
<h2>
|
||||
<strong>
|
||||
<Trans>Document Distribution Method</Trans>
|
||||
@@ -735,14 +735,14 @@ export const EnvelopeEditorSettingsDialog = ({
|
||||
<TooltipTrigger>
|
||||
<InfoIcon className="mx-2 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="text-muted-foreground p-4">
|
||||
<TooltipContent className="p-4 text-muted-foreground">
|
||||
<DocumentSendEmailMessageHelper />
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</FormLabel>
|
||||
|
||||
<FormControl>
|
||||
<Textarea className="bg-background h-16 resize-none" {...field} />
|
||||
<Textarea className="h-16 resize-none bg-background" {...field} />
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
|
||||
@@ -28,36 +28,40 @@ export const EnvelopeSignerHeader = () => {
|
||||
const { envelopeData, envelope, recipientFieldsRemaining, recipient } =
|
||||
useRequiredEnvelopeSigningContext();
|
||||
|
||||
const isEmbedSigning = useEmbedSigningContext() !== null;
|
||||
|
||||
return (
|
||||
<nav className="embed--DocumentWidgetHeader bg-background border-border max-w-screen flex flex-row justify-between border-b px-4 py-3 md:px-6">
|
||||
<nav className="embed--DocumentWidgetHeader max-w-screen flex flex-row justify-between border-b border-border bg-background px-4 py-3 md:px-6">
|
||||
{/* Left side - Logo and title */}
|
||||
<div className="flex min-w-0 flex-1 items-center space-x-2 md:w-auto md:flex-none">
|
||||
<Link to="/" className="flex-shrink-0">
|
||||
{envelopeData.settings.brandingEnabled && envelopeData.settings.brandingLogo ? (
|
||||
<img
|
||||
src={`/api/branding/logo/team/${envelope.teamId}`}
|
||||
alt={`${envelope.team.name}'s Logo`}
|
||||
className="h-6 w-auto"
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<BrandingLogo className="hidden h-6 w-auto md:block" />
|
||||
<BrandingLogoIcon className="h-6 w-auto md:hidden" />
|
||||
</>
|
||||
)}
|
||||
</Link>
|
||||
{!isEmbedSigning && (
|
||||
<Link to="/" className="flex-shrink-0">
|
||||
{envelopeData.settings.brandingEnabled && envelopeData.settings.brandingLogo ? (
|
||||
<img
|
||||
src={`/api/branding/logo/team/${envelope.teamId}`}
|
||||
alt={`${envelope.team.name}'s Logo`}
|
||||
className="h-6 w-auto"
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<BrandingLogo className="hidden h-6 w-auto md:block" />
|
||||
<BrandingLogoIcon className="h-6 w-auto md:hidden" />
|
||||
</>
|
||||
)}
|
||||
</Link>
|
||||
)}
|
||||
|
||||
<h1
|
||||
title={envelope.title}
|
||||
className="text-foreground min-w-0 truncate text-base font-semibold md:hidden"
|
||||
className="min-w-0 truncate text-base font-semibold text-foreground md:hidden"
|
||||
>
|
||||
{envelope.title}
|
||||
</h1>
|
||||
|
||||
<Separator orientation="vertical" className="hidden h-6 md:block" />
|
||||
{!isEmbedSigning && <Separator orientation="vertical" className="hidden h-6 md:block" />}
|
||||
|
||||
<div className="hidden items-center space-x-2 md:flex">
|
||||
<h1 className="text-foreground whitespace-nowrap text-sm font-medium">
|
||||
<h1 className="whitespace-nowrap text-sm font-medium text-foreground">
|
||||
{envelope.title}
|
||||
</h1>
|
||||
|
||||
@@ -74,7 +78,7 @@ export const EnvelopeSignerHeader = () => {
|
||||
|
||||
{/* Right side - Desktop content */}
|
||||
<div className="hidden items-center space-x-2 lg:flex">
|
||||
<p className="text-muted-foreground mr-2 flex-shrink-0 text-sm">
|
||||
<p className="mr-2 flex-shrink-0 text-sm text-muted-foreground">
|
||||
<Plural
|
||||
one="1 Field Remaining"
|
||||
other="# Fields Remaining"
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Skeleton } from '@documenso/ui/primitives/skeleton';
|
||||
export default function DocumentEditSkeleton() {
|
||||
return (
|
||||
<div className="mx-auto -mt-4 flex w-full max-w-screen-xl flex-col px-4 md:px-8">
|
||||
<Link to="/" className="flex grow-0 items-center text-[#7AC455] hover:opacity-80">
|
||||
<Link to="/" className="flex grow-0 items-center text-documenso-700 hover:opacity-80">
|
||||
<ChevronLeft className="mr-2 inline-block h-5 w-5" />
|
||||
<Trans>Documents</Trans>
|
||||
</Link>
|
||||
|
||||
@@ -95,7 +95,7 @@ export const DocumentLogsTable = ({ documentId, userId }: DocumentLogsTableProps
|
||||
header: _(msg`Action`),
|
||||
accessorKey: 'type',
|
||||
cell: ({ row }) => (
|
||||
<span>{formatDocumentAuditLogAction(_, row.original, userId).description}</span>
|
||||
<span>{formatDocumentAuditLogAction(i18n, row.original, userId).description}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -65,7 +65,7 @@ const formatUserAgent = (userAgent: string | null | undefined, userAgentInfo: UA
|
||||
};
|
||||
|
||||
export const InternalAuditLogTable = ({ logs }: AuditLogDataTableProps) => {
|
||||
const { _ } = useLingui();
|
||||
const { _, i18n } = useLingui();
|
||||
|
||||
const parser = new UAParser();
|
||||
|
||||
@@ -73,7 +73,7 @@ export const InternalAuditLogTable = ({ logs }: AuditLogDataTableProps) => {
|
||||
<div className="space-y-4">
|
||||
{logs.map((log, index) => {
|
||||
parser.setUA(log.userAgent || '');
|
||||
const formattedAction = formatDocumentAuditLogAction(_, log);
|
||||
const formattedAction = formatDocumentAuditLogAction(i18n, log);
|
||||
const userAgentInfo = parser.getResult();
|
||||
|
||||
return (
|
||||
@@ -95,17 +95,17 @@ export const InternalAuditLogTable = ({ logs }: AuditLogDataTableProps) => {
|
||||
/>
|
||||
|
||||
<div>
|
||||
<div className="text-muted-foreground text-sm font-medium uppercase tracking-wide print:text-[8pt]">
|
||||
<div className="text-sm font-medium uppercase tracking-wide text-muted-foreground print:text-[8pt]">
|
||||
{log.type.replace(/_/g, ' ')}
|
||||
</div>
|
||||
|
||||
<div className="text-foreground text-sm font-medium print:text-[8pt]">
|
||||
<div className="text-sm font-medium text-foreground print:text-[8pt]">
|
||||
{formattedAction.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="text-muted-foreground text-sm print:text-[8pt]">
|
||||
<div className="text-sm text-muted-foreground print:text-[8pt]">
|
||||
{DateTime.fromJSDate(log.createdAt)
|
||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||
.toLocaleString(dateFormat)}
|
||||
@@ -117,27 +117,27 @@ export const InternalAuditLogTable = ({ logs }: AuditLogDataTableProps) => {
|
||||
{/* Details Section - Two column layout */}
|
||||
<div className="grid grid-cols-2 gap-x-8 gap-y-2 text-xs print:text-[6pt]">
|
||||
<div>
|
||||
<div className="text-muted-foreground/70 font-medium uppercase tracking-wide">
|
||||
<div className="font-medium uppercase tracking-wide text-muted-foreground/70">
|
||||
{_(msg`User`)}
|
||||
</div>
|
||||
|
||||
<div className="text-foreground mt-1 font-mono">{log.email || 'N/A'}</div>
|
||||
<div className="mt-1 font-mono text-foreground">{log.email || 'N/A'}</div>
|
||||
</div>
|
||||
|
||||
<div className="text-right">
|
||||
<div className="text-muted-foreground/70 font-medium uppercase tracking-wide">
|
||||
<div className="font-medium uppercase tracking-wide text-muted-foreground/70">
|
||||
{_(msg`IP Address`)}
|
||||
</div>
|
||||
|
||||
<div className="text-foreground mt-1 font-mono">{log.ipAddress || 'N/A'}</div>
|
||||
<div className="mt-1 font-mono text-foreground">{log.ipAddress || 'N/A'}</div>
|
||||
</div>
|
||||
|
||||
<div className="col-span-2">
|
||||
<div className="text-muted-foreground/70 font-medium uppercase tracking-wide">
|
||||
<div className="font-medium uppercase tracking-wide text-muted-foreground/70">
|
||||
{_(msg`User Agent`)}
|
||||
</div>
|
||||
|
||||
<div className="text-foreground mt-1">
|
||||
<div className="mt-1 text-foreground">
|
||||
{_(formatUserAgent(log.userAgent, userAgentInfo))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -40,8 +40,8 @@ export default function OrganisationSettingsTeamsPage() {
|
||||
if (organisation.teams.length === 0) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center px-4 py-16">
|
||||
<div className="bg-muted mb-6 flex h-20 w-20 items-center justify-center rounded-full">
|
||||
<UsersIcon className="text-muted-foreground h-10 w-10" />
|
||||
<div className="mb-6 flex h-20 w-20 items-center justify-center rounded-full bg-muted">
|
||||
<UsersIcon className="h-10 w-10 text-muted-foreground" />
|
||||
</div>
|
||||
|
||||
<h2 className="mb-2 text-xl font-semibold">
|
||||
@@ -53,7 +53,7 @@ export default function OrganisationSettingsTeamsPage() {
|
||||
organisation.currentOrganisationRole,
|
||||
) ? (
|
||||
<>
|
||||
<p className="text-muted-foreground mb-8 max-w-md text-center text-sm">
|
||||
<p className="mb-8 max-w-md text-center text-sm text-muted-foreground">
|
||||
<Trans>
|
||||
Teams help you organise your work and collaborate with others. Create your first
|
||||
team to get started.
|
||||
@@ -73,21 +73,21 @@ export default function OrganisationSettingsTeamsPage() {
|
||||
<h3 className="mb-2 font-medium">
|
||||
<Trans>What you can do with teams:</Trans>
|
||||
</h3>
|
||||
<ul className="text-muted-foreground space-y-2 text-sm">
|
||||
<ul className="space-y-2 text-sm text-muted-foreground">
|
||||
<li className="flex flex-row items-center gap-2">
|
||||
<div className="bg-muted mt-0.5 flex h-5 w-5 items-center justify-center rounded-full font-bold">
|
||||
<div className="mt-0.5 flex h-5 w-5 items-center justify-center rounded-full bg-muted font-bold">
|
||||
<span className="text-xs">1</span>
|
||||
</div>
|
||||
<Trans>Organize your documents and templates</Trans>
|
||||
</li>
|
||||
<li className="flex flex-row items-center gap-2">
|
||||
<div className="bg-muted mt-0.5 flex h-5 w-5 items-center justify-center rounded-full font-bold">
|
||||
<div className="mt-0.5 flex h-5 w-5 items-center justify-center rounded-full bg-muted font-bold">
|
||||
<span className="text-xs">2</span>
|
||||
</div>
|
||||
<Trans>Invite team members to collaborate</Trans>
|
||||
</li>
|
||||
<li className="flex flex-row items-center gap-2">
|
||||
<div className="bg-muted mt-0.5 flex h-5 w-5 items-center justify-center rounded-full font-bold">
|
||||
<div className="mt-0.5 flex h-5 w-5 items-center justify-center rounded-full bg-muted font-bold">
|
||||
<span className="text-xs">3</span>
|
||||
</div>
|
||||
<Trans>Manage permissions and access controls</Trans>
|
||||
@@ -96,7 +96,7 @@ export default function OrganisationSettingsTeamsPage() {
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<p className="text-muted-foreground mb-8 max-w-md text-center text-sm">
|
||||
<p className="mb-8 max-w-md text-center text-sm text-muted-foreground">
|
||||
<Trans>
|
||||
You currently have no access to any teams within this organisation. Please contact
|
||||
your organisation to request access.
|
||||
@@ -114,7 +114,7 @@ export default function OrganisationSettingsTeamsPage() {
|
||||
<h1 className="text-2xl font-semibold tracking-tight">
|
||||
<Trans>{organisation.name} Teams</Trans>
|
||||
</h1>
|
||||
<p className="text-muted-foreground mt-1 text-sm">
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
<Trans>Select a team to view its dashboard</Trans>
|
||||
</p>
|
||||
</div>
|
||||
@@ -129,7 +129,7 @@ export default function OrganisationSettingsTeamsPage() {
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{organisation.teams.map((team) => (
|
||||
<Link to={`/t/${team.url}`} key={team.id}>
|
||||
<Card className="hover:bg-muted/50 border-border h-full border transition-all">
|
||||
<Card className="h-full border border-border transition-all hover:bg-muted/50">
|
||||
<CardContent className="p-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<Avatar className="h-10 w-10 border-2 border-solid">
|
||||
@@ -145,7 +145,7 @@ export default function OrganisationSettingsTeamsPage() {
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h3 className="font-medium">{team.name}</h3>
|
||||
<div className="text-muted-foreground truncate text-xs">
|
||||
<div className="truncate text-xs text-muted-foreground">
|
||||
{formatTeamUrl(team.url)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -154,11 +154,11 @@ export default function OrganisationSettingsTeamsPage() {
|
||||
</div>
|
||||
|
||||
<div className="mt-2 flex items-center gap-4">
|
||||
<div className="text-muted-foreground flex items-center gap-1 text-xs">
|
||||
<div className="flex items-center gap-1 text-xs text-muted-foreground">
|
||||
<CalendarIcon className="h-3 w-3" />
|
||||
{i18n.date(team.createdAt, { dateStyle: 'short' })}
|
||||
</div>
|
||||
<div className="text-muted-foreground flex items-center gap-1 text-xs">
|
||||
<div className="flex items-center gap-1 text-xs text-muted-foreground">
|
||||
<UserIcon className="h-3 w-3" />
|
||||
<span>{t(TEAM_MEMBER_ROLE_MAP[team.currentTeamRole])}</span>
|
||||
</div>
|
||||
|
||||
@@ -79,7 +79,7 @@ export default function OrganisationSettingsBrandingPage() {
|
||||
if (isLoadingOrganisation || !organisationWithSettings) {
|
||||
return (
|
||||
<div className="flex items-center justify-center rounded-lg py-32">
|
||||
<Loader className="text-muted-foreground h-6 w-6 animate-spin" />
|
||||
<Loader className="h-6 w-6 animate-spin text-muted-foreground" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ export default function DocumentPage({ params }: Route.ComponentProps) {
|
||||
<DocumentRecipientLinkCopyDialog recipients={envelope.recipients} />
|
||||
)}
|
||||
|
||||
<Link to={documentRootPath} className="flex items-center text-[#7AC455] hover:opacity-80">
|
||||
<Link to={documentRootPath} className="flex items-center text-documenso-700 hover:opacity-80">
|
||||
<ChevronLeft className="mr-2 inline-block h-5 w-5" />
|
||||
<Trans>Documents</Trans>
|
||||
</Link>
|
||||
|
||||
@@ -84,7 +84,7 @@ export default function DocumentEditPage() {
|
||||
|
||||
return (
|
||||
<div className="mx-auto -mt-4 w-full max-w-screen-xl px-4 md:px-8">
|
||||
<Link to={documentRootPath} className="flex items-center text-[#7AC455] hover:opacity-80">
|
||||
<Link to={documentRootPath} className="flex items-center text-documenso-700 hover:opacity-80">
|
||||
<ChevronLeft className="mr-2 inline-block h-5 w-5" />
|
||||
<Trans>Documents</Trans>
|
||||
</Link>
|
||||
|
||||
@@ -134,7 +134,7 @@ export default function DocumentsLogsPage({ loaderData }: Route.ComponentProps)
|
||||
<div className="mx-auto -mt-4 w-full max-w-screen-xl px-4 md:px-8">
|
||||
<Link
|
||||
to={`${documentRootPath}/${document.envelopeId}`}
|
||||
className="flex items-center text-[#7AC455] hover:opacity-80"
|
||||
className="flex items-center text-documenso-700 hover:opacity-80"
|
||||
>
|
||||
<ChevronLeft className="mr-2 inline-block h-5 w-5" />
|
||||
<Trans>Document</Trans>
|
||||
|
||||
@@ -117,7 +117,7 @@ export default function TemplatePage({ params }: Route.ComponentProps) {
|
||||
|
||||
return (
|
||||
<div className="mx-auto -mt-4 w-full max-w-screen-xl px-4 md:px-8">
|
||||
<Link to={templateRootPath} className="flex items-center text-[#7AC455] hover:opacity-80">
|
||||
<Link to={templateRootPath} className="flex items-center text-documenso-700 hover:opacity-80">
|
||||
<ChevronLeft className="mr-2 inline-block h-5 w-5" />
|
||||
<Trans>Templates</Trans>
|
||||
</Link>
|
||||
|
||||
@@ -61,7 +61,7 @@ export default function TemplateEditPage() {
|
||||
<div>
|
||||
<Link
|
||||
to={`${templateRootPath}/${template.envelopeId}`}
|
||||
className="flex items-center text-[#7AC455] hover:opacity-80"
|
||||
className="flex items-center text-documenso-700 hover:opacity-80"
|
||||
>
|
||||
<ChevronLeft className="mr-2 inline-block h-5 w-5" />
|
||||
<Trans>Template</Trans>
|
||||
|
||||
@@ -149,7 +149,7 @@ export default function AuditLog({ loaderData }: Route.ComponentProps) {
|
||||
<span className="mt-1 block">
|
||||
{DateTime.fromJSDate(document.createdAt)
|
||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||
.toFormat('yyyy-mm-dd hh:mm:ss a (ZZZZ)')}
|
||||
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)')}
|
||||
</span>
|
||||
</p>
|
||||
|
||||
@@ -159,7 +159,7 @@ export default function AuditLog({ loaderData }: Route.ComponentProps) {
|
||||
<span className="mt-1 block">
|
||||
{DateTime.fromJSDate(document.updatedAt)
|
||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||
.toFormat('yyyy-mm-dd hh:mm:ss a (ZZZZ)')}
|
||||
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)')}
|
||||
</span>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -355,16 +355,16 @@ const SigningPageV1 = ({ data }: { data: Awaited<ReturnType<typeof handleV1Loade
|
||||
</Trans>
|
||||
</h2>
|
||||
|
||||
<p className="text-muted-foreground/60 mt-2.5 max-w-[60ch] text-center text-sm font-medium md:text-base">
|
||||
<p className="mt-2.5 max-w-[60ch] text-center text-sm font-medium text-muted-foreground/60 md:text-base">
|
||||
<Trans>This document has been cancelled by the owner.</Trans>
|
||||
</p>
|
||||
|
||||
{user ? (
|
||||
<Link to="/" className="text-documenso-700 hover:text-documenso-600 mt-36">
|
||||
<Link to="/" className="mt-36 text-documenso-700 hover:text-documenso-600">
|
||||
<Trans>Go Back Home</Trans>
|
||||
</Link>
|
||||
) : (
|
||||
<p className="text-muted-foreground/60 mt-36 text-sm">
|
||||
<p className="mt-36 text-sm text-muted-foreground/60">
|
||||
<Trans>
|
||||
Want to send slick signing links like this one?{' '}
|
||||
<Link
|
||||
@@ -455,16 +455,16 @@ const SigningPageV2 = ({ data }: { data: Awaited<ReturnType<typeof handleV2Loade
|
||||
</Trans>
|
||||
</h2>
|
||||
|
||||
<p className="text-muted-foreground/60 mt-2.5 max-w-[60ch] text-center text-sm font-medium md:text-base">
|
||||
<p className="mt-2.5 max-w-[60ch] text-center text-sm font-medium text-muted-foreground/60 md:text-base">
|
||||
<Trans>This document has been cancelled by the owner.</Trans>
|
||||
</p>
|
||||
|
||||
{user ? (
|
||||
<Link to="/" className="text-documenso-700 hover:text-documenso-600 mt-36">
|
||||
<Link to="/" className="mt-36 text-documenso-700 hover:text-documenso-600">
|
||||
<Trans>Go Back Home</Trans>
|
||||
</Link>
|
||||
) : (
|
||||
<p className="text-muted-foreground/60 mt-36 text-sm">
|
||||
<p className="mt-36 text-sm text-muted-foreground/60">
|
||||
<Trans>
|
||||
Want to send slick signing links like this one?{' '}
|
||||
<Link
|
||||
|
||||
@@ -91,25 +91,25 @@ export default function RejectedSigningPage({ loaderData }: Route.ComponentProps
|
||||
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="flex items-center gap-x-4">
|
||||
<XCircle className="text-destructive h-10 w-10" />
|
||||
<XCircle className="h-10 w-10 text-destructive" />
|
||||
|
||||
<h2 className="max-w-[35ch] text-center text-2xl font-semibold leading-normal md:text-3xl lg:text-4xl">
|
||||
<Trans>Document Rejected</Trans>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div className="text-destructive mt-4 flex items-center text-center text-sm">
|
||||
<div className="mt-4 flex items-center text-center text-sm text-destructive">
|
||||
<Trans>You have rejected this document</Trans>
|
||||
</div>
|
||||
|
||||
<p className="text-muted-foreground mt-6 max-w-[60ch] text-center text-sm">
|
||||
<p className="mt-6 max-w-[60ch] text-center text-sm text-muted-foreground">
|
||||
<Trans>
|
||||
The document owner has been notified of your decision. They may contact you with further
|
||||
instructions if necessary.
|
||||
</Trans>
|
||||
</p>
|
||||
|
||||
<p className="text-muted-foreground mt-2 max-w-[60ch] text-center text-sm">
|
||||
<p className="mt-2 max-w-[60ch] text-center text-sm text-muted-foreground">
|
||||
<Trans>No further action is required from you at this time.</Trans>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -78,14 +78,14 @@ export default function WaitingForTurnToSignPage({ loaderData }: Route.Component
|
||||
<Trans>Waiting for Your Turn</Trans>
|
||||
</h2>
|
||||
|
||||
<p className="text-muted-foreground mt-2 text-sm">
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
<Trans>
|
||||
It's currently not your turn to sign. You will receive an email with instructions once
|
||||
it's your turn to sign the document.
|
||||
</Trans>
|
||||
</p>
|
||||
|
||||
<p className="text-muted-foreground mt-4 text-sm">
|
||||
<p className="mt-4 text-sm text-muted-foreground">
|
||||
<Trans>Please check your email for updates.</Trans>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -107,5 +107,5 @@
|
||||
"vite-plugin-babel-macros": "^1.0.6",
|
||||
"vite-tsconfig-paths": "^5.1.4"
|
||||
},
|
||||
"version": "2.3.2"
|
||||
"version": "2.4.0"
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
###########################
|
||||
# BASE CONTAINER #
|
||||
###########################
|
||||
FROM node:22-alpine3.20 AS base
|
||||
FROM node:22-alpine3.22 AS base
|
||||
|
||||
RUN apk add --no-cache openssl
|
||||
RUN apk add --no-cache font-freefont
|
||||
|
||||
Generated
+3
-3
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@documenso/root",
|
||||
"version": "2.3.2",
|
||||
"version": "2.4.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@documenso/root",
|
||||
"version": "2.3.2",
|
||||
"version": "2.4.0",
|
||||
"hasInstallScript": true,
|
||||
"workspaces": [
|
||||
"apps/*",
|
||||
@@ -109,7 +109,7 @@
|
||||
},
|
||||
"apps/remix": {
|
||||
"name": "@documenso/remix",
|
||||
"version": "2.3.2",
|
||||
"version": "2.4.0",
|
||||
"dependencies": {
|
||||
"@cantoo/pdf-lib": "^2.5.3",
|
||||
"@documenso/api": "*",
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
"apps/*",
|
||||
"packages/*"
|
||||
],
|
||||
"version": "2.3.2",
|
||||
"version": "2.4.0",
|
||||
"scripts": {
|
||||
"postinstall": "patch-package",
|
||||
"build": "turbo run build",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 163 KiB |
@@ -113,7 +113,7 @@ export const ConfirmTeamEmailTemplate = ({
|
||||
|
||||
<Section className="mb-6 mt-8 text-center">
|
||||
<Button
|
||||
className="bg-documenso-500 inline-flex items-center justify-center rounded-lg px-6 py-3 text-center text-sm font-medium text-black no-underline"
|
||||
className="inline-flex items-center justify-center rounded-lg bg-documenso-500 px-6 py-3 text-center text-sm font-medium text-black no-underline"
|
||||
href={`${baseUrl}/team/verify/email/${token}`}
|
||||
>
|
||||
<Trans>Accept</Trans>
|
||||
|
||||
@@ -72,7 +72,7 @@ export const ResetPasswordTemplate = ({
|
||||
<Trans>
|
||||
Didn't request a password change? We are here to help you secure your account,
|
||||
just{' '}
|
||||
<Link className="text-documenso-700 font-normal" href="mailto:hi@documenso.com">
|
||||
<Link className="font-normal text-documenso-700" href="mailto:hi@documenso.com">
|
||||
contact us
|
||||
</Link>
|
||||
.
|
||||
|
||||
@@ -21,3 +21,12 @@ export const USE_INTERNAL_URL_BROWSERLESS = () =>
|
||||
|
||||
export const IS_AI_FEATURES_CONFIGURED = () =>
|
||||
!!env('GOOGLE_VERTEX_PROJECT_ID') && !!env('GOOGLE_VERTEX_API_KEY');
|
||||
|
||||
/**
|
||||
* Temporary flag to toggle between Playwright-based and Konva-based PDF generation
|
||||
* for audit logs during sealing.
|
||||
*
|
||||
* @deprecated This is a temporary flag and will be removed once Konva-based generation is stable.
|
||||
*/
|
||||
export const NEXT_PRIVATE_USE_PLAYWRIGHT_PDF = () =>
|
||||
env('NEXT_PRIVATE_USE_PLAYWRIGHT_PDF') === 'true';
|
||||
|
||||
@@ -8,3 +8,8 @@ export const MIN_STANDARD_FONT_SIZE = 8;
|
||||
export const MIN_HANDWRITING_FONT_SIZE = 20;
|
||||
|
||||
export const CAVEAT_FONT_PATH = () => `${NEXT_PUBLIC_WEBAPP_URL()}/fonts/caveat.ttf`;
|
||||
|
||||
export const PDF_SIZE_A4_72PPI = {
|
||||
width: 595,
|
||||
height: 842,
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
rotateDegrees,
|
||||
translate,
|
||||
} from '@cantoo/pdf-lib';
|
||||
import type { DocumentData, DocumentMeta, Envelope, EnvelopeItem, Field } from '@prisma/client';
|
||||
import type { DocumentData, Envelope, EnvelopeItem, Field } from '@prisma/client';
|
||||
import {
|
||||
DocumentStatus,
|
||||
EnvelopeType,
|
||||
@@ -20,9 +20,13 @@ import path from 'node:path';
|
||||
import { groupBy } from 'remeda';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { generateAuditLogPdf } from '@documenso/lib/server-only/pdf/generate-audit-log-pdf';
|
||||
import { generateCertificatePdf } from '@documenso/lib/server-only/pdf/generate-certificate-pdf';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { signPdf } from '@documenso/signing';
|
||||
|
||||
import { NEXT_PRIVATE_USE_PLAYWRIGHT_PDF } from '../../../constants/app';
|
||||
import { PDF_SIZE_A4_72PPI } from '../../../constants/pdf';
|
||||
import { AppError, AppErrorCode } from '../../../errors/app-error';
|
||||
import { sendCompletedEmail } from '../../../server-only/document/send-completed-email';
|
||||
import { getAuditLogsPdf } from '../../../server-only/htmltopdf/get-audit-logs-pdf';
|
||||
@@ -48,7 +52,7 @@ import { putPdfFileServerSide } from '../../../universal/upload/put-file.server'
|
||||
import { fieldsContainUnsignedRequiredField } from '../../../utils/advanced-fields-helpers';
|
||||
import { isDocumentCompleted } from '../../../utils/document';
|
||||
import { createDocumentAuditLogData } from '../../../utils/document-audit-logs';
|
||||
import { mapDocumentIdToSecondaryId, mapSecondaryIdToDocumentId } from '../../../utils/envelope';
|
||||
import { mapDocumentIdToSecondaryId } from '../../../utils/envelope';
|
||||
import type { JobRunIO } from '../../client/_internal/job';
|
||||
import type { TSealDocumentJobDefinition } from './seal-document';
|
||||
|
||||
@@ -68,8 +72,19 @@ export const run = async ({
|
||||
secondaryId: mapDocumentIdToSecondaryId(documentId),
|
||||
},
|
||||
include: {
|
||||
user: {
|
||||
select: {
|
||||
name: true,
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
documentMeta: true,
|
||||
recipients: true,
|
||||
fields: {
|
||||
include: {
|
||||
signature: true,
|
||||
},
|
||||
},
|
||||
envelopeItems: {
|
||||
include: {
|
||||
documentData: true,
|
||||
@@ -116,23 +131,20 @@ export const run = async ({
|
||||
});
|
||||
}
|
||||
|
||||
let envelopeItems = envelope.envelopeItems;
|
||||
let { envelopeItems } = envelope;
|
||||
|
||||
const fields = envelope.fields;
|
||||
|
||||
if (envelopeItems.length < 1) {
|
||||
throw new Error(`Document ${envelope.id} has no envelope items`);
|
||||
}
|
||||
|
||||
const recipients = await prisma.recipient.findMany({
|
||||
where: {
|
||||
envelopeId: envelope.id,
|
||||
role: {
|
||||
not: RecipientRole.CC,
|
||||
},
|
||||
},
|
||||
});
|
||||
const recipientsWithoutCCers = envelope.recipients.filter(
|
||||
(recipient) => recipient.role !== RecipientRole.CC,
|
||||
);
|
||||
|
||||
// Determine if the document has been rejected by checking if any recipient has rejected it
|
||||
const rejectedRecipient = recipients.find(
|
||||
const rejectedRecipient = recipientsWithoutCCers.find(
|
||||
(recipient) => recipient.signingStatus === SigningStatus.REJECTED,
|
||||
);
|
||||
|
||||
@@ -141,15 +153,6 @@ export const run = async ({
|
||||
// Get the rejection reason from the rejected recipient
|
||||
const rejectionReason = rejectedRecipient?.rejectionReason ?? '';
|
||||
|
||||
const fields = await prisma.field.findMany({
|
||||
where: {
|
||||
envelopeId: envelope.id,
|
||||
},
|
||||
include: {
|
||||
signature: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Skip the field check if the document is rejected
|
||||
if (!isRejected && fieldsContainUnsignedRequiredField(fields)) {
|
||||
throw new Error(`Document ${envelope.id} has unsigned required fields`);
|
||||
@@ -178,13 +181,52 @@ export const run = async ({
|
||||
});
|
||||
}
|
||||
|
||||
const legacyDocumentId = mapSecondaryIdToDocumentId(envelope.secondaryId);
|
||||
let certificateDoc: PDFDocument | null = null;
|
||||
let auditLogDoc: PDFDocument | null = null;
|
||||
|
||||
const { certificateData, auditLogData } = await getCertificateAndAuditLogData({
|
||||
legacyDocumentId,
|
||||
documentMeta: envelope.documentMeta,
|
||||
settings,
|
||||
});
|
||||
if (settings.includeSigningCertificate || settings.includeAuditLog) {
|
||||
const certificatePayload = {
|
||||
envelope,
|
||||
recipients: envelope.recipients, // Need to use the recipients from envelope which contains ALL recipients.
|
||||
fields,
|
||||
language: envelope.documentMeta.language,
|
||||
envelopeOwner: {
|
||||
email: envelope.user.email,
|
||||
name: envelope.user.name || '',
|
||||
},
|
||||
envelopeItems: envelopeItems.map((item) => item.title),
|
||||
pageWidth: PDF_SIZE_A4_72PPI.width,
|
||||
pageHeight: PDF_SIZE_A4_72PPI.height,
|
||||
};
|
||||
|
||||
// Use Playwright-based PDF generation if enabled, otherwise use Konva-based generation.
|
||||
// This is a temporary toggle while we validate the Konva-based approach.
|
||||
const usePlaywrightPdf = NEXT_PRIVATE_USE_PLAYWRIGHT_PDF();
|
||||
|
||||
const makeCertificatePdf = async () =>
|
||||
usePlaywrightPdf
|
||||
? getCertificatePdf({
|
||||
documentId,
|
||||
language: envelope.documentMeta.language,
|
||||
}).then(async (buffer) => PDFDocument.load(buffer))
|
||||
: generateCertificatePdf(certificatePayload);
|
||||
|
||||
const makeAuditLogPdf = async () =>
|
||||
usePlaywrightPdf
|
||||
? getAuditLogsPdf({
|
||||
documentId,
|
||||
language: envelope.documentMeta.language,
|
||||
}).then(async (buffer) => PDFDocument.load(buffer))
|
||||
: generateAuditLogPdf(certificatePayload);
|
||||
|
||||
const [createdCertificatePdf, createdAuditLogPdf] = await Promise.all([
|
||||
settings.includeSigningCertificate ? makeCertificatePdf() : null,
|
||||
settings.includeAuditLog ? makeAuditLogPdf() : null,
|
||||
]);
|
||||
|
||||
certificateDoc = createdCertificatePdf;
|
||||
auditLogDoc = createdAuditLogPdf;
|
||||
}
|
||||
|
||||
const newDocumentData: Array<{ oldDocumentDataId: string; newDocumentDataId: string }> = [];
|
||||
|
||||
@@ -203,8 +245,8 @@ export const run = async ({
|
||||
envelopeItemFields,
|
||||
isRejected,
|
||||
rejectionReason,
|
||||
certificateData,
|
||||
auditLogData,
|
||||
certificateDoc,
|
||||
auditLogDoc,
|
||||
});
|
||||
|
||||
newDocumentData.push(result);
|
||||
@@ -300,8 +342,8 @@ type DecorateAndSignPdfOptions = {
|
||||
envelopeItemFields: Field[];
|
||||
isRejected: boolean;
|
||||
rejectionReason: string;
|
||||
certificateData: Buffer | null;
|
||||
auditLogData: Buffer | null;
|
||||
certificateDoc: PDFDocument | null;
|
||||
auditLogDoc: PDFDocument | null;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -313,8 +355,8 @@ const decorateAndSignPdf = async ({
|
||||
envelopeItemFields,
|
||||
isRejected,
|
||||
rejectionReason,
|
||||
certificateData,
|
||||
auditLogData,
|
||||
certificateDoc,
|
||||
auditLogDoc,
|
||||
}: DecorateAndSignPdfOptions) => {
|
||||
const pdfData = await getFileServerSide(envelopeItem.documentData);
|
||||
|
||||
@@ -330,9 +372,7 @@ const decorateAndSignPdf = async ({
|
||||
await addRejectionStampToPdf(pdfDoc, rejectionReason);
|
||||
}
|
||||
|
||||
if (certificateData) {
|
||||
const certificateDoc = await PDFDocument.load(certificateData);
|
||||
|
||||
if (certificateDoc) {
|
||||
const certificatePages = await pdfDoc.copyPages(
|
||||
certificateDoc,
|
||||
certificateDoc.getPageIndices(),
|
||||
@@ -343,9 +383,7 @@ const decorateAndSignPdf = async ({
|
||||
});
|
||||
}
|
||||
|
||||
if (auditLogData) {
|
||||
const auditLogDoc = await PDFDocument.load(auditLogData);
|
||||
|
||||
if (auditLogDoc) {
|
||||
const auditLogPages = await pdfDoc.copyPages(auditLogDoc, auditLogDoc.getPageIndices());
|
||||
|
||||
auditLogPages.forEach((page) => {
|
||||
@@ -470,47 +508,3 @@ const decorateAndSignPdf = async ({
|
||||
newDocumentDataId: newDocumentData.id,
|
||||
};
|
||||
};
|
||||
|
||||
export const getCertificateAndAuditLogData = async ({
|
||||
legacyDocumentId,
|
||||
documentMeta,
|
||||
settings,
|
||||
}: {
|
||||
legacyDocumentId: number;
|
||||
documentMeta: DocumentMeta;
|
||||
settings: { includeSigningCertificate: boolean; includeAuditLog: boolean };
|
||||
}) => {
|
||||
const getCertificateDataPromise = settings.includeSigningCertificate
|
||||
? getCertificatePdf({
|
||||
documentId: legacyDocumentId,
|
||||
language: documentMeta.language,
|
||||
}).catch((e) => {
|
||||
console.log('Failed to get certificate PDF');
|
||||
console.error(e);
|
||||
|
||||
return null;
|
||||
})
|
||||
: null;
|
||||
|
||||
const getAuditLogDataPromise = settings.includeAuditLog
|
||||
? getAuditLogsPdf({
|
||||
documentId: legacyDocumentId,
|
||||
language: documentMeta.language,
|
||||
}).catch((e) => {
|
||||
console.log('Failed to get audit logs PDF');
|
||||
console.error(e);
|
||||
|
||||
return null;
|
||||
})
|
||||
: null;
|
||||
|
||||
const [certificateData, auditLogData] = await Promise.all([
|
||||
getCertificateDataPromise,
|
||||
getAuditLogDataPromise,
|
||||
]);
|
||||
|
||||
return {
|
||||
certificateData,
|
||||
auditLogData,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* @deprecated We use Konva to generate the audit logs PDF now.
|
||||
*/
|
||||
import { DateTime } from 'luxon';
|
||||
import type { Browser } from 'playwright';
|
||||
|
||||
@@ -33,7 +36,9 @@ export const getAuditLogsPdf = async ({ documentId, language }: GetAuditLogsPdfO
|
||||
// !: Previously we would have to keep the playwright version in sync with the browserless version to avoid errors.
|
||||
browser = await chromium.connectOverCDP(browserlessUrl);
|
||||
} else {
|
||||
browser = await chromium.launch();
|
||||
browser = await chromium.launch({
|
||||
executablePath: env('PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH') || undefined,
|
||||
});
|
||||
}
|
||||
|
||||
if (!browser) {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* @deprecated We use Konva to generate the certificate PDF now.
|
||||
*/
|
||||
import { DateTime } from 'luxon';
|
||||
import type { Browser } from 'playwright';
|
||||
|
||||
@@ -33,7 +36,9 @@ export const getCertificatePdf = async ({ documentId, language }: GetCertificate
|
||||
// !: Previously we would have to keep the playwright version in sync with the browserless version to avoid errors.
|
||||
browser = await chromium.connectOverCDP(browserlessUrl);
|
||||
} else {
|
||||
browser = await chromium.launch();
|
||||
browser = await chromium.launch({
|
||||
executablePath: env('PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH') || undefined,
|
||||
});
|
||||
}
|
||||
|
||||
if (!browser) {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { i18n } from '@lingui/core';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { ZSupportedLanguageCodeSchema } from '../../constants/i18n';
|
||||
import { parseDocumentAuditLogData } from '../../utils/document-audit-logs';
|
||||
import { getTranslations } from '../../utils/i18n';
|
||||
import { getOrganisationClaimByTeamId } from '../organisation/get-organisation-claims';
|
||||
import type { GenerateCertificatePdfOptions } from './generate-certificate-pdf';
|
||||
import { mergeFilesIntoPdf } from './generate-certificate-pdf';
|
||||
import { renderAuditLogs } from './render-audit-logs';
|
||||
|
||||
type GenerateAuditLogPdfOptions = GenerateCertificatePdfOptions & {
|
||||
envelopeItems: string[];
|
||||
};
|
||||
|
||||
export const generateAuditLogPdf = async (options: GenerateAuditLogPdfOptions) => {
|
||||
const { envelope, envelopeOwner, envelopeItems, recipients, language, pageWidth, pageHeight } =
|
||||
options;
|
||||
|
||||
const documentLanguage = ZSupportedLanguageCodeSchema.parse(language);
|
||||
|
||||
const [organisationClaim, auditLogs, messages] = await Promise.all([
|
||||
getOrganisationClaimByTeamId({ teamId: envelope.teamId }),
|
||||
getAuditLogs(envelope.id),
|
||||
getTranslations(documentLanguage),
|
||||
]);
|
||||
|
||||
i18n.loadAndActivate({
|
||||
locale: documentLanguage,
|
||||
messages,
|
||||
});
|
||||
|
||||
const auditLogPages = await renderAuditLogs({
|
||||
envelope,
|
||||
envelopeOwner,
|
||||
envelopeItems,
|
||||
recipients,
|
||||
auditLogs,
|
||||
hidePoweredBy: organisationClaim.flags.hidePoweredBy ?? false,
|
||||
pageWidth,
|
||||
pageHeight,
|
||||
i18n,
|
||||
});
|
||||
|
||||
return await mergeFilesIntoPdf(auditLogPages);
|
||||
};
|
||||
|
||||
const getAuditLogs = async (envelopeId: string) => {
|
||||
const auditLogs = await prisma.documentAuditLog.findMany({
|
||||
where: {
|
||||
envelopeId,
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'desc',
|
||||
},
|
||||
});
|
||||
|
||||
return auditLogs.map((auditLog) => parseDocumentAuditLogData(auditLog));
|
||||
};
|
||||
@@ -0,0 +1,160 @@
|
||||
import { PDFDocument } from '@cantoo/pdf-lib';
|
||||
import { i18n } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import type { DocumentMeta } from '@prisma/client';
|
||||
import type { Envelope, Field, Recipient, Signature } from '@prisma/client';
|
||||
import { FieldType } from '@prisma/client';
|
||||
import { prop, sortBy } from 'remeda';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { ZSupportedLanguageCodeSchema } from '../../constants/i18n';
|
||||
import type { TDocumentAuditLogBaseSchema } from '../../types/document-audit-logs';
|
||||
import { extractDocumentAuthMethods } from '../../utils/document-auth';
|
||||
import { getTranslations } from '../../utils/i18n';
|
||||
import { getDocumentCertificateAuditLogs } from '../document/get-document-certificate-audit-logs';
|
||||
import { getOrganisationClaimByTeamId } from '../organisation/get-organisation-claims';
|
||||
import { renderCertificate } from './render-certificate';
|
||||
|
||||
export type GenerateCertificatePdfOptions = {
|
||||
envelope: Envelope & {
|
||||
documentMeta: DocumentMeta;
|
||||
};
|
||||
envelopeOwner: {
|
||||
name: string;
|
||||
email: string;
|
||||
};
|
||||
recipients: Recipient[];
|
||||
fields: (Pick<Field, 'id' | 'type' | 'secondaryId' | 'recipientId'> & {
|
||||
signature?: Pick<Signature, 'signatureImageAsBase64' | 'typedSignature'> | null;
|
||||
})[];
|
||||
language?: string;
|
||||
pageWidth: number;
|
||||
pageHeight: number;
|
||||
};
|
||||
|
||||
export const generateCertificatePdf = async (options: GenerateCertificatePdfOptions) => {
|
||||
const { envelope, envelopeOwner, recipients, fields, language, pageWidth, pageHeight } = options;
|
||||
|
||||
const documentLanguage = ZSupportedLanguageCodeSchema.parse(language);
|
||||
|
||||
const [organisationClaim, auditLogs, messages] = await Promise.all([
|
||||
getOrganisationClaimByTeamId({ teamId: envelope.teamId }),
|
||||
getDocumentCertificateAuditLogs({
|
||||
envelopeId: envelope.id,
|
||||
}),
|
||||
getTranslations(documentLanguage),
|
||||
]);
|
||||
|
||||
i18n.loadAndActivate({
|
||||
locale: documentLanguage,
|
||||
messages,
|
||||
});
|
||||
|
||||
const payload = {
|
||||
recipients: recipients.map((recipient) => {
|
||||
const recipientId = recipient.id;
|
||||
|
||||
const signatureField = fields.find(
|
||||
(field) => field.recipientId === recipient.id && field.type === FieldType.SIGNATURE,
|
||||
);
|
||||
|
||||
const emailSent: TDocumentAuditLogBaseSchema | undefined = auditLogs['EMAIL_SENT'].find(
|
||||
(log) => log.type === 'EMAIL_SENT' && log.data.recipientId === recipientId,
|
||||
);
|
||||
|
||||
const documentSent: TDocumentAuditLogBaseSchema | undefined = auditLogs['DOCUMENT_SENT'].find(
|
||||
(log) => log.type === 'DOCUMENT_SENT',
|
||||
);
|
||||
|
||||
const documentOpened: TDocumentAuditLogBaseSchema | undefined = auditLogs[
|
||||
'DOCUMENT_OPENED'
|
||||
].find((log) => log.type === 'DOCUMENT_OPENED' && log.data.recipientId === recipientId);
|
||||
|
||||
const documentRecipientCompleted: TDocumentAuditLogBaseSchema | undefined = auditLogs[
|
||||
'DOCUMENT_RECIPIENT_COMPLETED'
|
||||
].find(
|
||||
(log) =>
|
||||
log.type === 'DOCUMENT_RECIPIENT_COMPLETED' && log.data.recipientId === recipientId,
|
||||
);
|
||||
|
||||
const documentRecipientRejected: TDocumentAuditLogBaseSchema | undefined = auditLogs[
|
||||
'DOCUMENT_RECIPIENT_REJECTED'
|
||||
].find(
|
||||
(log) => log.type === 'DOCUMENT_RECIPIENT_REJECTED' && log.data.recipientId === recipientId,
|
||||
);
|
||||
|
||||
const extractedAuthMethods = extractDocumentAuthMethods({
|
||||
documentAuth: envelope.authOptions,
|
||||
recipientAuth: recipient.authOptions,
|
||||
});
|
||||
|
||||
const insertedAuditLogsWithFieldAuth = sortBy(
|
||||
auditLogs.DOCUMENT_FIELD_INSERTED.filter(
|
||||
(log) => log.data.recipientId === recipient.id && log.data.fieldSecurity,
|
||||
),
|
||||
[prop('createdAt'), 'desc'],
|
||||
);
|
||||
|
||||
const actionAuthMethod = insertedAuditLogsWithFieldAuth.at(0)?.data?.fieldSecurity?.type;
|
||||
|
||||
let authLevel = match(actionAuthMethod)
|
||||
.with('ACCOUNT', () => i18n._(msg`Account Re-Authentication`))
|
||||
.with('TWO_FACTOR_AUTH', () => i18n._(msg`Two-Factor Re-Authentication`))
|
||||
.with('PASSWORD', () => i18n._(msg`Password Re-Authentication`))
|
||||
.with('PASSKEY', () => i18n._(msg`Passkey Re-Authentication`))
|
||||
.with('EXPLICIT_NONE', () => i18n._(msg`Email`))
|
||||
.with(undefined, () => null)
|
||||
.exhaustive();
|
||||
|
||||
if (!authLevel) {
|
||||
const accessAuthMethod = extractedAuthMethods.derivedRecipientAccessAuth.at(0);
|
||||
|
||||
authLevel = match(accessAuthMethod)
|
||||
.with('ACCOUNT', () => i18n._(msg`Account Authentication`))
|
||||
.with('TWO_FACTOR_AUTH', () => i18n._(msg`Two-Factor Authentication`))
|
||||
.with(undefined, () => i18n._(msg`Email`))
|
||||
.exhaustive();
|
||||
}
|
||||
|
||||
return {
|
||||
id: recipient.id,
|
||||
name: recipient.name,
|
||||
email: recipient.email,
|
||||
role: recipient.role,
|
||||
signingStatus: recipient.signingStatus,
|
||||
signatureField,
|
||||
rejectionReason: recipient.rejectionReason,
|
||||
authLevel,
|
||||
logs: {
|
||||
emailed: emailSent ?? null,
|
||||
sent: documentSent ?? null,
|
||||
opened: documentOpened ?? null,
|
||||
completed: documentRecipientCompleted ?? null,
|
||||
rejected: documentRecipientRejected ?? null,
|
||||
},
|
||||
};
|
||||
}),
|
||||
envelopeOwner,
|
||||
qrToken: envelope.qrToken,
|
||||
hidePoweredBy: organisationClaim.flags.hidePoweredBy ?? false,
|
||||
pageWidth,
|
||||
pageHeight,
|
||||
i18n,
|
||||
};
|
||||
|
||||
const certificatePages = await renderCertificate(payload);
|
||||
|
||||
return await mergeFilesIntoPdf(certificatePages);
|
||||
};
|
||||
|
||||
export async function mergeFilesIntoPdf(buffers: Uint8Array[]) {
|
||||
const mergedPdf = await PDFDocument.create();
|
||||
|
||||
for (const buffer of buffers) {
|
||||
const pdf = await PDFDocument.load(buffer);
|
||||
const pages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
|
||||
pages.forEach((p) => mergedPdf.addPage(p));
|
||||
}
|
||||
|
||||
return mergedPdf;
|
||||
}
|
||||
@@ -0,0 +1,721 @@
|
||||
import type { I18n } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import type { DocumentMeta } from '@prisma/client';
|
||||
import type { Envelope, RecipientRole } from '@prisma/client';
|
||||
import Konva from 'konva';
|
||||
import 'konva/skia-backend';
|
||||
import type { DateTimeFormatOptions } from 'luxon';
|
||||
import { DateTime } from 'luxon';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import type { Canvas } from 'skia-canvas';
|
||||
import { FontLibrary } from 'skia-canvas';
|
||||
import { Image as SkiaImage } from 'skia-canvas';
|
||||
import { match } from 'ts-pattern';
|
||||
import { P } from 'ts-pattern';
|
||||
import { UAParser } from 'ua-parser-js';
|
||||
|
||||
import { DOCUMENT_STATUS } from '../../constants/document';
|
||||
import { APP_I18N_OPTIONS } from '../../constants/i18n';
|
||||
import { RECIPIENT_ROLES_DESCRIPTION } from '../../constants/recipient-roles';
|
||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
||||
import type { TDocumentAuditLog } from '../../types/document-audit-logs';
|
||||
import { formatDocumentAuditLogAction } from '../../utils/document-audit-logs';
|
||||
|
||||
export type AuditLogRecipient = {
|
||||
id: number;
|
||||
name: string;
|
||||
email: string;
|
||||
role: RecipientRole;
|
||||
};
|
||||
|
||||
type GenerateAuditLogsOptions = {
|
||||
envelope: Envelope & {
|
||||
documentMeta: DocumentMeta;
|
||||
};
|
||||
envelopeItems: string[];
|
||||
recipients: AuditLogRecipient[];
|
||||
auditLogs: TDocumentAuditLog[];
|
||||
hidePoweredBy: boolean;
|
||||
pageWidth: number;
|
||||
pageHeight: number;
|
||||
i18n: I18n;
|
||||
envelopeOwner: {
|
||||
email: string;
|
||||
name: string;
|
||||
};
|
||||
};
|
||||
|
||||
const parser = new UAParser();
|
||||
|
||||
const textMutedForegroundLight = '#929DAE';
|
||||
const textForeground = '#000';
|
||||
const textMutedForeground = '#64748B';
|
||||
const textBase = 10;
|
||||
const textSm = 9;
|
||||
const textXs = 8;
|
||||
const fontMedium = '500';
|
||||
|
||||
const pageTopMargin = 60;
|
||||
const pageBottomMargin = 15;
|
||||
const contentMaxWidth = 768;
|
||||
const rowPadding = 10;
|
||||
const titleFontSize = 18;
|
||||
|
||||
type RenderOverviewCardLabelAndTextOptions = {
|
||||
label: string;
|
||||
text: string | string[];
|
||||
width: number;
|
||||
groupX?: number;
|
||||
};
|
||||
|
||||
const renderOverviewCardLabels = (options: RenderOverviewCardLabelAndTextOptions) => {
|
||||
const { width, text } = options;
|
||||
|
||||
const labelYSpacing = 4;
|
||||
|
||||
const group = new Konva.Group({
|
||||
x: options.groupX ?? 0,
|
||||
});
|
||||
|
||||
const label = new Konva.Text({
|
||||
x: 0,
|
||||
y: 0,
|
||||
text: options.label,
|
||||
fontStyle: fontMedium,
|
||||
fontFamily: 'Inter',
|
||||
fill: textForeground,
|
||||
fontSize: textSm,
|
||||
});
|
||||
|
||||
group.add(label);
|
||||
|
||||
if (typeof text === 'string') {
|
||||
const value = new Konva.Text({
|
||||
x: 0,
|
||||
y: label.height() + labelYSpacing,
|
||||
width: width - label.width(),
|
||||
fontFamily: 'Inter',
|
||||
text,
|
||||
fill: textForeground,
|
||||
wrap: 'char',
|
||||
fontSize: textSm,
|
||||
});
|
||||
|
||||
group.add(value);
|
||||
} else {
|
||||
for (const textValue of text) {
|
||||
const value = new Konva.Text({
|
||||
x: 0,
|
||||
y: group.getClientRect().height + 4,
|
||||
width: width - label.width(),
|
||||
fontFamily: 'Inter',
|
||||
text: '• ' + textValue,
|
||||
fill: textForeground,
|
||||
wrap: 'char',
|
||||
fontSize: textSm,
|
||||
});
|
||||
|
||||
group.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
return group;
|
||||
};
|
||||
|
||||
type RenderVerticalLabelAndTextOptions = {
|
||||
label: string;
|
||||
text: string;
|
||||
width?: number;
|
||||
align?: 'left' | 'right';
|
||||
x?: number;
|
||||
y?: number;
|
||||
textFontFamily?: string;
|
||||
};
|
||||
|
||||
const renderVerticalLabelAndText = (options: RenderVerticalLabelAndTextOptions) => {
|
||||
const { label, text, width, align, x, y, textFontFamily } = options;
|
||||
|
||||
const group = new Konva.Group({
|
||||
x: x ?? 0,
|
||||
y: y ?? 0,
|
||||
});
|
||||
|
||||
const konvaLabel = new Konva.Text({
|
||||
align: align ?? 'left',
|
||||
fontFamily: 'Inter',
|
||||
width,
|
||||
text: label,
|
||||
fontSize: textXs,
|
||||
fill: textMutedForegroundLight,
|
||||
});
|
||||
|
||||
group.add(konvaLabel);
|
||||
|
||||
const konvaText = new Konva.Text({
|
||||
y: group.getClientRect().height + 6,
|
||||
align: align ?? 'left',
|
||||
fontFamily: textFontFamily ?? 'Inter',
|
||||
width,
|
||||
text: text,
|
||||
fontSize: textXs,
|
||||
fill: textForeground,
|
||||
});
|
||||
|
||||
group.add(konvaText);
|
||||
|
||||
return group;
|
||||
};
|
||||
|
||||
type RenderOverviewCardOptions = {
|
||||
envelope: Envelope & {
|
||||
documentMeta: DocumentMeta;
|
||||
};
|
||||
envelopeItems: string[];
|
||||
envelopeOwner: {
|
||||
email: string;
|
||||
name: string;
|
||||
};
|
||||
recipients: AuditLogRecipient[];
|
||||
width: number;
|
||||
i18n: I18n;
|
||||
};
|
||||
|
||||
const renderOverviewCard = (options: RenderOverviewCardOptions) => {
|
||||
const { envelope, envelopeItems, envelopeOwner, recipients, width, i18n } = options;
|
||||
const cardPadding = 16;
|
||||
|
||||
const overviewCard = new Konva.Group();
|
||||
|
||||
const columnSpacing = 10;
|
||||
const columnWidth = (width - columnSpacing) / 2;
|
||||
const rowVerticalSpacing = 32;
|
||||
|
||||
const rowOne = new Konva.Group({
|
||||
x: cardPadding,
|
||||
y: cardPadding,
|
||||
});
|
||||
|
||||
const envelopeIdLabel = renderOverviewCardLabels({
|
||||
label: i18n._(msg`Envelope ID`),
|
||||
text: envelope.id,
|
||||
width: columnWidth,
|
||||
});
|
||||
const ownerLabel = renderOverviewCardLabels({
|
||||
label: i18n._(msg`Owner`),
|
||||
text: `${envelopeOwner.name} (${envelopeOwner.email})`,
|
||||
width: columnWidth,
|
||||
groupX: columnWidth + columnSpacing,
|
||||
});
|
||||
|
||||
rowOne.add(envelopeIdLabel);
|
||||
rowOne.add(ownerLabel);
|
||||
overviewCard.add(rowOne);
|
||||
|
||||
const rowTwo = new Konva.Group({
|
||||
x: cardPadding,
|
||||
y: overviewCard.getClientRect().height + rowVerticalSpacing,
|
||||
});
|
||||
|
||||
const statusLabel = renderOverviewCardLabels({
|
||||
label: i18n._(msg`Status`),
|
||||
text: i18n
|
||||
._(envelope.deletedAt ? msg`Deleted` : DOCUMENT_STATUS[envelope.status].description)
|
||||
.toUpperCase(),
|
||||
width: columnWidth,
|
||||
});
|
||||
const timeZoneLabel = renderOverviewCardLabels({
|
||||
label: i18n._(msg`Time Zone`),
|
||||
text: envelope.documentMeta?.timezone || 'N/A',
|
||||
width: columnWidth,
|
||||
groupX: columnWidth + columnSpacing,
|
||||
});
|
||||
|
||||
rowTwo.add(statusLabel);
|
||||
rowTwo.add(timeZoneLabel);
|
||||
overviewCard.add(rowTwo);
|
||||
|
||||
const rowThree = new Konva.Group({
|
||||
x: cardPadding,
|
||||
y: overviewCard.getClientRect().height + rowVerticalSpacing,
|
||||
});
|
||||
|
||||
const createdAtLabel = renderOverviewCardLabels({
|
||||
label: i18n._(msg`Created At`),
|
||||
text: DateTime.fromJSDate(envelope.createdAt)
|
||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)'),
|
||||
width: columnWidth,
|
||||
});
|
||||
const lastUpdatedLabel = renderOverviewCardLabels({
|
||||
label: i18n._(msg`Last Updated`),
|
||||
text: DateTime.fromJSDate(envelope.updatedAt)
|
||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)'),
|
||||
width: columnWidth,
|
||||
groupX: columnWidth + columnSpacing,
|
||||
});
|
||||
|
||||
rowThree.add(createdAtLabel);
|
||||
rowThree.add(lastUpdatedLabel);
|
||||
overviewCard.add(rowThree);
|
||||
|
||||
const rowFour = new Konva.Group({
|
||||
x: cardPadding,
|
||||
y: overviewCard.getClientRect().height + rowVerticalSpacing,
|
||||
});
|
||||
|
||||
const enclosedDocumentsLabel = renderOverviewCardLabels({
|
||||
label: i18n._(msg`Enclosed Documents`),
|
||||
text: envelopeItems,
|
||||
width: columnWidth,
|
||||
});
|
||||
|
||||
const recipientsLabel = renderOverviewCardLabels({
|
||||
label: i18n._(msg`Recipients`),
|
||||
text: recipients.map(
|
||||
(recipient) =>
|
||||
`[${i18n._(RECIPIENT_ROLES_DESCRIPTION[recipient.role].roleName)}] ${recipient.name} (${recipient.email})`,
|
||||
),
|
||||
width: columnWidth,
|
||||
groupX: columnWidth + columnSpacing,
|
||||
});
|
||||
|
||||
rowFour.add(enclosedDocumentsLabel);
|
||||
rowFour.add(recipientsLabel);
|
||||
overviewCard.add(rowFour);
|
||||
|
||||
// Create rect border around the overview card
|
||||
const cardRect = new Konva.Rect({
|
||||
x: 0,
|
||||
y: 0,
|
||||
width,
|
||||
height: overviewCard.getClientRect().height + cardPadding * 2,
|
||||
stroke: '#e5e7eb',
|
||||
strokeWidth: 1.5,
|
||||
cornerRadius: 8,
|
||||
});
|
||||
|
||||
overviewCard.add(cardRect);
|
||||
|
||||
return overviewCard;
|
||||
};
|
||||
|
||||
type RenderRowOptions = {
|
||||
auditLog: TDocumentAuditLog;
|
||||
width: number;
|
||||
i18n: I18n;
|
||||
};
|
||||
|
||||
const renderRow = (options: RenderRowOptions) => {
|
||||
const { auditLog, width, i18n } = options;
|
||||
|
||||
const paddingWithinCard = 12;
|
||||
|
||||
const columnSpacing = 10;
|
||||
const columnWidth = (width - paddingWithinCard * 2 - columnSpacing) / 2;
|
||||
|
||||
const indicatorWidth = 3;
|
||||
const indicatorPaddingRight = 10;
|
||||
const rowGroup = new Konva.Group();
|
||||
|
||||
const rowHeaderGroup = new Konva.Group();
|
||||
|
||||
const auditLogIndicatorColor = new Konva.Circle({
|
||||
x: indicatorWidth,
|
||||
y: indicatorWidth + 3,
|
||||
radius: indicatorWidth,
|
||||
fill: getAuditLogIndicatorColor(auditLog.type),
|
||||
});
|
||||
|
||||
const auditLogTypeText = new Konva.Text({
|
||||
x: indicatorWidth + indicatorPaddingRight,
|
||||
y: 0,
|
||||
width: columnWidth - indicatorWidth - indicatorPaddingRight,
|
||||
text: auditLog.type.replace(/_/g, ' '),
|
||||
fontFamily: 'Inter',
|
||||
fontSize: textSm,
|
||||
fontStyle: fontMedium,
|
||||
fill: textMutedForeground,
|
||||
});
|
||||
|
||||
const auditLogDescriptionText = new Konva.Text({
|
||||
x: indicatorWidth + indicatorPaddingRight,
|
||||
y: auditLogTypeText.height() + 4,
|
||||
width: columnWidth - indicatorWidth - indicatorPaddingRight,
|
||||
text: formatDocumentAuditLogAction(i18n, auditLog).description,
|
||||
fontFamily: 'Inter',
|
||||
fontSize: textSm,
|
||||
fill: textForeground,
|
||||
});
|
||||
|
||||
const auditLogTimestampText = new Konva.Text({
|
||||
x: columnWidth + columnSpacing,
|
||||
width: columnWidth,
|
||||
text: DateTime.fromJSDate(auditLog.createdAt)
|
||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||
.toLocaleString(dateFormat),
|
||||
fontFamily: 'Inter',
|
||||
align: 'right',
|
||||
fontSize: textSm,
|
||||
fill: textMutedForeground,
|
||||
});
|
||||
|
||||
rowHeaderGroup.add(auditLogIndicatorColor);
|
||||
rowHeaderGroup.add(auditLogTypeText);
|
||||
rowHeaderGroup.add(auditLogDescriptionText);
|
||||
rowHeaderGroup.add(auditLogTimestampText);
|
||||
|
||||
rowHeaderGroup.setAttrs({
|
||||
x: paddingWithinCard,
|
||||
y: paddingWithinCard,
|
||||
} satisfies Partial<Konva.GroupConfig>);
|
||||
|
||||
rowGroup.add(rowHeaderGroup);
|
||||
|
||||
// Draw border line.
|
||||
const borderLine = new Konva.Line({
|
||||
points: [0, 0, width - paddingWithinCard * 2, 0],
|
||||
stroke: '#e5e7eb',
|
||||
strokeWidth: 1,
|
||||
x: paddingWithinCard,
|
||||
y: rowGroup.getClientRect().height + paddingWithinCard + 12,
|
||||
});
|
||||
|
||||
rowGroup.add(borderLine);
|
||||
|
||||
const bottomSection = new Konva.Group({
|
||||
x: paddingWithinCard,
|
||||
y: rowGroup.getClientRect().height + paddingWithinCard + 12,
|
||||
});
|
||||
|
||||
// Row 1 Column 1
|
||||
const userLabel = renderVerticalLabelAndText({
|
||||
label: i18n._(msg`User`).toUpperCase(),
|
||||
text: auditLog.email || 'N/A',
|
||||
align: 'left',
|
||||
width: columnWidth,
|
||||
textFontFamily: 'ui-monospace',
|
||||
});
|
||||
|
||||
// Row 1 Column 2
|
||||
const ipAddressLabel = renderVerticalLabelAndText({
|
||||
label: i18n._(msg`IP Address`).toUpperCase(),
|
||||
text: auditLog.ipAddress || 'N/A',
|
||||
align: 'right',
|
||||
x: columnWidth + columnSpacing,
|
||||
width: columnWidth,
|
||||
textFontFamily: 'ui-monospace',
|
||||
});
|
||||
|
||||
bottomSection.add(userLabel);
|
||||
bottomSection.add(ipAddressLabel);
|
||||
|
||||
parser.setUA(auditLog.userAgent || '');
|
||||
const userAgentInfo = parser.getResult();
|
||||
|
||||
// Row 2 Column 1
|
||||
const userAgentLabel = renderVerticalLabelAndText({
|
||||
label: i18n._(msg`User Agent`).toUpperCase(),
|
||||
text: i18n._(formatUserAgent(auditLog.userAgent, userAgentInfo)),
|
||||
align: 'left',
|
||||
width,
|
||||
y: bottomSection.getClientRect().height + 16,
|
||||
});
|
||||
|
||||
bottomSection.add(userAgentLabel);
|
||||
rowGroup.add(bottomSection);
|
||||
|
||||
const cardRect = new Konva.Rect({
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: rowGroup.getClientRect().width,
|
||||
height: rowGroup.getClientRect().height + paddingWithinCard * 2,
|
||||
stroke: '#e5e7eb',
|
||||
strokeWidth: 1,
|
||||
cornerRadius: 8,
|
||||
});
|
||||
|
||||
rowGroup.add(cardRect);
|
||||
|
||||
return rowGroup;
|
||||
};
|
||||
|
||||
const renderBranding = () => {
|
||||
const branding = new Konva.Group();
|
||||
|
||||
const brandingHeight = 16;
|
||||
|
||||
const logoPath = path.join(process.cwd(), 'public/static/logo.png');
|
||||
const logo = fs.readFileSync(logoPath);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const img = new SkiaImage(logo) as unknown as HTMLImageElement;
|
||||
|
||||
const brandingImage = new Konva.Image({
|
||||
image: img,
|
||||
height: brandingHeight,
|
||||
width: brandingHeight * (img.width / img.height),
|
||||
});
|
||||
|
||||
branding.add(brandingImage);
|
||||
return branding;
|
||||
};
|
||||
|
||||
type GroupRowsIntoPagesOptions = {
|
||||
auditLogs: TDocumentAuditLog[];
|
||||
maxHeight: number;
|
||||
contentWidth: number;
|
||||
i18n: I18n;
|
||||
overviewCard: Konva.Group;
|
||||
};
|
||||
|
||||
const groupRowsIntoPages = (options: GroupRowsIntoPagesOptions) => {
|
||||
const { auditLogs, maxHeight, contentWidth, i18n, overviewCard } = options;
|
||||
|
||||
const groupedRows: Konva.Group[][] = [[]];
|
||||
|
||||
const overviewCardHeight = overviewCard.getClientRect().height;
|
||||
|
||||
// First page has title + overview card
|
||||
let availableHeight = maxHeight - pageTopMargin - overviewCardHeight;
|
||||
let currentGroupedRowIndex = 0;
|
||||
|
||||
// Group rows into pages.
|
||||
for (const auditLog of auditLogs) {
|
||||
const row = renderRow({ auditLog, width: contentWidth, i18n });
|
||||
|
||||
const rowHeight = row.getClientRect().height;
|
||||
const requiredHeight = rowHeight + rowPadding;
|
||||
|
||||
if (requiredHeight > availableHeight) {
|
||||
currentGroupedRowIndex++;
|
||||
groupedRows[currentGroupedRowIndex] = [row];
|
||||
|
||||
// Subsequent pages only have title (no overview card)
|
||||
availableHeight = maxHeight - pageTopMargin;
|
||||
} else {
|
||||
groupedRows[currentGroupedRowIndex].push(row);
|
||||
}
|
||||
|
||||
// Reduce available height by the row height.
|
||||
availableHeight -= requiredHeight;
|
||||
}
|
||||
|
||||
return groupedRows;
|
||||
};
|
||||
|
||||
type RenderPagesOptions = {
|
||||
groupedRows: Konva.Group[][];
|
||||
margin: number;
|
||||
pageTopMargin: number;
|
||||
i18n: I18n;
|
||||
overviewCard: Konva.Group;
|
||||
};
|
||||
|
||||
const renderPages = (options: RenderPagesOptions) => {
|
||||
const { groupedRows, margin, pageTopMargin, i18n, overviewCard } = options;
|
||||
|
||||
const rowPadding = 10;
|
||||
const pages: Konva.Group[] = [];
|
||||
|
||||
// Render the rows for each page.
|
||||
for (const [pageIndex, rows] of groupedRows.entries()) {
|
||||
const pageGroup = new Konva.Group();
|
||||
|
||||
// Add title to each page
|
||||
const pageTitle = new Konva.Text({
|
||||
x: margin,
|
||||
y: 0,
|
||||
height: pageTopMargin,
|
||||
verticalAlign: 'middle',
|
||||
text: i18n._(msg`Audit Log`),
|
||||
fill: textForeground,
|
||||
fontFamily: 'Inter',
|
||||
fontSize: titleFontSize,
|
||||
fontStyle: '700',
|
||||
});
|
||||
pageGroup.add(pageTitle);
|
||||
|
||||
// Add overview card only on first page
|
||||
if (pageIndex === 0) {
|
||||
overviewCard.setAttrs({
|
||||
x: margin,
|
||||
y: pageGroup.getClientRect().height,
|
||||
});
|
||||
pageGroup.add(overviewCard);
|
||||
}
|
||||
|
||||
// Add rows to the page
|
||||
for (const row of rows) {
|
||||
const yPosition = pageGroup.getClientRect().height + rowPadding;
|
||||
|
||||
row.setAttrs({
|
||||
x: margin,
|
||||
y: yPosition,
|
||||
});
|
||||
|
||||
pageGroup.add(row);
|
||||
}
|
||||
|
||||
pages.push(pageGroup);
|
||||
}
|
||||
|
||||
return pages;
|
||||
};
|
||||
|
||||
export async function renderAuditLogs({
|
||||
envelope,
|
||||
envelopeOwner,
|
||||
envelopeItems,
|
||||
recipients,
|
||||
auditLogs,
|
||||
pageWidth,
|
||||
pageHeight,
|
||||
i18n,
|
||||
hidePoweredBy,
|
||||
}: GenerateAuditLogsOptions) {
|
||||
const fontPath = path.join(process.cwd(), 'public/fonts');
|
||||
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
FontLibrary.use({
|
||||
['Caveat']: [path.join(fontPath, 'caveat.ttf')],
|
||||
['Inter']: [path.join(fontPath, 'inter-variablefont_opsz,wght.ttf')],
|
||||
});
|
||||
|
||||
const minimumMargin = 10;
|
||||
|
||||
const contentWidth = Math.min(pageWidth - minimumMargin * 2, contentMaxWidth);
|
||||
const margin = (pageWidth - contentWidth) / 2;
|
||||
|
||||
let stage: Konva.Stage | null = new Konva.Stage({ width: pageWidth, height: pageHeight });
|
||||
|
||||
const overviewCard = renderOverviewCard({
|
||||
envelope,
|
||||
envelopeOwner,
|
||||
envelopeItems,
|
||||
recipients,
|
||||
width: contentWidth,
|
||||
i18n,
|
||||
});
|
||||
|
||||
const groupedRows = groupRowsIntoPages({
|
||||
auditLogs,
|
||||
maxHeight: pageHeight,
|
||||
contentWidth,
|
||||
i18n,
|
||||
overviewCard,
|
||||
});
|
||||
|
||||
const pageGroups = renderPages({
|
||||
groupedRows,
|
||||
margin,
|
||||
pageTopMargin,
|
||||
i18n,
|
||||
overviewCard,
|
||||
});
|
||||
|
||||
const brandingGroup = renderBranding();
|
||||
const brandingRect = brandingGroup.getClientRect();
|
||||
const brandingTopPadding = 24;
|
||||
|
||||
const pages: Uint8Array[] = [];
|
||||
|
||||
let isBrandingPlaced = false;
|
||||
|
||||
// Render each page group to PDF
|
||||
for (const [index, pageGroup] of pageGroups.entries()) {
|
||||
stage.destroyChildren();
|
||||
const page = new Konva.Layer();
|
||||
|
||||
page.add(pageGroup);
|
||||
|
||||
// Add branding on the last page if there is space.
|
||||
if (index === pageGroups.length - 1 && !hidePoweredBy) {
|
||||
const remainingHeight = pageHeight - pageGroup.getClientRect().height - pageBottomMargin;
|
||||
|
||||
if (brandingRect.height + brandingTopPadding <= remainingHeight) {
|
||||
brandingGroup.setAttrs({
|
||||
x: pageWidth - brandingRect.width - margin,
|
||||
y: pageGroup.getClientRect().height + brandingTopPadding,
|
||||
} satisfies Partial<Konva.GroupConfig>);
|
||||
|
||||
page.add(brandingGroup);
|
||||
isBrandingPlaced = true;
|
||||
}
|
||||
}
|
||||
|
||||
stage.add(page);
|
||||
|
||||
// Export the page and save it.
|
||||
const canvas = page.canvas._canvas as unknown as Canvas; // eslint-disable-line @typescript-eslint/consistent-type-assertions
|
||||
const buffer = await canvas.toBuffer('pdf');
|
||||
pages.push(new Uint8Array(buffer));
|
||||
}
|
||||
|
||||
// Need to create an empty page for the branding if it hasn't been placed yet.
|
||||
if (!hidePoweredBy && !isBrandingPlaced) {
|
||||
stage.destroyChildren();
|
||||
const page = new Konva.Layer();
|
||||
|
||||
brandingGroup.setAttrs({
|
||||
x: pageWidth - brandingRect.width - margin,
|
||||
y: pageTopMargin,
|
||||
} satisfies Partial<Konva.GroupConfig>);
|
||||
|
||||
page.add(brandingGroup);
|
||||
stage.add(page);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const canvas = page.canvas._canvas as unknown as Canvas;
|
||||
const buffer = await canvas.toBuffer('pdf');
|
||||
|
||||
pages.push(new Uint8Array(buffer));
|
||||
}
|
||||
|
||||
stage.destroy();
|
||||
stage = null;
|
||||
|
||||
return pages;
|
||||
}
|
||||
|
||||
const dateFormat: DateTimeFormatOptions = {
|
||||
...DateTime.DATETIME_SHORT,
|
||||
hourCycle: 'h12',
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the color indicator for the audit log type
|
||||
*/
|
||||
const getAuditLogIndicatorColor = (type: string) =>
|
||||
match(type)
|
||||
.with(DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED, () => '#22c55e') // bg-green-500
|
||||
.with(DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_REJECTED, () => '#ef4444') // bg-red-500
|
||||
.with(DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_SENT, () => '#f97316') // bg-orange-500
|
||||
.with(
|
||||
P.union(
|
||||
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_INSERTED,
|
||||
DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_FIELD_UNINSERTED,
|
||||
),
|
||||
() => '#3b82f6', // bg-blue-500
|
||||
)
|
||||
.otherwise(() => '#f1f5f9'); // bg-muted
|
||||
|
||||
const formatUserAgent = (userAgent: string | null | undefined, userAgentInfo: UAParser.IResult) => {
|
||||
if (!userAgent) {
|
||||
return msg`N/A`;
|
||||
}
|
||||
|
||||
const browser = userAgentInfo.browser.name;
|
||||
const version = userAgentInfo.browser.version;
|
||||
const os = userAgentInfo.os.name;
|
||||
|
||||
// If we can parse meaningful browser info, format it nicely
|
||||
if (browser && os) {
|
||||
const browserInfo = version ? `${browser} ${version}` : browser;
|
||||
|
||||
return msg`${browserInfo} on ${os}`;
|
||||
}
|
||||
|
||||
return msg`${userAgent}`;
|
||||
};
|
||||
@@ -0,0 +1,819 @@
|
||||
import type { I18n } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import type { Field, Signature } from '@prisma/client';
|
||||
import { SigningStatus } from '@prisma/client';
|
||||
import type { RecipientRole } from '@prisma/client';
|
||||
import Konva from 'konva';
|
||||
import 'konva/skia-backend';
|
||||
import { DateTime } from 'luxon';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import type { Canvas } from 'skia-canvas';
|
||||
import { FontLibrary } from 'skia-canvas';
|
||||
import { Image as SkiaImage } from 'skia-canvas';
|
||||
import { UAParser } from 'ua-parser-js';
|
||||
import { renderSVG } from 'uqr';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app';
|
||||
import { APP_I18N_OPTIONS } from '../../constants/i18n';
|
||||
import {
|
||||
RECIPIENT_ROLES_DESCRIPTION,
|
||||
RECIPIENT_ROLE_SIGNING_REASONS,
|
||||
} from '../../constants/recipient-roles';
|
||||
import type { TDocumentAuditLogBaseSchema } from '../../types/document-audit-logs';
|
||||
import { svgToPng } from '../../utils/images/svg-to-png';
|
||||
|
||||
type ColumnWidths = [number, number, number];
|
||||
|
||||
type BaseAuditLog = Pick<TDocumentAuditLogBaseSchema, 'createdAt' | 'ipAddress' | 'userAgent'>;
|
||||
|
||||
export type CertificateRecipient = {
|
||||
id: number;
|
||||
name: string;
|
||||
email: string;
|
||||
role: RecipientRole;
|
||||
rejectionReason: string | null;
|
||||
signingStatus: SigningStatus;
|
||||
signatureField?: Pick<Field, 'id' | 'secondaryId' | 'recipientId'> & {
|
||||
signature?: Pick<Signature, 'signatureImageAsBase64' | 'typedSignature'> | null;
|
||||
};
|
||||
authLevel: string;
|
||||
logs: {
|
||||
emailed: BaseAuditLog | null;
|
||||
sent: BaseAuditLog | null;
|
||||
opened: BaseAuditLog | null;
|
||||
completed: BaseAuditLog | null;
|
||||
rejected: BaseAuditLog | null;
|
||||
};
|
||||
};
|
||||
|
||||
type GenerateCertificateOptions = {
|
||||
recipients: CertificateRecipient[];
|
||||
qrToken: string | null;
|
||||
hidePoweredBy: boolean;
|
||||
i18n: I18n;
|
||||
envelopeOwner: {
|
||||
name: string;
|
||||
email: string;
|
||||
};
|
||||
pageWidth: number;
|
||||
pageHeight: number;
|
||||
};
|
||||
|
||||
// Helper function to get device info from user agent
|
||||
const getDevice = (userAgent?: string | null): string => {
|
||||
if (!userAgent) {
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
const parser = new UAParser(userAgent);
|
||||
|
||||
parser.setUA(userAgent);
|
||||
|
||||
const result = parser.getResult();
|
||||
|
||||
return `${result.os.name} - ${result.browser.name} ${result.browser.version}`;
|
||||
};
|
||||
|
||||
const textMutedForegroundLight = '#929DAE';
|
||||
const textForeground = '#000';
|
||||
const textMutedForeground = '#64748B';
|
||||
const textBase = 10;
|
||||
const textSm = 9;
|
||||
const textXs = 8;
|
||||
const fontMedium = '500';
|
||||
|
||||
const columnWidthPercentages = [30, 30, 40];
|
||||
const rowPadding = 12;
|
||||
const tableHeaderHeight = 38;
|
||||
const pageTopMargin = 72;
|
||||
const pageBottomMargin = 12;
|
||||
const contentMaxWidth = 768;
|
||||
|
||||
const titleFontSize = 18;
|
||||
|
||||
type RenderLabelAndTextOptions = {
|
||||
label: string;
|
||||
text: string;
|
||||
width: number;
|
||||
y?: number;
|
||||
};
|
||||
|
||||
const renderLabelAndText = (options: RenderLabelAndTextOptions) => {
|
||||
const { width, y } = options;
|
||||
|
||||
const group = new Konva.Group({
|
||||
y,
|
||||
});
|
||||
|
||||
const label = new Konva.Text({
|
||||
x: 0,
|
||||
y: 0,
|
||||
text: `${options.label}: `,
|
||||
fontStyle: fontMedium,
|
||||
fontFamily: 'Inter',
|
||||
fill: textMutedForeground,
|
||||
fontSize: textSm,
|
||||
});
|
||||
|
||||
group.add(label);
|
||||
|
||||
const value = new Konva.Text({
|
||||
x: label.width(),
|
||||
y: 0,
|
||||
width: width - label.width(),
|
||||
fontFamily: 'Inter',
|
||||
text: options.text,
|
||||
fill: textMutedForeground,
|
||||
wrap: 'char',
|
||||
fontSize: textSm,
|
||||
});
|
||||
|
||||
group.add(value);
|
||||
|
||||
return group;
|
||||
};
|
||||
|
||||
type RenderRowHeaderOptions = {
|
||||
columnWidths: number[];
|
||||
i18n: I18n;
|
||||
};
|
||||
|
||||
const renderRowHeader = (options: RenderRowHeaderOptions) => {
|
||||
const { columnWidths, i18n } = options;
|
||||
|
||||
const columnOneWidth = columnWidths[0];
|
||||
const columnTwoWidth = columnWidths[1];
|
||||
const columnThreeWidth = columnWidths[2];
|
||||
|
||||
const headerRow = new Konva.Group();
|
||||
|
||||
const headerFontStyling = {
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 11,
|
||||
fontStyle: fontMedium,
|
||||
verticalAlign: 'middle',
|
||||
fill: textMutedForeground,
|
||||
height: tableHeaderHeight,
|
||||
};
|
||||
|
||||
const header1 = new Konva.Text({
|
||||
x: rowPadding,
|
||||
width: columnOneWidth,
|
||||
text: i18n._(msg`Signer Events`),
|
||||
...headerFontStyling,
|
||||
});
|
||||
headerRow.add(header1);
|
||||
|
||||
const header2 = new Konva.Text({
|
||||
x: columnOneWidth + rowPadding,
|
||||
width: columnTwoWidth,
|
||||
text: i18n._(msg`Signature`),
|
||||
...headerFontStyling,
|
||||
});
|
||||
headerRow.add(header2);
|
||||
|
||||
const header3 = new Konva.Text({
|
||||
x: columnOneWidth + columnTwoWidth + rowPadding,
|
||||
width: columnThreeWidth,
|
||||
text: i18n._(msg`Details`),
|
||||
...headerFontStyling,
|
||||
});
|
||||
headerRow.add(header3);
|
||||
|
||||
return headerRow;
|
||||
};
|
||||
|
||||
const columnPadding = 10;
|
||||
|
||||
type RenderColumnOptions = {
|
||||
recipient: CertificateRecipient;
|
||||
width: number;
|
||||
i18n: I18n;
|
||||
envelopeOwner: {
|
||||
name: string;
|
||||
email: string;
|
||||
};
|
||||
};
|
||||
|
||||
const renderColumnOne = (options: RenderColumnOptions) => {
|
||||
const { recipient, width, i18n } = options;
|
||||
|
||||
const columnGroup = new Konva.Group();
|
||||
|
||||
const textSectionPadding = 8;
|
||||
|
||||
const textFontStyling = {
|
||||
x: 0,
|
||||
fontFamily: 'Inter',
|
||||
wrap: 'char',
|
||||
lineHeight: 1.2,
|
||||
fill: textMutedForeground,
|
||||
width: width - columnPadding,
|
||||
};
|
||||
|
||||
if (recipient.name) {
|
||||
const nameText = new Konva.Text({
|
||||
y: 0,
|
||||
text: recipient.name,
|
||||
fontSize: textBase,
|
||||
...textFontStyling,
|
||||
fontStyle: fontMedium,
|
||||
});
|
||||
|
||||
columnGroup.add(nameText);
|
||||
}
|
||||
|
||||
const emailText = new Konva.Text({
|
||||
y: columnGroup.getClientRect().height,
|
||||
text: recipient.email,
|
||||
fontSize: textBase,
|
||||
...textFontStyling,
|
||||
});
|
||||
|
||||
columnGroup.add(emailText);
|
||||
|
||||
const roleText = new Konva.Text({
|
||||
y: columnGroup.getClientRect().height + textSectionPadding,
|
||||
text: i18n._(RECIPIENT_ROLES_DESCRIPTION[recipient.role].roleName),
|
||||
fontSize: textSm,
|
||||
...textFontStyling,
|
||||
});
|
||||
columnGroup.add(roleText);
|
||||
|
||||
const authLabel = new Konva.Text({
|
||||
y: columnGroup.getClientRect().height + textSectionPadding,
|
||||
text: `${i18n._(msg`Authentication Level`)}:`,
|
||||
fontSize: textSm,
|
||||
fontStyle: fontMedium,
|
||||
...textFontStyling,
|
||||
});
|
||||
columnGroup.add(authLabel);
|
||||
|
||||
const authValue = new Konva.Text({
|
||||
y: columnGroup.getClientRect().height,
|
||||
text: recipient.authLevel,
|
||||
fontSize: textSm,
|
||||
...textFontStyling,
|
||||
});
|
||||
columnGroup.add(authValue);
|
||||
|
||||
return columnGroup;
|
||||
};
|
||||
|
||||
const renderColumnTwo = (options: RenderColumnOptions) => {
|
||||
const { recipient, width, i18n } = options;
|
||||
|
||||
// Column 2: Signature
|
||||
const column = new Konva.Group();
|
||||
|
||||
const columnWidth = width - columnPadding;
|
||||
|
||||
if (recipient.signatureField?.secondaryId) {
|
||||
// Signature container with green border
|
||||
const signatureContainer = new Konva.Group({ x: 0, y: 0 });
|
||||
|
||||
const minSignatureHeight = 40;
|
||||
const maxSignatureWidth = 100;
|
||||
|
||||
// Signature content
|
||||
if (recipient.signatureField?.signature?.signatureImageAsBase64) {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const img = new SkiaImage(
|
||||
recipient.signatureField?.signature?.signatureImageAsBase64,
|
||||
) as unknown as HTMLImageElement;
|
||||
|
||||
const signatureImage = new Konva.Image({
|
||||
image: img,
|
||||
x: 4,
|
||||
y: 4,
|
||||
width: maxSignatureWidth,
|
||||
height: maxSignatureWidth * (img.height / img.width),
|
||||
});
|
||||
|
||||
signatureContainer.add(signatureImage);
|
||||
} else if (recipient.signatureField?.signature?.typedSignature) {
|
||||
const typedSig = new Konva.Text({
|
||||
x: 2,
|
||||
text: recipient.signatureField?.signature?.typedSignature,
|
||||
padding: 4,
|
||||
fontFamily: 'Caveat',
|
||||
fontSize: 16,
|
||||
align: 'center',
|
||||
verticalAlign: 'middle',
|
||||
width: maxSignatureWidth,
|
||||
});
|
||||
|
||||
if (typedSig.getClientRect().height < minSignatureHeight) {
|
||||
typedSig.setAttrs({
|
||||
height: minSignatureHeight,
|
||||
});
|
||||
}
|
||||
|
||||
signatureContainer.add(typedSig);
|
||||
}
|
||||
|
||||
column.add(signatureContainer);
|
||||
|
||||
const signatureHeight = Math.max(signatureContainer.getClientRect().height, minSignatureHeight);
|
||||
|
||||
const signatureBorder = new Konva.Rect({
|
||||
x: 2,
|
||||
y: 2,
|
||||
width: maxSignatureWidth,
|
||||
height: signatureHeight,
|
||||
stroke: 'rgba(122, 196, 85, 0.6)',
|
||||
strokeWidth: 1,
|
||||
cornerRadius: 8,
|
||||
});
|
||||
signatureContainer.add(signatureBorder);
|
||||
|
||||
const signatureShadow = new Konva.Rect({
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: maxSignatureWidth + 4,
|
||||
height: signatureHeight + 4,
|
||||
stroke: 'rgba(122, 196, 85, 0.1)',
|
||||
strokeWidth: 4,
|
||||
cornerRadius: 8,
|
||||
});
|
||||
signatureContainer.add(signatureShadow);
|
||||
|
||||
// Signature ID
|
||||
const sigIdLabel = new Konva.Text({
|
||||
x: 0,
|
||||
y: signatureHeight + 10,
|
||||
text: `${i18n._(msg`Signature ID`)}:`,
|
||||
fill: textMutedForeground,
|
||||
width: columnWidth,
|
||||
fontFamily: 'Inter',
|
||||
fontSize: textSm,
|
||||
fontStyle: fontMedium,
|
||||
lineHeight: 1.4,
|
||||
});
|
||||
column.add(sigIdLabel);
|
||||
|
||||
const sigIdValue = new Konva.Text({
|
||||
x: 0,
|
||||
y: column.getClientRect().height,
|
||||
text: recipient.signatureField.secondaryId.toUpperCase(),
|
||||
fill: textMutedForeground,
|
||||
fontFamily: 'monospace',
|
||||
fontSize: textSm,
|
||||
width: columnWidth,
|
||||
wrap: 'char',
|
||||
});
|
||||
column.add(sigIdValue);
|
||||
} else {
|
||||
const naText = new Konva.Text({
|
||||
x: 0,
|
||||
y: 0,
|
||||
text: 'N/A',
|
||||
fill: textMutedForeground,
|
||||
fontFamily: 'Inter',
|
||||
fontSize: textSm,
|
||||
});
|
||||
column.add(naText);
|
||||
}
|
||||
|
||||
const ipLabelAndText = renderLabelAndText({
|
||||
label: i18n._(msg`IP Address`),
|
||||
text: recipient.logs.completed?.ipAddress ?? i18n._(msg`Unknown`),
|
||||
width,
|
||||
y: column.getClientRect().height + 6,
|
||||
});
|
||||
column.add(ipLabelAndText);
|
||||
|
||||
const deviceLabelAndText = renderLabelAndText({
|
||||
label: i18n._(msg`Device`),
|
||||
text: getDevice(recipient.logs.completed?.userAgent),
|
||||
width,
|
||||
y: column.getClientRect().height + 6,
|
||||
});
|
||||
column.add(deviceLabelAndText);
|
||||
|
||||
return column;
|
||||
};
|
||||
|
||||
const renderColumnThree = (options: RenderColumnOptions) => {
|
||||
const { recipient, width, i18n, envelopeOwner } = options;
|
||||
|
||||
const column = new Konva.Group();
|
||||
|
||||
const itemsToRender = [
|
||||
{
|
||||
label: i18n._(msg`Sent`),
|
||||
value: recipient.logs.emailed
|
||||
? DateTime.fromJSDate(recipient.logs.emailed.createdAt)
|
||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)')
|
||||
: recipient.logs.sent
|
||||
? DateTime.fromJSDate(recipient.logs.sent.createdAt)
|
||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)')
|
||||
: i18n._(msg`Unknown`),
|
||||
},
|
||||
{
|
||||
label: i18n._(msg`Viewed`),
|
||||
value: recipient.logs.opened
|
||||
? DateTime.fromJSDate(recipient.logs.opened.createdAt)
|
||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)')
|
||||
: i18n._(msg`Unknown`),
|
||||
},
|
||||
];
|
||||
|
||||
if (recipient.logs.rejected) {
|
||||
itemsToRender.push({
|
||||
label: i18n._(msg`Rejected`),
|
||||
value: DateTime.fromJSDate(recipient.logs.rejected.createdAt)
|
||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)'),
|
||||
});
|
||||
} else {
|
||||
itemsToRender.push({
|
||||
label: i18n._(msg`Signed`),
|
||||
value: recipient.logs.completed
|
||||
? DateTime.fromJSDate(recipient.logs.completed.createdAt)
|
||||
.setLocale(APP_I18N_OPTIONS.defaultLocale)
|
||||
.toFormat('yyyy-MM-dd hh:mm:ss a (ZZZZ)')
|
||||
: i18n._(msg`Unknown`),
|
||||
});
|
||||
}
|
||||
|
||||
const isOwner = recipient.email.toLowerCase() === envelopeOwner.email.toLowerCase();
|
||||
|
||||
itemsToRender.push({
|
||||
label: i18n._(msg`Reason`),
|
||||
value:
|
||||
recipient.signingStatus === SigningStatus.REJECTED
|
||||
? recipient.rejectionReason || ''
|
||||
: isOwner
|
||||
? i18n._(msg`I am the owner of this document`)
|
||||
: i18n._(RECIPIENT_ROLE_SIGNING_REASONS[recipient.role]),
|
||||
});
|
||||
|
||||
for (const [index, item] of itemsToRender.entries()) {
|
||||
const labelAndText = renderLabelAndText({
|
||||
label: item.label,
|
||||
text: item.value,
|
||||
width,
|
||||
y: column.getClientRect().height + (index === 0 ? 0 : 8),
|
||||
});
|
||||
column.add(labelAndText);
|
||||
}
|
||||
|
||||
return column;
|
||||
};
|
||||
|
||||
type RenderRowOptions = {
|
||||
recipient: CertificateRecipient;
|
||||
columnWidths: ColumnWidths;
|
||||
i18n: I18n;
|
||||
envelopeOwner: {
|
||||
name: string;
|
||||
email: string;
|
||||
};
|
||||
};
|
||||
|
||||
const renderRow = (options: RenderRowOptions) => {
|
||||
const { recipient, columnWidths, i18n, envelopeOwner } = options;
|
||||
|
||||
const rowGroup = new Konva.Group();
|
||||
|
||||
const width = columnWidths[0] + columnWidths[1] + columnWidths[2];
|
||||
|
||||
// Draw top border line.
|
||||
const borderLine = new Konva.Line({
|
||||
points: [0, 0, width + rowPadding * 2, 0],
|
||||
stroke: '#e5e7eb',
|
||||
strokeWidth: 1,
|
||||
});
|
||||
|
||||
rowGroup.add(borderLine);
|
||||
|
||||
// Column 1: Signer Events
|
||||
const columnGroup = renderColumnOne({
|
||||
recipient,
|
||||
width: columnWidths[0],
|
||||
i18n,
|
||||
envelopeOwner,
|
||||
});
|
||||
columnGroup.setAttrs({
|
||||
x: rowPadding,
|
||||
y: rowPadding,
|
||||
} satisfies Partial<Konva.GroupConfig>);
|
||||
rowGroup.add(columnGroup);
|
||||
|
||||
const columnTwoGroup = renderColumnTwo({
|
||||
recipient,
|
||||
width: columnWidths[1],
|
||||
i18n,
|
||||
envelopeOwner,
|
||||
});
|
||||
columnTwoGroup.setAttrs({
|
||||
x: rowPadding + columnWidths[0],
|
||||
y: rowPadding,
|
||||
} satisfies Partial<Konva.GroupConfig>);
|
||||
rowGroup.add(columnTwoGroup);
|
||||
|
||||
// Column 3: Details
|
||||
const columnThreeGroup = renderColumnThree({
|
||||
recipient,
|
||||
width: columnWidths[2],
|
||||
i18n,
|
||||
envelopeOwner,
|
||||
});
|
||||
columnThreeGroup.setAttrs({
|
||||
x: rowPadding + columnWidths[0] + columnWidths[1],
|
||||
y: rowPadding,
|
||||
} satisfies Partial<Konva.GroupConfig>);
|
||||
rowGroup.add(columnThreeGroup);
|
||||
|
||||
const rowBottomPadding = new Konva.Rect({
|
||||
x: 0,
|
||||
y: rowGroup.getClientRect().height,
|
||||
width: rowGroup.getClientRect().width,
|
||||
height: rowPadding,
|
||||
});
|
||||
rowGroup.add(rowBottomPadding);
|
||||
|
||||
return rowGroup;
|
||||
};
|
||||
|
||||
const renderBranding = async ({ qrToken, i18n }: { qrToken: string | null; i18n: I18n }) => {
|
||||
const branding = new Konva.Group();
|
||||
|
||||
const brandingHeight = 12;
|
||||
|
||||
const text = new Konva.Text({
|
||||
x: 0,
|
||||
verticalAlign: 'middle',
|
||||
text: i18n._(msg`Signing certificate provided by`) + ':',
|
||||
fontStyle: fontMedium,
|
||||
fontFamily: 'Inter',
|
||||
fontSize: textSm,
|
||||
height: brandingHeight,
|
||||
});
|
||||
|
||||
const logoPath = path.join(process.cwd(), 'public/static/logo.png');
|
||||
const logo = fs.readFileSync(logoPath);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const img = new SkiaImage(logo) as unknown as HTMLImageElement;
|
||||
|
||||
const documensoImage = new Konva.Image({
|
||||
image: img,
|
||||
height: brandingHeight,
|
||||
width: brandingHeight * (img.width / img.height),
|
||||
x: text.width() + 16,
|
||||
});
|
||||
|
||||
const qrSize = qrToken ? 72 : 0;
|
||||
|
||||
const logoGroup = new Konva.Group({
|
||||
y: qrSize + 16,
|
||||
});
|
||||
logoGroup.add(text);
|
||||
logoGroup.add(documensoImage);
|
||||
|
||||
branding.add(logoGroup);
|
||||
|
||||
if (qrToken) {
|
||||
const qrSvg = renderSVG(`${NEXT_PUBLIC_WEBAPP_URL()}/share/${qrToken}`, {
|
||||
ecc: 'Q',
|
||||
});
|
||||
|
||||
const svgImage = await svgToPng(qrSvg);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const qrSkiaImage = new SkiaImage(svgImage) as unknown as HTMLImageElement;
|
||||
const qrImage = new Konva.Image({
|
||||
image: qrSkiaImage,
|
||||
height: qrSize,
|
||||
width: qrSize,
|
||||
x: branding.getClientRect().width - qrSize,
|
||||
y: 0,
|
||||
});
|
||||
|
||||
branding.add(qrImage);
|
||||
}
|
||||
|
||||
return branding;
|
||||
};
|
||||
|
||||
type GroupRowsIntoPagesOptions = {
|
||||
recipients: CertificateRecipient[];
|
||||
maxHeight: number;
|
||||
i18n: I18n;
|
||||
columnWidths: ColumnWidths;
|
||||
envelopeOwner: {
|
||||
name: string;
|
||||
email: string;
|
||||
};
|
||||
};
|
||||
|
||||
const groupRowsIntoPages = (options: GroupRowsIntoPagesOptions) => {
|
||||
const { recipients, maxHeight, i18n, columnWidths, envelopeOwner } = options;
|
||||
|
||||
const rowHeader = renderRowHeader({ columnWidths, i18n });
|
||||
const rowHeaderHeight = rowHeader.getClientRect().height;
|
||||
|
||||
const groupedRows: Konva.Group[][] = [[]];
|
||||
|
||||
let availablePageHeight = maxHeight - rowHeaderHeight;
|
||||
let currentGroupedRowIndex = 0;
|
||||
|
||||
// Group rows into pages.
|
||||
for (const recipient of recipients) {
|
||||
const row = renderRow({ recipient, columnWidths, i18n, envelopeOwner });
|
||||
|
||||
const rowHeight = row.getClientRect().height;
|
||||
|
||||
if (rowHeight > availablePageHeight) {
|
||||
currentGroupedRowIndex++;
|
||||
groupedRows[currentGroupedRowIndex] = [row];
|
||||
availablePageHeight = maxHeight - rowHeaderHeight;
|
||||
} else {
|
||||
groupedRows[currentGroupedRowIndex].push(row);
|
||||
}
|
||||
|
||||
// Reduce available height by the row height.
|
||||
availablePageHeight -= rowHeight;
|
||||
}
|
||||
|
||||
return groupedRows;
|
||||
};
|
||||
|
||||
type RenderTablesOptions = {
|
||||
groupedRows: Konva.Group[][];
|
||||
columnWidths: ColumnWidths;
|
||||
i18n: I18n;
|
||||
};
|
||||
|
||||
const renderTables = (options: RenderTablesOptions) => {
|
||||
const { groupedRows, columnWidths, i18n } = options;
|
||||
|
||||
const tables: Konva.Group[] = [];
|
||||
|
||||
// Render the rows for each page.
|
||||
for (const rows of groupedRows) {
|
||||
const table = new Konva.Group();
|
||||
const tableHeader = renderRowHeader({ columnWidths, i18n });
|
||||
|
||||
table.add(tableHeader);
|
||||
|
||||
for (const row of rows) {
|
||||
row.setAttrs({
|
||||
x: 0,
|
||||
y: table.getClientRect().height,
|
||||
} satisfies Partial<Konva.GroupConfig>);
|
||||
|
||||
table.add(row);
|
||||
}
|
||||
|
||||
// Add table background and border.
|
||||
const tableClientRect = table.getClientRect();
|
||||
const cardRect = new Konva.Rect({
|
||||
x: tableClientRect.x,
|
||||
y: tableClientRect.y,
|
||||
width: tableClientRect.width,
|
||||
height: tableClientRect.height,
|
||||
stroke: '#e5e7eb',
|
||||
strokeWidth: 1.5,
|
||||
cornerRadius: 8,
|
||||
});
|
||||
table.add(cardRect);
|
||||
|
||||
tables.push(table);
|
||||
}
|
||||
|
||||
return tables;
|
||||
};
|
||||
|
||||
export async function renderCertificate({
|
||||
recipients,
|
||||
qrToken,
|
||||
hidePoweredBy,
|
||||
i18n,
|
||||
envelopeOwner,
|
||||
pageWidth,
|
||||
pageHeight,
|
||||
}: GenerateCertificateOptions) {
|
||||
const fontPath = path.join(process.cwd(), 'public/fonts');
|
||||
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
FontLibrary.use({
|
||||
['Caveat']: [path.join(fontPath, 'caveat.ttf')],
|
||||
['Inter']: [path.join(fontPath, 'inter-variablefont_opsz,wght.ttf')],
|
||||
});
|
||||
|
||||
const minimumMargin = 10;
|
||||
|
||||
const tableWidth = Math.min(pageWidth - minimumMargin * 2, contentMaxWidth);
|
||||
const tableContentWidth = tableWidth - rowPadding * 2;
|
||||
const margin = (pageWidth - tableWidth) / 2;
|
||||
|
||||
const columnOneWidth = (tableContentWidth * columnWidthPercentages[0]) / 100;
|
||||
const columnTwoWidth = (tableContentWidth * columnWidthPercentages[1]) / 100;
|
||||
const columnThreeWidth = (tableContentWidth * columnWidthPercentages[2]) / 100;
|
||||
|
||||
const columnWidths: ColumnWidths = [columnOneWidth, columnTwoWidth, columnThreeWidth];
|
||||
|
||||
// Helper to render a Konva stage to a PNG buffer
|
||||
let stage: Konva.Stage | null = new Konva.Stage({ width: pageWidth, height: pageHeight });
|
||||
|
||||
const maxTableHeight = pageHeight - pageTopMargin - pageBottomMargin;
|
||||
|
||||
const groupedRows = groupRowsIntoPages({
|
||||
recipients,
|
||||
maxHeight: maxTableHeight,
|
||||
columnWidths,
|
||||
i18n,
|
||||
envelopeOwner,
|
||||
});
|
||||
|
||||
const tables = renderTables({ groupedRows, columnWidths, i18n });
|
||||
|
||||
const brandingGroup = await renderBranding({ qrToken, i18n });
|
||||
const brandingRect = brandingGroup.getClientRect();
|
||||
const brandingTopPadding = 24;
|
||||
|
||||
const pages: Uint8Array[] = [];
|
||||
|
||||
let isQrPlaced = false;
|
||||
|
||||
// Add a table to each page.
|
||||
for (const [index, table] of tables.entries()) {
|
||||
stage.destroyChildren();
|
||||
const page = new Konva.Layer();
|
||||
|
||||
const group = new Konva.Group();
|
||||
|
||||
const titleText = new Konva.Text({
|
||||
x: margin,
|
||||
y: 0,
|
||||
height: pageTopMargin,
|
||||
verticalAlign: 'middle',
|
||||
text: i18n._(msg`Signing Certificate`),
|
||||
fontFamily: 'Inter',
|
||||
fontSize: titleFontSize,
|
||||
fontStyle: '700',
|
||||
});
|
||||
|
||||
table.setAttrs({
|
||||
x: margin,
|
||||
y: pageTopMargin,
|
||||
} satisfies Partial<Konva.GroupConfig>);
|
||||
|
||||
group.add(titleText);
|
||||
group.add(table);
|
||||
|
||||
// Add QR code and branding on the last page if there is space.
|
||||
if (index === tables.length - 1 && !hidePoweredBy) {
|
||||
const remainingHeight = pageHeight - group.getClientRect().height - pageBottomMargin;
|
||||
|
||||
if (brandingRect.height + brandingTopPadding <= remainingHeight) {
|
||||
brandingGroup.setAttrs({
|
||||
x: pageWidth - brandingRect.width - margin,
|
||||
y: group.getClientRect().height + brandingTopPadding,
|
||||
} satisfies Partial<Konva.GroupConfig>);
|
||||
|
||||
page.add(brandingGroup);
|
||||
isQrPlaced = true;
|
||||
}
|
||||
}
|
||||
|
||||
page.add(group);
|
||||
stage.add(page);
|
||||
|
||||
// Export the page and save it.
|
||||
const canvas = page.canvas._canvas as unknown as Canvas; // eslint-disable-line @typescript-eslint/consistent-type-assertions
|
||||
const buffer = await canvas.toBuffer('pdf');
|
||||
pages.push(new Uint8Array(buffer));
|
||||
}
|
||||
|
||||
// Need to create an empty page for the QR code if it hasn't been placed yet.
|
||||
if (!hidePoweredBy && !isQrPlaced) {
|
||||
const page = new Konva.Layer();
|
||||
|
||||
brandingGroup.setAttrs({
|
||||
x: pageWidth - brandingRect.width - margin,
|
||||
y: pageTopMargin / 2, // Less padding since there's nothing else on this page.
|
||||
} satisfies Partial<Konva.GroupConfig>);
|
||||
|
||||
page.add(brandingGroup);
|
||||
stage.add(page);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const canvas = page.canvas._canvas as unknown as Canvas;
|
||||
const buffer = await canvas.toBuffer('pdf');
|
||||
|
||||
pages.push(new Uint8Array(buffer));
|
||||
}
|
||||
|
||||
stage.destroy();
|
||||
stage = null;
|
||||
|
||||
return pages;
|
||||
}
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: de\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2025-12-15 02:39\n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -244,6 +244,7 @@ msgid "{0} Teams"
|
||||
msgstr "{0} Teams"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{browserInfo} on {os}"
|
||||
msgstr "{browserInfo} auf {os}"
|
||||
|
||||
@@ -475,6 +476,7 @@ msgid "{teamName} has invited you to {action} {documentName}"
|
||||
msgstr "{teamName} hat Sie eingeladen, {action} {documentName}"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{userAgent}"
|
||||
msgstr "{userAgent}"
|
||||
|
||||
@@ -955,6 +957,7 @@ msgid "Account"
|
||||
msgstr "Konto"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Authentication"
|
||||
msgstr "Kontowauthentifizierung"
|
||||
|
||||
@@ -992,6 +995,7 @@ msgid "Account Linking Request"
|
||||
msgstr "Kontoverknüpfungsanfrage"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Re-Authentication"
|
||||
msgstr "Kontowiederauthentifizierung"
|
||||
|
||||
@@ -1939,6 +1943,7 @@ msgid "Attempts sealing the document again, useful for after a code change has o
|
||||
msgstr "Versuche, das Dokument erneut zu versiegeln, nützlich nach einer Codeänderung, um ein fehlerhaftes Dokument zu beheben."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Audit Log"
|
||||
msgstr "Audit-Protokoll"
|
||||
|
||||
@@ -1947,6 +1952,7 @@ msgid "Audit Logs"
|
||||
msgstr "Protokolle"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Authentication Level"
|
||||
msgstr "Authentifizierungsstufe"
|
||||
|
||||
@@ -2967,6 +2973,7 @@ msgstr "Erstellt"
|
||||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Created At"
|
||||
msgstr "Erstellt am"
|
||||
|
||||
@@ -3111,7 +3118,7 @@ msgstr "Standardwert"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr ""
|
||||
msgstr "Dokumenteigentum delegieren"
|
||||
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
msgid "delete"
|
||||
@@ -3259,6 +3266,7 @@ msgstr "Löschen Sie Ihr Konto und alle Inhalte, einschließlich abgeschlossener
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Deleted"
|
||||
msgstr "Gelöscht"
|
||||
|
||||
@@ -3272,6 +3280,7 @@ msgstr "Ziel"
|
||||
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Details"
|
||||
msgstr "Einzelheiten"
|
||||
|
||||
@@ -3328,6 +3337,7 @@ msgstr "Entwicklermodus"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Device"
|
||||
msgstr "Gerät"
|
||||
|
||||
@@ -3679,7 +3689,7 @@ msgstr "Dokument geöffnet"
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Document ownership delegated"
|
||||
msgstr ""
|
||||
msgstr "Dokumenteigentum delegiert"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
@@ -4090,6 +4100,8 @@ msgstr "Offenlegung der elektronischen Unterschrift"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx
|
||||
@@ -4120,10 +4132,6 @@ msgstr "E-Mail bereits bestätigt"
|
||||
msgid "Email already exists"
|
||||
msgstr "E-Mail existiert bereits"
|
||||
|
||||
#: apps/remix/app/components/general/direct-template/direct-template-configure-form.tsx
|
||||
msgid "Email cannot already exist in the template"
|
||||
msgstr "E-Mail darf nicht bereits in der Vorlage vorhanden sein"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx
|
||||
msgid "Email Confirmed!"
|
||||
msgstr "E-Mail bestätigt!"
|
||||
@@ -4290,7 +4298,7 @@ msgstr "SSO-Portal aktivieren"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Enable team API tokens to delegate document ownership to another team member."
|
||||
msgstr ""
|
||||
msgstr "Team-API-Tokens aktivieren, um das Dokumenteigentum an ein anderes Teammitglied zu delegieren."
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
@@ -4309,6 +4317,10 @@ msgstr "Das Aktivieren des Kontos führt dazu, dass der Benutzer das Konto wiede
|
||||
msgid "Enclosed Document"
|
||||
msgstr "Beigefügte Dokument"
|
||||
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Beigefügte Dokumente"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Geben Sie einen Namen für Ihren neuen Ordner ein. Ordner helfen Ihnen, Ihre Dateien zu organisieren."
|
||||
@@ -4384,6 +4396,7 @@ msgid "Envelope Duplicated"
|
||||
msgstr "Umschlag dupliziert"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Envelope ID"
|
||||
msgstr "Umschlag-ID"
|
||||
|
||||
@@ -5081,6 +5094,7 @@ msgid "I am required to receive a copy of this document"
|
||||
msgstr "Ich bin verpflichtet, eine Kopie dieses Dokuments zu erhalten"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "I am the owner of this document"
|
||||
msgstr "Ich bin der Besitzer dieses Dokuments"
|
||||
|
||||
@@ -5308,6 +5322,8 @@ msgstr "Rechnung"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "IP Address"
|
||||
msgstr "IP-Adresse"
|
||||
|
||||
@@ -5420,6 +5436,7 @@ msgid "Last updated"
|
||||
msgstr "Zuletzt aktualisiert"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Last Updated"
|
||||
msgstr "Zuletzt aktualisiert"
|
||||
|
||||
@@ -5632,7 +5649,7 @@ msgstr "Organisation verwalten"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
msgid "Manage Organisation"
|
||||
msgstr ""
|
||||
msgstr "Organisation verwalten"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations._index.tsx
|
||||
msgid "Manage organisations"
|
||||
@@ -5881,6 +5898,7 @@ msgid "My Folder"
|
||||
msgstr "Mein Ordner"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "N/A"
|
||||
msgstr "N/A"
|
||||
|
||||
@@ -6407,6 +6425,7 @@ msgstr "Organisationseinstellungen überschreiben"
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Owner"
|
||||
msgstr "Besitzer"
|
||||
|
||||
@@ -6457,6 +6476,7 @@ msgid "Passkey name"
|
||||
msgstr "Passkey-Name"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Passkey Re-Authentication"
|
||||
msgstr "Passwortwiederauthentifizierung"
|
||||
|
||||
@@ -6483,6 +6503,7 @@ msgid "Password"
|
||||
msgstr "Passwort"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Password Re-Authentication"
|
||||
msgstr "Passwort-Neuauthentifizierung"
|
||||
|
||||
@@ -6953,6 +6974,7 @@ msgid "Ready"
|
||||
msgstr "Bereit"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Reason"
|
||||
msgstr "Grund"
|
||||
|
||||
@@ -7039,6 +7061,7 @@ msgstr "Empfänger aktualisiert"
|
||||
#: apps/remix/app/components/general/template/template-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Recipients"
|
||||
msgstr "Empfänger"
|
||||
|
||||
@@ -7116,6 +7139,7 @@ msgstr "Dokument Ablehnen"
|
||||
#: apps/remix/app/components/general/stack-avatars-with-tooltip.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Rejected"
|
||||
msgstr "Abgelehnt"
|
||||
|
||||
@@ -7356,7 +7380,7 @@ msgstr "Zurück"
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx
|
||||
msgid "Return Home"
|
||||
msgstr ""
|
||||
msgstr "Zur Startseite zurückkehren"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/o.$orgUrl.signin.tsx
|
||||
msgid "Return to Documenso sign in page here"
|
||||
@@ -7787,6 +7811,7 @@ msgstr "Senden..."
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Sent"
|
||||
msgstr "Gesendet"
|
||||
|
||||
@@ -8017,6 +8042,7 @@ msgstr "Initialen ins Feld signieren"
|
||||
#: apps/remix/app/components/general/envelope-signing/envelope-signer-form.tsx
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/types.ts
|
||||
@@ -8025,6 +8051,7 @@ msgid "Signature"
|
||||
msgstr "Unterschrift"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signature ID"
|
||||
msgstr "Signatur-ID"
|
||||
|
||||
@@ -8050,6 +8077,7 @@ msgstr "Gesammelte Unterschriften"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/ui/components/document/document-read-only-fields.tsx
|
||||
#: packages/ui/components/document/envelope-recipient-field-tooltip.tsx
|
||||
msgid "Signed"
|
||||
@@ -8075,6 +8103,7 @@ msgid "Signer"
|
||||
msgstr "Unterzeichner"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signer Events"
|
||||
msgstr "Signer-Ereignisse"
|
||||
|
||||
@@ -8089,10 +8118,12 @@ msgid "Signing"
|
||||
msgstr "Unterzeichnung"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing Certificate"
|
||||
msgstr "Unterzeichnungszertifikat"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing certificate provided by"
|
||||
msgstr "Unterzeichnungszertifikat bereitgestellt von"
|
||||
|
||||
@@ -8300,6 +8331,7 @@ msgstr "Statistiken"
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
@@ -8865,7 +8897,7 @@ msgstr "Der Dokumenteneigentümer wurde über Ihre Entscheidung informiert. Er k
|
||||
#. placeholder {1}: data.teamName
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "The document ownership was delegated to {0} on behalf of {1}"
|
||||
msgstr ""
|
||||
msgstr "Das Dokumenteigentum wurde im Namen von {1} an {0} delegiert"
|
||||
|
||||
#: apps/remix/app/components/dialogs/template-use-dialog.tsx
|
||||
msgid "The document was created but could not be sent to recipients."
|
||||
@@ -9442,6 +9474,7 @@ msgstr "Zeitzone"
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx
|
||||
msgid "Time Zone"
|
||||
@@ -9633,6 +9666,7 @@ msgstr "Wiederherstellungscodes für die Zwei-Faktor-Authentifizierung werden ve
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Zwei-Faktor-Authentifizierung"
|
||||
|
||||
@@ -9649,6 +9683,7 @@ msgid "Two-factor authentication has been disabled for your account. You will no
|
||||
msgstr "Die Zwei-Faktor-Authentifizierung wurde für Ihr Konto deaktiviert. Sie müssen beim Anmelden keinen Code aus Ihrer Authentifizierungs-App mehr eingeben."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Re-Authentication"
|
||||
msgstr "Zwei-Faktor-Wiederauthentifizierung"
|
||||
|
||||
@@ -9782,6 +9817,10 @@ msgstr "Rückgängig"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Unknown"
|
||||
msgstr "Unbekannt"
|
||||
|
||||
@@ -10084,10 +10123,12 @@ msgstr "Verwenden Sie Ihren Passkey zur Authentifizierung"
|
||||
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User"
|
||||
msgstr "Benutzer"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User Agent"
|
||||
msgstr "Benutzer-Agent"
|
||||
|
||||
@@ -10331,6 +10372,7 @@ msgstr "DNS-Datensätze für diese E-Mail-Domain anzeigen"
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-list.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Viewed"
|
||||
msgstr "Betrachtet"
|
||||
|
||||
@@ -11654,3 +11696,4 @@ msgstr "Ihr Verifizierungscode:"
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
msgid "your-domain.com another-domain.com"
|
||||
msgstr "your-domain.com another-domain.com"
|
||||
|
||||
|
||||
@@ -239,6 +239,7 @@ msgid "{0} Teams"
|
||||
msgstr "{0} Teams"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{browserInfo} on {os}"
|
||||
msgstr "{browserInfo} on {os}"
|
||||
|
||||
@@ -470,6 +471,7 @@ msgid "{teamName} has invited you to {action} {documentName}"
|
||||
msgstr "{teamName} has invited you to {action} {documentName}"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{userAgent}"
|
||||
msgstr "{userAgent}"
|
||||
|
||||
@@ -950,6 +952,7 @@ msgid "Account"
|
||||
msgstr "Account"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Authentication"
|
||||
msgstr "Account Authentication"
|
||||
|
||||
@@ -987,6 +990,7 @@ msgid "Account Linking Request"
|
||||
msgstr "Account Linking Request"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Re-Authentication"
|
||||
msgstr "Account Re-Authentication"
|
||||
|
||||
@@ -1934,6 +1938,7 @@ msgid "Attempts sealing the document again, useful for after a code change has o
|
||||
msgstr "Attempts sealing the document again, useful for after a code change has occurred to resolve an erroneous document."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Audit Log"
|
||||
msgstr "Audit Log"
|
||||
|
||||
@@ -1942,6 +1947,7 @@ msgid "Audit Logs"
|
||||
msgstr "Audit Logs"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Authentication Level"
|
||||
msgstr "Authentication Level"
|
||||
|
||||
@@ -2962,6 +2968,7 @@ msgstr "Created"
|
||||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Created At"
|
||||
msgstr "Created At"
|
||||
|
||||
@@ -3254,6 +3261,7 @@ msgstr "Delete your account and all its contents, including completed documents.
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Deleted"
|
||||
msgstr "Deleted"
|
||||
|
||||
@@ -3267,6 +3275,7 @@ msgstr "Destination"
|
||||
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Details"
|
||||
msgstr "Details"
|
||||
|
||||
@@ -3323,6 +3332,7 @@ msgstr "Developer Mode"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Device"
|
||||
msgstr "Device"
|
||||
|
||||
@@ -4085,6 +4095,8 @@ msgstr "Electronic Signature Disclosure"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx
|
||||
@@ -4115,10 +4127,6 @@ msgstr "Email already confirmed"
|
||||
msgid "Email already exists"
|
||||
msgstr "Email already exists"
|
||||
|
||||
#: apps/remix/app/components/general/direct-template/direct-template-configure-form.tsx
|
||||
msgid "Email cannot already exist in the template"
|
||||
msgstr "Email cannot already exist in the template"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx
|
||||
msgid "Email Confirmed!"
|
||||
msgstr "Email Confirmed!"
|
||||
@@ -4304,6 +4312,10 @@ msgstr "Enabling the account results in the user being able to use the account a
|
||||
msgid "Enclosed Document"
|
||||
msgstr "Enclosed Document"
|
||||
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Enclosed Documents"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Enter a name for your new folder. Folders help you organise your items."
|
||||
@@ -4379,6 +4391,7 @@ msgid "Envelope Duplicated"
|
||||
msgstr "Envelope Duplicated"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Envelope ID"
|
||||
msgstr "Envelope ID"
|
||||
|
||||
@@ -5076,6 +5089,7 @@ msgid "I am required to receive a copy of this document"
|
||||
msgstr "I am required to receive a copy of this document"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "I am the owner of this document"
|
||||
msgstr "I am the owner of this document"
|
||||
|
||||
@@ -5303,6 +5317,8 @@ msgstr "Invoice"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "IP Address"
|
||||
msgstr "IP Address"
|
||||
|
||||
@@ -5415,6 +5431,7 @@ msgid "Last updated"
|
||||
msgstr "Last updated"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Last Updated"
|
||||
msgstr "Last Updated"
|
||||
|
||||
@@ -5876,6 +5893,7 @@ msgid "My Folder"
|
||||
msgstr "My Folder"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "N/A"
|
||||
msgstr "N/A"
|
||||
|
||||
@@ -6402,6 +6420,7 @@ msgstr "Override organisation settings"
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Owner"
|
||||
msgstr "Owner"
|
||||
|
||||
@@ -6452,6 +6471,7 @@ msgid "Passkey name"
|
||||
msgstr "Passkey name"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Passkey Re-Authentication"
|
||||
msgstr "Passkey Re-Authentication"
|
||||
|
||||
@@ -6478,6 +6498,7 @@ msgid "Password"
|
||||
msgstr "Password"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Password Re-Authentication"
|
||||
msgstr "Password Re-Authentication"
|
||||
|
||||
@@ -6948,6 +6969,7 @@ msgid "Ready"
|
||||
msgstr "Ready"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Reason"
|
||||
msgstr "Reason"
|
||||
|
||||
@@ -7034,6 +7056,7 @@ msgstr "Recipient updated"
|
||||
#: apps/remix/app/components/general/template/template-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Recipients"
|
||||
msgstr "Recipients"
|
||||
|
||||
@@ -7111,6 +7134,7 @@ msgstr "Reject Document"
|
||||
#: apps/remix/app/components/general/stack-avatars-with-tooltip.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Rejected"
|
||||
msgstr "Rejected"
|
||||
|
||||
@@ -7782,6 +7806,7 @@ msgstr "Sending..."
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Sent"
|
||||
msgstr "Sent"
|
||||
|
||||
@@ -8012,6 +8037,7 @@ msgstr "Sign your initials into the field"
|
||||
#: apps/remix/app/components/general/envelope-signing/envelope-signer-form.tsx
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/types.ts
|
||||
@@ -8020,6 +8046,7 @@ msgid "Signature"
|
||||
msgstr "Signature"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signature ID"
|
||||
msgstr "Signature ID"
|
||||
|
||||
@@ -8045,6 +8072,7 @@ msgstr "Signatures Collected"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/ui/components/document/document-read-only-fields.tsx
|
||||
#: packages/ui/components/document/envelope-recipient-field-tooltip.tsx
|
||||
msgid "Signed"
|
||||
@@ -8070,6 +8098,7 @@ msgid "Signer"
|
||||
msgstr "Signer"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signer Events"
|
||||
msgstr "Signer Events"
|
||||
|
||||
@@ -8084,10 +8113,12 @@ msgid "Signing"
|
||||
msgstr "Signing"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing Certificate"
|
||||
msgstr "Signing Certificate"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing certificate provided by"
|
||||
msgstr "Signing certificate provided by"
|
||||
|
||||
@@ -8295,6 +8326,7 @@ msgstr "Stats"
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
@@ -9437,6 +9469,7 @@ msgstr "Time zone"
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx
|
||||
msgid "Time Zone"
|
||||
@@ -9628,6 +9661,7 @@ msgstr "Two factor authentication recovery codes are used to access your account
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Two-Factor Authentication"
|
||||
|
||||
@@ -9644,6 +9678,7 @@ msgid "Two-factor authentication has been disabled for your account. You will no
|
||||
msgstr "Two-factor authentication has been disabled for your account. You will no longer be required to enter a code from your authenticator app when signing in."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Re-Authentication"
|
||||
msgstr "Two-Factor Re-Authentication"
|
||||
|
||||
@@ -9777,6 +9812,10 @@ msgstr "Undo"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Unknown"
|
||||
msgstr "Unknown"
|
||||
|
||||
@@ -10079,10 +10118,12 @@ msgstr "Use your passkey for authentication"
|
||||
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User"
|
||||
msgstr "User"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User Agent"
|
||||
msgstr "User Agent"
|
||||
|
||||
@@ -10326,6 +10367,7 @@ msgstr "View the DNS records for this email domain"
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-list.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Viewed"
|
||||
msgstr "Viewed"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: es\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2025-12-15 02:39\n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Spanish\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -244,6 +244,7 @@ msgid "{0} Teams"
|
||||
msgstr "{0} Equipos"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{browserInfo} on {os}"
|
||||
msgstr "{browserInfo} en {os}"
|
||||
|
||||
@@ -475,6 +476,7 @@ msgid "{teamName} has invited you to {action} {documentName}"
|
||||
msgstr "{teamName} te ha invitado a {action} {documentName}"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{userAgent}"
|
||||
msgstr "{userAgent}"
|
||||
|
||||
@@ -955,6 +957,7 @@ msgid "Account"
|
||||
msgstr "Cuenta"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Authentication"
|
||||
msgstr "Autenticación de Cuenta"
|
||||
|
||||
@@ -992,6 +995,7 @@ msgid "Account Linking Request"
|
||||
msgstr "Solicitud de Vinculación de Cuenta"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Re-Authentication"
|
||||
msgstr "Re-autenticación de Cuenta"
|
||||
|
||||
@@ -1939,6 +1943,7 @@ msgid "Attempts sealing the document again, useful for after a code change has o
|
||||
msgstr "Intenta sellar el documento de nuevo, útil después de que se haya producido un cambio de código para resolver un documento erróneo."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Audit Log"
|
||||
msgstr "Registro de Auditoría"
|
||||
|
||||
@@ -1947,6 +1952,7 @@ msgid "Audit Logs"
|
||||
msgstr "Registros de Auditoría"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Authentication Level"
|
||||
msgstr "Nivel de Autenticación"
|
||||
|
||||
@@ -2967,6 +2973,7 @@ msgstr "Creado"
|
||||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Created At"
|
||||
msgstr "Creado En"
|
||||
|
||||
@@ -3111,7 +3118,7 @@ msgstr "Valor Predeterminado"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr ""
|
||||
msgstr "Delegar la propiedad del documento"
|
||||
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
msgid "delete"
|
||||
@@ -3259,6 +3266,7 @@ msgstr "Eliminar su cuenta y todo su contenido, incluidos documentos completados
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Deleted"
|
||||
msgstr "Eliminado"
|
||||
|
||||
@@ -3272,6 +3280,7 @@ msgstr "Destino"
|
||||
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Details"
|
||||
msgstr "Detalles"
|
||||
|
||||
@@ -3328,6 +3337,7 @@ msgstr "Modo desarrollador"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Device"
|
||||
msgstr "Dispositivo"
|
||||
|
||||
@@ -3679,7 +3689,7 @@ msgstr "Documento abierto"
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Document ownership delegated"
|
||||
msgstr ""
|
||||
msgstr "Propiedad del documento delegada"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
@@ -4090,6 +4100,8 @@ msgstr "Divulgación de Firma Electrónica"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx
|
||||
@@ -4120,10 +4132,6 @@ msgstr "Correo electrónico ya confirmado"
|
||||
msgid "Email already exists"
|
||||
msgstr "El correo ya existe"
|
||||
|
||||
#: apps/remix/app/components/general/direct-template/direct-template-configure-form.tsx
|
||||
msgid "Email cannot already exist in the template"
|
||||
msgstr "El correo electrónico no puede existir ya en la plantilla"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx
|
||||
msgid "Email Confirmed!"
|
||||
msgstr "¡Correo electrónico confirmado!"
|
||||
@@ -4290,7 +4298,7 @@ msgstr "Habilitar portal SSO"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Enable team API tokens to delegate document ownership to another team member."
|
||||
msgstr ""
|
||||
msgstr "Habilita los tokens de API del equipo para delegar la propiedad del documento a otro miembro del equipo."
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
@@ -4309,6 +4317,10 @@ msgstr "Habilitar la cuenta permite al usuario usar la cuenta de nuevo, junto co
|
||||
msgid "Enclosed Document"
|
||||
msgstr "Documento Adjunto"
|
||||
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Documentos adjuntos"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Ingrese un nombre para su nueva carpeta. Las carpetas le ayudan a organizar sus elementos."
|
||||
@@ -4384,6 +4396,7 @@ msgid "Envelope Duplicated"
|
||||
msgstr "Sobre Duplicado"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Envelope ID"
|
||||
msgstr "ID de Sobre"
|
||||
|
||||
@@ -5081,6 +5094,7 @@ msgid "I am required to receive a copy of this document"
|
||||
msgstr "Se me requiere recibir una copia de este documento"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "I am the owner of this document"
|
||||
msgstr "Soy el propietario de este documento"
|
||||
|
||||
@@ -5308,6 +5322,8 @@ msgstr "Factura"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "IP Address"
|
||||
msgstr "Dirección IP"
|
||||
|
||||
@@ -5420,6 +5436,7 @@ msgid "Last updated"
|
||||
msgstr "Última actualización"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Last Updated"
|
||||
msgstr "Última Actualización"
|
||||
|
||||
@@ -5632,7 +5649,7 @@ msgstr "Administrar organización"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
msgid "Manage Organisation"
|
||||
msgstr ""
|
||||
msgstr "Gestionar organización"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations._index.tsx
|
||||
msgid "Manage organisations"
|
||||
@@ -5881,6 +5898,7 @@ msgid "My Folder"
|
||||
msgstr "Mi Carpeta"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "N/A"
|
||||
msgstr "N/A"
|
||||
|
||||
@@ -6407,6 +6425,7 @@ msgstr "Anular la configuración de la organización"
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Owner"
|
||||
msgstr "Propietario"
|
||||
|
||||
@@ -6457,6 +6476,7 @@ msgid "Passkey name"
|
||||
msgstr "Nombre de clave de acceso"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Passkey Re-Authentication"
|
||||
msgstr "Re-autenticación de Passkey"
|
||||
|
||||
@@ -6483,6 +6503,7 @@ msgid "Password"
|
||||
msgstr "Contraseña"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Password Re-Authentication"
|
||||
msgstr "Reautenticación de contraseña"
|
||||
|
||||
@@ -6953,6 +6974,7 @@ msgid "Ready"
|
||||
msgstr "Listo"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Reason"
|
||||
msgstr "Razón"
|
||||
|
||||
@@ -7039,6 +7061,7 @@ msgstr "Destinatario actualizado"
|
||||
#: apps/remix/app/components/general/template/template-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Recipients"
|
||||
msgstr "Destinatarios"
|
||||
|
||||
@@ -7116,6 +7139,7 @@ msgstr "Rechazar Documento"
|
||||
#: apps/remix/app/components/general/stack-avatars-with-tooltip.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Rejected"
|
||||
msgstr "Rejected"
|
||||
|
||||
@@ -7356,7 +7380,7 @@ msgstr "Regresar"
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx
|
||||
msgid "Return Home"
|
||||
msgstr ""
|
||||
msgstr "Volver al inicio"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/o.$orgUrl.signin.tsx
|
||||
msgid "Return to Documenso sign in page here"
|
||||
@@ -7787,6 +7811,7 @@ msgstr "Enviando..."
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Sent"
|
||||
msgstr "Enviado"
|
||||
|
||||
@@ -8017,6 +8042,7 @@ msgstr "Firme sus iniciales en el campo"
|
||||
#: apps/remix/app/components/general/envelope-signing/envelope-signer-form.tsx
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/types.ts
|
||||
@@ -8025,6 +8051,7 @@ msgid "Signature"
|
||||
msgstr "Firma"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signature ID"
|
||||
msgstr "ID de Firma"
|
||||
|
||||
@@ -8050,6 +8077,7 @@ msgstr "Firmas recolectadas"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/ui/components/document/document-read-only-fields.tsx
|
||||
#: packages/ui/components/document/envelope-recipient-field-tooltip.tsx
|
||||
msgid "Signed"
|
||||
@@ -8075,6 +8103,7 @@ msgid "Signer"
|
||||
msgstr "Firmante"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signer Events"
|
||||
msgstr "Eventos del Firmante"
|
||||
|
||||
@@ -8089,10 +8118,12 @@ msgid "Signing"
|
||||
msgstr "Firmando"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing Certificate"
|
||||
msgstr "Certificado de Firma"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing certificate provided by"
|
||||
msgstr "Certificado de firma proporcionado por"
|
||||
|
||||
@@ -8300,6 +8331,7 @@ msgstr "Estadísticas"
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Status"
|
||||
msgstr "Estado"
|
||||
|
||||
@@ -8865,7 +8897,7 @@ msgstr "The document owner has been notified of your decision. They may contact
|
||||
#. placeholder {1}: data.teamName
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "The document ownership was delegated to {0} on behalf of {1}"
|
||||
msgstr ""
|
||||
msgstr "La propiedad del documento fue delegada a {0} en nombre de {1}"
|
||||
|
||||
#: apps/remix/app/components/dialogs/template-use-dialog.tsx
|
||||
msgid "The document was created but could not be sent to recipients."
|
||||
@@ -9442,6 +9474,7 @@ msgstr "Zona horaria"
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx
|
||||
msgid "Time Zone"
|
||||
@@ -9633,6 +9666,7 @@ msgstr "Los códigos de recuperación de autenticación de dos factores se utili
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Autenticación de dos factores"
|
||||
|
||||
@@ -9649,6 +9683,7 @@ msgid "Two-factor authentication has been disabled for your account. You will no
|
||||
msgstr "La autenticación de dos factores ha sido desactivada para tu cuenta. Ya no se te pedirá ingresar un código de tu aplicación de autenticador al iniciar sesión."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Re-Authentication"
|
||||
msgstr "Re-autenticación de Doble Factor"
|
||||
|
||||
@@ -9782,6 +9817,10 @@ msgstr "Deshacer"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Unknown"
|
||||
msgstr "Desconocido"
|
||||
|
||||
@@ -10084,10 +10123,12 @@ msgstr "Utilice su clave de acceso para la autenticación"
|
||||
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User"
|
||||
msgstr "Usuario"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User Agent"
|
||||
msgstr "Agente de usuario"
|
||||
|
||||
@@ -10331,6 +10372,7 @@ msgstr "Ver los registros DNS para este dominio de correo electrónico"
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-list.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Viewed"
|
||||
msgstr "Visto"
|
||||
|
||||
@@ -11654,3 +11696,4 @@ msgstr "Su código de verificación:"
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
msgid "your-domain.com another-domain.com"
|
||||
msgstr "su-dominio.com otro-dominio.com"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: fr\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2025-12-15 02:39\n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: French\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
@@ -244,6 +244,7 @@ msgid "{0} Teams"
|
||||
msgstr "{0} Équipes"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{browserInfo} on {os}"
|
||||
msgstr "{browserInfo} sur {os}"
|
||||
|
||||
@@ -475,6 +476,7 @@ msgid "{teamName} has invited you to {action} {documentName}"
|
||||
msgstr "{teamName} vous a invité à {action} {documentName}"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{userAgent}"
|
||||
msgstr "{userAgent}"
|
||||
|
||||
@@ -955,6 +957,7 @@ msgid "Account"
|
||||
msgstr "Compte"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Authentication"
|
||||
msgstr "Authentification de compte"
|
||||
|
||||
@@ -992,6 +995,7 @@ msgid "Account Linking Request"
|
||||
msgstr "Demande de liaison de compte"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Re-Authentication"
|
||||
msgstr "Ré-authentification de compte"
|
||||
|
||||
@@ -1939,6 +1943,7 @@ msgid "Attempts sealing the document again, useful for after a code change has o
|
||||
msgstr "Essaye de sceller le document à nouveau, utile après qu'un changement de code ait eu lieu pour résoudre un document erroné."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Audit Log"
|
||||
msgstr "Journal d'audit"
|
||||
|
||||
@@ -1947,6 +1952,7 @@ msgid "Audit Logs"
|
||||
msgstr "Journaux de vérification"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Authentication Level"
|
||||
msgstr "Niveau d'authentification"
|
||||
|
||||
@@ -2967,6 +2973,7 @@ msgstr "Créé"
|
||||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Created At"
|
||||
msgstr "Créé le"
|
||||
|
||||
@@ -3111,7 +3118,7 @@ msgstr "Valeur par défaut"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr ""
|
||||
msgstr "Déléguer la propriété du document"
|
||||
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
msgid "delete"
|
||||
@@ -3259,6 +3266,7 @@ msgstr "Supprimez votre compte et tout son contenu, y compris les documents comp
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Deleted"
|
||||
msgstr "Supprimé"
|
||||
|
||||
@@ -3272,6 +3280,7 @@ msgstr "Destination"
|
||||
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Details"
|
||||
msgstr "Détails"
|
||||
|
||||
@@ -3328,6 +3337,7 @@ msgstr "Mode développeur"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Device"
|
||||
msgstr "Appareil"
|
||||
|
||||
@@ -3679,7 +3689,7 @@ msgstr "Document ouvert"
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Document ownership delegated"
|
||||
msgstr ""
|
||||
msgstr "Propriété du document déléguée"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
@@ -4090,6 +4100,8 @@ msgstr "Divulgation de signature électronique"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx
|
||||
@@ -4120,10 +4132,6 @@ msgstr "E-mail déjà confirmé"
|
||||
msgid "Email already exists"
|
||||
msgstr "L'e-mail existe déjà"
|
||||
|
||||
#: apps/remix/app/components/general/direct-template/direct-template-configure-form.tsx
|
||||
msgid "Email cannot already exist in the template"
|
||||
msgstr "L'e-mail ne peut déjà exister dans le modèle"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx
|
||||
msgid "Email Confirmed!"
|
||||
msgstr "Email confirmé !"
|
||||
@@ -4290,7 +4298,7 @@ msgstr "Activer le portail SSO"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Enable team API tokens to delegate document ownership to another team member."
|
||||
msgstr ""
|
||||
msgstr "Activer les jetons d’API d’équipe pour déléguer la propriété du document à un autre membre de l’équipe."
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
@@ -4309,6 +4317,10 @@ msgstr "Activer le compte permet à l'utilisateur de pouvoir utiliser le compte
|
||||
msgid "Enclosed Document"
|
||||
msgstr "Document joint"
|
||||
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Documents joints"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Entrez un nom pour votre nouveau dossier. Les dossiers vous aident à organiser vos éléments."
|
||||
@@ -4384,6 +4396,7 @@ msgid "Envelope Duplicated"
|
||||
msgstr "Enveloppe dupliquée"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Envelope ID"
|
||||
msgstr "ID de l'enveloppe"
|
||||
|
||||
@@ -5081,6 +5094,7 @@ msgid "I am required to receive a copy of this document"
|
||||
msgstr "Je dois recevoir une copie de ce document"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "I am the owner of this document"
|
||||
msgstr "Je suis le propriétaire de ce document"
|
||||
|
||||
@@ -5308,6 +5322,8 @@ msgstr "Facture"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "IP Address"
|
||||
msgstr "Adresse IP"
|
||||
|
||||
@@ -5420,6 +5436,7 @@ msgid "Last updated"
|
||||
msgstr "Dernière mise à jour"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Last Updated"
|
||||
msgstr "Dernière mise à jour"
|
||||
|
||||
@@ -5632,7 +5649,7 @@ msgstr "Gérer l'organisation"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
msgid "Manage Organisation"
|
||||
msgstr ""
|
||||
msgstr "Gérer l’organisation"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations._index.tsx
|
||||
msgid "Manage organisations"
|
||||
@@ -5881,6 +5898,7 @@ msgid "My Folder"
|
||||
msgstr "Mon Dossier"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "N/A"
|
||||
msgstr "N/A"
|
||||
|
||||
@@ -6407,6 +6425,7 @@ msgstr "Ignorer les paramètres de l'organisation"
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Owner"
|
||||
msgstr "Propriétaire"
|
||||
|
||||
@@ -6457,6 +6476,7 @@ msgid "Passkey name"
|
||||
msgstr "Nom de la clé d'accès"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Passkey Re-Authentication"
|
||||
msgstr "Ré-authentification par clé d'accès"
|
||||
|
||||
@@ -6483,6 +6503,7 @@ msgid "Password"
|
||||
msgstr "Mot de passe"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Password Re-Authentication"
|
||||
msgstr "Ré-authentification par mot de passe"
|
||||
|
||||
@@ -6953,6 +6974,7 @@ msgid "Ready"
|
||||
msgstr "Prêt"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Reason"
|
||||
msgstr "Raison"
|
||||
|
||||
@@ -7039,6 +7061,7 @@ msgstr "Destinataire mis à jour"
|
||||
#: apps/remix/app/components/general/template/template-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Recipients"
|
||||
msgstr "Destinataires"
|
||||
|
||||
@@ -7116,6 +7139,7 @@ msgstr "Rejeter le Document"
|
||||
#: apps/remix/app/components/general/stack-avatars-with-tooltip.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Rejected"
|
||||
msgstr "Rejeté"
|
||||
|
||||
@@ -7356,7 +7380,7 @@ msgstr "Retour"
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx
|
||||
msgid "Return Home"
|
||||
msgstr ""
|
||||
msgstr "Retour à l’accueil"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/o.$orgUrl.signin.tsx
|
||||
msgid "Return to Documenso sign in page here"
|
||||
@@ -7787,6 +7811,7 @@ msgstr "Envoi..."
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Sent"
|
||||
msgstr "Envoyé"
|
||||
|
||||
@@ -8017,6 +8042,7 @@ msgstr "Signez vos initiales dans le champ"
|
||||
#: apps/remix/app/components/general/envelope-signing/envelope-signer-form.tsx
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/types.ts
|
||||
@@ -8025,6 +8051,7 @@ msgid "Signature"
|
||||
msgstr "Signature"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signature ID"
|
||||
msgstr "ID de signature"
|
||||
|
||||
@@ -8050,6 +8077,7 @@ msgstr "Signatures collectées"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/ui/components/document/document-read-only-fields.tsx
|
||||
#: packages/ui/components/document/envelope-recipient-field-tooltip.tsx
|
||||
msgid "Signed"
|
||||
@@ -8075,6 +8103,7 @@ msgid "Signer"
|
||||
msgstr "Signataire"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signer Events"
|
||||
msgstr "Événements de signataire"
|
||||
|
||||
@@ -8089,10 +8118,12 @@ msgid "Signing"
|
||||
msgstr "En train de signer"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing Certificate"
|
||||
msgstr "Certificat de signature"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing certificate provided by"
|
||||
msgstr "Certificat de signature fourni par"
|
||||
|
||||
@@ -8300,6 +8331,7 @@ msgstr "Statistiques"
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Status"
|
||||
msgstr "Statut"
|
||||
|
||||
@@ -8865,7 +8897,7 @@ msgstr "Le propriétaire du document a été informé de votre décision. Il peu
|
||||
#. placeholder {1}: data.teamName
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "The document ownership was delegated to {0} on behalf of {1}"
|
||||
msgstr ""
|
||||
msgstr "La propriété du document a été déléguée à {0} au nom de {1}"
|
||||
|
||||
#: apps/remix/app/components/dialogs/template-use-dialog.tsx
|
||||
msgid "The document was created but could not be sent to recipients."
|
||||
@@ -9442,6 +9474,7 @@ msgstr "Fuseau horaire"
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx
|
||||
msgid "Time Zone"
|
||||
@@ -9633,6 +9666,7 @@ msgstr "Les codes de récupération de l'authentification à deux facteurs sont
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Authentification à deux facteurs"
|
||||
|
||||
@@ -9649,6 +9683,7 @@ msgid "Two-factor authentication has been disabled for your account. You will no
|
||||
msgstr "L'authentification à deux facteurs a été désactivée pour votre compte. Vous ne serez plus tenu d'entrer un code de votre application d'authentification lors de la connexion."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Re-Authentication"
|
||||
msgstr "Ré-authentification à deux facteurs"
|
||||
|
||||
@@ -9782,6 +9817,10 @@ msgstr "Annuler"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Unknown"
|
||||
msgstr "Inconnu"
|
||||
|
||||
@@ -10084,10 +10123,12 @@ msgstr "Utilisez votre clé d'accès pour l'authentification"
|
||||
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User"
|
||||
msgstr "Utilisateur"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User Agent"
|
||||
msgstr "Agent utilisateur"
|
||||
|
||||
@@ -10331,6 +10372,7 @@ msgstr "Voir les enregistrements DNS pour ce domaine de messagerie"
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-list.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Viewed"
|
||||
msgstr "Vu"
|
||||
|
||||
@@ -11654,3 +11696,4 @@ msgstr "Votre code de vérification :"
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
msgid "your-domain.com another-domain.com"
|
||||
msgstr "your-domain.com another-domain.com"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: it\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2025-12-15 02:39\n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Italian\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -244,6 +244,7 @@ msgid "{0} Teams"
|
||||
msgstr "{0} Squadre"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{browserInfo} on {os}"
|
||||
msgstr "{browserInfo} su {os}"
|
||||
|
||||
@@ -475,6 +476,7 @@ msgid "{teamName} has invited you to {action} {documentName}"
|
||||
msgstr "{teamName} ti ha invitato a {action} {documentName}"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{userAgent}"
|
||||
msgstr "{userAgent}"
|
||||
|
||||
@@ -955,6 +957,7 @@ msgid "Account"
|
||||
msgstr "Account"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Authentication"
|
||||
msgstr "Autenticazione dell'account"
|
||||
|
||||
@@ -992,6 +995,7 @@ msgid "Account Linking Request"
|
||||
msgstr "Richiesta di Collegamento Account"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Re-Authentication"
|
||||
msgstr "Ri-autenticazione dell'account"
|
||||
|
||||
@@ -1939,6 +1943,7 @@ msgid "Attempts sealing the document again, useful for after a code change has o
|
||||
msgstr "Tenta nuovamente di sigillare il documento, utile dopo una modifica al codice per risolvere un documento errato."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Audit Log"
|
||||
msgstr "Registro di controllo"
|
||||
|
||||
@@ -1947,6 +1952,7 @@ msgid "Audit Logs"
|
||||
msgstr "Registri di Audit"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Authentication Level"
|
||||
msgstr "Livello di Autenticazione"
|
||||
|
||||
@@ -2967,6 +2973,7 @@ msgstr "Creato"
|
||||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Created At"
|
||||
msgstr "Creato il"
|
||||
|
||||
@@ -3111,7 +3118,7 @@ msgstr "Valore predefinito"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr ""
|
||||
msgstr "Delega della proprietà del documento"
|
||||
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
msgid "delete"
|
||||
@@ -3259,6 +3266,7 @@ msgstr "Elimina il tuo account e tutti i suoi contenuti, inclusi i documenti com
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Deleted"
|
||||
msgstr "Eliminato"
|
||||
|
||||
@@ -3272,6 +3280,7 @@ msgstr "Destinazione"
|
||||
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Details"
|
||||
msgstr "Dettagli"
|
||||
|
||||
@@ -3328,6 +3337,7 @@ msgstr "Modalità sviluppatore"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Device"
|
||||
msgstr "Dispositivo"
|
||||
|
||||
@@ -3679,7 +3689,7 @@ msgstr "Documento aperto"
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Document ownership delegated"
|
||||
msgstr ""
|
||||
msgstr "Proprietà del documento delegata"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
@@ -4090,6 +4100,8 @@ msgstr "Divulgazione della firma elettronica"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx
|
||||
@@ -4120,10 +4132,6 @@ msgstr "Email già confermata"
|
||||
msgid "Email already exists"
|
||||
msgstr "Email già esistente"
|
||||
|
||||
#: apps/remix/app/components/general/direct-template/direct-template-configure-form.tsx
|
||||
msgid "Email cannot already exist in the template"
|
||||
msgstr "L'email non può già esistere nel modello"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx
|
||||
msgid "Email Confirmed!"
|
||||
msgstr "Email confermato!"
|
||||
@@ -4290,7 +4298,7 @@ msgstr "Abilita portale SSO"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Enable team API tokens to delegate document ownership to another team member."
|
||||
msgstr ""
|
||||
msgstr "Abilita i token API del team per delegare la proprietà del documento a un altro membro del team."
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
@@ -4309,6 +4317,10 @@ msgstr "Abilitare l'account consente all'utente di utilizzare nuovamente l'accou
|
||||
msgid "Enclosed Document"
|
||||
msgstr "Documento Allegato"
|
||||
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Documenti allegati"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Inserisci un nome per la tua nuova cartella. Le cartelle ti aiutano a organizzare i tuoi elementi."
|
||||
@@ -4384,6 +4396,7 @@ msgid "Envelope Duplicated"
|
||||
msgstr "Busta Duplicata"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Envelope ID"
|
||||
msgstr "ID Busta"
|
||||
|
||||
@@ -5081,6 +5094,7 @@ msgid "I am required to receive a copy of this document"
|
||||
msgstr "Sono tenuto a ricevere una copia di questo documento"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "I am the owner of this document"
|
||||
msgstr "Sono il proprietario di questo documento"
|
||||
|
||||
@@ -5308,6 +5322,8 @@ msgstr "Fattura"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "IP Address"
|
||||
msgstr "Indirizzo IP"
|
||||
|
||||
@@ -5420,6 +5436,7 @@ msgid "Last updated"
|
||||
msgstr "Ultimo aggiornamento"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Last Updated"
|
||||
msgstr "Ultimo aggiornamento"
|
||||
|
||||
@@ -5632,7 +5649,7 @@ msgstr "Gestisci l'organizzazione"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
msgid "Manage Organisation"
|
||||
msgstr ""
|
||||
msgstr "Gestisci organizzazione"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations._index.tsx
|
||||
msgid "Manage organisations"
|
||||
@@ -5881,6 +5898,7 @@ msgid "My Folder"
|
||||
msgstr "La Mia Cartella"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "N/A"
|
||||
msgstr "N/A"
|
||||
|
||||
@@ -6407,6 +6425,7 @@ msgstr "Sovrascrivi impostazioni organizzazione"
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Owner"
|
||||
msgstr "Proprietario"
|
||||
|
||||
@@ -6457,6 +6476,7 @@ msgid "Passkey name"
|
||||
msgstr "Nome della passkey"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Passkey Re-Authentication"
|
||||
msgstr "Ri-autenticazione con chiave di accesso"
|
||||
|
||||
@@ -6483,6 +6503,7 @@ msgid "Password"
|
||||
msgstr "\"Password\""
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Password Re-Authentication"
|
||||
msgstr "Riautenticazione della password"
|
||||
|
||||
@@ -6953,6 +6974,7 @@ msgid "Ready"
|
||||
msgstr "Pronto"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Reason"
|
||||
msgstr "Motivo"
|
||||
|
||||
@@ -7039,6 +7061,7 @@ msgstr "Destinatario aggiornato"
|
||||
#: apps/remix/app/components/general/template/template-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Recipients"
|
||||
msgstr "Destinatari"
|
||||
|
||||
@@ -7116,6 +7139,7 @@ msgstr "Rifiuta Documento"
|
||||
#: apps/remix/app/components/general/stack-avatars-with-tooltip.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Rejected"
|
||||
msgstr "Rifiutato"
|
||||
|
||||
@@ -7356,7 +7380,7 @@ msgstr "Ritorna"
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx
|
||||
msgid "Return Home"
|
||||
msgstr ""
|
||||
msgstr "Torna alla home"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/o.$orgUrl.signin.tsx
|
||||
msgid "Return to Documenso sign in page here"
|
||||
@@ -7787,6 +7811,7 @@ msgstr "Invio..."
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Sent"
|
||||
msgstr "Inviato"
|
||||
|
||||
@@ -8017,6 +8042,7 @@ msgstr "Firma le tue iniziali nel campo"
|
||||
#: apps/remix/app/components/general/envelope-signing/envelope-signer-form.tsx
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/types.ts
|
||||
@@ -8025,6 +8051,7 @@ msgid "Signature"
|
||||
msgstr "Firma"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signature ID"
|
||||
msgstr "ID Firma"
|
||||
|
||||
@@ -8050,6 +8077,7 @@ msgstr "Firme raccolte"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/ui/components/document/document-read-only-fields.tsx
|
||||
#: packages/ui/components/document/envelope-recipient-field-tooltip.tsx
|
||||
msgid "Signed"
|
||||
@@ -8075,6 +8103,7 @@ msgid "Signer"
|
||||
msgstr "Firmante"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signer Events"
|
||||
msgstr "Eventi del Firmatario"
|
||||
|
||||
@@ -8089,10 +8118,12 @@ msgid "Signing"
|
||||
msgstr "Firma in corso"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing Certificate"
|
||||
msgstr "Certificato di Firma"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing certificate provided by"
|
||||
msgstr "Certificato di firma fornito da"
|
||||
|
||||
@@ -8300,6 +8331,7 @@ msgstr "Statistiche"
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Status"
|
||||
msgstr "Stato"
|
||||
|
||||
@@ -8865,7 +8897,7 @@ msgstr "Il proprietario del documento è stato informato della tua decisione. Po
|
||||
#. placeholder {1}: data.teamName
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "The document ownership was delegated to {0} on behalf of {1}"
|
||||
msgstr ""
|
||||
msgstr "La proprietà del documento è stata delegata a {0} per conto di {1}"
|
||||
|
||||
#: apps/remix/app/components/dialogs/template-use-dialog.tsx
|
||||
msgid "The document was created but could not be sent to recipients."
|
||||
@@ -9442,6 +9474,7 @@ msgstr "Fuso orario"
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx
|
||||
msgid "Time Zone"
|
||||
@@ -9633,6 +9666,7 @@ msgstr "I codici di recupero dell'autenticazione a due fattori sono utilizzati p
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Autenticazione a due fattori"
|
||||
|
||||
@@ -9649,6 +9683,7 @@ msgid "Two-factor authentication has been disabled for your account. You will no
|
||||
msgstr "L'autenticazione a due fattori è stata disattivata per il tuo account. Non sarà più necessario inserire un codice dalla tua app di autenticazione quando accedi."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Re-Authentication"
|
||||
msgstr "Ri-autenticazione a due fattori"
|
||||
|
||||
@@ -9782,6 +9817,10 @@ msgstr "Annulla"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Unknown"
|
||||
msgstr "Sconosciuto"
|
||||
|
||||
@@ -10084,10 +10123,12 @@ msgstr "Usa la tua chiave di accesso per l'autenticazione"
|
||||
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User"
|
||||
msgstr "Utente"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User Agent"
|
||||
msgstr "User Agent"
|
||||
|
||||
@@ -10331,6 +10372,7 @@ msgstr "Visualizza i record DNS per questo dominio email"
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-list.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Viewed"
|
||||
msgstr "Visualizzato"
|
||||
|
||||
@@ -11654,3 +11696,4 @@ msgstr "Il tuo codice di verifica:"
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
msgid "your-domain.com another-domain.com"
|
||||
msgstr "tuo-dominio.com altro-dominio.com"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: ja\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2025-12-15 02:39\n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Japanese\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
@@ -244,6 +244,7 @@ msgid "{0} Teams"
|
||||
msgstr "{0} のチーム"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{browserInfo} on {os}"
|
||||
msgstr "{browserInfo}({os})"
|
||||
|
||||
@@ -475,6 +476,7 @@ msgid "{teamName} has invited you to {action} {documentName}"
|
||||
msgstr "{teamName} から {action} {documentName} の依頼が届いています"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{userAgent}"
|
||||
msgstr "{userAgent}"
|
||||
|
||||
@@ -955,6 +957,7 @@ msgid "Account"
|
||||
msgstr "アカウント"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Authentication"
|
||||
msgstr "アカウント認証"
|
||||
|
||||
@@ -992,6 +995,7 @@ msgid "Account Linking Request"
|
||||
msgstr "アカウントリンクリクエスト"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Re-Authentication"
|
||||
msgstr "アカウント再認証"
|
||||
|
||||
@@ -1939,6 +1943,7 @@ msgid "Attempts sealing the document again, useful for after a code change has o
|
||||
msgstr "文書の再封止を試行します。コード変更後に文書の不具合を解消する際などに役立ちます。"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Audit Log"
|
||||
msgstr "監査ログ"
|
||||
|
||||
@@ -1947,6 +1952,7 @@ msgid "Audit Logs"
|
||||
msgstr "監査ログ"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Authentication Level"
|
||||
msgstr "認証レベル"
|
||||
|
||||
@@ -2967,6 +2973,7 @@ msgstr "作成日時"
|
||||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Created At"
|
||||
msgstr "作成日時"
|
||||
|
||||
@@ -3111,7 +3118,7 @@ msgstr "既定値"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr ""
|
||||
msgstr "文書の所有権を委譲する"
|
||||
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
msgid "delete"
|
||||
@@ -3259,6 +3266,7 @@ msgstr "アカウントと、その完了済み文書を含むすべての内容
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Deleted"
|
||||
msgstr "削除済み"
|
||||
|
||||
@@ -3272,6 +3280,7 @@ msgstr "送信先"
|
||||
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Details"
|
||||
msgstr "詳細"
|
||||
|
||||
@@ -3328,6 +3337,7 @@ msgstr "開発者モード"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Device"
|
||||
msgstr "デバイス"
|
||||
|
||||
@@ -3679,7 +3689,7 @@ msgstr "ドキュメントが開かれました"
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Document ownership delegated"
|
||||
msgstr ""
|
||||
msgstr "文書の所有権が委譲されました"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
@@ -4090,6 +4100,8 @@ msgstr "電子署名に関する開示"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx
|
||||
@@ -4120,10 +4132,6 @@ msgstr "メールはすでに確認済みです"
|
||||
msgid "Email already exists"
|
||||
msgstr "メールはすでに存在します"
|
||||
|
||||
#: apps/remix/app/components/general/direct-template/direct-template-configure-form.tsx
|
||||
msgid "Email cannot already exist in the template"
|
||||
msgstr "このテンプレート内ですでに使用されているメールアドレスは指定できません"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx
|
||||
msgid "Email Confirmed!"
|
||||
msgstr "メールアドレスが確認されました!"
|
||||
@@ -4290,7 +4298,7 @@ msgstr "SSO ポータルを有効にする"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Enable team API tokens to delegate document ownership to another team member."
|
||||
msgstr ""
|
||||
msgstr "チーム API トークンを有効にして、別のチームメンバーに文書の所有権を委譲できるようにします。"
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
@@ -4309,6 +4317,10 @@ msgstr "アカウントを有効にすると、そのユーザーは再びアカ
|
||||
msgid "Enclosed Document"
|
||||
msgstr "同封文書"
|
||||
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "同封された文書"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "新しいフォルダ名を入力してください。フォルダを使うとアイテムを整理できます。"
|
||||
@@ -4384,6 +4396,7 @@ msgid "Envelope Duplicated"
|
||||
msgstr "封筒を複製しました"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Envelope ID"
|
||||
msgstr "封筒ID"
|
||||
|
||||
@@ -5081,6 +5094,7 @@ msgid "I am required to receive a copy of this document"
|
||||
msgstr "私はこのドキュメントのコピー受信が必須です"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "I am the owner of this document"
|
||||
msgstr "私はこの文書の所有者です"
|
||||
|
||||
@@ -5308,6 +5322,8 @@ msgstr "請求書"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "IP Address"
|
||||
msgstr "IP アドレス"
|
||||
|
||||
@@ -5420,6 +5436,7 @@ msgid "Last updated"
|
||||
msgstr "最終更新日時"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Last Updated"
|
||||
msgstr "最終更新"
|
||||
|
||||
@@ -5632,7 +5649,7 @@ msgstr "組織を管理"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
msgid "Manage Organisation"
|
||||
msgstr ""
|
||||
msgstr "組織を管理する"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations._index.tsx
|
||||
msgid "Manage organisations"
|
||||
@@ -5881,6 +5898,7 @@ msgid "My Folder"
|
||||
msgstr "マイフォルダ"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "N/A"
|
||||
msgstr "N/A"
|
||||
|
||||
@@ -6407,6 +6425,7 @@ msgstr "組織設定を上書き"
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Owner"
|
||||
msgstr "所有者"
|
||||
|
||||
@@ -6457,6 +6476,7 @@ msgid "Passkey name"
|
||||
msgstr "パスキー名"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Passkey Re-Authentication"
|
||||
msgstr "パスキーによる再認証"
|
||||
|
||||
@@ -6483,6 +6503,7 @@ msgid "Password"
|
||||
msgstr "パスワード"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Password Re-Authentication"
|
||||
msgstr "パスワード再認証"
|
||||
|
||||
@@ -6953,6 +6974,7 @@ msgid "Ready"
|
||||
msgstr "準備完了"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Reason"
|
||||
msgstr "理由"
|
||||
|
||||
@@ -7039,6 +7061,7 @@ msgstr "受信者を更新しました"
|
||||
#: apps/remix/app/components/general/template/template-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Recipients"
|
||||
msgstr "受信者"
|
||||
|
||||
@@ -7116,6 +7139,7 @@ msgstr "ドキュメントを却下"
|
||||
#: apps/remix/app/components/general/stack-avatars-with-tooltip.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Rejected"
|
||||
msgstr "却下済み"
|
||||
|
||||
@@ -7356,7 +7380,7 @@ msgstr "戻る"
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx
|
||||
msgid "Return Home"
|
||||
msgstr ""
|
||||
msgstr "ホームに戻る"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/o.$orgUrl.signin.tsx
|
||||
msgid "Return to Documenso sign in page here"
|
||||
@@ -7787,6 +7811,7 @@ msgstr "送信中..."
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Sent"
|
||||
msgstr "送信日時"
|
||||
|
||||
@@ -8017,6 +8042,7 @@ msgstr "イニシャルをフィールドに入力してください"
|
||||
#: apps/remix/app/components/general/envelope-signing/envelope-signer-form.tsx
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/types.ts
|
||||
@@ -8025,6 +8051,7 @@ msgid "Signature"
|
||||
msgstr "署名"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signature ID"
|
||||
msgstr "署名 ID"
|
||||
|
||||
@@ -8050,6 +8077,7 @@ msgstr "収集された署名数"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/ui/components/document/document-read-only-fields.tsx
|
||||
#: packages/ui/components/document/envelope-recipient-field-tooltip.tsx
|
||||
msgid "Signed"
|
||||
@@ -8075,6 +8103,7 @@ msgid "Signer"
|
||||
msgstr "署名者"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signer Events"
|
||||
msgstr "署名者のイベント"
|
||||
|
||||
@@ -8089,10 +8118,12 @@ msgid "Signing"
|
||||
msgstr "署名中"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing Certificate"
|
||||
msgstr "署名証明書"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing certificate provided by"
|
||||
msgstr "署名証明書の提供元"
|
||||
|
||||
@@ -8300,6 +8331,7 @@ msgstr "統計"
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Status"
|
||||
msgstr "ステータス"
|
||||
|
||||
@@ -8865,7 +8897,7 @@ msgstr "お客様の決定について、ドキュメントの所有者に通知
|
||||
#. placeholder {1}: data.teamName
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "The document ownership was delegated to {0} on behalf of {1}"
|
||||
msgstr ""
|
||||
msgstr "文書の所有権は、{1} を代表して {0} に委譲されました"
|
||||
|
||||
#: apps/remix/app/components/dialogs/template-use-dialog.tsx
|
||||
msgid "The document was created but could not be sent to recipients."
|
||||
@@ -9442,6 +9474,7 @@ msgstr "タイムゾーン"
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx
|
||||
msgid "Time Zone"
|
||||
@@ -9633,6 +9666,7 @@ msgstr "二要素認証のリカバリーコードは、認証アプリにアク
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "二要素認証"
|
||||
|
||||
@@ -9649,6 +9683,7 @@ msgid "Two-factor authentication has been disabled for your account. You will no
|
||||
msgstr "アカウントの二要素認証を無効にしました。今後、サインイン時に認証アプリのコードを入力する必要はありません。"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Re-Authentication"
|
||||
msgstr "二要素認証による再認証"
|
||||
|
||||
@@ -9782,6 +9817,10 @@ msgstr "元に戻す"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Unknown"
|
||||
msgstr "不明"
|
||||
|
||||
@@ -10084,10 +10123,12 @@ msgstr "パスキーで認証する"
|
||||
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User"
|
||||
msgstr "ユーザー"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User Agent"
|
||||
msgstr "ユーザーエージェント"
|
||||
|
||||
@@ -10331,6 +10372,7 @@ msgstr "このメールドメインの DNS レコードを表示"
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-list.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Viewed"
|
||||
msgstr "閲覧済み"
|
||||
|
||||
@@ -11654,3 +11696,4 @@ msgstr "認証コード:"
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
msgid "your-domain.com another-domain.com"
|
||||
msgstr "your-domain.com another-domain.com"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: ko\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2025-12-15 02:39\n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Korean\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
@@ -244,6 +244,7 @@ msgid "{0} Teams"
|
||||
msgstr "{0} 팀"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{browserInfo} on {os}"
|
||||
msgstr "{browserInfo} / {os}"
|
||||
|
||||
@@ -475,6 +476,7 @@ msgid "{teamName} has invited you to {action} {documentName}"
|
||||
msgstr "{teamName}이(가) 귀하께 {action} {documentName} 문서를 요청했습니다."
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{userAgent}"
|
||||
msgstr "{userAgent}"
|
||||
|
||||
@@ -955,6 +957,7 @@ msgid "Account"
|
||||
msgstr "계정"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Authentication"
|
||||
msgstr "계정 인증"
|
||||
|
||||
@@ -992,6 +995,7 @@ msgid "Account Linking Request"
|
||||
msgstr "계정 연결 요청"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Re-Authentication"
|
||||
msgstr "계정 재인증"
|
||||
|
||||
@@ -1939,6 +1943,7 @@ msgid "Attempts sealing the document again, useful for after a code change has o
|
||||
msgstr "코드 변경으로 잘못된 문서를 수정한 후, 문서를 다시 봉인할 때 유용합니다."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Audit Log"
|
||||
msgstr "감사 로그"
|
||||
|
||||
@@ -1947,6 +1952,7 @@ msgid "Audit Logs"
|
||||
msgstr "감사 로그"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Authentication Level"
|
||||
msgstr "인증 수준"
|
||||
|
||||
@@ -2967,6 +2973,7 @@ msgstr "생성일"
|
||||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Created At"
|
||||
msgstr "생성 일시"
|
||||
|
||||
@@ -3111,7 +3118,7 @@ msgstr "기본값"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr ""
|
||||
msgstr "문서 소유권 위임"
|
||||
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
msgid "delete"
|
||||
@@ -3259,6 +3266,7 @@ msgstr "계정 및 완료된 문서를 포함한 모든 콘텐츠가 삭제됩
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Deleted"
|
||||
msgstr "삭제됨"
|
||||
|
||||
@@ -3272,6 +3280,7 @@ msgstr "대상"
|
||||
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Details"
|
||||
msgstr "세부 정보"
|
||||
|
||||
@@ -3328,6 +3337,7 @@ msgstr "개발자 모드"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Device"
|
||||
msgstr "디바이스"
|
||||
|
||||
@@ -3679,7 +3689,7 @@ msgstr "문서가 열렸습니다."
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Document ownership delegated"
|
||||
msgstr ""
|
||||
msgstr "문서 소유권이 위임됨"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
@@ -4090,6 +4100,8 @@ msgstr "전자 서명 고지"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx
|
||||
@@ -4120,10 +4132,6 @@ msgstr "이미 확인된 이메일입니다."
|
||||
msgid "Email already exists"
|
||||
msgstr "이메일이 이미 존재합니다."
|
||||
|
||||
#: apps/remix/app/components/general/direct-template/direct-template-configure-form.tsx
|
||||
msgid "Email cannot already exist in the template"
|
||||
msgstr "이 이메일은 템플릿에 이미 존재할 수 없습니다"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx
|
||||
msgid "Email Confirmed!"
|
||||
msgstr "이메일이 확인되었습니다!"
|
||||
@@ -4290,7 +4298,7 @@ msgstr "SSO 포털 활성화"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Enable team API tokens to delegate document ownership to another team member."
|
||||
msgstr ""
|
||||
msgstr "팀 API 토큰을 활성화하여 문서 소유권을 다른 팀 구성원에게 위임하세요."
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
@@ -4309,6 +4317,10 @@ msgstr "계정을 활성화하면 사용자가 다시 계정을 사용할 수
|
||||
msgid "Enclosed Document"
|
||||
msgstr "동봉 문서"
|
||||
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "동봉된 문서들"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "새 폴더 이름을 입력하세요. 폴더는 항목을 정리하는 데 도움이 됩니다."
|
||||
@@ -4384,6 +4396,7 @@ msgid "Envelope Duplicated"
|
||||
msgstr "봉투가 복제되었습니다"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Envelope ID"
|
||||
msgstr "봉투 ID"
|
||||
|
||||
@@ -5081,6 +5094,7 @@ msgid "I am required to receive a copy of this document"
|
||||
msgstr "저는 이 문서의 사본을 받아야 합니다."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "I am the owner of this document"
|
||||
msgstr "이 문서의 소유자입니다"
|
||||
|
||||
@@ -5308,6 +5322,8 @@ msgstr "청구서"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "IP Address"
|
||||
msgstr "IP 주소"
|
||||
|
||||
@@ -5420,6 +5436,7 @@ msgid "Last updated"
|
||||
msgstr "마지막 업데이트"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Last Updated"
|
||||
msgstr "마지막 업데이트"
|
||||
|
||||
@@ -5632,7 +5649,7 @@ msgstr "조직 관리"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
msgid "Manage Organisation"
|
||||
msgstr ""
|
||||
msgstr "조직 관리"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations._index.tsx
|
||||
msgid "Manage organisations"
|
||||
@@ -5881,6 +5898,7 @@ msgid "My Folder"
|
||||
msgstr "내 폴더"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "N/A"
|
||||
msgstr "해당 없음"
|
||||
|
||||
@@ -6407,6 +6425,7 @@ msgstr "조직 설정 재정의"
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Owner"
|
||||
msgstr "소유자"
|
||||
|
||||
@@ -6457,6 +6476,7 @@ msgid "Passkey name"
|
||||
msgstr "패스키 이름"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Passkey Re-Authentication"
|
||||
msgstr "패스키 재인증"
|
||||
|
||||
@@ -6483,6 +6503,7 @@ msgid "Password"
|
||||
msgstr "비밀번호"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Password Re-Authentication"
|
||||
msgstr "비밀번호 재인증"
|
||||
|
||||
@@ -6953,6 +6974,7 @@ msgid "Ready"
|
||||
msgstr "준비됨"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Reason"
|
||||
msgstr "이유"
|
||||
|
||||
@@ -7039,6 +7061,7 @@ msgstr "수신자가 업데이트되었습니다"
|
||||
#: apps/remix/app/components/general/template/template-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Recipients"
|
||||
msgstr "수신자"
|
||||
|
||||
@@ -7116,6 +7139,7 @@ msgstr "문서 거부"
|
||||
#: apps/remix/app/components/general/stack-avatars-with-tooltip.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Rejected"
|
||||
msgstr "거부됨"
|
||||
|
||||
@@ -7356,7 +7380,7 @@ msgstr "돌아가기"
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx
|
||||
msgid "Return Home"
|
||||
msgstr ""
|
||||
msgstr "홈으로 돌아가기"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/o.$orgUrl.signin.tsx
|
||||
msgid "Return to Documenso sign in page here"
|
||||
@@ -7787,6 +7811,7 @@ msgstr "전송 중..."
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Sent"
|
||||
msgstr "발송됨"
|
||||
|
||||
@@ -8017,6 +8042,7 @@ msgstr "필드에 이니셜을 입력하세요"
|
||||
#: apps/remix/app/components/general/envelope-signing/envelope-signer-form.tsx
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/types.ts
|
||||
@@ -8025,6 +8051,7 @@ msgid "Signature"
|
||||
msgstr "서명"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signature ID"
|
||||
msgstr "서명 ID"
|
||||
|
||||
@@ -8050,6 +8077,7 @@ msgstr "수집된 서명 수"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/ui/components/document/document-read-only-fields.tsx
|
||||
#: packages/ui/components/document/envelope-recipient-field-tooltip.tsx
|
||||
msgid "Signed"
|
||||
@@ -8075,6 +8103,7 @@ msgid "Signer"
|
||||
msgstr "서명자"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signer Events"
|
||||
msgstr "서명자 이벤트"
|
||||
|
||||
@@ -8089,10 +8118,12 @@ msgid "Signing"
|
||||
msgstr "서명 중"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing Certificate"
|
||||
msgstr "서명 인증서"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing certificate provided by"
|
||||
msgstr "서명 인증서 제공자"
|
||||
|
||||
@@ -8300,6 +8331,7 @@ msgstr "통계"
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Status"
|
||||
msgstr "상태"
|
||||
|
||||
@@ -8865,7 +8897,7 @@ msgstr "문서 소유자에게 귀하의 결정이 이미 전달되었습니다.
|
||||
#. placeholder {1}: data.teamName
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "The document ownership was delegated to {0} on behalf of {1}"
|
||||
msgstr ""
|
||||
msgstr "문서 소유권이 {1}을(를) 대신해 {0}에게 위임되었습니다"
|
||||
|
||||
#: apps/remix/app/components/dialogs/template-use-dialog.tsx
|
||||
msgid "The document was created but could not be sent to recipients."
|
||||
@@ -9442,6 +9474,7 @@ msgstr "시간대"
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx
|
||||
msgid "Time Zone"
|
||||
@@ -9633,6 +9666,7 @@ msgstr "2단계 인증 복구 코드는 인증 앱에 대한 접근 권한을
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "2단계 인증"
|
||||
|
||||
@@ -9649,6 +9683,7 @@ msgid "Two-factor authentication has been disabled for your account. You will no
|
||||
msgstr "계정의 2단계 인증이 비활성화되었습니다. 앞으로 로그인할 때 인증 앱의 코드를 입력하지 않아도 됩니다."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Re-Authentication"
|
||||
msgstr "2단계 재인증"
|
||||
|
||||
@@ -9782,6 +9817,10 @@ msgstr "실행 취소"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Unknown"
|
||||
msgstr "알 수 없음"
|
||||
|
||||
@@ -10084,10 +10123,12 @@ msgstr "패스키로 인증하세요."
|
||||
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User"
|
||||
msgstr "사용자"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User Agent"
|
||||
msgstr "User Agent"
|
||||
|
||||
@@ -10331,6 +10372,7 @@ msgstr "이 이메일 도메인에 대한 DNS 레코드를 확인합니다."
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-list.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Viewed"
|
||||
msgstr "열람됨"
|
||||
|
||||
@@ -11654,3 +11696,4 @@ msgstr "인증 코드:"
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
msgid "your-domain.com another-domain.com"
|
||||
msgstr "your-domain.com another-domain.com"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: nl\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2025-12-15 02:39\n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Dutch\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -244,6 +244,7 @@ msgid "{0} Teams"
|
||||
msgstr "{0} teams"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{browserInfo} on {os}"
|
||||
msgstr "{browserInfo} op {os}"
|
||||
|
||||
@@ -475,6 +476,7 @@ msgid "{teamName} has invited you to {action} {documentName}"
|
||||
msgstr "{teamName} heeft je uitgenodigd om {action} {documentName}"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{userAgent}"
|
||||
msgstr "{userAgent}"
|
||||
|
||||
@@ -955,6 +957,7 @@ msgid "Account"
|
||||
msgstr "Account"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Authentication"
|
||||
msgstr "Accountauthenticatie"
|
||||
|
||||
@@ -992,6 +995,7 @@ msgid "Account Linking Request"
|
||||
msgstr "Verzoek tot koppelen account"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Re-Authentication"
|
||||
msgstr "Account‑herauthenticatie"
|
||||
|
||||
@@ -1939,6 +1943,7 @@ msgid "Attempts sealing the document again, useful for after a code change has o
|
||||
msgstr "Probeert het document opnieuw te verzegelen, handig nadat een codewijziging is gedaan om een foutief document op te lossen."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Audit Log"
|
||||
msgstr "Auditlog"
|
||||
|
||||
@@ -1947,6 +1952,7 @@ msgid "Audit Logs"
|
||||
msgstr "Auditlogs"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Authentication Level"
|
||||
msgstr "Authenticatieniveau"
|
||||
|
||||
@@ -2967,6 +2973,7 @@ msgstr "Aangemaakt"
|
||||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Created At"
|
||||
msgstr "Aangemaakt op"
|
||||
|
||||
@@ -3111,7 +3118,7 @@ msgstr "Standaardwaarde"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr ""
|
||||
msgstr "Documenteigendom delegeren"
|
||||
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
msgid "delete"
|
||||
@@ -3259,6 +3266,7 @@ msgstr "Verwijder je account en alle inhoud, inclusief voltooide documenten. Dez
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Deleted"
|
||||
msgstr "Verwijderd"
|
||||
|
||||
@@ -3272,6 +3280,7 @@ msgstr "Bestemming"
|
||||
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Details"
|
||||
msgstr "Details"
|
||||
|
||||
@@ -3328,6 +3337,7 @@ msgstr "Ontwikkelaarsmodus"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Device"
|
||||
msgstr "Apparaat"
|
||||
|
||||
@@ -3679,7 +3689,7 @@ msgstr "Document geopend"
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Document ownership delegated"
|
||||
msgstr ""
|
||||
msgstr "Documenteigendom gedelegeerd"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
@@ -4090,6 +4100,8 @@ msgstr "Kennisgeving elektronische handtekening"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx
|
||||
@@ -4120,10 +4132,6 @@ msgstr "E-mailadres al bevestigd"
|
||||
msgid "Email already exists"
|
||||
msgstr "E-mailadres bestaat al"
|
||||
|
||||
#: apps/remix/app/components/general/direct-template/direct-template-configure-form.tsx
|
||||
msgid "Email cannot already exist in the template"
|
||||
msgstr "E‑mail mag nog niet in de sjabloon bestaan"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx
|
||||
msgid "Email Confirmed!"
|
||||
msgstr "E‑mail bevestigd!"
|
||||
@@ -4290,7 +4298,7 @@ msgstr "SSO-portaal inschakelen"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Enable team API tokens to delegate document ownership to another team member."
|
||||
msgstr ""
|
||||
msgstr "Schakel team-API-tokens in om documenteigendom aan een ander teamlid te delegeren."
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
@@ -4309,6 +4317,10 @@ msgstr "Als je het account inschakelt, kan de gebruiker het account weer gebruik
|
||||
msgid "Enclosed Document"
|
||||
msgstr "Bijgevoegd document"
|
||||
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Bijgevoegde documenten"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Voer een naam in voor je nieuwe map. Mappen helpen je je items te organiseren."
|
||||
@@ -4384,6 +4396,7 @@ msgid "Envelope Duplicated"
|
||||
msgstr "Envelope gedupliceerd"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Envelope ID"
|
||||
msgstr "Envelope-ID"
|
||||
|
||||
@@ -5081,6 +5094,7 @@ msgid "I am required to receive a copy of this document"
|
||||
msgstr "Ik moet een kopie van dit document ontvangen"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "I am the owner of this document"
|
||||
msgstr "Ik ben de eigenaar van dit document"
|
||||
|
||||
@@ -5308,6 +5322,8 @@ msgstr "Factuur"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "IP Address"
|
||||
msgstr "IP‑adres"
|
||||
|
||||
@@ -5420,6 +5436,7 @@ msgid "Last updated"
|
||||
msgstr "Laatst bijgewerkt"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Last Updated"
|
||||
msgstr "Laatst bijgewerkt"
|
||||
|
||||
@@ -5632,7 +5649,7 @@ msgstr "Organisatie beheren"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
msgid "Manage Organisation"
|
||||
msgstr ""
|
||||
msgstr "Organisatie beheren"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations._index.tsx
|
||||
msgid "Manage organisations"
|
||||
@@ -5881,6 +5898,7 @@ msgid "My Folder"
|
||||
msgstr "Mijn map"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "N/A"
|
||||
msgstr "n.v.t."
|
||||
|
||||
@@ -6407,6 +6425,7 @@ msgstr "Organisatie-instellingen overschrijven"
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Owner"
|
||||
msgstr "Eigenaar"
|
||||
|
||||
@@ -6457,6 +6476,7 @@ msgid "Passkey name"
|
||||
msgstr "Naam van passkey"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Passkey Re-Authentication"
|
||||
msgstr "Passkey‑herauthenticatie"
|
||||
|
||||
@@ -6483,6 +6503,7 @@ msgid "Password"
|
||||
msgstr "Wachtwoord"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Password Re-Authentication"
|
||||
msgstr "Wachtwoordherauthenticatie"
|
||||
|
||||
@@ -6953,6 +6974,7 @@ msgid "Ready"
|
||||
msgstr "Klaar"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Reason"
|
||||
msgstr "Reden"
|
||||
|
||||
@@ -7039,6 +7061,7 @@ msgstr "Ontvanger bijgewerkt"
|
||||
#: apps/remix/app/components/general/template/template-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Recipients"
|
||||
msgstr "Ontvangers"
|
||||
|
||||
@@ -7116,6 +7139,7 @@ msgstr "Document weigeren"
|
||||
#: apps/remix/app/components/general/stack-avatars-with-tooltip.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Rejected"
|
||||
msgstr "Geweigerd"
|
||||
|
||||
@@ -7356,7 +7380,7 @@ msgstr "Terugkeren"
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx
|
||||
msgid "Return Home"
|
||||
msgstr ""
|
||||
msgstr "Terug naar startpagina"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/o.$orgUrl.signin.tsx
|
||||
msgid "Return to Documenso sign in page here"
|
||||
@@ -7787,6 +7811,7 @@ msgstr "Verzenden..."
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Sent"
|
||||
msgstr "Verzonden"
|
||||
|
||||
@@ -8017,6 +8042,7 @@ msgstr "Schrijf uw initialen in het veld"
|
||||
#: apps/remix/app/components/general/envelope-signing/envelope-signer-form.tsx
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/types.ts
|
||||
@@ -8025,6 +8051,7 @@ msgid "Signature"
|
||||
msgstr "Handtekening"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signature ID"
|
||||
msgstr "Handtekening‑ID"
|
||||
|
||||
@@ -8050,6 +8077,7 @@ msgstr "Verzamelde handtekeningen"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/ui/components/document/document-read-only-fields.tsx
|
||||
#: packages/ui/components/document/envelope-recipient-field-tooltip.tsx
|
||||
msgid "Signed"
|
||||
@@ -8075,6 +8103,7 @@ msgid "Signer"
|
||||
msgstr "Ondertekenaar"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signer Events"
|
||||
msgstr "Ondertekenaarsgebeurtenissen"
|
||||
|
||||
@@ -8089,10 +8118,12 @@ msgid "Signing"
|
||||
msgstr "Ondertekenen"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing Certificate"
|
||||
msgstr "Ondertekeningscertificaat"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing certificate provided by"
|
||||
msgstr "Ondertekeningscertificaat verstrekt door"
|
||||
|
||||
@@ -8300,6 +8331,7 @@ msgstr "Statistieken"
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
@@ -8865,7 +8897,7 @@ msgstr "De documenteigenaar is op de hoogte gebracht van je beslissing. Indien n
|
||||
#. placeholder {1}: data.teamName
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "The document ownership was delegated to {0} on behalf of {1}"
|
||||
msgstr ""
|
||||
msgstr "De documenteigendom is namens {1} gedelegeerd aan {0}"
|
||||
|
||||
#: apps/remix/app/components/dialogs/template-use-dialog.tsx
|
||||
msgid "The document was created but could not be sent to recipients."
|
||||
@@ -9442,6 +9474,7 @@ msgstr "Tijdzone"
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx
|
||||
msgid "Time Zone"
|
||||
@@ -9633,6 +9666,7 @@ msgstr "Herstelcodes voor twee‑factor‑authenticatie worden gebruikt om toega
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Twee‑factor‑authenticatie"
|
||||
|
||||
@@ -9649,6 +9683,7 @@ msgid "Two-factor authentication has been disabled for your account. You will no
|
||||
msgstr "Twee‑factor‑authenticatie is uitgeschakeld voor je account. Je hoeft niet langer een code van je authenticator‑app in te voeren bij het inloggen."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Re-Authentication"
|
||||
msgstr "Twee‑factor‑herauthenticatie"
|
||||
|
||||
@@ -9782,6 +9817,10 @@ msgstr "Ongedaan maken"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Unknown"
|
||||
msgstr "Onbekend"
|
||||
|
||||
@@ -10084,10 +10123,12 @@ msgstr "Gebruik je passkey voor authenticatie"
|
||||
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User"
|
||||
msgstr "Gebruiker"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User Agent"
|
||||
msgstr "User Agent"
|
||||
|
||||
@@ -10331,6 +10372,7 @@ msgstr "Bekijk de DNS-records voor dit e-maildomein"
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-list.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Viewed"
|
||||
msgstr "Bekeken"
|
||||
|
||||
@@ -11654,3 +11696,4 @@ msgstr "Uw verificatiecode:"
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
msgid "your-domain.com another-domain.com"
|
||||
msgstr "your-domain.com another-domain.com"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: pl\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2025-12-15 02:39\n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Polish\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
|
||||
@@ -244,6 +244,7 @@ msgid "{0} Teams"
|
||||
msgstr "Zespół {0}"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{browserInfo} on {os}"
|
||||
msgstr "{browserInfo} na {os}"
|
||||
|
||||
@@ -475,6 +476,7 @@ msgid "{teamName} has invited you to {action} {documentName}"
|
||||
msgstr "Sprawdź i {action} dokument „{documentName}” utworzony przez zespół {teamName}"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{userAgent}"
|
||||
msgstr "{userAgent}"
|
||||
|
||||
@@ -955,6 +957,7 @@ msgid "Account"
|
||||
msgstr "Konto"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Authentication"
|
||||
msgstr "Konto"
|
||||
|
||||
@@ -992,6 +995,7 @@ msgid "Account Linking Request"
|
||||
msgstr "Prośba o połączenie konta"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Re-Authentication"
|
||||
msgstr "Konto"
|
||||
|
||||
@@ -1939,6 +1943,7 @@ msgid "Attempts sealing the document again, useful for after a code change has o
|
||||
msgstr "Ponowna próba zapieczętowania dokumentu jest przydatna po zmianie kodu, aby usunąć błędy dokumentu."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Audit Log"
|
||||
msgstr "Dziennik logów"
|
||||
|
||||
@@ -1947,6 +1952,7 @@ msgid "Audit Logs"
|
||||
msgstr "Dziennik logów"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Authentication Level"
|
||||
msgstr "Poziom uwierzytelniania"
|
||||
|
||||
@@ -2967,6 +2973,7 @@ msgstr "Utworzono"
|
||||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Created At"
|
||||
msgstr "Utworzono"
|
||||
|
||||
@@ -3111,7 +3118,7 @@ msgstr "Domyślna wartość"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr ""
|
||||
msgstr "Zmień właściciela dokumentu"
|
||||
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
msgid "delete"
|
||||
@@ -3259,6 +3266,7 @@ msgstr "Usuń swoje konto i wszystkie jego dane, w tym zakończone dokumenty. Ta
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Deleted"
|
||||
msgstr "Usunięto"
|
||||
|
||||
@@ -3272,6 +3280,7 @@ msgstr "Adres docelowy"
|
||||
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Details"
|
||||
msgstr "Szczegóły"
|
||||
|
||||
@@ -3328,6 +3337,7 @@ msgstr "Tryb programisty"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Device"
|
||||
msgstr "Urządzenie"
|
||||
|
||||
@@ -3679,7 +3689,7 @@ msgstr "Otwarto dokument"
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Document ownership delegated"
|
||||
msgstr ""
|
||||
msgstr "Zmieniono właściciela dokumentu"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
@@ -4090,6 +4100,8 @@ msgstr "Informacje o podpisie elektronicznym"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx
|
||||
@@ -4120,10 +4132,6 @@ msgstr "Adres e-mail został już potwierdzony"
|
||||
msgid "Email already exists"
|
||||
msgstr "Adres e-mail już istnieje"
|
||||
|
||||
#: apps/remix/app/components/general/direct-template/direct-template-configure-form.tsx
|
||||
msgid "Email cannot already exist in the template"
|
||||
msgstr "Adres e-mail nie może już istnieć w szablonie"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx
|
||||
msgid "Email Confirmed!"
|
||||
msgstr "Adres e-mail został potwierdzony!"
|
||||
@@ -4290,7 +4298,7 @@ msgstr "Włącz logowanie SSO"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Enable team API tokens to delegate document ownership to another team member."
|
||||
msgstr ""
|
||||
msgstr "Włącz tokeny API zespołu, aby zmienić właściciela dokumentu na innego użytkownika zespołu."
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
@@ -4309,6 +4317,10 @@ msgstr "Włączenie konta spowoduje, że użytkownik będzie mógł ponownie kor
|
||||
msgid "Enclosed Document"
|
||||
msgstr "Załączony dokument"
|
||||
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Załączone dokumenty"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Wpisz nazwę nowego folderu. Foldery pomagają uporządkować elementy."
|
||||
@@ -4384,6 +4396,7 @@ msgid "Envelope Duplicated"
|
||||
msgstr "Zduplikowano kopertę"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Envelope ID"
|
||||
msgstr "Identyfikator koperty"
|
||||
|
||||
@@ -5081,6 +5094,7 @@ msgid "I am required to receive a copy of this document"
|
||||
msgstr "Muszę otrzymać kopię dokumentu"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "I am the owner of this document"
|
||||
msgstr "Jestem właścicielem tego dokumentu"
|
||||
|
||||
@@ -5308,6 +5322,8 @@ msgstr "Faktura"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "IP Address"
|
||||
msgstr "Adres IP"
|
||||
|
||||
@@ -5420,6 +5436,7 @@ msgid "Last updated"
|
||||
msgstr "Zaktualizowano"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Last Updated"
|
||||
msgstr "Zaktualizowano"
|
||||
|
||||
@@ -5632,7 +5649,7 @@ msgstr "Zarządzaj organizacją"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
msgid "Manage Organisation"
|
||||
msgstr ""
|
||||
msgstr "Zarządzaj organizacją"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations._index.tsx
|
||||
msgid "Manage organisations"
|
||||
@@ -5881,6 +5898,7 @@ msgid "My Folder"
|
||||
msgstr "Mój folder"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "N/A"
|
||||
msgstr "Nie dotyczy"
|
||||
|
||||
@@ -6407,6 +6425,7 @@ msgstr "Nadpisz ustawienia organizacji"
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Owner"
|
||||
msgstr "Właściciel"
|
||||
|
||||
@@ -6457,6 +6476,7 @@ msgid "Passkey name"
|
||||
msgstr "Nazwa klucza dostępu"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Passkey Re-Authentication"
|
||||
msgstr "Klucz dostępu"
|
||||
|
||||
@@ -6483,6 +6503,7 @@ msgid "Password"
|
||||
msgstr "Hasło"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Password Re-Authentication"
|
||||
msgstr "Hasło"
|
||||
|
||||
@@ -6953,6 +6974,7 @@ msgid "Ready"
|
||||
msgstr "Gotowy"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Reason"
|
||||
msgstr "Rola"
|
||||
|
||||
@@ -7039,6 +7061,7 @@ msgstr "Odbiorca został zaktualizowany"
|
||||
#: apps/remix/app/components/general/template/template-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Recipients"
|
||||
msgstr "Odbiorcy"
|
||||
|
||||
@@ -7116,6 +7139,7 @@ msgstr "Odrzuć dokument"
|
||||
#: apps/remix/app/components/general/stack-avatars-with-tooltip.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Rejected"
|
||||
msgstr "Odrzucono"
|
||||
|
||||
@@ -7216,7 +7240,7 @@ msgstr "Odpowiedz na adres"
|
||||
#: packages/ui/primitives/document-flow/add-subject.tsx
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx
|
||||
msgid "Reply To Email <0>(Optional)</0>"
|
||||
msgstr "Odpowiedź na e-mail <0>(opcjonalnie)</0>"
|
||||
msgstr "Odpowiedz na wiadomość <0>(opcjonalnie)</0>"
|
||||
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
msgid "Request"
|
||||
@@ -7356,7 +7380,7 @@ msgstr "Wróć"
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx
|
||||
msgid "Return Home"
|
||||
msgstr ""
|
||||
msgstr "Powrót do strony głównej"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/o.$orgUrl.signin.tsx
|
||||
msgid "Return to Documenso sign in page here"
|
||||
@@ -7787,6 +7811,7 @@ msgstr "Wysyłanie..."
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Sent"
|
||||
msgstr "Wysłano"
|
||||
|
||||
@@ -7843,7 +7868,7 @@ msgstr "Udostępnij link"
|
||||
|
||||
#: packages/ui/components/document/document-share-button.tsx
|
||||
msgid "Share your signing experience!"
|
||||
msgstr "Podziel się swoimi wrażeniami związanymi z podpisywaniem!"
|
||||
msgstr "Podziel się wrażeniami z podpisywania!"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.public-profile.tsx
|
||||
msgid "Show"
|
||||
@@ -8017,6 +8042,7 @@ msgstr "Podpisz inicjały w polu"
|
||||
#: apps/remix/app/components/general/envelope-signing/envelope-signer-form.tsx
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/types.ts
|
||||
@@ -8025,6 +8051,7 @@ msgid "Signature"
|
||||
msgstr "Podpis"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signature ID"
|
||||
msgstr "Identyfikator podpisu"
|
||||
|
||||
@@ -8050,6 +8077,7 @@ msgstr "Liczba podpisów"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/ui/components/document/document-read-only-fields.tsx
|
||||
#: packages/ui/components/document/envelope-recipient-field-tooltip.tsx
|
||||
msgid "Signed"
|
||||
@@ -8075,6 +8103,7 @@ msgid "Signer"
|
||||
msgstr "Podpisujący"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signer Events"
|
||||
msgstr "Zdarzenia podpisujących"
|
||||
|
||||
@@ -8089,10 +8118,12 @@ msgid "Signing"
|
||||
msgstr "Podpisuje"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing Certificate"
|
||||
msgstr "Certyfikat podpisu"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing certificate provided by"
|
||||
msgstr "Certyfikat podpisu został dostarczony przez"
|
||||
|
||||
@@ -8300,6 +8331,7 @@ msgstr "Statystyki"
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
@@ -8865,7 +8897,7 @@ msgstr "Właściciel dokumentu został poinformowany o Twojej decyzji. Może si
|
||||
#. placeholder {1}: data.teamName
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "The document ownership was delegated to {0} on behalf of {1}"
|
||||
msgstr ""
|
||||
msgstr "Zmieniono właściciela dokumentu na {0} z zespołu {1}"
|
||||
|
||||
#: apps/remix/app/components/dialogs/template-use-dialog.tsx
|
||||
msgid "The document was created but could not be sent to recipients."
|
||||
@@ -9442,6 +9474,7 @@ msgstr "Strefa czasowa"
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx
|
||||
msgid "Time Zone"
|
||||
@@ -9633,6 +9666,7 @@ msgstr "Kody odzyskiwania są używane do odzyskania dostępu do konta, w przypa
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Weryfikacja dwuetapowa"
|
||||
|
||||
@@ -9649,6 +9683,7 @@ msgid "Two-factor authentication has been disabled for your account. You will no
|
||||
msgstr "Weryfikacja dwuetapowa konta została wyłączona. Wpisywanie kodu z aplikacji uwierzytelniającej podczas logowania nie będzie już wymagane."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Re-Authentication"
|
||||
msgstr "Weryfikacja dwuetapowa"
|
||||
|
||||
@@ -9782,6 +9817,10 @@ msgstr "Cofnij"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Unknown"
|
||||
msgstr "Nieznany"
|
||||
|
||||
@@ -10084,10 +10123,12 @@ msgstr "Użyj klucza dostępu do uwierzytelniania"
|
||||
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User"
|
||||
msgstr "Użytkownik"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User Agent"
|
||||
msgstr "User agent"
|
||||
|
||||
@@ -10331,6 +10372,7 @@ msgstr "Wyświetl rekordy DNS dla tej domeny"
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-list.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Viewed"
|
||||
msgstr "Wyświetlono"
|
||||
|
||||
@@ -10988,12 +11030,12 @@ msgstr "Aktualizujesz adres <0>{0}</0>"
|
||||
|
||||
#: apps/remix/app/components/dialogs/team-member-update-dialog.tsx
|
||||
msgid "You are currently updating <0>{memberName}</0>."
|
||||
msgstr "Aktualizujesz adres <0>{memberName}</0>."
|
||||
msgstr "Aktualizujesz użytkownika <0>{memberName}</0>."
|
||||
|
||||
#: apps/remix/app/components/dialogs/admin-organisation-member-update-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/organisation-member-update-dialog.tsx
|
||||
msgid "You are currently updating <0>{organisationMemberName}</0>."
|
||||
msgstr "Aktualnie aktualizujesz <0>{organisationMemberName}</0>."
|
||||
msgstr "Aktualizujesz użytkownika <0>{organisationMemberName}</0>."
|
||||
|
||||
#: apps/remix/app/components/tables/settings-security-passkey-table-actions.tsx
|
||||
msgid "You are currently updating the <0>{passkeyName}</0> passkey."
|
||||
@@ -11654,3 +11696,4 @@ msgstr "Twój kod weryfikacyjny:"
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
msgid "your-domain.com another-domain.com"
|
||||
msgstr "your-domain.com another-domain.com"
|
||||
|
||||
|
||||
@@ -239,6 +239,7 @@ msgid "{0} Teams"
|
||||
msgstr "{0} Equipes"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{browserInfo} on {os}"
|
||||
msgstr "{browserInfo} em {os}"
|
||||
|
||||
@@ -470,6 +471,7 @@ msgid "{teamName} has invited you to {action} {documentName}"
|
||||
msgstr "{teamName} convidou você para {action} {documentName}"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{userAgent}"
|
||||
msgstr "{userAgent}"
|
||||
|
||||
@@ -950,6 +952,7 @@ msgid "Account"
|
||||
msgstr "Conta"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Authentication"
|
||||
msgstr "Autenticação da Conta"
|
||||
|
||||
@@ -987,6 +990,7 @@ msgid "Account Linking Request"
|
||||
msgstr "Solicitação de Vínculo de Conta"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Re-Authentication"
|
||||
msgstr "Reautenticação da Conta"
|
||||
|
||||
@@ -1934,6 +1938,7 @@ msgid "Attempts sealing the document again, useful for after a code change has o
|
||||
msgstr "Tenta selar o documento novamente, útil após uma alteração de código ter ocorrido para resolver um documento com erro."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Audit Log"
|
||||
msgstr "Log de Auditoria"
|
||||
|
||||
@@ -1942,6 +1947,7 @@ msgid "Audit Logs"
|
||||
msgstr "Logs de Auditoria"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Authentication Level"
|
||||
msgstr "Nível de Autenticação"
|
||||
|
||||
@@ -2962,6 +2968,7 @@ msgstr "Criado"
|
||||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Created At"
|
||||
msgstr "Criado em"
|
||||
|
||||
@@ -3254,6 +3261,7 @@ msgstr "Exclua sua conta e todo o seu conteúdo, incluindo documentos concluído
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Deleted"
|
||||
msgstr "Excluído"
|
||||
|
||||
@@ -3267,6 +3275,7 @@ msgstr "Destino"
|
||||
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Details"
|
||||
msgstr "Detalhes"
|
||||
|
||||
@@ -3323,6 +3332,7 @@ msgstr "Modo Desenvolvedor"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Device"
|
||||
msgstr "Dispositivo"
|
||||
|
||||
@@ -4085,6 +4095,8 @@ msgstr "Divulgação de Assinatura Eletrônica"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx
|
||||
@@ -4115,10 +4127,6 @@ msgstr "E-mail já confirmado"
|
||||
msgid "Email already exists"
|
||||
msgstr "E-mail já existe"
|
||||
|
||||
#: apps/remix/app/components/general/direct-template/direct-template-configure-form.tsx
|
||||
msgid "Email cannot already exist in the template"
|
||||
msgstr "O e-mail não pode já existir no modelo"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx
|
||||
msgid "Email Confirmed!"
|
||||
msgstr "E-mail Confirmado!"
|
||||
@@ -4304,6 +4312,10 @@ msgstr "Ativar a conta resulta na possibilidade de o usuário usar a conta novam
|
||||
msgid "Enclosed Document"
|
||||
msgstr "Documento Anexo"
|
||||
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Enclosed Documents"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "Digite um nome para sua nova pasta. As pastas ajudam você a organizar seus itens."
|
||||
@@ -4379,6 +4391,7 @@ msgid "Envelope Duplicated"
|
||||
msgstr "Envelope Duplicado"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Envelope ID"
|
||||
msgstr "ID do Envelope"
|
||||
|
||||
@@ -5076,6 +5089,7 @@ msgid "I am required to receive a copy of this document"
|
||||
msgstr "Sou obrigado a receber uma cópia deste documento"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "I am the owner of this document"
|
||||
msgstr "Eu sou o proprietário deste documento"
|
||||
|
||||
@@ -5303,6 +5317,8 @@ msgstr "Fatura"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "IP Address"
|
||||
msgstr "Endereço IP"
|
||||
|
||||
@@ -5415,6 +5431,7 @@ msgid "Last updated"
|
||||
msgstr "Última atualização"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Last Updated"
|
||||
msgstr "Última Atualização"
|
||||
|
||||
@@ -5876,6 +5893,7 @@ msgid "My Folder"
|
||||
msgstr "Minha Pasta"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "N/A"
|
||||
msgstr "N/A"
|
||||
|
||||
@@ -6402,6 +6420,7 @@ msgstr "Substituir configurações da organização"
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Owner"
|
||||
msgstr "Proprietário"
|
||||
|
||||
@@ -6452,6 +6471,7 @@ msgid "Passkey name"
|
||||
msgstr "Nome da Passkey"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Passkey Re-Authentication"
|
||||
msgstr "Reautenticação por Passkey"
|
||||
|
||||
@@ -6478,6 +6498,7 @@ msgid "Password"
|
||||
msgstr "Senha"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Password Re-Authentication"
|
||||
msgstr "Reautenticação por Senha"
|
||||
|
||||
@@ -6948,6 +6969,7 @@ msgid "Ready"
|
||||
msgstr "Pronto"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Reason"
|
||||
msgstr "Motivo"
|
||||
|
||||
@@ -7034,6 +7056,7 @@ msgstr "Destinatário atualizado"
|
||||
#: apps/remix/app/components/general/template/template-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Recipients"
|
||||
msgstr "Destinatários"
|
||||
|
||||
@@ -7111,6 +7134,7 @@ msgstr "Rejeitar Documento"
|
||||
#: apps/remix/app/components/general/stack-avatars-with-tooltip.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Rejected"
|
||||
msgstr "Rejeitado"
|
||||
|
||||
@@ -7782,6 +7806,7 @@ msgstr "Enviando..."
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Sent"
|
||||
msgstr "Enviado"
|
||||
|
||||
@@ -8012,6 +8037,7 @@ msgstr "Assine suas iniciais no campo"
|
||||
#: apps/remix/app/components/general/envelope-signing/envelope-signer-form.tsx
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/types.ts
|
||||
@@ -8020,6 +8046,7 @@ msgid "Signature"
|
||||
msgstr "Assinatura"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signature ID"
|
||||
msgstr "ID da Assinatura"
|
||||
|
||||
@@ -8045,6 +8072,7 @@ msgstr "Assinaturas Coletadas"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/ui/components/document/document-read-only-fields.tsx
|
||||
#: packages/ui/components/document/envelope-recipient-field-tooltip.tsx
|
||||
msgid "Signed"
|
||||
@@ -8070,6 +8098,7 @@ msgid "Signer"
|
||||
msgstr "Signatário"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signer Events"
|
||||
msgstr "Eventos do Signatário"
|
||||
|
||||
@@ -8084,10 +8113,12 @@ msgid "Signing"
|
||||
msgstr "Assinando"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing Certificate"
|
||||
msgstr "Certificado de Assinatura"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing certificate provided by"
|
||||
msgstr "Certificado de assinatura fornecido por"
|
||||
|
||||
@@ -8295,6 +8326,7 @@ msgstr "Estatísticas"
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
@@ -9437,6 +9469,7 @@ msgstr "Fuso horário"
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx
|
||||
msgid "Time Zone"
|
||||
@@ -9628,6 +9661,7 @@ msgstr "Os códigos de recuperação da autenticação de dois fatores são usad
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Autenticação de Dois Fatores"
|
||||
|
||||
@@ -9644,6 +9678,7 @@ msgid "Two-factor authentication has been disabled for your account. You will no
|
||||
msgstr "A autenticação de dois fatores foi desativada para sua conta. Você não precisará mais inserir um código do seu aplicativo autenticador ao entrar."
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Re-Authentication"
|
||||
msgstr "Reautenticação de Dois Fatores"
|
||||
|
||||
@@ -9777,6 +9812,10 @@ msgstr ""
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Unknown"
|
||||
msgstr "Desconhecido"
|
||||
|
||||
@@ -10079,10 +10118,12 @@ msgstr "Use sua passkey para autenticação"
|
||||
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User"
|
||||
msgstr "Usuário"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User Agent"
|
||||
msgstr "Agente de Usuário"
|
||||
|
||||
@@ -10326,6 +10367,7 @@ msgstr "Visualizar os registros DNS para este domínio de e-mail"
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-list.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Viewed"
|
||||
msgstr "Visualizado"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: zh\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2025-12-15 02:39\n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
@@ -244,6 +244,7 @@ msgid "{0} Teams"
|
||||
msgstr "{0} 个团队"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{browserInfo} on {os}"
|
||||
msgstr "{browserInfo} 于 {os}"
|
||||
|
||||
@@ -475,6 +476,7 @@ msgid "{teamName} has invited you to {action} {documentName}"
|
||||
msgstr "{teamName} 已邀请您 {action} {documentName}"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "{userAgent}"
|
||||
msgstr "{userAgent}"
|
||||
|
||||
@@ -955,6 +957,7 @@ msgid "Account"
|
||||
msgstr "账户"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Authentication"
|
||||
msgstr "账号验证"
|
||||
|
||||
@@ -992,6 +995,7 @@ msgid "Account Linking Request"
|
||||
msgstr "账户关联请求"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Account Re-Authentication"
|
||||
msgstr "账号重新验证"
|
||||
|
||||
@@ -1939,6 +1943,7 @@ msgid "Attempts sealing the document again, useful for after a code change has o
|
||||
msgstr "将再次尝试对文档进行封存,这在代码变更后用于修复错误文档时非常有用。"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Audit Log"
|
||||
msgstr "审计日志"
|
||||
|
||||
@@ -1947,6 +1952,7 @@ msgid "Audit Logs"
|
||||
msgstr "审计日志"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Authentication Level"
|
||||
msgstr "验证级别"
|
||||
|
||||
@@ -2967,6 +2973,7 @@ msgstr "已创建"
|
||||
#: apps/remix/app/components/tables/admin-organisations-table.tsx
|
||||
#: apps/remix/app/components/tables/user-organisations-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Created At"
|
||||
msgstr "创建时间"
|
||||
|
||||
@@ -3111,7 +3118,7 @@ msgstr "默认值"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Delegate Document Ownership"
|
||||
msgstr ""
|
||||
msgstr "委派文档所有权"
|
||||
|
||||
#: apps/remix/app/components/dialogs/document-delete-dialog.tsx
|
||||
msgid "delete"
|
||||
@@ -3259,6 +3266,7 @@ msgstr "删除你的账号及其所有内容,包括已完成的文档。此操
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Deleted"
|
||||
msgstr "已删除"
|
||||
|
||||
@@ -3272,6 +3280,7 @@ msgstr "目标地址"
|
||||
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Details"
|
||||
msgstr "详情"
|
||||
|
||||
@@ -3328,6 +3337,7 @@ msgstr "开发者模式"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Device"
|
||||
msgstr "设备"
|
||||
|
||||
@@ -3679,7 +3689,7 @@ msgstr "文档已打开"
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgctxt "Audit log format"
|
||||
msgid "Document ownership delegated"
|
||||
msgstr ""
|
||||
msgstr "文档所有权已被委派"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-status.tsx
|
||||
msgid "Document pending"
|
||||
@@ -4090,6 +4100,8 @@ msgstr "电子签名披露"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/add-signers.tsx
|
||||
@@ -4120,10 +4132,6 @@ msgstr "邮箱已确认"
|
||||
msgid "Email already exists"
|
||||
msgstr "邮箱已存在"
|
||||
|
||||
#: apps/remix/app/components/general/direct-template/direct-template-configure-form.tsx
|
||||
msgid "Email cannot already exist in the template"
|
||||
msgstr "该邮箱不能已在模板中存在"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/verify-email.$token.tsx
|
||||
msgid "Email Confirmed!"
|
||||
msgstr "邮箱已确认!"
|
||||
@@ -4290,7 +4298,7 @@ msgstr "启用 SSO 门户"
|
||||
|
||||
#: apps/remix/app/components/forms/document-preferences-form.tsx
|
||||
msgid "Enable team API tokens to delegate document ownership to another team member."
|
||||
msgstr ""
|
||||
msgstr "启用团队 API 令牌,将文档所有权委派给另一位团队成员。"
|
||||
|
||||
#: apps/remix/app/components/dialogs/webhook-create-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/webhook-edit-dialog.tsx
|
||||
@@ -4309,6 +4317,10 @@ msgstr "启用账户后,用户将可以再次使用账户,以及与其相关
|
||||
msgid "Enclosed Document"
|
||||
msgstr "随附文档"
|
||||
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "随附文件"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgstr "为新文件夹输入名称。文件夹可以帮助您整理项目。"
|
||||
@@ -4384,6 +4396,7 @@ msgid "Envelope Duplicated"
|
||||
msgstr "信封已复制"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Envelope ID"
|
||||
msgstr "信封 ID"
|
||||
|
||||
@@ -5081,6 +5094,7 @@ msgid "I am required to receive a copy of this document"
|
||||
msgstr "我需要接收此文档的副本"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "I am the owner of this document"
|
||||
msgstr "我是此文档的所有者"
|
||||
|
||||
@@ -5308,6 +5322,8 @@ msgstr "发票"
|
||||
#: apps/remix/app/components/tables/settings-security-activity-table.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/settings+/security.sessions.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "IP Address"
|
||||
msgstr "IP 地址"
|
||||
|
||||
@@ -5420,6 +5436,7 @@ msgid "Last updated"
|
||||
msgstr "最后更新"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Last Updated"
|
||||
msgstr "最后更新"
|
||||
|
||||
@@ -5632,7 +5649,7 @@ msgstr "管理组织"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl._index.tsx
|
||||
msgid "Manage Organisation"
|
||||
msgstr ""
|
||||
msgstr "管理组织"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/organisations._index.tsx
|
||||
msgid "Manage organisations"
|
||||
@@ -5881,6 +5898,7 @@ msgid "My Folder"
|
||||
msgstr "我的文件夹"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "N/A"
|
||||
msgstr "N/A"
|
||||
|
||||
@@ -6407,6 +6425,7 @@ msgstr "覆盖组织设置"
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/dashboard.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Owner"
|
||||
msgstr "所有者"
|
||||
|
||||
@@ -6457,6 +6476,7 @@ msgid "Passkey name"
|
||||
msgstr "通行密钥名称"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Passkey Re-Authentication"
|
||||
msgstr "通行密钥重新验证"
|
||||
|
||||
@@ -6483,6 +6503,7 @@ msgid "Password"
|
||||
msgstr "密码"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Password Re-Authentication"
|
||||
msgstr "密码重新验证"
|
||||
|
||||
@@ -6953,6 +6974,7 @@ msgid "Ready"
|
||||
msgstr "就绪"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Reason"
|
||||
msgstr "原因"
|
||||
|
||||
@@ -7039,6 +7061,7 @@ msgstr "收件人已更新"
|
||||
#: apps/remix/app/components/general/template/template-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/admin+/documents.$id.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Recipients"
|
||||
msgstr "收件人"
|
||||
|
||||
@@ -7116,6 +7139,7 @@ msgstr "拒签文档"
|
||||
#: apps/remix/app/components/general/stack-avatars-with-tooltip.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/constants/document.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Rejected"
|
||||
msgstr "已拒签"
|
||||
|
||||
@@ -7356,7 +7380,7 @@ msgstr "返回"
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/rejected.tsx
|
||||
#: apps/remix/app/routes/_recipient+/sign.$token+/waiting.tsx
|
||||
msgid "Return Home"
|
||||
msgstr ""
|
||||
msgstr "返回主页"
|
||||
|
||||
#: apps/remix/app/routes/_unauthenticated+/o.$orgUrl.signin.tsx
|
||||
msgid "Return to Documenso sign in page here"
|
||||
@@ -7787,6 +7811,7 @@ msgstr "正在发送..."
|
||||
#: apps/remix/app/components/general/webhook-logs-sheet.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Sent"
|
||||
msgstr "已发送"
|
||||
|
||||
@@ -8017,6 +8042,7 @@ msgstr "在字段中填写您的姓名首字母缩写"
|
||||
#: apps/remix/app/components/general/envelope-signing/envelope-signer-form.tsx
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/utils/fields.ts
|
||||
#: packages/ui/primitives/document-flow/add-fields.tsx
|
||||
#: packages/ui/primitives/document-flow/types.ts
|
||||
@@ -8025,6 +8051,7 @@ msgid "Signature"
|
||||
msgstr "签名"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signature ID"
|
||||
msgstr "签名 ID"
|
||||
|
||||
@@ -8050,6 +8077,7 @@ msgstr "收集到的签名数量"
|
||||
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/ui/components/document/document-read-only-fields.tsx
|
||||
#: packages/ui/components/document/envelope-recipient-field-tooltip.tsx
|
||||
msgid "Signed"
|
||||
@@ -8075,6 +8103,7 @@ msgid "Signer"
|
||||
msgstr "签署人"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signer Events"
|
||||
msgstr "签署人事件"
|
||||
|
||||
@@ -8089,10 +8118,12 @@ msgid "Signing"
|
||||
msgstr "签署中"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing Certificate"
|
||||
msgstr "签署证书"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Signing certificate provided by"
|
||||
msgstr "签署证书由以下机构提供"
|
||||
|
||||
@@ -8300,6 +8331,7 @@ msgstr "统计"
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/settings.webhooks.$id._index.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
@@ -8865,7 +8897,7 @@ msgstr "文档所有者已收到您的决定通知。如有需要,他们可能
|
||||
#. placeholder {1}: data.teamName
|
||||
#: packages/lib/utils/document-audit-logs.ts
|
||||
msgid "The document ownership was delegated to {0} on behalf of {1}"
|
||||
msgstr ""
|
||||
msgstr "已代表 {1} 将该文档所有权委派给 {0}"
|
||||
|
||||
#: apps/remix/app/components/dialogs/template-use-dialog.tsx
|
||||
msgid "The document was created but could not be sent to recipients."
|
||||
@@ -9442,6 +9474,7 @@ msgstr "时区"
|
||||
#: apps/remix/app/components/embed/authoring/configure-document-advanced-settings.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/audit-log.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
#: packages/ui/primitives/document-flow/add-settings.tsx
|
||||
#: packages/ui/primitives/template-flow/add-template-settings.tsx
|
||||
msgid "Time Zone"
|
||||
@@ -9633,6 +9666,7 @@ msgstr "双重验证恢复代码用于在你无法访问验证器应用时登录
|
||||
|
||||
#: apps/remix/app/components/forms/signin.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "双重验证"
|
||||
|
||||
@@ -9649,6 +9683,7 @@ msgid "Two-factor authentication has been disabled for your account. You will no
|
||||
msgstr "你的账号已禁用双重验证。登录时将不再需要输入验证器应用中的验证码。"
|
||||
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/generate-certificate-pdf.ts
|
||||
msgid "Two-Factor Re-Authentication"
|
||||
msgstr "双重验证重新验证"
|
||||
|
||||
@@ -9782,6 +9817,10 @@ msgstr "撤销"
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Unknown"
|
||||
msgstr "未知"
|
||||
|
||||
@@ -10084,10 +10123,12 @@ msgstr "使用您的通行密钥进行认证"
|
||||
|
||||
#: apps/remix/app/components/tables/document-logs-table.tsx
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User"
|
||||
msgstr "用户"
|
||||
|
||||
#: apps/remix/app/components/tables/internal-audit-log-table.tsx
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "User Agent"
|
||||
msgstr "用户代理"
|
||||
|
||||
@@ -10331,6 +10372,7 @@ msgstr "查看此邮箱域名的 DNS 记录"
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-list.tsx
|
||||
#: apps/remix/app/components/general/document/document-page-view-recipients.tsx
|
||||
#: apps/remix/app/routes/_internal+/[__htmltopdf]+/certificate.tsx
|
||||
#: packages/lib/server-only/pdf/render-certificate.ts
|
||||
msgid "Viewed"
|
||||
msgstr "已查看"
|
||||
|
||||
@@ -11654,3 +11696,4 @@ msgstr "您的验证码:"
|
||||
#: apps/remix/app/routes/_authenticated+/o.$orgUrl.settings.sso.tsx
|
||||
msgid "your-domain.com another-domain.com"
|
||||
msgstr "your-domain.com another-domain.com"
|
||||
|
||||
|
||||
@@ -759,3 +759,5 @@ export type DocumentAuditLogByType<T = TDocumentAuditLog['type']> = Extract<
|
||||
TDocumentAuditLog,
|
||||
{ type: T }
|
||||
>;
|
||||
|
||||
export type TDocumentAuditLogBaseSchema = z.infer<typeof ZDocumentAuditLogBaseSchema>;
|
||||
|
||||
@@ -290,11 +290,12 @@ export const diffDocumentMetaChanges = (
|
||||
* Provide a userId to prefix the action with the user, example 'X did Y'.
|
||||
*/
|
||||
export const formatDocumentAuditLogAction = (
|
||||
_: I18n['_'],
|
||||
i18n: I18n,
|
||||
auditLog: TDocumentAuditLog,
|
||||
userId?: number,
|
||||
) => {
|
||||
const prefix = userId === auditLog.userId ? _(msg`You`) : auditLog.name || auditLog.email || '';
|
||||
const prefix =
|
||||
userId === auditLog.userId ? i18n._(msg`You`) : auditLog.name || auditLog.email || '';
|
||||
|
||||
const description = match(auditLog)
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.FIELD_CREATED }, () => ({
|
||||
@@ -452,7 +453,7 @@ export const formatDocumentAuditLogAction = (
|
||||
identified: msg`${prefix} moved the document to team`,
|
||||
}))
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_COMPLETED }, ({ data }) => {
|
||||
const userName = prefix || _(msg`Recipient`);
|
||||
const userName = prefix || i18n._(msg`Recipient`);
|
||||
|
||||
const result = match(data.recipientRole)
|
||||
.with(RecipientRole.SIGNER, () => msg`${userName} signed the document`)
|
||||
@@ -467,7 +468,7 @@ export const formatDocumentAuditLogAction = (
|
||||
};
|
||||
})
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_RECIPIENT_REJECTED }, ({ data }) => {
|
||||
const userName = prefix || _(msg`Recipient`);
|
||||
const userName = prefix || i18n._(msg`Recipient`);
|
||||
|
||||
const result = msg`${userName} rejected the document`;
|
||||
|
||||
@@ -477,7 +478,7 @@ export const formatDocumentAuditLogAction = (
|
||||
};
|
||||
})
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_ACCESS_AUTH_2FA_REQUESTED }, ({ data }) => {
|
||||
const userName = prefix || _(msg`Recipient`);
|
||||
const userName = prefix || i18n._(msg`Recipient`);
|
||||
|
||||
const result = msg`${userName} requested a 2FA token for the document`;
|
||||
|
||||
@@ -487,7 +488,7 @@ export const formatDocumentAuditLogAction = (
|
||||
};
|
||||
})
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_ACCESS_AUTH_2FA_VALIDATED }, ({ data }) => {
|
||||
const userName = prefix || _(msg`Recipient`);
|
||||
const userName = prefix || i18n._(msg`Recipient`);
|
||||
|
||||
const result = msg`${userName} validated a 2FA token for the document`;
|
||||
|
||||
@@ -497,7 +498,7 @@ export const formatDocumentAuditLogAction = (
|
||||
};
|
||||
})
|
||||
.with({ type: DOCUMENT_AUDIT_LOG_TYPE.DOCUMENT_ACCESS_AUTH_2FA_FAILED }, ({ data }) => {
|
||||
const userName = prefix || _(msg`Recipient`);
|
||||
const userName = prefix || i18n._(msg`Recipient`);
|
||||
|
||||
const result = msg`${userName} failed to validate a 2FA token for the document`;
|
||||
|
||||
@@ -541,6 +542,6 @@ export const formatDocumentAuditLogAction = (
|
||||
|
||||
return {
|
||||
prefix,
|
||||
description: _(prefix ? description.identified : description.anonymous),
|
||||
description: i18n._(prefix ? description.identified : description.anonymous),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -67,7 +67,7 @@ export const seedBlankDocument = async (
|
||||
teamId: number,
|
||||
options: CreateDocumentOptions = {},
|
||||
) => {
|
||||
const { key, createDocumentOptions = {} } = options;
|
||||
const { key, createDocumentOptions = {}, internalVersion = 1 } = options;
|
||||
|
||||
const documentData = await prisma.documentData.create({
|
||||
data: {
|
||||
@@ -87,7 +87,7 @@ export const seedBlankDocument = async (
|
||||
data: {
|
||||
id: prefixedId('envelope'),
|
||||
secondaryId: documentId.formattedDocumentId,
|
||||
internalVersion: 1,
|
||||
internalVersion,
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
documentMetaId: documentMeta.id,
|
||||
source: DocumentSource.DOCUMENT,
|
||||
@@ -287,7 +287,7 @@ export const seedDraftDocument = async (
|
||||
recipients: (User | string)[],
|
||||
options: CreateDocumentOptions = {},
|
||||
) => {
|
||||
const { key, createDocumentOptions = {} } = options;
|
||||
const { key, createDocumentOptions = {}, internalVersion = 1 } = options;
|
||||
|
||||
const documentData = await prisma.documentData.create({
|
||||
data: {
|
||||
@@ -307,7 +307,7 @@ export const seedDraftDocument = async (
|
||||
data: {
|
||||
id: prefixedId('envelope'),
|
||||
secondaryId: documentId.formattedDocumentId,
|
||||
internalVersion: 1,
|
||||
internalVersion,
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
documentMetaId: documentMeta.id,
|
||||
source: DocumentSource.DOCUMENT,
|
||||
@@ -372,6 +372,7 @@ export const seedDraftDocument = async (
|
||||
type CreateDocumentOptions = {
|
||||
key?: string | number;
|
||||
createDocumentOptions?: Partial<Prisma.EnvelopeUncheckedCreateInput>;
|
||||
internalVersion?: number;
|
||||
};
|
||||
|
||||
export const seedPendingDocument = async (
|
||||
@@ -380,7 +381,7 @@ export const seedPendingDocument = async (
|
||||
recipients: (User | string)[],
|
||||
options: CreateDocumentOptions = {},
|
||||
) => {
|
||||
const { key, createDocumentOptions = {} } = options;
|
||||
const { key, createDocumentOptions = {}, internalVersion = 1 } = options;
|
||||
|
||||
const documentData = await prisma.documentData.create({
|
||||
data: {
|
||||
@@ -400,7 +401,7 @@ export const seedPendingDocument = async (
|
||||
data: {
|
||||
id: prefixedId('envelope'),
|
||||
secondaryId: documentId.formattedDocumentId,
|
||||
internalVersion: 1,
|
||||
internalVersion,
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
documentMetaId: documentMeta.id,
|
||||
source: DocumentSource.DOCUMENT,
|
||||
@@ -620,7 +621,7 @@ export const seedCompletedDocument = async (
|
||||
recipients: (User | string)[],
|
||||
options: CreateDocumentOptions = {},
|
||||
) => {
|
||||
const { key, createDocumentOptions = {} } = options;
|
||||
const { key, createDocumentOptions = {}, internalVersion = 1 } = options;
|
||||
|
||||
const documentData = await prisma.documentData.create({
|
||||
data: {
|
||||
@@ -640,7 +641,7 @@ export const seedCompletedDocument = async (
|
||||
data: {
|
||||
id: prefixedId('envelope'),
|
||||
secondaryId: documentId.formattedDocumentId,
|
||||
internalVersion: 1,
|
||||
internalVersion,
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
documentMetaId: documentMeta.id,
|
||||
source: DocumentSource.DOCUMENT,
|
||||
|
||||
@@ -18,8 +18,8 @@ import { createEnvelopeRecipientsRoute } from './envelope-recipients/create-enve
|
||||
import { deleteEnvelopeRecipientRoute } from './envelope-recipients/delete-envelope-recipient';
|
||||
import { getEnvelopeRecipientRoute } from './envelope-recipients/get-envelope-recipient';
|
||||
import { updateEnvelopeRecipientsRoute } from './envelope-recipients/update-envelope-recipients';
|
||||
import { findEnvelopesRoute } from './find-envelopes';
|
||||
import { findEnvelopeAuditLogsRoute } from './find-envelope-audit-logs';
|
||||
import { findEnvelopesRoute } from './find-envelopes';
|
||||
import { getEnvelopeRoute } from './get-envelope';
|
||||
import { getEnvelopeItemsRoute } from './get-envelope-items';
|
||||
import { getEnvelopeItemsByTokenRoute } from './get-envelope-items-by-token';
|
||||
|
||||
@@ -23,7 +23,7 @@ export function DataTablePagination<TData>({
|
||||
}: DataTablePaginationProps<TData>) {
|
||||
return (
|
||||
<div className="flex flex-wrap items-center justify-between gap-x-4 gap-y-4 px-2">
|
||||
<div className="text-muted-foreground flex-1 text-sm">
|
||||
<div className="flex-1 text-sm text-muted-foreground">
|
||||
{match(additionalInformation)
|
||||
.with('SelectedCount', () => (
|
||||
<span>
|
||||
|
||||
@@ -39,7 +39,7 @@ const DialogOverlay = React.forwardRef<
|
||||
<DialogPrimitive.Overlay
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'bg-background/80 data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in fixed inset-0 z-50 backdrop-blur-sm transition-all duration-100',
|
||||
'fixed inset-0 z-50 bg-background/80 backdrop-blur-sm transition-all duration-100 data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -66,7 +66,7 @@ const DialogContent = React.forwardRef<
|
||||
<DialogPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'bg-background animate-in data-[state=open]:fade-in-90 sm:zoom-in-90 data-[state=open]:slide-in-from-bottom-10 data-[state=open]:sm:slide-in-from-bottom-0 fixed z-50 grid w-full gap-4 border p-6 shadow-lg sm:max-w-lg sm:rounded-lg',
|
||||
'fixed z-50 grid w-full gap-4 border bg-background p-6 shadow-lg animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:max-w-lg sm:rounded-lg sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0',
|
||||
{
|
||||
'rounded-b-xl': position === 'start',
|
||||
'rounded-t-xl': position === 'end',
|
||||
@@ -79,7 +79,7 @@ const DialogContent = React.forwardRef<
|
||||
{!hideClose && (
|
||||
<DialogPrimitive.Close
|
||||
data-testid="btn-dialog-close"
|
||||
className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none"
|
||||
className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
<span className="sr-only">
|
||||
@@ -131,7 +131,7 @@ const DialogDescription = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Description
|
||||
ref={ref}
|
||||
className={cn('text-muted-foreground text-sm', className)}
|
||||
className={cn('text-sm text-muted-foreground', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -323,7 +323,7 @@ export const AddSubjectFormPartial = ({
|
||||
<TooltipTrigger>
|
||||
<InfoIcon className="mx-2 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="text-muted-foreground p-4">
|
||||
<TooltipContent className="p-4 text-muted-foreground">
|
||||
<DocumentSendEmailMessageHelper />
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
@@ -331,7 +331,7 @@ export const AddSubjectFormPartial = ({
|
||||
|
||||
<FormControl>
|
||||
<Textarea
|
||||
className="bg-background mt-2 h-16 resize-none"
|
||||
className="mt-2 h-16 resize-none bg-background"
|
||||
{...field}
|
||||
maxLength={5000}
|
||||
/>
|
||||
@@ -360,7 +360,7 @@ export const AddSubjectFormPartial = ({
|
||||
className="rounded-lg border"
|
||||
>
|
||||
{document.status === DocumentStatus.DRAFT ? (
|
||||
<div className="text-muted-foreground py-16 text-center text-sm">
|
||||
<div className="py-16 text-center text-sm text-muted-foreground">
|
||||
<p>
|
||||
<Trans>We won't send anything to notify recipients.</Trans>
|
||||
</p>
|
||||
@@ -373,7 +373,7 @@ export const AddSubjectFormPartial = ({
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<ul className="text-muted-foreground divide-y">
|
||||
<ul className="divide-y text-muted-foreground">
|
||||
{recipients.length === 0 && (
|
||||
<li className="flex flex-col items-center justify-center py-6 text-sm">
|
||||
<Trans>No recipients</Trans>
|
||||
@@ -388,10 +388,10 @@ export const AddSubjectFormPartial = ({
|
||||
<AvatarWithText
|
||||
avatarFallback={recipient.email.slice(0, 1).toUpperCase()}
|
||||
primaryText={
|
||||
<p className="text-muted-foreground text-sm">{recipient.email}</p>
|
||||
<p className="text-sm text-muted-foreground">{recipient.email}</p>
|
||||
}
|
||||
secondaryText={
|
||||
<p className="text-muted-foreground/70 text-xs">
|
||||
<p className="text-xs text-muted-foreground/70">
|
||||
{_(RECIPIENT_ROLES_DESCRIPTION[recipient.role].roleName)}
|
||||
</p>
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export const DocumentFlowFormContainer = ({
|
||||
<form
|
||||
id={id}
|
||||
className={cn(
|
||||
'dark:bg-background border-border bg-widget sticky top-20 flex h-full max-h-[64rem] flex-col overflow-auto rounded-xl border px-4 py-6',
|
||||
'sticky top-20 flex h-full max-h-[64rem] flex-col overflow-auto rounded-xl border border-border bg-widget px-4 py-6 dark:bg-background',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -47,11 +47,11 @@ export const DocumentFlowFormContainerHeader = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<h3 className="text-foreground text-2xl font-semibold">{_(title)}</h3>
|
||||
<h3 className="text-2xl font-semibold text-foreground">{_(title)}</h3>
|
||||
|
||||
<p className="text-muted-foreground mt-2 text-sm">{_(description)}</p>
|
||||
<p className="mt-2 text-sm text-muted-foreground">{_(description)}</p>
|
||||
|
||||
<hr className="border-border mb-8 mt-4" />
|
||||
<hr className="mb-8 mt-4 border-border" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -66,10 +66,7 @@ export const DocumentFlowFormContainerContent = ({
|
||||
...props
|
||||
}: DocumentFlowFormContainerContentProps) => {
|
||||
return (
|
||||
<div
|
||||
className={cn('custom-scrollbar -mx-2 flex flex-1 flex-col px-2', className)}
|
||||
{...props}
|
||||
>
|
||||
<div className={cn('custom-scrollbar -mx-2 flex flex-1 flex-col px-2', className)} {...props}>
|
||||
<div className="flex flex-1 flex-col">{children}</div>
|
||||
</div>
|
||||
);
|
||||
@@ -102,17 +99,17 @@ export const DocumentFlowFormContainerStep = ({
|
||||
}: DocumentFlowFormContainerStepProps) => {
|
||||
return (
|
||||
<div>
|
||||
<p className="text-muted-foreground text-sm">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
<Trans>
|
||||
Step <span>{`${step} of ${maxStep}`}</span>
|
||||
</Trans>
|
||||
</p>
|
||||
|
||||
<div className="bg-muted relative mt-4 h-[2px] rounded-md">
|
||||
<div className="relative mt-4 h-[2px] rounded-md bg-muted">
|
||||
<motion.div
|
||||
layout="size"
|
||||
layoutId="document-flow-container-step"
|
||||
className="bg-primary absolute inset-y-0 left-0"
|
||||
className="absolute inset-y-0 left-0 bg-primary"
|
||||
style={{
|
||||
width: `${(100 / maxStep) * step}%`,
|
||||
}}
|
||||
@@ -150,7 +147,7 @@ export const DocumentFlowFormContainerActions = ({
|
||||
<div className="mt-4 flex gap-x-4">
|
||||
<Button
|
||||
type="button"
|
||||
className="dark:bg-muted dark:hover:bg-muted/80 flex-1 bg-black/5 hover:bg-black/10"
|
||||
className="flex-1 bg-black/5 hover:bg-black/10 dark:bg-muted dark:hover:bg-muted/80"
|
||||
size="lg"
|
||||
variant="secondary"
|
||||
disabled={disabled || loading || !canGoBack || !onGoBackClick}
|
||||
@@ -161,7 +158,7 @@ export const DocumentFlowFormContainerActions = ({
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
className="bg-primary flex-1"
|
||||
className="flex-1 bg-primary"
|
||||
size="lg"
|
||||
disabled={disabled || disableNextStep || loading || !canGoNext}
|
||||
loading={loading}
|
||||
|
||||
@@ -62,7 +62,7 @@ export const FieldContent = ({ field, documentMeta }: FieldIconProps) => {
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<Checkbox className="h-3 w-3" disabled />
|
||||
<Label className="text-foreground ml-1.5 text-xs font-normal opacity-50">
|
||||
<Label className="ml-1.5 text-xs font-normal text-foreground opacity-50">
|
||||
<Trans>Checkbox option</Trans>
|
||||
</Label>
|
||||
</div>
|
||||
@@ -90,7 +90,7 @@ export const FieldContent = ({ field, documentMeta }: FieldIconProps) => {
|
||||
{item.value && (
|
||||
<Label
|
||||
htmlFor={`checkbox-${index}`}
|
||||
className="text-foreground ml-1.5 text-xs font-normal"
|
||||
className="ml-1.5 text-xs font-normal text-foreground"
|
||||
>
|
||||
{item.value}
|
||||
</Label>
|
||||
@@ -122,7 +122,7 @@ export const FieldContent = ({ field, documentMeta }: FieldIconProps) => {
|
||||
{item.value && (
|
||||
<Label
|
||||
htmlFor={`option-${index}`}
|
||||
className="text-foreground ml-1.5 text-xs font-normal"
|
||||
className="ml-1.5 text-xs font-normal text-foreground"
|
||||
>
|
||||
{item.value}
|
||||
</Label>
|
||||
@@ -140,7 +140,7 @@ export const FieldContent = ({ field, documentMeta }: FieldIconProps) => {
|
||||
!field.inserted
|
||||
) {
|
||||
return (
|
||||
<div className="text-field-card-foreground flex flex-row items-center py-0.5 text-[clamp(0.07rem,25cqw,0.825rem)] text-sm">
|
||||
<div className="flex flex-row items-center py-0.5 text-[clamp(0.07rem,25cqw,0.825rem)] text-sm text-field-card-foreground">
|
||||
<p>
|
||||
<Trans>Select</Trans>
|
||||
</p>
|
||||
@@ -196,7 +196,7 @@ export const FieldContent = ({ field, documentMeta }: FieldIconProps) => {
|
||||
<div className="flex h-full w-full items-center overflow-hidden">
|
||||
<p
|
||||
className={cn(
|
||||
'text-foreground w-full whitespace-pre-wrap text-left text-[clamp(0.07rem,25cqw,0.825rem)] duration-200',
|
||||
'w-full whitespace-pre-wrap text-left text-[clamp(0.07rem,25cqw,0.825rem)] text-foreground duration-200',
|
||||
{
|
||||
'!text-center': textAlign === 'center' || !textToDisplay,
|
||||
'!text-right': textAlign === 'right',
|
||||
|
||||
@@ -269,8 +269,8 @@ export const FieldItem = ({
|
||||
className={cn(
|
||||
'absolute -top-16 left-0 right-0 rounded-md p-2 text-center text-xs text-gray-700',
|
||||
{
|
||||
'bg-foreground/5 border-primary border': !fieldHasCheckedValues,
|
||||
'bg-documenso-200 border-primary border': fieldHasCheckedValues,
|
||||
'border border-primary bg-foreground/5': !fieldHasCheckedValues,
|
||||
'border border-primary bg-documenso-200': fieldHasCheckedValues,
|
||||
},
|
||||
)}
|
||||
>
|
||||
@@ -321,8 +321,25 @@ export const FieldItem = ({
|
||||
</div>
|
||||
|
||||
{isDevMode && (
|
||||
<div className="text-muted-foreground absolute -top-6 left-0 right-0 text-center text-[10px]">
|
||||
{`x: ${field.pageX.toFixed(2)}, y: ${field.pageY.toFixed(2)}`}
|
||||
<div className="absolute -top-20 left-1/2 z-50 -translate-x-1/2 rounded-md border border-border bg-background/95 px-2 py-1 shadow-sm backdrop-blur-sm">
|
||||
<div className="flex flex-col gap-0.5 text-[9px]">
|
||||
<span>
|
||||
<span className="text-muted-foreground">Pos X: </span>
|
||||
<span className="font-mono text-foreground">{field.pageX.toFixed(2)}</span>
|
||||
</span>
|
||||
<span>
|
||||
<span className="text-muted-foreground">Pos Y: </span>
|
||||
<span className="font-mono text-foreground">{field.pageY.toFixed(2)}</span>
|
||||
</span>
|
||||
<span>
|
||||
<span className="text-muted-foreground">Width: </span>
|
||||
<span className="font-mono text-foreground">{field.pageWidth.toFixed(2)}</span>
|
||||
</span>
|
||||
<span>
|
||||
<span className="text-muted-foreground">Height: </span>
|
||||
<span className="font-mono text-foreground">{field.pageHeight.toFixed(2)}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -42,7 +42,7 @@ const SheetOverlay = React.forwardRef<
|
||||
>(({ className, children: _children, ...props }, ref) => (
|
||||
<SheetPrimitive.Overlay
|
||||
className={cn(
|
||||
'bg-background/80 data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in fixed inset-0 z-[61] backdrop-blur-sm transition-all duration-100',
|
||||
'fixed inset-0 z-[61] bg-background/80 backdrop-blur-sm transition-all duration-100 data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -159,7 +159,7 @@ const SheetContent = React.forwardRef<
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none">
|
||||
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
|
||||
<X className="h-4 w-4" />
|
||||
<span className="sr-only">
|
||||
<Trans>Close</Trans>
|
||||
@@ -192,7 +192,7 @@ const SheetTitle = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SheetPrimitive.Title
|
||||
ref={ref}
|
||||
className={cn('text-foreground text-lg font-semibold', className)}
|
||||
className={cn('text-lg font-semibold text-foreground', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
@@ -205,7 +205,7 @@ const SheetDescription = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SheetPrimitive.Description
|
||||
ref={ref}
|
||||
className={cn('text-muted-foreground text-sm', className)}
|
||||
className={cn('text-sm text-muted-foreground', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -294,7 +294,7 @@ export const SignaturePadDraw = ({
|
||||
<div className="absolute bottom-3 right-3 flex gap-2">
|
||||
<button
|
||||
type="button"
|
||||
className="focus-visible:ring-ring ring-offset-background text-muted-foreground/60 hover:text-muted-foreground rounded-full p-0 text-[0.688rem] focus-visible:outline-none focus-visible:ring-2"
|
||||
className="rounded-full p-0 text-[0.688rem] text-muted-foreground/60 ring-offset-background hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
||||
onClick={() => onClearClick()}
|
||||
>
|
||||
<Trans>Clear Signature</Trans>
|
||||
@@ -303,7 +303,7 @@ export const SignaturePadDraw = ({
|
||||
|
||||
{isSignatureValid === false && (
|
||||
<div className="absolute bottom-4 left-4 flex gap-2">
|
||||
<span className="text-destructive text-xs">
|
||||
<span className="text-xs text-destructive">
|
||||
<Trans>Signature is too small</Trans>
|
||||
</span>
|
||||
</div>
|
||||
@@ -314,7 +314,7 @@ export const SignaturePadDraw = ({
|
||||
<button
|
||||
type="button"
|
||||
title="undo"
|
||||
className="focus-visible:ring-ring ring-offset-background text-muted-foreground/60 hover:text-muted-foreground rounded-full p-0 text-[0.688rem] focus-visible:outline-none focus-visible:ring-2"
|
||||
className="rounded-full p-0 text-[0.688rem] text-muted-foreground/60 ring-offset-background hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
||||
onClick={onUndoClick}
|
||||
>
|
||||
<Undo2 className="h-4 w-4" />
|
||||
|
||||
@@ -239,7 +239,7 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
<InfoIcon className="mx-2 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
|
||||
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
|
||||
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
|
||||
Controls the language for the document, including the language to be used
|
||||
for email notifications, and the final certificate that is generated and
|
||||
attached to the document.
|
||||
@@ -337,7 +337,7 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
<InfoIcon className="mx-2 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
|
||||
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
|
||||
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
|
||||
<h2>
|
||||
<strong>
|
||||
<Trans>Document Distribution Method</Trans>
|
||||
@@ -423,7 +423,7 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
field.onChange(value);
|
||||
void handleAutoSave();
|
||||
}}
|
||||
className="bg-background w-full"
|
||||
className="w-full bg-background"
|
||||
emptySelectionPlaceholder={t`Select signature types`}
|
||||
/>
|
||||
</FormControl>
|
||||
@@ -463,11 +463,11 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
{distributionMethod === DocumentDistributionMethod.EMAIL && (
|
||||
<Accordion type="multiple">
|
||||
<AccordionItem value="email-options" className="border-none">
|
||||
<AccordionTrigger className="text-foreground rounded border px-3 py-2 text-left hover:bg-neutral-200/30 hover:no-underline">
|
||||
<AccordionTrigger className="rounded border px-3 py-2 text-left text-foreground hover:bg-neutral-200/30 hover:no-underline">
|
||||
<Trans>Email Options</Trans>
|
||||
</AccordionTrigger>
|
||||
|
||||
<AccordionContent className="text-muted-foreground -mx-1 px-1 pt-4 text-sm leading-relaxed [&>div]:pb-0">
|
||||
<AccordionContent className="-mx-1 px-1 pt-4 text-sm leading-relaxed text-muted-foreground [&>div]:pb-0">
|
||||
<div className="flex flex-col space-y-6">
|
||||
{organisation.organisationClaim.flags.emailDomains && (
|
||||
<FormField
|
||||
@@ -566,7 +566,7 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
<TooltipTrigger>
|
||||
<InfoIcon className="mx-2 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="text-muted-foreground p-4">
|
||||
<TooltipContent className="p-4 text-muted-foreground">
|
||||
<DocumentSendEmailMessageHelper />
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
@@ -574,7 +574,7 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
|
||||
<FormControl>
|
||||
<Textarea
|
||||
className="bg-background h-16 resize-none"
|
||||
className="h-16 resize-none bg-background"
|
||||
{...field}
|
||||
maxLength={5000}
|
||||
onBlur={handleAutoSave}
|
||||
@@ -603,11 +603,11 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
|
||||
<Accordion type="multiple">
|
||||
<AccordionItem value="advanced-options" className="border-none">
|
||||
<AccordionTrigger className="text-foreground rounded border px-3 py-2 text-left hover:bg-neutral-200/30 hover:no-underline">
|
||||
<AccordionTrigger className="rounded border px-3 py-2 text-left text-foreground hover:bg-neutral-200/30 hover:no-underline">
|
||||
<Trans>Advanced Options</Trans>
|
||||
</AccordionTrigger>
|
||||
|
||||
<AccordionContent className="text-muted-foreground -mx-1 px-1 pt-4 text-sm leading-relaxed">
|
||||
<AccordionContent className="-mx-1 px-1 pt-4 text-sm leading-relaxed text-muted-foreground">
|
||||
<div className="flex flex-col space-y-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
@@ -621,7 +621,7 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
<InfoIcon className="mx-2 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
|
||||
<TooltipContent className="text-muted-foreground max-w-xs">
|
||||
<TooltipContent className="max-w-xs text-muted-foreground">
|
||||
<Trans>
|
||||
Add an external ID to the template. This can be used to identify
|
||||
in external systems.
|
||||
@@ -691,7 +691,7 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
|
||||
<FormControl>
|
||||
<Combobox
|
||||
className="bg-background time-zone-field"
|
||||
className="time-zone-field bg-background"
|
||||
options={TIME_ZONES}
|
||||
{...field}
|
||||
onChange={(value) => {
|
||||
@@ -718,7 +718,7 @@ export const AddTemplateSettingsFormPartial = ({
|
||||
<InfoIcon className="mx-2 h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
|
||||
<TooltipContent className="text-muted-foreground max-w-xs">
|
||||
<TooltipContent className="max-w-xs text-muted-foreground">
|
||||
<Trans>
|
||||
Add a URL to redirect the user to once the document is signed
|
||||
</Trans>
|
||||
|
||||
Reference in New Issue
Block a user