diff --git a/apps/OpenSign/src/components/pdf/RenderAllPdfPage.js b/apps/OpenSign/src/components/pdf/RenderAllPdfPage.js index cb1fa0700..f8642ab9a 100644 --- a/apps/OpenSign/src/components/pdf/RenderAllPdfPage.js +++ b/apps/OpenSign/src/components/pdf/RenderAllPdfPage.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState } from "react"; import RSC from "react-scrollbars-custom"; import { Document, Page } from "react-pdf"; import { themeColor } from "../../constant/const"; @@ -9,13 +9,48 @@ function RenderAllPdfPage({ setAllPages, setPageNumber, setSignBtnPosition, - pageNumber + pageNumber, + signerPos, + signerObjectId }) { + const [signPageNumber, setSignPageNumber] = useState([]); //set all number of pages after load pdf function onDocumentLoad({ numPages }) { setAllPages(numPages); + if (signerPos) { + const checkUser = signerPos.filter( + (data) => data.signerObjId === signerObjectId + ); + let pageNumberArr = []; + if (checkUser?.length > 0) { + checkUser[0]?.placeHolder?.map((data) => { + pageNumberArr.push(data?.pageNumber); + }); + + setSignPageNumber(pageNumberArr); + } + } } + //'function `addSignatureBookmark`f function is utilized to display the page where the user's signature is located. + const addSignatureBookmark = (index) => { + const ispageNumber = signPageNumber.includes(index + 1); + return ( + ispageNumber && ( +
+ +
+ ) + ); + }; return (
{ setPageNumber(index + 1); @@ -75,15 +111,25 @@ function RenderAllPdfPage({ } }} > - + {signerPos && addSignatureBookmark(index)} + +
+ +
))} diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js index 624abf6e2..bdd274ecd 100644 --- a/apps/OpenSign/src/pages/PdfRequestFiles.js +++ b/apps/OpenSign/src/pages/PdfRequestFiles.js @@ -472,36 +472,8 @@ function PdfRequestFiles() { }); }; - // const checkSendInOrder = () => { - // if (sendInOrder) { - // const index = pdfDetails?.[0].Signers.findIndex( - // (x) => x.Email === jsonSender.email - // ); - // const newIndex = index - 1; - // if (newIndex !== -1) { - // const user = pdfDetails?.[0].Signers[newIndex]; - // const isPrevUserSigned = - // pdfDetails?.[0].AuditTrail && - // pdfDetails?.[0].AuditTrail.some( - // (x) => - // x.UserPtr.objectId === user.objectId && x.Activity === "Signed" - // ); - // if (isPrevUserSigned) { - // return true; - // } else { - // return false; - // } - // } else { - // return true; - // } - // } else { - // return true; - // } - // }; //function for embed signature or image url in pdf async function embedWidgetsData() { - // const validateSigning = checkSendInOrder(); - // if (validateSigning) { try { const checkUser = signerPos.filter( (data) => data.signerObjId === signerObjectId @@ -512,83 +484,97 @@ function PdfRequestFiles() { showAlert = false, widgetKey, radioExist, - requiredCheckbox; + requiredCheckbox, + pageNumber; // `pageNumber` is used to check on which page user did not fill widget's data then change current pageNumber and show tour message on that page for (let i = 0; i < checkUser[0].placeHolder.length; i++) { for (let j = 0; j < checkUser[0].placeHolder[i].pos.length; j++) { + //get current page + const updatePage = checkUser[0].placeHolder[i]?.pageNumber; + //checking checbox type widget checkboxExist = checkUser[0].placeHolder[i].pos[j].type === "checkbox"; + //checking radio button type widget radioExist = checkUser[0].placeHolder[i].pos[j].type === radioButtonWidget; + //condition to check checkbox widget exist or not if (checkboxExist) { + //get all required type checkbox requiredCheckbox = checkUser[0].placeHolder[i].pos.filter( (position) => !position.options?.isReadOnly && position.type === "checkbox" ); - + //if required type checkbox data exit then check user checked all checkbox or some checkbox remain to check + //also validate to minimum and maximum required checkbox if (requiredCheckbox && requiredCheckbox.length > 0) { for (let i = 0; i < requiredCheckbox.length; i++) { + //get minimum required count if exit const minCount = requiredCheckbox[i].options?.validation?.minRequiredCount; const parseMin = minCount && parseInt(minCount); + //get maximum required count if exit const maxCount = requiredCheckbox[i].options?.validation?.maxRequiredCount; const parseMax = maxCount && parseInt(maxCount); + //in `response` variable is used to get how many checkbox checked by user const response = requiredCheckbox[i].options?.response?.length; + //in `defaultValue` variable is used to get how many checkbox checked by default const defaultValue = requiredCheckbox[i].options?.defaultValue?.length; - if (parseMin === 0 && parseMax === 0) { - if (!showAlert) { - showAlert = false; - setminRequiredCount(null); - } - } else if (parseMin === 0 && parseMax > 0) { - if (!showAlert) { - showAlert = false; - setminRequiredCount(null); - } - } else if (!response) { - if (!defaultValue) { - if (!showAlert) { - showAlert = true; - widgetKey = requiredCheckbox[i].key; - setminRequiredCount(parseMin); - } - } - } else if (parseMin > 0 && parseMin > response) { + //condition to check parseMin and parseMax greater than 0 then consider it as a required check box + if ( + parseMin > 0 && + parseMax > 0 && + !response && + !defaultValue && + !showAlert + ) { + showAlert = true; + widgetKey = requiredCheckbox[i].key; + pageNumber = updatePage; + setminRequiredCount(parseMin); + } + //else condition to validate minimum required checkbox + else if (parseMin > 0 && parseMin > response) { if (!showAlert) { showAlert = true; widgetKey = requiredCheckbox[i].key; + pageNumber = updatePage; + setminRequiredCount(parseMin); } } } } - } else if (radioExist) { + } + //condition to check radio widget exist or not + else if (radioExist) { + //get all required type radio button requiredRadio = checkUser[0].placeHolder[i].pos.filter( (position) => !position.options?.isReadOnly && position.type === radioButtonWidget ); + //if required type radio data exit then check user checked all radio button or some radio remain to check if (requiredRadio && requiredRadio?.length > 0) { let checkSigned; for (let i = 0; i < requiredRadio?.length; i++) { checkSigned = requiredRadio[i]?.options.response; - if (!checkSigned) { - let checkDefaultSigned = - requiredRadio[i]?.options.defaultValue; - if (!checkDefaultSigned) { - if (!showAlert) { - showAlert = true; - widgetKey = requiredRadio[i].key; - setminRequiredCount(null); - } - } + let checkDefaultSigned = + requiredRadio[i]?.options.defaultValue; + if (!checkSigned && !checkDefaultSigned && !showAlert) { + showAlert = true; + widgetKey = requiredRadio[i].key; + pageNumber = updatePage; + setminRequiredCount(null); } } } - } else { + } + //else condition to check all type widget data fill or not except checkbox and radio button + else { + //get all required type widgets except checkbox and radio const requiredWidgets = checkUser[0].placeHolder[i].pos.filter( (position) => position.options?.status === "required" && @@ -601,33 +587,36 @@ function PdfRequestFiles() { checkSigned = requiredWidgets[i]?.options?.response; if (!checkSigned) { const checkSignUrl = requiredWidgets[i]?.pos?.SignUrl; - let checkDefaultSigned = requiredWidgets[i]?.options?.defaultValue; - if (!checkSignUrl) { - if (!checkDefaultSigned) { - if (!showAlert) { - showAlert = true; - widgetKey = requiredWidgets[i].key; - setminRequiredCount(null); - } - } + if (!checkSignUrl && !checkDefaultSigned && !showAlert) { + showAlert = true; + widgetKey = requiredWidgets[i].key; + pageNumber = updatePage; + setminRequiredCount(null); } } } } } } + //when showAlert is true then break the loop and show alert to fill required data in widgets + if (showAlert) { + break; + } } if (checkboxExist && requiredCheckbox && showAlert) { setUnSignedWidgetId(widgetKey); + setPageNumber(pageNumber); setWidgetsTour(true); } else if (radioExist && showAlert) { setUnSignedWidgetId(widgetKey); + setPageNumber(pageNumber); setWidgetsTour(true); } else if (showAlert) { setUnSignedWidgetId(widgetKey); + setPageNumber(pageNumber); setWidgetsTour(true); } else { setIsUiLoading(true); @@ -882,15 +871,6 @@ function PdfRequestFiles() { alertMessage: "something went wrong, please try again later." }); } - - // } - // else { - // setIsAlert({ - // isShow: true, - // alertMessage: - // "Please wait for your turn to sign this document, as it has been set up by the creator to be signed in a specific order; you'll be notified when it's your turn." - // }); - // } } //function for update TourStatus @@ -1349,6 +1329,8 @@ function PdfRequestFiles() { {/* this component used to render all pdf pages in left side */} 0) { + const alreadyPlaceholder = documentData[0]?.SignedUrl; + if (alreadyPlaceholder) { + setCheckTourStatus(true); + } else if (tourstatus && tourstatus.length > 0) { setTourStatus(tourstatus); const checkTourRecipients = tourstatus.filter( (data) => data.placeholder diff --git a/apps/OpenSign/src/pages/SignyourselfPdf.js b/apps/OpenSign/src/pages/SignyourselfPdf.js index 027abb889..db813272f 100644 --- a/apps/OpenSign/src/pages/SignyourselfPdf.js +++ b/apps/OpenSign/src/pages/SignyourselfPdf.js @@ -233,29 +233,6 @@ function SignYourSelf() { setSignBtnPosition([]); } } - - if (!isCompleted) { - //check current user email verified or not - const currentUser = JSON.parse(JSON.stringify(Parse.User.current())); - let isEmailVerified; - isEmailVerified = currentUser?.emailVerified; - if (isEmailVerified) { - setIsEmailVerified(isEmailVerified); - } else { - try { - const userQuery = new Parse.Query(Parse.User); - const user = await userQuery.get(currentUser.objectId, { - sessionToken: localStorage.getItem("accesstoken") - }); - if (user) { - isEmailVerified = user?.get("emailVerified"); - setIsEmailVerified(isEmailVerified); - } - } catch (e) { - setHandleError("Error: Something went wrong!"); - } - } - } } else if ( documentData === "Error: Something went wrong!" || (documentData.result && documentData.result.error) @@ -603,104 +580,126 @@ function SignYourSelf() { }; //function for send placeholder's co-ordinate(x,y) position embed signature url or stamp url async function embedWidgetsData() { - let showAlert = false, - isSignatureExist = false; - try { - for (let i = 0; i < xyPostion?.length; i++) { - const requiredWidgets = xyPostion[i].pos.filter( - (position) => position.type !== "checkbox" - ); - if (requiredWidgets && requiredWidgets?.length > 0) { - let checkSigned; - for (let i = 0; i < requiredWidgets?.length; i++) { - checkSigned = requiredWidgets[i]?.options?.response; - if (!checkSigned) { - const checkSignUrl = requiredWidgets[i]?.pos?.SignUrl; - let checkDefaultSigned = - requiredWidgets[i]?.options?.defaultValue; - if (!checkSignUrl) { - if (!checkDefaultSigned) { - if (!showAlert) { - showAlert = true; + //check current user email is verified or not + const currentUser = JSON.parse(JSON.stringify(Parse.User.current())); + let isEmailVerified; + isEmailVerified = currentUser?.emailVerified; + if (isEmailVerified) { + setIsEmailVerified(isEmailVerified); + } else { + try { + const userQuery = new Parse.Query(Parse.User); + const user = await userQuery.get(currentUser.objectId, { + sessionToken: localStorage.getItem("accesstoken") + }); + if (user) { + isEmailVerified = user?.get("emailVerified"); + setIsEmailVerified(isEmailVerified); + } + } catch (e) { + setHandleError("Error: Something went wrong!"); + } + } + if (isEmailVerified) { + let showAlert = false, + isSignatureExist = false; + try { + for (let i = 0; i < xyPostion?.length; i++) { + const requiredWidgets = xyPostion[i].pos.filter( + (position) => position.type !== "checkbox" + ); + if (requiredWidgets && requiredWidgets?.length > 0) { + let checkSigned; + for (let i = 0; i < requiredWidgets?.length; i++) { + checkSigned = requiredWidgets[i]?.options?.response; + if (!checkSigned) { + const checkSignUrl = requiredWidgets[i]?.pos?.SignUrl; + let checkDefaultSigned = + requiredWidgets[i]?.options?.defaultValue; + if (!checkSignUrl) { + if (!checkDefaultSigned) { + if (!showAlert) { + showAlert = true; + } } } } } } - } - //condition to check exist signature widget or not - if (!isSignatureExist) { - isSignatureExist = xyPostion[i].pos.some( - (data) => data?.type === "signature" - ); - } - } - if (xyPostion.length === 0 || !isSignatureExist) { - setIsAlert({ - header: "Fields required", - isShow: true, - alertMessage: - "Please ensure there's at least one signature widget added" - }); - return; - } else if (showAlert) { - setIsAlert({ - isShow: true, - alertMessage: - "Please ensure all field is accurately filled and meets all requirements." - }); - return; - } else { - setIsCeleb(true); - setTimeout(() => { - setIsCeleb(false); - }, 3000); - setIsUiLoading(true); - const existingPdfBytes = pdfArrayBuffer; - // Load a PDFDocument from the existing PDF bytes - try { - const pdfDoc = await PDFDocument.load(existingPdfBytes); - const isSignYourSelfFlow = true; - const extUserPtr = pdfDetails[0].ExtUserPtr; - const HeaderDocId = extUserPtr?.HeaderDocId; - //embed document's object id to all pages in pdf document - if (!HeaderDocId) { - await embedDocId(pdfDoc, documentId, allPages); - } - //embed multi signature in pdf - const pdfBytes = await multiSignEmbed( - xyPostion, - pdfDoc, - pdfOriginalWidth, - isSignYourSelfFlow, - containerWH - ); - // console.log("pdf", pdfBytes); - //function for call to embed signature in pdf and get digital signature pdf - await signPdfFun(pdfBytes, documentId); - } catch (err) { - setIsUiLoading(false); - if (err && err.message.includes("is encrypted.")) { - setIsAlert({ - isShow: true, - alertMessage: `Currently encrypted pdf files are not supported.` - }); - } else { - console.log("err in signing", err); - setIsAlert({ - isShow: true, - alertMessage: `Something went wrong.` - }); + //condition to check exist signature widget or not + if (!isSignatureExist) { + isSignatureExist = xyPostion[i].pos.some( + (data) => data?.type === "signature" + ); } } + if (xyPostion.length === 0 || !isSignatureExist) { + setIsAlert({ + header: "Fields required", + isShow: true, + alertMessage: + "Please ensure there's at least one signature widget added" + }); + return; + } else if (showAlert) { + setIsAlert({ + isShow: true, + alertMessage: + "Please ensure all field is accurately filled and meets all requirements." + }); + return; + } else { + setIsCeleb(true); + setTimeout(() => { + setIsCeleb(false); + }, 3000); + setIsUiLoading(true); + const existingPdfBytes = pdfArrayBuffer; + // Load a PDFDocument from the existing PDF bytes + try { + const pdfDoc = await PDFDocument.load(existingPdfBytes); + const isSignYourSelfFlow = true; + const extUserPtr = pdfDetails[0].ExtUserPtr; + const HeaderDocId = extUserPtr?.HeaderDocId; + //embed document's object id to all pages in pdf document + if (!HeaderDocId) { + await embedDocId(pdfDoc, documentId, allPages); + } + //embed multi signature in pdf + const pdfBytes = await multiSignEmbed( + xyPostion, + pdfDoc, + pdfOriginalWidth, + isSignYourSelfFlow, + containerWH + ); + // console.log("pdf", pdfBytes); + //function for call to embed signature in pdf and get digital signature pdf + await signPdfFun(pdfBytes, documentId); + } catch (err) { + setIsUiLoading(false); + if (err && err.message.includes("is encrypted.")) { + setIsAlert({ + isShow: true, + alertMessage: `Currently encrypted pdf files are not supported.` + }); + } else { + console.log("err in signing", err); + setIsAlert({ + isShow: true, + alertMessage: `Something went wrong.` + }); + } + } + } + } catch (err) { + console.log("err in embedselfsign ", err); + setIsUiLoading(false); + setIsAlert({ + isShow: true, + alertMessage: "something went wrong, please try again later." + }); } - } catch (err) { - console.log("err in embedselfsign ", err); - setIsUiLoading(false); - setIsAlert({ - isShow: true, - alertMessage: "something went wrong, please try again later." - }); } } //function for get digital signature