chore: merge main, resolve biome formatting conflicts

Merge origin/main into feat/external-2fa-codes. Resolve formatting
conflicts caused by biome rollout; preserve both feature streams:
PR's external 2FA token + signing-session 2FA proof additions plus
main's RateLimit/RecipientExpired/signingReminders/date-auto-insert.

In complete-document-with-token.ts, drop the duplicate early
field-fetching block introduced when main moved that logic later
with date auto-insert support; keep the EXTERNAL_TWO_FACTOR_AUTH
check using derivedRecipientActionAuth.
This commit is contained in:
ephraimduncan
2026-05-12 11:46:11 +00:00
parent 9194884fbe
commit 138d663c25
1959 changed files with 93488 additions and 47038 deletions
@@ -1,12 +1,3 @@
import { useEffect, useMemo } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { t } from '@lingui/core/macro';
import { Trans } from '@lingui/react/macro';
import { PlusIcon, Trash } from 'lucide-react';
import { useForm, useWatch } from 'react-hook-form';
import { z } from 'zod';
import { validateCheckboxLength } from '@documenso/lib/advanced-fields-validation/validate-checkbox';
import {
type TCheckboxFieldMeta as CheckboxFieldMeta,
@@ -20,23 +11,17 @@ import {
checkboxValidationRules,
checkboxValidationSigns,
} from '@documenso/ui/primitives/document-flow/field-items-advanced-settings/constants';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@documenso/ui/primitives/form/form';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@documenso/ui/primitives/form/form';
import { Input } from '@documenso/ui/primitives/input';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@documenso/ui/primitives/select';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@documenso/ui/primitives/select';
import { Separator } from '@documenso/ui/primitives/separator';
import { zodResolver } from '@hookform/resolvers/zod';
import { t } from '@lingui/core/macro';
import { Trans } from '@lingui/react/macro';
import { PlusIcon, Trash } from 'lucide-react';
import { useEffect, useMemo } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import { z } from 'zod';
import {
EditorGenericFontSizeField,
@@ -150,19 +135,13 @@ export const EditorFieldCheckboxForm = ({
const preselectedValues = (formValues.values || [])?.filter((value) => value.checked);
if (formValues.validationLength && formValues.validationRule && preselectedValues.length > 0) {
const validationRule = checkboxValidationSigns.find(
(sign) => sign.label === formValues.validationRule,
);
const validationRule = checkboxValidationSigns.find((sign) => sign.label === formValues.validationRule);
if (!validationRule) {
return false;
}
return validateCheckboxLength(
preselectedValues.length,
validationRule.value,
formValues.validationLength,
);
return validateCheckboxLength(preselectedValues.length, validationRule.value, formValues.validationLength);
}
return true;
@@ -184,7 +163,10 @@ export const EditorFieldCheckboxForm = ({
</FormLabel>
<FormControl>
<Select value={field.value} onValueChange={field.onChange}>
<SelectTrigger className="text-muted-foreground bg-background w-full">
<SelectTrigger
data-testid="field-form-direction"
className="w-full bg-background text-muted-foreground"
>
<SelectValue placeholder={t`Select direction`} />
</SelectTrigger>
<SelectContent position="popper">
@@ -214,7 +196,10 @@ export const EditorFieldCheckboxForm = ({
</FormLabel>
<FormControl>
<Select {...field} onValueChange={field.onChange}>
<SelectTrigger className="text-muted-foreground bg-background w-full">
<SelectTrigger
data-testid="field-form-validationRule"
className="w-full bg-background text-muted-foreground"
>
<SelectValue placeholder={t`Select at least`} />
</SelectTrigger>
<SelectContent position="popper">
@@ -245,8 +230,7 @@ export const EditorFieldCheckboxForm = ({
const currentValues = formValues.values || [];
const minimumNumberOfValuesRequired =
validationNumber - currentValues.length;
const minimumNumberOfValuesRequired = validationNumber - currentValues.length;
if (!formValues.validationRule) {
form.setValue('validationRule', checkboxValidationRules[0]);
@@ -260,7 +244,10 @@ export const EditorFieldCheckboxForm = ({
void form.trigger();
}}
>
<SelectTrigger className="text-muted-foreground bg-background mt-5 w-full">
<SelectTrigger
data-testid="field-form-validationLength"
className="mt-5 w-full bg-background text-muted-foreground"
>
<SelectValue placeholder={t`Pick a number`} />
</SelectTrigger>
<SelectContent position="popper">
@@ -286,16 +273,16 @@ export const EditorFieldCheckboxForm = ({
<EditorGenericReadOnlyField formControl={form.control} />
<section className="space-y-2">
<div className="-mx-4 mb-4 mt-2">
<div className="-mx-4 mt-2 mb-4">
<Separator />
</div>
<div className="flex flex-row items-center justify-between gap-2">
<p className="text-sm font-medium">
<p className="font-medium text-sm">
<Trans>Checkbox values</Trans>
</p>
<button type="button" onClick={() => addValue()}>
<button type="button" data-testid="field-form-values-add" onClick={() => addValue()}>
<PlusIcon className="h-4 w-4" />
</button>
</div>
@@ -310,7 +297,8 @@ export const EditorFieldCheckboxForm = ({
<FormItem>
<FormControl>
<Checkbox
className="data-[state=checked]:bg-primary border-foreground/30 h-5 w-5"
data-testid={`field-form-values-${index}-checked`}
className="h-5 w-5 border-foreground/30 data-[state=checked]:bg-primary"
checked={field.value}
onCheckedChange={field.onChange}
/>
@@ -325,7 +313,7 @@ export const EditorFieldCheckboxForm = ({
render={({ field }) => (
<FormItem>
<FormControl>
<Input className="w-full" {...field} />
<Input data-testid={`field-form-values-${index}-value`} className="w-full" {...field} />
</FormControl>
</FormItem>
)}
@@ -333,6 +321,7 @@ export const EditorFieldCheckboxForm = ({
<button
type="button"
data-testid={`field-form-values-${index}-remove`}
className="flex h-10 w-10 items-center justify-center text-slate-500 hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-50"
onClick={() => removeValue(index)}
>
@@ -345,9 +334,7 @@ export const EditorFieldCheckboxForm = ({
{!isValidationRuleMetForPreselectedValues && (
<Alert variant="warning">
<AlertDescription>
<Trans>
The preselected values will be ignored unless they meet the validation criteria.
</Trans>
<Trans>The preselected values will be ignored unless they meet the validation criteria.</Trans>
</AlertDescription>
</Alert>
)}
@@ -1,31 +1,28 @@
import { useEffect } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
DEFAULT_FIELD_FONT_SIZE,
type TDateFieldMeta as DateFieldMeta,
DEFAULT_FIELD_FONT_SIZE,
FIELD_DATE_META_DEFAULT_VALUES,
FIELD_DEFAULT_GENERIC_ALIGN,
ZDateFieldMeta,
} from '@documenso/lib/types/field-meta';
import { Form } from '@documenso/ui/primitives/form/form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
EditorGenericFontSizeField,
EditorGenericTextAlignField,
} from './editor-field-generic-field-forms';
import { EditorGenericFontSizeField, EditorGenericTextAlignField } from './editor-field-generic-field-forms';
const ZDateFieldFormSchema = ZDateFieldMeta.pick({
fontSize: true,
textAlign: true,
overflow: true,
});
type TDateFieldFormSchema = z.infer<typeof ZDateFieldFormSchema>;
type EditorFieldDateFormProps = {
value: DateFieldMeta | undefined;
value: z.input<typeof ZDateFieldMeta> | undefined;
onValueChange: (value: DateFieldMeta) => void;
};
@@ -41,6 +38,7 @@ export const EditorFieldDateForm = ({
defaultValues: {
fontSize: value.fontSize || DEFAULT_FIELD_FONT_SIZE,
textAlign: value.textAlign ?? FIELD_DEFAULT_GENERIC_ALIGN,
overflow: value.overflow || FIELD_DATE_META_DEFAULT_VALUES.overflow,
},
});
@@ -1,35 +1,16 @@
import { useEffect } from 'react';
import { DEFAULT_FIELD_FONT_SIZE, type TDropdownFieldMeta as DropdownFieldMeta } from '@documenso/lib/types/field-meta';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@documenso/ui/primitives/form/form';
import { Input } from '@documenso/ui/primitives/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@documenso/ui/primitives/select';
import { Separator } from '@documenso/ui/primitives/separator';
import { zodResolver } from '@hookform/resolvers/zod';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react/macro';
import { Trans } from '@lingui/react/macro';
import { Trans, useLingui } from '@lingui/react/macro';
import { PlusIcon, Trash } from 'lucide-react';
import { useEffect } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import { z } from 'zod';
import {
DEFAULT_FIELD_FONT_SIZE,
type TDropdownFieldMeta as DropdownFieldMeta,
} from '@documenso/lib/types/field-meta';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@documenso/ui/primitives/form/form';
import { Input } from '@documenso/ui/primitives/input';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@documenso/ui/primitives/select';
import { Separator } from '@documenso/ui/primitives/separator';
import {
EditorGenericFontSizeField,
EditorGenericReadOnlyField,
@@ -96,7 +77,7 @@ export const EditorFieldDropdownForm = ({
mode: 'onChange',
defaultValues: {
defaultValue: value.defaultValue,
values: value.values || [{ value: 'Option 1' }],
values: value.values || [{ value: t`Option 1` }],
required: value.required || false,
readOnly: value.readOnly || false,
fontSize: value.fontSize || DEFAULT_FIELD_FONT_SIZE,
@@ -110,13 +91,13 @@ export const EditorFieldDropdownForm = ({
const addValue = () => {
const currentValues = form.getValues('values') || [];
let newValue = 'New option';
let newValue = t`New option`;
// Iterate to create a unique value
for (let i = 0; i < currentValues.length; i++) {
newValue = `New option ${i + 1}`;
if (currentValues.some((item) => item.value === `New option ${i + 1}`)) {
newValue = `New option ${i + 1}`;
newValue = t`New option ${i + 1}`;
if (currentValues.some((item) => item.value === t`New option ${i + 1}`)) {
newValue = t`New option ${i + 1}`;
} else {
break;
}
@@ -176,7 +157,10 @@ export const EditorFieldDropdownForm = ({
value={field.value ?? '-1'}
onValueChange={(value) => field.onChange(value === '-1' ? undefined : value)}
>
<SelectTrigger className="text-muted-foreground bg-background w-full">
<SelectTrigger
data-testid="field-form-defaultValue"
className="w-full bg-background text-muted-foreground"
>
<SelectValue placeholder={t`Default Value`} />
</SelectTrigger>
<SelectContent position="popper">
@@ -206,16 +190,16 @@ export const EditorFieldDropdownForm = ({
<EditorGenericReadOnlyField formControl={form.control} />
<section className="space-y-2">
<div className="-mx-4 mb-4 mt-2">
<div className="-mx-4 mt-2 mb-4">
<Separator />
</div>
<div className="flex flex-row items-center justify-between gap-2">
<p className="text-sm font-medium">
<p className="font-medium text-sm">
<Trans>Dropdown values</Trans>
</p>
<button type="button" onClick={addValue}>
<button type="button" data-testid="field-form-values-add" onClick={addValue}>
<PlusIcon className="h-4 w-4" />
</button>
</div>
@@ -229,7 +213,7 @@ export const EditorFieldDropdownForm = ({
render={({ field }) => (
<FormItem className="w-full">
<FormControl>
<Input {...field} />
<Input data-testid={`field-form-values-${index}-value`} {...field} />
</FormControl>
<FormMessage />
</FormItem>
@@ -238,6 +222,7 @@ export const EditorFieldDropdownForm = ({
<button
type="button"
data-testid={`field-form-values-${index}-remove`}
className="flex h-10 w-10 items-center justify-center text-slate-500 hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-50"
onClick={() => removeValue(index)}
>
@@ -1,31 +1,28 @@
import { useEffect } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
DEFAULT_FIELD_FONT_SIZE,
type TEmailFieldMeta as EmailFieldMeta,
FIELD_DEFAULT_GENERIC_ALIGN,
FIELD_EMAIL_META_DEFAULT_VALUES,
ZEmailFieldMeta,
} from '@documenso/lib/types/field-meta';
import { Form } from '@documenso/ui/primitives/form/form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
EditorGenericFontSizeField,
EditorGenericTextAlignField,
} from './editor-field-generic-field-forms';
import { EditorGenericFontSizeField, EditorGenericTextAlignField } from './editor-field-generic-field-forms';
const ZEmailFieldFormSchema = ZEmailFieldMeta.pick({
fontSize: true,
textAlign: true,
overflow: true,
});
type TEmailFieldFormSchema = z.infer<typeof ZEmailFieldFormSchema>;
type EditorFieldEmailFormProps = {
value: EmailFieldMeta | undefined;
value: z.input<typeof ZEmailFieldMeta> | undefined;
onValueChange: (value: EmailFieldMeta) => void;
};
@@ -41,6 +38,7 @@ export const EditorFieldEmailForm = ({
defaultValues: {
fontSize: value.fontSize || DEFAULT_FIELD_FONT_SIZE,
textAlign: value.textAlign ?? FIELD_DEFAULT_GENERIC_ALIGN,
overflow: value.overflow || FIELD_EMAIL_META_DEFAULT_VALUES.overflow,
},
});
@@ -1,29 +1,17 @@
import { useEffect } from 'react';
import { Trans, useLingui } from '@lingui/react/macro';
import { type Control, useFormContext } from 'react-hook-form';
import { FIELD_MIN_LINE_HEIGHT } from '@documenso/lib/types/field-meta';
import { FIELD_MAX_LINE_HEIGHT } from '@documenso/lib/types/field-meta';
import { FIELD_MIN_LETTER_SPACING } from '@documenso/lib/types/field-meta';
import { FIELD_MAX_LETTER_SPACING } from '@documenso/lib/types/field-meta';
import {
FIELD_MAX_LETTER_SPACING,
FIELD_MAX_LINE_HEIGHT,
FIELD_MIN_LETTER_SPACING,
FIELD_MIN_LINE_HEIGHT,
} from '@documenso/lib/types/field-meta';
import { cn } from '@documenso/ui/lib/utils';
import { Checkbox } from '@documenso/ui/primitives/checkbox';
import {
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@documenso/ui/primitives/form/form';
import { FormControl, FormField, FormItem, FormLabel, FormMessage } from '@documenso/ui/primitives/form/form';
import { Input } from '@documenso/ui/primitives/input';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@documenso/ui/primitives/select';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@documenso/ui/primitives/select';
import { Trans, useLingui } from '@lingui/react/macro';
import { useEffect } from 'react';
import { type Control, useFormContext } from 'react-hook-form';
// Can't seem to get the non-any type to work with correct types.
// Eg Control<{ fontSize?: number } doesn't seem to work when there are required items.
@@ -50,6 +38,7 @@ export const EditorGenericFontSizeField = ({
</FormLabel>
<FormControl>
<Input
data-testid="field-form-fontSize"
type="number"
min={8}
max={96}
@@ -88,7 +77,7 @@ export const EditorGenericTextAlignField = ({
</FormLabel>
<FormControl>
<Select {...field} onValueChange={field.onChange}>
<SelectTrigger>
<SelectTrigger data-testid="field-form-textAlign">
<SelectValue placeholder={t`Select text align`} />
</SelectTrigger>
<SelectContent>
@@ -131,7 +120,7 @@ export const EditorGenericVerticalAlignField = ({
</FormLabel>
<FormControl>
<Select {...field} onValueChange={field.onChange}>
<SelectTrigger>
<SelectTrigger data-testid="field-form-verticalAlign">
<SelectValue placeholder={t`Select vertical align`} />
</SelectTrigger>
<SelectContent>
@@ -174,6 +163,7 @@ export const EditorGenericLineHeightField = ({
</FormLabel>
<FormControl>
<Input
data-testid="field-form-lineHeight"
type="number"
min={FIELD_MIN_LINE_HEIGHT}
max={FIELD_MAX_LINE_HEIGHT}
@@ -209,6 +199,7 @@ export const EditorGenericLetterSpacingField = ({
</FormLabel>
<FormControl>
<Input
data-testid="field-form-letterSpacing"
type="number"
min={FIELD_MIN_LETTER_SPACING}
max={FIELD_MAX_LETTER_SPACING}
@@ -250,12 +241,13 @@ export const EditorGenericRequiredField = ({
<FormControl>
<div className="flex items-center">
<Checkbox
data-testid="field-form-required"
id="field-required"
checked={field.value}
onCheckedChange={field.onChange}
/>
<label className="text-muted-foreground ml-2 text-sm" htmlFor="field-required">
<label className="ml-2 text-muted-foreground text-sm" htmlFor="field-required">
<Trans>Required Field</Trans>
</label>
</div>
@@ -293,12 +285,13 @@ export const EditorGenericReadOnlyField = ({
<FormControl>
<div className="flex items-center">
<Checkbox
data-testid="field-form-readOnly"
id="field-read-only"
checked={field.value}
onCheckedChange={field.onChange}
/>
<label className="text-muted-foreground ml-2 text-sm" htmlFor="field-read-only">
<label className="ml-2 text-muted-foreground text-sm" htmlFor="field-read-only">
<Trans>Read Only</Trans>
</label>
</div>
@@ -329,7 +322,7 @@ export const EditorGenericLabelField = ({
<Trans>Label</Trans>
</FormLabel>
<FormControl>
<Input placeholder={t`Field label`} {...field} />
<Input data-testid="field-form-label" placeholder={t`Field label`} {...field} />
</FormControl>
<FormMessage />
</FormItem>
@@ -1,9 +1,3 @@
import { useEffect } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
DEFAULT_FIELD_FONT_SIZE,
FIELD_DEFAULT_GENERIC_ALIGN,
@@ -11,11 +5,12 @@ import {
ZInitialsFieldMeta,
} from '@documenso/lib/types/field-meta';
import { Form } from '@documenso/ui/primitives/form/form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
EditorGenericFontSizeField,
EditorGenericTextAlignField,
} from './editor-field-generic-field-forms';
import { EditorGenericFontSizeField, EditorGenericTextAlignField } from './editor-field-generic-field-forms';
const ZInitialsFieldFormSchema = ZInitialsFieldMeta.pick({
fontSize: true,
@@ -1,9 +1,3 @@
import { useEffect } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
DEFAULT_FIELD_FONT_SIZE,
FIELD_DEFAULT_GENERIC_ALIGN,
@@ -11,11 +5,12 @@ import {
ZNameFieldMeta,
} from '@documenso/lib/types/field-meta';
import { Form } from '@documenso/ui/primitives/form/form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
EditorGenericFontSizeField,
EditorGenericTextAlignField,
} from './editor-field-generic-field-forms';
import { EditorGenericFontSizeField, EditorGenericTextAlignField } from './editor-field-generic-field-forms';
const ZNameFieldFormSchema = ZNameFieldMeta.pick({
fontSize: true,
@@ -1,10 +1,3 @@
import { useEffect } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { Trans, useLingui } from '@lingui/react/macro';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
DEFAULT_FIELD_FONT_SIZE,
FIELD_DEFAULT_GENERIC_ALIGN,
@@ -15,23 +8,15 @@ import {
ZNumberFieldMeta,
} from '@documenso/lib/types/field-meta';
import { numberFormatValues } from '@documenso/ui/primitives/document-flow/field-items-advanced-settings/constants';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@documenso/ui/primitives/form/form';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@documenso/ui/primitives/form/form';
import { Input } from '@documenso/ui/primitives/input';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@documenso/ui/primitives/select';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@documenso/ui/primitives/select';
import { Separator } from '@documenso/ui/primitives/separator';
import { zodResolver } from '@hookform/resolvers/zod';
import { Trans, useLingui } from '@lingui/react/macro';
import { useEffect } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
EditorGenericFontSizeField,
@@ -167,7 +152,12 @@ export const EditorFieldNumberForm = ({
<Trans>Placeholder</Trans>
</FormLabel>
<FormControl>
<Input className="bg-background" placeholder={t`Placeholder`} {...field} />
<Input
data-testid="field-form-placeholder"
className="bg-background"
placeholder={t`Placeholder`}
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
@@ -183,7 +173,7 @@ export const EditorFieldNumberForm = ({
<Trans>Value</Trans>
</FormLabel>
<FormControl>
<Input className="bg-background" placeholder={t`Value`} {...field} />
<Input data-testid="field-form-value" className="bg-background" placeholder={t`Value`} {...field} />
</FormControl>
<FormMessage />
</FormItem>
@@ -203,7 +193,10 @@ export const EditorFieldNumberForm = ({
value={field.value === null ? '-1' : field.value}
onValueChange={(value) => field.onChange(value === '-1' ? null : value)}
>
<SelectTrigger className="text-muted-foreground bg-background w-full">
<SelectTrigger
data-testid="field-form-numberFormat"
className="w-full bg-background text-muted-foreground"
>
<SelectValue placeholder={t`Field format`} />
</SelectTrigger>
<SelectContent position="popper">
@@ -238,11 +231,11 @@ export const EditorFieldNumberForm = ({
{/* Validation section */}
<section className="space-y-2">
<div className="-mx-4 mb-4 mt-2">
<div className="-mx-4 mt-2 mb-4">
<Separator />
</div>
<p className="text-sm font-medium">
<p className="font-medium text-sm">
<Trans>Validation</Trans>
</p>
@@ -257,13 +250,12 @@ export const EditorFieldNumberForm = ({
</FormLabel>
<FormControl>
<Input
data-testid="field-form-minValue"
className="bg-background"
placeholder="E.g. 0"
placeholder={t`E.g. 0`}
{...field}
value={field.value ?? ''}
onChange={(e) =>
field.onChange(e.target.value === '' ? null : e.target.value)
}
onChange={(e) => field.onChange(e.target.value === '' ? null : e.target.value)}
/>
</FormControl>
<FormMessage />
@@ -281,13 +273,12 @@ export const EditorFieldNumberForm = ({
</FormLabel>
<FormControl>
<Input
data-testid="field-form-maxValue"
className="bg-background"
placeholder="E.g. 100"
placeholder={t`E.g. 100`}
{...field}
value={field.value ?? ''}
onChange={(e) =>
field.onChange(e.target.value === '' ? null : e.target.value)
}
onChange={(e) => field.onChange(e.target.value === '' ? null : e.target.value)}
/>
</FormControl>
<FormMessage />
@@ -1,34 +1,19 @@
import { useEffect } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { Trans, useLingui } from '@lingui/react/macro';
import { PlusIcon, Trash } from 'lucide-react';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
DEFAULT_FIELD_FONT_SIZE,
type TRadioFieldMeta as RadioFieldMeta,
ZRadioFieldMeta,
} from '@documenso/lib/types/field-meta';
import { Checkbox } from '@documenso/ui/primitives/checkbox';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@documenso/ui/primitives/form/form';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@documenso/ui/primitives/form/form';
import { Input } from '@documenso/ui/primitives/input';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@documenso/ui/primitives/select';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@documenso/ui/primitives/select';
import { Separator } from '@documenso/ui/primitives/separator';
import { zodResolver } from '@hookform/resolvers/zod';
import { Trans, useLingui } from '@lingui/react/macro';
import { PlusIcon, Trash } from 'lucide-react';
import { useEffect } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
EditorGenericFontSizeField,
@@ -79,7 +64,7 @@ export const EditorFieldRadioForm = ({
mode: 'onChange',
defaultValues: {
label: value.label || '',
values: value.values || [{ id: 1, checked: false, value: 'Default value' }],
values: value.values || [{ id: 1, checked: false, value: t`Default value` }],
required: value.required || false,
readOnly: value.readOnly || false,
direction: value.direction || 'vertical',
@@ -93,8 +78,7 @@ export const EditorFieldRadioForm = ({
const addValue = () => {
const currentValues = form.getValues('values') || [];
const newId =
currentValues.length > 0 ? Math.max(...currentValues.map((val) => val.id)) + 1 : 1;
const newId = currentValues.length > 0 ? Math.max(...currentValues.map((val) => val.id)) + 1 : 1;
const newValues = [...currentValues, { id: newId, checked: false, value: '' }];
form.setValue('values', newValues);
@@ -140,7 +124,10 @@ export const EditorFieldRadioForm = ({
</FormLabel>
<FormControl>
<Select value={field.value} onValueChange={field.onChange}>
<SelectTrigger className="text-muted-foreground bg-background w-full">
<SelectTrigger
data-testid="field-form-direction"
className="w-full bg-background text-muted-foreground"
>
<SelectValue placeholder={t`Select direction`} />
</SelectTrigger>
<SelectContent position="popper">
@@ -163,16 +150,16 @@ export const EditorFieldRadioForm = ({
<EditorGenericReadOnlyField formControl={form.control} />
<section className="space-y-2">
<div className="-mx-4 mb-4 mt-2">
<div className="-mx-4 mt-2 mb-4">
<Separator />
</div>
<div className="flex flex-row items-center justify-between gap-2">
<p className="text-sm font-medium">
<p className="font-medium text-sm">
<Trans>Radio values</Trans>
</p>
<button type="button" onClick={addValue}>
<button type="button" data-testid="field-form-values-add" onClick={addValue}>
<PlusIcon className="h-4 w-4" />
</button>
</div>
@@ -187,7 +174,8 @@ export const EditorFieldRadioForm = ({
<FormItem>
<FormControl>
<Checkbox
className="data-[state=checked]:bg-primary border-foreground/30 h-5 w-5"
data-testid={`field-form-values-${index}-checked`}
className="h-5 w-5 border-foreground/30 data-[state=checked]:bg-primary"
checked={field.value}
onCheckedChange={(value) => {
// Uncheck all other values.
@@ -216,7 +204,7 @@ export const EditorFieldRadioForm = ({
render={({ field }) => (
<FormItem>
<FormControl>
<Input className="w-full" {...field} />
<Input data-testid={`field-form-values-${index}-value`} className="w-full" {...field} />
</FormControl>
</FormItem>
)}
@@ -224,6 +212,7 @@ export const EditorFieldRadioForm = ({
<button
type="button"
data-testid={`field-form-values-${index}-remove`}
className="flex h-10 w-10 items-center justify-center text-slate-500 hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-50"
onClick={() => removeValue(index)}
>
@@ -1,24 +1,27 @@
import { useEffect } from 'react';
import { DEFAULT_SIGNATURE_TEXT_FONT_SIZE } from '@documenso/lib/constants/pdf';
import {
FIELD_SIGNATURE_META_DEFAULT_VALUES,
type TSignatureFieldMeta,
ZSignatureFieldMeta,
} from '@documenso/lib/types/field-meta';
import { Form } from '@documenso/ui/primitives/form/form';
import { zodResolver } from '@hookform/resolvers/zod';
import { Trans } from '@lingui/react/macro';
import { useEffect } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import { DEFAULT_SIGNATURE_TEXT_FONT_SIZE } from '@documenso/lib/constants/pdf';
import { type TSignatureFieldMeta, ZSignatureFieldMeta } from '@documenso/lib/types/field-meta';
import { Form } from '@documenso/ui/primitives/form/form';
import { EditorGenericFontSizeField } from './editor-field-generic-field-forms';
const ZSignatureFieldFormSchema = ZSignatureFieldMeta.pick({
fontSize: true,
overflow: true,
});
type TSignatureFieldFormSchema = z.infer<typeof ZSignatureFieldFormSchema>;
type EditorFieldSignatureFormProps = {
value: TSignatureFieldMeta | undefined;
value: z.input<typeof ZSignatureFieldMeta> | undefined;
onValueChange: (value: TSignatureFieldMeta) => void;
};
@@ -32,6 +35,7 @@ export const EditorFieldSignatureForm = ({
resolver: zodResolver(ZSignatureFieldFormSchema),
mode: 'onChange',
defaultValues: {
overflow: value.overflow || FIELD_SIGNATURE_META_DEFAULT_VALUES.overflow,
fontSize: value.fontSize || DEFAULT_SIGNATURE_TEXT_FONT_SIZE,
},
});
@@ -60,7 +64,7 @@ export const EditorFieldSignatureForm = ({
<fieldset className="flex flex-col gap-2">
<div>
<EditorGenericFontSizeField formControl={form.control} />
<p className="text-muted-foreground mt-0.5 text-xs">
<p className="mt-0.5 text-muted-foreground text-xs">
<Trans>The typed signature font size</Trans>
</p>
</div>
@@ -1,10 +1,3 @@
import { useEffect } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { Trans, useLingui } from '@lingui/react/macro';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
DEFAULT_FIELD_FONT_SIZE,
FIELD_DEFAULT_GENERIC_ALIGN,
@@ -14,16 +7,14 @@ import {
type TTextFieldMeta as TextFieldMeta,
ZTextFieldMeta,
} from '@documenso/lib/types/field-meta';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@documenso/ui/primitives/form/form';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@documenso/ui/primitives/form/form';
import { Input } from '@documenso/ui/primitives/input';
import { Textarea } from '@documenso/ui/primitives/textarea';
import { zodResolver } from '@hookform/resolvers/zod';
import { Trans, useLingui } from '@lingui/react/macro';
import { useEffect } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import type { z } from 'zod';
import {
EditorGenericFontSizeField,
@@ -134,7 +125,7 @@ export const EditorFieldTextForm = ({
<Trans>Label</Trans>
</FormLabel>
<FormControl>
<Input placeholder={t`Field label`} {...field} />
<Input data-testid="field-form-label" placeholder={t`Field label`} {...field} />
</FormControl>
<FormMessage />
</FormItem>
@@ -150,7 +141,7 @@ export const EditorFieldTextForm = ({
<Trans>Placeholder</Trans>
</FormLabel>
<FormControl>
<Input placeholder={t`Field placeholder`} {...field} />
<Input data-testid="field-form-placeholder" placeholder={t`Field placeholder`} {...field} />
</FormControl>
<FormMessage />
</FormItem>
@@ -167,6 +158,7 @@ export const EditorFieldTextForm = ({
</FormLabel>
<FormControl>
<Textarea
data-testid="field-form-text"
className="h-auto"
placeholder={t`Add text to the field`}
{...field}
@@ -200,6 +192,7 @@ export const EditorFieldTextForm = ({
</FormLabel>
<FormControl>
<Input
data-testid="field-form-characterLimit"
className="bg-background"
placeholder={t`Character limit`}
{...field}