mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 00:03:33 +10:00
feat: add additional field options (#2154)
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import type { Recipient } from '@prisma/client';
|
||||
import type { Field, Recipient } from '@prisma/client';
|
||||
import { FieldType } from '@prisma/client';
|
||||
import { useFieldArray, useForm } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
@ -63,6 +63,8 @@ type UseEditorFieldsResponse = {
|
||||
// Selected recipient
|
||||
selectedRecipient: Recipient | null;
|
||||
setSelectedRecipient: (recipientId: number | null) => void;
|
||||
|
||||
resetForm: (fields?: Field[]) => void;
|
||||
};
|
||||
|
||||
export const useEditorFields = ({
|
||||
@ -72,24 +74,30 @@ export const useEditorFields = ({
|
||||
const [selectedFieldFormId, setSelectedFieldFormId] = useState<string | null>(null);
|
||||
const [selectedRecipientId, setSelectedRecipientId] = useState<number | null>(null);
|
||||
|
||||
const generateDefaultValues = (fields?: Field[]) => {
|
||||
const formFields = (fields || envelope.fields).map(
|
||||
(field): TLocalField => ({
|
||||
id: field.id,
|
||||
formId: nanoid(),
|
||||
envelopeItemId: field.envelopeItemId,
|
||||
page: field.page,
|
||||
type: field.type,
|
||||
positionX: Number(field.positionX),
|
||||
positionY: Number(field.positionY),
|
||||
width: Number(field.width),
|
||||
height: Number(field.height),
|
||||
recipientId: field.recipientId,
|
||||
fieldMeta: field.fieldMeta ? ZFieldMetaSchema.parse(field.fieldMeta) : undefined,
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
fields: formFields,
|
||||
};
|
||||
};
|
||||
|
||||
const form = useForm<TEditorFieldsFormSchema>({
|
||||
defaultValues: {
|
||||
fields: envelope.fields.map(
|
||||
(field): TLocalField => ({
|
||||
id: field.id,
|
||||
formId: nanoid(),
|
||||
envelopeItemId: field.envelopeItemId,
|
||||
page: field.page,
|
||||
type: field.type,
|
||||
positionX: Number(field.positionX),
|
||||
positionY: Number(field.positionY),
|
||||
width: Number(field.width),
|
||||
height: Number(field.height),
|
||||
recipientId: field.recipientId,
|
||||
fieldMeta: field.fieldMeta ? ZFieldMetaSchema.parse(field.fieldMeta) : undefined,
|
||||
}),
|
||||
),
|
||||
},
|
||||
defaultValues: generateDefaultValues(),
|
||||
resolver: zodResolver(ZEditorFieldsFormSchema),
|
||||
});
|
||||
|
||||
@ -272,6 +280,10 @@ export const useEditorFields = ({
|
||||
setSelectedRecipientId(foundRecipient?.id ?? null);
|
||||
};
|
||||
|
||||
const resetForm = (fields?: Field[]) => {
|
||||
form.reset(generateDefaultValues(fields));
|
||||
};
|
||||
|
||||
return {
|
||||
// Core state
|
||||
localFields,
|
||||
@ -295,6 +307,8 @@ export const useEditorFields = ({
|
||||
// Selected recipient
|
||||
selectedRecipient,
|
||||
setSelectedRecipient,
|
||||
|
||||
resetForm,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -30,6 +30,8 @@ type EnvelopeRenderItem = TEnvelope['envelopeItems'][number];
|
||||
type EnvelopeRenderProviderValue = {
|
||||
getPdfBuffer: (envelopeItemId: string) => FileData | null;
|
||||
envelopeItems: EnvelopeRenderItem[];
|
||||
envelopeStatus: TEnvelope['status'];
|
||||
envelopeType: TEnvelope['type'];
|
||||
currentEnvelopeItem: EnvelopeRenderItem | null;
|
||||
setCurrentEnvelopeItem: (envelopeItemId: string) => void;
|
||||
fields: Field[];
|
||||
@ -44,7 +46,7 @@ type EnvelopeRenderProviderValue = {
|
||||
interface EnvelopeRenderProviderProps {
|
||||
children: React.ReactNode;
|
||||
|
||||
envelope: Pick<TEnvelope, 'envelopeItems'>;
|
||||
envelope: Pick<TEnvelope, 'envelopeItems' | 'status' | 'type'>;
|
||||
|
||||
/**
|
||||
* Optional fields which are passed down to renderers for custom rendering needs.
|
||||
@ -100,7 +102,7 @@ export const EnvelopeRenderProvider = ({
|
||||
// Indexed by documentDataId.
|
||||
const [files, setFiles] = useState<Record<string, FileData>>({});
|
||||
|
||||
const [currentItem, setItem] = useState<EnvelopeRenderItem | null>(null);
|
||||
const [currentItem, setCurrentItem] = useState<EnvelopeRenderItem | null>(null);
|
||||
|
||||
const [renderError, setRenderError] = useState<boolean>(false);
|
||||
|
||||
@ -163,11 +165,15 @@ export const EnvelopeRenderProvider = ({
|
||||
const setCurrentEnvelopeItem = (envelopeItemId: string) => {
|
||||
const foundItem = envelope.envelopeItems.find((item) => item.id === envelopeItemId);
|
||||
|
||||
setItem(foundItem ?? null);
|
||||
setCurrentItem(foundItem ?? null);
|
||||
};
|
||||
|
||||
// Set the selected item to the first item if none is set.
|
||||
useEffect(() => {
|
||||
if (currentItem && !envelopeItems.some((item) => item.id === currentItem.id)) {
|
||||
setCurrentItem(null);
|
||||
}
|
||||
|
||||
if (!currentItem && envelopeItems.length > 0) {
|
||||
setCurrentEnvelopeItem(envelopeItems[0].id);
|
||||
}
|
||||
@ -203,6 +209,8 @@ export const EnvelopeRenderProvider = ({
|
||||
value={{
|
||||
getPdfBuffer,
|
||||
envelopeItems,
|
||||
envelopeStatus: envelope.status,
|
||||
envelopeType: envelope.type,
|
||||
currentEnvelopeItem: currentItem,
|
||||
setCurrentEnvelopeItem,
|
||||
fields: fields ?? [],
|
||||
|
||||
Reference in New Issue
Block a user