mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 08:13:56 +10:00
fix: recipients with CC role not being editable (#918)
## Description Fixed issue where setting a recipient role as CC will prevent any further changes as it is considered as "sent" and "signed". ## Other changes - Prevent editing document after completed - Removed CC and Viewers from the field recipient list since they will never be filled - Minor UI issues ## Checklist - [X] I have tested these changes locally and they work as expected. - [X] I have added/updated tests that prove the effectiveness of these changes. - [X] I have followed the project's coding style guidelines.
This commit is contained in:
@ -114,7 +114,7 @@ export const DataTableActionDropdown = ({ row, team }: DataTableActionDropdownPr
|
|||||||
<DropdownMenuContent className="w-52" align="start" forceMount>
|
<DropdownMenuContent className="w-52" align="start" forceMount>
|
||||||
<DropdownMenuLabel>Action</DropdownMenuLabel>
|
<DropdownMenuLabel>Action</DropdownMenuLabel>
|
||||||
|
|
||||||
{recipient?.role !== RecipientRole.CC && (
|
{recipient && recipient?.role !== RecipientRole.CC && (
|
||||||
<DropdownMenuItem disabled={!recipient || isComplete} asChild>
|
<DropdownMenuItem disabled={!recipient || isComplete} asChild>
|
||||||
<Link href={`/sign/${recipient?.token}`}>
|
<Link href={`/sign/${recipient?.token}`}>
|
||||||
{recipient?.role === RecipientRole.VIEWER && (
|
{recipient?.role === RecipientRole.VIEWER && (
|
||||||
|
|||||||
@ -118,7 +118,7 @@ export const NameField = ({ field, recipient }: NameFieldProps) => {
|
|||||||
<span className="text-muted-foreground">({recipient.email})</span>
|
<span className="text-muted-foreground">({recipient.email})</span>
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
|
|
||||||
<div className="py-4">
|
<div>
|
||||||
<Label htmlFor="signature">Full Name</Label>
|
<Label htmlFor="signature">Full Name</Label>
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
@ -46,6 +46,10 @@ export const setFieldsForDocument = async ({
|
|||||||
throw new Error('Document not found');
|
throw new Error('Document not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (document.completedAt) {
|
||||||
|
throw new Error('Document already complete');
|
||||||
|
}
|
||||||
|
|
||||||
const existingFields = await prisma.field.findMany({
|
const existingFields = await prisma.field.findMany({
|
||||||
where: {
|
where: {
|
||||||
documentId,
|
documentId,
|
||||||
|
|||||||
@ -44,6 +44,10 @@ export const setRecipientsForDocument = async ({
|
|||||||
throw new Error('Document not found');
|
throw new Error('Document not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (document.completedAt) {
|
||||||
|
throw new Error('Document already complete');
|
||||||
|
}
|
||||||
|
|
||||||
const normalizedRecipients = recipients.map((recipient) => ({
|
const normalizedRecipients = recipients.map((recipient) => ({
|
||||||
...recipient,
|
...recipient,
|
||||||
email: recipient.email.toLowerCase(),
|
email: recipient.email.toLowerCase(),
|
||||||
@ -77,8 +81,9 @@ export const setRecipientsForDocument = async ({
|
|||||||
})
|
})
|
||||||
.filter((recipient) => {
|
.filter((recipient) => {
|
||||||
return (
|
return (
|
||||||
recipient._persisted?.sendStatus !== SendStatus.SENT &&
|
recipient._persisted?.role === RecipientRole.CC ||
|
||||||
recipient._persisted?.signingStatus !== SigningStatus.SIGNED
|
(recipient._persisted?.sendStatus !== SendStatus.SENT &&
|
||||||
|
recipient._persisted?.signingStatus !== SigningStatus.SIGNED)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -96,6 +101,7 @@ export const setRecipientsForDocument = async ({
|
|||||||
email: recipient.email,
|
email: recipient.email,
|
||||||
role: recipient.role,
|
role: recipient.role,
|
||||||
documentId,
|
documentId,
|
||||||
|
sendStatus: recipient.role === RecipientRole.CC ? SendStatus.SENT : SendStatus.NOT_SENT,
|
||||||
signingStatus:
|
signingStatus:
|
||||||
recipient.role === RecipientRole.CC ? SigningStatus.SIGNED : SigningStatus.NOT_SIGNED,
|
recipient.role === RecipientRole.CC ? SigningStatus.SIGNED : SigningStatus.NOT_SIGNED,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -304,6 +304,13 @@ export const AddFieldsFormPartial = ({
|
|||||||
return recipientsByRole;
|
return recipientsByRole;
|
||||||
}, [recipients]);
|
}, [recipients]);
|
||||||
|
|
||||||
|
const recipientsByRoleToDisplay = useMemo(() => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
|
return (Object.entries(recipientsByRole) as [RecipientRole, Recipient[]][]).filter(
|
||||||
|
([role]) => role !== RecipientRole.CC && role !== RecipientRole.VIEWER,
|
||||||
|
);
|
||||||
|
}, [recipientsByRole]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DocumentFlowFormContainerHeader
|
<DocumentFlowFormContainerHeader
|
||||||
@ -382,13 +389,10 @@ export const AddFieldsFormPartial = ({
|
|||||||
</span>
|
</span>
|
||||||
</CommandEmpty>
|
</CommandEmpty>
|
||||||
|
|
||||||
{Object.entries(recipientsByRole).map(([role, recipients], roleIndex) => (
|
{recipientsByRoleToDisplay.map(([role, recipients], roleIndex) => (
|
||||||
<CommandGroup key={roleIndex}>
|
<CommandGroup key={roleIndex}>
|
||||||
<div className="text-muted-foreground mb-1 ml-2 mt-2 text-xs font-medium">
|
<div className="text-muted-foreground mb-1 ml-2 mt-2 text-xs font-medium">
|
||||||
{
|
{`${RECIPIENT_ROLES_DESCRIPTION[role].roleName}s`}
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
||||||
RECIPIENT_ROLES_DESCRIPTION[role as RecipientRole].roleName
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{recipients.length === 0 && (
|
{recipients.length === 0 && (
|
||||||
@ -403,7 +407,7 @@ export const AddFieldsFormPartial = ({
|
|||||||
{recipients.map((recipient) => (
|
{recipients.map((recipient) => (
|
||||||
<CommandItem
|
<CommandItem
|
||||||
key={recipient.id}
|
key={recipient.id}
|
||||||
className={cn('px-4 last:mb-1 [&:not(:first-child)]:mt-1', {
|
className={cn('px-2 last:mb-1 [&:not(:first-child)]:mt-1', {
|
||||||
'text-muted-foreground': recipient.sendStatus === SendStatus.SENT,
|
'text-muted-foreground': recipient.sendStatus === SendStatus.SENT,
|
||||||
})}
|
})}
|
||||||
onSelect={() => {
|
onSelect={() => {
|
||||||
@ -413,7 +417,7 @@ export const AddFieldsFormPartial = ({
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={cn('text-foreground/70 truncate', {
|
className={cn('text-foreground/70 truncate', {
|
||||||
'text-foreground': recipient === selectedSigner,
|
'text-foreground/80': recipient === selectedSigner,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{recipient.name && (
|
{recipient.name && (
|
||||||
|
|||||||
@ -105,7 +105,10 @@ export const AddSignersFormPartial = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return recipients.some(
|
return recipients.some(
|
||||||
(recipient) => recipient.id === id && recipient.sendStatus === SendStatus.SENT,
|
(recipient) =>
|
||||||
|
recipient.id === id &&
|
||||||
|
recipient.sendStatus === SendStatus.SENT &&
|
||||||
|
recipient.role !== RecipientRole.CC,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user