-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: download doc without signing certificate #1477
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Skipped Deployment
|
WalkthroughThe changes in this pull request introduce a new boolean field, Changes
Possibly related PRs
Suggested reviewers
Warning There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure. 🔧 eslint (1.23.1)
packages/lib/server-only/htmltopdf/get-certificate-pdf.tsOops! Something went wrong! :( ESLint: 8.57.1 ESLint couldn't find the config "@documenso/eslint-config" to extend from. Please check that the name of the config is correct. The config "@documenso/eslint-config" was referenced from the config file in "/.eslintrc.cjs". If you still have problems, please stop by https://eslint.org/chat/help to chat with the team. Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
🚨 @catalinpit has 7 pull requests awaiting review. Please consider reviewing them when possible. 🚨 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 2 out of 2 changed files in this pull request and generated no suggestions.
🚨 @catalinpit has 6 pull requests awaiting review. Please consider reviewing them when possible. 🚨 |
@@ -127,7 +136,11 @@ export const SEAL_DOCUMENT_JOB_DEFINITION = { | |||
flattenForm(pdfDoc); | |||
flattenAnnotations(pdfDoc); | |||
|
|||
if (certificateData) { | |||
if ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably could have been a ternary on certificateData
e.g.
const certificateData =
document.team?.teamGlobalSettings?.includeSignerCertificate === false
? null
: await getCertificatePdf({ documentId }).catch(() => null);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then you wouldn't need the below which seems like it would break on individual documents anyways 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (2)
packages/lib/server-only/htmltopdf/get-certificate-pdf.ts (2)
10-11
: Justify the ESLint disable commentThe
@typescript-eslint/ban-types
disable comment needs explanation. Consider adding a comment explaining why this exception is necessary, or explore alternative type definitions that don't require disabling the lint rule.
42-43
: Add logging for invalid language codesWhen an invalid language code is provided, it silently falls back to 'en'. Consider adding debug logging to help track such occurrences.
- const lang = isValidLanguageCode(language) ? language : 'en'; + const lang = isValidLanguageCode(language) ? language : 'en'; + if (language && !isValidLanguageCode(language)) { + console.debug(`Invalid language code provided: ${language}, falling back to 'en'`); + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (3)
packages/lib/jobs/definitions/internal/seal-document.ts
(2 hunks)packages/lib/server-only/document/seal-document.ts
(3 hunks)packages/lib/server-only/htmltopdf/get-certificate-pdf.ts
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/lib/jobs/definitions/internal/seal-document.ts
- packages/lib/server-only/document/seal-document.ts
🔇 Additional comments (1)
packages/lib/server-only/htmltopdf/get-certificate-pdf.ts (1)
Line range hint 14-66
: Verify the necessity of certificate generation
Based on the PR objectives, this function should only be called when signing certificates are required. Let's verify that the calling code properly handles this condition.
✅ Verification successful
Let me gather more context about the condition check.
Certificate generation is properly conditioned by team settings
The code correctly checks document.team?.teamGlobalSettings?.includeSigningCertificate
with a fallback to true
before calling getCertificatePdf
. This ensures certificates are only generated when required by the team's settings.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for calls to getCertificatePdf to ensure they respect the includeSigningCertificate setting
rg -A 5 "getCertificatePdf" | grep -v "get-certificate-pdf.ts"
# Search for the condition check before calling this function
ast-grep --pattern 'if ($CONDITION) {
$$$
getCertificatePdf($$$)
$$$
}'
Length of output: 2674
Script:
#!/bin/bash
# Search for the condition that determines if certificate generation is needed
rg -B 5 -A 2 "getCertificatePdf\(" packages/lib/server-only/document/seal-document.ts packages/lib/jobs/definitions/internal/seal-document.ts
Length of output: 1598
if (language) { | ||
await page.context().addCookies([ | ||
{ | ||
name: 'language', | ||
value: language, | ||
value: lang, | ||
url: NEXT_PUBLIC_WEBAPP_URL(), | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Optimize language cookie setting logic
The code sets the language cookie even when the provided language is invalid. Consider only setting the cookie when we have a valid language code.
- if (language) {
+ if (language && isValidLanguageCode(language)) {
await page.context().addCookies([
{
name: 'language',
value: lang,
url: NEXT_PUBLIC_WEBAPP_URL(),
},
]);
}
Committable suggestion skipped: line range outside the PR's diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (2)
packages/app-tests/e2e/features/include-document-certificate.spec.ts (2)
157-232
: Improve test reliability by using explicit wait conditionsThe test relies on implicit timing which could lead to flaky tests.
Consider using explicit wait conditions instead of relying on URL changes:
- await page.waitForURL(`/sign/${recipient.token}/complete`); + await Promise.all([ + page.waitForURL(`/sign/${recipient.token}/complete`), + page.waitForResponse(response => + response.url().includes('/api/documents') && + response.status() === 200 + ) + ]);
1-271
: Good test coverage with room for improvementThe tests comprehensively cover the signing certificate feature, including both individual and team document scenarios. While functional, the implementation could benefit from:
- Helper functions to reduce code duplication
- More robust wait conditions instead of timeouts
- Better error handling for canvas interactions
- Additional edge cases:
- Document with multiple signers
- Handling of large documents
- Network error scenarios
Consider creating a shared test utilities file for common operations like document signing simulation and status verification.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
package-lock.json
is excluded by!**/package-lock.json
📒 Files selected for processing (2)
packages/app-tests/e2e/features/include-document-certificate.spec.ts
(1 hunks)packages/app-tests/package.json
(1 hunks)
🔇 Additional comments (3)
packages/app-tests/package.json (2)
17-20
: Review dependency versioning strategy
A few observations about the dependencies:
- Internal dependencies (@documenso/*) use * which is typical for monorepos
- pdf-lib is pinned to ^1.17.1 which is good for external dependencies
Let's verify if pdf-lib version is the latest stable and check for any security advisories:
✅ Verification successful
Dependency version is up-to-date and secure
The version of pdf-lib (^1.17.1) used in the project is:
- Currently the latest stable version available on npm
- Has no known security vulnerabilities according to GitHub's advisory database
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check latest version and security advisories for pdf-lib
# Check NPM for latest versions
curl -s https://registry.npmjs.org/pdf-lib | jq '.["dist-tags"].latest'
# Check for security advisories
gh api graphql -f query='
{
securityVulnerabilities(first: 5, ecosystem: NPM, package: "pdf-lib") {
nodes {
advisory {
summary
severity
publishedAt
}
vulnerableVersionRange
firstPatchedVersion {
identifier
}
}
}
}'
Length of output: 423
10-10
: LGTM: Test script enhancement
The addition of $E2E_TEST_PATH
variable allows for more flexible test execution by enabling specific test file targeting.
Let's verify the existence of the referenced E2E tests:
✅ Verification successful
E2E tests are present and properly implemented
The review comment's concern has been addressed as there are comprehensive E2E tests for the document certificate functionality in packages/app-tests/e2e/features/include-document-certificate.spec.ts
. The tests cover:
- Individual documents with signing certificates
- Team documents with signing certificates enabled/disabled
- Team settings for toggling signing certificates
The $E2E_TEST_PATH
variable in the test script is well justified as it allows running specific test files, which is particularly useful for these new certificate-related tests.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for E2E test files related to document certificate functionality
# Look for E2E test files
fd . "packages/app-tests/e2e" -e ts -e tsx
Length of output: 1508
Script:
#!/bin/bash
# Let's check the content of the include-document-certificate.spec.ts file
cat "packages/app-tests/e2e/features/include-document-certificate.spec.ts"
Length of output: 8808
packages/app-tests/e2e/features/include-document-certificate.spec.ts (1)
1-13
: LGTM! Well-organized imports
The imports are properly organized, separating external dependencies from internal ones.
test('team document with signing certificate enabled should include certificate', async ({ | ||
page, | ||
}) => { | ||
const team = await seedTeam(); | ||
|
||
const { document, recipients } = await seedPendingDocumentWithFullFields({ | ||
owner: team.owner, | ||
recipients: ['signer@example.com'], | ||
fields: [FieldType.SIGNATURE], | ||
updateDocumentOptions: { | ||
teamId: team.id, | ||
}, | ||
}); | ||
|
||
await prisma.teamGlobalSettings.create({ | ||
data: { | ||
teamId: team.id, | ||
includeSigningCertificate: true, | ||
}, | ||
}); | ||
|
||
const documentData = await prisma.documentData | ||
.findFirstOrThrow({ | ||
where: { | ||
id: document.documentDataId, | ||
}, | ||
}) | ||
.then(async (data) => getFile(data)); | ||
|
||
const originalPdf = await PDFDocument.load(documentData); | ||
|
||
const recipient = recipients[0]; | ||
|
||
// Sign the document | ||
await page.goto(`/sign/${recipient.token}`); | ||
|
||
const canvas = page.locator('canvas'); | ||
const box = await canvas.boundingBox(); | ||
if (box) { | ||
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2); | ||
await page.mouse.down(); | ||
await page.mouse.move(box.x + box.width / 4, box.y + box.height / 4); | ||
await page.mouse.up(); | ||
} | ||
|
||
for (const field of recipient.Field) { | ||
await page.locator(`#field-${field.id}`).getByRole('button').click(); | ||
|
||
await expect(page.locator(`#field-${field.id}`)).toHaveAttribute('data-inserted', 'true'); | ||
} | ||
|
||
await page.getByRole('button', { name: 'Complete' }).click(); | ||
await page.getByRole('button', { name: 'Sign' }).click(); | ||
await page.waitForURL(`/sign/${recipient.token}/complete`); | ||
|
||
await expect(async () => { | ||
const { status } = await getDocumentByToken({ | ||
token: recipient.token, | ||
}); | ||
|
||
expect(status).toBe(DocumentStatus.COMPLETED); | ||
}).toPass(); | ||
|
||
// Get the completed document | ||
const completedDocument = await prisma.document.findFirstOrThrow({ | ||
where: { id: document.id }, | ||
include: { documentData: true }, | ||
}); | ||
|
||
const completedDocumentData = await getFile(completedDocument.documentData); | ||
|
||
// Load the PDF and check number of pages | ||
const completedPdf = await PDFDocument.load(completedDocumentData); | ||
|
||
expect(completedPdf.getPageCount()).toBe(originalPdf.getPageCount() + 1); // Original + Certificate | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Reduce code duplication by extracting common test logic
There's significant duplication in the document signing simulation logic across all tests.
Consider extracting common functionality into helper functions:
async function simulateSignature(page: Page, canvas: Locator) {
await canvas.waitFor({ state: 'visible' });
const box = await canvas.boundingBox();
if (!box) {
throw new Error('Canvas not found');
}
// Signature simulation logic...
}
async function completeDocumentSigning(page: Page, recipient: any) {
await page.goto(`/sign/${recipient.token}`);
// Sign document
await simulateSignature(page, page.locator('canvas'));
// Fill fields
for (const field of recipient.Field) {
await page.locator(`#field-${field.id}`).getByRole('button').click();
await expect(page.locator(`#field-${field.id}`)).toHaveAttribute('data-inserted', 'true');
}
// Complete signing
await page.getByRole('button', { name: 'Complete' }).click();
await page.getByRole('button', { name: 'Sign' }).click();
await page.waitForURL(`/sign/${recipient.token}/complete`);
}
async function verifyDocumentStatus(recipient: any) {
await expect(async () => {
const { status } = await getDocumentByToken({ token: recipient.token });
expect(status).toBe(DocumentStatus.COMPLETED);
}).toPass();
}
test('team can toggle signing certificate setting', async ({ page }) => { | ||
const team = await seedTeam(); | ||
|
||
await apiSignin({ | ||
page, | ||
email: team.owner.email, | ||
redirectPath: `/t/${team.url}/settings/preferences`, | ||
}); | ||
|
||
// Toggle signing certificate setting | ||
await page.getByLabel('Include the Signing Certificate in the Document').click(); | ||
await page.getByRole('button', { name: /Save/ }).first().click(); | ||
|
||
await page.waitForTimeout(1000); | ||
|
||
// Verify the setting was saved | ||
const updatedTeam = await prisma.team.findFirstOrThrow({ | ||
where: { id: team.id }, | ||
include: { teamGlobalSettings: true }, | ||
}); | ||
|
||
expect(updatedTeam.teamGlobalSettings?.includeSigningCertificate).toBe(false); | ||
|
||
// Toggle the setting back to true | ||
await page.getByLabel('Include the Signing Certificate in the Document').click(); | ||
await page.getByRole('button', { name: /Save/ }).first().click(); | ||
|
||
await page.waitForTimeout(1000); | ||
|
||
// Verify the setting was saved | ||
const updatedTeam2 = await prisma.team.findFirstOrThrow({ | ||
where: { id: team.id }, | ||
include: { teamGlobalSettings: true }, | ||
}); | ||
|
||
expect(updatedTeam2.teamGlobalSettings?.includeSigningCertificate).toBe(true); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Replace arbitrary timeouts with proper wait conditions
The test uses waitForTimeout
which could make it flaky.
Consider using network or state conditions instead:
- await page.waitForTimeout(1000);
+ await page.waitForResponse(response =>
+ response.url().includes('/api/teams') &&
+ response.status() === 200
+ );
Also, consider adding assertions for the UI state:
await expect(
page.getByLabel('Include the Signing Certificate in the Document')
).toBeChecked({ checked: false });
test('individual document should always include signing certificate', async ({ page }) => { | ||
const user = await seedUser(); | ||
|
||
const { document, recipients } = await seedPendingDocumentWithFullFields({ | ||
owner: user, | ||
recipients: ['signer@example.com'], | ||
fields: [FieldType.SIGNATURE], | ||
}); | ||
|
||
const documentData = await prisma.documentData | ||
.findFirstOrThrow({ | ||
where: { | ||
id: document.documentDataId, | ||
}, | ||
}) | ||
.then(async (data) => getFile(data)); | ||
|
||
const originalPdf = await PDFDocument.load(documentData); | ||
|
||
const recipient = recipients[0]; | ||
|
||
// Sign the document | ||
await page.goto(`/sign/${recipient.token}`); | ||
|
||
const canvas = page.locator('canvas'); | ||
const box = await canvas.boundingBox(); | ||
if (box) { | ||
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2); | ||
await page.mouse.down(); | ||
await page.mouse.move(box.x + box.width / 4, box.y + box.height / 4); | ||
await page.mouse.up(); | ||
} | ||
|
||
for (const field of recipient.Field) { | ||
await page.locator(`#field-${field.id}`).getByRole('button').click(); | ||
|
||
await expect(page.locator(`#field-${field.id}`)).toHaveAttribute('data-inserted', 'true'); | ||
} | ||
|
||
await page.getByRole('button', { name: 'Complete' }).click(); | ||
await page.getByRole('button', { name: 'Sign' }).click(); | ||
await page.waitForURL(`/sign/${recipient.token}/complete`); | ||
|
||
await expect(async () => { | ||
const { status } = await getDocumentByToken({ | ||
token: recipient.token, | ||
}); | ||
|
||
expect(status).toBe(DocumentStatus.COMPLETED); | ||
}).toPass(); | ||
|
||
// Get the completed document | ||
const completedDocument = await prisma.document.findFirstOrThrow({ | ||
where: { id: document.id }, | ||
include: { documentData: true }, | ||
}); | ||
|
||
const completedDocumentData = await getFile(completedDocument.documentData); | ||
|
||
// Load the PDF and check number of pages | ||
const pdfDoc = await PDFDocument.load(completedDocumentData); | ||
|
||
expect(pdfDoc.getPageCount()).toBe(originalPdf.getPageCount() + 1); // Original + Certificate | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider making canvas interaction more robust
The canvas interaction for signature simulation might be flaky due to timing and positioning issues.
Consider these improvements:
- const box = await canvas.boundingBox();
- if (box) {
- await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
- await page.mouse.down();
- await page.mouse.move(box.x + box.width / 4, box.y + box.height / 4);
- await page.mouse.up();
- }
+ await canvas.waitFor({ state: 'visible' });
+ const box = await canvas.boundingBox();
+ if (!box) {
+ throw new Error('Canvas not found');
+ }
+
+ // Center point
+ const centerX = box.x + box.width / 2;
+ const centerY = box.y + box.height / 2;
+
+ await page.mouse.move(centerX, centerY);
+ await page.mouse.down();
+ await page.waitForTimeout(100); // Ensure mouse down is registered
+
+ // Draw signature
+ const endX = box.x + box.width / 4;
+ const endY = box.y + box.height / 4;
+ await page.mouse.move(endX, endY);
+ await page.waitForTimeout(100); // Ensure movement is registered
+ await page.mouse.up();
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
test('individual document should always include signing certificate', async ({ page }) => { | |
const user = await seedUser(); | |
const { document, recipients } = await seedPendingDocumentWithFullFields({ | |
owner: user, | |
recipients: ['signer@example.com'], | |
fields: [FieldType.SIGNATURE], | |
}); | |
const documentData = await prisma.documentData | |
.findFirstOrThrow({ | |
where: { | |
id: document.documentDataId, | |
}, | |
}) | |
.then(async (data) => getFile(data)); | |
const originalPdf = await PDFDocument.load(documentData); | |
const recipient = recipients[0]; | |
// Sign the document | |
await page.goto(`/sign/${recipient.token}`); | |
const canvas = page.locator('canvas'); | |
const box = await canvas.boundingBox(); | |
if (box) { | |
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2); | |
await page.mouse.down(); | |
await page.mouse.move(box.x + box.width / 4, box.y + box.height / 4); | |
await page.mouse.up(); | |
} | |
for (const field of recipient.Field) { | |
await page.locator(`#field-${field.id}`).getByRole('button').click(); | |
await expect(page.locator(`#field-${field.id}`)).toHaveAttribute('data-inserted', 'true'); | |
} | |
await page.getByRole('button', { name: 'Complete' }).click(); | |
await page.getByRole('button', { name: 'Sign' }).click(); | |
await page.waitForURL(`/sign/${recipient.token}/complete`); | |
await expect(async () => { | |
const { status } = await getDocumentByToken({ | |
token: recipient.token, | |
}); | |
expect(status).toBe(DocumentStatus.COMPLETED); | |
}).toPass(); | |
// Get the completed document | |
const completedDocument = await prisma.document.findFirstOrThrow({ | |
where: { id: document.id }, | |
include: { documentData: true }, | |
}); | |
const completedDocumentData = await getFile(completedDocument.documentData); | |
// Load the PDF and check number of pages | |
const pdfDoc = await PDFDocument.load(completedDocumentData); | |
expect(pdfDoc.getPageCount()).toBe(originalPdf.getPageCount() + 1); // Original + Certificate | |
}); | |
test('individual document should always include signing certificate', async ({ page }) => { | |
const user = await seedUser(); | |
const { document, recipients } = await seedPendingDocumentWithFullFields({ | |
owner: user, | |
recipients: ['signer@example.com'], | |
fields: [FieldType.SIGNATURE], | |
}); | |
const documentData = await prisma.documentData | |
.findFirstOrThrow({ | |
where: { | |
id: document.documentDataId, | |
}, | |
}) | |
.then(async (data) => getFile(data)); | |
const originalPdf = await PDFDocument.load(documentData); | |
const recipient = recipients[0]; | |
// Sign the document | |
await page.goto(`/sign/${recipient.token}`); | |
const canvas = page.locator('canvas'); | |
await canvas.waitFor({ state: 'visible' }); | |
const box = await canvas.boundingBox(); | |
if (!box) { | |
throw new Error('Canvas not found'); | |
} | |
// Center point | |
const centerX = box.x + box.width / 2; | |
const centerY = box.y + box.height / 2; | |
await page.mouse.move(centerX, centerY); | |
await page.mouse.down(); | |
await page.waitForTimeout(100); // Ensure mouse down is registered | |
// Draw signature | |
const endX = box.x + box.width / 4; | |
const endY = box.y + box.height / 4; | |
await page.mouse.move(endX, endY); | |
await page.waitForTimeout(100); // Ensure movement is registered | |
await page.mouse.up(); | |
for (const field of recipient.Field) { | |
await page.locator(`#field-${field.id}`).getByRole('button').click(); | |
await expect(page.locator(`#field-${field.id}`)).toHaveAttribute('data-inserted', 'true'); | |
} | |
await page.getByRole('button', { name: 'Complete' }).click(); | |
await page.getByRole('button', { name: 'Sign' }).click(); | |
await page.waitForURL(`/sign/${recipient.token}/complete`); | |
await expect(async () => { | |
const { status } = await getDocumentByToken({ | |
token: recipient.token, | |
}); | |
expect(status).toBe(DocumentStatus.COMPLETED); | |
}).toPass(); | |
// Get the completed document | |
const completedDocument = await prisma.document.findFirstOrThrow({ | |
where: { id: document.id }, | |
include: { documentData: true }, | |
}); | |
const completedDocumentData = await getFile(completedDocument.documentData); | |
// Load the PDF and check number of pages | |
const pdfDoc = await PDFDocument.load(completedDocumentData); | |
expect(pdfDoc.getPageCount()).toBe(originalPdf.getPageCount() + 1); // Original + Certificate | |
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (2)
packages/lib/translations/en/web.po (2)
1055-1057
: Improve clarity of signing certificate messageThe message about signing certificate inclusion could be clearer and more concise.
-msgid "Controls whether the signing certificate will be included in the document when it is downloaded. The signing certificate can still be downloaded from the logs page separately." +msgid "Controls whether to include the signing certificate in downloaded documents. The certificate can still be downloaded separately from the logs page."
1043-1051
: Improve document preferences messagesThe document preferences messages could be more concise while maintaining clarity.
-msgid "Controls the default language of an uploaded document. This will be used as the language in email communications with the recipients." +msgid "Sets the default document language, which will be used in recipient email communications." -msgid "Controls the default visibility of an uploaded document." +msgid "Sets who can view uploaded documents by default."
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (5)
packages/lib/server-only/htmltopdf/get-certificate-pdf.ts
(2 hunks)packages/lib/translations/de/web.po
(32 hunks)packages/lib/translations/en/web.po
(32 hunks)packages/lib/translations/es/web.po
(32 hunks)packages/lib/translations/fr/web.po
(32 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- packages/lib/server-only/htmltopdf/get-certificate-pdf.ts
- packages/lib/translations/de/web.po
- packages/lib/translations/es/web.po
- packages/lib/translations/fr/web.po
@@ -785,7 +785,7 @@ msgstr "Bulk Copy" | |||
msgid "Bulk Import" | |||
msgstr "Bulk Import" | |||
|
|||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:156 | |||
#: apps/web/src/app/(dashboard)/documents/delete-document-dialog.tsx:158 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Standardize document deletion messages
The document deletion messages have inconsistent formatting and wording across different contexts.
Standardize the messages to use consistent language:
-msgid "All inserted signatures will be voided"
+msgid "All signatures will be voided"
-msgid "All recipients will be notified"
+msgid "All recipients will receive a notification"
-msgid "Once confirmed, the following will occur:"
+msgid "The following actions will occur:"
-msgid "Please note that this action is <0>irreversible</0>."
+msgid "This action cannot be undone."
-msgid "Please note that this action is <0>irreversible</0>. Once confirmed, this document will be permanently deleted."
+msgid "This action cannot be undone. The document will be permanently deleted."
Also applies to: 809-809, 2521-2521, 2713-2713, 2717-2717
Description
I added the option of downloading a document without the signing certificate for teams. They can disable/enable the option in the preferences tab.
The signing certificate can still be downloaded separately from the
logs
page.Checklist
Summary by CodeRabbit
New Features
Bug Fixes
Translations