feat: polish envelopes (#2090)

## Description

The rest of the owl
This commit is contained in:
David Nguyen
2025-10-24 16:22:06 +11:00
committed by GitHub
parent 88836404d1
commit 03eb6af69a
141 changed files with 5171 additions and 2402 deletions
@@ -0,0 +1,74 @@
import { FieldType } from '@prisma/client';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import type { TFieldCheckbox } from '@documenso/lib/types/field';
import { parseCheckboxCustomText } from '@documenso/lib/utils/fields';
import type { TSignEnvelopeFieldValue } from '@documenso/trpc/server/envelope-router/sign-envelope-field.types';
import { checkboxValidationSigns } from '@documenso/ui/primitives/document-flow/field-items-advanced-settings/constants';
import { SignFieldCheckboxDialog } from '~/components/dialogs/sign-field-checkbox-dialog';
type HandleCheckboxFieldClickOptions = {
field: TFieldCheckbox;
clickedCheckboxIndex: number;
};
export const handleCheckboxFieldClick = async (
options: HandleCheckboxFieldClickOptions,
): Promise<Extract<TSignEnvelopeFieldValue, { type: typeof FieldType.CHECKBOX }> | null> => {
const { field, clickedCheckboxIndex } = options;
if (field.type !== FieldType.CHECKBOX) {
throw new AppError(AppErrorCode.INVALID_REQUEST, {
message: 'Invalid field type',
});
}
const { values = [], validationRule, validationLength } = field.fieldMeta;
const { customText } = field;
const currentCheckedIndices: number[] = customText ? parseCheckboxCustomText(customText) : [];
const newValues = values.map((_value, i) => {
let isChecked = currentCheckedIndices.includes(i);
if (i === clickedCheckboxIndex) {
isChecked = !isChecked;
}
return {
index: i,
isChecked,
};
});
let checkedValues: number[] | null = newValues.filter((v) => v.isChecked).map((v) => v.index);
if (validationRule && validationLength) {
const checkboxValidationRule = checkboxValidationSigns.find(
(sign) => sign.label === validationRule,
);
if (!checkboxValidationRule) {
throw new AppError(AppErrorCode.INVALID_REQUEST, {
message: 'Invalid checkbox validation rule',
});
}
checkedValues = await SignFieldCheckboxDialog.call({
fieldMeta: field.fieldMeta,
validationRule: checkboxValidationRule.value,
validationLength,
preselectedIndices: currentCheckedIndices,
});
}
if (!checkedValues) {
return null;
}
return {
type: FieldType.CHECKBOX,
value: checkedValues,
};
};
@@ -9,12 +9,13 @@ import { SignFieldEmailDialog } from '~/components/dialogs/sign-field-email-dial
type HandleEmailFieldClickOptions = {
field: TFieldEmail;
email: string | null;
placeholderEmail: string | null;
};
export const handleEmailFieldClick = async (
options: HandleEmailFieldClickOptions,
): Promise<Extract<TSignEnvelopeFieldValue, { type: typeof FieldType.EMAIL }> | null> => {
const { field, email } = options;
const { field, email, placeholderEmail } = options;
if (field.type !== FieldType.EMAIL) {
throw new AppError(AppErrorCode.INVALID_REQUEST, {
@@ -32,7 +33,9 @@ export const handleEmailFieldClick = async (
let emailToInsert = email;
if (!emailToInsert) {
emailToInsert = await SignFieldEmailDialog.call({});
emailToInsert = await SignFieldEmailDialog.call({
placeholderEmail,
});
}
if (!emailToInsert) {
@@ -30,7 +30,6 @@ export const handleSignatureFieldClick = async (
return {
type: FieldType.SIGNATURE,
value: null,
isBase64: false,
};
}
@@ -51,6 +50,5 @@ export const handleSignatureFieldClick = async (
return {
type: FieldType.SIGNATURE,
value: signatureToInsert,
isBase64: signatureToInsert.startsWith('data:image'),
};
};