From 939d917b7b37c5dfe76b32ac856880c40513e4e4 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Fri, 12 Jan 2024 22:01:20 +0530 Subject: [PATCH 01/58] feat: implement changes to ensure compatibility with multiple widgets --- .../src/Component/SignYourselfPdf.js | 144 ++- .../Component/WidgetComponent/allWidgets.js | 72 ++ .../WidgetComponent/dropdownWidgetOption.js | 141 ++ .../Component/WidgetComponent/placeholder.js | 236 ++++ .../WidgetComponent/placeholderBorder.js | 29 + .../WidgetComponent/placeholderType.js | 165 +++ .../Component/component/fieldsComponent.js | 242 +++- .../src/Component/component/renderPdf.js | 1142 +++++++++++------ .../src/Component/component/signPad.js | 17 +- .../src/Component/placeHolderSign.js | 94 +- .../SignDocuments/src/css/signature.css | 88 +- .../SignDocuments/src/utils/Utils.js | 311 ++++- 12 files changed, 2164 insertions(+), 517 deletions(-) create mode 100644 microfrontends/SignDocuments/src/Component/WidgetComponent/allWidgets.js create mode 100644 microfrontends/SignDocuments/src/Component/WidgetComponent/dropdownWidgetOption.js create mode 100644 microfrontends/SignDocuments/src/Component/WidgetComponent/placeholder.js create mode 100644 microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderBorder.js create mode 100644 microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderType.js diff --git a/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js b/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js index 221d3d3f7..5e4f05de6 100644 --- a/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js +++ b/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js @@ -103,9 +103,8 @@ function SignYourSelf() { const [{ isDragSign }, dragSignature] = useDrag({ type: "BOX", item: { - type: "BOX", id: 1, - text: "drag me" + text: "signature" }, collect: (monitor) => ({ isDragSign: !!monitor.isDragging() @@ -115,14 +114,14 @@ function SignYourSelf() { const [{ isDragStamp }, dragStamp] = useDrag({ type: "BOX", item: { - type: "BOX", id: 2, - text: "drag me" + text: "stamp" }, collect: (monitor) => ({ isDragStamp: !!monitor.isDragging() }) }); + const [{ isDragSignatureSS }, dragSignatureSS] = useDrag({ type: "BOX", @@ -172,6 +171,17 @@ function SignYourSelf() { const jsonSender = JSON.parse(senderUser); useEffect(() => { + // localStorage.setItem("accesstoken", "r:d70a32032557e982aab7aec1cae668fc"); + // localStorage.setItem( + // "baseUrl", + // "https://staging-app.opensignlabs.com/api/app/" + // ); + // localStorage.setItem("parseAppId", "opensignstgn"); + // localStorage.setItem( + // "Parse/opensignstgn/currentUser", + // '{"name":"raktima","email":"raktimachaurasiya@gmail.com","phone":"9876567876","username":"raktimachaurasiya@gmail.com","createdAt":"2024-01-03T05:48:49.407Z","sessionToken":"r:d70a32032557e982aab7aec1cae668fc","updatedAt":"2024-01-03T05:48:49.407Z","emailVerified":false,"ACL":{"YHwDtLNto7":{"read":true,"write":true}},"__type":"Object","className":"_User","objectId":"YHwDtLNto7"}' + // ); + // localStorage.setItem("_appName", "contracts"); if (documentId) { getDocumentDetails(true); } @@ -316,16 +326,18 @@ function SignYourSelf() { const addPositionOfSignature = (item, monitor) => { const key = Math.floor(1000 + Math.random() * 9000); let dropData = []; + let dropObj = {}; let filterDropPos = xyPostion.filter( (data) => data.pageNumber === pageNumber ); if (item === "onclick") { - const dropObj = { + dropObj = { xPosition: window.innerWidth / 2 - 100, yPosition: window.innerHeight / 2 - 60, isDrag: false, key: key, isStamp: monitor, + type: item.text, yBottom: window.innerHeight / 2 - 60 }; @@ -347,7 +359,7 @@ function SignYourSelf() { const y = offset.y - containerRect.top; const ybottom = containerRect.bottom - offset.y; - const dropObj = { + dropObj = { xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x, yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y, isDrag: false, @@ -355,7 +367,8 @@ function SignYourSelf() { isStamp: isDragStamp || isDragStampSS ? true : false, firstXPos: signBtnPosition[0] && signBtnPosition[0].xPos, firstYPos: signBtnPosition[0] && signBtnPosition[0].yPos, - yBottom: ybottom + yBottom: ybottom, + type: item.text }; dropData.push(dropObj); @@ -379,8 +392,11 @@ function SignYourSelf() { pos: newSignPos }; xyPostion.splice(index, 1, xyPos); - setIsSignPad(true); - setSignKey(key); + if (isDragSign || isDragSignatureSS || isDragStamp || isDragStampSS) { + setIsSignPad(true); + setSignKey(key); + } + // } } else { const xyPos = { @@ -388,8 +404,11 @@ function SignYourSelf() { pos: dropData }; setXyPostion((prev) => [...prev, xyPos]); - setIsSignPad(true); - setSignKey(key); + + if (isDragSign || isDragSignatureSS) { + setIsSignPad(true); + setSignKey(key); + } } // setXyPostion((prev) => [...prev, xyPos]); @@ -405,64 +424,64 @@ function SignYourSelf() { checkSignUrl.push(posData); } } - if (xyPostion.length === 0) { - setIsAlert({ - isShow: true, - alertMessage: "Please complete your signature!" - }); - return; - } else if (xyPostion.length > 0 && checkSignUrl.length > 0) { - setIsAlert({ - isShow: true, - alertMessage: "Please complete your signature!" - }); - return; - } else { - setIsCeleb(true); - setTimeout(() => { - setIsCeleb(false); - }, 3000); - const loadObj = { - isLoad: true, - message: "This might take some time" - }; - setIsLoading(loadObj); - const url = pdfDetails[0] && pdfDetails[0].URL; + // if (xyPostion.length === 0) { + // setIsAlert({ + // isShow: true, + // alertMessage: "Please complete your signature!" + // }); + // return; + // } else if (xyPostion.length > 0 && checkSignUrl.length > 0) { + // setIsAlert({ + // isShow: true, + // alertMessage: "Please complete your signature!" + // }); + // return; + // } else { + setIsCeleb(true); + setTimeout(() => { + setIsCeleb(false); + }, 3000); + const loadObj = { + isLoad: true, + message: "This might take some time" + }; + setIsLoading(loadObj); + const url = pdfDetails[0] && pdfDetails[0].URL; - const existingPdfBytes = await fetch(url).then((res) => - res.arrayBuffer() - ); + const existingPdfBytes = await fetch(url).then((res) => res.arrayBuffer()); - // Load a PDFDocument from the existing PDF bytes - const pdfDoc = await PDFDocument.load(existingPdfBytes, { - ignoreEncryption: true - }); + // Load a PDFDocument from the existing PDF bytes + const pdfDoc = await PDFDocument.load(existingPdfBytes, { + ignoreEncryption: true + }); - const flag = true; - //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( - xyPostion, - pdfDoc, - pdfOriginalWidth, - flag, - containerWH - ); + const flag = true; + //embed document's object id to all pages in pdf document + await embedDocId(pdfDoc, documentId, allPages); - //function for call to embed signature in pdf and get digital signature pdf - signPdfFun(pdfBytes, documentId); - setIsSignPad(false); - setIsEmail(true); - setXyPostion([]); - setSignBtnPosition([]); - } + //embed multi signature in pdf + const pdfBytes = await multiSignEmbed( + xyPostion, + pdfDoc, + pdfOriginalWidth, + flag, + containerWH + ); + + console.log("pdf", pdfBytes); + //function for call to embed signature in pdf and get digital signature pdf + signPdfFun(pdfBytes, documentId); + + setIsSignPad(false); + setIsEmail(true); + setXyPostion([]); + setSignBtnPosition([]); + // } } //function for get digital signature const signPdfFun = async (base64Url, documentId) => { - const singleSign = { + let singleSign = { pdfFile: base64Url, docId: documentId }; @@ -603,7 +622,6 @@ function SignYourSelf() { setXyPostion(getUpdatePosition); }; - //function for capture position on hover signature button const handleDivClick = (e) => { const divRect = e.currentTarget.getBoundingClientRect(); @@ -664,11 +682,9 @@ function SignYourSelf() { setXyPostion(getXyData); setShowAlreadySignDoc({ status: false }); }; - const handleDontShow = (isChecked) => { setIsDontShow(isChecked); }; - const tourConfig = [ { selector: '[data-tut="reactourFirst"]', diff --git a/microfrontends/SignDocuments/src/Component/WidgetComponent/allWidgets.js b/microfrontends/SignDocuments/src/Component/WidgetComponent/allWidgets.js new file mode 100644 index 000000000..74f3d6aab --- /dev/null +++ b/microfrontends/SignDocuments/src/Component/WidgetComponent/allWidgets.js @@ -0,0 +1,72 @@ +import React from "react"; +import { themeColor } from "../../utils/ThemeColor/backColor"; +import { getWidgetType } from "../../utils/Utils"; + +function AllWidgets(props) { + const signStyle = "signatureBtn"; + + return props.updateWidgets.map((item, ind) => { + return ( +
{ + item.ref(element); + if (element) { + if (props?.signRef) { + props.signRef.current = element; + } + } + }} + className={signStyle} + onMouseMove={props?.handleDivClick} + onMouseDown={props?.handleMouseLeave} + style={{ + // opacity: isDragSign ? 0.5 : 1, + boxShadow: + "0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18)", + marginLeft: `${props?.marginLeft}px` + }} + > + {/*
+ + + {item.type} + +
+
+ +
*/} + {getWidgetType(item)} +
+ ); + }); +} + +export default AllWidgets; diff --git a/microfrontends/SignDocuments/src/Component/WidgetComponent/dropdownWidgetOption.js b/microfrontends/SignDocuments/src/Component/WidgetComponent/dropdownWidgetOption.js new file mode 100644 index 000000000..8888a7c5b --- /dev/null +++ b/microfrontends/SignDocuments/src/Component/WidgetComponent/dropdownWidgetOption.js @@ -0,0 +1,141 @@ +import React, { useState } from "react"; +import Modal from "react-bootstrap/Modal"; +import ModalHeader from "react-bootstrap/esm/ModalHeader"; +import { themeColor } from "../../utils/ThemeColor/backColor"; +function DropdownWidgetOption(props) { + const [dropdownOptionList, setDropdownOptionList] = useState([ + "option-1", + "option-2" + ]); + + const [dropdownName, setDropdownName] = useState("Dropdown-1"); + const [error, setError] = useState(""); + const handleInputChange = (index, value) => { + setDropdownOptionList((prevInputs) => { + const newInputs = [...prevInputs]; + newInputs[index] = value; + return newInputs; + }); + }; + + const handleAddInput = () => { + setDropdownOptionList((prevInputs) => [...prevInputs, ""]); + }; + const handleAddOption = () => { + setDropdownOptionList([...dropdownOptionList, ""]); + }; + const handleDeleteInput = (ind) => { + const getUpdatedOptions = dropdownOptionList.filter( + (data, index) => index !== ind + ); + setDropdownOptionList(getUpdatedOptions); + }; + const handleSaveOption = () => { + const existEmptyOption = dropdownOptionList.some((data) => data === ""); + + if (existEmptyOption) { + setError("Enter all option"); + setTimeout(() => { + setError(""); + }, 1000); + } else { + props.handleSaveDropdownOptions(dropdownName, dropdownOptionList); + props.setShowDropdown(false); + } + }; + + return ( + //props.showDropdown + + + Dropdown options + + +
+ + setDropdownName(e.target.value)} + className="drodown-input" + /> + + +
+ {dropdownOptionList.map((option, index) => ( +
+ handleInputChange(index, e.target.value)} + /> + + handleDeleteInput(index)} + style={{ color: "red", fontSize: "25px", marginLeft: "10px" }} + > +
+ ))} + + +
+
+ {error} +
+ + + + +
+ ); +} + +export default DropdownWidgetOption; diff --git a/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholder.js b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholder.js new file mode 100644 index 000000000..adf770299 --- /dev/null +++ b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholder.js @@ -0,0 +1,236 @@ +import React from "react"; +import BorderResize from "../component/borderResize"; +import PlaceholderBorder from "./placeholderBorder"; +import { Rnd } from "react-rnd"; +import { defaultWidthHeight } from "../../utils/Utils"; +import PlaceholderType from "./placeholderType"; + +function Placeholder(props) { + const handlePlaceholderClick = () => { + if (!props.data && !props.isDragging) { + if (props.pos.type) { + if (props.pos.type === "signature" || props.pos.type === "stamp") { + props.setIsSignPad(true); + props.setSignKey(props.pos.key); + props.setIsStamp(props.pos.isStamp); + } else if (props.pos.type === "dropdown") { + props.setShowDropdown(true); + props.setSignKey(props.pos.key); + } + } else { + props.setIsSignPad(true); + props.setSignKey(props.pos.key); + props.setIsStamp(props.pos?.isStamp ? props.pos.isStamp : false); + } + } else if (props.isPlaceholder && props.pos.type) { + if (props.pos.type === "dropdown") { + props.setShowDropdown(true); + props.setSignKey(props.pos.key); + } + } else { + if ( + !props.pos.type && + props.isNeedSign && + props.data.signerObjId === props.signerObjId + ) { + props.setIsSignPad(true); + props.setSignKey(props.pos.key); + props.setIsStamp(props.pos.isStamp); + } else if ( + (props.isNeedSign && props.pos.type === "signature") || + props.pos.type === "stamp" + ) { + props.setIsSignPad(true); + props.setSignKey(props.pos.key); + props.setIsStamp(props.pos.isStamp); + } else if (props.isNeedSign && props.pos.type === "dropdown") { + props.setSignKey(props.pos.key); + } + } + }; + + return ( + props.handleTabDrag && props.handleTabDrag(props.pos.key)} + size={{ + width: props.posWidth(props.pos, props.isSignYourself), + height: props.posHeight(props.pos, props.isSignYourself) + }} + onResizeStart={() => { + props.setIsResize && props.setIsResize(true); + }} + onResizeStop={() => { + props.setIsResize && props.setIsResize(false); + }} + disableDragging={props.isNeedSign || (props.isRecipient && true)} + onDragStop={(event, dragElement) => + props.handleStop && + props.handleStop(event, dragElement, props.signerObjId, props.pos.key) + } + default={{ + x: props.xPos(props.pos, props.isSignYourself), + y: props.yPos(props.pos, props.isSignYourself) + }} + onResize={(e, direction, ref, delta, position) => { + props.handleSignYourselfImageResize && + props.handleSignYourselfImageResize( + ref, + props.pos.key, + props.xyPostion, + props.setXyPostion, + props.index, + props.data && props.data.Id, + false + ); + }} + onClick={() => handlePlaceholderClick()} + > + {props.isShowBorder ? ( + + ) : props.data && props.isNeedSign ? ( + props.data?.signerObjId === props.signerObjId ? ( + + ) : ( + <> + ) + ) : ( + + )} + + {props.isShowBorder && } +
handlePlaceholderClick()} + > + {props.isShowBorder && ( + <> + {props.isPlaceholder && ( + { + e.stopPropagation(); + props.handleLinkUser(props.data.Id); + props.setUniqueId(props.data.Id); + }} + onTouchEnd={(e) => { + e.stopPropagation(); + props.handleLinkUser(props.data.Id); + props.setUniqueId(props.data.Id); + }} + style={{ + color: "#188ae2" + }} + > + )} + + { + if (props.data) { + props.setSignerObjId(props.data.signerObjId); + } + e.stopPropagation(); + props.setIsPageCopy(true); + props.setSignKey(props.pos.key); + }} + onTouchEnd={(e) => { + if (props.data) { + props.setSignerObjId(props.data.signerObjId); + } + e.stopPropagation(); + props.setIsPageCopy(true); + props.setSignKey(props.pos.key); + }} + style={{ + color: "#188ae2" + }} + > + { + e.stopPropagation(); + if (props.data) { + props.handleDeleteSign(props.pos.key, props.data.signerObjId); + } else { + props.handleDeleteSign(props.pos.key); + props.setIsStamp(false); + } + }} + onTouchEnd={(e) => { + e.stopPropagation(); + if (props.data) { + props.handleDeleteSign(props.pos.key, props.data.signerObjId); + } else { + props.handleDeleteSign(props.pos.key); + props.setIsStamp(false); + } + }} + style={{ + color: "#188ae2" + }} + > + + )} + + +
+
+ ); +} + +export default Placeholder; diff --git a/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderBorder.js b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderBorder.js new file mode 100644 index 000000000..143ba17d8 --- /dev/null +++ b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderBorder.js @@ -0,0 +1,29 @@ +import React from "react"; +import { themeColor } from "../../utils/ThemeColor/backColor"; +import { defaultWidthHeight, resizeBorderExtraWidth } from "../../utils/Utils"; +function PlaceholderBorder(props) { + const getResizeBorderExtraWidth = resizeBorderExtraWidth(); + const defaultWidth = defaultWidthHeight(props.pos.type).width; + const defaultHeight = defaultWidthHeight(props.pos.type).height; + + return ( +
+ ); +} + +export default PlaceholderBorder; diff --git a/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderType.js b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderType.js new file mode 100644 index 000000000..6c8c401ef --- /dev/null +++ b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderType.js @@ -0,0 +1,165 @@ +import React, { useState } from "react"; +import { onChangeInput } from "../../utils/Utils"; + +function PlaceholderType(props) { + const [selectOption, setSelectOption] = useState(""); + + switch (props.pos.type) { + case "signature": + return props.pos.SignUrl ? ( +
+ signimg +
+ ) : ( +
+
{props.pos.type}
+ + {props?.handleUserName && + props?.handleUserName(props?.data.signerObjId, props?.data.Role)} +
+ ); + + case "stamp": + return props.pos.SignUrl ? ( +
+ signimg +
+ ) : ( +
+
{props.pos.type}
+ + {props?.handleUserName && + props?.handleUserName(props?.data?.signerObjId, props?.data?.Role)} +
+ ); + + case "checkbox": + return ( + + onChangeInput( + e.target.checked, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data.signerObjId, + false + ) + } + /> + ); + case "text": + return ( + + onChangeInput( + e.target.value, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data.signerObjId, + false + ) + } + /> + ); + case "dropdown": + return !props.isPlaceholder ? ( + + ) : ( +
+ {props.pos.widgetName ? props.pos.widgetName : props.pos.type} +
+ ); + + default: + return props.pos.SignUrl ? ( +
+ signimg +
+ ) : ( +
+ {props.pos.isStamp ?
stamp
:
signature
} + {props?.handleUserName && + props?.handleUserName(props?.data?.signerObjId, props?.data?.Role)} +
+ ); + } +} + +export default PlaceholderType; diff --git a/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js b/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js index c3b4947ef..bc2efa951 100644 --- a/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js +++ b/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js @@ -1,6 +1,9 @@ -import React, { useState } from "react"; +import React, { useState, useRef, useEffect } from "react"; import ModalUi from "../../premitives/ModalUi"; import RecipientList from "../../premitives/RecipientList"; +import { useDrag } from "react-dnd"; +import AllWidgets from "../WidgetComponent/allWidgets"; +import { widgets } from "../../utils/Utils"; function FieldsComponent({ pdfUrl, @@ -39,9 +42,44 @@ function FieldsComponent({ title }) { const [isSignersModal, setIsSignersModal] = useState(false); - const signStyle = pdfUrl ? "disableSign" : "signatureBtn"; + const [{ isDragDropdown }, dropdown] = useDrag({ + type: "BOX", + item: { + type: "BOX", + id: 5, + text: "dropdown" + }, + collect: (monitor) => ({ + isDragDropdown: !!monitor.isDragging() + }) + }); + const [{ isDragCheck }, checkbox] = useDrag({ + type: "BOX", + item: { + type: "BOX", + id: 6, + text: "checkbox" + }, + collect: (monitor) => ({ + isDragCheck: !!monitor.isDragging() + }) + }); + const [{ isDragText }, text] = useDrag({ + type: "BOX", + item: { + type: "BOX", + id: 2, + text: "text" + }, + collect: (monitor) => ({ + isDragText: !!monitor.isDragging() + }) + }); + const signStyle = pdfUrl ? "disableSign" : "signatureBtn"; const isMobile = window.innerWidth < 767; + const scrollContainerRef = useRef(null); + const [widget, setWidget] = useState([]); const color = [ "#93a3db", @@ -57,13 +95,31 @@ function FieldsComponent({ "#66ccff", "#ffffcc" ]; - const handleModal = () => { setIsSignersModal(!isSignersModal); }; + + useEffect(() => { + const widgetRef = [dragSignature, dragStamp, dropdown, checkbox, text]; + const getWidgetArray = widgets; + const newUpdateSigner = getWidgetArray.map((obj, ind) => { + return { ...obj, ref: widgetRef[ind] }; + }); + setWidget(newUpdateSigner); + }, []); + + const filterWidgets = widget.filter((data) => data.type !== "dropdown"); + const updateWidgets = isSignYourself ? filterWidgets : widget; + + const handleScroll = (scrollOffset) => { + if (scrollContainerRef.current) { + scrollContainerRef.current.scrollLeft += scrollOffset; + } + }; + return ( <> - {isMobile && isSignYourself ? ( + {isMobile ? ( !isMailSend && (
Add role
)} -
+ */} +
+ handleScroll(-100)} + className="fa-solid fa-circle-chevron-left" + > +
+ {/* {updateWidgets.map((item, ind) => { + return ( +
{ + item.ref(element); + if (element) { + signRef.current = element; + } + }} + className={signStyle} + onMouseMove={handleDivClick} + onMouseDown={handleMouseLeave} + style={{ + opacity: isDragSign ? 0.5 : 1, + boxShadow: + "0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18)", + marginLeft: "5px" + }} + > +
+ + + {item.type} + +
+
+ +
+
+ ); + })} */} + +
+ handleScroll(100)} + className="fa-solid fa-circle-chevron-right" + >
) @@ -237,7 +394,7 @@ function FieldsComponent({
- {pdfUrl ? ( + {/* {pdfUrl ? ( <>
{ dragStamp(element); dragRef.current = element; if (isDragStamp) { - // setIsStamp(true); + } }} className={!pdfUrl ? signStyle : "disableSign"} @@ -364,7 +520,71 @@ function FieldsComponent({ />
- )} + )} */} + {/* {updateWidgets.map((item, ind) => { + return ( +
{ + item.ref(element); + if (element) { + signRef.current = element; + } + }} + className={signStyle} + onMouseMove={handleDivClick} + onMouseDown={handleMouseLeave} + style={{ + opacity: isDragSign ? 0.5 : 1, + boxShadow: + "0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.18)" + }} + > +
+ + + {item.type} + +
+
+ +
+
+ ); + })} */} + )} diff --git a/microfrontends/SignDocuments/src/Component/component/renderPdf.js b/microfrontends/SignDocuments/src/Component/component/renderPdf.js index 0172cea2e..1a47969e9 100644 --- a/microfrontends/SignDocuments/src/Component/component/renderPdf.js +++ b/microfrontends/SignDocuments/src/Component/component/renderPdf.js @@ -6,11 +6,13 @@ import { Document, Page, pdfjs } from "react-pdf"; import BorderResize from "./borderResize"; import { addZIndex, + defaultWidthHeight, handleImageResize, handleSignYourselfImageResize } from "../../utils/Utils"; import EmailToast from "./emailToast"; import PlaceholderBorder from "./placeholderBorder"; +import Placeholder from "../WidgetComponent/placeholder"; pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`; @@ -35,6 +37,7 @@ function RenderPdf({ pdfUrl, numPages, pageDetails, + pdfRequest, setCurrentSigner, signerObjectId, @@ -52,7 +55,8 @@ function RenderPdf({ setUniqueId, signersdata, setIsPageCopy, - setSignerObjId + setSignerObjId, + setShowDropdown }) { const isMobile = window.innerWidth < 767; const newWidth = containerWH.width; @@ -62,7 +66,7 @@ function RenderPdf({ // handle signature block width and height according to screen const posWidth = (pos, signYourself) => { - const defaultWidth = 150; + const defaultWidth = defaultWidthHeight(pos.type).width; const posWidth = pos.Width ? pos.Width : defaultWidth; let width; if (signYourself) { @@ -76,6 +80,7 @@ function RenderPdf({ return width; } else { width = (posWidth || defaultWidth) / scale; + return width; } } else { @@ -99,11 +104,14 @@ function RenderPdf({ } }; const posHeight = (pos, signYourself) => { + // console.log("signyourself",pos) let height; const posHeight = pos.Height; - const defaultHeight = 60; + const defaultHeight = defaultWidthHeight(pos.type).height; + if (signYourself) { height = posHeight ? posHeight : defaultHeight; + return height; } else { if (isMobile) { @@ -113,6 +121,7 @@ function RenderPdf({ return height; } else { height = (posHeight || defaultHeight) / scale; + return height; } } else { @@ -200,6 +209,26 @@ function RenderPdf({ if (data.signerObjId === signerObjectId) { setCurrentSigner(true); } + const handleAllUserName = () => { + pdfDetails[0].Signers.map((signerData, key) => { + return ( + signerData.objectId === data.signerObjId && ( +
+ {signerData.Name} +
+ ) + ); + }); + }; return ( checkSign.length === 0 && @@ -211,7 +240,7 @@ function RenderPdf({ return ( pos && ( - {signerData.Name} -
- {pos.isStamp ? "stamp" : "signature"} -
) ); }) )} -
+ */} +
) ); @@ -380,12 +422,13 @@ function RenderPdf({ justifyContent: "center" }} > - {pos.isStamp ? "stamp" : "signature"} + {pos.type} )} ); }; + const handleUserName = (signerId, Role) => { if (signerId) { const checkSign = signersdata.find((sign) => sign.objectId === signerId); @@ -418,6 +461,141 @@ function RenderPdf({ > {pdfLoadFail.status && + // recipient + // ? !pdfUrl && + // !isAlreadySign.mssg && + // xyPostion.length > 0 && + // xyPostion.map((data, ind) => { + // return ( + // + // {data.pageNumber === pageNumber && + // data.pos.map((pos) => { + // return ( + // pos && ( + // // { + // // handleSignYourselfImageResize( + // // ref, + // // pos.key, + // // xyPostion, + // // index, + // // setXyPostion + // // ); + // // }} + // // size={{ + // // width: posWidth(pos), + // // height: posHeight(pos) + // // }} + // // lockAspectRatio={ + // // pos.Width ? pos.Width / pos.Height : 2.5 + // // } + // // //if pos.isMobile false -- placeholder saved from desktop view then handle position in mobile view divide by scale + // // //else if pos.isMobile true -- placeholder saved from mobile or tablet view then handle position in desktop view divide by scale + // // default={{ + // // x: xPos(pos), + // // y: yPos(pos) + // // }} + // // onClick={() => { + // // setIsSignPad(true); + // // setSignKey(pos.key); + // // setIsStamp( + // // pos?.isStamp ? pos.isStamp : false + // // ); + // // }} + // // > + // // + // // {pos.SignUrl ? ( + // // no img { + // // setIsSignPad(true); + // // setSignKey(pos.key); + // // }} + // // src={pos.SignUrl} + // // style={{ + // // width: "100%", + // // height: "100%", + // // objectFit: "contain" + // // }} + // // /> + // // ) : ( + // //
+ // //
{pos.type}
+ + // // {handleUserName( + // // data.signerObjId, + // // data.Role + // // )} + // //
+ // // )} + // //
+ // + // ) + // ); + // })} + //
+ // ); + // }) + // : (pdfRequest ? signerPos.map((data, key) => { return ( @@ -589,7 +767,6 @@ function RenderPdf({ onTouchEnd={(e) => { e.stopPropagation(); handleDeleteSign(pos.key, data.Id); - // data.signerObjId }} onClick={(e) => { e.stopPropagation(); @@ -609,15 +786,11 @@ function RenderPdf({ marginTop: "0px" }} > - {pos.isStamp ? ( -
stamp
- ) : ( -
signature
- )} +
{pos.type}
{handleUserName( data.signerObjId, data.Role - )} + )}{" "} @@ -636,138 +809,162 @@ function RenderPdf({ data.pos.map((pos) => { return ( pos && ( - handleTabDrag(pos.key)} - onDragStop={handleStop} - onResize={( - e, - direction, - ref, - delta, - position - ) => { - handleSignYourselfImageResize( - ref, - pos.key, - xyPostion, - index, - setXyPostion - ); - }} - > - - -
{ - if (!isDragging && isMobile) { - setTimeout(() => { - e.stopPropagation(); - setIsSignPad(true); - setSignKey(pos.key); - setIsStamp(pos.isStamp); - }, 500); - } - }} - > - { - e.stopPropagation(); - setIsPageCopy(true); - setSignKey(pos.key); - }} - style={{ - color: "#188ae2" - }} - > - { - e.stopPropagation(); - if (data) { - handleDeleteSign( - pos.key, - data.signerObjId - ); - } else { - handleDeleteSign(pos.key); - setIsStamp(false); - } - }} - style={{ - color: "#188ae2" - }} - > + // handleTabDrag(pos.key)} + // onDragStop={handleStop} + // onResize={( + // e, + // direction, + // ref, + // delta, + // position + // ) => { + // handleSignYourselfImageResize( + // ref, + // pos.key, + // xyPostion, + // index, + // setXyPostion + // ); + // }} + // > + // + // + //
{ + // if (!isDragging && isMobile) { + // setTimeout(() => { + // e.stopPropagation(); + // setIsSignPad(true); + // setSignKey(pos.key); + // setIsStamp(pos.isStamp); + // }, 500); + // } + // }} + // > + // { + // e.stopPropagation(); + // setIsPageCopy(true); + // setSignKey(pos.key); + // }} + // style={{ + // color: "#188ae2" + // }} + // > + // { + // e.stopPropagation(); + // if (data) { + // handleDeleteSign( + // pos.key, + // data.signerObjId + // ); + // } else { + // handleDeleteSign(pos.key); + // setIsStamp(false); + // } + // }} + // style={{ + // color: "#188ae2" + // }} + // > - {pos.SignUrl ? ( -
- signimg -
- ) : ( -
- {pos.isStamp ? "stamp" : "signature"} -
- )} -
-
+ // {pos.SignUrl ? ( + //
+ // signimg + //
+ // ) : ( + //
+ // {pos.isStamp ? "stamp" : "signature"} + //
+ // )} + //
+ //
+ ) ); })} @@ -836,6 +1033,143 @@ function RenderPdf({ > {pdfLoadFail.status && + // recipient + // ? !pdfUrl && + // !isAlreadySign.mssg && + // xyPostion.length > 0 && + // xyPostion.map((data, ind) => { + // return ( + // + // {data.pageNumber === pageNumber && + // data.pos.map((pos) => { + // return ( + // pos && ( + // // { + // // handleSignYourselfImageResize( + // // ref, + // // pos.key, + // // xyPostion, + // // index, + // // setXyPostion + // // ); + // // }} + // // key={pos.key} + // // bounds="parent" + // // style={{ + // // cursor: "all-scroll", + // // borderColor: themeColor(), + // // borderStyle: "dashed", + // // borderWidth: "0.1px", + // // zIndex: "1", + // // background: data.blockColor + // // ? data.blockColor + // // : "#daebe0" + // // }} + // // className="signYourselfBlock" + // // size={{ + // // width: posWidth(pos), + // // height: posHeight(pos) + // // }} + // // lockAspectRatio={ + // // pos.Width ? pos.Width / pos.Height : 2.5 + // // } + // // default={{ + // // x: xPos(pos), + // // y: yPos(pos) + // // }} + // // onClick={() => { + // // setIsSignPad(true); + // // setSignKey(pos.key); + // // setIsStamp(pos?.isStamp ? pos.isStamp : false); + // // }} + // // > + // //
+ // // + // // {pos.SignUrl ? ( + // // no img { + // // setIsSignPad(true); + // // setSignKey(pos.key); + // // }} + // // src={pos.SignUrl} + // // style={{ + // // width: "100%", + // // height: "100%", + // // objectFit: "contain" + // // }} + // // /> + // // ) : ( + // //
+ // // {pos.isStamp ? ( + // //
stamp
+ // // ) : ( + // //
signature
+ // // )} + // // {handleUserName( + // // data.signerObjId, + // // data.Role + // // )} + // //
+ // // )} + // //
+ // //
+ + // + // ) + // ); + // })} + //
+ // ); + // }) + // : (pdfRequest ? signerPos.map((data, key) => { return ( @@ -854,161 +1188,198 @@ function RenderPdf({ {placeData.pageNumber === pageNumber && placeData.pos.map((pos) => { return ( - { - if (!isDragging) { - handleLinkUser(data.Id); - setUniqueId(data.Id); - } - const dataNewPlace = addZIndex( - signerPos, - pos.key, - setZIndex - ); - setSignerPos((prevState) => { - const newState = [...prevState]; - newState.splice( - 0, - signerPos.length, - ...dataNewPlace - ); - return newState; - }); - }} - key={pos.key} - enableResizing={{ - top: false, - right: false, - bottom: false, - left: false, - topRight: false, - bottomRight: true, - bottomLeft: false, - topLeft: false - }} - bounds="parent" - style={{ - cursor: "all-scroll", - background: data.blockColor, - zIndex: pos.zIndex - }} - className="signYourselfBlock" - onDrag={() => handleTabDrag(pos.key)} - size={{ - width: posWidth(pos), - height: posHeight(pos) - }} - lockAspectRatio={ - pos.Width - ? pos.Width / pos.Height - : 2.5 - } - onDragStop={(event, dragElement) => - handleStop( - event, - dragElement, - data.Id, - pos.key - ) - } - default={{ - x: xPos(pos), - y: yPos(pos) - }} - onResizeStart={() => { - setIsResize(true); - }} - onResizeStop={() => { - setIsResize && setIsResize(false); - }} - onResize={( - e, - direction, - ref, - delta, - position - ) => { - e.stopPropagation(); - handleImageResize( - ref, - pos.key, - data.Id, //data.signerObjId, - position, - signerPos, - pageNumber, - setSignerPos, - pdfOriginalWidth, - containerWH, - false - ); - }} - > - - -
- { - e.stopPropagation(); - handleLinkUser(data.Id); - setUniqueId(data.Id); - }} - style={{ - color: "#188ae2" - }} - > - { - e.stopPropagation(); - setIsPageCopy(true); - setSignKey(pos.key); - setUniqueId(data.Id); - setSignerObjId(data.signerObjId); - }} - style={{ - color: "#188ae2" - }} - > - { - e.stopPropagation(); - handleDeleteSign( - pos.key, - data.Id - ); - // data.signerObjId - }} - style={{ - color: "#188ae2" - }} - > + // { + // if (!isDragging) { + // handleLinkUser(data.Id); + // setUniqueId(data.Id); + // } + // const dataNewPlace = addZIndex( + // signerPos, + // pos.key, + // setZIndex + // ); + // setSignerPos((prevState) => { + // const newState = [...prevState]; + // newState.splice( + // 0, + // signerPos.length, + // ...dataNewPlace + // ); + // return newState; + // }); + // }} + // key={pos.key} + // enableResizing={{ + // top: false, + // right: false, + // bottom: false, + // left: false, + // topRight: false, + // bottomRight: true, + // bottomLeft: false, + // topLeft: false + // }} + // bounds="parent" + // style={{ + // cursor: "all-scroll", + // background: data.blockColor, + // zIndex: pos.zIndex + // }} + // className="signYourselfBlock" + // onDrag={() => handleTabDrag(pos.key)} + // size={{ + // width: posWidth(pos), + // height: posHeight(pos) + // }} + // lockAspectRatio={ + // pos.Width + // ? pos.Width / pos.Height + // : 2.5 + // } + // onDragStop={ + // (event, dragElement) => + // handleStop( + // event, + // dragElement, + // data.Id, + // pos.key + // ) + // // data.signerObjId, + // } + // // default={{ + // // x: pos.xPosition, + // // y: pos.yPosition + // // }} + // default={{ + // x: xPos(pos), + // y: yPos(pos) + // }} + // onResizeStart={() => { + // setIsResize(true); + // }} + // onResizeStop={() => { + // setIsResize && setIsResize(false); + // }} + // onResize={( + // e, + // direction, + // ref, + // delta, + // position + // ) => { + // e.stopPropagation(); + // handleImageResize( + // ref, + // pos.key, + // data.Id, //data.signerObjId, + // position, + // signerPos, + // pageNumber, + // setSignerPos, + // pdfOriginalWidth, + // containerWH, + // false + // ); + // }} + // > + // + // + //
+ // { + // e.stopPropagation(); + // handleLinkUser(data.Id); + // setUniqueId(data.Id); + // }} + // style={{ + // color: "#188ae2" + // }} + // > + // { + // e.stopPropagation(); + // setIsPageCopy(true); + // setSignKey(pos.key); + // setUniqueId(data.Id); + // setSignerObjId( + // data.signerObjId + // ); + // }} + // style={{ + // color: "#188ae2" + // }} + // > + // { + // e.stopPropagation(); + // handleDeleteSign( + // pos.key, + // data.Id + // ); + // // data.signerObjId + // }} + // style={{ + // color: "#188ae2" + // }} + // > -
- {pos.isStamp ? ( -
stamp
- ) : ( -
signature
- )} - {handleUserName( - data.signerObjId, - data.Role - )} -
-
-
+ //
+ // {pos.isStamp ? ( + //
stamp
+ // ) : ( + //
signature
+ // )} + // {handleUserName( + // data.signerObjId, + // data.Role + // )} + //
+ //
+ //
+ ); })} @@ -1024,78 +1395,103 @@ function RenderPdf({ data.pos.map((pos) => { return ( pos && ( - 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 + // }} + // onClick={() => { + // if (!isDragging) { + // setIsSignPad(true); + // setSignKey(pos.key); + // setIsStamp(pos.isStamp); + // } + // }} + // onResize={( + // e, + // direction, + // ref, + // delta, + // position + // ) => { + // e.stopPropagation(); + // handleSignYourselfImageResize( + // ref, + // pos.key, + // xyPostion, + // index, + // setXyPostion + // ); + // }} + // > + // + // + // + // + 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 - }} - onClick={() => { - if (!isDragging) { - setIsSignPad(true); - setSignKey(pos.key); - setIsStamp(pos.isStamp); - } - }} - onResize={( - e, - direction, - ref, - delta, - position - ) => { - e.stopPropagation(); - handleSignYourselfImageResize( - ref, - pos.key, - xyPostion, - index, - setXyPostion - ); - }} - > - - - - + index={index} + xyPostion={xyPostion} + setXyPostion={setXyPostion} + pdfOriginalWidth={pdfOriginalWidth} + containerWH={containerWH} + setIsSignPad={setIsSignPad} + isShowBorder={true} + isSignYourself={true} + xPos={xPos} + yPos={yPos} + posWidth={posWidth} + posHeight={posHeight} + /> ) ); })} ); }))} + {/* this component for render pdf document is in middle of the component */} { diff --git a/microfrontends/SignDocuments/src/Component/component/signPad.js b/microfrontends/SignDocuments/src/Component/component/signPad.js index ff0d72caf..fb7f42f77 100644 --- a/microfrontends/SignDocuments/src/Component/component/signPad.js +++ b/microfrontends/SignDocuments/src/Component/component/signPad.js @@ -66,7 +66,7 @@ function SignPad({ setIsSignImg(""); } else if (isTab === "uploadImage") { - setImage(""); + setImage(""); } }; //function for set signature url @@ -388,7 +388,8 @@ function SignPad({ <>
diff --git a/microfrontends/SignDocuments/src/Component/placeHolderSign.js b/microfrontends/SignDocuments/src/Component/placeHolderSign.js index 5dd79e66b..450f46509 100644 --- a/microfrontends/SignDocuments/src/Component/placeHolderSign.js +++ b/microfrontends/SignDocuments/src/Component/placeHolderSign.js @@ -31,6 +31,7 @@ import LinkUserModal from "./component/LinkUserModal"; import Title from "./component/Title"; import TourContentWithBtn from "../premitives/TourContentWithBtn"; import ModalUi from "../premitives/ModalUi"; +import DropdownWidgetOption from "../Component/WidgetComponent/dropdownWidgetOption"; function PlaceHolderSign() { const navigate = useNavigate(); @@ -84,6 +85,8 @@ function PlaceHolderSign() { const [signerExistModal, setSignerExistModal] = useState(false); const [isDontShow, setIsDontShow] = useState(false); const [isDragging, setIsDragging] = useState(false); + const [showDropdown, setShowDropdown] = useState(false); + const color = [ "#93a3db", "#e6c3db", @@ -111,7 +114,7 @@ function PlaceHolderSign() { item: { type: "BOX", id: 1, - text: "drag me" + text: "signature" }, collect: (monitor) => ({ isDragSign: !!monitor.isDragging() @@ -122,7 +125,13 @@ function PlaceHolderSign() { item: { type: "BOX", id: 2, - text: "drag me" + text: "stamp" + }, + type: "BOX", + item: { + type: "BOX", + id: 2, + text: "stamp" }, collect: (monitor) => ({ isDragStamp: !!monitor.isDragging() @@ -132,9 +141,8 @@ function PlaceHolderSign() { const [{ isDragSignatureSS }, dragSignatureSS] = useDrag({ type: "BOX", item: { - type: "BOX", id: 3, - text: "drag me" + text: "signature" }, collect: (monitor) => ({ isDragSignatureSS: !!monitor.isDragging() @@ -144,9 +152,8 @@ function PlaceHolderSign() { const [{ isDragStampSS }, dragStampSS] = useDrag({ type: "BOX", item: { - type: "BOX", id: 4, - text: "drag me" + text: "stamp" }, collect: (monitor) => ({ isDragStampSS: !!monitor.isDragging() @@ -339,6 +346,7 @@ function PlaceHolderSign() { let placeHolder; if (item === "onclick") { const dropObj = { + //onclick put placeholder center on pdf xPosition: window.innerWidth / 2 - 100, yPosition: window.innerHeight / 2 - 60, isStamp: monitor, @@ -347,7 +355,8 @@ function PlaceHolderSign() { scale: scale, isMobile: isMobile, yBottom: window.innerHeight / 2 - 60, - zIndex: posZIndex + zIndex: posZIndex, + type: item.text }; dropData.push(dropObj); placeHolder = { @@ -375,7 +384,8 @@ function PlaceHolderSign() { yBottom: ybottom, scale: scale, isMobile: isMobile, - zIndex: posZIndex + zIndex: posZIndex, + type: item.text }; dropData.push(dropObj); @@ -642,7 +652,6 @@ function PlaceHolderSign() { setIsSendAlert(alert); } }; - const sendEmailToSigners = async () => { const loadObj = { isLoad: true, @@ -682,7 +691,7 @@ function PlaceHolderSign() { const hostUrl = window.location.origin + "/loadmf/signmicroapp"; let signPdf = `${hostUrl}/login/${pdfDetails?.[0].objectId}/${signerMail[i].Email}/${objectId}/${serverParams}`; - const openSignUrl = "https://www.opensignlabs.com/contact-us"; + const openSignUrl = "https://www.opensignlabs.com/"; const orgName = pdfDetails[0]?.ExtUserPtr.Company ? pdfDetails[0].ExtUserPtr.Company : ""; @@ -787,12 +796,11 @@ function PlaceHolderSign() { } } }; - const handleDontShow = (isChecked) => { setIsDontShow(isChecked); }; - //here you can add your messages in content and selector is key of particular steps + const tourConfig = [ { selector: '[data-tut="reactourFirst"]', @@ -851,6 +859,55 @@ function PlaceHolderSign() { } ]; + const handleSaveDropdownOptions = (dropdownName, dropdownOptions) => { + //get current signers placeholder position data + const currentSigner = signerPos.filter( + (data) => data.signerObjId === signerObjId + ); + //get current pagenumber placeholder index + const getIndex = currentSigner[0].placeHolder.findIndex((object) => { + return object.pageNumber === pageNumber; + }); + + const placeholderPosition = currentSigner[0].placeHolder; + //function of save signature image and get updated position with signature image url + + let getXYdata = placeholderPosition[getIndex].pos; + const updateXYData = getXYdata.map((position) => { + if (position.key === signKey) { + return { + ...position, + widgetName: dropdownName, + widgetOption: dropdownOptions + }; + } + return position; + }); + + const getUpdatePosition = placeholderPosition.map((obj, ind) => { + if (ind === getIndex) { + return { ...obj, pos: updateXYData }; + } + return obj; + }); + + const updateSignerData = currentSigner.map((obj, ind) => { + if (obj.signerObjId === signerObjId) { + return { ...obj, placeHolder: getUpdatePosition }; + } + return obj; + }); + + const index = signerPos.findIndex( + (data) => data.signerObjId === signerObjId + ); + setSignerPos((prevState) => { + const newState = [...prevState]; + newState.splice(index, 1, ...updateSignerData); + return newState; + }); + }; + //function for update TourStatus const closeTour = async () => { setPlaceholderTour(false); @@ -925,7 +982,6 @@ function PlaceHolderSign() { } return { ...x }; }); - // console.log("updateSigner ", updateSigner); if (updateSigner && updateSigner.length > 0) { const currEmail = pdfDetails[0].ExtUserPtr.Email; const getCurrentUserDeatils = updateSigner.filter( @@ -935,6 +991,7 @@ function PlaceHolderSign() { setCurrentId(getCurrentUserDeatils[0].Email); } } + // console.log("updateSigner ", updateSigner); setSignersData(updateSigner); const index = signersdata.findIndex((x) => x.Id === uniqueId); @@ -1027,7 +1084,7 @@ function PlaceHolderSign() { {isSendAlert.mssg === "confirm" && (
@@ -1221,7 +1284,7 @@ function PlaceHolderSign() { dragStamp={dragStamp} dragRef={dragRef} isDragStamp={isDragStamp} - isSignYourself={true} + isSignYourself={false} isDragSignatureSS={isDragSignatureSS} dragSignatureSS={dragSignatureSS} dragStampSS={dragStampSS} @@ -1309,7 +1372,6 @@ function PlaceHolderSign() {
- { + const isSigners = xyPostion.some((data) => data.signerPtr); + console.log("isSigner", isSigners); + if (isSigners) { + const filterSignerPos = xyPostion.filter( + (data) => data.signerObjId === signerObjId + ); + + const getPlaceHolder = filterSignerPos[0].placeHolder; + const getPageNumer = getPlaceHolder.filter( + (data) => data.pageNumber === index + ); + if (getPageNumer.length > 0) { + const getXYdata = getPageNumer[0].pos; + const getPosData = getXYdata; + const addSignPos = getPosData.map((url, ind) => { + if (url.key === signKey) { + return { + ...url, + widgetValue: value + }; + } + return url; + }); + + const newUpdateSignPos = getPlaceHolder.map((obj, ind) => { + if (obj.pageNumber === index) { + return { ...obj, pos: addSignPos }; + } + return obj; + }); + const newUpdateSigner = xyPostion.map((obj, ind) => { + if (obj.Id === signerObjId) { + return { ...obj, placeHolder: newUpdateSignPos }; + } + return obj; + }); + + setXyPostion(newUpdateSigner); + } + } else { + let getXYdata = xyPostion[index].pos; + + const updatePosition = getXYdata.map((positionData, ind) => { + if (positionData.key === signKey) { + return { + ...positionData, + widgetValue: value + }; + } + return positionData; + }); + + const updatePlaceholder = xyPostion.map((obj, ind) => { + if (ind === index) { + return { ...obj, pos: updatePosition }; + } + return obj; + }); + setXyPostion(updatePlaceholder); + } +}; + +export const widgets = [ + { + type: "signature", + icon: "fa-solid fa-signature", + iconSize: "16px" + }, + { + type: "stamp", + icon: "fa-solid fa-stamp", + iconSize: "19px" + }, + { + type: "dropdown", + icon: "fa-solid fa-circle-chevron-down", + iconSize: "19px" + }, + { + type: "checkbox", + icon: "fa-solid fa-square-check", + iconSize: "21px" + }, + { + type: "text", + icon: "fa-solid fa-font", + iconSize: "21px" + } +]; + +export const getWidgetType = (item) => { + return ( + <> +
+ + + {item.type} + +
+
+ +
+ + ); +}; + +export const defaultWidthHeight = (type) => { + let obj; + switch (type) { + case "signature": + obj = { + width: 150, + height: 60 + }; + return obj; + + case "stamp": + obj = { + width: 150, + height: 60 + }; + return obj; + case "checkbox": + obj = { + width: 15, + height: 15 + }; + return obj; + case "text": + obj = { + width: 150, + height: 25 + }; + return obj; + case "dropdown": + obj = { + width: 120, + height: 22 + }; + return obj; + default: + obj = { + width: 150, + height: 60 + }; + return obj; + } +}; + export const resizeBorderExtraWidth = () => { return 20; }; @@ -400,7 +584,7 @@ export function urlValidator(url) { export const placeholderWidth = (pos, scale, signyourself) => { let width; - const defaultWidth = 150; + const defaultWidth = defaultWidthHeight(pos.type).width; const posWidth = pos.Width ? pos.Width : defaultWidth; if (signyourself) { @@ -443,12 +627,12 @@ export const placeholderWidth = (pos, scale, signyourself) => { export const placeholderHeight = (pos, scale, signyourself) => { let height; const posHeight = pos.Height; - const defaultHeight = 60; + const defaultHeight = defaultWidthHeight(pos.type).height; if (signyourself) { if (isMobile) { - return posHeight * scale; + return posHeight ? posHeight * scale : defaultHeight * scale; } else { - return posHeight; + return posHeight ? posHeight : defaultHeight; } } else { if (isMobile) { @@ -497,41 +681,42 @@ export const multiSignEmbed = async ( const pageNo = item.pageNumber; const imgUrlList = item.pos; const pages = pdfDoc.getPages(); + const form = pdfDoc.getForm(); 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"; + let signUrl = url.SignUrl && url.SignUrl; + if (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(); } - const res = await fetch(signUrl); - return res.arrayBuffer(); }) ); - images.forEach(async (imgData, id) => { + + imgUrlList.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); + if (imgData.type === "signature" || imgData.type === "stamp") { + if ( + (imgData.ImageType && imgData.ImageType === "image/png") || + imgData.ImageType === "image/jpeg" + ) { + img = await pdfDoc.embedJpg(images[id]); + } else { + img = await pdfDoc.embedPng(images[id]); + } } - - const scaleWidth = placeholderWidth(imgUrlList[id], scale, signyourself); - const scaleHeight = placeholderHeight( - imgUrlList[id], - scale, - signyourself - ); + let scaleWidth, scaleHeight; + scaleWidth = placeholderWidth(imgData, scale, signyourself); + scaleHeight = placeholderHeight(imgData, scale, signyourself); const xPos = (pos) => { const resizePos = pos.xPosition; @@ -565,7 +750,7 @@ export const multiSignEmbed = async ( }; const yPos = (pos) => { - const resizePos = imgUrlList[id].yPosition; + const resizePos = pos.yPosition; if (signyourself) { if (isMobile) { return page.getHeight() - resizePos * scale - scaleHeight; @@ -603,13 +788,48 @@ export const multiSignEmbed = async ( } } }; - - page.drawImage(img, { - x: xPos(imgUrlList[id]), - y: yPos(imgUrlList[id]), - width: scaleWidth, - height: scaleHeight - }); + const checkboxId = "checkbox_" + id; + if (imgData.type === "checkbox") { + const checkBox = form.createCheckBox(checkboxId); + + checkBox.addToPage(page, { + x: xPos(imgData), + y: yPos(imgData), + width: scaleWidth, + height: scaleHeight + }); + checkBox.check(); + checkBox.enableReadOnly(); + } else if (imgData.type === "text") { + const font = await pdfDoc.embedFont("Helvetica"); + const fontSize = 12; + const textContent = imgData.widgetValue; + page.drawText(textContent, { + x: xPos(imgData), + y: yPos(imgData), + size: fontSize, + font, + color: rgb(0, 0, 0) + }); + } else if (imgData.type === "dropdown") { + const dropdown = form.createDropdown(checkboxId); + dropdown.addOptions(imgData.widgetOption); + dropdown.select(imgData.widgetValue); + dropdown.addToPage(page, { + x: xPos(imgData), + y: yPos(imgData), + width: scaleWidth, + height: scaleHeight + }); + dropdown.disableEditing(); + } else { + page.drawImage(img, { + x: xPos(imgData), + y: yPos(imgData), + width: scaleWidth, + height: scaleHeight + }); + } }); } @@ -646,13 +866,10 @@ export const pdfNewWidthFun = (divRef) => { export const handleImageResize = ( ref, key, - signerId, - position, signerPos, - pageNumber, setSignerPos, - pdfOriginalWidth, - containerWH, + pageNumber, + signerId, showResize ) => { // const filterSignerPos = signerPos.filter( @@ -752,8 +969,8 @@ export const handleSignYourselfImageResize = ( ref, key, xyPostion, - index, - setXyPostion + setXyPostion, + index ) => { // const updateFilter = xyPostion[index].pos.filter( // (data) => data.key === key && data.Width && data.Height From f5d11f9ba6a6f2be14ecf0aa930136ed8a0cf678 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Mon, 15 Jan 2024 19:05:46 +0530 Subject: [PATCH 02/58] feat:implement new widgets- initial signature,name,company,job title & date in sign-yourself flow --- .../src/microappComponent/DragElement.js | 146 ++++++++++++------ apps/OpenSign/src/microappComponent/sign3.png | Bin 804 -> 0 bytes .../OpenSign/src/microappComponent/stamp2.png | Bin 561 -> 0 bytes .../{IconColor.js => themeColor.js} | 0 4 files changed, 100 insertions(+), 46 deletions(-) delete mode 100644 apps/OpenSign/src/microappComponent/sign3.png delete mode 100644 apps/OpenSign/src/microappComponent/stamp2.png rename apps/OpenSign/src/microappComponent/{IconColor.js => themeColor.js} (100%) diff --git a/apps/OpenSign/src/microappComponent/DragElement.js b/apps/OpenSign/src/microappComponent/DragElement.js index 2c8b5cb9d..912af9c13 100644 --- a/apps/OpenSign/src/microappComponent/DragElement.js +++ b/apps/OpenSign/src/microappComponent/DragElement.js @@ -1,56 +1,110 @@ import React from "react"; -import stamp from "./stamp2.png"; -import sign from "./sign3.png"; -import { themeColor } from "./IconColor.js"; +import { themeColor } from "./themeColor"; -function DragElement({ id }) { - const selectedId = id; +function DragElement(item) { + const getWidgets = [ + { + type: "signature", + icon: "fa-solid fa-pen-nib", + iconSize: "20px" + }, + { + type: "stamp", + icon: "fa-solid fa-stamp", + iconSize: "19px" + }, + { + type: "dropdown", + icon: "fa-solid fa-circle-chevron-down", + iconSize: "19px" + }, + { + type: "checkbox", + icon: "fa-solid fa-square-check", + iconSize: "22px" + }, + { + type: "text", + icon: "fa-solid fa-font", + iconSize: "21px" + }, + { + type: "initials", + icon: "fa-solid fa-signature", + iconSize: "15px" + }, + { + type: "name", + icon: "fa-solid fa-user", + iconSize: "21px" + }, + { + type: "company", + icon: "fa-solid fa-building", + iconSize: "24px" + }, + { + type: "job title", + icon: "fa-solid fa-address-card", + iconSize: "16px" + }, + { + type: "date", + icon: "fa-solid fa-calendar-days", + iconSize: "19px" + } + ]; + + const filterWidgetPreview = getWidgets.filter( + (data) => data.type === item?.text + ); return ( -
- {selectedId === 3 ? ( -
- sign img - - Signature - -
- ) : ( -
+
+ + - stamp img - Stamp -
- )} + {filterWidgetPreview[0].type} + +
+
+ +
); } diff --git a/apps/OpenSign/src/microappComponent/sign3.png b/apps/OpenSign/src/microappComponent/sign3.png deleted file mode 100644 index 4467b46cb8f1d26ec24f9e5b85c4c46ab958c652..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 804 zcmV+<1Ka$GP)x zd+zi6{^$L8-VbBiYOAd|5wHqmAJ_p@ZlU%$Dj!k#j>;G+lc-!Yc@eMzY(FXwQTa;A z((t45J8NzO#oeeKMCETJ=m6epflC>Jvl+ER_1-ROU!igx>`9O=C~N`N0-c$Gdjfj` zm5D0QULQXXg>ArmlShF)8-f;8?s(89?*iFh32)y+VXJ8c0n1Psb>N=?OH8W>>~W{t zeDVyLRub-vgFR+iO{jbc46wc_IVo&M?PFAamg|On2lgn?5kHt0ATY2f6=FwVyK5Fl zmD{mRpfchZ*l1D|*dBj+u2;#i{qcgTed_#qAXE5~KMTH%8@SJD!ZBcVX7DASVIpR5 z7N9ch1h}6We96!MBS8}Bs_cidHxu}h--R9}OQ!O`c?-i{%QPQeCKIo{fHkO$I|I76 z$?yX9aMGO9iO)Gr`J~D4-Lrx(CufrrbR=Ps$_CyOu-NU7CZ@c#6e^kt{LFST2>#h5 zP-GK2$MAk~l^f0&7>o$q6JEtOG@)t0Q{07$b!x$$Nbu#Yr$#oRslc&tQ9V3Gb=mP^-pn43&Gig!hEn zm(C2-XF>wzRhY~ZyeF`yomuEZ`1BcyJ97)~30PjSkx{v7YV8s720tyZr$RtiW`0xq zrUCpI$U&2(fDZpuEPxsh49Kr4(4(l_Ew4l~zLg0buiTuvX}mo1y~+ht{`f87-Aq#4 ik?0Jwt+v|wzx5AM4tpcYAmm8^0000c=YJiqbEszL82la1Aak%As`r| zr~HD1=qUufzx;G&Q!Rgs;tYVo51q;j0)SK$=>Y1Go2Id@K z1n~hXd#D_v^7Aax=e_(LjDlxC?xFIDHuBF<`3Q11cmr5KPb9uI6p05FMfUAPh!5*6zj57AgykypMCCiMWG0ejR323j*))|% z09Q~M&mi#`xEwqHvNrwPkhS0mR9;T8QoRb^0Iua*+VUaw3%DLUg33-0k)7ZbXjaPS zMsq881-M!+V%#^nC>06bVGwZ!^HPxkOMpwMJA>R#J6JTnM&+cS8Gc3MQEs5bb!cw> zx93{qr|iFP Date: Mon, 15 Jan 2024 19:09:18 +0530 Subject: [PATCH 03/58] feat:implement new widgets- initial signature,name,company,job title & date in sign-yourself flow --- .../src/Component/SignYourselfPdf.js | 108 +++++++++---- .../src/Component/TemplatePlaceholder.js | 8 +- .../Component/WidgetComponent/allWidgets.js | 48 +----- .../Component/WidgetComponent/placeholder.js | 24 ++- .../WidgetComponent/placeholderType.js | 114 +++++++++++--- .../src/Component/component/DragElement.js | 59 +------ .../Component/component/fieldsComponent.js | 89 +++++++++-- .../src/Component/component/renderPdf.js | 7 +- .../src/Component/placeHolderSign.js | 6 - .../SignDocuments/src/assests/sign3.png | Bin 804 -> 0 bytes .../SignDocuments/src/assests/stamp2.png | Bin 561 -> 0 bytes .../SignDocuments/src/css/signature.css | 2 +- .../SignDocuments/src/utils/Utils.js | 146 +++++++++++++----- 13 files changed, 398 insertions(+), 213 deletions(-) delete mode 100644 microfrontends/SignDocuments/src/assests/sign3.png delete mode 100644 microfrontends/SignDocuments/src/assests/stamp2.png diff --git a/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js b/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js index 5e4f05de6..c18be304f 100644 --- a/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js +++ b/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js @@ -1,8 +1,6 @@ import React, { useState, useRef, useEffect } from "react"; import { PDFDocument } from "pdf-lib"; import "../css/./signature.css"; -import sign from "../assests/sign3.png"; -import stamp from "../assests/stamp2.png"; import { themeColor } from "../utils/ThemeColor/backColor"; import axios from "axios"; import Loader from "./component/loader"; @@ -87,6 +85,7 @@ function SignYourSelf() { }); const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" }); const [isDontShow, setIsDontShow] = useState(false); + const [initial, setInitial] = useState(""); const divRef = useRef(null); const nodeRef = useRef(null); const [{ isOver }, drop] = useDrop({ @@ -171,17 +170,17 @@ function SignYourSelf() { const jsonSender = JSON.parse(senderUser); useEffect(() => { - // localStorage.setItem("accesstoken", "r:d70a32032557e982aab7aec1cae668fc"); - // localStorage.setItem( - // "baseUrl", - // "https://staging-app.opensignlabs.com/api/app/" - // ); - // localStorage.setItem("parseAppId", "opensignstgn"); - // localStorage.setItem( - // "Parse/opensignstgn/currentUser", - // '{"name":"raktima","email":"raktimachaurasiya@gmail.com","phone":"9876567876","username":"raktimachaurasiya@gmail.com","createdAt":"2024-01-03T05:48:49.407Z","sessionToken":"r:d70a32032557e982aab7aec1cae668fc","updatedAt":"2024-01-03T05:48:49.407Z","emailVerified":false,"ACL":{"YHwDtLNto7":{"read":true,"write":true}},"__type":"Object","className":"_User","objectId":"YHwDtLNto7"}' - // ); - // localStorage.setItem("_appName", "contracts"); + localStorage.setItem("accesstoken", "r:17de3495dd207dc88677da7f9f9e4d6b"); + localStorage.setItem( + "baseUrl", + "https://staging-app.opensignlabs.com/api/app/" + ); + localStorage.setItem("parseAppId", "opensignstgn"); + localStorage.setItem( + "Parse/opensignstgn/currentUser", + '{"name":"raktima","email":"raktimachaurasiya@gmail.com","phone":"5645676534","username":"raktimachaurasiya@gmail.com","emailVerified":false,"createdAt":"2024-01-10T14:40:59.326Z","updatedAt":"2024-01-10T14:40:59.326Z","ACL":{"9MUdPyX2ae":{"read":true,"write":true}},"sessionToken":"r:17de3495dd207dc88677da7f9f9e4d6b","__type":"Object","className":"_User","objectId":"9MUdPyX2ae"}' + ); + localStorage.setItem("_appName", "contracts"); if (documentId) { getDocumentDetails(true); } @@ -255,9 +254,9 @@ function SignYourSelf() { .then((Listdata) => { const json = Listdata.data; const res = json.results; - if (res[0] && res.length > 0) { setDefaultSignImg(res[0].ImageURL); + setInitial(res[0]?.Initials); } }) .catch((err) => { @@ -322,6 +321,28 @@ function SignYourSelf() { } }; + //calculate width and height + const calculateWidthHeight = (type) => { + const intialText = + type === "name" + ? pdfDetails[0].ExtUserPtr.Name + : type === "company" + ? pdfDetails[0].ExtUserPtr.Company + : type === "job title" && pdfDetails[0].ExtUserPtr.JobTitle; + const span = document.createElement("span"); + span.textContent = intialText; + span.style.font = `14px`; // here put your text size and font family + span.style.display = "hidden"; + document.body.appendChild(span); + const width = span.offsetWidth; + const height = span.offsetHeight; + + document.body.removeChild(span); + return { + getWidth: width, + getHeight: height + }; + }; //function for setting position after drop signature button over pdf const addPositionOfSignature = (item, monitor) => { const key = Math.floor(1000 + Math.random() * 9000); @@ -330,6 +351,7 @@ function SignYourSelf() { let filterDropPos = xyPostion.filter( (data) => data.pageNumber === pageNumber ); + if (item === "onclick") { dropObj = { xPosition: window.innerWidth / 2 - 100, @@ -338,7 +360,8 @@ function SignYourSelf() { key: key, isStamp: monitor, type: item.text, - yBottom: window.innerHeight / 2 - 60 + yBottom: window.innerHeight / 2 - 60, + SignUrl: item.text === "initials" && initial }; dropData.push(dropObj); @@ -368,7 +391,28 @@ function SignYourSelf() { firstXPos: signBtnPosition[0] && signBtnPosition[0].xPos, firstYPos: signBtnPosition[0] && signBtnPosition[0].yPos, yBottom: ybottom, - type: item.text + type: item.text, + SignUrl: item.text === "initials" && initial, + widgetValue: + item.text === "name" + ? pdfDetails[0].ExtUserPtr.Name + : item.text === "company" + ? pdfDetails[0].ExtUserPtr.Company + : item.text === "job title" + ? pdfDetails[0].ExtUserPtr.JobTitle + : "", + Width: + item.text === "name" || + item.text === "company" || + item.text === "job title" + ? calculateWidthHeight(item.text).getWidth + : "", + Height: + item.text === "company" || + item.text === "name" || + item.text === "job title" + ? calculateWidthHeight(item.text).getHeight + : "" }; dropData.push(dropObj); @@ -468,7 +512,7 @@ function SignYourSelf() { containerWH ); - console.log("pdf", pdfBytes); + // console.log("pdf", pdfBytes); //function for call to embed signature in pdf and get digital signature pdf signPdfFun(pdfBytes, documentId); @@ -514,7 +558,7 @@ function SignYourSelf() { }; //function for set and update x and y postion after drag and drop signature tab - const handleStop = (event, dragElement) => { + const handleStop = (event, dragElement, type) => { if (isDragging && dragElement) { event.preventDefault(); const containerRect = document @@ -533,13 +577,24 @@ function SignYourSelf() { const getPosData = getXYdata; const addSign = getPosData.map((url, ind) => { if (url.key === dragKey) { - return { - ...url, - xPosition: dragElement.x, - yPosition: dragElement.y, - isDrag: true, - yBottom: ybottom - }; + if (type === "initials") { + return { + ...url, + xPosition: dragElement.x, + yPosition: dragElement.y, + isDrag: true, + yBottom: ybottom, + SignUrl: initial + }; + } else { + return { + ...url, + xPosition: dragElement.x, + yPosition: dragElement.y, + isDrag: true, + yBottom: ybottom + }; + } } return url; }); @@ -954,8 +1009,6 @@ function SignYourSelf() { ) : ( diff --git a/microfrontends/SignDocuments/src/Component/TemplatePlaceholder.js b/microfrontends/SignDocuments/src/Component/TemplatePlaceholder.js index 07762c8d7..f41b5d454 100644 --- a/microfrontends/SignDocuments/src/Component/TemplatePlaceholder.js +++ b/microfrontends/SignDocuments/src/Component/TemplatePlaceholder.js @@ -3,8 +3,6 @@ import RenderAllPdfPage from "./component/renderAllPdfPage"; import { useParams, useNavigate } from "react-router-dom"; import axios from "axios"; import "../css/./signature.css"; -import sign from "../assests/sign3.png"; -import stamp from "../assests/stamp2.png"; import { themeColor } from "../utils/ThemeColor/backColor"; import { DndProvider } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; @@ -637,7 +635,7 @@ const TemplatePlaceholder = () => { if (signerPos.length !== signersdata.length) { setIsSendAlert(true); } else { - handleSaveTemplate(); + // handleSaveTemplate(); } }; const handleSaveTemplate = async () => { @@ -1149,8 +1147,6 @@ const TemplatePlaceholder = () => { dataTut="reactourFirst" dataTut2="reactourSecond" pdfUrl={isMailSend} - sign={sign} - stamp={stamp} dragSignature={dragSignature} signRef={signRef} handleDivClick={handleDivClick} @@ -1206,8 +1202,6 @@ const TemplatePlaceholder = () => {
{ return (
- {/*
- - - {item.type} - -
-
- -
*/} - {getWidgetType(item)} + {item.ref && getWidgetType(item, props?.marginLeft)}
); }); diff --git a/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholder.js b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholder.js index adf770299..d60a66c28 100644 --- a/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholder.js +++ b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholder.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState } from "react"; import BorderResize from "../component/borderResize"; import PlaceholderBorder from "./placeholderBorder"; import { Rnd } from "react-rnd"; @@ -6,7 +6,13 @@ import { defaultWidthHeight } from "../../utils/Utils"; import PlaceholderType from "./placeholderType"; function Placeholder(props) { + const [isDraggingEnabled, setDraggingEnabled] = useState(true); + const handlePlaceholderClick = () => { + if (props.pos.type === "text") { + setDraggingEnabled(false); + } + if (!props.data && !props.isDragging) { if (props.pos.type) { if (props.pos.type === "signature" || props.pos.type === "stamp") { @@ -79,6 +85,11 @@ function Placeholder(props) { style={{ border: "1px solid #007bff", borderRadius: "2px", + textAlign: + props.pos.type !== "name" && + props.pos.type !== "company" && + props.pos.type !== "job title" && + "center", cursor: props.data && props.isNeedSign ? props.data?.signerObjId === props.signerObjId @@ -88,18 +99,23 @@ function Placeholder(props) { zIndex: "1", background: props.data ? props.data.blockColor : "rgb(203 233 237)" }} - onDrag={() => props.handleTabDrag && props.handleTabDrag(props.pos.key)} + onDrag={() => { + setDraggingEnabled(true); + props.handleTabDrag && props.handleTabDrag(props.pos.key); + }} size={{ width: props.posWidth(props.pos, props.isSignYourself), height: props.posHeight(props.pos, props.isSignYourself) }} onResizeStart={() => { + setDraggingEnabled(true); props.setIsResize && props.setIsResize(true); }} onResizeStop={() => { props.setIsResize && props.setIsResize(false); }} - disableDragging={props.isNeedSign || (props.isRecipient && true)} + disableDragging={!isDraggingEnabled} + // disableDragging={props.isNeedSign || (props.isRecipient && true)} onDragStop={(event, dragElement) => props.handleStop && props.handleStop(event, dragElement, props.signerObjId, props.pos.key) @@ -227,6 +243,8 @@ function Placeholder(props) { isPlaceholder={props.isPlaceholder} signerObjId={props.signerObjId} handleUserName={props.handleUserName} + setDraggingEnabled={setDraggingEnabled} + pdfDetails={props.pdfDetails} />
diff --git a/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderType.js b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderType.js index 6c8c401ef..1f102ba60 100644 --- a/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderType.js +++ b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderType.js @@ -4,20 +4,21 @@ import { onChangeInput } from "../../utils/Utils"; function PlaceholderType(props) { const [selectOption, setSelectOption] = useState(""); + const handleInputBlur = () => { + props.setDraggingEnabled(true); + }; switch (props.pos.type) { case "signature": return props.pos.SignUrl ? ( -
- signimg -
+ signimg ) : (
- signimg -
+ signimg ) : (
onChangeInput( e.target.checked, @@ -85,7 +86,9 @@ function PlaceholderType(props) { onChangeInput( e.target.value, @@ -132,7 +135,72 @@ function PlaceholderType(props) { {props.pos.widgetName ? props.pos.widgetName : props.pos.type}
); - + case "initials": + return ( + signimg + ); + case "name": + return ( +
+ {props.pos.widgetValue} +
+ ); + case "company": + return ( +
+
{props.pos.widgetValue}
+
+ ); + case "job title": + return ( +
+
{props.pos.widgetValue}
+
+ ); + case "date": + return ( + + onChangeInput( + e.target.value, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data.signerObjId, + false + ) + } + /> + ); default: return props.pos.SignUrl ? (
diff --git a/microfrontends/SignDocuments/src/Component/component/DragElement.js b/microfrontends/SignDocuments/src/Component/component/DragElement.js index 89568b3ca..978cc01a8 100644 --- a/microfrontends/SignDocuments/src/Component/component/DragElement.js +++ b/microfrontends/SignDocuments/src/Component/component/DragElement.js @@ -1,58 +1,13 @@ import React from "react"; -import stamp from "../../assests/stamp2.png"; -import sign from "../../assests/sign3.png"; -import { themeColor } from "../../utils/ThemeColor/backColor"; +import { getWidgetType, widgets } from "../../utils/Utils"; -function DragElement({ type, id }) { - const selectedId = id; - - return ( -
- {selectedId === 3 ? ( -
- sign img - - Signature - -
- ) : ( -
- stamp img - Stamp -
- )} -
+function DragElement(item) { + const getWidgets = widgets; + const filterWidgetPreview = getWidgets.filter( + (data) => data.type === item?.text ); + + return
{getWidgetType(filterWidgetPreview[0])}
; } export default DragElement; diff --git a/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js b/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js index bc2efa951..bb4f8621a 100644 --- a/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js +++ b/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js @@ -7,8 +7,6 @@ import { widgets } from "../../utils/Utils"; function FieldsComponent({ pdfUrl, - sign, - stamp, dragSignature, signRef, handleDivClick, @@ -39,7 +37,8 @@ function FieldsComponent({ signerPos, handleRoleChange, handleOnBlur, - title + title, + initial }) { const [isSignersModal, setIsSignersModal] = useState(false); @@ -69,14 +68,69 @@ function FieldsComponent({ type: "BOX", item: { type: "BOX", - id: 2, + id: 7, text: "text" }, collect: (monitor) => ({ isDragText: !!monitor.isDragging() }) }); - const signStyle = pdfUrl ? "disableSign" : "signatureBtn"; + const [{ isDragInitial }, initials] = useDrag({ + type: "BOX", + item: { + type: "BOX", + id: 8, + text: "initials" + }, + collect: (monitor) => ({ + isDragInitial: !!monitor.isDragging() + }) + }); + const [{ isDragName }, name] = useDrag({ + type: "BOX", + item: { + type: "BOX", + id: 9, + text: "name" + }, + collect: (monitor) => ({ + isDragName: !!monitor.isDragging() + }) + }); + const [{ isDragCompany }, company] = useDrag({ + type: "BOX", + item: { + type: "BOX", + id: 10, + text: "company" + }, + collect: (monitor) => ({ + isDragCompany: !!monitor.isDragging() + }) + }); + const [{ isDragJobtitle }, jobTitle] = useDrag({ + type: "BOX", + item: { + type: "BOX", + id: 11, + text: "job title" + }, + collect: (monitor) => ({ + isDragJobtitle: !!monitor.isDragging() + }) + }); + const [{ isDragDate }, date] = useDrag({ + type: "BOX", + item: { + type: "BOX", + id: 11, + text: "date" + }, + collect: (monitor) => ({ + isDragDate: !!monitor.isDragging() + }) + }); + const isMobile = window.innerWidth < 767; const scrollContainerRef = useRef(null); const [widget, setWidget] = useState([]); @@ -100,12 +154,27 @@ function FieldsComponent({ }; useEffect(() => { - const widgetRef = [dragSignature, dragStamp, dropdown, checkbox, text]; + const widgetRef = [ + dragSignature, + dragStamp, + dropdown, + checkbox, + text, + initials, + name, + company, + jobTitle, + date + ]; const getWidgetArray = widgets; const newUpdateSigner = getWidgetArray.map((obj, ind) => { return { ...obj, ref: widgetRef[ind] }; }); - setWidget(newUpdateSigner); + const removeInitial = newUpdateSigner.filter( + (widgetData) => widgetData.type !== "initials" + ); + + setWidget(initial ? newUpdateSigner : removeInitial); }, []); const filterWidgets = widget.filter((data) => data.type !== "dropdown"); @@ -294,7 +363,7 @@ function FieldsComponent({ color: "rgb(140 142 149)", position: "fixed", left: "1%", - bottom: "6%", + bottom: "3%", fontSize: "23px" }} onClick={() => handleScroll(-100)} @@ -372,8 +441,8 @@ function FieldsComponent({ style={{ color: "rgb(140 142 149)", position: "fixed", - left: "95%", - bottom: "6%", + left: "93%", + bottom: "3%", fontSize: "23px" }} onClick={() => handleScroll(100)} diff --git a/microfrontends/SignDocuments/src/Component/component/renderPdf.js b/microfrontends/SignDocuments/src/Component/component/renderPdf.js index 1a47969e9..78e0eed33 100644 --- a/microfrontends/SignDocuments/src/Component/component/renderPdf.js +++ b/microfrontends/SignDocuments/src/Component/component/renderPdf.js @@ -104,7 +104,6 @@ function RenderPdf({ } }; const posHeight = (pos, signYourself) => { - // console.log("signyourself",pos) let height; const posHeight = pos.Height; const defaultHeight = defaultWidthHeight(pos.type).height; @@ -964,6 +963,7 @@ function RenderPdf({ yPos={yPos} posWidth={posWidth} posHeight={posHeight} + pdfDetails={pdfDetails[0]} /> ) ); @@ -1468,7 +1468,9 @@ function RenderPdf({ handleDeleteSign={handleDeleteSign} setIsStamp={setIsStamp} handleTabDrag={handleTabDrag} - handleStop={handleStop} + handleStop={(event, dragElement) => + handleStop(event, dragElement, pos.type) + } handleSignYourselfImageResize={ handleSignYourselfImageResize } @@ -1484,6 +1486,7 @@ function RenderPdf({ yPos={yPos} posWidth={posWidth} posHeight={posHeight} + pdfDetails={pdfDetails[0]} /> ) ); diff --git a/microfrontends/SignDocuments/src/Component/placeHolderSign.js b/microfrontends/SignDocuments/src/Component/placeHolderSign.js index 450f46509..c1034ce06 100644 --- a/microfrontends/SignDocuments/src/Component/placeHolderSign.js +++ b/microfrontends/SignDocuments/src/Component/placeHolderSign.js @@ -1,8 +1,6 @@ import React, { useState, useRef, useEffect } from "react"; import axios from "axios"; import "../css/./signature.css"; -import sign from "../assests/sign3.png"; -import stamp from "../assests/stamp2.png"; import { themeColor } from "../utils/ThemeColor/backColor"; import { DndProvider } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; @@ -1273,8 +1271,6 @@ function PlaceHolderSign() { dataTut="reactourFirst" dataTut2="reactourSecond" pdfUrl={isMailSend} - sign={sign} - stamp={stamp} dragSignature={dragSignature} signRef={signRef} handleDivClick={handleDivClick} @@ -1321,8 +1317,6 @@ function PlaceHolderSign() {
x zd+zi6{^$L8-VbBiYOAd|5wHqmAJ_p@ZlU%$Dj!k#j>;G+lc-!Yc@eMzY(FXwQTa;A z((t45J8NzO#oeeKMCETJ=m6epflC>Jvl+ER_1-ROU!igx>`9O=C~N`N0-c$Gdjfj` zm5D0QULQXXg>ArmlShF)8-f;8?s(89?*iFh32)y+VXJ8c0n1Psb>N=?OH8W>>~W{t zeDVyLRub-vgFR+iO{jbc46wc_IVo&M?PFAamg|On2lgn?5kHt0ATY2f6=FwVyK5Fl zmD{mRpfchZ*l1D|*dBj+u2;#i{qcgTed_#qAXE5~KMTH%8@SJD!ZBcVX7DASVIpR5 z7N9ch1h}6We96!MBS8}Bs_cidHxu}h--R9}OQ!O`c?-i{%QPQeCKIo{fHkO$I|I76 z$?yX9aMGO9iO)Gr`J~D4-Lrx(CufrrbR=Ps$_CyOu-NU7CZ@c#6e^kt{LFST2>#h5 zP-GK2$MAk~l^f0&7>o$q6JEtOG@)t0Q{07$b!x$$Nbu#Yr$#oRslc&tQ9V3Gb=mP^-pn43&Gig!hEn zm(C2-XF>wzRhY~ZyeF`yomuEZ`1BcyJ97)~30PjSkx{v7YV8s720tyZr$RtiW`0xq zrUCpI$U&2(fDZpuEPxsh49Kr4(4(l_Ew4l~zLg0buiTuvX}mo1y~+ht{`f87-Aq#4 ik?0Jwt+v|wzx5AM4tpcYAmm8^0000c=YJiqbEszL82la1Aak%As`r| zr~HD1=qUufzx;G&Q!Rgs;tYVo51q;j0)SK$=>Y1Go2Id@K z1n~hXd#D_v^7Aax=e_(LjDlxC?xFIDHuBF<`3Q11cmr5KPb9uI6p05FMfUAPh!5*6zj57AgykypMCCiMWG0ejR323j*))|% z09Q~M&mi#`xEwqHvNrwPkhS0mR9;T8QoRb^0Iua*+VUaw3%DLUg33-0k)7ZbXjaPS zMsq881-M!+V%#^nC>06bVGwZ!^HPxkOMpwMJA>R#J6JTnM&+cS8Gc3MQEs5bb!cw> zx93{qr|iFP { const isSigners = xyPostion.some((data) => data.signerPtr); - console.log("isSigner", isSigners); + if (isSigners) { const filterSignerPos = xyPostion.filter( (data) => data.signerObjId === signerObjId @@ -76,8 +76,8 @@ export const onChangeInput = ( export const widgets = [ { type: "signature", - icon: "fa-solid fa-signature", - iconSize: "16px" + icon: "fa-solid fa-pen-nib", + iconSize: "20px" }, { type: "stamp", @@ -92,53 +92,88 @@ export const widgets = [ { type: "checkbox", icon: "fa-solid fa-square-check", - iconSize: "21px" + iconSize: "22px" }, { type: "text", icon: "fa-solid fa-font", iconSize: "21px" + }, + { + type: "initials", + icon: "fa-solid fa-signature", + iconSize: "15px" + }, + { + type: "name", + icon: "fa-solid fa-user", + iconSize: "21px" + }, + { + type: "company", + icon: "fa-solid fa-building", + iconSize: "24px" + }, + { + type: "job title", + icon: "fa-solid fa-address-card", + iconSize: "16px" + }, + { + type: "date", + icon: "fa-solid fa-calendar-days", + iconSize: "19px" } ]; -export const getWidgetType = (item) => { +export const getWidgetType = (item, marginLeft) => { return ( <>
- - - {item.type} - -
-
- + + + {item.type} + +
+
+ +
); @@ -178,6 +213,37 @@ export const defaultWidthHeight = (type) => { height: 22 }; return obj; + case "initials": + obj = { + width: 150, + height: 60 + }; + return obj; + case "name": + obj = { + width: 150, + height: 25 + }; + return obj; + + case "company": + obj = { + width: 150, + height: 25 + }; + return obj; + case "job title": + obj = { + width: 150, + height: 25 + }; + return obj; + case "date": + obj = { + width: 100, + height: 20 + }; + return obj; default: obj = { width: 150, @@ -704,7 +770,11 @@ export const multiSignEmbed = async ( imgUrlList.forEach(async (imgData, id) => { let img; - if (imgData.type === "signature" || imgData.type === "stamp") { + if ( + imgData.type === "signature" || + imgData.type === "stamp" || + imgData.type === "initials" + ) { if ( (imgData.ImageType && imgData.ImageType === "image/png") || imgData.ImageType === "image/jpeg" @@ -800,13 +870,19 @@ export const multiSignEmbed = async ( }); checkBox.check(); checkBox.enableReadOnly(); - } else if (imgData.type === "text") { + } else if ( + imgData.type === "text" || + imgData.type === "name" || + imgData.type === "company" || + imgData.type === "job title" || + imgData.type === "date" + ) { const font = await pdfDoc.embedFont("Helvetica"); const fontSize = 12; const textContent = imgData.widgetValue; page.drawText(textContent, { x: xPos(imgData), - y: yPos(imgData), + y: yPos(imgData) + 10, size: fontSize, font, color: rgb(0, 0, 0) From 221a49bb4a434467c5dd0fdb77892c7663246012 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Mon, 15 Jan 2024 19:36:48 +0530 Subject: [PATCH 04/58] remove hard coded local storage data --- .../src/Component/SignYourselfPdf.js | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js b/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js index c18be304f..0e69563c6 100644 --- a/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js +++ b/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js @@ -170,17 +170,17 @@ function SignYourSelf() { const jsonSender = JSON.parse(senderUser); useEffect(() => { - localStorage.setItem("accesstoken", "r:17de3495dd207dc88677da7f9f9e4d6b"); - localStorage.setItem( - "baseUrl", - "https://staging-app.opensignlabs.com/api/app/" - ); - localStorage.setItem("parseAppId", "opensignstgn"); - localStorage.setItem( - "Parse/opensignstgn/currentUser", - '{"name":"raktima","email":"raktimachaurasiya@gmail.com","phone":"5645676534","username":"raktimachaurasiya@gmail.com","emailVerified":false,"createdAt":"2024-01-10T14:40:59.326Z","updatedAt":"2024-01-10T14:40:59.326Z","ACL":{"9MUdPyX2ae":{"read":true,"write":true}},"sessionToken":"r:17de3495dd207dc88677da7f9f9e4d6b","__type":"Object","className":"_User","objectId":"9MUdPyX2ae"}' - ); - localStorage.setItem("_appName", "contracts"); + // localStorage.setItem("accesstoken", "r:17de3495dd207dc88677da7f9f9e4d6b"); + // localStorage.setItem( + // "baseUrl", + // "https://staging-app.opensignlabs.com/api/app/" + // ); + // localStorage.setItem("parseAppId", "opensignstgn"); + // localStorage.setItem( + // "Parse/opensignstgn/currentUser", + // '{"name":"raktima","email":"raktimachaurasiya@gmail.com","phone":"5645676534","username":"raktimachaurasiya@gmail.com","emailVerified":false,"createdAt":"2024-01-10T14:40:59.326Z","updatedAt":"2024-01-10T14:40:59.326Z","ACL":{"9MUdPyX2ae":{"read":true,"write":true}},"sessionToken":"r:17de3495dd207dc88677da7f9f9e4d6b","__type":"Object","className":"_User","objectId":"9MUdPyX2ae"}' + // ); + // localStorage.setItem("_appName", "contracts"); if (documentId) { getDocumentDetails(true); } From bb732d7606f50b680c0723c969269a4b17b76d57 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Tue, 16 Jan 2024 19:47:07 +0530 Subject: [PATCH 05/58] feat: add dropdown,initial sign,name,job title in placeholder flow --- .../src/Component/PdfRequestFiles.js | 115 ++---------- .../src/Component/SignYourselfPdf.js | 170 +++++++++--------- .../Component/WidgetComponent/allWidgets.js | 4 + .../Component/WidgetComponent/placeholder.js | 25 +-- .../WidgetComponent/placeholderType.js | 151 ++++++++++++++-- .../Component/component/fieldsComponent.js | 1 + .../src/Component/component/renderPdf.js | 8 +- .../src/Component/placeHolderSign.js | 140 ++++++++------- .../SignDocuments/src/utils/Utils.js | 162 +++++++++++++---- 9 files changed, 466 insertions(+), 310 deletions(-) diff --git a/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js b/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js index 901c37a3f..2b23e9384 100644 --- a/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js +++ b/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js @@ -79,6 +79,7 @@ function PdfRequestFiles() { const [isExpired, setIsExpired] = useState(false); const [alreadySign, setAlreadySign] = useState(false); const [containerWH, setContainerWH] = useState({}); + const [initial, setInitial] = useState(""); const divRef = useRef(null); const isMobile = window.innerWidth < 767; const rowLevel = @@ -268,6 +269,7 @@ function PdfRequestFiles() { if (res[0] && res.length > 0) { setDefaultSignImg(res[0].ImageURL); + setInitial(res[0]?.Initials); } const loadObj = { isLoad: false @@ -289,18 +291,23 @@ function PdfRequestFiles() { (data) => data.signerObjId === signerObjectId ); if (checkUser && checkUser.length > 0) { - let checkSignUrl = []; - const checkSign = checkUser[0].placeHolder.filter( - (data, ind) => data.pos - ); - for (let i = 0; i < checkSign.length; i++) { - const posData = checkSign[i].pos.filter((pos) => !pos.SignUrl); - if (posData && posData.length > 0) { - checkSignUrl.push(posData); - } + let checkSigned = 0; + let allXyPos = 0; + + for (let i = 0; i < checkUser[0].placeHolder.length; i++) { + const posSignUrlData = checkUser[0].placeHolder[i].pos.filter( + (pos) => pos.SignUrl + ); + const posWidgetData = checkUser[0].placeHolder[i].pos.filter( + (pos) => pos.widgetValue + ); + + checkSigned = + checkSigned + posSignUrlData.length + posWidgetData.length; + allXyPos = allXyPos + checkUser[0].placeHolder[i].pos.length; } - if (checkSignUrl && checkSignUrl.length > 0) { + if (allXyPos !== checkSigned) { setIsAlert({ isShow: true, alertMessage: "Please complete your signature!" @@ -315,93 +322,7 @@ function PdfRequestFiles() { const pdfDoc = await PDFDocument.load(existingPdfBytes, { ignoreEncryption: true }); - // let pdfBase64; - - //checking if signature is only one then send image url in jpeg formate to server - // if (pngUrl.length === 1 && pngUrl[0].pos.length === 1) { - // if (isDocId) { - // try { - // pdfBase64 = await getBase64FromUrl(pdfUrl); - // } catch (err) { - // console.log(err); - // } - // } else { - // //embed document's object id to all pages in pdf document - // try { - // await embedDocId(pdfDoc, documentId, allPages); - // } catch (err) { - // console.log(err); - // } - // try { - // pdfBase64 = await pdfDoc.saveAsBase64({ - // useObjectStreams: false - // }); - // } catch (err) { - // console.log(err); - // } - // } - // for (let pngData of pngUrl) { - // const imgUrlList = pngData.pos; - // const pageNo = pngData.pageNumber; - // imgUrlList.map(async (data) => { - // //cheking signUrl is defau;t signature url of custom url - // let ImgUrl = data.SignUrl; - // const checkUrl = urlValidator(ImgUrl); - // //if default signature url then convert it in base 64 - // if (checkUrl) { - // ImgUrl = await getBase64FromIMG(ImgUrl + "?get"); - // } - // //function for called convert png signatre to jpeg in base 64 - // convertPNGtoJPEG(ImgUrl) - // .then((jpegBase64Data) => { - // const removeBase64Fromjpeg = "data:image/jpeg;base64,"; - // const newImgUrl = jpegBase64Data.replace( - // removeBase64Fromjpeg, - // "" - // ); - // //function for call to embed signature in pdf and get digital signature pdf - // signPdfFun( - // newImgUrl, - // documentId, - // signerObjectId, - // pdfOriginalWidth, - // pngUrl, - // containerWH, - // setIsAlert, - // data, - // pdfBase64, - // pageNo - // ) - // .then((res) => { - // if (res && res.status === "success") { - // setPdfUrl(res.data); - // setIsSigned(true); - // setSignedSigners([]); - // setUnSignedSigners([]); - // getDocumentDetails(); - // } else { - // setIsAlert({ - // isShow: true, - // alertMessage: "something went wrong" - // }); - // } - // }) - // .catch((err) => { - // setIsAlert({ - // isShow: true, - // alertMessage: "something went wrong" - // }); - // }); - // }) - // .catch((error) => { - // console.error("Error:", error); - // }); - // }); - // } - // } - // //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) { const flag = false; //embed document's object id to all pages in pdf document if (!isDocId) { @@ -415,6 +336,7 @@ function PdfRequestFiles() { flag, containerWH ); + //function for call to embed signature in pdf and get digital signature pdf try { const res = await signPdfFun( @@ -922,6 +844,7 @@ function PdfRequestFiles() { pdfLoadFail={pdfLoadFail} setSignerPos={setSignerPos} containerWH={containerWH} + initial={initial} /> )}
diff --git a/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js b/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js index 0e69563c6..2dfc58da9 100644 --- a/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js +++ b/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js @@ -17,7 +17,8 @@ import { multiSignEmbed, pdfNewWidthFun, addDefaultSignatureImg, - onImageSelect + onImageSelect, + calculateInitialWidthHeight } from "../utils/Utils"; import { useParams } from "react-router-dom"; import Tour from "reactour"; @@ -321,28 +322,6 @@ function SignYourSelf() { } }; - //calculate width and height - const calculateWidthHeight = (type) => { - const intialText = - type === "name" - ? pdfDetails[0].ExtUserPtr.Name - : type === "company" - ? pdfDetails[0].ExtUserPtr.Company - : type === "job title" && pdfDetails[0].ExtUserPtr.JobTitle; - const span = document.createElement("span"); - span.textContent = intialText; - span.style.font = `14px`; // here put your text size and font family - span.style.display = "hidden"; - document.body.appendChild(span); - const width = span.offsetWidth; - const height = span.offsetHeight; - - document.body.removeChild(span); - return { - getWidth: width, - getHeight: height - }; - }; //function for setting position after drop signature button over pdf const addPositionOfSignature = (item, monitor) => { const key = Math.floor(1000 + Math.random() * 9000); @@ -357,11 +336,31 @@ function SignYourSelf() { xPosition: window.innerWidth / 2 - 100, yPosition: window.innerHeight / 2 - 60, isDrag: false, + isStamp: monitor.type === "stamp" && true, key: key, - isStamp: monitor, - type: item.text, + type: monitor.type, yBottom: window.innerHeight / 2 - 60, - SignUrl: item.text === "initials" && initial + SignUrl: monitor.type === "initials" && initial, + widgetValue: + monitor.type === "name" + ? pdfDetails[0].ExtUserPtr.Name + : monitor.type === "company" + ? pdfDetails[0].ExtUserPtr.Company + : monitor.type === "job title" + ? pdfDetails[0].ExtUserPtr.JobTitle + : "", + Width: + monitor.type === "name" || + monitor.type === "company" || + monitor.type === "job title" + ? calculateInitialWidthHeight(monitor.type, pdfDetails[0]).getWidth + : "", + Height: + monitor.type === "company" || + monitor.type === "name" || + monitor.type === "job title" + ? calculateInitialWidthHeight(monitor.type, pdfDetails[0]).getHeight + : "" }; dropData.push(dropObj); @@ -386,8 +385,8 @@ function SignYourSelf() { xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x, yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y, isDrag: false, + isStamp: item.text === "stamp" && true, key: key, - isStamp: isDragStamp || isDragStampSS ? true : false, firstXPos: signBtnPosition[0] && signBtnPosition[0].xPos, firstYPos: signBtnPosition[0] && signBtnPosition[0].yPos, yBottom: ybottom, @@ -405,13 +404,13 @@ function SignYourSelf() { item.text === "name" || item.text === "company" || item.text === "job title" - ? calculateWidthHeight(item.text).getWidth + ? calculateInitialWidthHeight(item.text, pdfDetails[0]).getWidth : "", Height: item.text === "company" || item.text === "name" || item.text === "job title" - ? calculateWidthHeight(item.text).getHeight + ? calculateInitialWidthHeight(item.text, pdfDetails[0]).getHeight : "" }; @@ -449,78 +448,79 @@ function SignYourSelf() { }; setXyPostion((prev) => [...prev, xyPos]); - if (isDragSign || isDragSignatureSS) { + if (isDragSign || isDragSignatureSS || isDragStamp || isDragStampSS) { setIsSignPad(true); setSignKey(key); } } - - // setXyPostion((prev) => [...prev, xyPos]); }; //function for send placeholder's co-ordinate(x,y) position embed signature url or stamp url async function embedImages() { - let checkSignUrl = []; + let checkSigned = 0; + let allXyPos = 0; for (let i = 0; i < xyPostion.length; i++) { - const posData = xyPostion[i].pos.filter((pos) => !pos.SignUrl); - if (posData && posData.length > 0) { - checkSignUrl.push(posData); - } - } - // if (xyPostion.length === 0) { - // setIsAlert({ - // isShow: true, - // alertMessage: "Please complete your signature!" - // }); - // return; - // } else if (xyPostion.length > 0 && checkSignUrl.length > 0) { - // setIsAlert({ - // isShow: true, - // alertMessage: "Please complete your signature!" - // }); - // return; - // } else { - setIsCeleb(true); - setTimeout(() => { - setIsCeleb(false); - }, 3000); - const loadObj = { - isLoad: true, - message: "This might take some time" - }; - setIsLoading(loadObj); - const url = pdfDetails[0] && pdfDetails[0].URL; + const posSignUrlData = xyPostion[i].pos.filter((pos) => pos.SignUrl); + const posWidgetData = xyPostion[i].pos.filter((pos) => pos.widgetValue); - const existingPdfBytes = await fetch(url).then((res) => res.arrayBuffer()); + checkSigned = checkSigned + posSignUrlData.length + posWidgetData.length; + allXyPos = allXyPos + xyPostion[i].pos.length; + } + if (xyPostion.length === 0) { + setIsAlert({ + isShow: true, + alertMessage: "Please complete your signature!" + }); + return; + } else if (xyPostion.length > 0 && allXyPos !== checkSigned) { + setIsAlert({ + isShow: true, + alertMessage: "Please complete your signature!" + }); + return; + } else { + setIsCeleb(true); + setTimeout(() => { + setIsCeleb(false); + }, 3000); + const loadObj = { + isLoad: true, + message: "This might take some time" + }; + setIsLoading(loadObj); + const url = pdfDetails[0] && pdfDetails[0].URL; - // Load a PDFDocument from the existing PDF bytes - const pdfDoc = await PDFDocument.load(existingPdfBytes, { - ignoreEncryption: true - }); + const existingPdfBytes = await fetch(url).then((res) => + res.arrayBuffer() + ); - const flag = true; - //embed document's object id to all pages in pdf document - await embedDocId(pdfDoc, documentId, allPages); + // Load a PDFDocument from the existing PDF bytes + const pdfDoc = await PDFDocument.load(existingPdfBytes, { + ignoreEncryption: true + }); - //embed multi signature in pdf - const pdfBytes = await multiSignEmbed( - xyPostion, - pdfDoc, - pdfOriginalWidth, - flag, - containerWH - ); + const flag = true; + //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( + xyPostion, + pdfDoc, + pdfOriginalWidth, + flag, + containerWH + ); - // console.log("pdf", pdfBytes); - //function for call to embed signature in pdf and get digital signature pdf - signPdfFun(pdfBytes, documentId); + //function for call to embed signature in pdf and get digital signature pdf + signPdfFun(pdfBytes, documentId); - setIsSignPad(false); - setIsEmail(true); - setXyPostion([]); - setSignBtnPosition([]); - // } + setIsSignPad(false); + setIsEmail(true); + setXyPostion([]); + setSignBtnPosition([]); + } } //function for get digital signature diff --git a/microfrontends/SignDocuments/src/Component/WidgetComponent/allWidgets.js b/microfrontends/SignDocuments/src/Component/WidgetComponent/allWidgets.js index 4fd96e06c..3974f0270 100644 --- a/microfrontends/SignDocuments/src/Component/WidgetComponent/allWidgets.js +++ b/microfrontends/SignDocuments/src/Component/WidgetComponent/allWidgets.js @@ -6,6 +6,10 @@ function AllWidgets(props) { return (
+ props.addPositionOfSignature && + props.addPositionOfSignature("onclick", item) + } ref={(element) => { item.ref(element); if (element) { diff --git a/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholder.js b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholder.js index d60a66c28..bce9dd82d 100644 --- a/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholder.js +++ b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholder.js @@ -8,20 +8,20 @@ import PlaceholderType from "./placeholderType"; function Placeholder(props) { const [isDraggingEnabled, setDraggingEnabled] = useState(true); + //onclick placeholder function to open signature pad const handlePlaceholderClick = () => { - if (props.pos.type === "text") { + if (props.pos.type === "text" || props.pos.type === "checkbox") { setDraggingEnabled(false); } - - if (!props.data && !props.isDragging) { + if (props.isNeedSign && !props.isDragging) { if (props.pos.type) { if (props.pos.type === "signature" || props.pos.type === "stamp") { props.setIsSignPad(true); props.setSignKey(props.pos.key); props.setIsStamp(props.pos.isStamp); - } else if (props.pos.type === "dropdown") { - props.setShowDropdown(true); - props.setSignKey(props.pos.key); + } else if (props.pos.type === "dropdown" && !props.isNeedSign) { + props?.setShowDropdown(true); + props?.setSignKey(props.pos.key); } } else { props.setIsSignPad(true); @@ -33,7 +33,7 @@ function Placeholder(props) { props.setShowDropdown(true); props.setSignKey(props.pos.key); } - } else { + } else if (!props.pos.type) { if ( !props.pos.type && props.isNeedSign && @@ -209,8 +209,9 @@ function Placeholder(props) { className="fa-regular fa-circle-xmark signCloseBtn" onClick={(e) => { e.stopPropagation(); + if (props.data) { - props.handleDeleteSign(props.pos.key, props.data.signerObjId); + props.handleDeleteSign(props.pos.key, props.data.Id); } else { props.handleDeleteSign(props.pos.key); props.setIsStamp(false); @@ -219,7 +220,7 @@ function Placeholder(props) { onTouchEnd={(e) => { e.stopPropagation(); if (props.data) { - props.handleDeleteSign(props.pos.key, props.data.signerObjId); + props.handleDeleteSign(props.pos.key, props.data.Id); } else { props.handleDeleteSign(props.pos.key); props.setIsStamp(false); @@ -239,12 +240,14 @@ function Placeholder(props) { setXyPostion={props.setXyPostion} data={props.data} setSignKey={props.setSignKey} - isShowDropdown={props.isShowDropdown} + isShowDropdown={props?.isShowDropdown} isPlaceholder={props.isPlaceholder} signerObjId={props.signerObjId} handleUserName={props.handleUserName} setDraggingEnabled={setDraggingEnabled} - pdfDetails={props.pdfDetails} + pdfDetails={props?.pdfDetails && props?.pdfDetails[0]} + isNeedSign={props.isNeedSign} + initial={props.initial} />
diff --git a/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderType.js b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderType.js index 1f102ba60..4852a6a8f 100644 --- a/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderType.js +++ b/microfrontends/SignDocuments/src/Component/WidgetComponent/placeholderType.js @@ -1,12 +1,26 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { onChangeInput } from "../../utils/Utils"; function PlaceholderType(props) { const [selectOption, setSelectOption] = useState(""); - + const type = props.pos.type; const handleInputBlur = () => { props.setDraggingEnabled(true); }; + useEffect(() => { + if (props.isNeedSign) { + onChangeInput( + props.pdfDetails, + null, + props.xyPostion, + null, + props.setXyPostion, + props.data && props.data.signerObjId, + props.initial + ); + } + }, [type]); + switch (props.pos.type) { case "signature": return props.pos.SignUrl ? ( @@ -136,19 +150,54 @@ function PlaceholderType(props) { ); case "initials": - return ( + return props.pos.SignUrl || props.initial ? ( signimg + ) : ( +
+
{props.pos.type}
+ + {props?.handleUserName && + props?.handleUserName(props?.data.signerObjId, props?.data.Role)} +
); + case "name": - return ( + return props.isNeedSign ? ( + + onChangeInput( + e.target.value, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data.signerObjId, + false + ) + } + /> + ) : props.pos.widgetValue ? (
{props.pos.widgetValue}
+ ) : ( +
+ {props.pos.type} +
); + case "company": - return ( + return props.isNeedSign ? ( + + onChangeInput( + e.target.value, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data.signerObjId, + false + ) + } + /> + ) : props.pos.widgetValue ? ( +
+ {props.pos.widgetValue} +
+ ) : (
-
{props.pos.widgetValue}
+ {props.pos.type}
); + case "job title": - return ( + return props.isNeedSign ? ( + + onChangeInput( + e.target.value, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data.signerObjId, + false + ) + } + /> + ) : props.pos.widgetValue ? ( +
+ {props.pos.widgetValue} +
+ ) : (
-
{props.pos.widgetValue}
+ {props.pos.type}
); case "date": @@ -186,7 +306,9 @@ function PlaceholderType(props) { className="inputPlaceholder" style={{ outlineColor: "#007bff" }} type="date" - disabled={props.isPlaceholder} + disabled={ + props.isNeedSign ? false : props.isPlaceholder ? true : false + } onBlur={handleInputBlur} onChange={(e) => onChangeInput( @@ -201,6 +323,7 @@ function PlaceholderType(props) { } /> ); + default: return props.pos.SignUrl ? (
diff --git a/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js b/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js index bb4f8621a..6f0137a4a 100644 --- a/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js +++ b/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js @@ -435,6 +435,7 @@ function FieldsComponent({ handleMouseLeave={handleMouseLeave} signRef={signRef} marginLeft={5} + addPositionOfSignature={addPositionOfSignature} />
) @@ -964,6 +968,7 @@ function RenderPdf({ posWidth={posWidth} posHeight={posHeight} pdfDetails={pdfDetails[0]} + isDragging={isDragging} /> ) ); @@ -1487,6 +1492,7 @@ function RenderPdf({ posWidth={posWidth} posHeight={posHeight} pdfDetails={pdfDetails[0]} + isDragging={isDragging} /> ) ); diff --git a/microfrontends/SignDocuments/src/Component/placeHolderSign.js b/microfrontends/SignDocuments/src/Component/placeHolderSign.js index c1034ce06..a610b79e5 100644 --- a/microfrontends/SignDocuments/src/Component/placeHolderSign.js +++ b/microfrontends/SignDocuments/src/Component/placeHolderSign.js @@ -452,9 +452,14 @@ function PlaceHolderSign() { } setSignerPos((prev) => [...prev, placeHolderPos]); } + if (item.text === "dropdown") { + setShowDropdown(true); + setSignKey(key); + } } } }; + //function for get pdf page details const pageDetails = async (pdf) => { const load = { @@ -858,52 +863,46 @@ function PlaceHolderSign() { ]; const handleSaveDropdownOptions = (dropdownName, dropdownOptions) => { - //get current signers placeholder position data - const currentSigner = signerPos.filter( - (data) => data.signerObjId === signerObjId - ); - //get current pagenumber placeholder index - const getIndex = currentSigner[0].placeHolder.findIndex((object) => { - return object.pageNumber === pageNumber; - }); + const filterSignerPos = signerPos.filter((data) => data.Id === uniqueId); - const placeholderPosition = currentSigner[0].placeHolder; - //function of save signature image and get updated position with signature image url + if (filterSignerPos.length > 0) { + const getPlaceHolder = filterSignerPos[0].placeHolder; - let getXYdata = placeholderPosition[getIndex].pos; - const updateXYData = getXYdata.map((position) => { - if (position.key === signKey) { - return { - ...position, - widgetName: dropdownName, - widgetOption: dropdownOptions - }; - } - return position; - }); + const getPageNumer = getPlaceHolder.filter( + (data) => data.pageNumber === pageNumber + ); - const getUpdatePosition = placeholderPosition.map((obj, ind) => { - if (ind === getIndex) { - return { ...obj, pos: updateXYData }; - } - return obj; - }); + if (getPageNumer.length > 0) { + const getXYdata = getPageNumer[0].pos; - const updateSignerData = currentSigner.map((obj, ind) => { - if (obj.signerObjId === signerObjId) { - return { ...obj, placeHolder: getUpdatePosition }; - } - return obj; - }); + const getPosData = getXYdata; + const addSignPos = getPosData.map((position, ind) => { + if (position.key === signKey) { + return { + ...position, + widgetName: dropdownName, + widgetOption: dropdownOptions + }; + } + return position; + }); - const index = signerPos.findIndex( - (data) => data.signerObjId === signerObjId - ); - setSignerPos((prevState) => { - const newState = [...prevState]; - newState.splice(index, 1, ...updateSignerData); - return newState; - }); + const newUpdateSignPos = getPlaceHolder.map((obj, ind) => { + if (obj.pageNumber === pageNumber) { + return { ...obj, pos: addSignPos }; + } + return obj; + }); + const newUpdateSigner = signerPos.map((obj, ind) => { + if (obj.Id === uniqueId) { + return { ...obj, placeHolder: newUpdateSignPos }; + } + return obj; + }); + + setSignerPos(newUpdateSigner); + } + } }; //function for update TourStatus @@ -1082,7 +1081,7 @@ function PlaceHolderSign() { {isSendAlert.mssg === "confirm" && ( + + + + + ); +} + +export default DriveBody; diff --git a/apps/OpenSign/src/components/pdf/BorderResize.js b/apps/OpenSign/src/components/pdf/BorderResize.js new file mode 100644 index 000000000..505c68d30 --- /dev/null +++ b/apps/OpenSign/src/components/pdf/BorderResize.js @@ -0,0 +1,17 @@ +import React from "react"; + +function BorderResize({ right, top }) { + return ( +
+ ); +} + +export default BorderResize; diff --git a/apps/OpenSign/src/components/pdf/Certificate.js b/apps/OpenSign/src/components/pdf/Certificate.js new file mode 100644 index 000000000..1885bdd58 --- /dev/null +++ b/apps/OpenSign/src/components/pdf/Certificate.js @@ -0,0 +1,277 @@ +import React, { useEffect, useState } from "react"; +import "../../styles/certificate.css"; +import opensignLogo from "../../assets/images/open-sign-logo.png"; +import { + Page, + Text, + View, + Document, + StyleSheet, + Image +} from "@react-pdf/renderer"; + +function Certificate({ pdfData }) { + const [isMultiSigners, setIsMultiSigners] = useState(); + const [multiSigner, setMultiSigners] = useState([]); + const [isLoad, setIsLoad] = useState(false); + + useEffect(() => { + handleSignerData(); + // eslint-disable-next-line + }, []); + + const handleSignerData = () => { + const checkSigners = pdfData.filter((data) => data.Signers); + if (checkSigners && checkSigners.length > 0) { + setIsMultiSigners(true); + + const checkSignSigners = + pdfData[0].AuditTrail && + pdfData[0].AuditTrail.length > 0 && + pdfData[0].AuditTrail.filter((data) => data.Activity === "Signed"); + + setMultiSigners(checkSignSigners); + } else { + setIsMultiSigners(false); + } + setIsLoad(true); + }; + + const styles = StyleSheet.create({ + page: { + borderRadius: "5px", + padding: "10px", + backgroundColor: "white" + }, + section1: { + border: "1px solid rgb(177, 174, 174)", + padding: "20px" + }, + textStyle: { + fontWeight: "bold", + fontSize: "11px", + marginBottom: "10px" + }, + textStyle2: { + fontWeight: "600", + fontSize: "11px", + marginBottom: "10px", + color: "gray" + }, + image: { + width: "71px", + height: "17px" + } + }); + + const generatedDate = () => { + const newDate = new Date(); + const utcTime = newDate.toUTCString(); + + return ( + + Generated On {utcTime} + + ); + }; + const changeCompletedDate = () => { + const completedOn = pdfData[0].updatedAt; + const newDate = new Date(completedOn); + const utcTime = newDate.toUTCString(); + + return {utcTime}; + }; + + const signerName = (data) => { + const getSignerName = pdfData[0].Signers.filter( + (sign) => sign.objectId === data.UserPtr.objectId + ); + + return ( + getSignerName[0] && + getSignerName.length > 0 && ( + <> + + Name :   + {getSignerName[0].Name} + + + Email :   + {getSignerName[0].Email} + + + ) + ); + }; + + return ( + isLoad && ( + + {/** Page defines a single page of content. */} + + + + + {generatedDate()} + + + + + {" "} + Certificate of Completion + + + + + + Summary + + + + + Document ID :   + {pdfData[0].objectId} + + + Document Name :   + {pdfData[0].Name} + + + Organization :   + + {pdfData[0].ExtUserPtr.Company} + + + + Completed on :  {changeCompletedDate()} + + {multiSigner && multiSigner.length > 0 && ( + + Signers :   + + {multiSigner.length} + + + )} + + {isMultiSigners ? ( + + + Recipients + + + + {multiSigner && + multiSigner.map((data, ind) => { + return ( + + + {signerName(data)} + + + Accessed from :   + + {data.ipAddress} + + + + ); + })} + + + ) : ( + + + Recipients + + + Signers :  1 + + + Name :   + + {pdfData[0].ExtUserPtr.Name} + + + + Email :   + + {pdfData[0].ExtUserPtr.Email} + + + + Accessed from :   + + {pdfData[0].AuditTrail && + pdfData[0].AuditTrail[0].ipAddress} + + + + + Signed on :  {changeCompletedDate()} + + + )} + + + + + + ) + ); +} + +export default Certificate; diff --git a/apps/OpenSign/src/components/pdf/DefaultSignature.js b/apps/OpenSign/src/components/pdf/DefaultSignature.js new file mode 100644 index 000000000..a440e807e --- /dev/null +++ b/apps/OpenSign/src/components/pdf/DefaultSignature.js @@ -0,0 +1,74 @@ +import React from "react"; +import { themeColor } from "../../constant/const"; +function DefaultSignature({ defaultSignImg, xyPostion, setDefaultSignAlert }) { + const confirmToaddDefaultSign = () => { + if (xyPostion.length > 0) { + setDefaultSignAlert({ + isShow: true, + alertMessage: + "Are you sure you want to auto sign at requested all locations?" + }); + } else { + setDefaultSignAlert({ + isShow: true, + alertMessage: "please select position!" + }); + } + }; + + return ( +
+
+ Signature +
+
+ <> +

Your Signature

+
+ default img +
+ + +
+
+ ); +} + +export default DefaultSignature; diff --git a/apps/OpenSign/src/components/pdf/DraftDocument.js b/apps/OpenSign/src/components/pdf/DraftDocument.js new file mode 100644 index 000000000..6decadf5b --- /dev/null +++ b/apps/OpenSign/src/components/pdf/DraftDocument.js @@ -0,0 +1,97 @@ +import React, { useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import Loader from "./Loader"; +import { contractDocument } from "../../constant/Utils"; +import HandleError from "../../primitives/HandleError"; +function DraftDocument() { + const navigate = useNavigate(); + const [isLoading, setIsLoading] = useState({ + isLoader: true, + message: "This might take some time" + }); + + const rowLevel = + localStorage.getItem("rowlevel") && + JSON.parse(localStorage.getItem("rowlevel")); + const docId = + rowLevel && rowLevel?.id + ? rowLevel.id + : rowLevel?.objectId && rowLevel.objectId; + + useEffect(() => { + getDocumentDetails(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + //get document details + const getDocumentDetails = async () => { + //getting document details + const documentData = await contractDocument(docId); + if (documentData && documentData.length > 0) { + handleDraftDoc(documentData); + } else if ( + documentData === "Error: Something went wrong!" || + (documentData.result && documentData.result.error) + ) { + setIsLoading({ + isLoader: false, + message: "Error: Something went wrong!" + }); + } else { + setIsLoading({ + isLoader: false, + message: "No data found!" + }); + } + }; + + //check document type and render on signyour self and placeholder route + const handleDraftDoc = (documentData) => { + const data = documentData[0]; + const signerExist = data.Signers && data.Signers; + const isDecline = data.IsDeclined && data.IsDeclined; + const isPlaceholder = data.Placeholders && data.Placeholders; + const signedUrl = data.SignedUrl; + //checking if document has completed and request signature flow + if (data?.IsCompleted && signerExist?.length > 0) { + navigate(`/pdfRequestFiles/${data.objectId}`); + } + //checking if document has completed and signyour-self flow + else if (!signerExist && !isPlaceholder) { + navigate(`/signaturePdf/${data.objectId}`); + } + //checking if document has declined by someone + else if (isDecline) { + navigate(`/pdfRequestFiles/${data.objectId}`); + //checking draft type document + } else if ( + signerExist?.length > 0 && + isPlaceholder?.length > 0 && + !signedUrl + ) { + navigate(`/placeHolderSign/${data.objectId}`); + } + //Inprogress document + else if (isPlaceholder?.length > 0 && signerExist?.length > 0) { + navigate(`/pdfRequestFiles/${data.objectId}`); + } //placeholder draft document + else if ( + (signerExist?.length > 0 && + (!isPlaceholder || isPlaceholder?.length === 0)) || + ((!signerExist || signerExist?.length === 0) && isPlaceholder?.length > 0) + ) { + navigate(`/placeHolderSign/${data.objectId}`); + } + }; + + return ( +
+ {isLoading.isLoader ? ( + + ) : ( + + )} +
+ ); +} + +export default DraftDocument; diff --git a/apps/OpenSign/src/components/pdf/DragElement.js b/apps/OpenSign/src/components/pdf/DragElement.js new file mode 100644 index 000000000..e8bcfed52 --- /dev/null +++ b/apps/OpenSign/src/components/pdf/DragElement.js @@ -0,0 +1,13 @@ +import React from "react"; +import { getWidgetType, widgets } from "../../constant/Utils"; + +function DragElement(item) { + const getWidgets = widgets; + const filterWidgetPreview = getWidgets.filter( + (data) => data.type === item?.text + ); + + return
{getWidgetType(filterWidgetPreview[0])}
; +} + +export default DragElement; diff --git a/apps/OpenSign/src/components/pdf/DropdownWidgetOption.js b/apps/OpenSign/src/components/pdf/DropdownWidgetOption.js new file mode 100644 index 000000000..d9d7a7a6b --- /dev/null +++ b/apps/OpenSign/src/components/pdf/DropdownWidgetOption.js @@ -0,0 +1,374 @@ +import React, { useEffect, useState } from "react"; +import { themeColor } from "../../constant/const"; +import ModalUi from "../../primitives/ModalUi"; +function DropdownWidgetOption(props) { + const [dropdownOptionList, setDropdownOptionList] = useState([ + "option-1", + "option-2" + ]); + const [minCount, setMinCount] = useState(0); + const [maxCount, setMaxCount] = useState(0); + const [dropdownName, setDropdownName] = useState(props.type); + const [isReadOnly, setIsReadOnly] = useState(false); + const [status, setStatus] = useState("required"); + const [defaultValue, setDefaultValue] = useState(""); + const statusArr = ["required", "optional"]; + const [defaultCheckbox, setDefaultCheckbox] = useState([]); + + useEffect(() => { + if ( + props.currWidgetsDetails?.options?.name && + props.currWidgetsDetails?.options?.values + ) { + setDropdownName(props.currWidgetsDetails?.options?.name); + setDropdownOptionList(props.currWidgetsDetails?.options?.values); + setMinCount( + props.currWidgetsDetails?.options?.validation?.minRequiredCount + ); + setMaxCount( + props.currWidgetsDetails?.options?.validation?.maxRequiredCount + ); + setIsReadOnly(props.currWidgetsDetails?.options?.isReadOnly); + setStatus(props.currWidgetsDetails?.options?.status || "required"); + setDefaultValue(props.currWidgetsDetails?.options?.defaultValue || ""); + setDefaultCheckbox(props.currWidgetsDetails?.options?.defaultValue || []); + } else { + setStatus("required"); + } + }, [props.currWidgetsDetails]); + const handleInputChange = (index, value) => { + setDropdownOptionList((prevInputs) => { + const newInputs = [...prevInputs]; + newInputs[index] = value; + return newInputs; + }); + }; + + const handleAddInput = () => { + const flage = true; + setDropdownOptionList((prevInputs) => [...prevInputs, ""]); + props.handleSaveWidgetsOptions(null, null, null, null, null, flage, false); + }; + + const handleDeleteInput = (ind) => { + const flage = true; + const getUpdatedOptions = dropdownOptionList.filter( + (data, index) => index !== ind + ); + setDropdownOptionList(getUpdatedOptions); + props.handleSaveWidgetsOptions(null, null, null, null, null, false, flage); + }; + + const handleSaveOption = () => { + const defaultData = + defaultCheckbox && defaultCheckbox.length > 0 + ? defaultCheckbox + : defaultValue; + + props.handleSaveWidgetsOptions( + dropdownName, + dropdownOptionList, + minCount, + maxCount, + isReadOnly, + null, + null, + status, + defaultData + ); + props.setShowDropdown(false); + setDropdownOptionList(["option-1", "option-2"]); + setDropdownName(props.type); + props.setCurrWidgetsDetails({}); + setIsReadOnly(false); + setMinCount(0); + setMaxCount(0); + setDefaultCheckbox([]); + setDefaultValue(""); + }; + + const handleSetMinMax = (e) => { + const minValue = e.target.value; + if (minValue > dropdownOptionList.length) { + return ""; + } else { + return minValue; + } + }; + + const handleDefaultCheck = (index) => { + const getDefaultCheck = defaultCheckbox.includes(index); + if (getDefaultCheck) { + return true; + } else { + return false; + } + }; + + return ( + //props.showDropdown + +
+
{ + e.preventDefault(); + handleSaveOption(); + }} + > +
+ {["checkbox", "radio"].includes(props.type) && + !props.isSignYourself && ( +
+ { + setIsReadOnly(e.target.checked); + }} + /> + + +
+ )} + + setDropdownName(e.target.value)} + className="drodown-input" + /> + + {props.type === "checkbox" && !props.isSignYourself && ( + <> + + { + const count = handleSetMinMax(e); + setMinCount(count); + }} + className="drodown-input" + /> + + { + const count = handleSetMinMax(e); + setMaxCount(count); + }} + className="drodown-input" + /> + + )} + + +
+ {dropdownOptionList.map((option, index) => ( +
+ {props.type === "checkbox" && !props.isSignYourself && ( + { + if (e.target.checked) { + const getDefaultCheck = + defaultCheckbox?.includes(index); + if (!getDefaultCheck) { + setDefaultCheckbox((prev) => [...prev, index]); + } + } else { + const removeOption = defaultCheckbox.filter( + (data) => data !== index + ); + setDefaultCheckbox(removeOption); + } + }} + style={{ + width: "23px", + height: "19px", + marginRight: "5px" + }} + /> + )} + handleInputChange(index, e.target.value)} + /> + + handleDeleteInput(index)} + style={{ + color: "red", + fontSize: "25px", + marginLeft: "10px" + }} + > +
+ ))} + + +
+ {["dropdown", "radio"].includes(props.type) && ( + <> + + + + )} + {props.type !== "checkbox" && props.type !== "radio" && ( + <> +
+ {statusArr.map((data, ind) => { + return ( +
+ setStatus(data.toLowerCase())} + checked={status.toLowerCase() === data.toLowerCase()} + /> +
+ {data} +
+
+ ); + })} +
+ + )} +
+ +
+ + {props.currWidgetsDetails?.options?.values?.length > 0 && ( + + )} +
+
+
+ ); +} + +export default DropdownWidgetOption; diff --git a/apps/OpenSign/src/components/pdf/EditTemplate.js b/apps/OpenSign/src/components/pdf/EditTemplate.js new file mode 100644 index 000000000..5c0688bda --- /dev/null +++ b/apps/OpenSign/src/components/pdf/EditTemplate.js @@ -0,0 +1,142 @@ +import React, { useState } from "react"; +import "../../styles/AddUser.css"; +// import SelectFolder from "../../premitives/SelectFolder"; + +const EditTemplate = ({ template, onSuccess }) => { + // const [folder, setFolder] = useState({ ObjectId: "", Name: "" }); + const [formData, setFormData] = useState({ + Name: template?.Name || "", + Note: template?.Note || "", + Description: template?.Description || "", + SendinOrder: template?.SendinOrder ? `${template?.SendinOrder}` : "false" + }); + + const handleStrInput = (e) => { + setFormData({ ...formData, [e.target.name]: e.target.value }); + }; + // const handleFolder = (data) => { + // console.log("handleFolder ", data) + // setFolder(data); + // }; + + // Define a function to handle form submission + const handleSubmit = async (e) => { + e.preventDefault(); + e.stopPropagation(); + const isChecked = formData.SendinOrder === "true" ? true : false; + const data = { ...formData, SendinOrder: isChecked }; + onSuccess(data); + }; + + return ( +
+
+
+
+ +
+ {template.URL?.split("/")?.pop()?.split("_")[1]} +
+
+
+ + handleStrInput(e)} + required + className="addUserInput" + /> +
+
+ + handleStrInput(e)} + className="addUserInput" + /> +
+
+ + handleStrInput(e)} + className="addUserInput" + /> +
+
+ +
+ +
Yes
+
+
+ +
No
+
+
+ {/* */} +
+ +
+ +
+
+ ); +}; + +export default EditTemplate; diff --git a/apps/OpenSign/src/components/pdf/EmailComponent.js b/apps/OpenSign/src/components/pdf/EmailComponent.js new file mode 100644 index 000000000..c9e5983b6 --- /dev/null +++ b/apps/OpenSign/src/components/pdf/EmailComponent.js @@ -0,0 +1,430 @@ +import React, { useState } from "react"; +import { saveAs } from "file-saver"; +import celebration from "../../assets/images/newCeleb.gif"; +import axios from "axios"; +import { getBase64FromUrl } from "../../constant/Utils"; +import { themeColor } from "../../constant/const"; +import printModule from "print-js"; +import loader from "../../assets/images/loader2.gif"; + +function EmailComponent({ + isEmail, + pdfUrl, + isCeleb, + setIsEmail, + setSuccessEmail, + pdfName, + sender, + setIsAlert +}) { + const [emailList, setEmailList] = useState([]); + const [emailValue, setEmailValue] = useState(); + const [isLoading, setIsLoading] = useState(false); + //function for send email + const sendEmail = async () => { + setIsLoading(true); + let sendMail; + for (let i = 0; i < emailList.length; i++) { + try { + const imgPng = + "https://qikinnovation.ams3.digitaloceanspaces.com/logo.png"; + // "https://qikinnovation.ams3.digitaloceanspaces.com/mailLogo_2023-08-18T12%3A51%3A31.573Z.png"; + + let url = `${localStorage.getItem("baseUrl")}functions/sendmailv3/`; + const headers = { + "Content-Type": "application/json", + "X-Parse-Application-Id": localStorage.getItem("parseAppId"), + sessionToken: localStorage.getItem("accesstoken") + }; + const openSignUrl = "https://www.opensignlabs.com/contact-us"; + const themeBGcolor = themeColor; + let params = { + pdfName: pdfName, + url: pdfUrl, + recipient: emailList[i], + subject: `${sender.name} has signed the doc - ${pdfName}`, + from: sender.email, + html: + "

Document Copy

A copy of the document " + + pdfName + + " is attached to this email. Kindly download the document from the attachment.

This is an automated email from OpenSignâ„¢. For any queries regarding this email, please contact the sender " + + sender.email + + " directly. If you think this email is inappropriate or spam, you may file a complaint with OpenSignâ„¢ here

" + }; + sendMail = await axios.post(url, params, { headers: headers }); + } catch (error) { + console.log("error", error); + setIsLoading(false); + setIsEmail(false); + setIsAlert({ + isShow: true, + alertMessage: "something went wrong" + }); + } + } + + if (sendMail && sendMail.data.result.status === "success") { + setSuccessEmail(true); + setTimeout(() => { + setSuccessEmail(false); + setIsEmail(false); + setEmailValue(""); + setEmailList([]); + }, 1500); + + setIsLoading(false); + } else if (sendMail && sendMail.data.result.status === "error") { + setIsLoading(false); + setIsEmail(false); + setIsAlert({ + isShow: true, + alertMessage: "something went wrong" + }); + setEmailValue(""); + setEmailList([]); + } else { + setIsLoading(false); + setIsEmail(false); + setIsAlert({ + isShow: true, + alertMessage: "something went wrong" + }); + setEmailValue(""); + setEmailList([]); + } + }; + + //function for remove email + const removeChip = (index) => { + const updateEmailCount = emailList.filter((data, key) => key !== index); + setEmailList(updateEmailCount); + }; + //function for get email value + const handleEmailValue = (e) => { + const value = e.target.value; + setEmailValue(value); + }; + + //function for save email in array after press enter + const handleEnterPress = (e) => { + if (e.key === "Enter" && emailValue) { + setEmailList((prev) => [...prev, emailValue]); + setEmailValue(""); + } else if (e === "add" && emailValue) { + setEmailList((prev) => [...prev, emailValue]); + setEmailValue(""); + } + }; + + // function for print signed pdf + const handleToPrint = async (event) => { + event.preventDefault(); + + const pdf = await getBase64FromUrl(pdfUrl); + const isAndroidDevice = navigator.userAgent.match(/Android/i); + const isAppleDevice = + (/iPad|iPhone|iPod/.test(navigator.platform) || + (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1)) && + !window.MSStream; + if (isAndroidDevice || isAppleDevice) { + const byteArray = Uint8Array.from( + atob(pdf) + .split("") + .map((char) => char.charCodeAt(0)) + ); + const blob = new Blob([byteArray], { type: "application/pdf" }); + const blobUrl = URL.createObjectURL(blob); + window.open(blobUrl, "_blank"); + } else { + printModule({ printable: pdf, type: "pdf", base64: true }); + } + }; + + //handle download signed pdf + const handleDownloadPdf = () => { + saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSignâ„¢.pdf`); + }; + + const sanitizeFileName = (pdfName) => { + // Replace spaces with underscore + return pdfName.replace(/ /g, "_"); + }; + + const isAndroid = /Android/i.test(navigator.userAgent); + + return ( +
+ {/* isEmail */} + {isEmail && ( +
+
+ {isLoading && ( +
+ no img + + This might take some time + +
+ )} +
+ Successfully signed! + +
+
+ {!isAndroid && ( + + )} + + +
+
+
+ {isCeleb && ( +
+ print img +
+ )} +

+ Recipients added here will get a copy of the signed document. +

+ {emailList.length > 0 ? ( + <> +
+
+ {emailList.map((data, ind) => { + return ( +
+ + {data} + + removeChip(ind)} + > + + +
+ ); + })} +
+ {emailList.length <= 9 && ( + { + if (emailValue) { + handleEnterPress("add"); + } + }} + required + /> + )} +
+ + ) : ( +
+ { + if (emailValue) { + handleEnterPress("add"); + } + }} + required + /> +
+ )} + { + if (emailValue) { + handleEnterPress("add"); + } + }} + > + + + +
+ Note: + + {" "} + You can only send to ten recipients at a time. + +
+
+ + +
+
+
+ )} +
+ ); +} + +export default EmailComponent; diff --git a/apps/OpenSign/src/components/pdf/Header.js b/apps/OpenSign/src/components/pdf/Header.js new file mode 100644 index 000000000..626671581 --- /dev/null +++ b/apps/OpenSign/src/components/pdf/Header.js @@ -0,0 +1,762 @@ +import React from "react"; +import PrevNext from "./PrevNext"; +import { PDFDownloadLink } from "@react-pdf/renderer"; +import Certificate from "./Certificate"; +import printModule from "print-js"; +import { getBase64FromUrl } from "../../constant/Utils"; +import { saveAs } from "file-saver"; +import "../../styles/signature.css"; +import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; +import { useNavigate } from "react-router-dom"; +import { themeColor } from "../../constant/const"; + +function Header({ + isPdfRequestFiles, + isPlaceholder, + recipient, + setIsDecline, + pageNumber, + isAlreadySign, + allPages, + changePage, + pdfUrl, + documentStatus, + embedWidgetsData, + pdfDetails, + signerPos, + signersdata, + isMailSend, + alertSendEmail, + isCompleted, + isShowHeader, + decline, + currentSigner, + dataTut4, + alreadySign, + isSignYourself, + setIsEmail, + completeBtnTitle, + setIsEditTemplate +}) { + const filterPrefill = + signerPos && signerPos?.filter((data) => data.Role !== "prefill"); + const isMobile = window.innerWidth < 767; + const navigate = useNavigate(); + const isGuestSigner = localStorage.getItem("isGuestSigner"); + //for go to previous page + function previousPage() { + changePage(-1); + } + //for go to next page + function nextPage() { + changePage(1); + } + //function for show decline alert + const handleDeclinePdfAlert = async () => { + const currentDecline = { + currnt: "Sure", + isDeclined: true + }; + setIsDecline(currentDecline); + }; + + //function for print digital sign pdf + const handleToPrint = async (event) => { + event.preventDefault(); + + const pdf = await getBase64FromUrl(pdfUrl); + const isAndroidDevice = navigator.userAgent.match(/Android/i); + const isAppleDevice = + (/iPad|iPhone|iPod/.test(navigator.platform) || + (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1)) && + !window.MSStream; + if (isAndroidDevice || isAppleDevice) { + const byteArray = Uint8Array.from( + atob(pdf) + .split("") + .map((char) => char.charCodeAt(0)) + ); + const blob = new Blob([byteArray], { type: "application/pdf" }); + const blobUrl = URL.createObjectURL(blob); + window.open(blobUrl, "_blank"); + } else { + printModule({ printable: pdf, type: "pdf", base64: true }); + } + }; + + //handle download signed pdf + const handleDownloadPdf = () => { + const pdfName = pdfDetails[0] && pdfDetails[0].Name; + saveAs(pdfUrl, `${sanitizeFileName(pdfName)}_signed_by_OpenSignâ„¢.pdf`); + }; + + const sanitizeFileName = (pdfName) => { + // Replace spaces with underscore + return pdfName.replace(/ /g, "_"); + }; + //certificate generate and download component in mobile view + const CertificateDropDown = () => { + //after generate download certifcate pdf + const handleDownload = (pdfBlob, fileName) => { + if (pdfBlob) { + const url = window.URL.createObjectURL(pdfBlob); + // Create a temporary anchor element + const link = document.createElement("a"); + link.href = url; + link.download = fileName; + // Append the anchor to the body + document.body.appendChild(link); + // Programmatically click the anchor to trigger the download + link.click(); + // Remove the anchor from the body + document.body.removeChild(link); + // Release the object URL to free up resources + window.URL.revokeObjectURL(url); + } + }; + + return ( + e.preventDefault()} + style={{ textDecoration: "none", zIndex: "35" }} + document={} + > + {({ blob, loading }) => ( + <> + {loading ? ( +
+ + Certificate +
+ ) : ( +
+ handleDownload( + blob, + `completion certificate-${ + pdfDetails[0] && pdfDetails[0].Name + }.pdf` + ) + } + > + + Certificate +
+ )} + + )} +
+ ); + }; + const CertificateComponent = () => { + return ( + } + fileName={`completion certificate-${ + pdfDetails[0] && pdfDetails[0].Name + }.pdf`} + > + {({ loading }) => ( + + )} + + ); + }; + return ( +
+ {isMobile && isShowHeader ? ( + + ) : ( +
+ + + {recipient ? ( + pdfUrl || isAlreadySign.mssg ? ( +
+ {pdfDetails[0] && pdfDetails.length > 0 && ( + + )} + + + +
+ ) : ( +
+ + + +
+ ) + ) : isPlaceholder ? ( + <> + {!isMailSend && + signersdata.length > 0 && + signersdata.length !== filterPrefill.length && ( +
+ {filterPrefill.length === 0 ? ( + + Add {signersdata.length - filterPrefill.length}{" "} + recipients signature + + ) : ( + + Add {signersdata.length - filterPrefill.length} more + recipients signature + + )} +
+ )} + +
+ {setIsEditTemplate && ( + + )} + + + +
+ + ) : isPdfRequestFiles ? ( + alreadySign ? ( +
+ {isCompleted.isCertificate && } + + + +
+ ) : ( +
+ + {currentSigner && ( + <> + + + + )} +
+ ) + ) : pdfUrl || (documentStatus && documentStatus.isCompleted) ? ( +
+ + + + +
+ ) : ( +
+ + + +
+ )} +
+ )} +
+ ); +} + +export default Header; diff --git a/apps/OpenSign/src/components/pdf/Loader.js b/apps/OpenSign/src/components/pdf/Loader.js new file mode 100644 index 000000000..a1c3bed1e --- /dev/null +++ b/apps/OpenSign/src/components/pdf/Loader.js @@ -0,0 +1,27 @@ +import React from "react"; +import loader from "../../assets/images/loader2.gif"; + +function Loader({ isLoading }) { + return ( +
+ no img + + {isLoading.message} + +
+ ); +} + +export default Loader; diff --git a/apps/OpenSign/src/components/pdf/Placeholder.js b/apps/OpenSign/src/components/pdf/Placeholder.js new file mode 100644 index 000000000..cae1c79f3 --- /dev/null +++ b/apps/OpenSign/src/components/pdf/Placeholder.js @@ -0,0 +1,624 @@ +import React, { useState, useEffect } from "react"; +import BorderResize from "./BorderResize"; +import PlaceholderBorder from "./PlaceholderBorder"; +import { Rnd } from "react-rnd"; +import { defaultWidthHeight, isMobile } from "../../constant/Utils"; +import PlaceholderType from "./PlaceholderType"; +import moment from "moment"; +import "../../styles/opensigndrive.css"; + +function Placeholder(props) { + const [isDraggingEnabled, setDraggingEnabled] = useState(true); + const [isShowDateFormat, setIsShowDateFormat] = useState(false); + const [selectDate, setSelectDate] = useState({ + date: moment(new Date().getTime()).format("MM/DD/YYYY"), + format: "MM/dd/YYYY" + }); + const [dateFormat, setDateFormat] = useState([]); + const [saveDateFormat, setSaveDateFormat] = useState(""); + const dateFormatArr = [ + "L", + "DD-MM-YYYY", + "YYYY-MM-DD", + "MM.DD.YYYY", + "MM-DD-YYYY", + "MMM DD, YYYY", + "LL", + "DD MMM, YYYY", + "DD MMMM, YYYY" + ]; + + const selectFormat = (data) => { + switch (data) { + case "L": + return "MM/dd/yyyy"; + case "DD-MM-YYYY": + return "dd-MM-yyyy"; + case "DD/MM/YYYY": + return "dd/MM/yyyy"; + case "LL": + return "MMMM dd, yyyy"; + case "DD MMM, YYYY": + return "dd MMM, YYYY"; + case "YYYY-MM-DD": + return "YYYY-MM-dd"; + case "MM-DD-YYYY": + return "MM-dd-YYYY"; + case "MM.DD.YYYY": + return "MM.dd.YYYY"; + case "MMM DD, YYYY": + return "MMM dd, YYYY"; + case "DD MMMM, YYYY": + return "dd MMMM, YYYY"; + default: + return "dd/MM/yyyy"; + } + }; + + //function for add selected date and format in selectFormat + const changeDateFormat = () => { + const updateDate = []; + dateFormatArr.map((data) => { + let date; + if (selectDate.format === "dd-MM-yyyy") { + const [day, month, year] = selectDate.date.split("-"); + date = new Date(`${year}-${month}-${day}`); + } else { + date = new Date(selectDate?.date); + } + const milliseconds = date.getTime(); + const newDate = moment(milliseconds).format(data); + const dateObj = { + date: newDate, + format: selectFormat(data) + }; + updateDate.push(dateObj); + }); + setDateFormat(updateDate); + }; + useEffect(() => { + if (props.isPlaceholder || props.isSignYourself) { + selectDate && changeDateFormat(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectDate]); + //handle to close drop down menu onclick screen + useEffect(() => { + const closeMenuOnOutsideClick = (e) => { + if (isShowDateFormat && !e.target.closest("#menu-container")) { + setIsShowDateFormat(!isShowDateFormat); + } + }; + document.addEventListener("click", closeMenuOnOutsideClick); + return () => { + // Cleanup the event listener when the component unmounts + document.removeEventListener("click", closeMenuOnOutsideClick); + }; + }, [isShowDateFormat]); + + //onclick placeholder function to open signature pad + const handlePlaceholderClick = () => { + if (props.setSelectWidgetId) { + props.setSelectWidgetId(props.pos.key); + } + + const widgetTypeExist = [ + "text", + "checkbox", + "name", + "company", + "job title", + "date", + "email" + ].includes(props.pos.type); + + if (widgetTypeExist) { + setDraggingEnabled(false); + } + if ((props.isNeedSign || props.isSignYourself) && !props.isDragging) { + if (props.pos.type) { + if ( + props.pos.type === "signature" || + props.pos.type === "stamp" || + props.pos.type === "image" + ) { + props.setIsSignPad(true); + props.setSignKey(props.pos.key); + props.setIsStamp(props.pos.isStamp); + } else if (props.pos.type === "initials") { + props.setIsSignPad(true); + props.setSignKey(props.pos.key); + props.setIsStamp(props.pos.isStamp); + props.setIsInitial(true); + } + } else { + props.setIsSignPad(true); + props.setSignKey(props.pos.key); + props.setIsStamp(props.pos?.isStamp ? props.pos.isStamp : false); + } + } else if ( + props.isPlaceholder && + !props.isDragging && + props.pos.type !== "label" + ) { + if (props.pos.key === props.selectWidgetId) { + props.handleLinkUser(props.data.Id); + props.setUniqueId(props.data.Id); + } + } else if (!props.pos.type) { + if ( + !props.pos.type && + props.isNeedSign && + props.data.signerObjId === props.signerObjId + ) { + props.setIsSignPad(true); + props.setSignKey(props.pos.key); + props.setIsStamp(props.pos.isStamp); + } else if ( + (props.isNeedSign && props.pos.type === "signature") || + props.pos.type === "stamp" + ) { + props.setIsSignPad(true); + props.setSignKey(props.pos.key); + props.setIsStamp(props.pos.isStamp); + } else if (props.isNeedSign && props.pos.type === "dropdown") { + props.setSignKey(props.pos.key); + } + } + }; + + const handleWidgetsOnclick = () => { + if (props.pos.type === "radio") { + props.setIsRadio(true); + } else if (props.pos.type === "dropdown") { + props?.setShowDropdown(true); + } else if (props.pos.type === "checkbox") { + props?.setIsCheckbox(true); + } else { + props?.handleNameModal(true); + } + + if (props.isPlaceholder) { + props.setUniqueId(props.data.Id); + } + props.setSignKey(props.pos.key); + props.setWidgetType(props.pos.type); + props.setCurrWidgetsDetails(props.pos); + }; + const PlaceholderIcon = () => { + return ( + props.isShowBorder && ( + <> + {(props.isPlaceholder || props.isSignYourself) && ( + <> + {props.pos.type === "checkbox" && props.isSignYourself ? ( + { + e.stopPropagation(); + handleWidgetsOnclick(); + }} + onTouchEnd={(e) => { + e.stopPropagation(); + handleWidgetsOnclick(); + }} + className="fa-solid fa-gear settingIcon" + style={{ + color: "#188ae2", + right: "9px", + top: "-28px" + }} + > + ) : ( + props.pos.type !== "date" && + props.pos.type !== "label" && + props.pos.type !== "signature" && + !props.isSignYourself && ( + { + e.stopPropagation(); + handleWidgetsOnclick(); + }} + onTouchEnd={(e) => { + e.stopPropagation(); + handleWidgetsOnclick(); + }} + className="fa-solid fa-gear settingIcon" + style={{ + color: "#188ae2", + right: ["checkbox", "radio"].includes(props.pos.type) + ? "24px" + : "47px", + top: ["checkbox", "radio"].includes(props.pos.type) + ? "-28px" + : "-19px" + }} + > + ) + )} + + {props.pos.type !== "label" && !props.isSignYourself && ( + { + e.stopPropagation(); + props.handleLinkUser(props.data.Id); + props.setUniqueId(props.data.Id); + }} + onTouchEnd={(e) => { + e.stopPropagation(); + props.handleLinkUser(props.data.Id); + props.setUniqueId(props.data.Id); + }} + style={{ + color: "#188ae2", + right: + props.pos.type === "checkbox" || + props.pos.type === "radio" + ? "8px" + : "32px", + top: + props.pos.type === "checkbox" || + props.pos.type === "radio" + ? "-28px" + : "-18px" + }} + > + )} + + )} + {props.pos.type === "date" && selectDate && ( + + )} + { + if (props.data) { + props.setSignerObjId(props.data.signerObjId); + props.setUniqueId(props.data.Id); + } + e.stopPropagation(); + props.setIsPageCopy(true); + props.setSignKey(props.pos.key); + }} + onTouchEnd={(e) => { + if (props.data) { + props.setSignerObjId(props.data.signerObjId); + props.setUniqueId(props.data.Id); + } + e.stopPropagation(); + props.setIsPageCopy(true); + props.setSignKey(props.pos.key); + }} + style={{ + color: "#188ae2", + right: + props.pos.type === "checkbox" || props.pos.type === "radio" + ? "-9px" + : "12px", + top: + props.pos.type === "checkbox" || props.pos.type === "radio" + ? "-28px" + : "-18px" + }} + > + { + e.stopPropagation(); + + if (props.data) { + props.handleDeleteSign(props.pos.key, props.data.Id); + } else { + props.handleDeleteSign(props.pos.key); + props.setIsStamp(false); + } + }} + onTouchEnd={(e) => { + e.stopPropagation(); + if (props.data) { + props.handleDeleteSign(props.pos.key, props.data?.Id); + } else { + props.handleDeleteSign(props.pos.key); + props.setIsStamp(false); + } + }} + style={{ + color: "#188ae2", + right: + props.pos.type === "checkbox" || props.pos.type === "radio" + ? "-27px" + : "-8px", + top: + props.pos.type === "checkbox" || props.pos.type === "radio" + ? "-28px" + : "-18px" + }} + > + + ) + ); + }; + + return ( + { + setDraggingEnabled(true); + props.handleTabDrag && props.handleTabDrag(props.pos.key); + }} + size={{ + width: props.posWidth(props.pos, props.isSignYourself), + height: props.posHeight(props.pos, props.isSignYourself) + }} + onResizeStart={() => { + setDraggingEnabled(true); + props.setIsResize && props.setIsResize(true); + }} + onResizeStop={() => { + props.setIsResize && props.setIsResize(false); + }} + disableDragging={ + props.isNeedSign + ? true + : props.isPlaceholder && props.pos.type !== "date" + ? false + : !isDraggingEnabled + } + onDragStop={(event, dragElement) => + props.handleStop && + props.handleStop(event, dragElement, props.data?.Id, props.pos?.key) + } + default={{ + x: props.xPos(props.pos, props.isSignYourself), + y: props.yPos(props.pos, props.isSignYourself) + }} + onResize={(e, direction, ref) => { + props.handleSignYourselfImageResize && + props.handleSignYourselfImageResize( + ref, + props.pos.key, + props.xyPostion, + props.setXyPostion, + props.index, + props.data && props.data.Id, + false + ); + }} + onClick={() => { + !props.isNeedSign && props.setWidgetType(props.pos.type); + props.isNeedSign && props.data?.signerObjId === props.signerObjId + ? handlePlaceholderClick() + : props.isPlaceholder + ? handlePlaceholderClick() + : props.isSignYourself && handlePlaceholderClick(); + }} + > + {props.isShowBorder && + props.pos.type !== "radio" && + props.pos.type !== "checkbox" && + props.pos.key === props.selectWidgetId ? ( + + ) : props.data && props.isNeedSign && props.pos.type !== "checkbox" ? ( + props.data?.signerObjId === props.signerObjId && + props.pos.type !== "radio" && + props.pos.type !== "checkbox" ? ( + + ) : ( + <> + ) + ) : ( + props.pos.type !== "radio" && + props.pos.type !== "checkbox" && + props.pos.key === props.selectWidgetId && + )} + + {props.isShowBorder && props.pos.key === props.selectWidgetId && ( + + )} + {isMobile ? ( +
{ + !props.isNeedSign && props.setWidgetType(props.pos.type); + props.isNeedSign && props.data?.signerObjId === props.signerObjId + ? handlePlaceholderClick() + : props.isPlaceholder + ? handlePlaceholderClick() + : props.isSignYourself && handlePlaceholderClick(); + }} + > + {props.pos.key === props.selectWidgetId && } + + +
+ ) : ( + <> + {props.pos.key === props.selectWidgetId && } + + + )} +
+ ); +} + +export default Placeholder; diff --git a/apps/OpenSign/src/components/pdf/PlaceholderBorder.js b/apps/OpenSign/src/components/pdf/PlaceholderBorder.js new file mode 100644 index 000000000..10cec89aa --- /dev/null +++ b/apps/OpenSign/src/components/pdf/PlaceholderBorder.js @@ -0,0 +1,35 @@ +import React from "react"; +import { themeColor } from "../../constant/const"; +import { + defaultWidthHeight, + resizeBorderExtraWidth +} from "../../constant/Utils"; +function PlaceholderBorder(props) { + const getResizeBorderExtraWidth = + props.pos.type === "checkbox" || props.pos.type === "radio" + ? 38 + : resizeBorderExtraWidth(); + const defaultWidth = defaultWidthHeight(props.pos.type).width; + const defaultHeight = defaultWidthHeight(props.pos.type).height; + + return ( +
+ ); +} + +export default PlaceholderBorder; diff --git a/apps/OpenSign/src/components/pdf/PlaceholderCopy.js b/apps/OpenSign/src/components/pdf/PlaceholderCopy.js new file mode 100644 index 000000000..be1646d08 --- /dev/null +++ b/apps/OpenSign/src/components/pdf/PlaceholderCopy.js @@ -0,0 +1,249 @@ +import React, { useState } from "react"; +import { themeColor } from "../../constant/const"; +import ModalUi from "../../primitives/ModalUi"; + +function PlaceholderCopy(props) { + const copyType = ["All pages", "All pages but last", "All pages but first"]; + const [selectCopyType, setSelectCopyType] = useState(""); + + //get RandomKey Id + const randomKey = () => { + const randomId = Math.floor(1000 + Math.random() * 9000); + return randomId; + }; + + //function for get copy placeholder position + const getCopyPlaceholderPosition = ( + type, + currentPlaceholder, + newPageNumber, + existPlaceholderPosition + ) => { + const filterPosition = + existPlaceholderPosition && + existPlaceholderPosition.filter( + (data) => data.xPosition !== currentPlaceholder.xPosition + ); + //copy all page placeholder at requested position except first page + if (newPageNumber === 1 && type === "first") { + if (filterPosition && filterPosition.length > 0) { + return { + pageNumber: newPageNumber, + pos: [...filterPosition] + }; + } + } + //copy all page placeholder at requested position except last page + else if (newPageNumber === props.allPages && type === "last") { + if (existPlaceholderPosition) { + return { + pageNumber: newPageNumber, + pos: [...filterPosition] + }; + } + } + //copy all page placeholder at requested position with existing placeholder position + else if (existPlaceholderPosition) { + return { + pageNumber: newPageNumber, + pos: [...filterPosition, currentPlaceholder] + }; + } + //copy all page placeholder at requested position + else { + return { + pageNumber: newPageNumber, + pos: [currentPlaceholder] + }; + } + }; + + //function for copy placeholder as per select copy type + const copyPlaceholder = (type) => { + let newPlaceholderPosition = []; + let newPageNumber = 1; + const signerPosition = props.xyPostion; + const signerId = props.signerObjId ? props.signerObjId : props.Id; + + //handle placeholder array and copy for multiple signers placeholder at requested location + if (signerId) { + //get current signers data + let filterSignerPosition; + if (props?.signerObjId) { + filterSignerPosition = signerPosition.filter( + (data) => data.signerObjId === signerId + ); + } else { + filterSignerPosition = signerPosition.filter( + (item) => item.Id === signerId + ); + } + //get current pagenumber's all placeholder position data + const placeholderPosition = filterSignerPosition[0].placeHolder.filter( + (data) => data.pageNumber === props.pageNumber + ); + //get current placeholder position data which user want to copy + const currentPlaceholder = placeholderPosition[0].pos.find( + (position) => position.key === props.signKey + ); + + for (let i = 0; i < props.allPages; i++) { + const newId = randomKey(); + currentPlaceholder.key = newId; + //get exist placeholder position for particular page + const existPlaceholder = filterSignerPosition[0].placeHolder.filter( + (data) => data.pageNumber === newPageNumber + ); + const existPlaceholderPosition = + existPlaceholder[0] && existPlaceholder[0].pos; + + //function for get copy to requested location of placeholder position + const getPlaceholderObj = getCopyPlaceholderPosition( + type, + currentPlaceholder, + newPageNumber, + existPlaceholderPosition + ); + if (getPlaceholderObj) { + newPlaceholderPosition.push(getPlaceholderObj); + } + newPageNumber++; + } + let updatedSignerPlaceholder; + if (props?.signerObjId) { + updatedSignerPlaceholder = signerPosition.map((signersData) => { + if (signersData.signerObjId === props.signerObjId) { + return { + ...signersData, + placeHolder: newPlaceholderPosition + }; + } + return signersData; + }); + } else { + updatedSignerPlaceholder = signerPosition.map((signersData) => { + if (signersData.Id === props.Id) { + return { + ...signersData, + placeHolder: newPlaceholderPosition + }; + } + return signersData; + }); + } + + const signersData = signerPosition; + signersData.splice(0, signerPosition.length, ...updatedSignerPlaceholder); + props.setXyPostion(signersData); + } + //handle signyourself array and copy for single signers placeholder at requested location + else { + const xyPostion = props.xyPostion; + + const placeholderPosition = xyPostion.filter( + (data) => data.pageNumber === props.pageNumber + ); + //get current placeholder position data which user want to copy + const currentPlaceholder = placeholderPosition[0].pos.find( + (pos) => pos.key === props.signKey + ); + + for (let i = 0; i < props.allPages; i++) { + //get exist placeholder position for particular page + const existPlaceholder = xyPostion.filter( + (data) => data.pageNumber === newPageNumber + ); + const existPlaceholderPosition = + existPlaceholder[0] && existPlaceholder[0].pos; + + const newId = randomKey(); + currentPlaceholder.key = newId; + //function for get copy to requested location of placeholder position + const getPlaceholderObj = getCopyPlaceholderPosition( + type, + currentPlaceholder, + newPageNumber, + existPlaceholderPosition + ); + if (getPlaceholderObj) { + newPlaceholderPosition.push(getPlaceholderObj); + } + + newPageNumber++; + } + props.setXyPostion(newPlaceholderPosition); + } + }; + + //function for getting selected type placeholder copy + const handleApplyCopy = () => { + if (selectCopyType === "All pages") { + copyPlaceholder("all"); + } else if (selectCopyType === "All pages but last") { + copyPlaceholder("last"); + } else if (selectCopyType === "All pages but first") { + copyPlaceholder("first"); + } + }; + + return ( + { + props.setIsPageCopy(false); + }} + > +
+ {copyType.map((data, key) => { + return ( +
+ +
+ ); + })} + +
+ + +
+
+ ); +} + +export default PlaceholderCopy; diff --git a/apps/OpenSign/src/components/pdf/PlaceholderType.js b/apps/OpenSign/src/components/pdf/PlaceholderType.js new file mode 100644 index 000000000..16bec9698 --- /dev/null +++ b/apps/OpenSign/src/components/pdf/PlaceholderType.js @@ -0,0 +1,741 @@ +import React, { useEffect, useState, forwardRef, useRef } from "react"; +import { onChangeInput } from "../../constant/Utils"; +import DatePicker from "react-datepicker"; +import "react-datepicker/dist/react-datepicker.css"; +import "../../styles/signature.css"; +import RegexParser from "regex-parser"; + +function PlaceholderType(props) { + const type = props.pos.type; + const [selectOption, setSelectOption] = useState( + props.pos?.options?.defaultValue ? props.pos?.options?.defaultValue : "" + ); + const [startDate, setStartDate] = useState(new Date()); + const [validatePlaceholder, setValidatePlaceholder] = useState(""); + const inputRef = useRef(null); + const [textValue, setTextValue] = useState(); + const [selectedCheckbox, setSelectedCheckbox] = useState([]); + + const validateExpression = (regexValidation) => { + let regexObject = regexValidation; + if (props.pos?.options.validation.type === "regex") { + regexObject = RegexParser(regexValidation); + } + // new RegExp(regexValidation); + let isValidate = regexObject.test(textValue); + if (!isValidate) { + props.setValidateAlert(true); + inputRef.current.focus(); + } + }; + + const handleInputBlur = () => { + props.setDraggingEnabled(true); + const validateType = props.pos?.options?.validation?.type; + + let regexValidation; + if (validateType) { + switch (validateType) { + case "email": + regexValidation = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; + validateExpression(regexValidation); + break; + case "number": + regexValidation = /^\d+$/; + validateExpression(regexValidation); + break; + case "text": + regexValidation = /^[a-zA-Z\s]+$/; + validateExpression(regexValidation); + break; + default: + regexValidation = props.pos?.options.validation.pattern; + validateExpression(regexValidation); + } + } + }; + + const handleTextValid = (e) => { + const textInput = e.target.value; + setTextValue(textInput); + }; + function checkRegularExpress(validateType) { + switch (validateType) { + case "email": + setValidatePlaceholder("demo@gmail.com"); + break; + case "number": + setValidatePlaceholder("12345"); + break; + case "text": + setValidatePlaceholder("enter text"); + break; + default: + setValidatePlaceholder("enter text"); + } + } + useEffect(() => { + setDefaultdata(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + function setDefaultdata() { + if (props.pos?.options?.hint) { + setValidatePlaceholder(props.pos?.options.hint); + } else if (props.pos?.options?.validation?.type) { + checkRegularExpress(props.pos?.options?.validation?.type); + } + if (props.isNeedSign && props.pos.type === "date") { + const updateDate = new Date(); + setStartDate(updateDate); + } + setTextValue( + props.pos?.options?.defaultValue ? props.pos?.options?.defaultValue : "" + ); + if (props.pos?.type && props.pos.type === "checkbox" && props.isNeedSign) { + const isDefaultValue = props.pos.options?.defaultValue; + setSelectedCheckbox(isDefaultValue); + } + } + useEffect(() => { + if (props.pos?.type && props.pos.type === "date") { + if (props.selectDate) { + let updateDate; + if (props.selectDate.format === "dd-MM-yyyy") { + const [day, month, year] = props.saveDateFormat.split("-"); + updateDate = new Date(`${year}-${month}-${day}`); + } else { + updateDate = new Date(); + } + // const updateDate = new Date(props.saveDateFormat); + setStartDate(updateDate); + const dateObj = { + date: props.saveDateFormat, + format: props.selectDate + ? props.selectDate?.format + : props.pos?.options?.validation?.format + ? props.pos?.options?.validation?.format + : "MM/dd/YYYY" + }; + props.setSelectDate(dateObj); + } + + onChangeInput( + props.saveDateFormat, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data.Id, + false, + props.selectDate?.format + ? props.selectDate.format + : props.pos?.options?.validation?.format + ? props.pos?.options?.validation?.format + : "MM/dd/YYYY" + ); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.saveDateFormat]); + + const dateValue = (value) => { + props.setSaveDateFormat(value); + return {value}; + }; + const ExampleCustomInput = forwardRef(({ value, onClick }, ref) => ( +
+ {dateValue(value)} + +
+ )); + ExampleCustomInput.displayName = "ExampleCustomInput"; + + useEffect(() => { + if (props.pos?.type) { + const senderUser = localStorage.getItem(`Extand_Class`); + const jsonSender = JSON.parse(senderUser); + + if (props.isNeedSign && props.data?.signerObjId === props.signerObjId) { + onChangeInput( + jsonSender && jsonSender[0], + null, + props.xyPostion, + null, + props.setXyPostion, + props.data.Id, + true + ); + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [type]); + + const calculateFontSize = () => { + const fontSize = 10 + Math.min(props.pos.Width, props.pos.Height) * 0.1; + const size = fontSize ? fontSize : 12; + return size + "px"; + }; + //function for show checked checkbox + const selectCheckbox = (ind) => { + const res = props.pos.options?.response; + const defaultCheck = props.pos.options?.defaultValue; + if (res && res?.length > 0) { + const isSelectIndex = res.indexOf(ind); + if (isSelectIndex > -1) { + return true; + } else { + return false; + } + // } + } else if (defaultCheck) { + const isSelectIndex = defaultCheck.indexOf(ind); + if (isSelectIndex > -1) { + return true; + } else { + return false; + } + } else { + return false; + } + }; + + const handleRadioCheck = (data) => { + const defaultData = props.pos.options?.defaultValue; + if (textValue === data) { + return true; + } else if (defaultData === data) { + return true; + } else { + return false; + } + }; + + //function for set checked and unchecked value of checkbox + const handleCheckboxValue = (isChecked, ind) => { + let updateSelectedCheckbox = [], + checkedList; + let isDefaultValue, isDefaultEmpty; + if (props.pos?.type && ["checkbox", "radio"].includes(props.pos.type)) { + updateSelectedCheckbox = selectedCheckbox; + if (isChecked) { + updateSelectedCheckbox.push(ind); + setSelectedCheckbox(updateSelectedCheckbox); + } else { + checkedList = selectedCheckbox.filter((data) => data !== ind); + setSelectedCheckbox(checkedList); + } + if (props.isNeedSign) { + isDefaultValue = props.pos.options?.defaultValue; + } + if (isDefaultValue && isDefaultValue.length > 0) { + isDefaultEmpty = true; + } + onChangeInput( + checkedList ? checkedList : updateSelectedCheckbox, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data.Id, + false, + null, + null, + null, + isDefaultEmpty + ); + } + }; + + //function to handle select radio widget and set value seletced by user + const handleCheckRadio = (isChecked, data) => { + let isDefaultValue, isDefaultEmpty; + if (props.isNeedSign) { + isDefaultValue = props.pos.options?.defaultValue; + } + if (isDefaultValue) { + isDefaultEmpty = true; + } + if (isChecked) { + setTextValue(data); + } else { + setTextValue(""); + } + onChangeInput( + textValue, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data.Id, + false, + null, + null, + null, + isDefaultEmpty + ); + }; + switch (props.pos.type) { + case "signature": + return props.pos.SignUrl ? ( + signimg + ) : ( +
+ {props?.handleUserName && + props?.handleUserName( + props?.data?.Id, + props?.data?.Role, + props?.pos?.type + )} +
+ ); + case "stamp": + return props.pos.SignUrl ? ( + signimg + ) : ( +
+ {props?.handleUserName && + props?.handleUserName( + props?.data?.Id, + props?.data?.Role, + props?.pos?.type + )} +
+ ); + case "checkbox": + return ( +
+ {props.pos.options?.values?.map((data, ind) => { + return ( + { + if (e.target.checked && !props.isPlaceholder) { + const maxRequired = + props.pos.options?.validation?.maxRequiredCount; + const maxCountInt = maxRequired && parseInt(maxRequired); + if (maxCountInt > 0) { + if (selectedCheckbox.length <= maxCountInt - 1) { + handleCheckboxValue(e.target.checked, ind); + } + } else { + handleCheckboxValue(e.target.checked, ind); + } + } else { + handleCheckboxValue(e.target.checked, ind); + } + }} + /> + ); + })} +
+ ); + case "text": + return props.isSignYourself || + (props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? ( + { + setTextValue(e.target.value); + onChangeInput( + e.target.value, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data?.Id, + false + ); + }} + /> + ) : ( +
+ {props.pos.type} +
+ ); + case "dropdown": + return props.data?.signerObjId === props.signerObjId ? ( + + ) : ( +
+ {props.pos?.options?.name ? props.pos.options.name : props.pos.type} +
+ ); + case "initials": + return props.pos.SignUrl ? ( + signimg + ) : ( +
+ {props?.handleUserName && + props?.handleUserName( + props?.data?.Id, + props?.data?.Role, + props?.pos?.type + )} +
+ ); + case "name": + return props.isSignYourself || + (props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? ( + { + handleTextValid(e); + onChangeInput( + e.target.value, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data?.Id, + false + ); + }} + /> + ) : ( +
+ {props.pos.type} +
+ ); + case "company": + return props.isSignYourself || + (props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? ( + { + handleTextValid(e); + onChangeInput( + e.target.value, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data?.Id, + false + ); + }} + /> + ) : ( +
+ {props.pos.type} +
+ ); + case "job title": + return props.isSignYourself || + (props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? ( + { + handleTextValid(e); + onChangeInput( + e.target.value, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data?.Id, + false + ); + }} + /> + ) : ( +
+ {props.pos.type} +
+ ); + case "date": + return ( +
+ { + setStartDate(date); + }} + popperPlacement="top-end" + customInput={} + dateFormat={ + props.selectDate + ? props.selectDate?.format + : props.pos?.options?.validation?.format + ? props.pos?.options?.validation?.format + : "dd MMMM, YYYY" + } + /> +
+ ); + case "image": + return props.pos.SignUrl ? ( + signimg + ) : ( +
+ {props?.handleUserName && + props?.handleUserName( + props?.data?.Id, + props?.data?.Role, + props?.pos?.type + )} +
+ ); + case "email": + return props.isSignYourself || + (props.isNeedSign && props.data?.signerObjId === props.signerObjId) ? ( + { + handleTextValid(e); + onChangeInput( + e.target.value, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data?.Id, + false + ); + }} + /> + ) : ( +
+ {props.pos.type} +
+ ); + case "radio": + return ( +
+ {props.pos.options?.values.map((data, ind) => { + return ( + { + if (!props.isPlaceholder) { + handleCheckRadio(e.target.checked, data); + } + }} + /> + ); + })} +
+ ); + case "label": + return ( +