feat: add option to disable Document created from template (#2609)

This commit is contained in:
Catalin Pit 2026-03-23 06:11:42 +02:00 committed by GitHub
parent ace472c294
commit 5be71cca21
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 72 additions and 9 deletions

View file

@ -219,7 +219,8 @@ export const EmailPreferencesForm = ({
<FormDescription>
<Trans>
Controls the default email settings when new documents or templates are created
Controls the default email settings when new documents or templates are created.
Updating these settings will not affect existing documents or templates.
</Trans>
</FormDescription>
</FormItem>

View file

@ -209,6 +209,7 @@ test.describe('API V2 Envelopes', () => {
documentDeleted: false,
ownerRecipientExpired: true,
ownerDocumentCompleted: true,
ownerDocumentCreated: true,
},
},
attachments: [

View file

@ -54,6 +54,7 @@ const DB_EXPECTED_VALUES = {
documentDeleted: false,
ownerDocumentCompleted: false,
ownerRecipientExpired: false,
ownerDocumentCreated: false,
},
};
@ -138,6 +139,7 @@ const runSettingsFlow = async (
await root.locator('#documentDeleted').click();
await root.locator('#ownerDocumentCompleted').click();
await root.locator('#ownerRecipientExpired').click();
await root.locator('#ownerDocumentCreated').click();
await root.locator('input[name="meta.emailReplyTo"]').fill(TEST_SETTINGS_VALUES.replyTo);
await root.locator('input[name="meta.subject"]').fill(TEST_SETTINGS_VALUES.subject);
await root.locator('textarea[name="meta.message"]').fill(TEST_SETTINGS_VALUES.message);
@ -207,6 +209,7 @@ const runSettingsFlow = async (
await expect(root.locator('#documentDeleted')).toHaveAttribute('aria-checked', 'false');
await expect(root.locator('#ownerDocumentCompleted')).toHaveAttribute('aria-checked', 'false');
await expect(root.locator('#ownerRecipientExpired')).toHaveAttribute('aria-checked', 'false');
await expect(root.locator('#ownerDocumentCreated')).toHaveAttribute('aria-checked', 'false');
await expect(root.locator('input[name="meta.emailReplyTo"]')).toHaveValue(
TEST_SETTINGS_VALUES.replyTo,
);

View file

@ -231,6 +231,7 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
documentDeleted: false, // unchecked
ownerRecipientExpired: true,
ownerDocumentCompleted: true,
ownerDocumentCreated: true,
});
// Edit the team email settings
@ -271,6 +272,7 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
documentDeleted: true,
ownerRecipientExpired: true,
ownerDocumentCompleted: false,
ownerDocumentCreated: true,
});
// Verify that a document can be created successfully with the team email settings
@ -292,6 +294,7 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
documentDeleted: true,
ownerRecipientExpired: true,
ownerDocumentCompleted: false,
ownerDocumentCreated: true,
});
// Test inheritance by setting team back to inherit from organisation
@ -318,6 +321,7 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
documentDeleted: false,
ownerRecipientExpired: true,
ownerDocumentCompleted: true,
ownerDocumentCreated: true,
});
// Verify that a document can be created successfully with the email settings
@ -339,5 +343,6 @@ test('[ORGANISATIONS]: manage email preferences', async ({ page }) => {
documentDeleted: false,
ownerRecipientExpired: true,
ownerDocumentCompleted: true,
ownerDocumentCreated: true,
});
});

View file

@ -24,6 +24,7 @@ import { jobs } from '../../jobs/client';
import { DOCUMENT_AUDIT_LOG_TYPE, RECIPIENT_DIFF_TYPE } from '../../types/document-audit-logs';
import type { TRecipientActionAuthTypes } from '../../types/document-auth';
import { DocumentAccessAuth, ZRecipientAuthOptionsSchema } from '../../types/document-auth';
import { extractDerivedDocumentEmailSettings } from '../../types/document-email';
import { ZFieldMetaSchema } from '../../types/field-meta';
import {
ZWebhookDocumentSchema,
@ -743,14 +744,17 @@ export const createDocumentFromDirectTemplate = async ({
};
});
// Send email to template owner via background job.
await jobs.triggerJob({
name: 'send.document.created.from.direct.template.email',
payload: {
envelopeId: createdEnvelope.id,
recipientId,
},
});
const emailSettings = extractDerivedDocumentEmailSettings(documentMeta);
if (emailSettings.ownerDocumentCreated) {
await jobs.triggerJob({
name: 'send.document.created.from.direct.template.email',
payload: {
envelopeId: createdEnvelope.id,
recipientId,
},
});
}
try {
// This handles sending emails and sealing the document if required.

View file

@ -440,6 +440,7 @@ export const generateSampleWebhookPayload = (
documentCompleted: true,
ownerDocumentCompleted: true,
ownerRecipientExpired: true,
ownerDocumentCreated: true,
recipientSigningRequest: true,
},
},

View file

@ -11,6 +11,7 @@ export enum DocumentEmailEvents {
DocumentDeleted = 'documentDeleted',
OwnerDocumentCompleted = 'ownerDocumentCompleted',
OwnerRecipientExpired = 'ownerRecipientExpired',
OwnerDocumentCreated = 'ownerDocumentCreated',
}
export const ZDocumentEmailSettingsSchema = z
@ -59,6 +60,12 @@ export const ZDocumentEmailSettingsSchema = z
"Whether to send an email to the document owner when a recipient's signing window has expired.",
)
.default(true),
ownerDocumentCreated: z
.boolean()
.describe(
'Whether to send an email to the document owner when a document is created from a direct template.',
)
.default(true),
})
.strip()
.catch(() => ({ ...DEFAULT_DOCUMENT_EMAIL_SETTINGS }));
@ -86,6 +93,7 @@ export const extractDerivedDocumentEmailSettings = (
documentDeleted: false,
ownerDocumentCompleted: emailSettings.ownerDocumentCompleted,
ownerRecipientExpired: emailSettings.ownerRecipientExpired,
ownerDocumentCreated: emailSettings.ownerDocumentCreated,
};
};
@ -98,4 +106,5 @@ export const DEFAULT_DOCUMENT_EMAIL_SETTINGS: TDocumentEmailSettings = {
documentDeleted: true,
ownerDocumentCompleted: true,
ownerRecipientExpired: true,
ownerDocumentCreated: true,
};

View file

@ -291,6 +291,45 @@ export const DocumentEmailCheckboxes = ({
</label>
</div>
<div className="flex flex-row items-center">
<Checkbox
id={DocumentEmailEvents.OwnerDocumentCreated}
className="h-5 w-5"
checked={value.ownerDocumentCreated}
onCheckedChange={(checked) =>
onChange({ ...value, [DocumentEmailEvents.OwnerDocumentCreated]: Boolean(checked) })
}
/>
<label
className="ml-2 flex flex-row items-center text-sm text-muted-foreground"
htmlFor={DocumentEmailEvents.OwnerDocumentCreated}
>
<Trans>Email the owner when a document is created from a direct template</Trans>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
<h2>
<strong>
<Trans>Document created from direct template email</Trans>
</strong>
</h2>
<p>
<Trans>
This email is sent to the document owner when a recipient creates a document via a
direct template link.
</Trans>
</p>
</TooltipContent>
</Tooltip>
</label>
</div>
<div className="flex flex-row items-center">
<Checkbox
id={DocumentEmailEvents.OwnerRecipientExpired}