feat: assistant role (#1588)

## Description

Introduces the ability for users with the **Assistant** role to prefill
fields on behalf of other signers. Assistants can fill in various field
types such as text, checkboxes, dates, and more, streamlining the
document preparation process before it reaches the final signers.

https://github.com/user-attachments/assets/c1321578-47ec-405b-a70a-7d9578385895
This commit is contained in:
Ephraim Duncan
2025-02-01 03:31:18 +00:00
committed by GitHub
parent 4017b250fb
commit 332e0657e0
53 changed files with 1638 additions and 700 deletions

View File

@ -12,7 +12,6 @@ import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION } from '@documenso/lib/constants/tr
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import type { TRecipientActionAuth } from '@documenso/lib/types/document-auth';
import { ZNameFieldMeta } from '@documenso/lib/types/field-meta';
import { type Recipient } from '@documenso/prisma/client';
import type { FieldWithSignature } from '@documenso/prisma/types/field-with-signature';
import { trpc } from '@documenso/trpc/react';
import type {
@ -28,16 +27,16 @@ import { useToast } from '@documenso/ui/primitives/use-toast';
import { useRequiredDocumentAuthContext } from './document-auth-provider';
import { useRequiredSigningContext } from './provider';
import { useRecipientContext } from './recipient-context';
import { SigningFieldContainer } from './signing-field-container';
export type NameFieldProps = {
field: FieldWithSignature;
recipient: Recipient;
onSignField?: (value: TSignFieldWithTokenMutationSchema) => Promise<void> | void;
onUnsignField?: (value: TRemovedSignedFieldWithTokenMutationSchema) => Promise<void> | void;
};
export const NameField = ({ field, recipient, onSignField, onUnsignField }: NameFieldProps) => {
export const NameField = ({ field, onSignField, onUnsignField }: NameFieldProps) => {
const router = useRouter();
const { _ } = useLingui();
@ -45,6 +44,7 @@ export const NameField = ({ field, recipient, onSignField, onUnsignField }: Name
const { fullName: providedFullName, setFullName: setProvidedFullName } =
useRequiredSigningContext();
const { recipient, targetSigner, isAssistantMode } = useRecipientContext();
const { executeActionAuthProcedure } = useRequiredDocumentAuthContext();
@ -67,7 +67,7 @@ export const NameField = ({ field, recipient, onSignField, onUnsignField }: Name
const [localFullName, setLocalFullName] = useState('');
const onPreSign = () => {
if (!providedFullName) {
if (!providedFullName && !isAssistantMode) {
setShowFullNameModal(true);
return false;
}
@ -90,9 +90,9 @@ export const NameField = ({ field, recipient, onSignField, onUnsignField }: Name
const onSign = async (authOptions?: TRecipientActionAuth, name?: string) => {
try {
const value = name || providedFullName;
const value = name || providedFullName || '';
if (!value) {
if (!value && !isAssistantMode) {
setShowFullNameModal(true);
return;
}
@ -124,7 +124,9 @@ export const NameField = ({ field, recipient, onSignField, onUnsignField }: Name
toast({
title: _(msg`Error`),
description: _(msg`An error occurred while signing the document.`),
description: isAssistantMode
? _(msg`An error occurred while signing as assistant.`)
: _(msg`An error occurred while signing the document.`),
variant: 'destructive',
});
}
@ -150,7 +152,7 @@ export const NameField = ({ field, recipient, onSignField, onUnsignField }: Name
toast({
title: _(msg`Error`),
description: _(msg`An error occurred while removing the signature.`),
description: _(msg`An error occurred while removing the field.`),
variant: 'destructive',
});
}