diff --git a/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js b/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js index d26887d24..acfeca3e5 100644 --- a/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js +++ b/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js @@ -1,6 +1,6 @@ import React, { useState, useRef, useEffect } from "react"; import { themeColor } from "../utils/ThemeColor/backColor"; -import { PDFDocument, rgb } from "pdf-lib"; +import { PDFDocument } from "pdf-lib"; import "../css/signature.css"; import axios from "axios"; import ModalHeader from "react-bootstrap/esm/ModalHeader"; @@ -16,7 +16,9 @@ import { contractDocument, getBase64FromIMG, getBase64FromUrl, - urlValidator + urlValidator, + multiSignEmbed, + embedDocId } from "../utils/Utils"; import Loader from "./component/loader"; import HandleError from "./component/HandleError"; @@ -319,29 +321,12 @@ function PdfRequestFiles() { if (isDocId) { pdfBase64 = await getBase64FromUrl(url); } else { - for (let i = 0; i < allPages; i++) { - const font = await pdfDoc.embedFont("Helvetica"); - - const fontSize = 10; - const textContent = - documentId && `OpenSign™ DocumentId: ${documentId}`; - - const pages = pdfDoc.getPages(); - const page = pages[i]; - - page.drawText(textContent, { - x: 10, - y: page.getHeight() - 10, - size: fontSize, - font, - color: rgb(0.5, 0.5, 0.5) - }); - } + //embed document's object id to all pages in pdf document + await embedDocId(pdfDoc, documentId, allPages); pdfBase64 = await pdfDoc.saveAsBase64({ useObjectStreams: false }); } - for (let i = 0; i < pngUrl.length; i++) { const imgUrlList = pngUrl[i].pos; const pageNo = pngUrl[i].pageNumber; @@ -381,112 +366,15 @@ function PdfRequestFiles() { } //else if signature is more than one then embed all sign with the use of pdf-lib else if (pngUrl.length > 0 && pngUrl[0].pos.length > 0) { - for (let i = 0; i < allPages; i++) { - const font = await pdfDoc.embedFont("Helvetica"); - - const fontSize = 10; - const textContent = - documentId && `OpenSign™ DocumentId: ${documentId} `; - - const pages = pdfDoc.getPages(); - const page = pages[i]; - - page.drawText(textContent, { - x: 10, - y: page.getHeight() - 10, - size: fontSize, - font, - color: rgb(0.5, 0.5, 0.5) - }); - } - - for (let i = 0; i < pngUrl.length; i++) { - const pageNo = pngUrl[i].pageNumber; - - const imgUrlList = pngUrl[i].pos; - const pages = pdfDoc.getPages(); - const page = pages[pageNo - 1]; - - const images = await Promise.all( - imgUrlList.map(async (url) => { - let signUrl = url.SignUrl; - if (url.ImageType === "image/png") { - //function for convert signature png base64 url to jpeg base64 - const newUrl = await convertPNGtoJPEG(signUrl); - signUrl = newUrl; - } - const checkUrl = urlValidator(signUrl); - if (checkUrl) { - signUrl = signUrl + "?get"; - } - const res = await fetch(signUrl); - return res.arrayBuffer(); - }) - ); - images.forEach(async (imgData, id) => { - let img = await pdfDoc.embedJpg(imgData); - const imgHeight = imgUrlList[id].Height - ? imgUrlList[id].Height - : 60; - const imgWidth = imgUrlList[id].Width - ? imgUrlList[id].Width - : 150; - const isMobile = window.innerWidth < 767; - const newWidth = window.innerWidth; - const scale = isMobile ? pdfOriginalWidth / newWidth : 1; - const xPos = (pos) => { - //checking both condition mobile and desktop view - if (isMobile) { - //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale - if (pos.isMobile) { - const x = pos.xPosition * (pos.scale / scale); - return x * scale + 50; - } else { - const x = pos.xPosition / scale; - return x * scale; - } - } else { - //else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale - if (pos.isMobile) { - const x = pos.xPosition * pos.scale + 50; - return x; - } else { - return pos.xPosition; - } - } - }; - const yPos = (pos) => { - //checking both condition mobile and desktop view - const y = pos.yPosition / scale; - if (isMobile) { - //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale - if (pos.isMobile) { - const y = pos.yPosition * (pos.scale / scale); - return page.getHeight() - y * scale - imgHeight; - } else { - return page.getHeight() - y * scale - imgHeight; - } - } else { - //else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale - if (pos.isMobile) { - const y = pos.yPosition * pos.scale; - return page.getHeight() - y - imgHeight; - } else { - return page.getHeight() - pos.yPosition - imgHeight; - } - } - }; - page.drawImage(img, { - x: xPos(imgUrlList[id]), - y: yPos(imgUrlList[id]), - width: imgWidth, - height: imgHeight - }); - }); - } - const pdfBytes = await pdfDoc.saveAsBase64({ - useObjectStreams: false - }); + //embed document's object id to all pages in pdf document + await embedDocId(pdfDoc, documentId, allPages); + //embed multi signature in pdf + const pdfBytes = await multiSignEmbed( + pngUrl, + pdfDoc, + pdfOriginalWidth, + false + ); signPdfFun(pdfBytes, documentId, pngUrl); } diff --git a/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js b/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js index 2460d6c36..d072f2a3d 100644 --- a/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js +++ b/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js @@ -1,5 +1,5 @@ import React, { useState, useRef, useEffect } from "react"; -import { PDFDocument, rgb } from "pdf-lib"; +import { PDFDocument } from "pdf-lib"; import "../css/./signature.css"; import sign from "../assests/sign3.png"; import stamp from "../assests/stamp2.png"; @@ -18,7 +18,9 @@ import ModalHeader from "react-bootstrap/esm/ModalHeader"; import { convertPNGtoJPEG, contractDocument, - getBase64FromIMG + getBase64FromIMG, + embedDocId, + multiSignEmbed } from "../utils/Utils"; import { useParams } from "react-router-dom"; import Tour from "reactour"; @@ -30,7 +32,7 @@ import Header from "./component/header"; import RenderPdf from "./component/renderPdf"; import { contractUsers, contactBook, urlValidator } from "../utils/Utils"; import { modalAlign } from "../utils/Utils"; -import { $ } from "select-dom"; + //For signYourself inProgress section signer can add sign and complete doc sign. function SignYourSelf() { const [pdfDetails, setPdfDetails] = useState([]); @@ -422,24 +424,7 @@ function SignYourSelf() { //checking if signature is only one then send image url in jpeg formate to server if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) { //embed document's object id to all pages in pdf document - for (let i = 0; i < allPages; i++) { - const font = await pdfDoc.embedFont("Helvetica"); - - const fontSize = 10; - const textContent = - documentId && `OpenSign™ DocumentId: ${documentId}`; - - const pages = pdfDoc.getPages(); - const page = pages[i]; - - page.drawText(textContent, { - x: 10, - y: page.getHeight() - 10, - size: fontSize, - font, - color: rgb(0.5, 0.5, 0.5) - }); - } + await embedDocId(pdfDoc, documentId, allPages); const pdfBase64 = await pdfDoc.saveAsBase64({ useObjectStreams: false }); @@ -475,85 +460,15 @@ function SignYourSelf() { } //else if signature is more than one then embed all sign with the use of pdf-lib else if (xyPostion.length > 0 && xyPostion[0].pos.length > 0) { - for (let i = 0; i < allPages; i++) { - const font = await pdfDoc.embedFont("Helvetica"); - - const fontSize = 10; - const textContent = - documentId && `OpenSign™ DocumentId: ${documentId} `; - - const pages = pdfDoc.getPages(); - const page = pages[i]; - - page.drawText(textContent, { - x: 10, - y: page.getHeight() - 10, - size: fontSize, - font, - color: rgb(0.5, 0.5, 0.5) - }); - } - for (let i = 0; i < pngUrl.length; i++) { - const pageNo = pngUrl[i].pageNumber; - - const imgUrlList = pngUrl[i].pos; - const pages = pdfDoc.getPages(); - const page = pages[pageNo - 1]; - - const images = await Promise.all( - imgUrlList.map(async (url) => { - let signUrl = url.SignUrl; - - if (url.ImageType === "image/png") { - //function for convert signature png base64 url to jpeg base64 - const newUrl = await convertPNGtoJPEG(signUrl); - signUrl = newUrl; - } - const checkUrl = urlValidator(signUrl); - if (checkUrl) { - signUrl = signUrl + "?get"; - } - const res = await fetch(signUrl); - - return res.arrayBuffer(); - }) - ); - images.forEach(async (imgData, id) => { - let img = await pdfDoc.embedJpg(imgData); - const imgHeight = imgUrlList[id].Height - ? imgUrlList[id].Height - : 60; - const imgWidth = imgUrlList[id].Width ? imgUrlList[id].Width : 150; - const isMobile = window.innerWidth < 767; - const newWidth = window.innerWidth; - const scale = isMobile ? pdfOriginalWidth / newWidth : 1; - - const posY = () => { - if (isMobile) { - if (id === 0) { - return ( - page.getHeight() - - imgUrlList[id].yPosition * scale - - imgHeight - ); - } else if (id > 0) { - return page.getHeight() - imgUrlList[id].yPosition * scale; - } - } else { - return page.getHeight() - imgUrlList[id].yPosition - imgHeight; - } - }; - page.drawImage(img, { - x: isMobile - ? imgUrlList[id].xPosition * scale + imgWidth / 2 - : imgUrlList[id].xPosition, - y: posY(), - width: imgWidth, - height: imgHeight - }); - }); - } - const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false }); + //embed document's object id to all pages in pdf document + await embedDocId(pdfDoc, documentId, allPages); + //embed multi signature in pdf + const pdfBytes = await multiSignEmbed( + pngUrl, + pdfDoc, + pdfOriginalWidth, + true + ); signPdfFun(pdfBytes, documentId); } setIsSignPad(false); @@ -574,16 +489,16 @@ function SignYourSelf() { let singleSign; const isMobile = window.innerWidth < 767; - const newWidth = window.innerWidth; + const newWidth = window.innerWidth - 32; const scale = isMobile ? pdfOriginalWidth / newWidth : 1; const imgWidth = xyPosData ? xyPosData.Width : 150; if (xyPostion.length === 1 && xyPostion[0].pos.length === 1) { const height = xyPosData.Height ? xyPosData.Height : 60; const bottomY = xyPosData.isDrag - ? xyPosData.yBottom * scale - height + ? xyPosData.yBottom * scale - height * scale : xyPosData.firstYPos - ? xyPosData.yBottom * scale - height + xyPosData.firstYPos - : xyPosData.yBottom * scale - height; + ? xyPosData.yBottom * scale - height * scale + xyPosData.firstYPos + : xyPosData.yBottom * scale - height * scale; singleSign = { pdfFile: pdfBase64Url, @@ -591,11 +506,11 @@ function SignYourSelf() { sign: { Base64: base64Url, Left: isMobile - ? xyPosData.xPosition * scale + imgWidth / 2 + ? xyPosData.xPosition * scale + 43 : xyPosData.xPosition, Bottom: bottomY, - Width: xyPosData.Width ? xyPosData.Width : 150, - Height: height, + Width: xyPosData.Width ? xyPosData.Width * scale : 150 * scale, + Height: height * scale, Page: pageNo } }; diff --git a/microfrontends/SignDocuments/src/Component/component/renderPdf.js b/microfrontends/SignDocuments/src/Component/component/renderPdf.js index 58e3670cd..abe0d34fe 100644 --- a/microfrontends/SignDocuments/src/Component/component/renderPdf.js +++ b/microfrontends/SignDocuments/src/Component/component/renderPdf.js @@ -42,8 +42,8 @@ function RenderPdf({ const isMobile = window.innerWidth < 767; const newWidth = window.innerWidth; const scale = isMobile ? pdfOriginalWidth / newWidth : 1; - //check isGuestSigner is present in local if yes than handle login flow header in mobile view - const isGuestSigner = localStorage.getItem("isGuestSigner"); + //check isGuestSigner is present in local if yes than handle login flow header in mobile view + const isGuestSigner = localStorage.getItem("isGuestSigner"); // handle signature block width and height according to screen const posWidth = (pos) => { let width; @@ -75,7 +75,6 @@ function RenderPdf({ return width; } }; - //function for render placeholder block over pdf document const checkSignedSignes = (data) => { @@ -434,279 +433,144 @@ function RenderPdf({ ); }) : pdfRequest - ? signerPos.map((data, key) => { - return ( - - {checkSignedSignes(data)} - - ); - }) - : placeholder - ? signerPos.map((data, ind) => { - return ( - - {data.placeHolder.map((placeData, index) => { - return ( - - {placeData.pageNumber === pageNumber && - placeData.pos.map((pos) => { - return ( - - handleTabDrag(pos.key, data.signerObjId) - } - size={{ - width: pos.Width ? pos.Width : 150, - height: pos.Height ? pos.Height : 60 - }} - lockAspectRatio={ - pos.Width ? pos.Width / pos.Height : 2.5 - } - resizeHandleStyles={{ - bottom: { display: "none" }, - right: { display: "none" }, - bottomRight: { display: "block" } - }} - onDragStop={(event, dragElement) => - handleStop( - event, - dragElement, - data.signerObjId, - pos.key - ) - } - default={{ - x: pos.xPosition, - y: pos.yPosition - }} - onResize={( - e, - direction, - ref, - delta, - position - ) => { - handleImageResize( - ref, - pos.key, - data.signerObjId, - position - ); - }} - > -
{ - e.stopPropagation(); - handleDeleteSign( - pos.key, - data.signerObjId - ); - }} - style={{ - position: "absolute", - right: 0, - display: "inline-block", - background: themeColor(), - cursor: "pointer", - padding: "0px 10px", - zIndex: 10 - }} - > - x -
-
{ + return ( + + {checkSignedSignes(data)} + + ); + }) + : placeholder + ? signerPos.map((data, ind) => { + return ( + + {data.placeHolder.map((placeData, index) => { + return ( + + {placeData.pageNumber === pageNumber && + placeData.pos.map((pos) => { + return ( + + handleTabDrag( + pos.key, + data.signerObjId + ) + } + size={{ + width: pos.Width ? pos.Width : 150, + height: pos.Height ? pos.Height : 60 + }} + lockAspectRatio={ + pos.Width + ? pos.Width / pos.Height + : 2.5 + } + resizeHandleStyles={{ + bottom: { display: "none" }, + right: { display: "none" }, + bottomRight: { display: "block" } + }} + onDragStop={(event, dragElement) => + handleStop( + event, + dragElement, + data.signerObjId, + pos.key + ) + } + default={{ + x: pos.xPosition, + y: pos.yPosition + }} + onResize={( + e, + direction, + ref, + delta, + position + ) => { + handleImageResize( + ref, + pos.key, + data.signerObjId, + position + ); + }} + > +
{ + e.stopPropagation(); + handleDeleteSign( + pos.key, + data.signerObjId + ); + }} + style={{ + position: "absolute", + right: 0, + display: "inline-block", + background: themeColor(), + cursor: "pointer", + padding: "0px 10px", + zIndex: 10 + }} + > + x +
+
- {pos.isStamp ? "stamp" : "signature"} -
-
- ); - })} -
- ); - })} -
- ); - }) - : xyPostion.map((data, ind) => { - return ( - - {data.pageNumber === pageNumber && - data.pos.map((pos) => { - return pos && pos.SignUrl ? ( - handleTabDrag(pos.key)} - onDragStop={handleStop} - onResize={( - e, - direction, - ref, - delta, - position - ) => { - handleImageResize( - ref, - pos.key, - direction, - position - ); - }} - > - {" "} -
{ - if (!isDragging) { - setTimeout(() => { - e.stopPropagation(); - setIsSignPad(true); - setSignKey(pos.key); - setIsStamp(pos.isStamp); - }, 500); + marginTop: "0px" + }} + > + {pos.isStamp ? "stamp" : "signature"} +
+
+ ); + })} +
+ ); + })} + + ); + }) + : xyPostion.map((data, ind) => { + return ( + + {data.pageNumber === pageNumber && + data.pos.map((pos) => { + return pos && pos.SignUrl ? ( + -
{ - e.stopPropagation(); - handleDeleteSign(pos.key); - setIsStamp(false); - }} - style={{ - position: "absolute", - right: 0, - display: "inline-block", - background: themeColor(), - cursor: "pointer", - padding: "0px 10px" - }} - > - x -
-
- signimg { - setSignKey(pos.key); - console.log("Drag 2"); - setIsSignPad(true); - setIsStamp(pos.isStamp); - }} - src={pos.SignUrl} - style={{ - width: "100%", - height: "100%", - objectFit: "contain" - }} - /> -
-
-
- ) : ( - <> - { - handleTabDrag(pos.key, e); - }} - onDragStop={handleStop} - size={{ - width: pos.Width ? pos.Width : 150, - height: pos.Height ? pos.Height : 60 - }} - default={{ - x: pos.xPosition, - y: pos.yPosition - }} - > -
{ - if (!isDragging) { - setTimeout(() => { - setIsSignPad(true); - setSignKey(pos.key); - setIsStamp(pos.isStamp); - }, 500); - } - }} - className="dragElm" + key={pos.key} style={{ padding: "0px", cursor: "all-scroll", - zIndex: 20, + zIndex: 1, position: "absolute", borderStyle: "dashed", width: "150px", @@ -716,50 +580,190 @@ function RenderPdf({ textAlign: "center", justifyContent: "center", borderWidth: "0.2px", - overflow: "hidden" + overflow: "hidden", + userSelect: "none" + }} + size={{ + width: pos.Width ? pos.Width : 151, + height: pos.Height ? pos.Height : 61 + }} + default={{ + x: pos.xPosition, + y: pos.yPosition + }} + onDrag={() => handleTabDrag(pos.key)} + onDragStop={handleStop} + onResize={( + e, + direction, + ref, + delta, + position + ) => { + handleImageResize( + ref, + pos.key, + direction, + position + ); }} > + {" "}
{ - e.stopPropagation(); - e.preventDefault(); - - handleDeleteSign(pos.key); - setIsStamp(false); - }} - onClick={(e) => { - e.stopPropagation(); // Prevent further event propagation + onTouchEnd={(e) => { + if (!isDragging) { + setTimeout(() => { + e.stopPropagation(); + setIsSignPad(true); + setSignKey(pos.key); + setIsStamp(pos.isStamp); + }, 500); + } }} + > +
{ + e.stopPropagation(); + handleDeleteSign(pos.key); + setIsStamp(false); + }} + style={{ + position: "absolute", + right: 0, + display: "inline-block", + background: themeColor(), + cursor: "pointer", + padding: "0px 10px" + }} + > + x +
+
+ signimg { + setSignKey(pos.key); + console.log("Drag 2"); + setIsSignPad(true); + setIsStamp(pos.isStamp); + }} + src={pos.SignUrl} + style={{ + width: "100%", + height: "100%", + objectFit: "contain" + }} + /> +
+
+ + ) : ( + <> + - x -
-
{ + handleTabDrag(pos.key, e); + }} + onDragStop={handleStop} + size={{ + width: pos.Width ? pos.Width : 150, + height: pos.Height ? pos.Height : 60 + }} + default={{ + x: pos.xPosition, + y: pos.yPosition }} > - {pos.isStamp ? "stamp" : "signature"} -
- -
- - ); - })} -
- ); - }))} +
{ + if (!isDragging) { + setTimeout(() => { + setIsSignPad(true); + setSignKey(pos.key); + setIsStamp(pos.isStamp); + }, 500); + } + }} + className="dragElm" + style={{ + padding: "0px", + cursor: "all-scroll", + zIndex: 20, + position: "absolute", + borderStyle: "dashed", + width: "150px", + height: "60px", + borderColor: themeColor(), + background: "#daebe0", + textAlign: "center", + justifyContent: "center", + borderWidth: "0.2px", + overflow: "hidden" + }} + > +
{ + e.stopPropagation(); + e.preventDefault(); + + handleDeleteSign(pos.key); + setIsStamp(false); + }} + onClick={(e) => { + e.stopPropagation(); // Prevent further event propagation + }} + style={{ + position: "absolute", + right: 0, + display: "inline-block", + background: themeColor(), + cursor: "pointer", + padding: "0px 10px" + }} + > + x +
+
+ {pos.isStamp ? "stamp" : "signature"} +
+
+ + + ); + })} +
+ ); + }))} {/* this component for render pdf document is in middle of the component */}
{Array.from(new Array(numPages), (el, index) => ( { @@ -980,89 +984,289 @@ function RenderPdf({ ); }) : pdfRequest - ? signerPos.map((data, key) => { - return ( - - {checkSignedSignes(data)} - - ); - }) - : placeholder - ? signerPos.map((data, ind) => { - return ( - - {data.placeHolder.map((placeData, index) => { - return ( - - {placeData.pageNumber === pageNumber && - placeData.pos.map((pos) => { - return ( - { + return ( + + {checkSignedSignes(data)} + + ); + }) + : placeholder + ? signerPos.map((data, ind) => { + return ( + + {data.placeHolder.map((placeData, index) => { + return ( + + {placeData.pageNumber === pageNumber && + placeData.pos.map((pos) => { + return ( + + handleTabDrag( + pos.key, + data.signerObjId + ) + } + size={{ + width: pos.Width ? pos.Width : 150, + height: pos.Height ? pos.Height : 60 + }} + lockAspectRatio={ + pos.Width + ? pos.Width / pos.Height + : 2.5 + } + resizeHandleStyles={{ + bottom: { display: "none" }, + right: { display: "none" }, + bottomRight: { display: "block" } + }} + onDragStop={(event, dragElement) => + handleStop( + event, + dragElement, + data.signerObjId, + pos.key + ) + } + default={{ + x: pos.xPosition, + y: pos.yPosition + }} + onResize={( + e, + direction, + ref, + delta, + position + ) => { + handleImageResize( + ref, + pos.key, + data.signerObjId, + position + ); + }} + > +
{ + e.stopPropagation(); + handleDeleteSign( + pos.key, + data.signerObjId + ); + }} + style={{ + position: "absolute", + right: 0, + display: "inline-block", + background: themeColor(), + cursor: "pointer", + padding: "0px 10px", + zIndex: 10 + }} + > + x +
+
+ {pos.isStamp + ? "stamp" + : "signature"} +
+
+ ); + })} +
+ ); + })} +
+ ); + }) + : xyPostion.map((data, ind) => { + return ( + + {data.pageNumber === pageNumber && + data.pos.map((pos) => { + return pos && pos.SignUrl ? ( + handleTabDrag(pos.key)} + size={{ + width: pos.Width ? pos.Width : 150, + height: pos.Height ? pos.Height : 60 + }} + onDragStop={handleStop} + default={{ + x: pos.xPosition, + y: pos.yPosition + }} + onResize={( + e, + direction, + ref, + delta, + position + ) => { + handleImageResize( + ref, + pos.key, + direction, + position + ); + }} + onClick={() => { + if (!isDragging) { + setIsSignPad(true); + setSignKey(pos.key); + setIsStamp(pos.isStamp); + } + }} + > +
{ + e.stopPropagation(); + handleDeleteSign(pos.key); + setIsStamp(false); + }} + style={{ + position: "absolute", + right: 0, + display: "inline-block", + background: themeColor(), + cursor: "pointer", + padding: "0px 10px" + }} + > + x +
+
+ signimg { + setSignKey(pos.key); + setIsSignPad(true); + setIsStamp(pos.isStamp); + }} + src={pos.SignUrl} + style={{ + width: "100%", + height: "100%", + objectFit: "contain" + }} + /> +
+
+ ) : ( + handleTabDrag(pos.key, e)} + size={{ + width: pos.Width ? pos.Width : 150, + height: pos.Height ? pos.Height : 60 + }} + onDragStop={handleStop} + default={{ + x: pos.xPosition, + y: pos.yPosition + }} + > +
{ + if (!isDragging) { + e.stopPropagation(); + setIsSignPad(true); + setSignKey(pos.key); + setIsStamp(pos.isStamp); + } + }} style={{ - padding: "0px", cursor: "all-scroll", - zIndex: 1, + zIndex: 10, position: "absolute", borderStyle: "dashed", - width: "200px", - height: "30px", + width: "150px", + height: "60px", borderColor: themeColor(), - background: data.blockColor, + background: "#daebe0", textAlign: "center", justifyContent: "center", + alignItems: "center", borderWidth: "0.2px" }} - onDrag={() => - handleTabDrag(pos.key, data.signerObjId) - } - size={{ - width: pos.Width ? pos.Width : 150, - height: pos.Height ? pos.Height : 60 - }} - lockAspectRatio={ - pos.Width ? pos.Width / pos.Height : 2.5 - } - resizeHandleStyles={{ - bottom: { display: "none" }, - right: { display: "none" }, - bottomRight: { display: "block" } - }} - onDragStop={(event, dragElement) => - handleStop( - event, - dragElement, - data.signerObjId, - pos.key - ) - } - default={{ - x: pos.xPosition, - y: pos.yPosition - }} - onResize={( - e, - direction, - ref, - delta, - position - ) => { - handleImageResize( - ref, - pos.key, - data.signerObjId, - position - ); - }} >
{ e.stopPropagation(); - handleDeleteSign( - pos.key, - data.signerObjId - ); + handleDeleteSign(pos.key); + setIsStamp(false); }} style={{ position: "absolute", @@ -1070,8 +1274,7 @@ function RenderPdf({ display: "inline-block", background: themeColor(), cursor: "pointer", - padding: "0px 10px", - zIndex: 10 + padding: "0px 10px" }} > x @@ -1079,212 +1282,20 @@ function RenderPdf({
{pos.isStamp ? "stamp" : "signature"}
- - ); - })} - - ); - })} - - ); - }) - : xyPostion.map((data, ind) => { - return ( - - {data.pageNumber === pageNumber && - data.pos.map((pos) => { - return pos && pos.SignUrl ? ( - handleTabDrag(pos.key)} - size={{ - width: pos.Width ? pos.Width : 150, - height: pos.Height ? pos.Height : 60 - }} - onDragStop={handleStop} - default={{ - x: pos.xPosition, - y: pos.yPosition - }} - onResize={( - e, - direction, - ref, - delta, - position - ) => { - handleImageResize( - ref, - pos.key, - direction, - position - ); - }} - onClick={() => { - if (!isDragging) { - setIsSignPad(true); - setSignKey(pos.key); - setIsStamp(pos.isStamp); - } - }} - > -
{ - e.stopPropagation(); - handleDeleteSign(pos.key); - setIsStamp(false); - }} - style={{ - position: "absolute", - right: 0, - display: "inline-block", - background: themeColor(), - cursor: "pointer", - padding: "0px 10px" - }} - > - x -
-
- signimg { - setSignKey(pos.key); - setIsSignPad(true); - setIsStamp(pos.isStamp); - }} - src={pos.SignUrl} - style={{ - width: "100%", - height: "100%", - objectFit: "contain" - }} - /> -
-
- ) : ( - handleTabDrag(pos.key, e)} - size={{ - width: pos.Width ? pos.Width : 150, - height: pos.Height ? pos.Height : 60 - }} - onDragStop={handleStop} - default={{ - x: pos.xPosition, - y: pos.yPosition - }} - > -
{ - if (!isDragging) { - e.stopPropagation(); - setIsSignPad(true); - setSignKey(pos.key); - setIsStamp(pos.isStamp); - } - }} - style={{ - cursor: "all-scroll", - zIndex: 10, - position: "absolute", - borderStyle: "dashed", - width: "150px", - height: "60px", - borderColor: themeColor(), - background: "#daebe0", - textAlign: "center", - justifyContent: "center", - alignItems: "center", - borderWidth: "0.2px" - }} - > -
{ - e.stopPropagation(); - handleDeleteSign(pos.key); - setIsStamp(false); - }} - style={{ - position: "absolute", - right: 0, - display: "inline-block", - background: themeColor(), - cursor: "pointer", - padding: "0px 10px" - }} - > - x -
-
- {pos.isStamp ? "stamp" : "signature"} -
-
-
- ); - })} -
- ); - }))} +
+ + ); + })} + + ); + }))} {/* this component for render pdf document is in middle of the component */} {Array.from(new Array(numPages), (el, index) => ( @@ -1326,4 +1337,4 @@ function RenderPdf({ ); } -export default RenderPdf; \ No newline at end of file +export default RenderPdf; diff --git a/microfrontends/SignDocuments/src/Component/recipientSignPdf.js b/microfrontends/SignDocuments/src/Component/recipientSignPdf.js index 801a30a54..2d73241b9 100644 --- a/microfrontends/SignDocuments/src/Component/recipientSignPdf.js +++ b/microfrontends/SignDocuments/src/Component/recipientSignPdf.js @@ -1,5 +1,5 @@ import React, { useState, useRef, useEffect } from "react"; -import { PDFDocument, rgb } from "pdf-lib"; +import { PDFDocument } from "pdf-lib"; import "../css/./signature.css"; import axios from "axios"; import Modal from "react-bootstrap/Modal"; @@ -19,7 +19,9 @@ import { contractUsers, contactBook, contractDocument, - urlValidator + urlValidator, + multiSignEmbed, + embedDocId } from "../utils/Utils"; import Tour from "reactour"; import Signedby from "./component/signedby"; @@ -424,23 +426,8 @@ function EmbedPdfImage() { if (isDocId) { pdfBase64 = await getBase64FromUrl(url); } else { - for (let i = 0; i < allPages; i++) { - const font = await pdfDoc.embedFont("Helvetica"); - - const fontSize = 10; - const textContent = docId && `OpenSign™ DocumentId: ${docId} `; - - const pages = pdfDoc.getPages(); - const page = pages[i]; - - page.drawText(textContent, { - x: 10, - y: page.getHeight() - 10, - size: fontSize, - font, - color: rgb(0.5, 0.5, 0.5) - }); - } + //embed document's object id to all pages in pdf document + await embedDocId(pdfDoc, docId, allPages); pdfBase64 = await pdfDoc.saveAsBase64({ useObjectStreams: false }); } for (let i = 0; i < xyPostion.length; i++) { @@ -475,115 +462,18 @@ function EmbedPdfImage() { } //else if signature is more than one then embed all sign with the use of pdf-lib else if (xyPostion.length > 0 && xyPostion[0].pos.length > 0) { - for (let i = 0; i < allPages; i++) { - const font = await pdfDoc.embedFont("Helvetica"); - - const fontSize = 10; - const textContent = docId && `OpenSign™ DocumentId: ${docId} `; - - const pages = pdfDoc.getPages(); - const page = pages[i]; - - page.drawText(textContent, { - x: 10, - y: page.getHeight() - 10, - size: fontSize, - font, - color: rgb(0.5, 0.5, 0.5) - }); - } - for (let i = 0; i < pngUrl.length; i++) { - const pageNo = pngUrl[i].pageNumber; - - const imgUrlList = pngUrl[i].pos; - const pages = pdfDoc.getPages(); - const page = pages[pageNo - 1]; - - const images = await Promise.all( - imgUrlList.map(async (url) => { - let signUrl = url.SignUrl; - if (url.ImageType === "image/png") { - //function for convert signature png base64 url to jpeg base64 - const newUrl = await convertPNGtoJPEG(signUrl); - signUrl = newUrl; - } - const checkUrl = urlValidator(signUrl); - if (checkUrl) { - signUrl = signUrl + "?get"; - } - const res = await fetch(signUrl); - - return res.arrayBuffer(); - }) - ); - images.forEach(async (imgData, id) => { - let img = await pdfDoc.embedJpg(imgData); - - const imgHeight = imgUrlList[id].Height - ? imgUrlList[id].Height - : 60; - const imgWidth = imgUrlList[id].Width ? imgUrlList[id].Width : 150; - const isMobile = window.innerWidth < 767; - const newWidth = window.innerWidth; - const scale = isMobile ? pdfOriginalWidth / newWidth : 1; - const xPos = (pos) => { - //checking both condition mobile and desktop view - if (isMobile) { - //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale - if (pos.isMobile) { - const x = pos.xPosition * (pos.scale / scale); - return x * scale + 50; - } else { - const x = pos.xPosition / scale; - return x * scale; - } - } else { - //else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale - if (pos.isMobile) { - const x = pos.xPosition * pos.scale + 50; - return x; - } else { - return pos.xPosition; - } - } - }; - const yPos = (pos) => { - //checking both condition mobile and desktop view - - if (isMobile) { - //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale - if (pos.isMobile) { - const y = pos.yPosition * (pos.scale / scale); - return page.getHeight() - y * scale - imgHeight; - } else { - const y = pos.yPosition / scale; - return page.getHeight() - y * scale - imgHeight; - } - } else { - //else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale - if (pos.isMobile) { - const y = pos.yPosition * pos.scale; - return page.getHeight() - y - imgHeight; - } else { - return page.getHeight() - pos.yPosition - imgHeight; - } - } - }; - - page.drawImage(img, { - x: xPos(imgUrlList[id]), - y: yPos(imgUrlList[id]), - width: imgWidth, - height: imgHeight - }); - }); - } - const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false }); + //embed document's object id to all pages in pdf document + await embedDocId(pdfDoc, docId, allPages); + //embed multi signature in pdf + const pdfBytes = await multiSignEmbed( + pngUrl, + pdfDoc, + pdfOriginalWidth, + false + ); signPdfFun(pdfBytes, docId); } - setIsSignPad(false); - setXyPostion([]); } } diff --git a/microfrontends/SignDocuments/src/css/signature.css b/microfrontends/SignDocuments/src/css/signature.css index b04074759..fb97f992e 100644 --- a/microfrontends/SignDocuments/src/css/signature.css +++ b/microfrontends/SignDocuments/src/css/signature.css @@ -643,6 +643,7 @@ option { .stickyfooter { position: fixed; + z-index: 32 !important; bottom: 0px; right: 0rem; } diff --git a/microfrontends/SignDocuments/src/utils/Utils.js b/microfrontends/SignDocuments/src/utils/Utils.js index a78fc3e94..015f97f7f 100644 --- a/microfrontends/SignDocuments/src/utils/Utils.js +++ b/microfrontends/SignDocuments/src/utils/Utils.js @@ -1,6 +1,6 @@ import axios from "axios"; -import { $ } from 'select-dom'; - +import { $ } from "select-dom"; +import { rgb } from "pdf-lib"; export async function getBase64FromUrl(url) { const data = await fetch(url); const blob = await data.blob(); @@ -327,18 +327,155 @@ export const contactBook = async (objectId) => { export function urlValidator(url) { try { const newUrl = new URL(url); - return newUrl.protocol === 'http:' || newUrl.protocol === 'https:'; + return newUrl.protocol === "http:" || newUrl.protocol === "https:"; } catch (err) { return false; } } export function modalAlign() { - let modalDialog = $('.modal-dialog').getBoundingClientRect(); - let mobileHead = $('.mobileHead').getBoundingClientRect() - let modal = $('.modal-dialog'); + let modalDialog = $(".modal-dialog").getBoundingClientRect(); + let mobileHead = $(".mobileHead").getBoundingClientRect(); + let modal = $(".modal-dialog"); if (modalDialog.left < mobileHead.left) { let leftOffset = mobileHead.left - modalDialog.left; - modal.style.left = leftOffset + 'px'; - modal.style.top = (window.innerHeight/3) + 'px'; + modal.style.left = leftOffset + "px"; + modal.style.top = window.innerHeight / 3 + "px"; + } +} + +//function for embed multiple signature using pdf-lib +export const multiSignEmbed = async ( + pngUrl, + pdfDoc, + pdfOriginalWidth, + signyourself +) => { + for (let i = 0; i < pngUrl.length; i++) { + const pageNo = pngUrl[i].pageNumber; + const imgUrlList = pngUrl[i].pos; + const pages = pdfDoc.getPages(); + const page = pages[pageNo - 1]; + const images = await Promise.all( + imgUrlList.map(async (url) => { + let signUrl = url.SignUrl; + if (url.ImageType === "image/png") { + //function for convert signature png base64 url to jpeg base64 + const newUrl = await convertPNGtoJPEG(signUrl); + signUrl = newUrl; + } + const checkUrl = urlValidator(signUrl); + if (checkUrl) { + signUrl = signUrl + "?get"; + } + const res = await fetch(signUrl); + return res.arrayBuffer(); + }) + ); + images.forEach(async (imgData, id) => { + let img; + if ( + (imgUrlList[id].ImageType && + imgUrlList[id].ImageType === "image/png") || + imgUrlList[id].ImageType === "image/jpeg" + ) { + img = await pdfDoc.embedJpg(imgData); + } else { + img = await pdfDoc.embedPng(imgData); + } + const imgHeight = imgUrlList[id].Height ? imgUrlList[id].Height : 60; + const imgWidth = imgUrlList[id].Width ? imgUrlList[id].Width : 150; + const isMobile = window.innerWidth < 767; + const newWidth = window.innerWidth - 32; + const scale = isMobile ? pdfOriginalWidth / newWidth : 1; + const xPos = (pos) => { + if (signyourself) { + if (isMobile) { + return imgUrlList[id].xPosition * scale + 43; + } else { + return imgUrlList[id].xPosition; + } + } else { + //checking both condition mobile and desktop view + if (isMobile) { + //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale + if (pos.isMobile) { + const x = pos.xPosition * (pos.scale / scale); + return x * scale + 50; + } else { + const x = pos.xPosition / scale; + return x * scale; + } + } else { + //else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale + if (pos.isMobile) { + const x = pos.xPosition * pos.scale + 50; + return x; + } else { + return pos.xPosition; + } + } + } + }; + + const yPos = (pos) => { + if (signyourself) { + if (isMobile) { + return ( + page.getHeight() - + imgUrlList[id].yPosition * scale - + imgHeight * scale + ); + } else { + return page.getHeight() - imgUrlList[id].yPosition - imgHeight; + } + } else { + //checking both condition mobile and desktop view + const y = pos.yPosition / scale; + if (isMobile) { + //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divided by scale + if (pos.isMobile) { + const y = pos.yPosition * (pos.scale / scale); + return page.getHeight() - y * scale - imgHeight; + } else { + return page.getHeight() - y * scale - imgHeight; + } + } else { + //else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale + if (pos.isMobile) { + const y = pos.yPosition * pos.scale; + return page.getHeight() - y - imgHeight; + } else { + return page.getHeight() - pos.yPosition - imgHeight; + } + } + } + }; + + page.drawImage(img, { + x: xPos(imgUrlList[id]), + y: yPos(imgUrlList[id]), + width: signyourself ? imgWidth * scale : imgWidth, + height: signyourself ? imgHeight * scale : imgHeight + }); + }); + } + const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false }); + return pdfBytes; +}; +//function for embed document id +export const embedDocId = async (pdfDoc, documentId, allPages) => { + for (let i = 0; i < allPages; i++) { + const font = await pdfDoc.embedFont("Helvetica"); + const fontSize = 10; + const textContent = documentId && `OpenSign™ DocumentId: ${documentId} `; + const pages = pdfDoc.getPages(); + const page = pages[i]; + page.drawText(textContent, { + x: 10, + y: page.getHeight() - 10, + size: fontSize, + font, + color: rgb(0.5, 0.5, 0.5) + }); } };