Merge branch 'main' into fix-#41-db-migration-Signature_recipientId_fkey

This commit is contained in:
Timur Ercan
2023-04-11 15:34:32 +02:00
committed by GitHub
7 changed files with 128 additions and 100 deletions

View File

@ -66,7 +66,7 @@ export default function RecipientSelector(props: any) {
selected ? "font-semibold" : "font-normal",
"ml-3 block truncate"
)}>
{`${selectedRecipient?.name} <${selectedRecipient?.email}>`}
{`${recipient?.name} <${recipient?.email}>`}
</span>
</div>

View File

@ -73,6 +73,13 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
},
});
const signedRecipients = await prisma.recipient.findMany({
where: {
documentId: recipient.documentId,
signingStatus: SigningStatus.SIGNED,
},
});
// Don't check for inserted, because currently no "sign again" scenarios exist and
// this is probably the expected behaviour in unclean states.
const nonSignatureFields = await prisma.field.findMany({
@ -126,7 +133,11 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
});
document.document = documentWithInserts;
if (documentOwner) await sendSigningDoneMail(recipient, document, documentOwner);
if (documentOwner) await sendSigningDoneMail(document, documentOwner);
for (const signer of signedRecipients) {
await sendSigningDoneMail(document, signer);
}
}
return res.status(200).end();

View File

@ -291,6 +291,7 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
event.stopPropagation();
router.push("/documents/" + document.id);
}}
disabled={document.status === "COMPLETED"}
/>
<IconButton
icon={ArrowDownTrayIcon}

View File

@ -34,7 +34,10 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
},
{
title: props.document.title,
href: NEXT_PUBLIC_WEBAPP_URL + "/documents/" + props.document.id,
href:
props.document.status !== DocumentStatus.COMPLETED
? NEXT_PUBLIC_WEBAPP_URL + "/documents/" + props.document.id
: NEXT_PUBLIC_WEBAPP_URL + "/documents/" + props.document.id + "/recipients",
},
{
title: "Recipients",
@ -88,10 +91,14 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
href={"/api/documents/" + props.document.id}>
Download
</Button>
{props.document.status !== DocumentStatus.COMPLETED && (
<>
<Button
icon={PencilSquareIcon}
disabled={props.document.status === DocumentStatus.COMPLETED}
color={props.document.status === DocumentStatus.COMPLETED ? "primary" : "secondary"}
color={
props.document.status === DocumentStatus.COMPLETED ? "primary" : "secondary"
}
className="mr-2"
href={breadcrumbItems[1].href}>
Edit Document
@ -112,13 +119,17 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
}>
Send
</Button>
</>
)}
</div>
</div>
<div className="mt-10 overflow-hidden rounded-md bg-white p-4 shadow sm:p-6">
<div className="border-b border-gray-200 pb-3 sm:pb-5">
<h3 className="text-lg font-medium leading-6 text-gray-900 ">Signers</h3>
<p className="mt-2 max-w-4xl text-sm text-gray-500">
The people who will sign the document.
{props.document.status !== DocumentStatus.COMPLETED
? "The people who will sign the document."
: "The people who signed the document."}
</p>
</div>
<FormProvider {...form}>
@ -215,9 +226,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
className="mt-3 inline-block flex-shrink-0 rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-gray-800">
Not Sent
</span>
) : (
""
)}
) : null}
{item.sendStatus === "SENT" && item.readStatus !== "OPENED" ? (
<span id="sent_icon">
<span
@ -226,9 +235,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
<CheckIcon className="mr-1 inline h-5" /> Sent
</span>
</span>
) : (
""
)}
) : null}
{item.readStatus === "OPENED" && item.signingStatus === "NOT_SIGNED" ? (
<span id="read_icon">
<span
@ -239,9 +246,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
Seen
</span>
</span>
) : (
""
)}
) : null}
{item.signingStatus === "SIGNED" ? (
<span id="signed_icon">
<span
@ -251,11 +256,10 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
Signed
</span>
</span>
) : (
""
)}
) : null}
</div>
</div>
{props.document.status !== DocumentStatus.COMPLETED && (
<div className="mr-1 flex">
<IconButton
icon={PaperAirplaneIcon}
@ -290,11 +294,13 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
className="group-hover:text-neon-dark group-hover:disabled:text-gray-400"
/>
</div>
)}
</div>
</div>
</li>
))}
</ul>
{props.document.status !== "COMPLETED" && (
<Button
icon={UserPlusIcon}
className="mt-3"
@ -310,6 +316,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
}}>
Add Signer
</Button>
)}
</form>
</FormProvider>
</div>

View File

@ -3,7 +3,7 @@ import { addDigitalSignature } from "@documenso/signing/addDigitalSignature";
import { sendMail } from "./sendMail";
import { Document as PrismaDocument } from "@prisma/client";
export const sendSigningDoneMail = async (recipient: any, document: PrismaDocument, user: any) => {
export const sendSigningDoneMail = async (document: PrismaDocument, user: any) => {
await sendMail(
user.email,
`Completed: "${document.title}"`,

View File

@ -12,27 +12,36 @@ export async function insertTextInPDF(
): Promise<string> {
const fontBytes = fs.readFileSync("public/fonts/Qwigley-Regular.ttf");
const existingPdfBytes = pdfAsBase64;
const pdfDoc = await PDFDocument.load(pdfAsBase64);
const pdfDoc = await PDFDocument.load(existingPdfBytes);
pdfDoc.registerFontkit(fontkit);
const customFont = await pdfDoc.embedFont(fontBytes);
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica);
const font = await pdfDoc.embedFont(useHandwritingFont ? fontBytes : StandardFonts.Helvetica);
const pages = pdfDoc.getPages();
const pdfPage = pages[page];
const textSize = useHandwritingFont ? 50 : 15;
const textWidth = customFont.widthOfTextAtSize(text, textSize);
const textHeight = customFont.heightAtSize(textSize);
const textWidth = font.widthOfTextAtSize(text, textSize);
const textHeight = font.heightAtSize(textSize);
const fieldSize = { width: 192, height: 64 };
const invertedYPosition = pdfPage.getHeight() - positionY - fieldSize.height;
// Because pdf-lib use a bottom-left coordinate system, we need to invert the y position
// we then center the text in the middle by adding half the height of the text
// plus the height of the field and divide the result by 2
const invertedYPosition =
pdfPage.getHeight() - positionY - (fieldSize.height + textHeight / 2) / 2;
// We center the text by adding the width of the field, subtracting the width of the text
// and dividing the result by 2
const centeredXPosition = positionX + (fieldSize.width - textWidth) / 2;
pdfPage.drawText(text, {
x: positionX,
x: centeredXPosition,
y: invertedYPosition,
size: textSize,
font: useHandwritingFont ? customFont : helveticaFont,
color: rgb(0, 0, 0),
font,
});
const pdfAsUint8Array = await pdfDoc.save();

View File

@ -24,7 +24,7 @@ async function createUser(userData: { email: string; password: string }) {
async function main() {
console.info("Start seeding...");
const password = "123456789";
const email = "example6@documenso.com";
const email = "example@documenso.com";
const user = await createUser({
email: email,
password: await hashPassword(password),