feat: add signature configurations (#1710)

Add ability to enable or disable allowed signature types: 
- Drawn
- Typed
- Uploaded

**Tabbed style signature dialog**

![image](https://github.com/user-attachments/assets/a816fab6-b071-42a5-bb5c-6d4a2572431e)

**Document settings**

![image](https://github.com/user-attachments/assets/f0c1bff1-6be1-4c87-b384-1666fa25d7a6)

**Team preferences**

![image](https://github.com/user-attachments/assets/8767b05e-1463-4087-8672-f3f43d8b0f2c)

## Changes Made

- Add multiselect to select allowed signatures in document and templates
settings tab
- Add multiselect to select allowed signatures in teams preferences 
- Removed "Enable typed signatures" from document/template edit page
- Refactored signature pad to use tabs instead of an all in one
signature pad

## Testing Performed

Added E2E tests to check settings are applied correctly for documents
and templates
This commit is contained in:
David Nguyen
2025-03-24 15:25:29 +11:00
committed by GitHub
parent 1b5d24e308
commit 3e97643e7e
78 changed files with 2390 additions and 1112 deletions

View File

@ -2,6 +2,7 @@ import { useEffect } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { Trans } from '@lingui/react/macro';
import { useLingui } from '@lingui/react/macro';
import { DocumentVisibility, TeamMemberRole } from '@prisma/client';
import { DocumentStatus, type Field, type Recipient, SendStatus } from '@prisma/client';
import { InfoIcon } from 'lucide-react';
@ -9,10 +10,12 @@ import { useForm } from 'react-hook-form';
import { match } from 'ts-pattern';
import { DATE_FORMATS, DEFAULT_DOCUMENT_DATE_FORMAT } from '@documenso/lib/constants/date-formats';
import { DOCUMENT_SIGNATURE_TYPES } from '@documenso/lib/constants/document';
import { SUPPORTED_LANGUAGES } from '@documenso/lib/constants/i18n';
import { DEFAULT_DOCUMENT_TIME_ZONE, TIME_ZONES } from '@documenso/lib/constants/time-zones';
import type { TDocument } from '@documenso/lib/types/document';
import { extractDocumentAuthMethods } from '@documenso/lib/utils/document-auth';
import { extractTeamSignatureSettings } from '@documenso/lib/utils/teams';
import {
DocumentGlobalAuthAccessSelect,
DocumentGlobalAuthAccessTooltip,
@ -39,7 +42,9 @@ import {
FormLabel,
FormMessage,
} from '@documenso/ui/primitives/form/form';
import { MultiSelectCombobox } from '@documenso/ui/primitives/multi-select-combobox';
import { DocumentSignatureSettingsTooltip } from '../../components/document/document-signature-settings-tooltip';
import { Combobox } from '../combobox';
import { Input } from '../input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../select';
@ -78,6 +83,8 @@ export const AddSettingsFormPartial = ({
currentTeamMemberRole,
onSubmit,
}: AddSettingsFormProps) => {
const { t } = useLingui();
const { documentAuthOption } = extractDocumentAuthMethods({
documentAuth: document.authOptions,
});
@ -90,6 +97,7 @@ export const AddSettingsFormPartial = ({
visibility: document.visibility || '',
globalAccessAuth: documentAuthOption?.globalAccessAuth || undefined,
globalActionAuth: documentAuthOption?.globalActionAuth || undefined,
meta: {
timezone:
TIME_ZONES.find((timezone) => timezone === document.documentMeta?.timezone) ??
@ -99,6 +107,7 @@ export const AddSettingsFormPartial = ({
?.value ?? DEFAULT_DOCUMENT_DATE_FORMAT,
redirectUrl: document.documentMeta?.redirectUrl ?? '',
language: document.documentMeta?.language ?? 'en',
signatureTypes: extractTeamSignatureSettings(document.documentMeta),
},
},
});
@ -189,9 +198,11 @@ export const AddSettingsFormPartial = ({
</TooltipTrigger>
<TooltipContent className="text-foreground max-w-md space-y-2 p-4">
Controls the language for the document, including the language to be used
for email notifications, and the final certificate that is generated and
attached to the document.
<Trans>
Controls the language for the document, including the language to be used
for email notifications, and the final certificate that is generated and
attached to the document.
</Trans>
</TooltipContent>
</Tooltip>
</FormLabel>
@ -314,6 +325,34 @@ export const AddSettingsFormPartial = ({
)}
/>
<FormField
control={form.control}
name="meta.signatureTypes"
render={({ field }) => (
<FormItem>
<FormLabel className="flex flex-row items-center">
<Trans>Allowed Signature Types</Trans>
<DocumentSignatureSettingsTooltip />
</FormLabel>
<FormControl>
<MultiSelectCombobox
options={Object.values(DOCUMENT_SIGNATURE_TYPES).map((option) => ({
label: t(option.label),
value: option.value,
}))}
selectedValues={field.value}
onChange={field.onChange}
className="bg-background w-full"
emptySelectionPlaceholder="Select signature types"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="meta.dateFormat"