chore: make duplicate recipients work for remplates

This commit is contained in:
Catalin Pit
2025-02-07 14:29:38 +02:00
parent 2896673a23
commit 64964f420a
5 changed files with 64 additions and 22 deletions

View File

@ -101,13 +101,15 @@ export const setTemplateRecipients = async ({
}, },
}); });
const removedRecipients = existingRecipients.filter( const removedRecipients = existingRecipients.filter((existingRecipient) => {
(existingRecipient) => // Keep direct template recipients from being removed
!normalizedRecipients.find( if (template.directLink?.directTemplateRecipientId === existingRecipient.id) {
(recipient) => return false;
recipient.id === existingRecipient.id || recipient.email === existingRecipient.email, }
),
); // Check if this recipient still exists in the normalized recipients
return !normalizedRecipients.some((recipient) => recipient.id === existingRecipient.id);
});
if (template.directLink !== null) { if (template.directLink !== null) {
const updatedDirectRecipient = recipients.find( const updatedDirectRecipient = recipients.find(
@ -132,15 +134,24 @@ export const setTemplateRecipients = async ({
} }
const linkedRecipients = normalizedRecipients.map((recipient) => { const linkedRecipients = normalizedRecipients.map((recipient) => {
const existing = existingRecipients.find( // For direct template recipients, match by ID only
(existingRecipient) => if (template.directLink?.directTemplateRecipientId === recipient.id) {
existingRecipient.id === recipient.id || existingRecipient.email === recipient.email, const existing = existingRecipients.find(
); (existingRecipient) => existingRecipient.id === recipient.id,
);
return { ...recipient, _persisted: existing };
}
return { // For other recipients, match by ID if it exists
...recipient, if (recipient.id) {
_persisted: existing, const existing = existingRecipients.find(
}; (existingRecipient) => existingRecipient.id === recipient.id,
);
return { ...recipient, _persisted: existing };
}
// For new recipients, create a new entry
return { ...recipient, _persisted: undefined };
}); });
const persistedRecipients = await prisma.$transaction(async (tx) => { const persistedRecipients = await prisma.$transaction(async (tx) => {

View File

@ -204,6 +204,7 @@ export const AddTemplateFieldsFormPartial = ({
event.preventDefault(); event.preventDefault();
const copiedField = structuredClone(fieldClipboard); const copiedField = structuredClone(fieldClipboard);
const signerIndex = recipients.findIndex((r) => r.id === selectedSigner?.id);
append({ append({
...copiedField, ...copiedField,
@ -212,12 +213,20 @@ export const AddTemplateFieldsFormPartial = ({
signerId: selectedSigner?.id ?? copiedField.signerId, signerId: selectedSigner?.id ?? copiedField.signerId,
recipientId: selectedSigner?.id || copiedField.recipientId || copiedField.signerId || 0, recipientId: selectedSigner?.id || copiedField.recipientId || copiedField.signerId || 0,
signerToken: selectedSigner?.token ?? copiedField.signerToken, signerToken: selectedSigner?.token ?? copiedField.signerToken,
signerIndex: signerIndex >= 0 ? signerIndex : 0,
pageX: copiedField.pageX + 3, pageX: copiedField.pageX + 3,
pageY: copiedField.pageY + 3, pageY: copiedField.pageY + 3,
}); });
} }
}, },
[append, fieldClipboard, selectedSigner?.email, selectedSigner?.id, selectedSigner?.token], [
append,
fieldClipboard,
selectedSigner?.email,
selectedSigner?.id,
selectedSigner?.token,
recipients,
],
); );
useHotkeys(['ctrl+c', 'meta+c'], (evt) => onFieldCopy(evt)); useHotkeys(['ctrl+c', 'meta+c'], (evt) => onFieldCopy(evt));
@ -323,6 +332,8 @@ export const AddTemplateFieldsFormPartial = ({
pageX -= fieldPageWidth / 2; pageX -= fieldPageWidth / 2;
pageY -= fieldPageHeight / 2; pageY -= fieldPageHeight / 2;
const signerIndex = recipients.findIndex((r) => r.id === selectedSigner.id);
append({ append({
formId: nanoid(12), formId: nanoid(12),
type: selectedField, type: selectedField,
@ -336,13 +347,14 @@ export const AddTemplateFieldsFormPartial = ({
recipientId: recipientId:
selectedSigner.id || lastActiveField?.recipientId || lastActiveField?.signerId || 0, selectedSigner.id || lastActiveField?.recipientId || lastActiveField?.signerId || 0,
signerToken: selectedSigner.token ?? '', signerToken: selectedSigner.token ?? '',
signerIndex: signerIndex >= 0 ? signerIndex : 0,
fieldMeta: undefined, fieldMeta: undefined,
}); });
setIsFieldWithinBounds(false); setIsFieldWithinBounds(false);
setSelectedField(null); setSelectedField(null);
}, },
[append, isWithinPageBounds, selectedField, selectedSigner, getPage], [append, isWithinPageBounds, selectedField, selectedSigner, getPage, recipients],
); );
const onFieldResize = useCallback( const onFieldResize = useCallback(
@ -552,14 +564,15 @@ export const AddTemplateFieldsFormPartial = ({
)} )}
{localFields.map((field, index) => { {localFields.map((field, index) => {
const recipientIndex = recipients.findIndex((r) => r.email === field.signerEmail); const recipientIndex =
field.signerIndex ?? recipients.findIndex((r) => r.id === field.signerId);
return ( return (
<FieldItem <FieldItem
key={index} key={index}
recipientIndex={recipientIndex === -1 ? 0 : recipientIndex} recipientIndex={recipientIndex >= 0 ? recipientIndex : 0}
field={field} field={field}
disabled={selectedSigner?.email !== field.signerEmail} disabled={selectedSigner?.id !== field.signerId}
minHeight={MIN_HEIGHT_PX} minHeight={MIN_HEIGHT_PX}
minWidth={MIN_WIDTH_PX} minWidth={MIN_WIDTH_PX}
defaultHeight={DEFAULT_HEIGHT_PX} defaultHeight={DEFAULT_HEIGHT_PX}

View File

@ -18,6 +18,7 @@ export const ZAddTemplateFieldsFormSchema = z.object({
pageY: z.number().min(0), pageY: z.number().min(0),
pageWidth: z.number().min(0), pageWidth: z.number().min(0),
pageHeight: z.number().min(0), pageHeight: z.number().min(0),
signerIndex: z.number().min(0),
fieldMeta: ZFieldMetaSchema, fieldMeta: ZFieldMetaSchema,
}), }),
), ),

View File

@ -92,6 +92,7 @@ export const AddTemplatePlaceholderRecipientsFormPartial = ({
actionAuth: undefined, actionAuth: undefined,
...generateRecipientPlaceholder(1), ...generateRecipientPlaceholder(1),
signingOrder: 1, signingOrder: 1,
signerIndex: 0,
}, },
]; ];
} }
@ -104,6 +105,7 @@ export const AddTemplatePlaceholderRecipientsFormPartial = ({
role: recipient.role, role: recipient.role,
actionAuth: ZRecipientAuthOptionsSchema.parse(recipient.authOptions)?.actionAuth ?? undefined, actionAuth: ZRecipientAuthOptionsSchema.parse(recipient.authOptions)?.actionAuth ?? undefined,
signingOrder: recipient.signingOrder ?? index + 1, signingOrder: recipient.signingOrder ?? index + 1,
signerIndex: index,
})); }));
if (signingOrder === DocumentSigningOrder.SEQUENTIAL) { if (signingOrder === DocumentSigningOrder.SEQUENTIAL) {
@ -174,21 +176,35 @@ export const AddTemplatePlaceholderRecipientsFormPartial = ({
}); });
const onAddPlaceholderSelfRecipient = () => { const onAddPlaceholderSelfRecipient = () => {
const currentSigners = form.getValues('signers');
const nextSignerIndex = currentSigners.length;
appendSigner({ appendSigner({
formId: nanoid(12), formId: nanoid(12),
name: user?.name ?? '', name: user?.name ?? '',
email: user?.email ?? '', email: user?.email ?? '',
role: RecipientRole.SIGNER, role: RecipientRole.SIGNER,
signingOrder: signers.length > 0 ? (signers[signers.length - 1]?.signingOrder ?? 0) + 1 : 1, signingOrder:
currentSigners.length > 0
? (currentSigners[currentSigners.length - 1]?.signingOrder ?? 0) + 1
: 1,
signerIndex: nextSignerIndex,
}); });
}; };
const onAddPlaceholderRecipient = () => { const onAddPlaceholderRecipient = () => {
const currentSigners = form.getValues('signers');
const nextSignerIndex = currentSigners.length;
appendSigner({ appendSigner({
formId: nanoid(12), formId: nanoid(12),
role: RecipientRole.SIGNER, role: RecipientRole.SIGNER,
...generateRecipientPlaceholder(placeholderRecipientCount), ...generateRecipientPlaceholder(placeholderRecipientCount),
signingOrder: signers.length > 0 ? (signers[signers.length - 1]?.signingOrder ?? 0) + 1 : 1, signingOrder:
currentSigners.length > 0
? (currentSigners[currentSigners.length - 1]?.signingOrder ?? 0) + 1
: 1,
signerIndex: nextSignerIndex,
}); });
setPlaceholderRecipientCount((count) => count + 1); setPlaceholderRecipientCount((count) => count + 1);

View File

@ -14,6 +14,7 @@ export const ZAddTemplatePlacholderRecipientsFormSchema = z.object({
name: z.string(), name: z.string(),
role: z.nativeEnum(RecipientRole), role: z.nativeEnum(RecipientRole),
signingOrder: z.number().optional(), signingOrder: z.number().optional(),
signerIndex: z.number().min(0),
actionAuth: ZMapNegativeOneToUndefinedSchema.pipe(ZRecipientActionAuthTypesSchema.optional()), actionAuth: ZMapNegativeOneToUndefinedSchema.pipe(ZRecipientActionAuthTypesSchema.optional()),
}), }),
), ),