mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 16:23:06 +10:00
Merge branch 'main' into reattach-pdf
This commit is contained in:
@ -326,9 +326,9 @@ export const AddFieldsFormPartial = ({
|
||||
{selectedField && (
|
||||
<Card
|
||||
className={cn(
|
||||
'bg-background pointer-events-none fixed z-50 cursor-pointer transition-opacity',
|
||||
'bg-field-card/80 pointer-events-none fixed z-50 cursor-pointer border-2 backdrop-blur-[1px]',
|
||||
{
|
||||
'border-primary': isFieldWithinBounds,
|
||||
'border-field-card-border': isFieldWithinBounds,
|
||||
'opacity-50': !isFieldWithinBounds,
|
||||
},
|
||||
)}
|
||||
@ -339,7 +339,7 @@ export const AddFieldsFormPartial = ({
|
||||
width: fieldBounds.current.width,
|
||||
}}
|
||||
>
|
||||
<CardContent className="text-foreground flex h-full w-full items-center justify-center p-2">
|
||||
<CardContent className="text-field-card-foreground flex h-full w-full items-center justify-center p-2">
|
||||
{FRIENDLY_FIELD_TYPE[selectedField]}
|
||||
</CardContent>
|
||||
</Card>
|
||||
@ -555,6 +555,28 @@ export const AddFieldsFormPartial = ({
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="group h-full w-full"
|
||||
onClick={() => setSelectedField(FieldType.TEXT)}
|
||||
onMouseDown={() => setSelectedField(FieldType.TEXT)}
|
||||
data-selected={selectedField === FieldType.TEXT ? true : undefined}
|
||||
>
|
||||
<Card className="group-data-[selected]:border-documenso h-full w-full cursor-pointer group-disabled:opacity-50">
|
||||
<CardContent className="flex flex-col items-center justify-center px-6 py-4">
|
||||
<p
|
||||
className={cn(
|
||||
'text-muted-foreground group-data-[selected]:text-foreground text-xl font-medium',
|
||||
)}
|
||||
>
|
||||
{'Text'}
|
||||
</p>
|
||||
|
||||
<p className="text-muted-foreground mt-2 text-xs">Custom Text</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</button>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -44,6 +44,7 @@ export type AddSignatureFormProps = {
|
||||
|
||||
onSubmit: (_data: TAddSignatureFormSchema) => Promise<void> | void;
|
||||
requireName?: boolean;
|
||||
requireCustomText?: boolean;
|
||||
requireSignature?: boolean;
|
||||
};
|
||||
|
||||
@ -54,6 +55,7 @@ export const AddSignatureFormPartial = ({
|
||||
|
||||
onSubmit,
|
||||
requireName = false,
|
||||
requireCustomText = false,
|
||||
requireSignature = true,
|
||||
}: AddSignatureFormProps) => {
|
||||
const { currentStep, totalSteps } = useStep();
|
||||
@ -70,6 +72,14 @@ export const AddSignatureFormPartial = ({
|
||||
});
|
||||
}
|
||||
|
||||
if (requireCustomText && val.customText.length === 0) {
|
||||
ctx.addIssue({
|
||||
path: ['customText'],
|
||||
code: 'custom',
|
||||
message: 'Text is required',
|
||||
});
|
||||
}
|
||||
|
||||
if (requireSignature && val.signature.length === 0) {
|
||||
ctx.addIssue({
|
||||
path: ['signature'],
|
||||
@ -85,6 +95,7 @@ export const AddSignatureFormPartial = ({
|
||||
name: '',
|
||||
email: '',
|
||||
signature: '',
|
||||
customText: '',
|
||||
},
|
||||
});
|
||||
|
||||
@ -131,6 +142,11 @@ export const AddSignatureFormPartial = ({
|
||||
return !form.formState.errors.email;
|
||||
}
|
||||
|
||||
if (fieldType === FieldType.TEXT) {
|
||||
await form.trigger('customText');
|
||||
return !form.formState.errors.customText;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -154,6 +170,11 @@ export const AddSignatureFormPartial = ({
|
||||
customText: form.getValues('name'),
|
||||
inserted: true,
|
||||
}))
|
||||
.with(FieldType.TEXT, () => ({
|
||||
...field,
|
||||
customText: form.getValues('customText'),
|
||||
inserted: true,
|
||||
}))
|
||||
.with(FieldType.SIGNATURE, () => {
|
||||
const value = form.getValues('signature');
|
||||
|
||||
@ -302,6 +323,29 @@ export const AddSignatureFormPartial = ({
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{requireCustomText && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="customText"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel required={requireCustomText}>Custom Text</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
className="bg-background"
|
||||
{...field}
|
||||
onChange={(value) => {
|
||||
onFormValueChange(FieldType.TEXT);
|
||||
field.onChange(value);
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</DocumentFlowFormContainerContent>
|
||||
|
||||
@ -330,7 +374,7 @@ export const AddSignatureFormPartial = ({
|
||||
<ElementVisible target={PDF_VIEWER_PAGE_SELECTOR}>
|
||||
{localFields.map((field) =>
|
||||
match(field.type)
|
||||
.with(FieldType.DATE, FieldType.EMAIL, FieldType.NAME, () => {
|
||||
.with(FieldType.DATE, FieldType.TEXT, FieldType.EMAIL, FieldType.NAME, () => {
|
||||
return (
|
||||
<SinglePlayerModeCustomTextField
|
||||
onClick={insertField(field)}
|
||||
|
||||
@ -6,6 +6,7 @@ export const ZAddSignatureFormSchema = z.object({
|
||||
.min(1, { message: 'Email is required' })
|
||||
.email({ message: 'Invalid email address' }),
|
||||
name: z.string(),
|
||||
customText: z.string(),
|
||||
signature: z.string(),
|
||||
});
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import React, { useId } from 'react';
|
||||
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { BadgeCheck, Copy, Eye, PencilLine, Plus, Trash } from 'lucide-react';
|
||||
import { Plus, Trash } from 'lucide-react';
|
||||
import { Controller, useFieldArray, useForm } from 'react-hook-form';
|
||||
|
||||
import { useLimits } from '@documenso/ee/server-only/limits/provider/client';
|
||||
@ -17,6 +17,7 @@ import { Button } from '../button';
|
||||
import { FormErrorMessage } from '../form/form-error-message';
|
||||
import { Input } from '../input';
|
||||
import { Label } from '../label';
|
||||
import { ROLE_ICONS } from '../recipient-role-icons';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger } from '../select';
|
||||
import { useStep } from '../stepper';
|
||||
import { useToast } from '../use-toast';
|
||||
@ -32,13 +33,6 @@ import {
|
||||
import { ShowFieldItem } from './show-field-item';
|
||||
import type { DocumentFlowStep } from './types';
|
||||
|
||||
const ROLE_ICONS: Record<RecipientRole, JSX.Element> = {
|
||||
SIGNER: <PencilLine className="h-4 w-4" />,
|
||||
APPROVER: <BadgeCheck className="h-4 w-4" />,
|
||||
CC: <Copy className="h-4 w-4" />,
|
||||
VIEWER: <Eye className="h-4 w-4" />,
|
||||
};
|
||||
|
||||
export type AddSignersFormProps = {
|
||||
documentFlow: DocumentFlowStep;
|
||||
recipients: Recipient[];
|
||||
|
||||
@ -226,7 +226,7 @@ export const AddSubjectFormPartial = ({
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="flex flex-col">
|
||||
<div className="mt-2 flex flex-col">
|
||||
<div className="flex flex-col gap-y-4">
|
||||
<div>
|
||||
<Label htmlFor="redirectUrl" className="flex items-center">
|
||||
|
||||
@ -128,24 +128,22 @@ export const FieldItem = ({
|
||||
)}
|
||||
|
||||
<Card
|
||||
className={cn('bg-background h-full w-full', {
|
||||
'border-primary': !disabled,
|
||||
'border-primary/80': active,
|
||||
className={cn('bg-field-card/80 h-full w-full backdrop-blur-[1px]', {
|
||||
'border-field-card-border': !disabled,
|
||||
'border-field-card-border/80': active,
|
||||
})}
|
||||
>
|
||||
<CardContent
|
||||
className={cn(
|
||||
'text-foreground flex h-full w-full flex-col items-center justify-center p-2',
|
||||
'text-field-card-foreground flex h-full w-full flex-col items-center justify-center p-2',
|
||||
{
|
||||
'text-muted-foreground/50': disabled,
|
||||
'text-field-card-foreground/50': disabled,
|
||||
},
|
||||
)}
|
||||
>
|
||||
{FRIENDLY_FIELD_TYPE[field.type]}
|
||||
|
||||
<p className="text-muted-foreground/50 w-full truncate text-center text-xs">
|
||||
{field.signerEmail}
|
||||
</p>
|
||||
<p className="w-full truncate text-center text-xs">{field.signerEmail}</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Rnd>,
|
||||
|
||||
@ -172,6 +172,7 @@ export function SinglePlayerModeCustomTextField({
|
||||
.with(FieldType.DATE, () => 'Date')
|
||||
.with(FieldType.NAME, () => 'Name')
|
||||
.with(FieldType.EMAIL, () => 'Email')
|
||||
.with(FieldType.TEXT, () => 'Text')
|
||||
.with(FieldType.SIGNATURE, FieldType.FREE_SIGNATURE, () => 'Signature')
|
||||
.otherwise(() => '')}
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user