mirror of
https://github.com/documenso/documenso.git
synced 2026-07-25 17:35:05 +10:00
fix: merge conflicts
This commit is contained in:
@@ -41,7 +41,7 @@ import {
|
||||
ZTextFieldMeta,
|
||||
} from '@documenso/lib/types/field-meta';
|
||||
import { getFileServerSide } from '@documenso/lib/universal/upload/get-file.server';
|
||||
import { putPdfFileServerSide } from '@documenso/lib/universal/upload/put-file.server';
|
||||
import { putNormalizedPdfFileServerSide } from '@documenso/lib/universal/upload/put-file.server';
|
||||
import {
|
||||
getPresignGetUrl,
|
||||
getPresignPostUrl,
|
||||
@@ -822,10 +822,12 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
||||
formValues: body.formValues,
|
||||
});
|
||||
|
||||
const newDocumentData = await putPdfFileServerSide({
|
||||
name: fileName,
|
||||
type: 'application/pdf',
|
||||
arrayBuffer: async () => Promise.resolve(prefilled),
|
||||
const newDocumentData = await putNormalizedPdfFileServerSide({
|
||||
file: {
|
||||
name: fileName,
|
||||
type: 'application/pdf',
|
||||
arrayBuffer: async () => Promise.resolve(prefilled),
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.envelopeItem.update({
|
||||
@@ -911,61 +913,13 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
||||
title: body.title,
|
||||
...body.meta,
|
||||
},
|
||||
formValues: body.formValues,
|
||||
requestMetadata: metadata,
|
||||
});
|
||||
} catch (err) {
|
||||
return AppError.toRestAPIError(err);
|
||||
}
|
||||
|
||||
if (envelope.envelopeItems.length !== 1) {
|
||||
throw new Error('API V1 does not support envelopes');
|
||||
}
|
||||
|
||||
const firstEnvelopeDocumentData = await prisma.envelopeItem.findFirstOrThrow({
|
||||
where: {
|
||||
envelopeId: envelope.id,
|
||||
},
|
||||
include: {
|
||||
documentData: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (body.formValues) {
|
||||
const fileName = envelope.title.endsWith('.pdf') ? envelope.title : `${envelope.title}.pdf`;
|
||||
|
||||
const pdf = await getFileServerSide(firstEnvelopeDocumentData.documentData);
|
||||
|
||||
const prefilled = await insertFormValuesInPdf({
|
||||
pdf: Buffer.from(pdf),
|
||||
formValues: body.formValues,
|
||||
});
|
||||
|
||||
const newDocumentData = await putPdfFileServerSide({
|
||||
name: fileName,
|
||||
type: 'application/pdf',
|
||||
arrayBuffer: async () => Promise.resolve(prefilled),
|
||||
});
|
||||
|
||||
await prisma.envelope.update({
|
||||
where: {
|
||||
id: envelope.id,
|
||||
},
|
||||
data: {
|
||||
formValues: body.formValues,
|
||||
envelopeItems: {
|
||||
update: {
|
||||
where: {
|
||||
id: firstEnvelopeDocumentData.id,
|
||||
},
|
||||
data: {
|
||||
documentDataId: newDocumentData.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (body.authOptions) {
|
||||
await prisma.envelope.update({
|
||||
where: {
|
||||
|
||||
@@ -0,0 +1,848 @@
|
||||
import { PDFDocument } from '@cantoo/pdf-lib';
|
||||
import { expect, test } from '@playwright/test';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { getFileServerSide } from '@documenso/lib/universal/upload/get-file.server';
|
||||
import { mapSecondaryIdToTemplateId } from '@documenso/lib/utils/envelope';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { EnvelopeType, RecipientRole } from '@documenso/prisma/client';
|
||||
import { seedUser } from '@documenso/prisma/seed/users';
|
||||
import type {
|
||||
TCreateEnvelopePayload,
|
||||
TCreateEnvelopeResponse,
|
||||
} from '@documenso/trpc/server/envelope-router/create-envelope.types';
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
const baseUrl = `${WEBAPP_BASE_URL}/api/v2-beta`;
|
||||
|
||||
// Form field names in the test PDF
|
||||
const FORM_FIELDS = {
|
||||
TEXT_FIELD: 'test_text_field',
|
||||
COMPANY_NAME: 'company_name',
|
||||
CHECKBOX: 'accept_terms',
|
||||
DROPDOWN: 'country',
|
||||
} as const;
|
||||
|
||||
// Test values to insert into form fields
|
||||
const TEST_FORM_VALUES = {
|
||||
[FORM_FIELDS.TEXT_FIELD]: 'Hello World',
|
||||
[FORM_FIELDS.COMPANY_NAME]: 'Documenso Inc.',
|
||||
[FORM_FIELDS.CHECKBOX]: true,
|
||||
[FORM_FIELDS.DROPDOWN]: 'Germany',
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to check if a PDF has interactive form fields.
|
||||
* Returns true if the PDF has form fields, false if they've been flattened.
|
||||
*/
|
||||
async function pdfHasFormFields(pdfBuffer: Uint8Array): Promise<boolean> {
|
||||
const pdfDoc = await PDFDocument.load(pdfBuffer);
|
||||
|
||||
const form = pdfDoc.getForm();
|
||||
const fields = form.getFields();
|
||||
|
||||
return fields.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get form field names from a PDF.
|
||||
*/
|
||||
async function getPdfFormFieldNames(pdfBuffer: Uint8Array): Promise<string[]> {
|
||||
const pdfDoc = await PDFDocument.load(pdfBuffer);
|
||||
|
||||
const form = pdfDoc.getForm();
|
||||
const fields = form.getFields();
|
||||
|
||||
return fields.map((field) => field.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get the value of a text field in a PDF.
|
||||
*/
|
||||
async function getPdfTextFieldValue(
|
||||
pdfBuffer: Uint8Array,
|
||||
fieldName: string,
|
||||
): Promise<string | undefined> {
|
||||
const pdfDoc = await PDFDocument.load(pdfBuffer);
|
||||
|
||||
const form = pdfDoc.getForm();
|
||||
|
||||
try {
|
||||
const textField = form.getTextField(fieldName);
|
||||
|
||||
return textField.getText() ?? '';
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
test.describe.configure({
|
||||
mode: 'parallel',
|
||||
});
|
||||
|
||||
test.describe('Form Flattening', () => {
|
||||
const formFieldsPdf = fs.readFileSync(
|
||||
path.join(__dirname, '../../../../assets/form-fields-test.pdf'),
|
||||
);
|
||||
|
||||
test.describe('Envelope Creation (DOCUMENT type)', () => {
|
||||
test('should flatten form fields when creating a DOCUMENT envelope with formValues', async ({
|
||||
request,
|
||||
}) => {
|
||||
const { user, team } = await seedUser();
|
||||
const { token } = await createApiToken({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
tokenName: 'test',
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
const payload: TCreateEnvelopePayload = {
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
title: 'Document with Form Values',
|
||||
formValues: TEST_FORM_VALUES,
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append('payload', JSON.stringify(payload));
|
||||
formData.append(
|
||||
'files',
|
||||
new File([formFieldsPdf], 'form-fields-test.pdf', { type: 'application/pdf' }),
|
||||
);
|
||||
|
||||
const res = await request.post(`${baseUrl}/envelope/create`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: formData,
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const response = (await res.json()) as TCreateEnvelopeResponse;
|
||||
|
||||
// Verify the envelope was created with the correct formValues
|
||||
const envelope = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: response.id },
|
||||
include: {
|
||||
envelopeItems: {
|
||||
include: { documentData: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(envelope.formValues).toEqual(TEST_FORM_VALUES);
|
||||
expect(envelope.type).toBe(EnvelopeType.DOCUMENT);
|
||||
|
||||
// Get the PDF and verify form fields are flattened
|
||||
const documentData = envelope.envelopeItems[0].documentData;
|
||||
const pdfBuffer = await getFileServerSide(documentData);
|
||||
|
||||
const hasFormFields = await pdfHasFormFields(pdfBuffer);
|
||||
|
||||
expect(hasFormFields).toBe(false);
|
||||
});
|
||||
|
||||
test('should flatten form fields when creating a DOCUMENT envelope without formValues', async ({
|
||||
request,
|
||||
}) => {
|
||||
const { user, team } = await seedUser();
|
||||
const { token } = await createApiToken({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
tokenName: 'test',
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
const payload: TCreateEnvelopePayload = {
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
title: 'Document without Form Values',
|
||||
// No formValues - but form should still be flattened for DOCUMENT type
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append('payload', JSON.stringify(payload));
|
||||
formData.append(
|
||||
'files',
|
||||
new File([formFieldsPdf], 'form-fields-test.pdf', { type: 'application/pdf' }),
|
||||
);
|
||||
|
||||
const res = await request.post(`${baseUrl}/envelope/create`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: formData,
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const response = (await res.json()) as TCreateEnvelopeResponse;
|
||||
|
||||
const envelope = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: response.id },
|
||||
include: {
|
||||
envelopeItems: {
|
||||
include: { documentData: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Get the PDF and verify form fields are flattened
|
||||
const documentData = envelope.envelopeItems[0].documentData;
|
||||
const pdfBuffer = await getFileServerSide(documentData);
|
||||
|
||||
const hasFormFields = await pdfHasFormFields(pdfBuffer);
|
||||
|
||||
expect(hasFormFields).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Template Creation (TEMPLATE type)', () => {
|
||||
test('should NOT flatten form fields when creating a TEMPLATE envelope', async ({
|
||||
request,
|
||||
}) => {
|
||||
const { user, team } = await seedUser();
|
||||
const { token } = await createApiToken({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
tokenName: 'test',
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
const payload: TCreateEnvelopePayload = {
|
||||
type: EnvelopeType.TEMPLATE,
|
||||
title: 'Template with Form Fields',
|
||||
// Note: formValues can be set but form should NOT be flattened for templates
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append('payload', JSON.stringify(payload));
|
||||
formData.append(
|
||||
'files',
|
||||
new File([formFieldsPdf], 'form-fields-test.pdf', { type: 'application/pdf' }),
|
||||
);
|
||||
|
||||
const res = await request.post(`${baseUrl}/envelope/create`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: formData,
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const response = (await res.json()) as TCreateEnvelopeResponse;
|
||||
|
||||
const envelope = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: response.id },
|
||||
include: {
|
||||
envelopeItems: {
|
||||
include: { documentData: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(envelope.type).toBe(EnvelopeType.TEMPLATE);
|
||||
|
||||
// Get the PDF and verify form fields are NOT flattened
|
||||
const documentData = envelope.envelopeItems[0].documentData;
|
||||
const pdfBuffer = await getFileServerSide(documentData);
|
||||
|
||||
const hasFormFields = await pdfHasFormFields(pdfBuffer);
|
||||
|
||||
expect(hasFormFields).toBe(true);
|
||||
|
||||
// Verify the specific form fields still exist
|
||||
const fieldNames = await getPdfFormFieldNames(pdfBuffer);
|
||||
|
||||
expect(fieldNames).toContain(FORM_FIELDS.TEXT_FIELD);
|
||||
expect(fieldNames).toContain(FORM_FIELDS.COMPANY_NAME);
|
||||
expect(fieldNames).toContain(FORM_FIELDS.CHECKBOX);
|
||||
expect(fieldNames).toContain(FORM_FIELDS.DROPDOWN);
|
||||
});
|
||||
|
||||
test('should preserve form fields in template even when formValues are provided', async ({
|
||||
request,
|
||||
}) => {
|
||||
const { user, team } = await seedUser();
|
||||
const { token } = await createApiToken({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
tokenName: 'test',
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
const payload: TCreateEnvelopePayload = {
|
||||
type: EnvelopeType.TEMPLATE,
|
||||
title: 'Template with Form Values',
|
||||
formValues: TEST_FORM_VALUES,
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append('payload', JSON.stringify(payload));
|
||||
formData.append(
|
||||
'files',
|
||||
new File([formFieldsPdf], 'form-fields-test.pdf', { type: 'application/pdf' }),
|
||||
);
|
||||
|
||||
const res = await request.post(`${baseUrl}/envelope/create`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: formData,
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const response = (await res.json()) as TCreateEnvelopeResponse;
|
||||
|
||||
const envelope = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: response.id },
|
||||
include: {
|
||||
envelopeItems: {
|
||||
include: { documentData: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// formValues should be stored in the database
|
||||
expect(envelope.formValues).toEqual(TEST_FORM_VALUES);
|
||||
expect(envelope.type).toBe(EnvelopeType.TEMPLATE);
|
||||
|
||||
// But the PDF should still have interactive form fields
|
||||
const documentData = envelope.envelopeItems[0].documentData;
|
||||
const pdfBuffer = await getFileServerSide(documentData);
|
||||
|
||||
const hasFormFields = await pdfHasFormFields(pdfBuffer);
|
||||
|
||||
expect(hasFormFields).toBe(true);
|
||||
expect(await getPdfTextFieldValue(pdfBuffer, FORM_FIELDS.TEXT_FIELD)).toBe(
|
||||
TEST_FORM_VALUES[FORM_FIELDS.TEXT_FIELD],
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Document from Template', () => {
|
||||
test('should flatten form fields when creating document from template with formValues', async ({
|
||||
request,
|
||||
}) => {
|
||||
const { user, team } = await seedUser();
|
||||
const { token } = await createApiToken({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
tokenName: 'test',
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
// First, create a template via API
|
||||
const templatePayload: TCreateEnvelopePayload = {
|
||||
type: EnvelopeType.TEMPLATE,
|
||||
title: 'Template for Document Creation',
|
||||
recipients: [
|
||||
{
|
||||
email: 'recipient@example.com',
|
||||
name: 'Test Recipient',
|
||||
role: RecipientRole.SIGNER,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const templateFormData = new FormData();
|
||||
templateFormData.append('payload', JSON.stringify(templatePayload));
|
||||
templateFormData.append(
|
||||
'files',
|
||||
new File([formFieldsPdf], 'form-fields-test.pdf', { type: 'application/pdf' }),
|
||||
);
|
||||
|
||||
const templateRes = await request.post(`${baseUrl}/envelope/create`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: templateFormData,
|
||||
});
|
||||
|
||||
expect(templateRes.ok()).toBeTruthy();
|
||||
const templateResponse = (await templateRes.json()) as TCreateEnvelopeResponse;
|
||||
|
||||
// Verify template has form fields
|
||||
const template = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: templateResponse.id },
|
||||
include: {
|
||||
envelopeItems: { include: { documentData: true } },
|
||||
recipients: true,
|
||||
},
|
||||
});
|
||||
|
||||
const templatePdfBuffer = await getFileServerSide(template.envelopeItems[0].documentData);
|
||||
|
||||
expect(await pdfHasFormFields(templatePdfBuffer)).toBe(true);
|
||||
|
||||
// Now create a document from the template with formValues
|
||||
const useTemplateRes = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/template/use`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: {
|
||||
templateId: mapSecondaryIdToTemplateId(template.secondaryId),
|
||||
recipients: [
|
||||
{
|
||||
id: template.recipients[0].id,
|
||||
email: 'recipient@example.com',
|
||||
name: 'Test Recipient',
|
||||
},
|
||||
],
|
||||
formValues: TEST_FORM_VALUES,
|
||||
},
|
||||
});
|
||||
|
||||
expect(useTemplateRes.ok()).toBeTruthy();
|
||||
expect(useTemplateRes.status()).toBe(200);
|
||||
|
||||
const documentResponse = await useTemplateRes.json();
|
||||
|
||||
// Get the created document
|
||||
const document = await prisma.envelope.findFirstOrThrow({
|
||||
where: {
|
||||
id: documentResponse.envelopeId,
|
||||
},
|
||||
include: {
|
||||
envelopeItems: { include: { documentData: true } },
|
||||
},
|
||||
});
|
||||
|
||||
expect(document.type).toBe(EnvelopeType.DOCUMENT);
|
||||
|
||||
// Verify form fields are flattened in the created document
|
||||
const documentPdfBuffer = await getFileServerSide(document.envelopeItems[0].documentData);
|
||||
const hasFormFields = await pdfHasFormFields(documentPdfBuffer);
|
||||
|
||||
expect(hasFormFields).toBe(false);
|
||||
});
|
||||
|
||||
test('should flatten form fields when creating document from template without formValues', async ({
|
||||
request,
|
||||
}) => {
|
||||
const { user, team } = await seedUser();
|
||||
const { token } = await createApiToken({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
tokenName: 'test',
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
// Create a template
|
||||
const templatePayload: TCreateEnvelopePayload = {
|
||||
type: EnvelopeType.TEMPLATE,
|
||||
title: 'Template without Form Values',
|
||||
recipients: [
|
||||
{
|
||||
email: 'recipient@example.com',
|
||||
name: 'Test Recipient',
|
||||
role: RecipientRole.SIGNER,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const templateFormData = new FormData();
|
||||
templateFormData.append('payload', JSON.stringify(templatePayload));
|
||||
templateFormData.append(
|
||||
'files',
|
||||
new File([formFieldsPdf], 'form-fields-test.pdf', { type: 'application/pdf' }),
|
||||
);
|
||||
|
||||
const templateRes = await request.post(`${baseUrl}/envelope/create`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: templateFormData,
|
||||
});
|
||||
|
||||
expect(templateRes.ok()).toBeTruthy();
|
||||
const templateResponse = (await templateRes.json()) as TCreateEnvelopeResponse;
|
||||
|
||||
const template = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: templateResponse.id },
|
||||
include: {
|
||||
envelopeItems: { include: { documentData: true } },
|
||||
recipients: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Create document from template WITHOUT formValues
|
||||
const useTemplateRes = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/template/use`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: {
|
||||
templateId: mapSecondaryIdToTemplateId(template.secondaryId),
|
||||
recipients: [
|
||||
{
|
||||
id: template.recipients[0].id,
|
||||
email: 'recipient@example.com',
|
||||
name: 'Test Recipient',
|
||||
},
|
||||
],
|
||||
// No formValues provided
|
||||
},
|
||||
});
|
||||
|
||||
expect(useTemplateRes.ok()).toBeTruthy();
|
||||
const documentResponse = await useTemplateRes.json();
|
||||
|
||||
const document = await prisma.envelope.findFirstOrThrow({
|
||||
where: { id: documentResponse.envelopeId },
|
||||
include: {
|
||||
envelopeItems: { include: { documentData: true } },
|
||||
},
|
||||
});
|
||||
|
||||
expect(document.type).toBe(EnvelopeType.DOCUMENT);
|
||||
|
||||
// Form fields should still be flattened even without formValues
|
||||
const documentPdfBuffer = await getFileServerSide(document.envelopeItems[0].documentData);
|
||||
const hasFormFields = await pdfHasFormFields(documentPdfBuffer);
|
||||
|
||||
expect(hasFormFields).toBe(false);
|
||||
});
|
||||
|
||||
test('should use template formValues when creating document without override', async ({
|
||||
request,
|
||||
}) => {
|
||||
const { user, team } = await seedUser();
|
||||
const { token } = await createApiToken({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
tokenName: 'test',
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
// Create a template with formValues
|
||||
const templatePayload: TCreateEnvelopePayload = {
|
||||
type: EnvelopeType.TEMPLATE,
|
||||
title: 'Template with Default Form Values',
|
||||
formValues: {
|
||||
[FORM_FIELDS.TEXT_FIELD]: 'Default Value',
|
||||
[FORM_FIELDS.COMPANY_NAME]: 'Default Company',
|
||||
},
|
||||
recipients: [
|
||||
{
|
||||
email: 'recipient@example.com',
|
||||
name: 'Test Recipient',
|
||||
role: RecipientRole.SIGNER,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const templateFormData = new FormData();
|
||||
templateFormData.append('payload', JSON.stringify(templatePayload));
|
||||
templateFormData.append(
|
||||
'files',
|
||||
new File([formFieldsPdf], 'form-fields-test.pdf', { type: 'application/pdf' }),
|
||||
);
|
||||
|
||||
const templateRes = await request.post(`${baseUrl}/envelope/create`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: templateFormData,
|
||||
});
|
||||
|
||||
expect(templateRes.ok()).toBeTruthy();
|
||||
const templateResponse = (await templateRes.json()) as TCreateEnvelopeResponse;
|
||||
|
||||
const template = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: templateResponse.id },
|
||||
include: {
|
||||
envelopeItems: { include: { documentData: true } },
|
||||
recipients: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Verify template stored the formValues
|
||||
expect(template.formValues).toEqual({
|
||||
[FORM_FIELDS.TEXT_FIELD]: 'Default Value',
|
||||
[FORM_FIELDS.COMPANY_NAME]: 'Default Company',
|
||||
});
|
||||
|
||||
// Create document from template without providing new formValues
|
||||
// The template's formValues should be used
|
||||
const useTemplateRes = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/template/use`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: {
|
||||
templateId: mapSecondaryIdToTemplateId(template.secondaryId),
|
||||
recipients: [
|
||||
{
|
||||
id: template.recipients[0].id,
|
||||
email: 'recipient@example.com',
|
||||
name: 'Test Recipient',
|
||||
},
|
||||
],
|
||||
// No formValues - should inherit from template
|
||||
},
|
||||
});
|
||||
|
||||
expect(useTemplateRes.ok()).toBeTruthy();
|
||||
const documentResponse = await useTemplateRes.json();
|
||||
|
||||
const document = await prisma.envelope.findFirstOrThrow({
|
||||
where: { id: documentResponse.envelopeId },
|
||||
include: {
|
||||
envelopeItems: { include: { documentData: true } },
|
||||
},
|
||||
});
|
||||
|
||||
// Form fields should be flattened
|
||||
const documentPdfBuffer = await getFileServerSide(document.envelopeItems[0].documentData);
|
||||
|
||||
expect(await pdfHasFormFields(documentPdfBuffer)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Form Values Verification', () => {
|
||||
test('should correctly insert form values into PDF before flattening', async ({ request }) => {
|
||||
const { user, team } = await seedUser();
|
||||
const { token } = await createApiToken({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
tokenName: 'test',
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
// Create a template first (form fields preserved)
|
||||
const templatePayload: TCreateEnvelopePayload = {
|
||||
type: EnvelopeType.TEMPLATE,
|
||||
title: 'Template for Value Verification',
|
||||
recipients: [
|
||||
{
|
||||
email: 'recipient@example.com',
|
||||
name: 'Test Recipient',
|
||||
role: RecipientRole.SIGNER,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const templateFormData = new FormData();
|
||||
|
||||
templateFormData.append('payload', JSON.stringify(templatePayload));
|
||||
templateFormData.append(
|
||||
'files',
|
||||
new File([formFieldsPdf], 'form-fields-test.pdf', { type: 'application/pdf' }),
|
||||
);
|
||||
|
||||
const templateRes = await request.post(`${baseUrl}/envelope/create`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: templateFormData,
|
||||
});
|
||||
|
||||
const templateResponse = (await templateRes.json()) as TCreateEnvelopeResponse;
|
||||
const template = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: templateResponse.id },
|
||||
include: {
|
||||
envelopeItems: { include: { documentData: true } },
|
||||
recipients: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Verify template PDF still has form fields
|
||||
const templatePdfBuffer = await getFileServerSide(template.envelopeItems[0].documentData);
|
||||
expect(await pdfHasFormFields(templatePdfBuffer)).toBe(true);
|
||||
|
||||
// Verify we can read a text field value (should be empty initially)
|
||||
const initialValue = await getPdfTextFieldValue(templatePdfBuffer, FORM_FIELDS.TEXT_FIELD);
|
||||
expect(initialValue).toBe('');
|
||||
|
||||
// Now create a document with form values
|
||||
const testValues = {
|
||||
[FORM_FIELDS.TEXT_FIELD]: 'Inserted Text Value',
|
||||
[FORM_FIELDS.COMPANY_NAME]: 'Test Company Name',
|
||||
};
|
||||
|
||||
const useTemplateRes = await request.post(`${WEBAPP_BASE_URL}/api/v2-beta/template/use`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: {
|
||||
templateId: mapSecondaryIdToTemplateId(template.secondaryId),
|
||||
recipients: [
|
||||
{
|
||||
id: template.recipients[0].id,
|
||||
email: 'recipient@example.com',
|
||||
name: 'Test Recipient',
|
||||
},
|
||||
],
|
||||
formValues: testValues,
|
||||
},
|
||||
});
|
||||
|
||||
expect(useTemplateRes.ok()).toBeTruthy();
|
||||
const documentResponse = await useTemplateRes.json();
|
||||
|
||||
const document = await prisma.envelope.findFirstOrThrow({
|
||||
where: { id: documentResponse.envelopeId },
|
||||
include: {
|
||||
envelopeItems: { include: { documentData: true } },
|
||||
},
|
||||
});
|
||||
|
||||
// The form should be flattened, so we can't read form fields
|
||||
const documentPdfBuffer = await getFileServerSide(document.envelopeItems[0].documentData);
|
||||
expect(await pdfHasFormFields(documentPdfBuffer)).toBe(false);
|
||||
|
||||
// The values should have been inserted before flattening
|
||||
// We can't verify the actual text content easily without visual inspection,
|
||||
// but we can verify the form fields are gone (flattened)
|
||||
const fieldNames = await getPdfFormFieldNames(documentPdfBuffer);
|
||||
expect(fieldNames.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Edge Cases', () => {
|
||||
test('should handle PDF without form fields gracefully', async ({ request }) => {
|
||||
const { user, team } = await seedUser();
|
||||
const { token } = await createApiToken({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
tokenName: 'test',
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
// Use a PDF without form fields
|
||||
const examplePdf = fs.readFileSync(path.join(__dirname, '../../../../assets/example.pdf'));
|
||||
|
||||
const payload: TCreateEnvelopePayload = {
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
title: 'Document with No Form Fields',
|
||||
formValues: {
|
||||
nonexistent_field: 'Some Value',
|
||||
},
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append('payload', JSON.stringify(payload));
|
||||
formData.append('files', new File([examplePdf], 'example.pdf', { type: 'application/pdf' }));
|
||||
|
||||
const res = await request.post(`${baseUrl}/envelope/create`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: formData,
|
||||
});
|
||||
|
||||
// Should succeed even with formValues for non-existent fields
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const response = (await res.json()) as TCreateEnvelopeResponse;
|
||||
const envelope = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: response.id },
|
||||
include: {
|
||||
envelopeItems: { include: { documentData: true } },
|
||||
},
|
||||
});
|
||||
|
||||
expect(envelope.formValues).toEqual({ nonexistent_field: 'Some Value' });
|
||||
});
|
||||
|
||||
test('should handle empty formValues object', async ({ request }) => {
|
||||
const { user, team } = await seedUser();
|
||||
const { token } = await createApiToken({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
tokenName: 'test',
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
const payload: TCreateEnvelopePayload = {
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
title: 'Document with Empty Form Values',
|
||||
formValues: {},
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append('payload', JSON.stringify(payload));
|
||||
formData.append(
|
||||
'files',
|
||||
new File([formFieldsPdf], 'form-fields-test.pdf', { type: 'application/pdf' }),
|
||||
);
|
||||
|
||||
const res = await request.post(`${baseUrl}/envelope/create`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: formData,
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const response = (await res.json()) as TCreateEnvelopeResponse;
|
||||
const envelope = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: response.id },
|
||||
include: {
|
||||
envelopeItems: { include: { documentData: true } },
|
||||
},
|
||||
});
|
||||
|
||||
// Form should still be flattened for DOCUMENT type
|
||||
const documentData = envelope.envelopeItems[0].documentData;
|
||||
const pdfBuffer = await getFileServerSide(documentData);
|
||||
|
||||
expect(await pdfHasFormFields(pdfBuffer)).toBe(false);
|
||||
});
|
||||
|
||||
test('should handle partial formValues (only some fields)', async ({ request }) => {
|
||||
const { user, team } = await seedUser();
|
||||
const { token } = await createApiToken({
|
||||
userId: user.id,
|
||||
teamId: team.id,
|
||||
tokenName: 'test',
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
const payload: TCreateEnvelopePayload = {
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
title: 'Document with Partial Form Values',
|
||||
formValues: {
|
||||
[FORM_FIELDS.TEXT_FIELD]: 'Only this field',
|
||||
// Other fields not set
|
||||
},
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append('payload', JSON.stringify(payload));
|
||||
formData.append(
|
||||
'files',
|
||||
new File([formFieldsPdf], 'form-fields-test.pdf', { type: 'application/pdf' }),
|
||||
);
|
||||
|
||||
const res = await request.post(`${baseUrl}/envelope/create`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: formData,
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const response = (await res.json()) as TCreateEnvelopeResponse;
|
||||
const envelope = await prisma.envelope.findUniqueOrThrow({
|
||||
where: { id: response.id },
|
||||
include: {
|
||||
envelopeItems: { include: { documentData: true } },
|
||||
},
|
||||
});
|
||||
|
||||
// Should store the partial formValues
|
||||
expect(envelope.formValues).toEqual({
|
||||
[FORM_FIELDS.TEXT_FIELD]: 'Only this field',
|
||||
});
|
||||
|
||||
// Form should still be flattened
|
||||
const documentData = envelope.envelopeItems[0].documentData;
|
||||
const pdfBuffer = await getFileServerSide(documentData);
|
||||
|
||||
expect(await pdfHasFormFields(pdfBuffer)).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,427 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
import { createApiToken } from '@documenso/lib/server-only/public-api/create-api-token';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { EnvelopeType, RecipientRole } from '@documenso/prisma/client';
|
||||
import { seedTeam } from '@documenso/prisma/seed/teams';
|
||||
import { seedBlankTemplate } from '@documenso/prisma/seed/templates';
|
||||
import type {
|
||||
TCreateEnvelopePayload,
|
||||
TCreateEnvelopeResponse,
|
||||
} from '@documenso/trpc/server/envelope-router/create-envelope.types';
|
||||
|
||||
import { apiSignin } from '../fixtures/authentication';
|
||||
|
||||
const WEBAPP_BASE_URL = NEXT_PUBLIC_WEBAPP_URL();
|
||||
const baseUrl = `${WEBAPP_BASE_URL}/api/v2-beta`;
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
/**
|
||||
* Helper function to set default recipients for a team
|
||||
*/
|
||||
const setTeamDefaultRecipients = async (
|
||||
teamId: number,
|
||||
defaultRecipients: Array<{ email: string; name: string; role: RecipientRole }>,
|
||||
) => {
|
||||
const teamSettings = await prisma.teamGlobalSettings.findFirstOrThrow({
|
||||
where: {
|
||||
team: {
|
||||
id: teamId,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.teamGlobalSettings.update({
|
||||
where: {
|
||||
id: teamSettings.id,
|
||||
},
|
||||
data: {
|
||||
defaultRecipients,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
test.describe('Default Recipients', () => {
|
||||
test('[DEFAULT_RECIPIENTS]: default recipients are added to documents created via UI', async ({
|
||||
page,
|
||||
}) => {
|
||||
const { team, owner } = await seedTeam({
|
||||
createTeamMembers: 2,
|
||||
});
|
||||
|
||||
// Get a team member to set as default recipient
|
||||
const teamMembers = await prisma.organisationMember.findMany({
|
||||
where: {
|
||||
organisationId: team.organisationId,
|
||||
userId: {
|
||||
not: owner.id,
|
||||
},
|
||||
},
|
||||
include: {
|
||||
user: true,
|
||||
},
|
||||
});
|
||||
|
||||
const defaultRecipientUser = teamMembers[0].user;
|
||||
|
||||
// Set up default recipients for the team
|
||||
await setTeamDefaultRecipients(team.id, [
|
||||
{
|
||||
email: defaultRecipientUser.email,
|
||||
name: defaultRecipientUser.name || defaultRecipientUser.email,
|
||||
role: RecipientRole.CC,
|
||||
},
|
||||
]);
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: owner.email,
|
||||
redirectPath: `/t/${team.url}/documents`,
|
||||
});
|
||||
|
||||
// Upload document via UI - this triggers document creation with default recipients
|
||||
const [fileChooser] = await Promise.all([
|
||||
page.waitForEvent('filechooser'),
|
||||
page
|
||||
.locator('input[type=file]')
|
||||
.nth(1)
|
||||
.evaluate((e) => {
|
||||
if (e instanceof HTMLInputElement) {
|
||||
e.click();
|
||||
}
|
||||
}),
|
||||
]);
|
||||
|
||||
await fileChooser.setFiles(path.join(__dirname, '../../../../assets/example.pdf'));
|
||||
|
||||
// Wait to be redirected to the edit page (v2 envelope editor)
|
||||
await page.waitForURL(new RegExp(`/t/${team.url}/documents/envelope_.*`));
|
||||
|
||||
// Extract document ID from URL
|
||||
const urlParts = page.url().split('/');
|
||||
const documentId = urlParts.find((part) => part.startsWith('envelope_'));
|
||||
|
||||
// Wait for the Recipients card to be visible (v2 envelope editor)
|
||||
await expect(page.getByRole('heading', { name: 'Recipients' })).toBeVisible();
|
||||
|
||||
await expect(page.getByTestId('signer-email-input').first()).not.toBeEmpty();
|
||||
|
||||
await page.getByRole('button', { name: 'Add Signer' }).click();
|
||||
|
||||
// Add a regular signer using the v2 editor
|
||||
await page.getByTestId('signer-email-input').last().fill('regular-signer@documenso.com');
|
||||
await page
|
||||
.getByPlaceholder(/Recipient/)
|
||||
.first()
|
||||
.fill('Regular Signer');
|
||||
|
||||
// Wait for autosave to complete
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Verify that default recipient is present in the database
|
||||
await expect(async () => {
|
||||
const envelope = await prisma.envelope.findFirstOrThrow({
|
||||
where: {
|
||||
id: documentId,
|
||||
},
|
||||
include: {
|
||||
recipients: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Should have 2 recipients: the regular signer + the default recipient
|
||||
expect(envelope.recipients.length).toBe(2);
|
||||
|
||||
const defaultRecipient = envelope.recipients.find(
|
||||
(r) => r.email.toLowerCase() === defaultRecipientUser.email.toLowerCase(),
|
||||
);
|
||||
expect(defaultRecipient).toBeDefined();
|
||||
expect(defaultRecipient?.role).toBe(RecipientRole.CC);
|
||||
|
||||
const regularSigner = envelope.recipients.find(
|
||||
(r) => r.email === 'regular-signer@documenso.com',
|
||||
);
|
||||
expect(regularSigner).toBeDefined();
|
||||
}).toPass();
|
||||
});
|
||||
|
||||
// TODO: Are we intending to allow default recipients to be removed from a document?
|
||||
test.skip('[DEFAULT_RECIPIENTS]: default recipients cannot be removed from a document', async ({
|
||||
page,
|
||||
}) => {
|
||||
const { team, owner } = await seedTeam({
|
||||
createTeamMembers: 2,
|
||||
});
|
||||
|
||||
// Get a team member to set as default recipient
|
||||
const teamMembers = await prisma.organisationMember.findMany({
|
||||
where: {
|
||||
organisationId: team.organisationId,
|
||||
userId: {
|
||||
not: owner.id,
|
||||
},
|
||||
},
|
||||
include: {
|
||||
user: true,
|
||||
},
|
||||
});
|
||||
|
||||
const defaultRecipientUser = teamMembers[0].user;
|
||||
|
||||
// Set up default recipients for the team
|
||||
await setTeamDefaultRecipients(team.id, [
|
||||
{
|
||||
email: defaultRecipientUser.email,
|
||||
name: defaultRecipientUser.name || defaultRecipientUser.email,
|
||||
role: RecipientRole.CC,
|
||||
},
|
||||
]);
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: owner.email,
|
||||
redirectPath: `/t/${team.url}/documents`,
|
||||
});
|
||||
|
||||
// Upload document via UI - this triggers document creation with default recipients
|
||||
const [fileChooser] = await Promise.all([
|
||||
page.waitForEvent('filechooser'),
|
||||
page
|
||||
.locator('input[type=file]')
|
||||
.nth(1)
|
||||
.evaluate((e) => {
|
||||
if (e instanceof HTMLInputElement) {
|
||||
e.click();
|
||||
}
|
||||
}),
|
||||
]);
|
||||
|
||||
await fileChooser.setFiles(path.join(__dirname, '../../../../assets/example.pdf'));
|
||||
|
||||
// Wait to be redirected to the edit page (v2 envelope editor)
|
||||
await page.waitForURL(new RegExp(`/t/${team.url}/documents/envelope_.*`));
|
||||
|
||||
// Extract document ID from URL
|
||||
const urlParts = page.url().split('/');
|
||||
const documentId = urlParts.find((part) => part.startsWith('envelope_'));
|
||||
|
||||
// Replace the default recipient with a regular signer
|
||||
await page.getByTestId('signer-email-input').first().fill('regular-signer@documenso.com');
|
||||
await page
|
||||
.getByPlaceholder(/Recipient/)
|
||||
.first()
|
||||
.fill('Regular Signer');
|
||||
|
||||
// Wait for autosave to complete
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Wait for recipients to be saved
|
||||
await expect(async () => {
|
||||
const envelope = await prisma.envelope.findFirstOrThrow({
|
||||
where: {
|
||||
id: documentId,
|
||||
},
|
||||
include: {
|
||||
recipients: true,
|
||||
},
|
||||
});
|
||||
expect(envelope.recipients.length).toBe(2);
|
||||
}).toPass();
|
||||
|
||||
// Verify that the default recipient's remove button is disabled
|
||||
// In the v2 editor, default recipients should have a disabled remove button
|
||||
// Find the fieldset containing the default recipient's email and check if its remove button is disabled
|
||||
const defaultRecipientRow = page.locator('fieldset').filter({
|
||||
hasText: defaultRecipientUser.email,
|
||||
});
|
||||
|
||||
// The default recipient row should exist and have a disabled remove button
|
||||
await expect(defaultRecipientRow).toHaveCount(1);
|
||||
const removeButton = defaultRecipientRow.getByTestId('remove-signer-button');
|
||||
await expect(removeButton).toBeDisabled();
|
||||
});
|
||||
|
||||
test('[DEFAULT_RECIPIENTS]: documents created via API have default recipients', async ({
|
||||
request,
|
||||
}) => {
|
||||
const { team, owner } = await seedTeam({
|
||||
createTeamMembers: 2,
|
||||
});
|
||||
|
||||
// Get a team member to set as default recipient
|
||||
const teamMembers = await prisma.organisationMember.findMany({
|
||||
where: {
|
||||
organisationId: team.organisationId,
|
||||
userId: {
|
||||
not: owner.id,
|
||||
},
|
||||
},
|
||||
include: {
|
||||
user: true,
|
||||
},
|
||||
});
|
||||
|
||||
const defaultRecipientUser = teamMembers[0].user;
|
||||
|
||||
// Set up default recipients for the team
|
||||
await setTeamDefaultRecipients(team.id, [
|
||||
{
|
||||
email: defaultRecipientUser.email,
|
||||
name: defaultRecipientUser.name || defaultRecipientUser.email,
|
||||
role: RecipientRole.CC,
|
||||
},
|
||||
]);
|
||||
|
||||
// Create API token
|
||||
const { token } = await createApiToken({
|
||||
userId: owner.id,
|
||||
teamId: team.id,
|
||||
tokenName: 'test-token',
|
||||
expiresIn: null,
|
||||
});
|
||||
|
||||
// Create envelope via API
|
||||
const payload: TCreateEnvelopePayload = {
|
||||
type: EnvelopeType.DOCUMENT,
|
||||
title: 'Test Document with Default Recipients',
|
||||
recipients: [
|
||||
{
|
||||
email: 'api-recipient@documenso.com',
|
||||
name: 'API Recipient',
|
||||
role: RecipientRole.SIGNER,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('payload', JSON.stringify(payload));
|
||||
|
||||
const pdfData = fs.readFileSync(path.join(__dirname, '../../../../assets/example.pdf'));
|
||||
formData.append('files', new File([pdfData], 'test.pdf', { type: 'application/pdf' }));
|
||||
|
||||
const res = await request.post(`${baseUrl}/envelope/create`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: formData,
|
||||
});
|
||||
|
||||
expect(res.ok()).toBeTruthy();
|
||||
expect(res.status()).toBe(200);
|
||||
|
||||
const response = (await res.json()) as TCreateEnvelopeResponse;
|
||||
|
||||
// Verify the envelope has both the API recipient and the default recipient
|
||||
const envelope = await prisma.envelope.findUniqueOrThrow({
|
||||
where: {
|
||||
id: response.id,
|
||||
},
|
||||
include: {
|
||||
recipients: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(envelope.recipients.length).toBe(2);
|
||||
|
||||
const apiRecipient = envelope.recipients.find((r) => r.email === 'api-recipient@documenso.com');
|
||||
expect(apiRecipient).toBeDefined();
|
||||
expect(apiRecipient?.role).toBe(RecipientRole.SIGNER);
|
||||
|
||||
const defaultRecipient = envelope.recipients.find(
|
||||
(r) => r.email.toLowerCase() === defaultRecipientUser.email.toLowerCase(),
|
||||
);
|
||||
expect(defaultRecipient).toBeDefined();
|
||||
expect(defaultRecipient?.role).toBe(RecipientRole.CC);
|
||||
});
|
||||
|
||||
test('[DEFAULT_RECIPIENTS]: documents created from template have default recipients', async ({
|
||||
page,
|
||||
}) => {
|
||||
const { team, owner } = await seedTeam({
|
||||
createTeamMembers: 2,
|
||||
});
|
||||
|
||||
// Get a team member to set as default recipient
|
||||
const teamMembers = await prisma.organisationMember.findMany({
|
||||
where: {
|
||||
organisationId: team.organisationId,
|
||||
userId: {
|
||||
not: owner.id,
|
||||
},
|
||||
},
|
||||
include: {
|
||||
user: true,
|
||||
},
|
||||
});
|
||||
|
||||
const defaultRecipientUser = teamMembers[0].user;
|
||||
|
||||
// Set up default recipients for the team
|
||||
await setTeamDefaultRecipients(team.id, [
|
||||
{
|
||||
email: defaultRecipientUser.email,
|
||||
name: defaultRecipientUser.name || defaultRecipientUser.email,
|
||||
role: RecipientRole.CC,
|
||||
},
|
||||
]);
|
||||
|
||||
// Create a template
|
||||
const template = await seedBlankTemplate(owner, team.id);
|
||||
|
||||
await apiSignin({
|
||||
page,
|
||||
email: owner.email,
|
||||
redirectPath: `/t/${team.url}/templates/${template.id}/edit`,
|
||||
});
|
||||
|
||||
// Set template title
|
||||
await page.getByLabel('Title').fill('Template with Default Recipients');
|
||||
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'Add Placeholder' })).toBeVisible();
|
||||
|
||||
// Add a template recipient
|
||||
await page.getByPlaceholder('Email').fill('template-recipient@documenso.com');
|
||||
await page.getByPlaceholder('Name').fill('Template Recipient');
|
||||
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'Add Fields' })).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: 'Save template' }).click();
|
||||
|
||||
// Use template to create document
|
||||
await page.waitForURL(`/t/${team.url}/templates`);
|
||||
await page.getByRole('button', { name: 'Use Template' }).click();
|
||||
await page.getByRole('button', { name: 'Create as draft' }).click();
|
||||
|
||||
// Wait for document to be created
|
||||
await page.waitForURL(new RegExp(`/t/${team.url}/documents/envelope_.*`));
|
||||
|
||||
const documentId = page.url().split('/').pop();
|
||||
|
||||
// Verify the document has both the template recipient and the default recipient
|
||||
const document = await prisma.envelope.findFirstOrThrow({
|
||||
where: {
|
||||
id: documentId,
|
||||
},
|
||||
include: {
|
||||
recipients: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(document.recipients.length).toBe(2);
|
||||
|
||||
const templateRecipient = document.recipients.find(
|
||||
(r) => r.email === 'template-recipient@documenso.com',
|
||||
);
|
||||
expect(templateRecipient).toBeDefined();
|
||||
|
||||
const defaultRecipient = document.recipients.find(
|
||||
(r) => r.email.toLowerCase() === defaultRecipientUser.email.toLowerCase(),
|
||||
);
|
||||
expect(defaultRecipient).toBeDefined();
|
||||
expect(defaultRecipient?.role).toBe(RecipientRole.CC);
|
||||
});
|
||||
});
|
||||
@@ -505,7 +505,9 @@ test('[TEMPLATE]: should create a document from a template using template docume
|
||||
});
|
||||
|
||||
expect(document.title).toEqual('TEMPLATE_WITH_ORIGINAL_DOC');
|
||||
expect(firstDocumentData.data).toEqual(templateWithData.envelopeItems[0].documentData.data);
|
||||
expect(firstDocumentData.initialData).toEqual(
|
||||
templateWithData.envelopeItems[0].documentData.data,
|
||||
);
|
||||
expect(firstDocumentData.initialData).toEqual(
|
||||
templateWithData.envelopeItems[0].documentData.initialData,
|
||||
);
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
"@hono/standard-validator": "^0.2.0",
|
||||
"@oslojs/crypto": "^1.0.1",
|
||||
"@oslojs/encoding": "^1.1.0",
|
||||
"@simplewebauthn/server": "^13.2.2",
|
||||
"arctic": "^3.7.0",
|
||||
"hono": "4.10.6",
|
||||
"hono": "4.11.4",
|
||||
"luxon": "^3.7.2",
|
||||
"nanoid": "^5.1.6",
|
||||
"ts-pattern": "^5.9.0",
|
||||
"zod": "^3.25.76"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { sValidator } from '@hono/standard-validator';
|
||||
import { UserSecurityAuditLogType } from '@prisma/client';
|
||||
import { verifyAuthenticationResponse } from '@simplewebauthn/server';
|
||||
import { isoBase64URL } from '@simplewebauthn/server/helpers';
|
||||
import { Hono } from 'hono';
|
||||
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
@@ -80,9 +81,9 @@ export const passkeyRoute = new Hono<HonoAuthContext>()
|
||||
expectedChallenge: challengeToken.token,
|
||||
expectedOrigin: origin,
|
||||
expectedRPID: rpId,
|
||||
authenticator: {
|
||||
credentialID: new Uint8Array(Array.from(passkey.credentialId)),
|
||||
credentialPublicKey: new Uint8Array(passkey.credentialPublicKey),
|
||||
credential: {
|
||||
id: isoBase64URL.fromBuffer(passkey.credentialId),
|
||||
publicKey: new Uint8Array(passkey.credentialPublicKey),
|
||||
counter: Number(passkey.counter),
|
||||
},
|
||||
}).catch(() => null);
|
||||
|
||||
@@ -1,30 +1,33 @@
|
||||
import type { MessageDescriptor } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
|
||||
import type { TDocumentAuth } from '../types/document-auth';
|
||||
import { DocumentAuth } from '../types/document-auth';
|
||||
|
||||
type DocumentAuthTypeData = {
|
||||
key: TDocumentAuth;
|
||||
value: string;
|
||||
value: MessageDescriptor;
|
||||
};
|
||||
|
||||
export const DOCUMENT_AUTH_TYPES: Record<string, DocumentAuthTypeData> = {
|
||||
[DocumentAuth.ACCOUNT]: {
|
||||
key: DocumentAuth.ACCOUNT,
|
||||
value: 'Require account',
|
||||
value: msg`Require account`,
|
||||
},
|
||||
[DocumentAuth.PASSKEY]: {
|
||||
key: DocumentAuth.PASSKEY,
|
||||
value: 'Require passkey',
|
||||
value: msg`Require passkey`,
|
||||
},
|
||||
[DocumentAuth.TWO_FACTOR_AUTH]: {
|
||||
key: DocumentAuth.TWO_FACTOR_AUTH,
|
||||
value: 'Require 2FA',
|
||||
value: msg`Require 2FA`,
|
||||
},
|
||||
[DocumentAuth.PASSWORD]: {
|
||||
key: DocumentAuth.PASSWORD,
|
||||
value: 'Require password',
|
||||
value: msg`Require password`,
|
||||
},
|
||||
[DocumentAuth.EXPLICIT_NONE]: {
|
||||
key: DocumentAuth.EXPLICIT_NONE,
|
||||
value: 'None (Overrides global settings)',
|
||||
value: msg`None (Overrides global settings)`,
|
||||
},
|
||||
} satisfies Record<TDocumentAuth, DocumentAuthTypeData>;
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
import type { MessageDescriptor } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
|
||||
import { DocumentVisibility } from '@documenso/lib/types/document-visibility';
|
||||
|
||||
import type { TDocumentVisibility } from '../types/document-visibility';
|
||||
|
||||
type DocumentVisibilityTypeData = {
|
||||
key: TDocumentVisibility;
|
||||
value: string;
|
||||
value: MessageDescriptor;
|
||||
};
|
||||
|
||||
export const DOCUMENT_VISIBILITY: Record<string, DocumentVisibilityTypeData> = {
|
||||
[DocumentVisibility.ADMIN]: {
|
||||
key: DocumentVisibility.ADMIN,
|
||||
value: 'Admins only',
|
||||
value: msg`Admins only`,
|
||||
},
|
||||
[DocumentVisibility.EVERYONE]: {
|
||||
key: DocumentVisibility.EVERYONE,
|
||||
value: 'Everyone',
|
||||
value: msg`Everyone`,
|
||||
},
|
||||
[DocumentVisibility.MANAGER_AND_ABOVE]: {
|
||||
key: DocumentVisibility.MANAGER_AND_ABOVE,
|
||||
value: 'Managers and above',
|
||||
value: msg`Managers and above`,
|
||||
},
|
||||
} satisfies Record<TDocumentVisibility, DocumentVisibilityTypeData>;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
"@node-rs/bcrypt": "^1.10.7",
|
||||
"@pdf-lib/fontkit": "^1.1.1",
|
||||
"@scure/base": "^1.2.6",
|
||||
"@simplewebauthn/server": "^13.2.2",
|
||||
"@sindresorhus/slugify": "^3.0.0",
|
||||
"@team-plain/typescript-sdk": "^5.11.0",
|
||||
"@vvo/tzdb": "^6.196.0",
|
||||
@@ -54,7 +55,7 @@
|
||||
"posthog-js": "^1.297.2",
|
||||
"posthog-node": "4.18.0",
|
||||
"react": "^18",
|
||||
"react-pdf": "^10.2.0",
|
||||
"react-pdf": "^10.3.0",
|
||||
"remeda": "^2.32.0",
|
||||
"sharp": "0.34.5",
|
||||
"skia-canvas": "^3.0.8",
|
||||
@@ -67,4 +68,4 @@
|
||||
"@types/luxon": "^3.7.1",
|
||||
"@types/pg": "^8.15.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Passkey } from '@prisma/client';
|
||||
import { generateAuthenticationOptions } from '@simplewebauthn/server';
|
||||
import type { AuthenticatorTransportFuture } from '@simplewebauthn/types';
|
||||
import type { AuthenticatorTransportFuture } from '@simplewebauthn/server';
|
||||
import { isoBase64URL } from '@simplewebauthn/server/helpers';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
@@ -53,8 +54,7 @@ export const createPasskeyAuthenticationOptions = async ({
|
||||
allowCredentials: preferredPasskey
|
||||
? [
|
||||
{
|
||||
id: preferredPasskey.credentialId,
|
||||
type: 'public-key',
|
||||
id: isoBase64URL.fromBuffer(preferredPasskey.credentialId),
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
transports: preferredPasskey.transports as AuthenticatorTransportFuture[],
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { generateRegistrationOptions } from '@simplewebauthn/server';
|
||||
import type { AuthenticatorTransportFuture } from '@simplewebauthn/types';
|
||||
import type { AuthenticatorTransportFuture } from '@simplewebauthn/server';
|
||||
import { isoBase64URL } from '@simplewebauthn/server/helpers';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
@@ -32,14 +33,13 @@ export const createPasskeyRegistrationOptions = async ({
|
||||
const options = await generateRegistrationOptions({
|
||||
rpName,
|
||||
rpID,
|
||||
userID: userId.toString(),
|
||||
userID: Buffer.from(userId.toString()),
|
||||
userName: user.email,
|
||||
userDisplayName: user.name ?? undefined,
|
||||
timeout: PASSKEY_TIMEOUT,
|
||||
attestationType: 'none',
|
||||
excludeCredentials: passkeys.map((passkey) => ({
|
||||
id: passkey.credentialId,
|
||||
type: 'public-key',
|
||||
id: isoBase64URL.fromBuffer(passkey.credentialId),
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
transports: passkey.transports as AuthenticatorTransportFuture[],
|
||||
})),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { UserSecurityAuditLogType } from '@prisma/client';
|
||||
import { verifyRegistrationResponse } from '@simplewebauthn/server';
|
||||
import type { RegistrationResponseJSON } from '@simplewebauthn/types';
|
||||
import type { RegistrationResponseJSON } from '@simplewebauthn/server';
|
||||
import { isoBase64URL } from '@simplewebauthn/server/helpers';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
@@ -83,20 +84,19 @@ export const createPasskey = async ({
|
||||
});
|
||||
}
|
||||
|
||||
const { credentialPublicKey, credentialID, counter, credentialDeviceType, credentialBackedUp } =
|
||||
verification.registrationInfo;
|
||||
const { credentialDeviceType, credentialBackedUp, credential } = verification.registrationInfo;
|
||||
|
||||
await prisma.$transaction(async (tx) => {
|
||||
await tx.passkey.create({
|
||||
data: {
|
||||
userId,
|
||||
name: passkeyName,
|
||||
credentialId: Buffer.from(credentialID),
|
||||
credentialPublicKey: Buffer.from(credentialPublicKey),
|
||||
counter,
|
||||
credentialId: Buffer.from(isoBase64URL.toBuffer(credential.id)),
|
||||
credentialPublicKey: Buffer.from(credential.publicKey),
|
||||
counter: credential.counter,
|
||||
credentialDeviceType,
|
||||
credentialBackedUp,
|
||||
transports: verificationResponse.response.transports,
|
||||
transports: credential.transports,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Envelope, Recipient } from '@prisma/client';
|
||||
import { verifyAuthenticationResponse } from '@simplewebauthn/server';
|
||||
import { isoBase64URL } from '@simplewebauthn/server/helpers';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
@@ -252,9 +253,9 @@ const verifyPasskey = async ({
|
||||
expectedChallenge: verificationToken.token,
|
||||
expectedOrigin: origin,
|
||||
expectedRPID: rpId,
|
||||
authenticator: {
|
||||
credentialID: new Uint8Array(Array.from(passkey.credentialId)),
|
||||
credentialPublicKey: new Uint8Array(passkey.credentialPublicKey),
|
||||
credential: {
|
||||
id: isoBase64URL.fromBuffer(passkey.credentialId),
|
||||
publicKey: new Uint8Array(passkey.credentialPublicKey),
|
||||
counter: Number(passkey.counter),
|
||||
},
|
||||
}).catch(() => null); // May want to log this for insights.
|
||||
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
mapEnvelopeToWebhookDocumentPayload,
|
||||
} from '../../types/webhook-payload';
|
||||
import { getFileServerSide } from '../../universal/upload/get-file.server';
|
||||
import { putPdfFileServerSide } from '../../universal/upload/put-file.server';
|
||||
import { putNormalizedPdfFileServerSide } from '../../universal/upload/put-file.server';
|
||||
import { isDocumentCompleted } from '../../utils/document';
|
||||
import { extractDocumentAuthMethods } from '../../utils/document-auth';
|
||||
import { type EnvelopeIdOptions, mapSecondaryIdToDocumentId } from '../../utils/envelope';
|
||||
@@ -336,10 +336,12 @@ const injectFormValuesIntoDocument = async (
|
||||
fileName = `${envelope.title}.pdf`;
|
||||
}
|
||||
|
||||
const newDocumentData = await putPdfFileServerSide({
|
||||
name: fileName,
|
||||
type: 'application/pdf',
|
||||
arrayBuffer: async () => Promise.resolve(prefilled),
|
||||
const newDocumentData = await putNormalizedPdfFileServerSide({
|
||||
file: {
|
||||
name: fileName,
|
||||
type: 'application/pdf',
|
||||
arrayBuffer: async () => Promise.resolve(prefilled),
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.envelopeItem.update({
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { normalizePdf as makeNormalizedPdf } from '@documenso/lib/server-only/pdf/normalize-pdf';
|
||||
import { ZDefaultRecipientsSchema } from '@documenso/lib/types/default-recipients';
|
||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
|
||||
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import { nanoid, prefixedId } from '@documenso/lib/universal/id';
|
||||
@@ -184,7 +185,9 @@ export const createEnvelope = async ({
|
||||
|
||||
const buffer = await getFileServerSide(documentData);
|
||||
|
||||
const normalizedPdf = await makeNormalizedPdf(Buffer.from(buffer));
|
||||
const normalizedPdf = await makeNormalizedPdf(Buffer.from(buffer), {
|
||||
flattenForm: type !== EnvelopeType.TEMPLATE,
|
||||
});
|
||||
|
||||
const titleToUse = item.title || title;
|
||||
|
||||
@@ -345,8 +348,22 @@ export const createEnvelope = async ({
|
||||
|
||||
const firstEnvelopeItem = envelope.envelopeItems[0];
|
||||
|
||||
const defaultRecipients = settings.defaultRecipients
|
||||
? ZDefaultRecipientsSchema.parse(settings.defaultRecipients)
|
||||
: [];
|
||||
|
||||
const mappedDefaultRecipients: CreateEnvelopeRecipientOptions[] = defaultRecipients.map(
|
||||
(recipient) => ({
|
||||
email: recipient.email,
|
||||
name: recipient.name,
|
||||
role: recipient.role,
|
||||
}),
|
||||
);
|
||||
|
||||
const allRecipients = [...(data.recipients || []), ...mappedDefaultRecipients];
|
||||
|
||||
await Promise.all(
|
||||
(data.recipients || []).map(async (recipient) => {
|
||||
allRecipients.map(async (recipient) => {
|
||||
const recipientAuthOptions = createRecipientAuthOptions({
|
||||
accessAuth: recipient.accessAuth ?? [],
|
||||
actionAuth: recipient.actionAuth ?? [],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Prisma } from '@prisma/client';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { OrganisationType } from '@prisma/client';
|
||||
import { OrganisationMemberRole } from '@prisma/client';
|
||||
|
||||
@@ -63,6 +63,7 @@ export const createOrganisation = async ({
|
||||
const organisationSetting = await tx.organisationGlobalSettings.create({
|
||||
data: {
|
||||
...generateDefaultOrganisationSettings(),
|
||||
defaultRecipients: Prisma.DbNull,
|
||||
id: generateDatabaseId('org_setting'),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -4,7 +4,9 @@ import { AppError } from '../../errors/app-error';
|
||||
import { flattenAnnotations } from './flatten-annotations';
|
||||
import { flattenForm, removeOptionalContentGroups } from './flatten-form';
|
||||
|
||||
export const normalizePdf = async (pdf: Buffer) => {
|
||||
export const normalizePdf = async (pdf: Buffer, options: { flattenForm?: boolean } = {}) => {
|
||||
const shouldFlattenForm = options.flattenForm ?? true;
|
||||
|
||||
const pdfDoc = await PDFDocument.load(pdf).catch((e) => {
|
||||
console.error(`PDF normalization error: ${e.message}`);
|
||||
|
||||
@@ -20,8 +22,11 @@ export const normalizePdf = async (pdf: Buffer) => {
|
||||
}
|
||||
|
||||
removeOptionalContentGroups(pdfDoc);
|
||||
await flattenForm(pdfDoc);
|
||||
flattenAnnotations(pdfDoc);
|
||||
|
||||
if (shouldFlattenForm) {
|
||||
await flattenForm(pdfDoc);
|
||||
flattenAnnotations(pdfDoc);
|
||||
}
|
||||
|
||||
return Buffer.from(await pdfDoc.save());
|
||||
};
|
||||
|
||||
@@ -8,7 +8,6 @@ import 'konva/skia-backend';
|
||||
import { DateTime } from 'luxon';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import sharp from 'sharp';
|
||||
import type { Canvas } from 'skia-canvas';
|
||||
import { FontLibrary } from 'skia-canvas';
|
||||
import { Image as SkiaImage } from 'skia-canvas';
|
||||
@@ -22,6 +21,7 @@ import {
|
||||
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];
|
||||
|
||||
@@ -584,7 +584,7 @@ const renderBranding = async ({ qrToken, i18n }: { qrToken: string | null; i18n:
|
||||
ecc: 'Q',
|
||||
});
|
||||
|
||||
const svgImage = await sharp(Buffer.from(qrSvg)).toFormat('png').toBuffer();
|
||||
const svgImage = await svgToPng(qrSvg);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const qrSkiaImage = new SkiaImage(svgImage) as unknown as HTMLImageElement;
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { OrganisationGroupType, OrganisationMemberRole, TeamMemberRole } from '@prisma/client';
|
||||
import {
|
||||
OrganisationGroupType,
|
||||
OrganisationMemberRole,
|
||||
Prisma,
|
||||
TeamMemberRole,
|
||||
} from '@prisma/client';
|
||||
import { match } from 'ts-pattern';
|
||||
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
@@ -137,6 +142,7 @@ export const createTeam = async ({
|
||||
const teamSettings = await tx.teamGlobalSettings.create({
|
||||
data: {
|
||||
...generateDefaultTeamSettings(),
|
||||
defaultRecipients: Prisma.DbNull,
|
||||
id: generateDatabaseId('team_setting'),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -19,9 +19,11 @@ import { prisma } from '@documenso/prisma';
|
||||
import { DEFAULT_DOCUMENT_DATE_FORMAT } from '../../constants/date-formats';
|
||||
import type { SupportedLanguageCodes } from '../../constants/i18n';
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import { ZDefaultRecipientsSchema } from '../../types/default-recipients';
|
||||
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
|
||||
import { ZRecipientAuthOptionsSchema } from '../../types/document-auth';
|
||||
import type { TDocumentEmailSettings } from '../../types/document-email';
|
||||
import type { TDocumentFormValues } from '../../types/document-form-values';
|
||||
import type {
|
||||
TCheckboxFieldMeta,
|
||||
TDropdownFieldMeta,
|
||||
@@ -42,7 +44,7 @@ import {
|
||||
} from '../../types/webhook-payload';
|
||||
import type { ApiRequestMetadata } from '../../universal/extract-request-metadata';
|
||||
import { getFileServerSide } from '../../universal/upload/get-file.server';
|
||||
import { putPdfFileServerSide } from '../../universal/upload/put-file.server';
|
||||
import { putNormalizedPdfFileServerSide } from '../../universal/upload/put-file.server';
|
||||
import { extractDerivedDocumentMeta } from '../../utils/document';
|
||||
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
|
||||
import {
|
||||
@@ -55,6 +57,7 @@ import { mapSecondaryIdToTemplateId } from '../../utils/envelope';
|
||||
import { buildTeamWhereQuery } from '../../utils/teams';
|
||||
import { getEnvelopeWhereInput } from '../envelope/get-envelope-by-id';
|
||||
import { incrementDocumentId } from '../envelope/increment-id';
|
||||
import { insertFormValuesInPdf } from '../pdf/insert-form-values-in-pdf';
|
||||
import { getTeamSettings } from '../team/get-team-settings';
|
||||
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
|
||||
|
||||
@@ -117,6 +120,8 @@ export type CreateDocumentFromTemplateOptions = {
|
||||
uploadSignatureEnabled?: boolean;
|
||||
drawSignatureEnabled?: boolean;
|
||||
};
|
||||
|
||||
formValues?: TDocumentFormValues;
|
||||
requestMetadata: ApiRequestMetadata;
|
||||
};
|
||||
|
||||
@@ -303,6 +308,7 @@ export const createDocumentFromTemplate = async ({
|
||||
folderId,
|
||||
prefillFields,
|
||||
attachments,
|
||||
formValues,
|
||||
}: CreateDocumentFromTemplateOptions) => {
|
||||
const { envelopeWhereInput } = await getEnvelopeWhereInput({
|
||||
id,
|
||||
@@ -396,6 +402,30 @@ export const createDocumentFromTemplate = async ({
|
||||
};
|
||||
});
|
||||
|
||||
const defaultRecipients = settings.defaultRecipients
|
||||
? ZDefaultRecipientsSchema.parse(settings.defaultRecipients)
|
||||
: [];
|
||||
|
||||
const defaultRecipientsFinal: FinalRecipient[] = defaultRecipients.map((recipient) => {
|
||||
const authOptions = ZRecipientAuthOptionsSchema.parse({});
|
||||
|
||||
return {
|
||||
templateRecipientId: -1,
|
||||
fields: [],
|
||||
name: recipient.name || recipient.email,
|
||||
email: recipient.email,
|
||||
role: recipient.role,
|
||||
signingOrder: null,
|
||||
authOptions: createRecipientAuthOptions({
|
||||
accessAuth: authOptions.accessAuth,
|
||||
actionAuth: authOptions.actionAuth,
|
||||
}),
|
||||
token: nanoid(),
|
||||
};
|
||||
});
|
||||
|
||||
const allFinalRecipients = [...finalRecipients, ...defaultRecipientsFinal];
|
||||
|
||||
// Key = original envelope item ID
|
||||
// Value = duplicated envelope item ID.
|
||||
const oldEnvelopeItemToNewEnvelopeItemIdMap: Record<string, string> = {};
|
||||
@@ -431,21 +461,31 @@ export const createDocumentFromTemplate = async ({
|
||||
});
|
||||
}
|
||||
|
||||
const buffer = await getFileServerSide(documentDataToDuplicate);
|
||||
let buffer = await getFileServerSide(documentDataToDuplicate);
|
||||
|
||||
const titleToUse = item.title || finalEnvelopeTitle;
|
||||
|
||||
const duplicatedFile = await putPdfFileServerSide({
|
||||
name: titleToUse,
|
||||
type: 'application/pdf',
|
||||
arrayBuffer: async () => Promise.resolve(buffer),
|
||||
if (formValues) {
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
buffer = await insertFormValuesInPdf({
|
||||
pdf: Buffer.from(buffer),
|
||||
formValues,
|
||||
});
|
||||
}
|
||||
|
||||
const duplicatedFile = await putNormalizedPdfFileServerSide({
|
||||
file: {
|
||||
name: titleToUse,
|
||||
type: 'application/pdf',
|
||||
arrayBuffer: async () => Promise.resolve(buffer),
|
||||
},
|
||||
});
|
||||
|
||||
const newDocumentData = await prisma.documentData.create({
|
||||
data: {
|
||||
type: duplicatedFile.type,
|
||||
data: duplicatedFile.data,
|
||||
initialData: duplicatedFile.initialData,
|
||||
initialData: documentDataToDuplicate.data,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -515,7 +555,7 @@ export const createDocumentFromTemplate = async ({
|
||||
documentMetaId: documentMeta.id,
|
||||
recipients: {
|
||||
createMany: {
|
||||
data: finalRecipients.map((recipient) => {
|
||||
data: allFinalRecipients.map((recipient) => {
|
||||
const authOptions = ZRecipientAuthOptionsSchema.parse(recipient?.authOptions);
|
||||
|
||||
return {
|
||||
@@ -596,7 +636,7 @@ export const createDocumentFromTemplate = async ({
|
||||
}
|
||||
}
|
||||
|
||||
Object.values(finalRecipients).forEach(({ token, fields }) => {
|
||||
Object.values(allFinalRecipients).forEach(({ token, fields }) => {
|
||||
const recipient = envelope.recipients.find((recipient) => recipient.token === token);
|
||||
|
||||
if (!recipient) {
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: de\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"PO-Revision-Date: 2026-01-13 02:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -1291,6 +1291,7 @@ msgid "Admin Panel"
|
||||
msgstr "Admin-Panel"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Admins only"
|
||||
msgstr "Nur Admins"
|
||||
|
||||
@@ -2578,6 +2579,7 @@ msgid "Configure the team roles for each member"
|
||||
msgstr "Konfigurieren Sie die Teamrollen für jedes Mitglied"
|
||||
|
||||
#: apps/remix/app/components/dialogs/public-profile-template-manage-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/template-direct-link-dialog.tsx
|
||||
msgid "Confirm"
|
||||
msgstr "Bestätigen"
|
||||
@@ -3734,6 +3736,7 @@ msgctxt "Audit log format"
|
||||
msgid "Document sent"
|
||||
msgstr "Dokument gesendet"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
msgid "Document Settings"
|
||||
msgstr "Dokumenteneinstellungen"
|
||||
@@ -4321,6 +4324,14 @@ msgstr "Beigefügte Dokument"
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Beigefügte Dokumente"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter"
|
||||
msgstr "Eingeben"
|
||||
|
||||
#: 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."
|
||||
@@ -4329,6 +4340,26 @@ msgstr "Geben Sie einen Namen für Ihren neuen Ordner ein. Ordner helfen Ihnen,
|
||||
msgid "Enter claim name"
|
||||
msgstr "Anspruchsname eingeben"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Enter Email"
|
||||
msgstr "E-Mail eingeben"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Enter Initials"
|
||||
msgstr "Initialen eingeben"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Enter Name"
|
||||
msgstr "Namen eingeben"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Enter Number"
|
||||
msgstr "Nummer eingeben"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter Text"
|
||||
msgstr "Text eingeben"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-email-domain-create-dialog.tsx
|
||||
msgid "Enter the domain you want to use for sending emails (without http:// or www)"
|
||||
msgstr "Geben Sie die Domain ein, die Sie zum Versenden von E-Mails verwenden möchten (ohne http:// oder www)"
|
||||
@@ -4523,6 +4554,7 @@ msgid "Event Type"
|
||||
msgstr "Ereignistyp"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
msgid "Everyone"
|
||||
msgstr "Jeder"
|
||||
@@ -5222,14 +5254,6 @@ msgstr "Initialen sind erforderlich"
|
||||
msgid "Initials Settings"
|
||||
msgstr "Einstellungen für Initialen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Insert a value into the number field"
|
||||
msgstr "Fügen Sie einen Wert in das Zahlenfeld ein."
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Insert a value into the text field"
|
||||
msgstr "Fügen Sie einen Wert in das Textfeld ein."
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
msgid "Inserted"
|
||||
msgstr "Eingefügt"
|
||||
@@ -5738,6 +5762,7 @@ msgid "Manager"
|
||||
msgstr "Manager"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Managers and above"
|
||||
msgstr "Manager und höher"
|
||||
|
||||
@@ -6133,6 +6158,10 @@ msgstr "Keine Sorge, das passiert! Geben Sie Ihre E-Mail ein, und wir senden Ihn
|
||||
msgid "None"
|
||||
msgstr "Keine"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "None (Overrides global settings)"
|
||||
msgstr "Keine (überschreibt globale Einstellungen)"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.edit.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/templates.$id._index.tsx
|
||||
@@ -6696,6 +6725,10 @@ msgstr "Bitte kontaktieren Sie den Webseiteninhaber für weitere Unterstützung.
|
||||
msgid "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
msgstr "Bitte geben Sie einen aussagekräftigen Namen für Ihr Token ein. Dies wird Ihnen helfen, es später zu identifizieren."
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Please enter a number"
|
||||
msgstr "Bitte gib eine Zahl ein"
|
||||
|
||||
#: apps/remix/app/components/forms/profile.tsx
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/components/general/claim-account.tsx
|
||||
@@ -6706,6 +6739,22 @@ msgstr "Bitte geben Sie einen gültigen Namen ein."
|
||||
msgid "Please enter a valid number"
|
||||
msgstr "Bitte geben Sie eine gültige Nummer ein."
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Please enter a value"
|
||||
msgstr "Bitte gib einen Wert ein"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Please enter your email address"
|
||||
msgstr "Bitte gib deine E-Mail-Adresse ein"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Please enter your full name"
|
||||
msgstr "Bitte gib deinen vollständigen Namen ein"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Please enter your initials"
|
||||
msgstr "Bitte geben Sie Ihre Initialen ein"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-mobile-widget.tsx
|
||||
msgid "Please mark as viewed to complete"
|
||||
msgstr "Bitte als angesehen markieren, um zu vervollständigen"
|
||||
@@ -7250,6 +7299,22 @@ msgstr "Anfrage"
|
||||
msgid "Requesting Organisation"
|
||||
msgstr "Anfragende Organisation"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require 2FA"
|
||||
msgstr "2FA erforderlich"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require account"
|
||||
msgstr "Konto erforderlich"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require passkey"
|
||||
msgstr "Passkey erforderlich"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require password"
|
||||
msgstr "Passwort erforderlich"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||
@@ -7662,6 +7727,10 @@ msgstr "Wählen Sie Mitglieder aus, die diesem Team hinzugefügt werden sollen"
|
||||
msgid "Select Option"
|
||||
msgstr "Option auswählen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Select Options"
|
||||
msgstr "Optionen auswählen"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-passkey.tsx
|
||||
msgid "Select passkey"
|
||||
msgstr "Passkey auswählen"
|
||||
@@ -7884,13 +7953,7 @@ msgstr "Erweiterte Einstellungen anzeigen"
|
||||
msgid "Show templates in your public profile for your audience to sign and get started quickly"
|
||||
msgstr "Vorlagen in Ihrem öffentlichen Profil anzeigen, damit Ihre Zielgruppe unterschreiben und schnell loslegen kann"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-signature-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-2fa.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-password.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auto-sign.tsx
|
||||
@@ -7924,10 +7987,6 @@ msgstr "Unterzeichnen als {0} <0>({1})</0>"
|
||||
msgid "Sign as<0>{0} <1>({1})</1></0>"
|
||||
msgstr "Unterzeichnen als<0>{0} <1>({1})</1></0>"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Sign Checkbox Field"
|
||||
msgstr "Sign Checkbox-Feld"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -7944,10 +8003,6 @@ msgstr "Dokument signieren"
|
||||
msgid "Sign Documents"
|
||||
msgstr "Dokumente unterschreiben"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign Email"
|
||||
msgstr "Signatur-E-Mail"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
msgid "Sign field"
|
||||
@@ -7970,18 +8025,6 @@ msgstr "Anmelden"
|
||||
msgid "Sign in to your account"
|
||||
msgstr "Melden Sie sich bei Ihrem Konto an"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign Initials"
|
||||
msgstr "Initialen signieren"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign Name"
|
||||
msgstr "Name signieren"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Sign Number Field"
|
||||
msgstr "Zahlenfeld signieren"
|
||||
|
||||
#: apps/remix/app/components/general/app-nav-mobile.tsx
|
||||
#: apps/remix/app/components/general/menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
@@ -7992,10 +8035,6 @@ msgstr "Ausloggen"
|
||||
msgid "Sign Signature Field"
|
||||
msgstr "Signaturfeld signieren"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Sign Text Field"
|
||||
msgstr "Textfeld signieren"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -8018,18 +8057,6 @@ msgstr "Registrieren mit Microsoft"
|
||||
msgid "Sign Up with OIDC"
|
||||
msgstr "Registrieren mit OIDC"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign your email into the field"
|
||||
msgstr "E-Mail ins Feld signieren"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign your full name into the field"
|
||||
msgstr "Vollständigen Namen ins Feld signieren"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign your initials into the field"
|
||||
msgstr "Initialen ins Feld signieren"
|
||||
|
||||
#: apps/remix/app/components/dialogs/ai-field-detection-dialog.tsx
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
|
||||
@@ -1286,6 +1286,7 @@ msgid "Admin Panel"
|
||||
msgstr "Admin Panel"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Admins only"
|
||||
msgstr "Admins only"
|
||||
|
||||
@@ -2573,6 +2574,7 @@ msgid "Configure the team roles for each member"
|
||||
msgstr "Configure the team roles for each member"
|
||||
|
||||
#: apps/remix/app/components/dialogs/public-profile-template-manage-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/template-direct-link-dialog.tsx
|
||||
msgid "Confirm"
|
||||
msgstr "Confirm"
|
||||
@@ -3729,6 +3731,7 @@ msgctxt "Audit log format"
|
||||
msgid "Document sent"
|
||||
msgstr "Document sent"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
msgid "Document Settings"
|
||||
msgstr "Document Settings"
|
||||
@@ -4316,6 +4319,14 @@ msgstr "Enclosed Document"
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Enclosed Documents"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter"
|
||||
msgstr "Enter"
|
||||
|
||||
#: 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."
|
||||
@@ -4324,6 +4335,26 @@ msgstr "Enter a name for your new folder. Folders help you organise your items."
|
||||
msgid "Enter claim name"
|
||||
msgstr "Enter claim name"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Enter Email"
|
||||
msgstr "Enter Email"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Enter Initials"
|
||||
msgstr "Enter Initials"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Enter Name"
|
||||
msgstr "Enter Name"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Enter Number"
|
||||
msgstr "Enter Number"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter Text"
|
||||
msgstr "Enter Text"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-email-domain-create-dialog.tsx
|
||||
msgid "Enter the domain you want to use for sending emails (without http:// or www)"
|
||||
msgstr "Enter the domain you want to use for sending emails (without http:// or www)"
|
||||
@@ -4518,6 +4549,7 @@ msgid "Event Type"
|
||||
msgstr "Event Type"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
msgid "Everyone"
|
||||
msgstr "Everyone"
|
||||
@@ -5217,14 +5249,6 @@ msgstr "Initials are required"
|
||||
msgid "Initials Settings"
|
||||
msgstr "Initials Settings"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Insert a value into the number field"
|
||||
msgstr "Insert a value into the number field"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Insert a value into the text field"
|
||||
msgstr "Insert a value into the text field"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
msgid "Inserted"
|
||||
msgstr "Inserted"
|
||||
@@ -5733,6 +5757,7 @@ msgid "Manager"
|
||||
msgstr "Manager"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Managers and above"
|
||||
msgstr "Managers and above"
|
||||
|
||||
@@ -6128,6 +6153,10 @@ msgstr "No worries, it happens! Enter your email and we'll email you a special l
|
||||
msgid "None"
|
||||
msgstr "None"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "None (Overrides global settings)"
|
||||
msgstr "None (Overrides global settings)"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.edit.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/templates.$id._index.tsx
|
||||
@@ -6691,6 +6720,10 @@ msgstr "Please contact the site owner for further assistance."
|
||||
msgid "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
msgstr "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Please enter a number"
|
||||
msgstr "Please enter a number"
|
||||
|
||||
#: apps/remix/app/components/forms/profile.tsx
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/components/general/claim-account.tsx
|
||||
@@ -6701,6 +6734,22 @@ msgstr "Please enter a valid name."
|
||||
msgid "Please enter a valid number"
|
||||
msgstr "Please enter a valid number"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Please enter a value"
|
||||
msgstr "Please enter a value"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Please enter your email address"
|
||||
msgstr "Please enter your email address"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Please enter your full name"
|
||||
msgstr "Please enter your full name"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Please enter your initials"
|
||||
msgstr "Please enter your initials"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-mobile-widget.tsx
|
||||
msgid "Please mark as viewed to complete"
|
||||
msgstr "Please mark as viewed to complete"
|
||||
@@ -7245,6 +7294,22 @@ msgstr "Request"
|
||||
msgid "Requesting Organisation"
|
||||
msgstr "Requesting Organisation"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require 2FA"
|
||||
msgstr "Require 2FA"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require account"
|
||||
msgstr "Require account"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require passkey"
|
||||
msgstr "Require passkey"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require password"
|
||||
msgstr "Require password"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||
@@ -7657,6 +7722,10 @@ msgstr "Select members to add to this team"
|
||||
msgid "Select Option"
|
||||
msgstr "Select Option"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Select Options"
|
||||
msgstr "Select Options"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-passkey.tsx
|
||||
msgid "Select passkey"
|
||||
msgstr "Select passkey"
|
||||
@@ -7879,13 +7948,7 @@ msgstr "Show advanced settings"
|
||||
msgid "Show templates in your public profile for your audience to sign and get started quickly"
|
||||
msgstr "Show templates in your public profile for your audience to sign and get started quickly"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-signature-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-2fa.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-password.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auto-sign.tsx
|
||||
@@ -7919,10 +7982,6 @@ msgstr "Sign as {0} <0>({1})</0>"
|
||||
msgid "Sign as<0>{0} <1>({1})</1></0>"
|
||||
msgstr "Sign as<0>{0} <1>({1})</1></0>"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Sign Checkbox Field"
|
||||
msgstr "Sign Checkbox Field"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -7939,10 +7998,6 @@ msgstr "Sign Document"
|
||||
msgid "Sign Documents"
|
||||
msgstr "Sign Documents"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign Email"
|
||||
msgstr "Sign Email"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
msgid "Sign field"
|
||||
@@ -7965,18 +8020,6 @@ msgstr "Sign In"
|
||||
msgid "Sign in to your account"
|
||||
msgstr "Sign in to your account"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign Initials"
|
||||
msgstr "Sign Initials"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign Name"
|
||||
msgstr "Sign Name"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Sign Number Field"
|
||||
msgstr "Sign Number Field"
|
||||
|
||||
#: apps/remix/app/components/general/app-nav-mobile.tsx
|
||||
#: apps/remix/app/components/general/menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
@@ -7987,10 +8030,6 @@ msgstr "Sign Out"
|
||||
msgid "Sign Signature Field"
|
||||
msgstr "Sign Signature Field"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Sign Text Field"
|
||||
msgstr "Sign Text Field"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -8013,18 +8052,6 @@ msgstr "Sign Up with Microsoft"
|
||||
msgid "Sign Up with OIDC"
|
||||
msgstr "Sign Up with OIDC"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign your email into the field"
|
||||
msgstr "Sign your email into the field"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign your full name into the field"
|
||||
msgstr "Sign your full name into the field"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign your initials into the field"
|
||||
msgstr "Sign your initials into the field"
|
||||
|
||||
#: apps/remix/app/components/dialogs/ai-field-detection-dialog.tsx
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: es\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"PO-Revision-Date: 2026-01-13 02:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Spanish\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -1291,6 +1291,7 @@ msgid "Admin Panel"
|
||||
msgstr "Panel de Administración"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Admins only"
|
||||
msgstr "Solo para administradores"
|
||||
|
||||
@@ -2578,6 +2579,7 @@ msgid "Configure the team roles for each member"
|
||||
msgstr "Configura los roles del equipo para cada miembro"
|
||||
|
||||
#: apps/remix/app/components/dialogs/public-profile-template-manage-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/template-direct-link-dialog.tsx
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmar"
|
||||
@@ -3734,6 +3736,7 @@ msgctxt "Audit log format"
|
||||
msgid "Document sent"
|
||||
msgstr "Documento enviado"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
msgid "Document Settings"
|
||||
msgstr "Configuración del Documento"
|
||||
@@ -4321,6 +4324,14 @@ msgstr "Documento Adjunto"
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Documentos adjuntos"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter"
|
||||
msgstr "Ingresar"
|
||||
|
||||
#: 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."
|
||||
@@ -4329,6 +4340,26 @@ msgstr "Ingrese un nombre para su nueva carpeta. Las carpetas le ayudan a organi
|
||||
msgid "Enter claim name"
|
||||
msgstr "Ingresar nombre de la reclamación"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Enter Email"
|
||||
msgstr "Ingresar correo electrónico"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Enter Initials"
|
||||
msgstr "Ingresar iniciales"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Enter Name"
|
||||
msgstr "Ingresar nombre"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Enter Number"
|
||||
msgstr "Ingresar número"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter Text"
|
||||
msgstr "Ingresar texto"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-email-domain-create-dialog.tsx
|
||||
msgid "Enter the domain you want to use for sending emails (without http:// or www)"
|
||||
msgstr "Ingresa el dominio que deseas usar para enviar correos electrónicos (sin http:// ni www)"
|
||||
@@ -4523,6 +4554,7 @@ msgid "Event Type"
|
||||
msgstr "Tipo de evento"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
msgid "Everyone"
|
||||
msgstr "Todos"
|
||||
@@ -5222,14 +5254,6 @@ msgstr "Se requieren iniciales"
|
||||
msgid "Initials Settings"
|
||||
msgstr "Configuración de Iniciales"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Insert a value into the number field"
|
||||
msgstr "Introduce un valor en el campo de número"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Insert a value into the text field"
|
||||
msgstr "Introduce un valor en el campo de texto"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
msgid "Inserted"
|
||||
msgstr "Insertado"
|
||||
@@ -5738,6 +5762,7 @@ msgid "Manager"
|
||||
msgstr "Gerente"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Managers and above"
|
||||
msgstr "Gerentes y superiores"
|
||||
|
||||
@@ -6133,6 +6158,10 @@ msgstr "¡No te preocupes, sucede! Ingresa tu correo electrónico y te enviaremo
|
||||
msgid "None"
|
||||
msgstr "Ninguno"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "None (Overrides global settings)"
|
||||
msgstr "Ninguno (anula la configuración global)"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.edit.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/templates.$id._index.tsx
|
||||
@@ -6696,6 +6725,10 @@ msgstr "Por favor, contacte al propietario del sitio para más asistencia."
|
||||
msgid "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
msgstr "Por favor, ingresa un nombre significativo para tu token. Esto te ayudará a identificarlo más tarde."
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Please enter a number"
|
||||
msgstr "Por favor ingresa un número"
|
||||
|
||||
#: apps/remix/app/components/forms/profile.tsx
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/components/general/claim-account.tsx
|
||||
@@ -6706,6 +6739,22 @@ msgstr "Por favor, introduce un nombre válido."
|
||||
msgid "Please enter a valid number"
|
||||
msgstr "Por favor, ingresa un número válido"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Please enter a value"
|
||||
msgstr "Por favor ingresa un valor"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Please enter your email address"
|
||||
msgstr "Por favor ingresa tu dirección de correo electrónico"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Please enter your full name"
|
||||
msgstr "Por favor ingresa tu nombre completo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Please enter your initials"
|
||||
msgstr "Por favor, introduzca sus iniciales"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-mobile-widget.tsx
|
||||
msgid "Please mark as viewed to complete"
|
||||
msgstr "Por favor marque como visto para completar"
|
||||
@@ -7250,6 +7299,22 @@ msgstr "Solicitud"
|
||||
msgid "Requesting Organisation"
|
||||
msgstr "Organización solicitante"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require 2FA"
|
||||
msgstr "Requerir 2FA"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require account"
|
||||
msgstr "Requerir cuenta"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require passkey"
|
||||
msgstr "Requerir llave de acceso"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require password"
|
||||
msgstr "Requerir contraseña"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||
@@ -7662,6 +7727,10 @@ msgstr "Seleccione los miembros para añadir a este equipo"
|
||||
msgid "Select Option"
|
||||
msgstr "Seleccionar una opción"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Select Options"
|
||||
msgstr "Seleccionar opciones"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-passkey.tsx
|
||||
msgid "Select passkey"
|
||||
msgstr "Seleccionar clave de acceso"
|
||||
@@ -7884,13 +7953,7 @@ msgstr "Mostrar configuraciones avanzadas"
|
||||
msgid "Show templates in your public profile for your audience to sign and get started quickly"
|
||||
msgstr "Mostrar plantillas en tu perfil público para que tu audiencia firme y comience rápidamente"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-signature-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-2fa.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-password.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auto-sign.tsx
|
||||
@@ -7924,10 +7987,6 @@ msgstr "Firmar como {0} <0>({1})</0>"
|
||||
msgid "Sign as<0>{0} <1>({1})</1></0>"
|
||||
msgstr "Firmar como<0>{0} <1>({1})</1></0>"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Sign Checkbox Field"
|
||||
msgstr "Campo de casilla de verificación de firma"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -7944,10 +8003,6 @@ msgstr "Firmar Documento"
|
||||
msgid "Sign Documents"
|
||||
msgstr "Firmar documentos"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign Email"
|
||||
msgstr "Correo de firma"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
msgid "Sign field"
|
||||
@@ -7970,18 +8025,6 @@ msgstr "Iniciar sesión"
|
||||
msgid "Sign in to your account"
|
||||
msgstr "Inicia sesión en tu cuenta"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign Initials"
|
||||
msgstr "Iniciales de firma"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign Name"
|
||||
msgstr "Nombre de firma"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Sign Number Field"
|
||||
msgstr "Campo de número de firma"
|
||||
|
||||
#: apps/remix/app/components/general/app-nav-mobile.tsx
|
||||
#: apps/remix/app/components/general/menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
@@ -7992,10 +8035,6 @@ msgstr "Cerrar sesión"
|
||||
msgid "Sign Signature Field"
|
||||
msgstr "Campo de firma Firma"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Sign Text Field"
|
||||
msgstr "Campo de texto de firma"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -8018,18 +8057,6 @@ msgstr "Registrarse con Microsoft"
|
||||
msgid "Sign Up with OIDC"
|
||||
msgstr "Regístrate con OIDC"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign your email into the field"
|
||||
msgstr "Firme su correo electrónico en el campo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign your full name into the field"
|
||||
msgstr "Firme su nombre completo en el campo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign your initials into the field"
|
||||
msgstr "Firme sus iniciales en el campo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/ai-field-detection-dialog.tsx
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: fr\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"PO-Revision-Date: 2026-01-13 02:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: French\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
@@ -1291,6 +1291,7 @@ msgid "Admin Panel"
|
||||
msgstr "Panneau d'administration"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Admins only"
|
||||
msgstr "Administrateurs uniquement"
|
||||
|
||||
@@ -2578,6 +2579,7 @@ msgid "Configure the team roles for each member"
|
||||
msgstr "Configurez les rôles d'équipe pour chaque membre"
|
||||
|
||||
#: apps/remix/app/components/dialogs/public-profile-template-manage-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/template-direct-link-dialog.tsx
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmer"
|
||||
@@ -3734,6 +3736,7 @@ msgctxt "Audit log format"
|
||||
msgid "Document sent"
|
||||
msgstr "Document envoyé"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
msgid "Document Settings"
|
||||
msgstr "Paramètres du document"
|
||||
@@ -4321,6 +4324,14 @@ msgstr "Document joint"
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Documents joints"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter"
|
||||
msgstr "Entrer"
|
||||
|
||||
#: 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."
|
||||
@@ -4329,6 +4340,26 @@ msgstr "Entrez un nom pour votre nouveau dossier. Les dossiers vous aident à or
|
||||
msgid "Enter claim name"
|
||||
msgstr "Entrez le nom de la réclamation"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Enter Email"
|
||||
msgstr "Entrer l’adresse e-mail"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Enter Initials"
|
||||
msgstr "Entrer les initiales"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Enter Name"
|
||||
msgstr "Entrer le nom"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Enter Number"
|
||||
msgstr "Entrer le numéro"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter Text"
|
||||
msgstr "Entrer le texte"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-email-domain-create-dialog.tsx
|
||||
msgid "Enter the domain you want to use for sending emails (without http:// or www)"
|
||||
msgstr "Entrez le domaine que vous souhaitez utiliser pour l'envoi des e-mails (sans http:// ou www)"
|
||||
@@ -4523,6 +4554,7 @@ msgid "Event Type"
|
||||
msgstr "Type d'événement"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
msgid "Everyone"
|
||||
msgstr "Tout le monde"
|
||||
@@ -5222,14 +5254,6 @@ msgstr "Les initiales sont requises"
|
||||
msgid "Initials Settings"
|
||||
msgstr "Paramètres des initiales"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Insert a value into the number field"
|
||||
msgstr "Insérez une valeur dans le champ de nombre"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Insert a value into the text field"
|
||||
msgstr "Insérez une valeur dans le champ de texte"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
msgid "Inserted"
|
||||
msgstr "Inséré"
|
||||
@@ -5738,6 +5762,7 @@ msgid "Manager"
|
||||
msgstr "Gestionnaire"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Managers and above"
|
||||
msgstr "Responsables et supérieur"
|
||||
|
||||
@@ -6133,6 +6158,10 @@ msgstr "Pas de soucis, ça arrive ! Entrez votre email et nous vous enverrons un
|
||||
msgid "None"
|
||||
msgstr "Aucun"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "None (Overrides global settings)"
|
||||
msgstr "Aucun (remplace les paramètres globaux)"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.edit.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/templates.$id._index.tsx
|
||||
@@ -6696,6 +6725,10 @@ msgstr "Veuillez contacter le propriétaire du site pour obtenir de l'aide suppl
|
||||
msgid "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
msgstr "Veuillez entrer un nom significatif pour votre token. Cela vous aidera à l'identifier plus tard."
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Please enter a number"
|
||||
msgstr "Veuillez entrer un nombre"
|
||||
|
||||
#: apps/remix/app/components/forms/profile.tsx
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/components/general/claim-account.tsx
|
||||
@@ -6706,6 +6739,22 @@ msgstr "Veuiillez entrer un nom valide."
|
||||
msgid "Please enter a valid number"
|
||||
msgstr "Veuillez entrer un numéro valide"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Please enter a value"
|
||||
msgstr "Veuillez entrer une valeur"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Please enter your email address"
|
||||
msgstr "Veuillez entrer votre adresse e-mail"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Please enter your full name"
|
||||
msgstr "Veuillez entrer votre nom complet"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Please enter your initials"
|
||||
msgstr "Veuillez saisir vos initiales"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-mobile-widget.tsx
|
||||
msgid "Please mark as viewed to complete"
|
||||
msgstr "Veuillez marquer comme vu pour compléter"
|
||||
@@ -7250,6 +7299,22 @@ msgstr "Requête"
|
||||
msgid "Requesting Organisation"
|
||||
msgstr "Organisation Demandeuse"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require 2FA"
|
||||
msgstr "Exiger une 2FA"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require account"
|
||||
msgstr "Exiger un compte"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require passkey"
|
||||
msgstr "Exiger une clé d’accès"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require password"
|
||||
msgstr "Exiger un mot de passe"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||
@@ -7662,6 +7727,10 @@ msgstr "Sélectionnez des membres à ajouter à cette équipe"
|
||||
msgid "Select Option"
|
||||
msgstr "Sélectionner une option"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Select Options"
|
||||
msgstr "Sélectionner des options"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-passkey.tsx
|
||||
msgid "Select passkey"
|
||||
msgstr "Sélectionner la clé d'authentification"
|
||||
@@ -7884,13 +7953,7 @@ msgstr "Afficher les paramètres avancés"
|
||||
msgid "Show templates in your public profile for your audience to sign and get started quickly"
|
||||
msgstr "Afficher des modèles dans votre profil public pour que votre audience puisse signer et commencer rapidement"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-signature-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-2fa.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-password.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auto-sign.tsx
|
||||
@@ -7924,10 +7987,6 @@ msgstr "Signer comme {0} <0>({1})</0>"
|
||||
msgid "Sign as<0>{0} <1>({1})</1></0>"
|
||||
msgstr "Signer comme<0>{0} <1>({1})</1></0>"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Sign Checkbox Field"
|
||||
msgstr "Champ de case à cocher signe"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -7944,10 +8003,6 @@ msgstr "Signer le document"
|
||||
msgid "Sign Documents"
|
||||
msgstr "Signer des documents"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign Email"
|
||||
msgstr "Email de Signature"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
msgid "Sign field"
|
||||
@@ -7970,18 +8025,6 @@ msgstr "Se connecter"
|
||||
msgid "Sign in to your account"
|
||||
msgstr "Connectez-vous à votre compte"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign Initials"
|
||||
msgstr "Initiales de Signature"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign Name"
|
||||
msgstr "Nom de Signature"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Sign Number Field"
|
||||
msgstr "Champ de nombre à signer"
|
||||
|
||||
#: apps/remix/app/components/general/app-nav-mobile.tsx
|
||||
#: apps/remix/app/components/general/menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
@@ -7992,10 +8035,6 @@ msgstr "Déconnexion"
|
||||
msgid "Sign Signature Field"
|
||||
msgstr "Champ de signature"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Sign Text Field"
|
||||
msgstr "Champ de texte à signer"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -8018,18 +8057,6 @@ msgstr "S'inscrire avec Microsoft"
|
||||
msgid "Sign Up with OIDC"
|
||||
msgstr "S'inscrire avec OIDC"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign your email into the field"
|
||||
msgstr "Signez votre email dans le champ"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign your full name into the field"
|
||||
msgstr "Signez votre nom complet dans le champ"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign your initials into the field"
|
||||
msgstr "Signez vos initiales dans le champ"
|
||||
|
||||
#: apps/remix/app/components/dialogs/ai-field-detection-dialog.tsx
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: it\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"PO-Revision-Date: 2026-01-13 02:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Italian\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -1291,6 +1291,7 @@ msgid "Admin Panel"
|
||||
msgstr "Pannello di Amministrazione"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Admins only"
|
||||
msgstr "Solo amministratori"
|
||||
|
||||
@@ -2578,6 +2579,7 @@ msgid "Configure the team roles for each member"
|
||||
msgstr "Configura i ruoli del team per ogni membro"
|
||||
|
||||
#: apps/remix/app/components/dialogs/public-profile-template-manage-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/template-direct-link-dialog.tsx
|
||||
msgid "Confirm"
|
||||
msgstr "Conferma"
|
||||
@@ -3734,6 +3736,7 @@ msgctxt "Audit log format"
|
||||
msgid "Document sent"
|
||||
msgstr "Documento inviato"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
msgid "Document Settings"
|
||||
msgstr "Impostazioni Documento"
|
||||
@@ -4321,6 +4324,14 @@ msgstr "Documento Allegato"
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Documenti allegati"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter"
|
||||
msgstr "Inserisci"
|
||||
|
||||
#: 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."
|
||||
@@ -4329,6 +4340,26 @@ msgstr "Inserisci un nome per la tua nuova cartella. Le cartelle ti aiutano a or
|
||||
msgid "Enter claim name"
|
||||
msgstr "Inserisci nome richiesta"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Enter Email"
|
||||
msgstr "Inserisci l'email"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Enter Initials"
|
||||
msgstr "Inserisci le iniziali"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Enter Name"
|
||||
msgstr "Inserisci il nome"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Enter Number"
|
||||
msgstr "Inserisci il numero"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter Text"
|
||||
msgstr "Inserisci il testo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-email-domain-create-dialog.tsx
|
||||
msgid "Enter the domain you want to use for sending emails (without http:// or www)"
|
||||
msgstr "Inserisci il dominio che desideri utilizzare per inviare email (senza http:// o www)"
|
||||
@@ -4523,6 +4554,7 @@ msgid "Event Type"
|
||||
msgstr "Tipo di Evento"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
msgid "Everyone"
|
||||
msgstr "Tutti"
|
||||
@@ -5222,14 +5254,6 @@ msgstr "Iniziali richieste"
|
||||
msgid "Initials Settings"
|
||||
msgstr "Impostazioni Iniziali"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Insert a value into the number field"
|
||||
msgstr "Inserisci un valore nel campo numero"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Insert a value into the text field"
|
||||
msgstr "Inserisci un valore nel campo di testo"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
msgid "Inserted"
|
||||
msgstr "Inserito"
|
||||
@@ -5738,6 +5762,7 @@ msgid "Manager"
|
||||
msgstr "Responsabile"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Managers and above"
|
||||
msgstr "Manager e superiori"
|
||||
|
||||
@@ -6133,6 +6158,10 @@ msgstr "Non ti preoccupare, succede! Inserisci la tua email e ti invieremo un li
|
||||
msgid "None"
|
||||
msgstr "Nessuno"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "None (Overrides global settings)"
|
||||
msgstr "Nessuno (sovrascrive le impostazioni globali)"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.edit.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/templates.$id._index.tsx
|
||||
@@ -6696,6 +6725,10 @@ msgstr "Si prega di contattare il proprietario del sito per ulteriori assistenza
|
||||
msgid "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
msgstr "Si prega di inserire un nome significativo per il proprio token. Questo ti aiuterà a identificarlo più tardi."
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Please enter a number"
|
||||
msgstr "Inserisci un numero"
|
||||
|
||||
#: apps/remix/app/components/forms/profile.tsx
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/components/general/claim-account.tsx
|
||||
@@ -6706,6 +6739,22 @@ msgstr "Per favore inserisci un nome valido."
|
||||
msgid "Please enter a valid number"
|
||||
msgstr "Per favore inserisci un numero valido"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Please enter a value"
|
||||
msgstr "Inserisci un valore"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Please enter your email address"
|
||||
msgstr "Inserisci il tuo indirizzo email"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Please enter your full name"
|
||||
msgstr "Inserisci il tuo nome completo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Please enter your initials"
|
||||
msgstr "Inserisci le tue iniziali"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-mobile-widget.tsx
|
||||
msgid "Please mark as viewed to complete"
|
||||
msgstr "Per favore segna come visto per completare"
|
||||
@@ -7250,6 +7299,22 @@ msgstr "Richiesta"
|
||||
msgid "Requesting Organisation"
|
||||
msgstr "Organizzazione richiedente"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require 2FA"
|
||||
msgstr "Richiedi 2FA"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require account"
|
||||
msgstr "Richiedi account"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require passkey"
|
||||
msgstr "Richiedi passkey"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require password"
|
||||
msgstr "Richiedi password"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||
@@ -7662,6 +7727,10 @@ msgstr "Seleziona membri da aggiungere a questo team"
|
||||
msgid "Select Option"
|
||||
msgstr "Seleziona opzione"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Select Options"
|
||||
msgstr "Seleziona opzioni"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-passkey.tsx
|
||||
msgid "Select passkey"
|
||||
msgstr "Seleziona una chiave di accesso"
|
||||
@@ -7884,13 +7953,7 @@ msgstr "Mostra impostazioni avanzate"
|
||||
msgid "Show templates in your public profile for your audience to sign and get started quickly"
|
||||
msgstr "Mostra modelli nel tuo profilo pubblico per il tuo pubblico da firmare e iniziare rapidamente"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-signature-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-2fa.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-password.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auto-sign.tsx
|
||||
@@ -7924,10 +7987,6 @@ msgstr "Firma come {0} <0>({1})</0>"
|
||||
msgid "Sign as<0>{0} <1>({1})</1></0>"
|
||||
msgstr "Firma come<0>{0} <1>({1})</1></0>"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Sign Checkbox Field"
|
||||
msgstr "Campo casella di controllo firma"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -7944,10 +8003,6 @@ msgstr "Firma documento"
|
||||
msgid "Sign Documents"
|
||||
msgstr "Firma documenti"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign Email"
|
||||
msgstr "Firma email"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
msgid "Sign field"
|
||||
@@ -7970,18 +8025,6 @@ msgstr "Accedi"
|
||||
msgid "Sign in to your account"
|
||||
msgstr "Accedi al tuo account"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign Initials"
|
||||
msgstr "Firma iniziali"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign Name"
|
||||
msgstr "Firma nome"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Sign Number Field"
|
||||
msgstr "Campo numero firma"
|
||||
|
||||
#: apps/remix/app/components/general/app-nav-mobile.tsx
|
||||
#: apps/remix/app/components/general/menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
@@ -7992,10 +8035,6 @@ msgstr "Disconnetti"
|
||||
msgid "Sign Signature Field"
|
||||
msgstr "Campo firma firma"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Sign Text Field"
|
||||
msgstr "Campo testo firma"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -8018,18 +8057,6 @@ msgstr "Registrati con Microsoft"
|
||||
msgid "Sign Up with OIDC"
|
||||
msgstr "Iscriviti con OIDC"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign your email into the field"
|
||||
msgstr "Firma la tua email nel campo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign your full name into the field"
|
||||
msgstr "Firma il tuo nome completo nel campo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign your initials into the field"
|
||||
msgstr "Firma le tue iniziali nel campo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/ai-field-detection-dialog.tsx
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: ja\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"PO-Revision-Date: 2026-01-13 02:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Japanese\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
@@ -1291,6 +1291,7 @@ msgid "Admin Panel"
|
||||
msgstr "管理画面"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Admins only"
|
||||
msgstr "管理者のみ"
|
||||
|
||||
@@ -2578,6 +2579,7 @@ msgid "Configure the team roles for each member"
|
||||
msgstr "メンバーごとにチームロールを設定します"
|
||||
|
||||
#: apps/remix/app/components/dialogs/public-profile-template-manage-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/template-direct-link-dialog.tsx
|
||||
msgid "Confirm"
|
||||
msgstr "確認"
|
||||
@@ -3734,6 +3736,7 @@ msgctxt "Audit log format"
|
||||
msgid "Document sent"
|
||||
msgstr "ドキュメントが送信されました"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
msgid "Document Settings"
|
||||
msgstr "ドキュメント設定"
|
||||
@@ -4321,6 +4324,14 @@ msgstr "同封文書"
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "同封された文書"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter"
|
||||
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 "新しいフォルダ名を入力してください。フォルダを使うとアイテムを整理できます。"
|
||||
@@ -4329,6 +4340,26 @@ msgstr "新しいフォルダ名を入力してください。フォルダを使
|
||||
msgid "Enter claim name"
|
||||
msgstr "クレーム名を入力"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Enter Email"
|
||||
msgstr "メールアドレスを入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Enter Initials"
|
||||
msgstr "イニシャルを入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Enter Name"
|
||||
msgstr "氏名を入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Enter Number"
|
||||
msgstr "番号を入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter Text"
|
||||
msgstr "テキストを入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-email-domain-create-dialog.tsx
|
||||
msgid "Enter the domain you want to use for sending emails (without http:// or www)"
|
||||
msgstr "メール送信に使用したいドメインを入力してください(http:// や www は不要)"
|
||||
@@ -4523,6 +4554,7 @@ msgid "Event Type"
|
||||
msgstr "イベントタイプ"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
msgid "Everyone"
|
||||
msgstr "全員"
|
||||
@@ -5222,14 +5254,6 @@ msgstr "イニシャルは必須です"
|
||||
msgid "Initials Settings"
|
||||
msgstr "イニシャルの設定"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Insert a value into the number field"
|
||||
msgstr "数値フィールドに値を入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Insert a value into the text field"
|
||||
msgstr "テキストフィールドに値を入力してください"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
msgid "Inserted"
|
||||
msgstr "挿入済み"
|
||||
@@ -5738,6 +5762,7 @@ msgid "Manager"
|
||||
msgstr "マネージャー"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Managers and above"
|
||||
msgstr "マネージャー以上"
|
||||
|
||||
@@ -6133,6 +6158,10 @@ msgstr "大丈夫です。メールアドレスを入力していただければ
|
||||
msgid "None"
|
||||
msgstr "なし"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "None (Overrides global settings)"
|
||||
msgstr "なし(グローバル設定を上書き)"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.edit.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/templates.$id._index.tsx
|
||||
@@ -6696,6 +6725,10 @@ msgstr "詳しくはサイトのオーナーにお問い合わせください。
|
||||
msgid "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
msgstr "トークンの用途が分かる名前を入力してください。後から識別しやすくなります。"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Please enter a number"
|
||||
msgstr "数値を入力してください"
|
||||
|
||||
#: apps/remix/app/components/forms/profile.tsx
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/components/general/claim-account.tsx
|
||||
@@ -6706,6 +6739,22 @@ msgstr "有効な名前を入力してください。"
|
||||
msgid "Please enter a valid number"
|
||||
msgstr "有効な数値を入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Please enter a value"
|
||||
msgstr "値を入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Please enter your email address"
|
||||
msgstr "メールアドレスを入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Please enter your full name"
|
||||
msgstr "氏名を入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Please enter your initials"
|
||||
msgstr "イニシャルを入力してください"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-mobile-widget.tsx
|
||||
msgid "Please mark as viewed to complete"
|
||||
msgstr "完了するには閲覧済みにしてください"
|
||||
@@ -7250,6 +7299,22 @@ msgstr "リクエスト"
|
||||
msgid "Requesting Organisation"
|
||||
msgstr "要求元の組織"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require 2FA"
|
||||
msgstr "2 要素認証を必須にする"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require account"
|
||||
msgstr "アカウントを必須にする"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require passkey"
|
||||
msgstr "パスキーを必須にする"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require password"
|
||||
msgstr "パスワードを必須にする"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||
@@ -7662,6 +7727,10 @@ msgstr "このチームに追加するメンバーを選択"
|
||||
msgid "Select Option"
|
||||
msgstr "オプションを選択"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Select Options"
|
||||
msgstr "オプションを選択"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-passkey.tsx
|
||||
msgid "Select passkey"
|
||||
msgstr "パスキーを選択"
|
||||
@@ -7884,13 +7953,7 @@ msgstr "詳細設定を表示"
|
||||
msgid "Show templates in your public profile for your audience to sign and get started quickly"
|
||||
msgstr "オーディエンスがすぐに署名を開始できるよう、公開プロフィールにテンプレートを表示します"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-signature-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-2fa.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-password.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auto-sign.tsx
|
||||
@@ -7924,10 +7987,6 @@ msgstr "{0} として署名 <0>({1})</0>"
|
||||
msgid "Sign as<0>{0} <1>({1})</1></0>"
|
||||
msgstr "<0>{0} <1>({1})</1></0>として署名"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Sign Checkbox Field"
|
||||
msgstr "署名用チェックボックスフィールド"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -7944,10 +8003,6 @@ msgstr "文書に署名"
|
||||
msgid "Sign Documents"
|
||||
msgstr "ドキュメントに署名"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign Email"
|
||||
msgstr "署名用メールアドレス"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
msgid "Sign field"
|
||||
@@ -7970,18 +8025,6 @@ msgstr "サインイン"
|
||||
msgid "Sign in to your account"
|
||||
msgstr "アカウントにサインイン"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign Initials"
|
||||
msgstr "署名用イニシャル"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign Name"
|
||||
msgstr "署名用氏名"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Sign Number Field"
|
||||
msgstr "署名用数値フィールド"
|
||||
|
||||
#: apps/remix/app/components/general/app-nav-mobile.tsx
|
||||
#: apps/remix/app/components/general/menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
@@ -7992,10 +8035,6 @@ msgstr "サインアウト"
|
||||
msgid "Sign Signature Field"
|
||||
msgstr "署名用署名フィールド"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Sign Text Field"
|
||||
msgstr "署名用テキストフィールド"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -8018,18 +8057,6 @@ msgstr "Microsoftでサインアップ"
|
||||
msgid "Sign Up with OIDC"
|
||||
msgstr "OIDC でサインアップ"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign your email into the field"
|
||||
msgstr "メールアドレスをフィールドに入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign your full name into the field"
|
||||
msgstr "氏名をフィールドに入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign your initials into the field"
|
||||
msgstr "イニシャルをフィールドに入力してください"
|
||||
|
||||
#: apps/remix/app/components/dialogs/ai-field-detection-dialog.tsx
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: ko\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"PO-Revision-Date: 2026-01-13 02:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Korean\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
@@ -1291,6 +1291,7 @@ msgid "Admin Panel"
|
||||
msgstr "관리자 패널"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Admins only"
|
||||
msgstr "관리자 전용"
|
||||
|
||||
@@ -2578,6 +2579,7 @@ msgid "Configure the team roles for each member"
|
||||
msgstr "각 구성원에 대한 팀 역할을 구성하세요."
|
||||
|
||||
#: apps/remix/app/components/dialogs/public-profile-template-manage-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/template-direct-link-dialog.tsx
|
||||
msgid "Confirm"
|
||||
msgstr "확인"
|
||||
@@ -3734,6 +3736,7 @@ msgctxt "Audit log format"
|
||||
msgid "Document sent"
|
||||
msgstr "문서가 전송되었습니다."
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
msgid "Document Settings"
|
||||
msgstr "문서 설정"
|
||||
@@ -4321,6 +4324,14 @@ msgstr "동봉 문서"
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "동봉된 문서들"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter"
|
||||
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 "새 폴더 이름을 입력하세요. 폴더는 항목을 정리하는 데 도움이 됩니다."
|
||||
@@ -4329,6 +4340,26 @@ msgstr "새 폴더 이름을 입력하세요. 폴더는 항목을 정리하는
|
||||
msgid "Enter claim name"
|
||||
msgstr "클레임 이름 입력"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Enter Email"
|
||||
msgstr "이메일을 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Enter Initials"
|
||||
msgstr "이니셜을 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Enter Name"
|
||||
msgstr "이름을 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Enter Number"
|
||||
msgstr "숫자를 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter Text"
|
||||
msgstr "텍스트를 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-email-domain-create-dialog.tsx
|
||||
msgid "Enter the domain you want to use for sending emails (without http:// or www)"
|
||||
msgstr "이메일 발신에 사용할 도메인을 입력하세요( http:// 또는 www 제외)."
|
||||
@@ -4523,6 +4554,7 @@ msgid "Event Type"
|
||||
msgstr "이벤트 유형"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
msgid "Everyone"
|
||||
msgstr "모두"
|
||||
@@ -5222,14 +5254,6 @@ msgstr "이니셜은 필수 항목입니다"
|
||||
msgid "Initials Settings"
|
||||
msgstr "이니셜 설정"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Insert a value into the number field"
|
||||
msgstr "숫자 필드에 값을 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Insert a value into the text field"
|
||||
msgstr "텍스트 필드에 값을 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
msgid "Inserted"
|
||||
msgstr "삽입됨"
|
||||
@@ -5738,6 +5762,7 @@ msgid "Manager"
|
||||
msgstr "관리자"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Managers and above"
|
||||
msgstr "관리자 이상"
|
||||
|
||||
@@ -6133,6 +6158,10 @@ msgstr "걱정하지 마세요. 이메일을 입력하시면 비밀번호를 재
|
||||
msgid "None"
|
||||
msgstr "없음"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "None (Overrides global settings)"
|
||||
msgstr "없음(전역 설정 무시)"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.edit.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/templates.$id._index.tsx
|
||||
@@ -6696,6 +6725,10 @@ msgstr "사이트 소유자에게 추가 지원을 요청해 주세요."
|
||||
msgid "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
msgstr "토큰을 나중에 식별할 수 있도록 의미 있는 이름을 입력해 주세요."
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Please enter a number"
|
||||
msgstr "숫자를 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/forms/profile.tsx
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/components/general/claim-account.tsx
|
||||
@@ -6706,6 +6739,22 @@ msgstr "올바른 이름을 입력해 주세요."
|
||||
msgid "Please enter a valid number"
|
||||
msgstr "올바른 숫자를 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Please enter a value"
|
||||
msgstr "값을 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Please enter your email address"
|
||||
msgstr "이메일 주소를 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Please enter your full name"
|
||||
msgstr "전체 이름을 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Please enter your initials"
|
||||
msgstr "이니셜을 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-mobile-widget.tsx
|
||||
msgid "Please mark as viewed to complete"
|
||||
msgstr "완료하려면 확인함으로 표시해 주세요"
|
||||
@@ -7250,6 +7299,22 @@ msgstr "요청"
|
||||
msgid "Requesting Organisation"
|
||||
msgstr "요청하는 조직"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require 2FA"
|
||||
msgstr "2단계 인증 필수"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require account"
|
||||
msgstr "계정 필수"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require passkey"
|
||||
msgstr "패스키 필수"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require password"
|
||||
msgstr "비밀번호 필수"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||
@@ -7662,6 +7727,10 @@ msgstr "이 팀에 추가할 구성원을 선택하세요."
|
||||
msgid "Select Option"
|
||||
msgstr "옵션 선택"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Select Options"
|
||||
msgstr "옵션 선택"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-passkey.tsx
|
||||
msgid "Select passkey"
|
||||
msgstr "패스키 선택"
|
||||
@@ -7884,13 +7953,7 @@ msgstr "고급 설정 표시"
|
||||
msgid "Show templates in your public profile for your audience to sign and get started quickly"
|
||||
msgstr "공개 프로필에 템플릿을 표시해, 사용자가 빠르게 서명하고 시작할 수 있도록 하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-signature-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-2fa.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-password.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auto-sign.tsx
|
||||
@@ -7924,10 +7987,6 @@ msgstr "{0} <0>({1})</0>로 서명"
|
||||
msgid "Sign as<0>{0} <1>({1})</1></0>"
|
||||
msgstr "<0>{0} <1>({1})</1></0>로 서명"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Sign Checkbox Field"
|
||||
msgstr "체크박스 필드 서명"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -7944,10 +8003,6 @@ msgstr "문서 서명"
|
||||
msgid "Sign Documents"
|
||||
msgstr "문서 서명"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign Email"
|
||||
msgstr "이메일 서명"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
msgid "Sign field"
|
||||
@@ -7970,18 +8025,6 @@ msgstr "로그인"
|
||||
msgid "Sign in to your account"
|
||||
msgstr "계정에 로그인"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign Initials"
|
||||
msgstr "이니셜 서명"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign Name"
|
||||
msgstr "이름 서명"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Sign Number Field"
|
||||
msgstr "숫자 필드 서명"
|
||||
|
||||
#: apps/remix/app/components/general/app-nav-mobile.tsx
|
||||
#: apps/remix/app/components/general/menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
@@ -7992,10 +8035,6 @@ msgstr "로그아웃"
|
||||
msgid "Sign Signature Field"
|
||||
msgstr "서명 필드 서명"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Sign Text Field"
|
||||
msgstr "텍스트 필드 서명"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -8018,18 +8057,6 @@ msgstr "Microsoft로 가입"
|
||||
msgid "Sign Up with OIDC"
|
||||
msgstr "OIDC로 가입"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign your email into the field"
|
||||
msgstr "필드에 이메일을 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign your full name into the field"
|
||||
msgstr "필드에 전체 이름을 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign your initials into the field"
|
||||
msgstr "필드에 이니셜을 입력하세요"
|
||||
|
||||
#: apps/remix/app/components/dialogs/ai-field-detection-dialog.tsx
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: nl\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"PO-Revision-Date: 2026-01-13 02:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Dutch\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
@@ -1291,6 +1291,7 @@ msgid "Admin Panel"
|
||||
msgstr "Beheerderspaneel"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Admins only"
|
||||
msgstr "Alleen beheerders"
|
||||
|
||||
@@ -2578,6 +2579,7 @@ msgid "Configure the team roles for each member"
|
||||
msgstr "Configureer de teamrollen voor elk lid"
|
||||
|
||||
#: apps/remix/app/components/dialogs/public-profile-template-manage-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/template-direct-link-dialog.tsx
|
||||
msgid "Confirm"
|
||||
msgstr "Bevestigen"
|
||||
@@ -3734,6 +3736,7 @@ msgctxt "Audit log format"
|
||||
msgid "Document sent"
|
||||
msgstr "Document verzonden"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
msgid "Document Settings"
|
||||
msgstr "Documentinstellingen"
|
||||
@@ -4321,6 +4324,14 @@ msgstr "Bijgevoegd document"
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Bijgevoegde documenten"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter"
|
||||
msgstr "Invoeren"
|
||||
|
||||
#: 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."
|
||||
@@ -4329,6 +4340,26 @@ msgstr "Voer een naam in voor je nieuwe map. Mappen helpen je je items te organi
|
||||
msgid "Enter claim name"
|
||||
msgstr "Voer claimnaam in"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Enter Email"
|
||||
msgstr "E-mailadres invoeren"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Enter Initials"
|
||||
msgstr "Initialen invoeren"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Enter Name"
|
||||
msgstr "Naam invoeren"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Enter Number"
|
||||
msgstr "Nummer invoeren"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter Text"
|
||||
msgstr "Tekst invoeren"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-email-domain-create-dialog.tsx
|
||||
msgid "Enter the domain you want to use for sending emails (without http:// or www)"
|
||||
msgstr "Voer het domein in dat je wilt gebruiken voor het verzenden van e-mails (zonder http:// of www)"
|
||||
@@ -4523,6 +4554,7 @@ msgid "Event Type"
|
||||
msgstr "Gebeurtenistype"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
msgid "Everyone"
|
||||
msgstr "Iedereen"
|
||||
@@ -5222,14 +5254,6 @@ msgstr "Initialen zijn verplicht"
|
||||
msgid "Initials Settings"
|
||||
msgstr "Initialen-instellingen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Insert a value into the number field"
|
||||
msgstr "Vul een waarde in het nummerveld in"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Insert a value into the text field"
|
||||
msgstr "Vul een waarde in het tekstveld in"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
msgid "Inserted"
|
||||
msgstr "Ingevoegd"
|
||||
@@ -5738,6 +5762,7 @@ msgid "Manager"
|
||||
msgstr "Manager"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Managers and above"
|
||||
msgstr "Managers en hoger"
|
||||
|
||||
@@ -6133,6 +6158,10 @@ msgstr "Geen zorgen, dat gebeurt wel eens! Vul je e‑mail in en we sturen je ee
|
||||
msgid "None"
|
||||
msgstr "Geen"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "None (Overrides global settings)"
|
||||
msgstr "Geen (Overschrijft globale instellingen)"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.edit.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/templates.$id._index.tsx
|
||||
@@ -6696,6 +6725,10 @@ msgstr "Neem contact op met de site-eigenaar voor verdere hulp."
|
||||
msgid "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
msgstr "Voer een betekenisvolle naam in voor je token. Hiermee kun je het later herkennen."
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Please enter a number"
|
||||
msgstr "Voer een nummer in"
|
||||
|
||||
#: apps/remix/app/components/forms/profile.tsx
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/components/general/claim-account.tsx
|
||||
@@ -6706,6 +6739,22 @@ msgstr "Voer een geldige naam in."
|
||||
msgid "Please enter a valid number"
|
||||
msgstr "Voer een geldig nummer in"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Please enter a value"
|
||||
msgstr "Voer een waarde in"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Please enter your email address"
|
||||
msgstr "Voer je e-mailadres in"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Please enter your full name"
|
||||
msgstr "Voer je volledige naam in"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Please enter your initials"
|
||||
msgstr "Vul je initialen in"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-mobile-widget.tsx
|
||||
msgid "Please mark as viewed to complete"
|
||||
msgstr "Markeer als bekeken om te voltooien"
|
||||
@@ -7250,6 +7299,22 @@ msgstr "Verzoek"
|
||||
msgid "Requesting Organisation"
|
||||
msgstr "Aanvragende organisatie"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require 2FA"
|
||||
msgstr "2FA vereisen"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require account"
|
||||
msgstr "Account vereisen"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require passkey"
|
||||
msgstr "Passkey vereisen"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require password"
|
||||
msgstr "Wachtwoord vereisen"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||
@@ -7662,6 +7727,10 @@ msgstr "Selecteer leden om aan dit team toe te voegen"
|
||||
msgid "Select Option"
|
||||
msgstr "Selecteer optie"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Select Options"
|
||||
msgstr "Selecteer opties"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-passkey.tsx
|
||||
msgid "Select passkey"
|
||||
msgstr "Passkey selecteren"
|
||||
@@ -7884,13 +7953,7 @@ msgstr "Geavanceerde instellingen weergeven"
|
||||
msgid "Show templates in your public profile for your audience to sign and get started quickly"
|
||||
msgstr "Toon sjablonen in je openbare profiel zodat je publiek snel kan ondertekenen en beginnen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-signature-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-2fa.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-password.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auto-sign.tsx
|
||||
@@ -7924,10 +7987,6 @@ msgstr "Ondertekenen als {0} <0>({1})</0>"
|
||||
msgid "Sign as<0>{0} <1>({1})</1></0>"
|
||||
msgstr "Ondertekenen als<0>{0} <1>({1})</1></0>"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Sign Checkbox Field"
|
||||
msgstr "Checkboxveld ondertekenen"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -7944,10 +8003,6 @@ msgstr "Document ondertekenen"
|
||||
msgid "Sign Documents"
|
||||
msgstr "Documenten ondertekenen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign Email"
|
||||
msgstr "E-mail ondertekenen"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
msgid "Sign field"
|
||||
@@ -7970,18 +8025,6 @@ msgstr "Inloggen"
|
||||
msgid "Sign in to your account"
|
||||
msgstr "Log in op je account"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign Initials"
|
||||
msgstr "Initialen ondertekenen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign Name"
|
||||
msgstr "Naam ondertekenen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Sign Number Field"
|
||||
msgstr "Nummer-veld ondertekenen"
|
||||
|
||||
#: apps/remix/app/components/general/app-nav-mobile.tsx
|
||||
#: apps/remix/app/components/general/menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
@@ -7992,10 +8035,6 @@ msgstr "Uitloggen"
|
||||
msgid "Sign Signature Field"
|
||||
msgstr "Handtekeningveld ondertekenen"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Sign Text Field"
|
||||
msgstr "Tekstveld ondertekenen"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -8018,18 +8057,6 @@ msgstr "Registreren met Microsoft"
|
||||
msgid "Sign Up with OIDC"
|
||||
msgstr "Registreren met OIDC"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign your email into the field"
|
||||
msgstr "Schrijf uw e-mailadres in het veld"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign your full name into the field"
|
||||
msgstr "Schrijf uw volledige naam in het veld"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign your initials into the field"
|
||||
msgstr "Schrijf uw initialen in het veld"
|
||||
|
||||
#: apps/remix/app/components/dialogs/ai-field-detection-dialog.tsx
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: pl\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"PO-Revision-Date: 2026-01-13 02:39\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"
|
||||
@@ -1291,6 +1291,7 @@ msgid "Admin Panel"
|
||||
msgstr "Panel administratora"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Admins only"
|
||||
msgstr "Tylko dla administratorów"
|
||||
|
||||
@@ -2578,6 +2579,7 @@ msgid "Configure the team roles for each member"
|
||||
msgstr "Skonfiguruj role w zespole dla każdego użytkownika"
|
||||
|
||||
#: apps/remix/app/components/dialogs/public-profile-template-manage-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/template-direct-link-dialog.tsx
|
||||
msgid "Confirm"
|
||||
msgstr "Potwierdź"
|
||||
@@ -3734,6 +3736,7 @@ msgctxt "Audit log format"
|
||||
msgid "Document sent"
|
||||
msgstr "Wysłano dokument"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
msgid "Document Settings"
|
||||
msgstr "Ustawienia dokumentu"
|
||||
@@ -4319,7 +4322,15 @@ msgstr "Załączony dokument"
|
||||
|
||||
#: packages/lib/server-only/pdf/render-audit-logs.ts
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "Załączone dokumenty"
|
||||
msgstr "Załączniki"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter"
|
||||
msgstr "Wpisz lub wprowadź wartość"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-create-dialog.tsx
|
||||
msgid "Enter a name for your new folder. Folders help you organise your items."
|
||||
@@ -4329,6 +4340,26 @@ msgstr "Wpisz nazwę nowego folderu. Foldery pomagają uporządkować elementy."
|
||||
msgid "Enter claim name"
|
||||
msgstr "Wpisz nazwę"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Enter Email"
|
||||
msgstr "Wpisz adres e-mail"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Enter Initials"
|
||||
msgstr "Wpisz inicjały"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Enter Name"
|
||||
msgstr "Wpisz imię i nazwisko"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Enter Number"
|
||||
msgstr "Wpisz liczbę"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter Text"
|
||||
msgstr "Wpisz tekst"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-email-domain-create-dialog.tsx
|
||||
msgid "Enter the domain you want to use for sending emails (without http:// or www)"
|
||||
msgstr "Wpisz domenę do wysyłania wiadomości (bez http:// lub www)"
|
||||
@@ -4523,6 +4554,7 @@ msgid "Event Type"
|
||||
msgstr "Rodzaj zdarzenia"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
msgid "Everyone"
|
||||
msgstr "Wszyscy"
|
||||
@@ -5222,14 +5254,6 @@ msgstr "Inicjały są wymagane"
|
||||
msgid "Initials Settings"
|
||||
msgstr "Ustawienia inicjałów"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Insert a value into the number field"
|
||||
msgstr "Wpisz wartość do pola liczby"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Insert a value into the text field"
|
||||
msgstr "Wpisz wartość do pola tekstowego"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
msgid "Inserted"
|
||||
msgstr "Wypełniono"
|
||||
@@ -5738,6 +5762,7 @@ msgid "Manager"
|
||||
msgstr "Manager"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Managers and above"
|
||||
msgstr "Managerowie i wyżej"
|
||||
|
||||
@@ -6133,6 +6158,10 @@ msgstr "Nie martw się! Wpisz swój adres e-mail, a my wyślemy Ci specjalny lin
|
||||
msgid "None"
|
||||
msgstr "Brak"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "None (Overrides global settings)"
|
||||
msgstr "Brak (odziedzicz metodę uwierzytelniania)"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.edit.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/templates.$id._index.tsx
|
||||
@@ -6696,6 +6725,10 @@ msgstr "Skontaktuj się z właścicielem dokumentu, aby uzyskać pomoc."
|
||||
msgid "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
msgstr "Wpisz nazwę tokena. Pomoże to później w jego identyfikacji."
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Please enter a number"
|
||||
msgstr "Wpisz liczbę"
|
||||
|
||||
#: apps/remix/app/components/forms/profile.tsx
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/components/general/claim-account.tsx
|
||||
@@ -6706,6 +6739,22 @@ msgstr "Wpisz prawidłową nazwę."
|
||||
msgid "Please enter a valid number"
|
||||
msgstr "Wpisz prawidłową liczbę"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Please enter a value"
|
||||
msgstr "Wpisz wartość"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Please enter your email address"
|
||||
msgstr "Wpisz swój adres e-mail"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Please enter your full name"
|
||||
msgstr "Wpisz swoje pełne imię i nazwisko"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Please enter your initials"
|
||||
msgstr "Wprowadź swoje inicjały"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-mobile-widget.tsx
|
||||
msgid "Please mark as viewed to complete"
|
||||
msgstr "Oznacz jako wyświetlony, aby zakończyć"
|
||||
@@ -7250,6 +7299,22 @@ msgstr "Żądanie"
|
||||
msgid "Requesting Organisation"
|
||||
msgstr "Wnioskująca organizacja"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require 2FA"
|
||||
msgstr "Wymagana weryfikacja dwuetapowa"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require account"
|
||||
msgstr "Wymagane konto"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require passkey"
|
||||
msgstr "Wymagany klucz dostępu"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require password"
|
||||
msgstr "Wymagane hasło"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||
@@ -7662,6 +7727,10 @@ msgstr "Wybierz użytkowników, których chcesz dodać do zespołu"
|
||||
msgid "Select Option"
|
||||
msgstr "Wybierz opcję"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Select Options"
|
||||
msgstr "Wybierz opcje"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-passkey.tsx
|
||||
msgid "Select passkey"
|
||||
msgstr "Wybierz klucz dostępu"
|
||||
@@ -7884,13 +7953,7 @@ msgstr "Pokaż ustawienia zaawansowane"
|
||||
msgid "Show templates in your public profile for your audience to sign and get started quickly"
|
||||
msgstr "Pokaż szablony w profilu publicznym, aby szybko podpisać dokument"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-signature-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-2fa.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-password.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auto-sign.tsx
|
||||
@@ -7924,10 +7987,6 @@ msgstr "Podpisz jako {0} <0>({1})</0>"
|
||||
msgid "Sign as<0>{0} <1>({1})</1></0>"
|
||||
msgstr "Podpisz jako<0>{0} <1>({1})</1></0>"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Sign Checkbox Field"
|
||||
msgstr "Podpisz pole wyboru"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -7944,10 +8003,6 @@ msgstr "Podpisz dokument"
|
||||
msgid "Sign Documents"
|
||||
msgstr "Podpisz dokumenty"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign Email"
|
||||
msgstr "Podpisz adres e-mail"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
msgid "Sign field"
|
||||
@@ -7970,18 +8025,6 @@ msgstr "Zaloguj się"
|
||||
msgid "Sign in to your account"
|
||||
msgstr "Zaloguj się na swoje konto"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign Initials"
|
||||
msgstr "Podpisz inicjały"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign Name"
|
||||
msgstr "Podpisz nazwę"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Sign Number Field"
|
||||
msgstr "Podpisz pole liczby"
|
||||
|
||||
#: apps/remix/app/components/general/app-nav-mobile.tsx
|
||||
#: apps/remix/app/components/general/menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
@@ -7992,10 +8035,6 @@ msgstr "Wyloguj"
|
||||
msgid "Sign Signature Field"
|
||||
msgstr "Podpisz pole podpisu"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Sign Text Field"
|
||||
msgstr "Podpisz pole tekstowe"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -8018,18 +8057,6 @@ msgstr "Zarejestruj się przez Microsoft"
|
||||
msgid "Sign Up with OIDC"
|
||||
msgstr "Zarejestruj się przez OIDC"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign your email into the field"
|
||||
msgstr "Podpisz adres e-mail w polu"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign your full name into the field"
|
||||
msgstr "Podpisz nazwę w polu"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign your initials into the field"
|
||||
msgstr "Podpisz inicjały w polu"
|
||||
|
||||
#: apps/remix/app/components/dialogs/ai-field-detection-dialog.tsx
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
|
||||
@@ -1286,6 +1286,7 @@ msgid "Admin Panel"
|
||||
msgstr "Painel de Administração"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Admins only"
|
||||
msgstr "Apenas administradores"
|
||||
|
||||
@@ -2573,6 +2574,7 @@ msgid "Configure the team roles for each member"
|
||||
msgstr "Configure as funções da equipe para cada membro"
|
||||
|
||||
#: apps/remix/app/components/dialogs/public-profile-template-manage-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/template-direct-link-dialog.tsx
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmar"
|
||||
@@ -3729,6 +3731,7 @@ msgctxt "Audit log format"
|
||||
msgid "Document sent"
|
||||
msgstr "Documento enviado"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
msgid "Document Settings"
|
||||
msgstr "Configurações do Documento"
|
||||
@@ -4316,6 +4319,14 @@ msgstr "Documento Anexo"
|
||||
msgid "Enclosed Documents"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter"
|
||||
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."
|
||||
@@ -4324,6 +4335,26 @@ msgstr "Digite um nome para sua nova pasta. As pastas ajudam você a organizar s
|
||||
msgid "Enter claim name"
|
||||
msgstr "Digite o nome da reivindicação"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Enter Email"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Enter Initials"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Enter Name"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Enter Number"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter Text"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-email-domain-create-dialog.tsx
|
||||
msgid "Enter the domain you want to use for sending emails (without http:// or www)"
|
||||
msgstr "Digite o domínio que você deseja usar para enviar e-mails (sem http:// ou www)"
|
||||
@@ -4518,6 +4549,7 @@ msgid "Event Type"
|
||||
msgstr "Tipo de Evento"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
msgid "Everyone"
|
||||
msgstr "Todos"
|
||||
@@ -5217,14 +5249,6 @@ msgstr "Iniciais são obrigatórias"
|
||||
msgid "Initials Settings"
|
||||
msgstr "Configurações de Iniciais"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Insert a value into the number field"
|
||||
msgstr "Insira um valor no campo numérico"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Insert a value into the text field"
|
||||
msgstr "Insira um valor no campo de texto"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
msgid "Inserted"
|
||||
msgstr "Inserido"
|
||||
@@ -5733,6 +5757,7 @@ msgid "Manager"
|
||||
msgstr "Gerente"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Managers and above"
|
||||
msgstr "Gerentes e acima"
|
||||
|
||||
@@ -6128,6 +6153,10 @@ msgstr "Não se preocupe, acontece! Digite seu e-mail e enviaremos um link espec
|
||||
msgid "None"
|
||||
msgstr "Nenhum"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "None (Overrides global settings)"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.edit.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/templates.$id._index.tsx
|
||||
@@ -6691,6 +6720,10 @@ msgstr "Por favor, entre em contato com o proprietário do site para mais assist
|
||||
msgid "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
msgstr "Por favor, insira um nome significativo para seu token. Isso ajudará você a identificá-lo mais tarde."
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Please enter a number"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/forms/profile.tsx
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/components/general/claim-account.tsx
|
||||
@@ -6701,6 +6734,22 @@ msgstr "Por favor, insira um nome válido."
|
||||
msgid "Please enter a valid number"
|
||||
msgstr "Por favor, insira um número válido"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Please enter a value"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Please enter your email address"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Please enter your full name"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Please enter your initials"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-mobile-widget.tsx
|
||||
msgid "Please mark as viewed to complete"
|
||||
msgstr "Por favor, marque como visualizado para completar"
|
||||
@@ -7245,6 +7294,22 @@ msgstr "Solicitação"
|
||||
msgid "Requesting Organisation"
|
||||
msgstr "Organização Solicitante"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require 2FA"
|
||||
msgstr ""
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require account"
|
||||
msgstr ""
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require passkey"
|
||||
msgstr ""
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require password"
|
||||
msgstr ""
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||
@@ -7657,6 +7722,10 @@ msgstr "Selecione membros para adicionar a esta equipe"
|
||||
msgid "Select Option"
|
||||
msgstr "Selecionar Opção"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Select Options"
|
||||
msgstr ""
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-passkey.tsx
|
||||
msgid "Select passkey"
|
||||
msgstr "Selecionar passkey"
|
||||
@@ -7879,13 +7948,7 @@ msgstr "Mostrar configurações avançadas"
|
||||
msgid "Show templates in your public profile for your audience to sign and get started quickly"
|
||||
msgstr "Mostre modelos em seu perfil público para seu público assinar e começar rapidamente"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-signature-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-2fa.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-password.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auto-sign.tsx
|
||||
@@ -7919,10 +7982,6 @@ msgstr "Assinar como {0} <0>({1})</0>"
|
||||
msgid "Sign as<0>{0} <1>({1})</1></0>"
|
||||
msgstr "Assinar como<0>{0} <1>({1})</1></0>"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Sign Checkbox Field"
|
||||
msgstr "Assinar Campo de Caixa de Seleção"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -7939,10 +7998,6 @@ msgstr "Assinar Documento"
|
||||
msgid "Sign Documents"
|
||||
msgstr "Assinar Documentos"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign Email"
|
||||
msgstr "Assinar E-mail"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
msgid "Sign field"
|
||||
@@ -7965,18 +8020,6 @@ msgstr "Entrar"
|
||||
msgid "Sign in to your account"
|
||||
msgstr "Entre na sua conta"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign Initials"
|
||||
msgstr "Assinar Iniciais"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign Name"
|
||||
msgstr "Assinar Nome"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Sign Number Field"
|
||||
msgstr "Assinar Campo Numérico"
|
||||
|
||||
#: apps/remix/app/components/general/app-nav-mobile.tsx
|
||||
#: apps/remix/app/components/general/menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
@@ -7987,10 +8030,6 @@ msgstr "Sair"
|
||||
msgid "Sign Signature Field"
|
||||
msgstr "Assinar Campo de Assinatura"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Sign Text Field"
|
||||
msgstr "Assinar Campo de Texto"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -8013,18 +8052,6 @@ msgstr "Inscrever-se com Microsoft"
|
||||
msgid "Sign Up with OIDC"
|
||||
msgstr "Inscrever-se com OIDC"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign your email into the field"
|
||||
msgstr "Assine seu e-mail no campo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign your full name into the field"
|
||||
msgstr "Assine seu nome completo no campo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign your initials into the field"
|
||||
msgstr "Assine suas iniciais no campo"
|
||||
|
||||
#: apps/remix/app/components/dialogs/ai-field-detection-dialog.tsx
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Language: zh\n"
|
||||
"Project-Id-Version: documenso-app\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2026-01-06 04:17\n"
|
||||
"PO-Revision-Date: 2026-01-13 02:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
@@ -1291,6 +1291,7 @@ msgid "Admin Panel"
|
||||
msgstr "管理面板"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Admins only"
|
||||
msgstr "仅限管理员"
|
||||
|
||||
@@ -2578,6 +2579,7 @@ msgid "Configure the team roles for each member"
|
||||
msgstr "配置每个成员的团队角色"
|
||||
|
||||
#: apps/remix/app/components/dialogs/public-profile-template-manage-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/template-direct-link-dialog.tsx
|
||||
msgid "Confirm"
|
||||
msgstr "确认"
|
||||
@@ -3734,6 +3736,7 @@ msgctxt "Audit log format"
|
||||
msgid "Document sent"
|
||||
msgstr "文档已发送"
|
||||
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor-settings-dialog.tsx
|
||||
#: apps/remix/app/components/general/envelope-editor/envelope-editor.tsx
|
||||
msgid "Document Settings"
|
||||
msgstr "文档设置"
|
||||
@@ -4321,6 +4324,14 @@ msgstr "随附文档"
|
||||
msgid "Enclosed Documents"
|
||||
msgstr "随附文件"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter"
|
||||
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 "为新文件夹输入名称。文件夹可以帮助您整理项目。"
|
||||
@@ -4329,6 +4340,26 @@ msgstr "为新文件夹输入名称。文件夹可以帮助您整理项目。"
|
||||
msgid "Enter claim name"
|
||||
msgstr "输入声明名称"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Enter Email"
|
||||
msgstr "输入邮箱"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Enter Initials"
|
||||
msgstr "输入姓名首字母"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Enter Name"
|
||||
msgstr "输入姓名"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Enter Number"
|
||||
msgstr "输入数字"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Enter Text"
|
||||
msgstr "输入文本"
|
||||
|
||||
#: apps/remix/app/components/dialogs/organisation-email-domain-create-dialog.tsx
|
||||
msgid "Enter the domain you want to use for sending emails (without http:// or www)"
|
||||
msgstr "输入您希望用于发送邮件的域名(不含 http:// 或 www)"
|
||||
@@ -4523,6 +4554,7 @@ msgid "Event Type"
|
||||
msgstr "事件类型"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
#: packages/ui/components/document/document-visibility-select.tsx
|
||||
msgid "Everyone"
|
||||
msgstr "所有人"
|
||||
@@ -5222,14 +5254,6 @@ msgstr "必须填写姓名首字母缩写"
|
||||
msgid "Initials Settings"
|
||||
msgstr "姓名首字母设置"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Insert a value into the number field"
|
||||
msgstr "在数字字段中输入一个值"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Insert a value into the text field"
|
||||
msgstr "在文本字段中输入一个值"
|
||||
|
||||
#: apps/remix/app/components/tables/admin-document-recipient-item-table.tsx
|
||||
msgid "Inserted"
|
||||
msgstr "已插入"
|
||||
@@ -5738,6 +5762,7 @@ msgid "Manager"
|
||||
msgstr "管理者"
|
||||
|
||||
#: apps/remix/app/components/dialogs/folder-update-dialog.tsx
|
||||
#: packages/lib/constants/document-visibility.ts
|
||||
msgid "Managers and above"
|
||||
msgstr "管理者及以上"
|
||||
|
||||
@@ -6133,6 +6158,10 @@ msgstr "别担心,这很常见!输入你的邮箱,我们会给你发送一
|
||||
msgid "None"
|
||||
msgstr "无"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "None (Overrides global settings)"
|
||||
msgstr "无(覆盖全局设置)"
|
||||
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id._index.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/documents.$id.edit.tsx
|
||||
#: apps/remix/app/routes/_authenticated+/t.$teamUrl+/templates.$id._index.tsx
|
||||
@@ -6696,6 +6725,10 @@ msgstr "请联系站点所有者以获取进一步帮助。"
|
||||
msgid "Please enter a meaningful name for your token. This will help you identify it later."
|
||||
msgstr "请输入一个有意义的令牌名称,以便日后识别。"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Please enter a number"
|
||||
msgstr "请输入一个数字"
|
||||
|
||||
#: apps/remix/app/components/forms/profile.tsx
|
||||
#: apps/remix/app/components/forms/signup.tsx
|
||||
#: apps/remix/app/components/general/claim-account.tsx
|
||||
@@ -6706,6 +6739,22 @@ msgstr "请输入有效姓名。"
|
||||
msgid "Please enter a valid number"
|
||||
msgstr "请输入有效的数字"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Please enter a value"
|
||||
msgstr "请输入一个值"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Please enter your email address"
|
||||
msgstr "请输入您的邮箱地址"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Please enter your full name"
|
||||
msgstr "请输入您的全名"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Please enter your initials"
|
||||
msgstr "请输入您的姓名首字母缩写"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-mobile-widget.tsx
|
||||
msgid "Please mark as viewed to complete"
|
||||
msgstr "请标记为已查看以完成"
|
||||
@@ -7250,6 +7299,22 @@ msgstr "请求"
|
||||
msgid "Requesting Organisation"
|
||||
msgstr "请求的组织"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require 2FA"
|
||||
msgstr "需要双重身份验证"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require account"
|
||||
msgstr "需要账户"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require passkey"
|
||||
msgstr "需要通行密钥"
|
||||
|
||||
#: packages/lib/constants/document-auth.ts
|
||||
msgid "Require password"
|
||||
msgstr "需要密码"
|
||||
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/checkbox-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/dropdown-field.tsx
|
||||
#: packages/ui/primitives/document-flow/field-items-advanced-settings/number-field.tsx
|
||||
@@ -7662,6 +7727,10 @@ msgstr "选择要添加到此团队的成员"
|
||||
msgid "Select Option"
|
||||
msgstr "选择选项"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Select Options"
|
||||
msgstr "选择选项"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-passkey.tsx
|
||||
msgid "Select passkey"
|
||||
msgstr "选择通行密钥"
|
||||
@@ -7884,13 +7953,7 @@ msgstr "显示高级设置"
|
||||
msgid "Show templates in your public profile for your audience to sign and get started quickly"
|
||||
msgstr "在公开资料中展示模板,方便你的用户快速签署上手"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-signature-dialog.tsx
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-2fa.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-password.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auto-sign.tsx
|
||||
@@ -7924,10 +7987,6 @@ msgstr "以 {0} <0>({1})</0> 的身份签署"
|
||||
msgid "Sign as<0>{0} <1>({1})</1></0>"
|
||||
msgstr "以<0>{0} <1>({1})</1></0>的身份签署"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-checkbox-dialog.tsx
|
||||
msgid "Sign Checkbox Field"
|
||||
msgstr "签署复选框字段"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -7944,10 +8003,6 @@ msgstr "签署文档"
|
||||
msgid "Sign Documents"
|
||||
msgstr "签署文档"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign Email"
|
||||
msgstr "签署电子邮件字段"
|
||||
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
#: apps/remix/app/components/general/document-signing/document-signing-auth-dialog.tsx
|
||||
msgid "Sign field"
|
||||
@@ -7970,18 +8025,6 @@ msgstr "登录"
|
||||
msgid "Sign in to your account"
|
||||
msgstr "登录到你的账号"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign Initials"
|
||||
msgstr "签署姓名首字母字段"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign Name"
|
||||
msgstr "签署姓名字段"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-number-dialog.tsx
|
||||
msgid "Sign Number Field"
|
||||
msgstr "签署数字字段"
|
||||
|
||||
#: apps/remix/app/components/general/app-nav-mobile.tsx
|
||||
#: apps/remix/app/components/general/menu-switcher.tsx
|
||||
#: apps/remix/app/components/general/org-menu-switcher.tsx
|
||||
@@ -7992,10 +8035,6 @@ msgstr "登出"
|
||||
msgid "Sign Signature Field"
|
||||
msgstr "签署签名字段"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-text-dialog.tsx
|
||||
msgid "Sign Text Field"
|
||||
msgstr "签署文本字段"
|
||||
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
#: apps/remix/app/components/embed/multisign/multi-sign-document-signing-view.tsx
|
||||
@@ -8018,18 +8057,6 @@ msgstr "使用 Microsoft 注册"
|
||||
msgid "Sign Up with OIDC"
|
||||
msgstr "使用 OIDC 注册"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-email-dialog.tsx
|
||||
msgid "Sign your email into the field"
|
||||
msgstr "在字段中填写您的电子邮件地址"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-name-dialog.tsx
|
||||
msgid "Sign your full name into the field"
|
||||
msgstr "在字段中填写您的全名"
|
||||
|
||||
#: apps/remix/app/components/dialogs/sign-field-initials-dialog.tsx
|
||||
msgid "Sign your initials into the field"
|
||||
msgstr "在字段中填写您的姓名首字母缩写"
|
||||
|
||||
#: apps/remix/app/components/dialogs/ai-field-detection-dialog.tsx
|
||||
#: apps/remix/app/components/embed/embed-direct-template-client-page.tsx
|
||||
#: apps/remix/app/components/embed/embed-document-signing-page-v1.tsx
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { RecipientRole } from '@prisma/client';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const ZDefaultRecipientSchema = z.object({
|
||||
email: z.string().email(),
|
||||
name: z.string(),
|
||||
role: z.nativeEnum(RecipientRole),
|
||||
});
|
||||
|
||||
export type TDefaultRecipient = z.infer<typeof ZDefaultRecipientSchema>;
|
||||
|
||||
export const ZDefaultRecipientsSchema = z.array(ZDefaultRecipientSchema);
|
||||
|
||||
export type TDefaultRecipients = z.infer<typeof ZDefaultRecipientsSchema>;
|
||||
@@ -48,6 +48,7 @@ type PutNormalizedPdfOptions = {
|
||||
file: File;
|
||||
originalData?: string;
|
||||
originalMimeType?: string;
|
||||
flattenForm?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -57,10 +58,11 @@ export const putNormalizedPdfFileServerSide = async ({
|
||||
file,
|
||||
originalData,
|
||||
originalMimeType,
|
||||
flattenForm = true,
|
||||
}: PutNormalizedPdfOptions) => {
|
||||
const buffer = Buffer.from(await file.arrayBuffer());
|
||||
|
||||
const normalized = await normalizePdf(buffer);
|
||||
const normalized = await normalizePdf(buffer, { flattenForm });
|
||||
|
||||
const fileName = file.name.endsWith('.pdf') ? file.name : `${file.name}.pdf`;
|
||||
|
||||
|
||||
@@ -137,6 +137,7 @@ export const generateDefaultOrganisationSettings = (): Omit<
|
||||
// emailReplyToName: null,
|
||||
emailDocumentSettings: DEFAULT_DOCUMENT_EMAIL_SETTINGS,
|
||||
|
||||
defaultRecipients: null,
|
||||
aiFeaturesEnabled: false,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -7,6 +7,6 @@ export const extractInitials = (text: string) =>
|
||||
.slice(0, 2)
|
||||
.join('');
|
||||
|
||||
export const recipientAbbreviation = (recipient: Recipient) => {
|
||||
export const recipientAbbreviation = (recipient: Pick<Recipient, 'name' | 'email'>) => {
|
||||
return extractInitials(recipient.name) || recipient.email.slice(0, 1).toUpperCase();
|
||||
};
|
||||
|
||||
@@ -204,6 +204,7 @@ export const generateDefaultTeamSettings = (): Omit<TeamGlobalSettings, 'id' | '
|
||||
emailReplyTo: null,
|
||||
// emailReplyToName: null,
|
||||
|
||||
defaultRecipients: null,
|
||||
aiFeaturesEnabled: null,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "OrganisationGlobalSettings" ADD COLUMN "defaultRecipients" JSONB;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "TeamGlobalSettings" ADD COLUMN "defaultRecipients" JSONB;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
-- CreateIndex
|
||||
CREATE INDEX IF NOT EXISTS "DocumentAuditLog_envelopeId_idx" ON "DocumentAuditLog"("envelopeId");
|
||||
@@ -472,6 +472,8 @@ model DocumentAuditLog {
|
||||
ipAddress String?
|
||||
|
||||
envelope Envelope @relation(fields: [envelopeId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([envelopeId])
|
||||
}
|
||||
|
||||
enum DocumentDataType {
|
||||
@@ -808,7 +810,7 @@ enum OrganisationMemberInviteStatus {
|
||||
DECLINED
|
||||
}
|
||||
|
||||
/// @zod.import(["import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';"])
|
||||
/// @zod.import(["import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';", "import { ZDefaultRecipientsSchema } from '@documenso/lib/types/default-recipients';"])
|
||||
model OrganisationGlobalSettings {
|
||||
id String @id
|
||||
organisation Organisation?
|
||||
@@ -826,6 +828,8 @@ model OrganisationGlobalSettings {
|
||||
uploadSignatureEnabled Boolean @default(true)
|
||||
drawSignatureEnabled Boolean @default(true)
|
||||
|
||||
defaultRecipients Json? /// [DefaultRecipient[]] @zod.custom.use(ZDefaultRecipientsSchema)
|
||||
|
||||
emailId String?
|
||||
email OrganisationEmail? @relation(fields: [emailId], references: [id])
|
||||
|
||||
@@ -842,7 +846,7 @@ model OrganisationGlobalSettings {
|
||||
aiFeaturesEnabled Boolean @default(false)
|
||||
}
|
||||
|
||||
/// @zod.import(["import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';"])
|
||||
/// @zod.import(["import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';", "import { ZDefaultRecipientsSchema } from '@documenso/lib/types/default-recipients';"])
|
||||
model TeamGlobalSettings {
|
||||
id String @id
|
||||
team Team?
|
||||
@@ -861,6 +865,8 @@ model TeamGlobalSettings {
|
||||
uploadSignatureEnabled Boolean?
|
||||
drawSignatureEnabled Boolean?
|
||||
|
||||
defaultRecipients Json? /// [DefaultRecipient[]] @zod.custom.use(ZDefaultRecipientsSchema)
|
||||
|
||||
emailId String?
|
||||
email OrganisationEmail? @relation(fields: [emailId], references: [id])
|
||||
|
||||
|
||||
Vendored
+3
@@ -1,4 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/no-namespace */
|
||||
import type { TDefaultRecipient } from '@documenso/lib/types/default-recipients';
|
||||
import type {
|
||||
TDocumentAuthOptions,
|
||||
TRecipientAuthOptions,
|
||||
@@ -26,6 +27,8 @@ declare global {
|
||||
type FieldMeta = TFieldMetaNotOptionalSchema;
|
||||
|
||||
type EnvelopeAttachmentType = TEnvelopeAttachmentType;
|
||||
|
||||
type DefaultRecipient = TDefaultRecipient;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"dependencies": {
|
||||
"@documenso/lib": "*",
|
||||
"@documenso/prisma": "*",
|
||||
"@simplewebauthn/server": "^13.2.2",
|
||||
"@tanstack/react-query": "5.90.10",
|
||||
"@trpc/client": "11.8.1",
|
||||
"@trpc/react-query": "11.8.1",
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import { EnvelopeType } from '@prisma/client';
|
||||
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import type { FindResultResponse } from '@documenso/lib/types/search-params';
|
||||
import { parseDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs';
|
||||
import { unsafeBuildEnvelopeIdQuery } from '@documenso/lib/utils/envelope';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { adminProcedure } from '../trpc';
|
||||
import {
|
||||
ZFindDocumentAuditLogsRequestSchema,
|
||||
ZFindDocumentAuditLogsResponseSchema,
|
||||
} from './find-document-audit-logs.types';
|
||||
|
||||
export const findDocumentAuditLogsRoute = adminProcedure
|
||||
.input(ZFindDocumentAuditLogsRequestSchema)
|
||||
.output(ZFindDocumentAuditLogsResponseSchema)
|
||||
.query(async ({ input }) => {
|
||||
const {
|
||||
envelopeId,
|
||||
page = 1,
|
||||
perPage = 50,
|
||||
orderByColumn = 'createdAt',
|
||||
orderByDirection = 'desc',
|
||||
} = input;
|
||||
|
||||
const envelope = await prisma.envelope.findFirst({
|
||||
where: unsafeBuildEnvelopeIdQuery(
|
||||
{
|
||||
type: 'envelopeId',
|
||||
id: envelopeId,
|
||||
},
|
||||
EnvelopeType.DOCUMENT,
|
||||
),
|
||||
});
|
||||
|
||||
if (!envelope) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Envelope not found',
|
||||
});
|
||||
}
|
||||
|
||||
const [data, count] = await Promise.all([
|
||||
prisma.documentAuditLog.findMany({
|
||||
where: { envelopeId: envelope.id },
|
||||
skip: Math.max(page - 1, 0) * perPage,
|
||||
take: perPage,
|
||||
orderBy: {
|
||||
[orderByColumn]: orderByDirection,
|
||||
},
|
||||
}),
|
||||
prisma.documentAuditLog.count({
|
||||
where: { envelopeId: envelope.id },
|
||||
}),
|
||||
]);
|
||||
|
||||
const parsedData = data.map((auditLog) => parseDocumentAuditLogData(auditLog));
|
||||
|
||||
return {
|
||||
data: parsedData,
|
||||
count,
|
||||
currentPage: Math.max(page, 1),
|
||||
perPage,
|
||||
totalPages: Math.ceil(count / perPage),
|
||||
} satisfies FindResultResponse<typeof parsedData>;
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { ZDocumentAuditLogSchema } from '@documenso/lib/types/document-audit-logs';
|
||||
import { ZFindResultResponse, ZFindSearchParamsSchema } from '@documenso/lib/types/search-params';
|
||||
|
||||
export const ZFindDocumentAuditLogsRequestSchema = ZFindSearchParamsSchema.extend({
|
||||
envelopeId: z.string(),
|
||||
orderByColumn: z.enum(['createdAt']).optional(),
|
||||
orderByDirection: z.enum(['asc', 'desc']).optional(),
|
||||
});
|
||||
|
||||
export const ZFindDocumentAuditLogsResponseSchema = ZFindResultResponse.extend({
|
||||
data: ZDocumentAuditLogSchema.array(),
|
||||
});
|
||||
|
||||
export type TFindDocumentAuditLogsRequest = z.infer<typeof ZFindDocumentAuditLogsRequestSchema>;
|
||||
export type TFindDocumentAuditLogsResponse = z.infer<typeof ZFindDocumentAuditLogsResponseSchema>;
|
||||
@@ -8,6 +8,7 @@ import { deleteUserRoute } from './delete-user';
|
||||
import { disableUserRoute } from './disable-user';
|
||||
import { enableUserRoute } from './enable-user';
|
||||
import { findAdminOrganisationsRoute } from './find-admin-organisations';
|
||||
import { findDocumentAuditLogsRoute } from './find-document-audit-logs';
|
||||
import { findDocumentJobsRoute } from './find-document-jobs';
|
||||
import { findDocumentsRoute } from './find-documents';
|
||||
import { findSubscriptionClaimsRoute } from './find-subscription-claims';
|
||||
@@ -56,6 +57,7 @@ export const adminRouter = router({
|
||||
delete: deleteDocumentRoute,
|
||||
reseal: resealDocumentRoute,
|
||||
findJobs: findDocumentJobsRoute,
|
||||
findAuditLogs: findDocumentAuditLogsRoute,
|
||||
},
|
||||
recipient: {
|
||||
update: updateRecipientRoute,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { RegistrationResponseJSON } from '@simplewebauthn/types';
|
||||
import type { RegistrationResponseJSON } from '@simplewebauthn/server';
|
||||
|
||||
import { createPasskey } from '@documenso/lib/server-only/auth/create-passkey';
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { EnvelopeType } from '@prisma/client';
|
||||
|
||||
import { getServerLimits } from '@documenso/ee/server-only/limits/server';
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { createEnvelope } from '@documenso/lib/server-only/envelope/create-envelope';
|
||||
@@ -96,6 +98,7 @@ export const createEnvelopeRoute = authenticatedProcedure
|
||||
},
|
||||
originalData,
|
||||
originalMimeType,
|
||||
flattenForm: type !== EnvelopeType.TEMPLATE,
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
@@ -34,6 +34,7 @@ export const useEnvelopeRoute = authenticatedProcedure
|
||||
prefillFields,
|
||||
override,
|
||||
attachments,
|
||||
formValues,
|
||||
} = payload;
|
||||
|
||||
ctx.logger.info({
|
||||
@@ -79,7 +80,11 @@ export const useEnvelopeRoute = authenticatedProcedure
|
||||
// Process uploaded files and create document data for them
|
||||
const uploadedFiles = await Promise.all(
|
||||
filesToUpload.map(async (file) => {
|
||||
const { id: documentDataId } = await putNormalizedPdfFileServerSide({ file });
|
||||
// We disable flattening here since `createDocumentFromTemplate` will handle it.
|
||||
const { id: documentDataId } = await putNormalizedPdfFileServerSide({
|
||||
file,
|
||||
flattenForm: false,
|
||||
});
|
||||
|
||||
return {
|
||||
name: file.name,
|
||||
@@ -146,6 +151,7 @@ export const useEnvelopeRoute = authenticatedProcedure
|
||||
prefillFields,
|
||||
override,
|
||||
attachments,
|
||||
formValues,
|
||||
});
|
||||
|
||||
// Distribute document if requested
|
||||
|
||||
@@ -2,6 +2,7 @@ import { z } from 'zod';
|
||||
import { zfd } from 'zod-form-data';
|
||||
|
||||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||
import { ZDocumentFormValuesSchema } from '@documenso/lib/types/document-form-values';
|
||||
import {
|
||||
ZDocumentMetaDateFormatSchema,
|
||||
ZDocumentMetaDistributionMethodSchema,
|
||||
@@ -108,6 +109,8 @@ export const ZUseEnvelopePayloadSchema = z.object({
|
||||
}),
|
||||
)
|
||||
.optional(),
|
||||
|
||||
formValues: ZDocumentFormValuesSchema.optional(),
|
||||
});
|
||||
|
||||
export const ZUseEnvelopeRequestSchema = zodFormData({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { OrganisationType } from '@prisma/client';
|
||||
import { OrganisationType, Prisma } from '@prisma/client';
|
||||
|
||||
import { ORGANISATION_MEMBER_ROLE_PERMISSIONS_MAP } from '@documenso/lib/constants/organisations';
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
@@ -36,6 +36,7 @@ export const updateOrganisationSettingsRoute = authenticatedProcedure
|
||||
typedSignatureEnabled,
|
||||
uploadSignatureEnabled,
|
||||
drawSignatureEnabled,
|
||||
defaultRecipients,
|
||||
delegateDocumentOwnership,
|
||||
|
||||
// Branding related settings.
|
||||
@@ -145,6 +146,7 @@ export const updateOrganisationSettingsRoute = authenticatedProcedure
|
||||
typedSignatureEnabled,
|
||||
uploadSignatureEnabled,
|
||||
drawSignatureEnabled,
|
||||
defaultRecipients: defaultRecipients === null ? Prisma.DbNull : defaultRecipients,
|
||||
delegateDocumentOwnership: derivedDelegateDocumentOwnership,
|
||||
|
||||
// Branding related settings.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { SUPPORTED_LANGUAGE_CODES } from '@documenso/lib/constants/i18n';
|
||||
import { ZDefaultRecipientsSchema } from '@documenso/lib/types/default-recipients';
|
||||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||
import {
|
||||
ZDocumentMetaDateFormatSchema,
|
||||
@@ -22,6 +23,7 @@ export const ZUpdateOrganisationSettingsRequestSchema = z.object({
|
||||
typedSignatureEnabled: z.boolean().optional(),
|
||||
uploadSignatureEnabled: z.boolean().optional(),
|
||||
drawSignatureEnabled: z.boolean().optional(),
|
||||
defaultRecipients: ZDefaultRecipientsSchema.nullish(),
|
||||
delegateDocumentOwnership: z.boolean().nullish(),
|
||||
|
||||
// Branding related settings.
|
||||
|
||||
@@ -53,6 +53,8 @@ export const updateTeamSettingsRoute = authenticatedProcedure
|
||||
// emailReplyToName,
|
||||
emailDocumentSettings,
|
||||
|
||||
// Default recipients settings.
|
||||
defaultRecipients,
|
||||
// AI features settings.
|
||||
aiFeaturesEnabled,
|
||||
} = data;
|
||||
@@ -165,6 +167,7 @@ export const updateTeamSettingsRoute = authenticatedProcedure
|
||||
// emailReplyToName,
|
||||
emailDocumentSettings:
|
||||
emailDocumentSettings === null ? Prisma.DbNull : emailDocumentSettings,
|
||||
defaultRecipients: defaultRecipients === null ? Prisma.DbNull : defaultRecipients,
|
||||
|
||||
// AI features settings.
|
||||
aiFeaturesEnabled,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { SUPPORTED_LANGUAGE_CODES } from '@documenso/lib/constants/i18n';
|
||||
import { ZDefaultRecipientsSchema } from '@documenso/lib/types/default-recipients';
|
||||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||
import {
|
||||
ZDocumentMetaDateFormatSchema,
|
||||
@@ -40,6 +41,8 @@ export const ZUpdateTeamSettingsRequestSchema = z.object({
|
||||
// emailReplyToName: z.string().nullish(),
|
||||
emailDocumentSettings: ZDocumentEmailSettingsSchema.nullish(),
|
||||
|
||||
// Default recipients settings.
|
||||
defaultRecipients: ZDefaultRecipientsSchema.nullish(),
|
||||
// AI features settings.
|
||||
aiFeaturesEnabled: z.boolean().nullish(),
|
||||
}),
|
||||
|
||||
@@ -197,7 +197,10 @@ export const templateRouter = router({
|
||||
attachments,
|
||||
} = payload;
|
||||
|
||||
const { id: templateDocumentDataId } = await putNormalizedPdfFileServerSide({ file });
|
||||
const { id: templateDocumentDataId } = await putNormalizedPdfFileServerSide({
|
||||
file,
|
||||
flattenForm: false,
|
||||
});
|
||||
|
||||
ctx.logger.info({
|
||||
input: {
|
||||
@@ -468,6 +471,7 @@ export const templateRouter = router({
|
||||
externalId,
|
||||
override,
|
||||
attachments,
|
||||
formValues,
|
||||
} = input;
|
||||
|
||||
ctx.logger.info({
|
||||
@@ -507,6 +511,7 @@ export const templateRouter = router({
|
||||
externalId,
|
||||
override,
|
||||
attachments,
|
||||
formValues,
|
||||
});
|
||||
|
||||
if (distributeDocument) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
ZDocumentActionAuthTypesSchema,
|
||||
} from '@documenso/lib/types/document-auth';
|
||||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||
import { ZDocumentFormValuesSchema } from '@documenso/lib/types/document-form-values';
|
||||
import {
|
||||
ZDocumentMetaDateFormatSchema,
|
||||
ZDocumentMetaDistributionMethodSchema,
|
||||
@@ -172,6 +173,8 @@ export const ZCreateDocumentFromTemplateRequestSchema = z.object({
|
||||
}),
|
||||
)
|
||||
.optional(),
|
||||
|
||||
formValues: ZDocumentFormValuesSchema.optional(),
|
||||
});
|
||||
|
||||
export const ZCreateDocumentFromTemplateResponseSchema = ZDocumentSchema;
|
||||
|
||||
@@ -35,7 +35,7 @@ export const DocumentGlobalAuthAccessSelect = ({
|
||||
},
|
||||
...Object.values(DocumentAccessAuth).map((authType) => ({
|
||||
value: authType,
|
||||
label: DOCUMENT_AUTH_TYPES[authType].value,
|
||||
label: _(DOCUMENT_AUTH_TYPES[authType].value),
|
||||
})),
|
||||
];
|
||||
|
||||
@@ -79,7 +79,7 @@ export const DocumentGlobalAuthAccessTooltip = () => (
|
||||
<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 access</Trans>
|
||||
|
||||
@@ -35,7 +35,7 @@ export const DocumentGlobalAuthActionSelect = ({
|
||||
.filter((auth) => auth !== DocumentAuth.ACCOUNT)
|
||||
.map((authType) => ({
|
||||
value: authType,
|
||||
label: DOCUMENT_AUTH_TYPES[authType].value,
|
||||
label: _(DOCUMENT_AUTH_TYPES[authType].value),
|
||||
})),
|
||||
];
|
||||
|
||||
@@ -79,7 +79,7 @@ export const DocumentGlobalAuthActionTooltip = () => (
|
||||
<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>
|
||||
<Trans>Global recipient action authentication</Trans>
|
||||
</h2>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React, { forwardRef } from 'react';
|
||||
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { TeamMemberRole } from '@prisma/client';
|
||||
import type { SelectProps } from '@radix-ui/react-select';
|
||||
import { InfoIcon } from 'lucide-react';
|
||||
@@ -28,7 +30,7 @@ export const DocumentVisibilitySelect = forwardRef<HTMLButtonElement, DocumentVi
|
||||
{ currentTeamMemberRole, isTeamSettings = false, disabled, canUpdateVisibility, ...props },
|
||||
ref,
|
||||
) => {
|
||||
const { t } = useLingui();
|
||||
const { _ } = useLingui();
|
||||
|
||||
const isAdmin = currentTeamMemberRole === TeamMemberRole.ADMIN;
|
||||
const isManager = currentTeamMemberRole === TeamMemberRole.MANAGER;
|
||||
@@ -42,16 +44,16 @@ export const DocumentVisibilitySelect = forwardRef<HTMLButtonElement, DocumentVi
|
||||
|
||||
<SelectContent position="popper">
|
||||
<SelectItem value={DocumentVisibility.EVERYONE}>
|
||||
{DOCUMENT_VISIBILITY.EVERYONE.value}
|
||||
{_(DOCUMENT_VISIBILITY.EVERYONE.value)}
|
||||
</SelectItem>
|
||||
<SelectItem
|
||||
value={DocumentVisibility.MANAGER_AND_ABOVE}
|
||||
disabled={!isAdmin && !isManager}
|
||||
>
|
||||
{DOCUMENT_VISIBILITY.MANAGER_AND_ABOVE.value}
|
||||
{_(DOCUMENT_VISIBILITY.MANAGER_AND_ABOVE.value)}
|
||||
</SelectItem>
|
||||
<SelectItem value={DocumentVisibility.ADMIN} disabled={!isAdmin}>
|
||||
{DOCUMENT_VISIBILITY.ADMIN.value}
|
||||
{_(DOCUMENT_VISIBILITY.ADMIN.value)}
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
@@ -68,7 +70,7 @@ export const DocumentVisibilityTooltip = () => {
|
||||
<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 visibility</Trans>
|
||||
|
||||
@@ -39,7 +39,7 @@ export const RecipientActionAuthSelect = ({
|
||||
.filter((auth) => auth !== RecipientActionAuth.ACCOUNT)
|
||||
.map((authType) => ({
|
||||
value: authType,
|
||||
label: DOCUMENT_AUTH_TYPES[authType].value,
|
||||
label: _(DOCUMENT_AUTH_TYPES[authType].value),
|
||||
})),
|
||||
];
|
||||
|
||||
@@ -83,7 +83,7 @@ export const RecipientActionAuthSelect = ({
|
||||
<InfoIcon className="h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
|
||||
<TooltipContent className="text-foreground max-w-md p-4">
|
||||
<TooltipContent className="max-w-md p-4 text-foreground">
|
||||
<h2>
|
||||
<strong>
|
||||
<Trans>Recipient action authentication</Trans>
|
||||
|
||||
@@ -67,13 +67,13 @@
|
||||
"lucide-react": "^0.554.0",
|
||||
"luxon": "^3.7.2",
|
||||
"perfect-freehand": "^1.2.2",
|
||||
"pdfjs-dist": "5.4.449",
|
||||
"pdfjs-dist": "5.4.296",
|
||||
"react": "^18",
|
||||
"react-colorful": "^5.6.1",
|
||||
"react-day-picker": "^8.10.1",
|
||||
"react-dom": "^18",
|
||||
"react-hook-form": "^7.66.1",
|
||||
"react-pdf": "^10.2.0",
|
||||
"react-pdf": "^10.3.0",
|
||||
"react-rnd": "^10.5.2",
|
||||
"remeda": "^2.32.0",
|
||||
"tailwind-merge": "^1.14.0",
|
||||
@@ -81,4 +81,4 @@
|
||||
"ts-pattern": "^5.9.0",
|
||||
"zod": "^3.25.76"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,7 +572,7 @@ export const AddSignersFormPartial = ({
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<span className="text-muted-foreground ml-1 cursor-help">
|
||||
<span className="ml-1 cursor-help text-muted-foreground">
|
||||
<HelpCircle className="h-3.5 w-3.5" />
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
@@ -615,7 +615,7 @@ export const AddSignersFormPartial = ({
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<span className="text-muted-foreground ml-1 cursor-help">
|
||||
<span className="ml-1 cursor-help text-muted-foreground">
|
||||
<HelpCircle className="h-3.5 w-3.5" />
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
@@ -666,7 +666,7 @@ export const AddSignersFormPartial = ({
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
className={cn('py-1', {
|
||||
'bg-widget-foreground pointer-events-none rounded-md pt-2':
|
||||
'pointer-events-none rounded-md bg-widget-foreground pt-2':
|
||||
snapshot.isDragging,
|
||||
})}
|
||||
>
|
||||
@@ -946,7 +946,7 @@ export const AddSignersFormPartial = ({
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
className="dark:bg-muted dark:hover:bg-muted/80 bg-black/5 hover:bg-black/10"
|
||||
className="bg-black/5 hover:bg-black/10 dark:bg-muted dark:hover:bg-muted/80"
|
||||
disabled={isSubmitting || isUserAlreadyARecipient}
|
||||
onClick={() => onAddSelfSigner()}
|
||||
>
|
||||
@@ -965,7 +965,7 @@ export const AddSignersFormPartial = ({
|
||||
/>
|
||||
|
||||
<label
|
||||
className="text-muted-foreground ml-2 text-sm"
|
||||
className="ml-2 text-sm text-muted-foreground"
|
||||
htmlFor="showAdvancedRecipientSettings"
|
||||
>
|
||||
<Trans>Show advanced settings</Trans>
|
||||
|
||||
Reference in New Issue
Block a user