fix: update link-only notification settings (#2821)

This commit is contained in:
Ephraim Duncan
2026-06-08 02:59:50 +00:00
committed by GitHub
parent f60698a353
commit 03b5fe6117
3 changed files with 401 additions and 307 deletions
@@ -9,7 +9,7 @@ import { DEFAULT_DOCUMENT_TIME_ZONE, TIME_ZONES } from '@documenso/lib/constants
import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION } from '@documenso/lib/constants/trpc'; import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION } from '@documenso/lib/constants/trpc';
import { AppError } from '@documenso/lib/errors/app-error'; import { AppError } from '@documenso/lib/errors/app-error';
import { ZDocumentAccessAuthTypesSchema, ZDocumentActionAuthTypesSchema } from '@documenso/lib/types/document-auth'; import { ZDocumentAccessAuthTypesSchema, ZDocumentActionAuthTypesSchema } from '@documenso/lib/types/document-auth';
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email'; import { DocumentEmailEvents, ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
import { import {
type TDocumentMetaDateFormat, type TDocumentMetaDateFormat,
ZDocumentMetaDateFormatSchema, ZDocumentMetaDateFormatSchema,
@@ -39,6 +39,7 @@ import { ExpirationPeriodPicker } from '@documenso/ui/components/document/expira
import { ReminderSettingsPicker } from '@documenso/ui/components/document/reminder-settings-picker'; import { ReminderSettingsPicker } from '@documenso/ui/components/document/reminder-settings-picker';
import { TemplateTypeSelect, TemplateTypeTooltip } from '@documenso/ui/components/template/template-type-select'; import { TemplateTypeSelect, TemplateTypeTooltip } from '@documenso/ui/components/template/template-type-select';
import { cn } from '@documenso/ui/lib/utils'; import { cn } from '@documenso/ui/lib/utils';
import { Alert, AlertDescription } from '@documenso/ui/primitives/alert';
import { Button } from '@documenso/ui/primitives/button'; import { Button } from '@documenso/ui/primitives/button';
import { CardDescription, CardHeader, CardTitle } from '@documenso/ui/primitives/card'; import { CardDescription, CardHeader, CardTitle } from '@documenso/ui/primitives/card';
import { Combobox } from '@documenso/ui/primitives/combobox'; import { Combobox } from '@documenso/ui/primitives/combobox';
@@ -114,7 +115,7 @@ export const ZAddSettingsFormSchema = z.object({
}), }),
}); });
type EnvelopeEditorSettingsTabType = 'general' | 'reminders' | 'email' | 'security'; type EnvelopeEditorSettingsTabType = 'general' | 'reminders' | 'notifications' | 'security';
const tabs = [ const tabs = [
{ {
@@ -130,10 +131,10 @@ const tabs = [
description: msg`Configure signing reminder settings for the document.`, description: msg`Configure signing reminder settings for the document.`,
}, },
{ {
id: 'email', id: 'notifications',
title: msg`Email`, title: msg`Notifications`,
icon: MailIcon, icon: MailIcon,
description: msg`Configure email settings for the document.`, description: msg`Configure notification settings for the document.`,
}, },
{ {
id: 'security', id: 'security',
@@ -143,6 +144,18 @@ const tabs = [
}, },
] as const; ] as const;
// Recipient-facing notification events. These are suppressed at send time
// when distributionMethod is not EMAIL (see extractDerivedDocumentEmailSettings),
// so the UI mirrors that by disabling the matching checkboxes.
const RECIPIENT_EMAIL_EVENTS = [
DocumentEmailEvents.RecipientSigningRequest,
DocumentEmailEvents.RecipientRemoved,
DocumentEmailEvents.RecipientSigned,
DocumentEmailEvents.DocumentPending,
DocumentEmailEvents.DocumentCompleted,
DocumentEmailEvents.DocumentDeleted,
] as const;
type TAddSettingsFormSchema = z.infer<typeof ZAddSettingsFormSchema>; type TAddSettingsFormSchema = z.infer<typeof ZAddSettingsFormSchema>;
type EnvelopeEditorSettingsDialogProps = { type EnvelopeEditorSettingsDialogProps = {
@@ -205,6 +218,8 @@ export const EnvelopeEditorSettingsDialog = ({ trigger, ...props }: EnvelopeEdit
); );
const emailSettings = form.watch('meta.emailSettings'); const emailSettings = form.watch('meta.emailSettings');
const distributionMethod = form.watch('meta.distributionMethod');
const isEmailDistribution = distributionMethod === DocumentDistributionMethod.EMAIL;
const { data: emailData, isLoading: isLoadingEmails } = trpc.enterprise.organisation.email.find.useQuery( const { data: emailData, isLoading: isLoadingEmails } = trpc.enterprise.organisation.email.find.useQuery(
{ {
@@ -334,7 +349,7 @@ export const EnvelopeEditorSettingsDialog = ({ trigger, ...props }: EnvelopeEdit
<nav className="col-span-12 mb-8 flex flex-wrap items-center justify-start gap-x-2 gap-y-4 px-4 md:col-span-3 md:w-full md:flex-col md:items-start md:gap-y-2"> <nav className="col-span-12 mb-8 flex flex-wrap items-center justify-start gap-x-2 gap-y-4 px-4 md:col-span-3 md:w-full md:flex-col md:items-start md:gap-y-2">
{tabs.map((tab) => { {tabs.map((tab) => {
if (tab.id === 'email' && !settings.allowConfigureDistribution) { if (tab.id === 'notifications' && !settings.allowConfigureDistribution) {
return null; return null;
} }
@@ -730,7 +745,7 @@ export const EnvelopeEditorSettingsDialog = ({ trigger, ...props }: EnvelopeEdit
)} )}
/> />
)) ))
.with({ activeTab: 'email', settings: { allowConfigureDistribution: true } }, () => ( .with({ activeTab: 'notifications', settings: { allowConfigureDistribution: true } }, () => (
<> <>
{settings.allowConfigureEmailSender && organisation.organisationClaim.flags.emailDomains && ( {settings.allowConfigureEmailSender && organisation.organisationClaim.flags.emailDomains && (
<FormField <FormField
@@ -747,6 +762,7 @@ export const EnvelopeEditorSettingsDialog = ({ trigger, ...props }: EnvelopeEdit
{...field} {...field}
value={field.value === null ? '-1' : field.value} value={field.value === null ? '-1' : field.value}
onValueChange={(value) => field.onChange(value === '-1' ? null : value)} onValueChange={(value) => field.onChange(value === '-1' ? null : value)}
disabled={!isEmailDistribution}
> >
<SelectTrigger loading={isLoadingEmails} className="bg-background"> <SelectTrigger loading={isLoadingEmails} className="bg-background">
<SelectValue /> <SelectValue />
@@ -783,7 +799,7 @@ export const EnvelopeEditorSettingsDialog = ({ trigger, ...props }: EnvelopeEdit
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input {...field} /> <Input {...field} disabled={!isEmailDistribution} />
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
@@ -804,7 +820,7 @@ export const EnvelopeEditorSettingsDialog = ({ trigger, ...props }: EnvelopeEdit
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Input {...field} /> <Input {...field} disabled={!isEmailDistribution} />
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
@@ -832,7 +848,11 @@ export const EnvelopeEditorSettingsDialog = ({ trigger, ...props }: EnvelopeEdit
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Textarea className="h-16 resize-none bg-background" {...field} /> <Textarea
className="h-16 resize-none bg-background"
{...field}
disabled={!isEmailDistribution}
/>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
@@ -843,7 +863,19 @@ export const EnvelopeEditorSettingsDialog = ({ trigger, ...props }: EnvelopeEdit
<DocumentEmailCheckboxes <DocumentEmailCheckboxes
value={emailSettings} value={emailSettings}
onChange={(value) => form.setValue('meta.emailSettings', value)} onChange={(value) => form.setValue('meta.emailSettings', value)}
hiddenEvents={isEmailDistribution ? undefined : RECIPIENT_EMAIL_EVENTS}
/> />
{!isEmailDistribution && (
<Alert variant="warning">
<AlertDescription>
<Trans>
Email distribution needs to be enabled in the general settings tab to configure recipient
email related settings.
</Trans>
</AlertDescription>
</Alert>
)}
</> </>
)) ))
.with({ activeTab: 'security' }, () => ( .with({ activeTab: 'security' }, () => (
@@ -115,6 +115,21 @@ const runSettingsFlow = async ({ root }: TEnvelopeEditorSurface, { externalId, i
await root.locator('input[name="externalId"]').fill(externalId); await root.locator('input[name="externalId"]').fill(externalId);
await root.locator('input[name="meta.redirectUrl"]').fill(TEST_SETTINGS_VALUES.redirectUrl); await root.locator('input[name="meta.redirectUrl"]').fill(TEST_SETTINGS_VALUES.redirectUrl);
await root.getByRole('button', { name: 'Notifications' }).click();
// Fill email-content fields and toggle recipient-facing notification checkboxes
// while distributionMethod is still EMAIL. After it flips to NONE below, these
// controls are disabled because no email is sent to recipients.
await root.locator('input[name="meta.subject"]').fill(TEST_SETTINGS_VALUES.subject);
await root.locator('textarea[name="meta.message"]').fill(TEST_SETTINGS_VALUES.message);
await root.locator('input[name="meta.emailReplyTo"]').fill(TEST_SETTINGS_VALUES.replyTo);
await root.locator('#recipientSigned').click();
await root.locator('#recipientSigningRequest').click();
await root.locator('#recipientRemoved').click();
await root.locator('#documentPending').click();
await root.locator('#documentCompleted').click();
await root.locator('#documentDeleted').click();
await root.getByRole('button', { name: 'General' }).click();
await root.locator('[data-testid="documentDistributionMethodSelectValue"]').click(); await root.locator('[data-testid="documentDistributionMethodSelectValue"]').click();
await root.getByRole('option', { name: TEST_SETTINGS_VALUES.distributionMethod }).click(); await root.getByRole('option', { name: TEST_SETTINGS_VALUES.distributionMethod }).click();
@@ -190,19 +205,35 @@ const runSettingsFlow = async ({ root }: TEnvelopeEditorSurface, { externalId, i
await root.getByRole('option', { name: TEST_SETTINGS_VALUES.reminderRepeatUnit }).click(); await root.getByRole('option', { name: TEST_SETTINGS_VALUES.reminderRepeatUnit }).click();
await clickSettingsDialogHeader(root); await clickSettingsDialogHeader(root);
await root.getByRole('button', { name: 'Email' }).click(); await root.getByRole('button', { name: 'Notifications' }).click();
await root.locator('#recipientSigned').click();
await root.locator('#recipientSigningRequest').click(); // Distribution is NONE: email-content fields stay rendered but disabled,
await root.locator('#recipientRemoved').click(); // recipient-facing checkboxes are hidden entirely and replaced by an alert,
await root.locator('#documentPending').click(); // owner-facing checkboxes stay editable so we toggle them here.
await root.locator('#documentCompleted').click(); await expect(root.locator('input[name="meta.subject"]')).toBeDisabled();
await root.locator('#documentDeleted').click(); await expect(root.locator('textarea[name="meta.message"]')).toBeDisabled();
await expect(root.locator('input[name="meta.emailReplyTo"]')).toBeDisabled();
await expect(root.locator('#recipientSigned')).toHaveCount(0);
await expect(root.locator('#recipientSigningRequest')).toHaveCount(0);
await expect(root.locator('#recipientRemoved')).toHaveCount(0);
await expect(root.locator('#documentPending')).toHaveCount(0);
await expect(root.locator('#documentCompleted')).toHaveCount(0);
await expect(root.locator('#documentDeleted')).toHaveCount(0);
await expect(root.getByText(/Email distribution needs to be enabled/)).toBeVisible();
// Email Sender select only renders when the org has the emailDomains feature
// flag plus allowConfigureEmailSender, so the assertion is conditional.
const emailSenderSelect = getComboboxByLabel(root, 'Email Sender');
const hasEmailSenderSelect = (await emailSenderSelect.count()) > 0;
if (hasEmailSenderSelect) {
await expect(emailSenderSelect).toBeDisabled();
}
await expect(root.locator('#ownerDocumentCompleted')).toBeEnabled();
await root.locator('#ownerDocumentCompleted').click(); await root.locator('#ownerDocumentCompleted').click();
await root.locator('#ownerRecipientExpired').click(); await root.locator('#ownerRecipientExpired').click();
await root.locator('#ownerDocumentCreated').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);
await root.getByRole('button', { name: 'Security' }).click(); await root.getByRole('button', { name: 'Security' }).click();
await selectMultiSelectOption(root, 'documentAccessSelectValue', TEST_SETTINGS_VALUES.accessAuth); await selectMultiSelectOption(root, 'documentAccessSelectValue', TEST_SETTINGS_VALUES.accessAuth);
@@ -264,13 +295,17 @@ const runSettingsFlow = async ({ root }: TEnvelopeEditorSurface, { externalId, i
TEST_SETTINGS_VALUES.reminderRepeatUnit, TEST_SETTINGS_VALUES.reminderRepeatUnit,
); );
await root.getByRole('button', { name: 'Email' }).click(); await root.getByRole('button', { name: 'Notifications' }).click();
await expect(root.locator('#recipientSigned')).toHaveAttribute('aria-checked', 'false'); // Distribution persisted as NONE: recipient-facing checkboxes are hidden, owner-facing
await expect(root.locator('#recipientSigningRequest')).toHaveAttribute('aria-checked', 'false'); // checkboxes remain visible and persist their stored values. Email-content fields are
await expect(root.locator('#recipientRemoved')).toHaveAttribute('aria-checked', 'false'); // still rendered (disabled) and persist their stored values.
await expect(root.locator('#documentPending')).toHaveAttribute('aria-checked', 'false'); await expect(root.locator('#recipientSigned')).toHaveCount(0);
await expect(root.locator('#documentCompleted')).toHaveAttribute('aria-checked', 'false'); await expect(root.locator('#recipientSigningRequest')).toHaveCount(0);
await expect(root.locator('#documentDeleted')).toHaveAttribute('aria-checked', 'false'); await expect(root.locator('#recipientRemoved')).toHaveCount(0);
await expect(root.locator('#documentPending')).toHaveCount(0);
await expect(root.locator('#documentCompleted')).toHaveCount(0);
await expect(root.locator('#documentDeleted')).toHaveCount(0);
await expect(root.getByText(/Email distribution needs to be enabled/)).toBeVisible();
await expect(root.locator('#ownerDocumentCompleted')).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('#ownerRecipientExpired')).toHaveAttribute('aria-checked', 'false');
await expect(root.locator('#ownerDocumentCreated')).toHaveAttribute('aria-checked', 'false'); await expect(root.locator('#ownerDocumentCreated')).toHaveAttribute('aria-checked', 'false');
@@ -13,334 +13,361 @@ type DocumentEmailCheckboxesProps = {
value: Value; value: Value;
onChange: (value: Value) => void; onChange: (value: Value) => void;
className?: string; className?: string;
hiddenEvents?: readonly DocumentEmailEvents[];
}; };
export const DocumentEmailCheckboxes = ({ value, onChange, className }: DocumentEmailCheckboxesProps) => { export const DocumentEmailCheckboxes = ({ value, onChange, className, hiddenEvents }: DocumentEmailCheckboxesProps) => {
const isHidden = (event: DocumentEmailEvents) => hiddenEvents?.includes(event) ?? false;
return ( return (
<div className={cn('space-y-3', className)}> <div className={cn('space-y-3', className)}>
<div className="flex flex-row items-center"> {!isHidden(DocumentEmailEvents.RecipientSigned) && (
<Checkbox <div className="flex flex-row items-center">
id={DocumentEmailEvents.RecipientSigned} <Checkbox
className="h-5 w-5" id={DocumentEmailEvents.RecipientSigned}
checked={value.recipientSigned} className="h-5 w-5"
onCheckedChange={(checked) => onChange({ ...value, [DocumentEmailEvents.RecipientSigned]: Boolean(checked) })} checked={value.recipientSigned}
/> onCheckedChange={(checked) =>
onChange({ ...value, [DocumentEmailEvents.RecipientSigned]: Boolean(checked) })
}
/>
<label <label
className="ml-2 flex flex-row items-center text-muted-foreground text-sm" className="ml-2 flex flex-row items-center text-muted-foreground text-sm"
htmlFor={DocumentEmailEvents.RecipientSigned} htmlFor={DocumentEmailEvents.RecipientSigned}
> >
<Trans>Email the owner when a recipient signs</Trans> <Trans>Email the owner when a recipient signs</Trans>
<Tooltip> <Tooltip>
<TooltipTrigger> <TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" /> <InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger> </TooltipTrigger>
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground"> <TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
<h2> <h2>
<strong> <strong>
<Trans>Recipient signed email</Trans> <Trans>Recipient signed email</Trans>
</strong> </strong>
</h2> </h2>
<p> <p>
<Trans>This email is sent to the document owner when a recipient has signed the document.</Trans> <Trans>This email is sent to the document owner when a recipient has signed the document.</Trans>
</p> </p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</label> </label>
</div> </div>
)}
<div className="flex flex-row items-center"> {!isHidden(DocumentEmailEvents.RecipientSigningRequest) && (
<Checkbox <div className="flex flex-row items-center">
id={DocumentEmailEvents.RecipientSigningRequest} <Checkbox
className="h-5 w-5" id={DocumentEmailEvents.RecipientSigningRequest}
checked={value.recipientSigningRequest} className="h-5 w-5"
onCheckedChange={(checked) => checked={value.recipientSigningRequest}
onChange({ ...value, [DocumentEmailEvents.RecipientSigningRequest]: Boolean(checked) }) onCheckedChange={(checked) =>
} onChange({ ...value, [DocumentEmailEvents.RecipientSigningRequest]: Boolean(checked) })
/> }
/>
<label <label
className="ml-2 flex flex-row items-center text-muted-foreground text-sm" className="ml-2 flex flex-row items-center text-muted-foreground text-sm"
htmlFor={DocumentEmailEvents.RecipientSigningRequest} htmlFor={DocumentEmailEvents.RecipientSigningRequest}
> >
<Trans>Email recipients with a signing request</Trans> <Trans>Email recipients with a signing request</Trans>
<Tooltip> <Tooltip>
<TooltipTrigger> <TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" /> <InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger> </TooltipTrigger>
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground"> <TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
<h2> <h2>
<strong> <strong>
<Trans>Recipient signing request email</Trans> <Trans>Recipient signing request email</Trans>
</strong> </strong>
</h2> </h2>
<p> <p>
<Trans>This email is sent to the recipient requesting them to sign the document.</Trans> <Trans>This email is sent to the recipient requesting them to sign the document.</Trans>
</p> </p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</label> </label>
</div> </div>
)}
<div className="flex flex-row items-center"> {!isHidden(DocumentEmailEvents.RecipientRemoved) && (
<Checkbox <div className="flex flex-row items-center">
id={DocumentEmailEvents.RecipientRemoved} <Checkbox
className="h-5 w-5" id={DocumentEmailEvents.RecipientRemoved}
checked={value.recipientRemoved} className="h-5 w-5"
onCheckedChange={(checked) => checked={value.recipientRemoved}
onChange({ ...value, [DocumentEmailEvents.RecipientRemoved]: Boolean(checked) }) onCheckedChange={(checked) =>
} onChange({ ...value, [DocumentEmailEvents.RecipientRemoved]: Boolean(checked) })
/> }
/>
<label <label
className="ml-2 flex flex-row items-center text-muted-foreground text-sm" className="ml-2 flex flex-row items-center text-muted-foreground text-sm"
htmlFor={DocumentEmailEvents.RecipientRemoved} htmlFor={DocumentEmailEvents.RecipientRemoved}
> >
<Trans>Email recipients when they're removed from a pending document</Trans> <Trans>Email recipients when they're removed from a pending document</Trans>
<Tooltip> <Tooltip>
<TooltipTrigger> <TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" /> <InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger> </TooltipTrigger>
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground"> <TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
<h2> <h2>
<strong> <strong>
<Trans>Recipient removed email</Trans> <Trans>Recipient removed email</Trans>
</strong> </strong>
</h2> </h2>
<p> <p>
<Trans>This email is sent to the recipient if they are removed from a pending document.</Trans> <Trans>This email is sent to the recipient if they are removed from a pending document.</Trans>
</p> </p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</label> </label>
</div> </div>
)}
<div className="flex flex-row items-center"> {!isHidden(DocumentEmailEvents.DocumentPending) && (
<Checkbox <div className="flex flex-row items-center">
id={DocumentEmailEvents.DocumentPending} <Checkbox
className="h-5 w-5" id={DocumentEmailEvents.DocumentPending}
checked={value.documentPending} className="h-5 w-5"
onCheckedChange={(checked) => onChange({ ...value, [DocumentEmailEvents.DocumentPending]: Boolean(checked) })} checked={value.documentPending}
/> onCheckedChange={(checked) =>
onChange({ ...value, [DocumentEmailEvents.DocumentPending]: Boolean(checked) })
}
/>
<label <label
className="ml-2 flex flex-row items-center text-muted-foreground text-sm" className="ml-2 flex flex-row items-center text-muted-foreground text-sm"
htmlFor={DocumentEmailEvents.DocumentPending} htmlFor={DocumentEmailEvents.DocumentPending}
> >
<Trans>Email the signer if the document is still pending</Trans> <Trans>Email the signer if the document is still pending</Trans>
<Tooltip> <Tooltip>
<TooltipTrigger> <TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" /> <InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger> </TooltipTrigger>
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground"> <TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
<h2> <h2>
<strong> <strong>
<Trans>Document pending email</Trans> <Trans>Document pending email</Trans>
</strong> </strong>
</h2> </h2>
<p> <p>
<Trans> <Trans>
This email will be sent to the recipient who has just signed the document, if there are still other This email will be sent to the recipient who has just signed the document, if there are still other
recipients who have not signed yet. recipients who have not signed yet.
</Trans> </Trans>
</p> </p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</label> </label>
</div> </div>
)}
<div className="flex flex-row items-center"> {!isHidden(DocumentEmailEvents.DocumentCompleted) && (
<Checkbox <div className="flex flex-row items-center">
id={DocumentEmailEvents.DocumentCompleted} <Checkbox
className="h-5 w-5" id={DocumentEmailEvents.DocumentCompleted}
checked={value.documentCompleted} className="h-5 w-5"
onCheckedChange={(checked) => checked={value.documentCompleted}
onChange({ ...value, [DocumentEmailEvents.DocumentCompleted]: Boolean(checked) }) onCheckedChange={(checked) =>
} onChange({ ...value, [DocumentEmailEvents.DocumentCompleted]: Boolean(checked) })
/> }
/>
<label <label
className="ml-2 flex flex-row items-center text-muted-foreground text-sm" className="ml-2 flex flex-row items-center text-muted-foreground text-sm"
htmlFor={DocumentEmailEvents.DocumentCompleted} htmlFor={DocumentEmailEvents.DocumentCompleted}
> >
<Trans>Email recipients when the document is completed</Trans> <Trans>Email recipients when the document is completed</Trans>
<Tooltip> <Tooltip>
<TooltipTrigger> <TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" /> <InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger> </TooltipTrigger>
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground"> <TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
<h2> <h2>
<strong> <strong>
<Trans>Document completed email</Trans> <Trans>Document completed email</Trans>
</strong> </strong>
</h2> </h2>
<p> <p>
<Trans>This will be sent to all recipients once the document has been fully completed.</Trans> <Trans>This will be sent to all recipients once the document has been fully completed.</Trans>
</p> </p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</label> </label>
</div> </div>
)}
<div className="flex flex-row items-center"> {!isHidden(DocumentEmailEvents.DocumentDeleted) && (
<Checkbox <div className="flex flex-row items-center">
id={DocumentEmailEvents.DocumentDeleted} <Checkbox
className="h-5 w-5" id={DocumentEmailEvents.DocumentDeleted}
checked={value.documentDeleted} className="h-5 w-5"
onCheckedChange={(checked) => onChange({ ...value, [DocumentEmailEvents.DocumentDeleted]: Boolean(checked) })} checked={value.documentDeleted}
/> onCheckedChange={(checked) =>
onChange({ ...value, [DocumentEmailEvents.DocumentDeleted]: Boolean(checked) })
}
/>
<label <label
className="ml-2 flex flex-row items-center text-muted-foreground text-sm" className="ml-2 flex flex-row items-center text-muted-foreground text-sm"
htmlFor={DocumentEmailEvents.DocumentDeleted} htmlFor={DocumentEmailEvents.DocumentDeleted}
> >
<Trans>Email recipients when a pending document is deleted</Trans> <Trans>Email recipients when a pending document is deleted</Trans>
<Tooltip> <Tooltip>
<TooltipTrigger> <TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" /> <InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger> </TooltipTrigger>
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground"> <TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
<h2> <h2>
<strong> <strong>
<Trans>Document deleted email</Trans> <Trans>Document deleted email</Trans>
</strong> </strong>
</h2> </h2>
<p> <p>
<Trans>This will be sent to all recipients if a pending document has been deleted.</Trans> <Trans>This will be sent to all recipients if a pending document has been deleted.</Trans>
</p> </p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</label> </label>
</div> </div>
)}
<div className="flex flex-row items-center"> {!isHidden(DocumentEmailEvents.OwnerDocumentCompleted) && (
<Checkbox <div className="flex flex-row items-center">
id={DocumentEmailEvents.OwnerDocumentCompleted} <Checkbox
className="h-5 w-5" id={DocumentEmailEvents.OwnerDocumentCompleted}
checked={value.ownerDocumentCompleted} className="h-5 w-5"
onCheckedChange={(checked) => checked={value.ownerDocumentCompleted}
onChange({ ...value, [DocumentEmailEvents.OwnerDocumentCompleted]: Boolean(checked) }) onCheckedChange={(checked) =>
} onChange({ ...value, [DocumentEmailEvents.OwnerDocumentCompleted]: Boolean(checked) })
/> }
/>
<label <label
className="ml-2 flex flex-row items-center text-muted-foreground text-sm" className="ml-2 flex flex-row items-center text-muted-foreground text-sm"
htmlFor={DocumentEmailEvents.OwnerDocumentCompleted} htmlFor={DocumentEmailEvents.OwnerDocumentCompleted}
> >
<Trans>Email the owner when the document is completed</Trans> <Trans>Email the owner when the document is completed</Trans>
<Tooltip> <Tooltip>
<TooltipTrigger> <TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" /> <InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger> </TooltipTrigger>
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground"> <TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
<h2> <h2>
<strong> <strong>
<Trans>Document completed email</Trans> <Trans>Document completed email</Trans>
</strong> </strong>
</h2> </h2>
<p> <p>
<Trans>This will be sent to the document owner once the document has been fully completed.</Trans> <Trans>This will be sent to the document owner once the document has been fully completed.</Trans>
</p> </p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</label> </label>
</div> </div>
)}
<div className="flex flex-row items-center"> {!isHidden(DocumentEmailEvents.OwnerDocumentCreated) && (
<Checkbox <div className="flex flex-row items-center">
id={DocumentEmailEvents.OwnerDocumentCreated} <Checkbox
className="h-5 w-5" id={DocumentEmailEvents.OwnerDocumentCreated}
checked={value.ownerDocumentCreated} className="h-5 w-5"
onCheckedChange={(checked) => checked={value.ownerDocumentCreated}
onChange({ ...value, [DocumentEmailEvents.OwnerDocumentCreated]: Boolean(checked) }) onCheckedChange={(checked) =>
} onChange({ ...value, [DocumentEmailEvents.OwnerDocumentCreated]: Boolean(checked) })
/> }
/>
<label <label
className="ml-2 flex flex-row items-center text-muted-foreground text-sm" className="ml-2 flex flex-row items-center text-muted-foreground text-sm"
htmlFor={DocumentEmailEvents.OwnerDocumentCreated} htmlFor={DocumentEmailEvents.OwnerDocumentCreated}
> >
<Trans>Email the owner when a document is created from a direct template</Trans> <Trans>Email the owner when a document is created from a direct template</Trans>
<Tooltip> <Tooltip>
<TooltipTrigger> <TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" /> <InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger> </TooltipTrigger>
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground"> <TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
<h2> <h2>
<strong> <strong>
<Trans>Document created from direct template email</Trans> <Trans>Document created from direct template email</Trans>
</strong> </strong>
</h2> </h2>
<p> <p>
<Trans> <Trans>
This email is sent to the document owner when a recipient creates a document via a direct template This email is sent to the document owner when a recipient creates a document via a direct template
link. link.
</Trans> </Trans>
</p> </p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</label> </label>
</div> </div>
)}
<div className="flex flex-row items-center"> {!isHidden(DocumentEmailEvents.OwnerRecipientExpired) && (
<Checkbox <div className="flex flex-row items-center">
id={DocumentEmailEvents.OwnerRecipientExpired} <Checkbox
className="h-5 w-5" id={DocumentEmailEvents.OwnerRecipientExpired}
checked={value.ownerRecipientExpired} className="h-5 w-5"
onCheckedChange={(checked) => checked={value.ownerRecipientExpired}
onChange({ ...value, [DocumentEmailEvents.OwnerRecipientExpired]: Boolean(checked) }) onCheckedChange={(checked) =>
} onChange({ ...value, [DocumentEmailEvents.OwnerRecipientExpired]: Boolean(checked) })
/> }
/>
<label <label
className="ml-2 flex flex-row items-center text-muted-foreground text-sm" className="ml-2 flex flex-row items-center text-muted-foreground text-sm"
htmlFor={DocumentEmailEvents.OwnerRecipientExpired} htmlFor={DocumentEmailEvents.OwnerRecipientExpired}
> >
<Trans>Send recipient expired email to the owner</Trans> <Trans>Send recipient expired email to the owner</Trans>
<Tooltip> <Tooltip>
<TooltipTrigger> <TooltipTrigger>
<InfoIcon className="mx-2 h-4 w-4" /> <InfoIcon className="mx-2 h-4 w-4" />
</TooltipTrigger> </TooltipTrigger>
<TooltipContent className="max-w-md space-y-2 p-4 text-foreground"> <TooltipContent className="max-w-md space-y-2 p-4 text-foreground">
<h2> <h2>
<strong> <strong>
<Trans>Recipient expired email</Trans> <Trans>Recipient expired email</Trans>
</strong> </strong>
</h2> </h2>
<p> <p>
<Trans>This will be sent to the document owner when a recipient's signing window has expired.</Trans> <Trans>This will be sent to the document owner when a recipient's signing window has expired.</Trans>
</p> </p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</label> </label>
</div> </div>
)}
</div> </div>
); );
}; };