mirror of
https://github.com/documenso/documenso.git
synced 2026-08-23 23:02:22 +10:00
feat: load editor recipients with group-preserving normalization
This commit is contained in:
@@ -9,7 +9,8 @@ import type { UseFormReturn } from 'react-hook-form';
|
|||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { isCcRecipient, normalizeRecipientSigningOrders, sortRecipientsForSigningOrder } from '../../utils/recipients';
|
import { normalizeGroupedSigningOrders } from '../../utils/recipient-groups';
|
||||||
|
import { isCcRecipient, sortRecipientsForSigningOrder } from '../../utils/recipients';
|
||||||
|
|
||||||
const LocalRecipientSchema = z.object({
|
const LocalRecipientSchema = z.object({
|
||||||
formId: z.string().min(1),
|
formId: z.string().min(1),
|
||||||
@@ -65,6 +66,24 @@ export const ZEditorRecipientsFormSchema = z
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const seenSigningOrders = new Set<number>();
|
||||||
|
|
||||||
|
data.signers.forEach((signer, index) => {
|
||||||
|
if (signer.role === RecipientRole.CC || typeof signer.signingOrder !== 'number') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seenSigningOrders.has(signer.signingOrder)) {
|
||||||
|
ctx.addIssue({
|
||||||
|
code: z.ZodIssueCode.custom,
|
||||||
|
message: 'CSC envelopes do not support recipient signing groups.',
|
||||||
|
path: ['signers', index, 'signingOrder'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
seenSigningOrders.add(signer.signingOrder);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TEditorRecipientsFormSchema = z.infer<typeof ZEditorRecipientsFormSchema>;
|
export type TEditorRecipientsFormSchema = z.infer<typeof ZEditorRecipientsFormSchema>;
|
||||||
@@ -101,7 +120,7 @@ export const useEditorRecipients = ({ envelope }: EditorRecipientsProps): UseEdi
|
|||||||
|
|
||||||
const signers: TLocalRecipient[] =
|
const signers: TLocalRecipient[] =
|
||||||
formRecipients.length > 0
|
formRecipients.length > 0
|
||||||
? normalizeRecipientSigningOrders(sortRecipientsForSigningOrder(formRecipients))
|
? normalizeGroupedSigningOrders(sortRecipientsForSigningOrder(formRecipients))
|
||||||
: [
|
: [
|
||||||
{
|
{
|
||||||
formId: initialId,
|
formId: initialId,
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { isSignatureFieldType } from '@documenso/prisma/guards/is-signature-field';
|
import { isSignatureFieldType } from '@documenso/prisma/guards/is-signature-field';
|
||||||
import type { Envelope, Field, Recipient } from '@prisma/client';
|
import type { Envelope, Field, Recipient } from '@prisma/client';
|
||||||
import { RecipientRole, SigningStatus } from '@prisma/client';
|
import { EnvelopeType, RecipientRole, SigningStatus } from '@prisma/client';
|
||||||
|
|
||||||
import { NEXT_PUBLIC_WEBAPP_URL } from '../constants/app';
|
import { NEXT_PUBLIC_WEBAPP_URL } from '../constants/app';
|
||||||
import { AppError, AppErrorCode } from '../errors/app-error';
|
import { AppError, AppErrorCode } from '../errors/app-error';
|
||||||
|
import type { TEditorEnvelope } from '../types/envelope-editor';
|
||||||
import type { TRecipientLite } from '../types/recipient';
|
import type { TRecipientLite } from '../types/recipient';
|
||||||
import { extractLegacyIds } from '../universal/id';
|
import { extractLegacyIds } from '../universal/id';
|
||||||
import { zEmail } from './zod';
|
import { zEmail } from './zod';
|
||||||
@@ -141,6 +142,32 @@ export const canRecipientBeModified = (
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Editor-level wrapper around `canRecipientBeModified`.
|
||||||
|
*
|
||||||
|
* Template recipients and unsaved (id-less) recipients can always be modified.
|
||||||
|
*/
|
||||||
|
export const canEditorRecipientBeModified = (
|
||||||
|
envelope: Pick<TEditorEnvelope, 'type' | 'recipients' | 'fields'>,
|
||||||
|
recipientId?: number,
|
||||||
|
) => {
|
||||||
|
if (envelope.type === EnvelopeType.TEMPLATE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recipientId === undefined) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const recipient = envelope.recipients.find((r) => r.id === recipientId);
|
||||||
|
|
||||||
|
if (!recipient) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return canRecipientBeModified(recipient, envelope.fields);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether a recipient can have their fields modified by the document owner.
|
* Whether a recipient can have their fields modified by the document owner.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user