diff --git a/apps/remix/app/components/forms/email-preferences-form.tsx b/apps/remix/app/components/forms/email-preferences-form.tsx index 2dd992676..649d67f7a 100644 --- a/apps/remix/app/components/forms/email-preferences-form.tsx +++ b/apps/remix/app/components/forms/email-preferences-form.tsx @@ -219,7 +219,8 @@ export const EmailPreferencesForm = ({ - 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. diff --git a/packages/app-tests/e2e/api/v2/envelopes-api.spec.ts b/packages/app-tests/e2e/api/v2/envelopes-api.spec.ts index ffabac913..27710c6f4 100644 --- a/packages/app-tests/e2e/api/v2/envelopes-api.spec.ts +++ b/packages/app-tests/e2e/api/v2/envelopes-api.spec.ts @@ -209,6 +209,7 @@ test.describe('API V2 Envelopes', () => { documentDeleted: false, ownerRecipientExpired: true, ownerDocumentCompleted: true, + ownerDocumentCreated: true, }, }, attachments: [ diff --git a/packages/app-tests/e2e/envelope-editor-v2/envelope-settings.spec.ts b/packages/app-tests/e2e/envelope-editor-v2/envelope-settings.spec.ts index 39009f3a6..a5a6f8aad 100644 --- a/packages/app-tests/e2e/envelope-editor-v2/envelope-settings.spec.ts +++ b/packages/app-tests/e2e/envelope-editor-v2/envelope-settings.spec.ts @@ -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, ); diff --git a/packages/app-tests/e2e/organisations/organisation-team-preferences.spec.ts b/packages/app-tests/e2e/organisations/organisation-team-preferences.spec.ts index abb2a08d6..c9b7febf9 100644 --- a/packages/app-tests/e2e/organisations/organisation-team-preferences.spec.ts +++ b/packages/app-tests/e2e/organisations/organisation-team-preferences.spec.ts @@ -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, }); }); diff --git a/packages/lib/server-only/template/create-document-from-direct-template.ts b/packages/lib/server-only/template/create-document-from-direct-template.ts index 81a3059b5..59b1ec910 100644 --- a/packages/lib/server-only/template/create-document-from-direct-template.ts +++ b/packages/lib/server-only/template/create-document-from-direct-template.ts @@ -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. diff --git a/packages/lib/server-only/webhooks/trigger/generate-sample-data.ts b/packages/lib/server-only/webhooks/trigger/generate-sample-data.ts index ec736d17a..5f25973ef 100644 --- a/packages/lib/server-only/webhooks/trigger/generate-sample-data.ts +++ b/packages/lib/server-only/webhooks/trigger/generate-sample-data.ts @@ -440,6 +440,7 @@ export const generateSampleWebhookPayload = ( documentCompleted: true, ownerDocumentCompleted: true, ownerRecipientExpired: true, + ownerDocumentCreated: true, recipientSigningRequest: true, }, }, diff --git a/packages/lib/types/document-email.ts b/packages/lib/types/document-email.ts index cc659519b..4ecb8b6a9 100644 --- a/packages/lib/types/document-email.ts +++ b/packages/lib/types/document-email.ts @@ -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, }; diff --git a/packages/ui/components/document/document-email-checkboxes.tsx b/packages/ui/components/document/document-email-checkboxes.tsx index dc846abbd..200503709 100644 --- a/packages/ui/components/document/document-email-checkboxes.tsx +++ b/packages/ui/components/document/document-email-checkboxes.tsx @@ -291,6 +291,45 @@ export const DocumentEmailCheckboxes = ({ +
+ + onChange({ ...value, [DocumentEmailEvents.OwnerDocumentCreated]: Boolean(checked) }) + } + /> + + +
+