From ba0c18b5919148c8aef7cd06daaf05b5d4095f6d Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Wed, 20 Mar 2024 12:38:34 +0530 Subject: [PATCH 01/36] fix: data fetching issue in openSign_drive --- .../src/components/opensigndrive/DriveBody.js | 47 +++---- apps/OpenSign/src/constant/Utils.js | 12 +- apps/OpenSign/src/layout/HomeLayout.js | 5 +- apps/OpenSign/src/pages/Opensigndrive.js | 125 ++++++++++++++---- .../cloud/parsefunction/getDrive.js | 7 +- 5 files changed, 131 insertions(+), 65 deletions(-) diff --git a/apps/OpenSign/src/components/opensigndrive/DriveBody.js b/apps/OpenSign/src/components/opensigndrive/DriveBody.js index 41e5a6110..11ad95a8f 100644 --- a/apps/OpenSign/src/components/opensigndrive/DriveBody.js +++ b/apps/OpenSign/src/components/opensigndrive/DriveBody.js @@ -12,15 +12,7 @@ import SelectFolder from "../shared/fields/SelectFolder"; //check this one import ModalUi from "../../primitives/ModalUi"; import { themeColor } from "../../constant/const"; -function DriveBody({ - pdfData, - setFolderName, - setDocId, - setIsLoading, - setPdfData, - isList, - setIsAlert -}) { +function DriveBody(props) { const [rename, setRename] = useState(""); const [renameValue, setRenameValue] = useState(""); const inputRef = useRef(null); @@ -50,28 +42,28 @@ function DriveBody({ name: data.Name, objectId: data.objectId }; - setFolderName((prev) => [...prev, folderData]); + props.setFolderName((prev) => [...prev, folderData]); const loadObj = { isLoad: true, message: "This might take some time" }; - setIsLoading(loadObj); - setDocId(data.objectId); + props.setIsLoading(loadObj); + props.setDocId(data.objectId); + props.setPdfData([]); + props.setSkip(0); + props.setLoadMore(true); }; //function for change doc name and update doc name in _document class const handledRenameDoc = async (data) => { setRename(""); const trimmedValue = renameValue.trim(); - if (trimmedValue.length > 0) { const updateName = { Name: renameValue }; const docId = data.objectId; - - const docData = pdfData; - + const docData = props.pdfData; const updatedData = docData.map((item) => { if (item.objectId === docId) { // If the item's ID matches the target ID, update the name @@ -80,8 +72,7 @@ function DriveBody({ // If the item's ID doesn't match, keep it unchanged return item; }); - - setPdfData(updatedData); + props.setPdfData(updatedData); await axios .put( `${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( @@ -102,7 +93,7 @@ function DriveBody({ }) .catch((err) => { console.log("Err ", err); - setIsAlert({ + props.setIsAlert({ isShow: true, alertMessage: "something went wrong" }); @@ -199,13 +190,13 @@ function DriveBody({ .then((result) => { const res = result.data; if (res) { - const updatedData = pdfData.filter((x) => x.objectId !== docId); - setPdfData(updatedData); + const updatedData = props.pdfData.filter((x) => x.objectId !== docId); + props.setPdfData(updatedData); } }) .catch((err) => { console.log("Err ", err); - setIsAlert({ + props.setIsAlert({ isShow: true, alertMessage: "something went wrong" }); @@ -262,10 +253,10 @@ function DriveBody({ // console.log("Listdata ", Listdata); const res = Listdata.data; if (res) { - const updatedData = pdfData.filter( + const updatedData = props.pdfData.filter( (x) => x.objectId !== updateDocId ); - setPdfData(updatedData); + props.setPdfData(updatedData); } }) .catch((err) => { @@ -584,7 +575,7 @@ function DriveBody({ //component to handle type of document and render according to type return ( <> - {isList ? ( + {props.isList ? (
@@ -597,7 +588,7 @@ function DriveBody({ - {pdfData.map((data, ind) => { + {props.pdfData.map((data, ind) => { return ( {handleFolderData(data, ind, "table")} @@ -609,7 +600,7 @@ function DriveBody({ ) : (
- {pdfData.map((data, ind) => { + {props.pdfData.map((data, ind) => { return (
{handleFolderData(data, ind, "list")} @@ -624,7 +615,7 @@ function DriveBody({ isOpenModal={isOpenMoveModal} folderCls={"contracts_Document"} setIsOpenMoveModal={setIsOpenMoveModal} - setPdfData={setPdfData} + setPdfData={props.setPdfData} /> )} { }); }; -//function for getting document details for getDrive -export const getDrive = async (documentId) => { +//function for getting document details for getDrive cloud function +export const getDrive = async (documentId, skip = 0, limit = 100) => { const data = { - docId: documentId && documentId + docId: documentId && documentId, + limit: limit, + skip: skip }; const driveDeatils = await axios .post(`${localStorage.getItem("baseUrl")}functions/getDrive`, data, { @@ -1078,8 +1080,8 @@ export const multiSignEmbed = async ( position.type === radioButtonWidget ? 10 : position.type === "checkbox" - ? 10 - : newUpdateHeight; + ? 10 + : newUpdateHeight; const newHeight = ind ? (ind > 0 ? widgetHeight : 0) : widgetHeight; if (signyourself) { diff --git a/apps/OpenSign/src/layout/HomeLayout.js b/apps/OpenSign/src/layout/HomeLayout.js index d3cfd8188..0cfccf180 100644 --- a/apps/OpenSign/src/layout/HomeLayout.js +++ b/apps/OpenSign/src/layout/HomeLayout.js @@ -224,7 +224,10 @@ const HomeLayout = () => {
-
+
{}
diff --git a/apps/OpenSign/src/pages/Opensigndrive.js b/apps/OpenSign/src/pages/Opensigndrive.js index b682c9b39..21ee616f9 100644 --- a/apps/OpenSign/src/pages/Opensigndrive.js +++ b/apps/OpenSign/src/pages/Opensigndrive.js @@ -7,8 +7,8 @@ import { useNavigate } from "react-router-dom"; import Title from "../components/Title"; import Parse from "parse"; import ModalUi from "../primitives/ModalUi"; -const DriveBody = React.lazy(() => - import("../components/opensigndrive/DriveBody") +const DriveBody = React.lazy( + () => import("../components/opensigndrive/DriveBody") ); const Loader = () => { return ( @@ -51,6 +51,10 @@ function Opensigndrive() { const [folderName, setFolderName] = useState([]); const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" }); const [isNewFol, setIsNewFol] = useState(false); + const [skip, setSkip] = useState(0); + const limit = 100; + const [loading, setLoading] = useState(false); + const [loadMore, setLoadMore] = useState(true); const currentUser = localStorage.getItem( `Parse/${localStorage.getItem("parseAppId")}/currentUser` @@ -70,19 +74,27 @@ function Opensigndrive() { }, [docId]); //function for get all pdf document list - const getPdfDocumentList = async () => { - const load = { - isLoad: true, - message: "This might take some time" - }; + const getPdfDocumentList = async (disbaleLoading) => { + setLoading(true); + if (!disbaleLoading) { + const load = { + isLoad: true, + message: "This might take some time" + }; + + setIsLoading(load); + } let driveDetails; - setIsLoading(load); try { - driveDetails = await getDrive(); + driveDetails = await getDrive(null, skip, limit); if (driveDetails) { if (driveDetails.length > 0) { - setPdfData(driveDetails); - sortApps(null, null, driveDetails); + setSkip((prevSkip) => prevSkip + limit); + // If the fetched data length is less than the limit, it means there's no more data to fetch + if (driveDetails.length < limit) { + setLoadMore(false); + } + sortApps(null, null, driveDetails, true); } const data = [ { @@ -107,25 +119,33 @@ function Opensigndrive() { isShow: true, alertMessage: "something went wrong" }); + } finally { + setLoading(false); } }; + //function for get parent folder document list - const getPdfFolderDocumentList = async () => { - const load = { - isLoad: true, - message: "This might take some time" - }; - setIsLoading(load); + const getPdfFolderDocumentList = async (disableLoading) => { + setLoading(true); + if (!disableLoading) { + const load = { + isLoad: true, + message: "This might take some time" + }; + setIsLoading(load); + } + let driveDetails; try { - driveDetails = await getDrive(docId); - + driveDetails = await getDrive(docId, skip, limit); if (driveDetails) { if (driveDetails.length > 0) { - setPdfData(driveDetails); - sortApps(null, null, driveDetails); - } else { - setPdfData([]); + setSkip((prevSkip) => prevSkip + limit); + // If the fetched data length is less than the limit, it means there's no more data to fetch + if (driveDetails.length < limit) { + setLoadMore(false); + } + sortApps(null, null, driveDetails, true); } const loadObj = { isLoad: false @@ -143,15 +163,55 @@ function Opensigndrive() { isShow: true, alertMessage: "something went wrong!" }); + } finally { + setLoading(false); } }; + //function to fetch drive details list on scroll bottom + const handleScroll = () => { + //get document of render openSign-drive component using id + const documentList = document.getElementById("renderList"); + //documentList.clientHeight property returns the height of an element's content area, including padding but not including borders, margins, or scrollbars. + //documentList.scrollHeight property returns the entire height of an element,including the parts that are not visible due to overflow.. + // documentList.scrollTop property show height of element, how much the content has been scrolled from the top. + // When the sum of scrollTop and clientHeight is equal to scrollHeight, it means that the user has scrolled to the bottom of the div. + if ( + documentList && + documentList.scrollTop + documentList.clientHeight >= + documentList.scrollHeight + ) { + if (!loading && loadMore) { + //disableLoading + let disableLoading = true; + if (docId) { + getPdfFolderDocumentList(disableLoading); + } else { + getPdfDocumentList(disableLoading); + } + } + } + }; + //useEffect + useEffect(() => { + const documentList = document.getElementById("renderList"); + if (documentList) { + documentList.addEventListener("scroll", handleScroll); + return () => { + documentList.removeEventListener("scroll", handleScroll); + }; + } + // eslint-disable-next-line + }, [loading, loadMore]); // Add/remove scroll event listener when loading or hasMore changes //function for get all pdf document list const getParentFolder = async () => { setIsFolder(true); }; //function for handle folder name path const handleRoute = (index) => { + setPdfData([]); + setSkip(0); + setLoadMore(true); const updateFolderName = folderName.filter((x, i) => { if (i <= index) { return x; @@ -244,7 +304,7 @@ function Opensigndrive() { } }; - const sortApps = (type, order, driveDetails) => { + const sortApps = (type, order, driveDetails, isInitial) => { const selectedSortType = type ? type : selectedSort ? selectedSort : "Date"; const sortOrder = order ? order : sortingOrder ? sortingOrder : "Decending"; @@ -254,8 +314,11 @@ function Opensigndrive() { } else if (selectedSortType === "Date") { sortingApp(sortingData, "Date", sortOrder); } - - setPdfData(sortingData); + if (isInitial) { + setPdfData([...pdfData, ...sortingData]); + } else { + setPdfData(sortingData); + } }; //function for handle auto scroll on folder path @@ -322,6 +385,7 @@ function Opensigndrive() { // Cleanup the event listener when the component unmounts document.removeEventListener("click", closeMenuOnOutsideClick); }; + // eslint-disable-next-line }, [isShowSort, isNewFol]); const handleFolderTab = (folderData) => { @@ -755,7 +819,7 @@ function Opensigndrive() { No Data Found!
) : ( - }> + <> - + {loading && ( +
Loading...
+ )} + )} )} diff --git a/apps/OpenSignServer/cloud/parsefunction/getDrive.js b/apps/OpenSignServer/cloud/parsefunction/getDrive.js index 516ca9764..524b2f2b2 100644 --- a/apps/OpenSignServer/cloud/parsefunction/getDrive.js +++ b/apps/OpenSignServer/cloud/parsefunction/getDrive.js @@ -2,7 +2,8 @@ import axios from 'axios'; export default async function getDrive(request) { const serverUrl = process.env.SERVER_URL; const appId = process.env.APP_ID; - + const limit = request.params.limit; + const skip = request.params.skip; const classUrl = serverUrl + '/classes/contracts_Document'; const docId = request.params.docId; try { @@ -16,9 +17,9 @@ export default async function getDrive(request) { if (userId) { let url; if (docId) { - url = `${classUrl}?where={"Folder":{"__type":"Pointer","className":"contracts_Document","objectId":"${docId}"},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"},"IsArchive":{"$ne":true}}&include=ExtUserPtr,Signers,Folder`; + url = `${classUrl}?where={"Folder":{"__type":"Pointer","className":"contracts_Document","objectId":"${docId}"},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"},"IsArchive":{"$ne":true}}&include=ExtUserPtr,Signers,Folder&skip=${skip}&limit=${limit}`; } else { - url = `${classUrl}?where={"Folder":{"$exists":false},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"},"IsArchive":{"$ne":true}}&include=ExtUserPtr,Signers`; + url = `${classUrl}?where={"Folder":{"$exists":false},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"${userId}"},"IsArchive":{"$ne":true}}&include=ExtUserPtr,Signers&skip=${skip}&limit=${limit}`; } try { const res = await axios.get(url, { From c1e6f2b5ab3a3ff8d081a3db435a52e9b42d6ca0 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Wed, 20 Mar 2024 12:49:07 +0530 Subject: [PATCH 02/36] add comment --- apps/OpenSign/src/pages/Opensigndrive.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/OpenSign/src/pages/Opensigndrive.js b/apps/OpenSign/src/pages/Opensigndrive.js index 21ee616f9..0a14e79d5 100644 --- a/apps/OpenSign/src/pages/Opensigndrive.js +++ b/apps/OpenSign/src/pages/Opensigndrive.js @@ -191,7 +191,7 @@ function Opensigndrive() { } } }; - //useEffect + //useEffect is used to call handleScroll function on scrolling event useEffect(() => { const documentList = document.getElementById("renderList"); if (documentList) { From 58eb71c52da47a3252a5afd49495825aed0b1e03 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Wed, 20 Mar 2024 14:50:48 +0530 Subject: [PATCH 03/36] fix: refactor code --- .../src/components/opensigndrive/DriveBody.js | 7 +- apps/OpenSign/src/pages/Opensigndrive.js | 103 +++--------------- 2 files changed, 17 insertions(+), 93 deletions(-) diff --git a/apps/OpenSign/src/components/opensigndrive/DriveBody.js b/apps/OpenSign/src/components/opensigndrive/DriveBody.js index 11ad95a8f..ca9c254d2 100644 --- a/apps/OpenSign/src/components/opensigndrive/DriveBody.js +++ b/apps/OpenSign/src/components/opensigndrive/DriveBody.js @@ -43,16 +43,13 @@ function DriveBody(props) { objectId: data.objectId }; props.setFolderName((prev) => [...prev, folderData]); - const loadObj = { + props.setIsLoading({ isLoad: true, message: "This might take some time" - }; - - props.setIsLoading(loadObj); + }); props.setDocId(data.objectId); props.setPdfData([]); props.setSkip(0); - props.setLoadMore(true); }; //function for change doc name and update doc name in _document class const handledRenameDoc = async (data) => { diff --git a/apps/OpenSign/src/pages/Opensigndrive.js b/apps/OpenSign/src/pages/Opensigndrive.js index 0a14e79d5..cacd70314 100644 --- a/apps/OpenSign/src/pages/Opensigndrive.js +++ b/apps/OpenSign/src/pages/Opensigndrive.js @@ -54,7 +54,6 @@ function Opensigndrive() { const [skip, setSkip] = useState(0); const limit = 100; const [loading, setLoading] = useState(false); - const [loadMore, setLoadMore] = useState(true); const currentUser = localStorage.getItem( `Parse/${localStorage.getItem("parseAppId")}/currentUser` @@ -65,11 +64,7 @@ function Opensigndrive() { const jsonCurrentUser = JSON.parse(currentUser); useEffect(() => { - if (docId) { - getPdfFolderDocumentList(); - } else { - getPdfDocumentList(); - } + getPdfDocumentList(); // eslint-disable-next-line }, [docId]); @@ -77,42 +72,21 @@ function Opensigndrive() { const getPdfDocumentList = async (disbaleLoading) => { setLoading(true); if (!disbaleLoading) { - const load = { - isLoad: true, - message: "This might take some time" - }; - - setIsLoading(load); + setIsLoading({ isLoad: true, message: "This might take some time" }); } let driveDetails; try { - driveDetails = await getDrive(null, skip, limit); + driveDetails = await getDrive(docId, skip, limit); if (driveDetails) { if (driveDetails.length > 0) { setSkip((prevSkip) => prevSkip + limit); - // If the fetched data length is less than the limit, it means there's no more data to fetch - if (driveDetails.length < limit) { - setLoadMore(false); - } sortApps(null, null, driveDetails, true); } - const data = [ - { - name: "OpenSign™ Drive", - objectId: "" - } - ]; - setFolderName(data); - const loadObj = { - isLoad: false - }; - setIsLoading(loadObj); + if (!docId) { + setFolderName([{ name: "OpenSign™ Drive", objectId: "" }]); + } } else if (driveDetails === "Error: Something went wrong!") { - const loadObj = { - isLoad: false - }; setHandleError("Error: Something went wrong!"); - setIsLoading(loadObj); } } catch (e) { setIsAlert({ @@ -121,52 +95,12 @@ function Opensigndrive() { }); } finally { setLoading(false); - } - }; - - //function for get parent folder document list - const getPdfFolderDocumentList = async (disableLoading) => { - setLoading(true); - if (!disableLoading) { - const load = { - isLoad: true, - message: "This might take some time" - }; - setIsLoading(load); - } - - let driveDetails; - try { - driveDetails = await getDrive(docId, skip, limit); - if (driveDetails) { - if (driveDetails.length > 0) { - setSkip((prevSkip) => prevSkip + limit); - // If the fetched data length is less than the limit, it means there's no more data to fetch - if (driveDetails.length < limit) { - setLoadMore(false); - } - sortApps(null, null, driveDetails, true); - } - const loadObj = { - isLoad: false - }; - setIsLoading(loadObj); - } else if (driveDetails === "Error: Something went wrong!") { - const loadObj = { - isLoad: false - }; - setHandleError("Error: Something went wrong!"); - setIsLoading(loadObj); - } - } catch (e) { - setIsAlert({ - isShow: true, - alertMessage: "something went wrong!" + setIsLoading({ + isLoad: false }); - } finally { - setLoading(false); } }; + //function to fetch drive details list on scroll bottom const handleScroll = () => { //get document of render openSign-drive component using id @@ -180,14 +114,11 @@ function Opensigndrive() { documentList.scrollTop + documentList.clientHeight >= documentList.scrollHeight ) { - if (!loading && loadMore) { - //disableLoading - let disableLoading = true; - if (docId) { - getPdfFolderDocumentList(disableLoading); - } else { - getPdfDocumentList(disableLoading); - } + //disableLoading is used disable initial loader + let disableLoading = true; + // If the fetched data length is less than the limit, it means there's no more data to fetch + if (!loading && pdfData.length % 100 === 0) { + getPdfDocumentList(disableLoading); } } }; @@ -200,9 +131,8 @@ function Opensigndrive() { documentList.removeEventListener("scroll", handleScroll); }; } - // eslint-disable-next-line - }, [loading, loadMore]); // Add/remove scroll event listener when loading or hasMore changes + }, [loading]); // Add/remove scroll event listener when loading or hasMore changes //function for get all pdf document list const getParentFolder = async () => { setIsFolder(true); @@ -211,7 +141,6 @@ function Opensigndrive() { const handleRoute = (index) => { setPdfData([]); setSkip(0); - setLoadMore(true); const updateFolderName = folderName.filter((x, i) => { if (i <= index) { return x; @@ -825,14 +754,12 @@ function Opensigndrive() { setFolderName={setFolderName} setIsLoading={setIsLoading} setDocId={setDocId} - getPdfFolderDocumentList={getPdfFolderDocumentList} getPdfDocumentList={getPdfDocumentList} isDocId={docId} setPdfData={setPdfData} isList={isList} setIsAlert={setIsAlert} setSkip={setSkip} - setLoadMore={setLoadMore} /> {loading && (
Loading...
From 62e1a1bd9be70f22df002b91d25080119228e3a8 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Wed, 20 Mar 2024 15:02:08 +0530 Subject: [PATCH 04/36] fix: refactor code --- apps/OpenSign/src/pages/Opensigndrive.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/OpenSign/src/pages/Opensigndrive.js b/apps/OpenSign/src/pages/Opensigndrive.js index cacd70314..9fe4e3656 100644 --- a/apps/OpenSign/src/pages/Opensigndrive.js +++ b/apps/OpenSign/src/pages/Opensigndrive.js @@ -748,7 +748,7 @@ function Opensigndrive() { No Data Found!
) : ( - <> + }> Loading...
)} - + )} )} From c1b226db962bf64474aa7ce99887017aef080739 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Wed, 20 Mar 2024 15:59:06 +0530 Subject: [PATCH 05/36] fix: handle condition of fetching opensign details --- apps/OpenSign/src/pages/Opensigndrive.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/apps/OpenSign/src/pages/Opensigndrive.js b/apps/OpenSign/src/pages/Opensigndrive.js index 9fe4e3656..57c101fe4 100644 --- a/apps/OpenSign/src/pages/Opensigndrive.js +++ b/apps/OpenSign/src/pages/Opensigndrive.js @@ -77,16 +77,14 @@ function Opensigndrive() { let driveDetails; try { driveDetails = await getDrive(docId, skip, limit); - if (driveDetails) { - if (driveDetails.length > 0) { - setSkip((prevSkip) => prevSkip + limit); - sortApps(null, null, driveDetails, true); - } - if (!docId) { - setFolderName([{ name: "OpenSign™ Drive", objectId: "" }]); - } - } else if (driveDetails === "Error: Something went wrong!") { + if (driveDetails && driveDetails === "Error: Something went wrong!") { setHandleError("Error: Something went wrong!"); + } else if (driveDetails && driveDetails.length > 0) { + setSkip((prevSkip) => prevSkip + limit); + sortApps(null, null, driveDetails, true); + } + if (!docId) { + setFolderName([{ name: "OpenSign™ Drive", objectId: "" }]); } } catch (e) { setIsAlert({ @@ -146,7 +144,6 @@ function Opensigndrive() { return x; } }); - setFolderName(updateFolderName); const getLastId = updateFolderName[updateFolderName.length - 1]; setDocId(getLastId.objectId); From c2891a0858731221b2c6eb4ad992b17b49c70f21 Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Wed, 20 Mar 2024 16:43:56 +0530 Subject: [PATCH 06/36] refactor code --- apps/OpenSign/src/pages/Opensigndrive.js | 26 +++++++++--------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/apps/OpenSign/src/pages/Opensigndrive.js b/apps/OpenSign/src/pages/Opensigndrive.js index 57c101fe4..61bfed76d 100644 --- a/apps/OpenSign/src/pages/Opensigndrive.js +++ b/apps/OpenSign/src/pages/Opensigndrive.js @@ -74,14 +74,13 @@ function Opensigndrive() { if (!disbaleLoading) { setIsLoading({ isLoad: true, message: "This might take some time" }); } - let driveDetails; try { - driveDetails = await getDrive(docId, skip, limit); + const driveDetails = await getDrive(docId, skip, limit); if (driveDetails && driveDetails === "Error: Something went wrong!") { setHandleError("Error: Something went wrong!"); } else if (driveDetails && driveDetails.length > 0) { setSkip((prevSkip) => prevSkip + limit); - sortApps(null, null, driveDetails, true); + sortApps("Date", "Decending", driveDetails, true); } if (!docId) { setFolderName([{ name: "OpenSign™ Drive", objectId: "" }]); @@ -113,7 +112,7 @@ function Opensigndrive() { documentList.scrollHeight ) { //disableLoading is used disable initial loader - let disableLoading = true; + const disableLoading = true; // If the fetched data length is less than the limit, it means there's no more data to fetch if (!loading && pdfData.length % 100 === 0) { getPdfDocumentList(disableLoading); @@ -130,11 +129,8 @@ function Opensigndrive() { }; } // eslint-disable-next-line - }, [loading]); // Add/remove scroll event listener when loading or hasMore changes - //function for get all pdf document list - const getParentFolder = async () => { - setIsFolder(true); - }; + }, [loading]); // Add/remove scroll event listener when loading changes + //function for handle folder name path const handleRoute = (index) => { setPdfData([]); @@ -233,17 +229,15 @@ function Opensigndrive() { const sortApps = (type, order, driveDetails, isInitial) => { const selectedSortType = type ? type : selectedSort ? selectedSort : "Date"; const sortOrder = order ? order : sortingOrder ? sortingOrder : "Decending"; - - let sortingData = driveDetails; if (selectedSortType === "Name") { - sortingApp(sortingData, "Name", sortOrder); + sortingApp(driveDetails, "Name", sortOrder); } else if (selectedSortType === "Date") { - sortingApp(sortingData, "Date", sortOrder); + sortingApp(driveDetails, "Date", sortOrder); } if (isInitial) { - setPdfData([...pdfData, ...sortingData]); + setPdfData([...pdfData, ...driveDetails]); } else { - setPdfData(sortingData); + setPdfData(driveDetails); } }; @@ -553,7 +547,7 @@ function Opensigndrive() { > getParentFolder()} + onClick={() => setIsFolder(true)} > Date: Wed, 20 Mar 2024 19:14:20 +0530 Subject: [PATCH 07/36] feat: updated draft document query --- .../src/components/opensigndrive/DriveBody.js | 13 +------------ .../cloud/parsefunction/reportsJson.js | 13 +++---------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/apps/OpenSign/src/components/opensigndrive/DriveBody.js b/apps/OpenSign/src/components/opensigndrive/DriveBody.js index ca9c254d2..89241f54f 100644 --- a/apps/OpenSign/src/components/opensigndrive/DriveBody.js +++ b/apps/OpenSign/src/components/opensigndrive/DriveBody.js @@ -302,18 +302,7 @@ function DriveBody(props) { status = "Completed"; } else if (isDecline) { status = "Declined"; - } else if (!signerExist || signerExist?.length === 0) { - status = "Draft"; - } else if ( - signerExist?.length > 0 && - (!isPlaceholder || isPlaceholder?.length === 0) - ) { - status = "Draft"; - } else if ( - signerExist?.length > 0 && - isPlaceholder?.length > 0 && - !signedUrl - ) { + } else if (!signedUrl) { status = "Draft"; } else if (isExpire) { status = "Expired"; diff --git a/apps/OpenSignServer/cloud/parsefunction/reportsJson.js b/apps/OpenSignServer/cloud/parsefunction/reportsJson.js index 199210639..2aa126dd5 100644 --- a/apps/OpenSignServer/cloud/parsefunction/reportsJson.js +++ b/apps/OpenSignServer/cloud/parsefunction/reportsJson.js @@ -11,11 +11,7 @@ export default function reportJson(id, userId) { IsCompleted: { $ne: true }, IsDeclined: { $ne: true }, IsArchive: { $ne: true }, - $or: [ - { Signers: { $eq: [] } }, - { Signers: null }, - { Signers: { $exists: true }, Placeholders: null }, - ], + SignedUrl: { $exists: false }, CreatedBy: { __type: 'Pointer', className: '_User', @@ -33,6 +29,7 @@ export default function reportJson(id, userId) { 'Signers.Phone', ], }; + // Need your sign report case '4Hhwbp482K': return { @@ -273,11 +270,7 @@ export default function reportJson(id, userId) { IsCompleted: { $ne: true }, IsDeclined: { $ne: true }, IsArchive: { $ne: true }, - $or: [ - { Signers: { $eq: [] } }, - { Signers: null }, - { Signers: { $exists: true }, Placeholders: null }, - ], + SignedUrl: { $exists: false }, CreatedBy: { __type: 'Pointer', className: '_User', From af6cb4c17de6221417488644c21ab40e38c4181b Mon Sep 17 00:00:00 2001 From: RaktimaNXG Date: Thu, 21 Mar 2024 12:39:00 +0530 Subject: [PATCH 08/36] feat: implement dragging functionality on recipient's list to modify sequence of send-in-order during edit document --- .../src/components/opensigndrive/DriveBody.js | 3 +- .../src/components/pdf/PlaceholderType.js | 2 +- .../src/components/pdf/RecipientList.js | 83 ++++++++++++++++--- apps/OpenSign/src/pages/Form.js | 2 + apps/OpenSign/src/pages/PlaceHolderSign.js | 3 +- .../OpenSign/src/pages/TemplatePlaceholder.js | 4 +- 6 files changed, 80 insertions(+), 17 deletions(-) diff --git a/apps/OpenSign/src/components/opensigndrive/DriveBody.js b/apps/OpenSign/src/components/opensigndrive/DriveBody.js index 89241f54f..a550e8eef 100644 --- a/apps/OpenSign/src/components/opensigndrive/DriveBody.js +++ b/apps/OpenSign/src/components/opensigndrive/DriveBody.js @@ -280,14 +280,13 @@ function DriveBody(props) { //component to handle type of document and render according to type const handleFolderData = (data, ind, listType) => { - let createddate, status, isDecline, signerExist, isComplete, isPlaceholder; + let createddate, status, isDecline, signerExist, isComplete; if (data.Type !== "Folder") { const expireDate = data.ExpiryDate && data.ExpiryDate.iso; const createdDate = data.createdAt && data.createdAt; createddate = new Date(createdDate).toLocaleDateString(); isComplete = data.IsCompleted && data.IsCompleted ? true : false; isDecline = data.IsDeclined && data.IsDeclined; - isPlaceholder = data.Placeholders && data.Placeholders; signerExist = data.Signers && data.Signers; const signedUrl = data.SignedUrl; diff --git a/apps/OpenSign/src/components/pdf/PlaceholderType.js b/apps/OpenSign/src/components/pdf/PlaceholderType.js index 52137b19a..03e79efb6 100644 --- a/apps/OpenSign/src/components/pdf/PlaceholderType.js +++ b/apps/OpenSign/src/components/pdf/PlaceholderType.js @@ -443,7 +443,7 @@ function PlaceholderType(props) { > {/* Default/Title option */} {props.pos?.options?.values.map((data, ind) => { diff --git a/apps/OpenSign/src/components/pdf/RecipientList.js b/apps/OpenSign/src/components/pdf/RecipientList.js index a46519d49..0b413e09f 100644 --- a/apps/OpenSign/src/components/pdf/RecipientList.js +++ b/apps/OpenSign/src/components/pdf/RecipientList.js @@ -43,7 +43,8 @@ const RecipientList = (props) => { display: "flex", flexDirection: "row", borderBottom: "1px solid #e3e1e1", - alignItems: "center" + alignItems: "center", + cursor: props.sendInOrder && "move" }; return style; }; @@ -55,7 +56,8 @@ const RecipientList = (props) => { display: "flex", flexDirection: "row", borderBottom: "1px solid #e3e1e1", - alignItems: "center" + alignItems: "center", + cursor: props.sendInOrder && "move" }; return style; }; @@ -63,19 +65,61 @@ const RecipientList = (props) => { return props.signerPos.some((x) => x.Id === Id); }; + //handle drag start + const handleDragStart = (e, id) => { + // `e.dataTransfer.getData('text/plain')`is used to set the data to be transferred during a drag operation. + // The first argument specifies the type of data being set, and the second argument is the actual data you want to transfer. + e.dataTransfer.setData("text/plain", id); + }; + + //handleDragOver prevents the default behavior of the dragover event, which is necessary for the drop event to be triggered. + const handleDragOver = (e) => { + e.preventDefault(); + }; + + //handle draggable element drop + const handleDrop = (e, index) => { + e.preventDefault(); + //`e.dataTransfer.getData('text/plain')` is used to get data thet you have save. + const draggedItemId = e.dataTransfer.getData("text/plain"); + //convert string to number + const intDragId = parseInt(draggedItemId); + const draggedItem = props.signersdata.filter( + (item) => item.Id === intDragId + ); + const remainingItems = props.signersdata.filter( + (item) => item.Id !== intDragId + ); + //splice method is used to replace or add new value in array at specific index + remainingItems.splice(index, 0, ...draggedItem); + props.setSignersData(remainingItems); + + //set current draggable recipient details after replace recipient list + props.setSignerObjId(remainingItems[index]?.objectId || ""); + props.setIsSelectId(index); + props.setContractName(remainingItems[index]?.className || ""); + props.setUniqueId(remainingItems[index]?.Id); + props.setRoleName(remainingItems[index]?.Role); + }; return ( <> {props.signersdata.length > 0 && props.signersdata.map((obj, ind) => { return (
+ props.sendInOrder && handleDragStart(e, obj.Id) + } + onDragOver={(e) => props.sendInOrder && handleDragOver(e)} + onDrop={(e) => props.sendInOrder && handleDrop(e, ind, obj.Id)} data-tut="reactourFirst" onMouseEnter={() => setIsHover(ind)} onMouseLeave={() => setIsHover(null)} - key={ind} style={ isHover === ind || props.isSelectListId === ind - ? onHoverStyle(ind, obj.blockColor) + ? onHoverStyle(ind, obj?.blockColor) : nonHoverStyle(ind) } onClick={() => { @@ -100,8 +144,8 @@ const RecipientList = (props) => {
{ borderRadius: 30 / 2, justifyContent: "center", alignItems: "center", - marginRight: "12px" + marginRight: "12px", + cursor: props.sendInOrder && "move" }} > { textAlign: "center", fontWeight: "bold", color: "white", - textTransform: "uppercase" + textTransform: "uppercase", + cursor: props.sendInOrder && "move" }} > {isWidgetExist(obj.Id) ? ( @@ -136,11 +182,15 @@ const RecipientList = (props) => { style={{ display: "flex", flexDirection: obj.Name ? "column" : "row", - alignItems: "center" + alignItems: "center", + cursor: props.sendInOrder && "move" }} > {obj.Name ? ( - + {obj.Name} ) : ( @@ -179,13 +229,16 @@ const RecipientList = (props) => { )} {obj.Name && ( - + {obj.Role} )}
- {props.handleDeleteUser && ( + {props.handleDeleteUser ? (
{ e.stopPropagation(); @@ -195,6 +248,12 @@ const RecipientList = (props) => { >
+ ) : ( + props.sendInOrder && ( +
+ +
+ ) )}
diff --git a/apps/OpenSign/src/pages/Form.js b/apps/OpenSign/src/pages/Form.js index 24fa145d5..924542ae6 100644 --- a/apps/OpenSign/src/pages/Form.js +++ b/apps/OpenSign/src/pages/Form.js @@ -165,6 +165,8 @@ const Forms = (props) => { "TimeToCompleteDays", parseInt(formData?.TimeToCompleteDays) ); + } + if (props.title !== "Sign Yourself") { const isChecked = formData.SendinOrder === "true" ? true : false; object.set("SendinOrder", isChecked); } diff --git a/apps/OpenSign/src/pages/PlaceHolderSign.js b/apps/OpenSign/src/pages/PlaceHolderSign.js index 1d8496a80..07c3d401e 100644 --- a/apps/OpenSign/src/pages/PlaceHolderSign.js +++ b/apps/OpenSign/src/pages/PlaceHolderSign.js @@ -1372,7 +1372,6 @@ function PlaceHolderSign() { const closePopup = () => { setIsAddUser({}); }; - return ( <> @@ -1735,6 +1734,8 @@ function PlaceHolderSign() { setContractName={setContractName} setUniqueId={setUniqueId} setRoleName={setRoleName} + sendInOrder={pdfDetails[0].SendinOrder} + setSignersData={setSignersData} // handleAddSigner={handleAddSigner} /> <div data-tut="reactourSecond"> diff --git a/apps/OpenSign/src/pages/TemplatePlaceholder.js b/apps/OpenSign/src/pages/TemplatePlaceholder.js index c6069ac17..bc21458a2 100644 --- a/apps/OpenSign/src/pages/TemplatePlaceholder.js +++ b/apps/OpenSign/src/pages/TemplatePlaceholder.js @@ -446,7 +446,7 @@ const TemplatePlaceholder = () => { setIsCheckbox(true); } else if (dragTypeValue === radioButtonWidget) { setIsRadio(true); - } + } setCurrWidgetsDetails({}); setWidgetType(dragTypeValue); setSignKey(key); @@ -1466,6 +1466,8 @@ const TemplatePlaceholder = () => { handleRoleChange={handleRoleChange} handleOnBlur={handleOnBlur} title={"Roles"} + sendInOrder={pdfDetails[0]?.SendinOrder} + setSignersData={setSignersData} /> <div data-tut="reactourSecond"> <WidgetComponent From 365b074f622515d93c2a16ce12b76e8ff548a633 Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Thu, 21 Mar 2024 16:08:07 +0530 Subject: [PATCH 09/36] fix: change default value of send in order,dragging functionality to change sequence of signers list in mobile --- apps/OpenSign/src/assets/images/dragIcon.png | Bin 0 -> 185 bytes .../src/components/pdf/RecipientList.js | 97 ++++++------------ .../src/components/pdf/WidgetComponent.js | 52 ++++++---- apps/OpenSign/src/constant/Utils.js | 29 ++++++ apps/OpenSign/src/pages/Form.js | 4 +- apps/OpenSign/src/pages/PlaceHolderSign.js | 30 +++--- .../OpenSign/src/pages/TemplatePlaceholder.js | 13 +++ apps/OpenSign/src/styles/signature.css | 5 +- 8 files changed, 126 insertions(+), 104 deletions(-) create mode 100644 apps/OpenSign/src/assets/images/dragIcon.png diff --git a/apps/OpenSign/src/assets/images/dragIcon.png b/apps/OpenSign/src/assets/images/dragIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..fe6ec76e6e1783ffc9ee2a96b4cab70264d14a89 GIT binary patch literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX1|+Qw)-3{3oCO|{#S9GG!XV7ZFl&wkP%zum z#WAE}&f9B-Tnz>SE*JM6JL9UGJhOOavnz{W_l^$3n`v@6lb<b)3^1<bJm6&%?XYFu zWaUMrUNUcA+)<yNr_x>AAHUqCb^E_?rTT@_yxo9Ui6LT+en3~p@`V@Mf6RIDxBv5u d*A8d4GfU67^6+T3d=k)F22WQ%mvv4FO#qQ+LYe>o literal 0 HcmV?d00001 diff --git a/apps/OpenSign/src/components/pdf/RecipientList.js b/apps/OpenSign/src/components/pdf/RecipientList.js index 0b413e09f..10efff360 100644 --- a/apps/OpenSign/src/components/pdf/RecipientList.js +++ b/apps/OpenSign/src/components/pdf/RecipientList.js @@ -1,36 +1,14 @@ import React, { useRef, useState } from "react"; -import { darkenColor, getFirstLetter } from "../../constant/Utils"; +import { + color, + darkenColor, + getFirstLetter, + isMobile, + nameColor +} from "../../constant/Utils"; +import dragIcon from "../../assets/images/dragIcon.png"; const RecipientList = (props) => { - const color = [ - "#93a3db", - "#e6c3db", - "#c0e3bc", - "#bce3db", - "#b8ccdb", - "#ceb8db", - "#ffccff", - "#99ffcc", - "#cc99ff", - "#ffcc99", - "#66ccff", - "#ffffcc" - ]; - - const nameColor = [ - "#304fbf", - "#7d5270", - "#5f825b", - "#578077", - "#576e80", - "#6d527d", - "#cc00cc", - "#006666", - "#cc00ff", - "#ff9900", - "#336699", - "#cc9900" - ]; const [isHover, setIsHover] = useState(); const [isEdit, setIsEdit] = useState(false); //function for onhover signer name change background color @@ -43,8 +21,7 @@ const RecipientList = (props) => { display: "flex", flexDirection: "row", borderBottom: "1px solid #e3e1e1", - alignItems: "center", - cursor: props.sendInOrder && "move" + alignItems: "center" }; return style; }; @@ -56,8 +33,7 @@ const RecipientList = (props) => { display: "flex", flexDirection: "row", borderBottom: "1px solid #e3e1e1", - alignItems: "center", - cursor: props.sendInOrder && "move" + alignItems: "center" }; return style; }; @@ -100,6 +76,7 @@ const RecipientList = (props) => { props.setContractName(remainingItems[index]?.className || ""); props.setUniqueId(remainingItems[index]?.Id); props.setRoleName(remainingItems[index]?.Role); + props.setBlockColor(remainingItems[index]?.blockColor); }; return ( <> @@ -117,6 +94,7 @@ const RecipientList = (props) => { data-tut="reactourFirst" onMouseEnter={() => setIsHover(ind)} onMouseLeave={() => setIsHover(null)} + className={props.sendInOrder && "dragCursor"} style={ isHover === ind || props.isSelectListId === ind ? onHoverStyle(ind, obj?.blockColor) @@ -128,6 +106,7 @@ const RecipientList = (props) => { props.setContractName(obj?.className || ""); props.setUniqueId(obj.Id); props.setRoleName(obj.Role); + props.setBlockColor(obj?.blockColor); if (props.handleModal) { props.handleModal(); } @@ -142,7 +121,6 @@ const RecipientList = (props) => { }} > <div - className="signerStyle" style={{ background: obj?.blockColor ? darkenColor(obj?.blockColor, 0.4) @@ -153,18 +131,17 @@ const RecipientList = (props) => { borderRadius: 30 / 2, justifyContent: "center", alignItems: "center", - marginRight: "12px", - cursor: props.sendInOrder && "move" + marginRight: "12px" }} > <span + className={props.sendInOrder && "dragCursor"} style={{ fontSize: "12px", textAlign: "center", fontWeight: "bold", color: "white", - textTransform: "uppercase", - cursor: props.sendInOrder && "move" + textTransform: "uppercase" }} > {isWidgetExist(obj.Id) ? ( @@ -182,21 +159,16 @@ const RecipientList = (props) => { style={{ display: "flex", flexDirection: obj.Name ? "column" : "row", - alignItems: "center", - cursor: props.sendInOrder && "move" + alignItems: "center" }} > {obj.Name ? ( - <span - className="userName" - style={{ cursor: props.sendInOrder ? "move" : "default" }} - > - {obj.Name} - </span> + <span className={"userName"}>{obj.Name}</span> ) : ( <> <span className="userName" + style={{ cursor: "pointer" }} onClick={() => { setIsEdit({ [obj.Id]: true }); props.setRoleName(obj.Role); @@ -207,7 +179,8 @@ const RecipientList = (props) => { ref={inputRef} style={{ backgroundColor: "transparent", - width: "inherit" + width: "inherit", + padding: "3px" }} value={obj.Role} onChange={(e) => props.handleRoleChange(e, obj.Id)} @@ -228,32 +201,28 @@ const RecipientList = (props) => { </span> </> )} - {obj.Name && ( - <span - className="useEmail" - style={{ cursor: props.sendInOrder ? "move" : "default" }} - > - {obj.Role} - </span> - )} + {obj.Name && <span className={"useEmail"}>{obj.Role}</span>} </div> </div> - {props.handleDeleteUser ? ( + {isMobile && props.sendInOrder && ( + <div> + <img + alt="loader img" + src={dragIcon} + style={{ width: 20, height: 20 }} + /> + </div> + )} + {props.handleDeleteUser && ( <div onClick={(e) => { e.stopPropagation(); props.handleDeleteUser(obj.Id); }} - style={{ cursor: "pointer" }} + style={{ cursor: "pointer", marginLeft: "5px" }} > <i className="fa-regular fa-trash-can"></i> </div> - ) : ( - props.sendInOrder && ( - <div style={{ cursor: "pointer" }}> - <i className="fa-solid fa-ellipsis-vertical"></i> - </div> - ) )} <hr /> </div> diff --git a/apps/OpenSign/src/components/pdf/WidgetComponent.js b/apps/OpenSign/src/components/pdf/WidgetComponent.js index f59ca7117..1e1f61fe0 100644 --- a/apps/OpenSign/src/components/pdf/WidgetComponent.js +++ b/apps/OpenSign/src/components/pdf/WidgetComponent.js @@ -34,8 +34,11 @@ function WidgetComponent({ handleRoleChange, handleOnBlur, title, - - isTemplateFlow + setSignersData, + sendInOrder, + isTemplateFlow, + setBlockColor, + blockColor }) { const [isSignersModal, setIsSignersModal] = useState(false); @@ -239,8 +242,8 @@ function WidgetComponent({ const updateWidgets = isSignYourself ? filterWidgets : isTemplateFlow - ? textWidgetData - : widget; + ? textWidgetData + : widget; return ( <> @@ -256,9 +259,11 @@ function WidgetComponent({ <div data-tut={dataTut} style={{ - background: isSelectListId - ? color[isSelectListId % color.length] - : color[0], + background: blockColor + ? blockColor + : isSelectListId + ? color[isSelectListId % color.length] + : color[0], padding: "10px 20px", display: "flex", alignItems: "center", @@ -386,20 +391,25 @@ function WidgetComponent({ handleClose={handleModal} > {signersdata.length > 0 ? ( - <RecipientList - signerPos={signerPos} - signersdata={signersdata} - isSelectListId={isSelectListId} - setSignerObjId={setSignerObjId} - setIsSelectId={setIsSelectId} - setContractName={setContractName} - setUniqueId={setUniqueId} - setRoleName={setRoleName} - handleDeleteUser={handleDeleteUser} - handleRoleChange={handleRoleChange} - handleOnBlur={handleOnBlur} - handleModal={handleModal} - /> + <div style={{ maxHeight: "600px", overflow: "auto" }}> + <RecipientList + signerPos={signerPos} + signersdata={signersdata} + isSelectListId={isSelectListId} + setSignerObjId={setSignerObjId} + setIsSelectId={setIsSelectId} + setContractName={setContractName} + setUniqueId={setUniqueId} + setRoleName={setRoleName} + handleDeleteUser={handleDeleteUser} + handleRoleChange={handleRoleChange} + handleOnBlur={handleOnBlur} + handleModal={handleModal} + sendInOrder={sendInOrder} + setSignersData={setSignersData} + setBlockColor={setBlockColor} + /> + </div> ) : ( <div style={{ diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js index 5c986634f..883238dea 100644 --- a/apps/OpenSign/src/constant/Utils.js +++ b/apps/OpenSign/src/constant/Utils.js @@ -12,6 +12,35 @@ export const openInNewTab = (url) => { window.open(url, "_blank", "noopener,noreferrer"); }; +export const color = [ + "#93a3db", + "#e6c3db", + "#c0e3bc", + "#bce3db", + "#b8ccdb", + "#ceb8db", + "#ffccff", + "#99ffcc", + "#cc99ff", + "#ffcc99", + "#66ccff", + "#ffffcc" +]; + +export const nameColor = [ + "#304fbf", + "#7d5270", + "#5f825b", + "#578077", + "#576e80", + "#6d527d", + "#cc00cc", + "#006666", + "#cc00ff", + "#ff9900", + "#336699", + "#cc9900" +]; export const toDataUrl = (file) => { return new Promise((resolve) => { const reader = new FileReader(); diff --git a/apps/OpenSign/src/pages/Form.js b/apps/OpenSign/src/pages/Form.js index 924542ae6..1e2afcae9 100644 --- a/apps/OpenSign/src/pages/Form.js +++ b/apps/OpenSign/src/pages/Form.js @@ -167,7 +167,7 @@ const Forms = (props) => { ); } if (props.title !== "Sign Yourself") { - const isChecked = formData.SendinOrder === "true" ? true : false; + const isChecked = formData.SendinOrder === "false" ? false : true; object.set("SendinOrder", isChecked); } object.set("URL", fileupload); @@ -237,7 +237,7 @@ const Forms = (props) => { Description: "", Note: "Please review and sign this document", TimeToCompleteDays: 15, - SendinOrder: "false" + SendinOrder: "true" }); setFileUpload([]); setpercentage(0); diff --git a/apps/OpenSign/src/pages/PlaceHolderSign.js b/apps/OpenSign/src/pages/PlaceHolderSign.js index 07c3d401e..56a8c641b 100644 --- a/apps/OpenSign/src/pages/PlaceHolderSign.js +++ b/apps/OpenSign/src/pages/PlaceHolderSign.js @@ -27,7 +27,8 @@ import { addWidgetOptions, textInputWidget, textWidget, - radioButtonWidget + radioButtonWidget, + color } from "../constant/Utils"; import RenderPdf from "../components/pdf/RenderPdf"; import { useNavigate } from "react-router-dom"; @@ -80,6 +81,7 @@ function PlaceHolderSign() { const [zIndex, setZIndex] = useState(1); const [signKey, setSignKey] = useState(); const [tempSignerId, setTempSignerId] = useState(""); + const [blockColor, setBlockColor] = useState(""); const [pdfLoadFail, setPdfLoadFail] = useState({ status: false, type: "load" @@ -106,20 +108,6 @@ function PlaceHolderSign() { status: false, message: "" }); - const color = [ - "#93a3db", - "#e6c3db", - "#c0e3bc", - "#bce3db", - "#b8ccdb", - "#ceb8db", - "#ffccff", - "#99ffcc", - "#cc99ff", - "#ffcc99", - "#66ccff", - "#ffffcc" - ]; const isMobile = window.innerWidth < 767; const [, drop] = useDrop({ @@ -276,14 +264,17 @@ function PlaceHolderSign() { }); setSignersData(updatedSigners); setUniqueId(updatedSigners[0].Id); + setBlockColor(updatedSigners[0].blockColor); } else { const updatedSigners = documentData[0].Signers.map((x, index) => ({ ...x, Id: randomId(), - Role: "User " + (index + 1) + Role: "User " + (index + 1), + blockColor: color[index % color.length] })); setSignersData(updatedSigners); setUniqueId(updatedSigners[0].Id); + setBlockColor(updatedSigners[0].blockColor); } } else { setRoleName("User 1"); @@ -303,6 +294,7 @@ function PlaceHolderSign() { setSignersData(updatedSigners); setIsSelectId(0); setUniqueId(updatedSigners[0].Id); + setBlockColor(updatedSigners[0].blockColor); } } } else if ( @@ -1716,6 +1708,10 @@ function PlaceHolderSign() { setUniqueId={setUniqueId} setRoleName={setRoleName} initial={true} + sendInOrder={pdfDetails[0].SendinOrder} + setSignersData={setSignersData} + blockColor={blockColor} + setBlockColor={setBlockColor} /> </div> ) : ( @@ -1736,6 +1732,8 @@ function PlaceHolderSign() { setRoleName={setRoleName} sendInOrder={pdfDetails[0].SendinOrder} setSignersData={setSignersData} + blockColor={blockColor} + setBlockColor={setBlockColor} // handleAddSigner={handleAddSigner} /> <div data-tut="reactourSecond"> diff --git a/apps/OpenSign/src/pages/TemplatePlaceholder.js b/apps/OpenSign/src/pages/TemplatePlaceholder.js index bc21458a2..82fe4d40e 100644 --- a/apps/OpenSign/src/pages/TemplatePlaceholder.js +++ b/apps/OpenSign/src/pages/TemplatePlaceholder.js @@ -77,6 +77,7 @@ const TemplatePlaceholder = () => { const [showDropdown, setShowDropdown] = useState(false); const [widgetType, setWidgetType] = useState(""); const [isRadio, setIsRadio] = useState(false); + const [blockColor, setBlockColor] = useState(""); const [selectWidgetId, setSelectWidgetId] = useState(""); const [isNameModal, setIsNameModal] = useState(false); const [pdfLoadFail, setPdfLoadFail] = useState({ @@ -223,6 +224,7 @@ const TemplatePlaceholder = () => { }); setSignersData(updatedSigners); setUniqueId(updatedSigners[0].Id); + setBlockColor(updatedSigners[0].blockColor); } else { const updatedSigners = documentData[0].Signers.map((x, index) => ({ ...x, @@ -231,6 +233,7 @@ const TemplatePlaceholder = () => { })); setSignersData(updatedSigners); setUniqueId(updatedSigners[0].Id); + setBlockColor(updatedSigners[0].blockColor); } } else { setRoleName("User 1"); @@ -249,6 +252,7 @@ const TemplatePlaceholder = () => { setUniqueId(updatedSigners[0].Id); setSignersData(updatedSigners); setIsSelectId(0); + setBlockColor(updatedSigners[0].blockColor); } } } else if ( @@ -854,6 +858,7 @@ const TemplatePlaceholder = () => { setIsModalRole(false); setRoleName(""); setUniqueId(Id); + setBlockColor(color[index]); setIsSelectId(index); setIsMailSend(false); }; @@ -870,9 +875,11 @@ const TemplatePlaceholder = () => { if (index === signersdata.length - 1) { setUniqueId(updateSigner[updateSigner.length - 1]?.Id || ""); setIsSelectId(index - 1 || 0); + setBlockColor(color[index - 1 || 0]); } else { setUniqueId(updateSigner[index]?.Id || ""); setIsSelectId(index); + setBlockColor(color[index]); } setSignerPos(updatePlaceholderUser); @@ -1443,6 +1450,10 @@ const TemplatePlaceholder = () => { title={"Roles"} initial={true} isTemplateFlow={true} + sendInOrder={pdfDetails[0].SendinOrder} + setSignersData={setSignersData} + blockColor={blockColor} + setBlockColor={setBlockColor} /> </div> ) : ( @@ -1468,6 +1479,8 @@ const TemplatePlaceholder = () => { title={"Roles"} sendInOrder={pdfDetails[0]?.SendinOrder} setSignersData={setSignersData} + blockColor={blockColor} + setBlockColor={setBlockColor} /> <div data-tut="reactourSecond"> <WidgetComponent diff --git a/apps/OpenSign/src/styles/signature.css b/apps/OpenSign/src/styles/signature.css index c50fa7d8e..dfc877cdb 100644 --- a/apps/OpenSign/src/styles/signature.css +++ b/apps/OpenSign/src/styles/signature.css @@ -14,6 +14,9 @@ justify-content: center; border-width: 0.2px; } +.dragCursor{ + cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAX0lEQVR4nO3WMQrAIAxG4dzaUUfPVQ/2OtWhtFJoTJb/G10eSCAxk4+ABnRLiF56RjQmznM0Ji5ugIG/kRU+/L5G/kLDJbug4ZIMQFlsoJoRr1ujL/GY6O3ibPNBbO0E9P+irqa88kEAAAAASUVORK5CYII="),auto; +} .dropdownContainer { display: flex; @@ -301,7 +304,7 @@ z-index: 2; background: white; } - + .signCopy { position: absolute; From aa9ba05ddeb8d41e402c1cb1d4c4a5042664aa1a Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs <93375423+prafull-opensignlabs@users.noreply.github.com> Date: Thu, 21 Mar 2024 16:45:28 +0530 Subject: [PATCH 10/36] Update move cursor icon --- apps/OpenSign/src/styles/signature.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/OpenSign/src/styles/signature.css b/apps/OpenSign/src/styles/signature.css index dfc877cdb..447757e3a 100644 --- a/apps/OpenSign/src/styles/signature.css +++ b/apps/OpenSign/src/styles/signature.css @@ -15,7 +15,7 @@ border-width: 0.2px; } .dragCursor{ - cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAX0lEQVR4nO3WMQrAIAxG4dzaUUfPVQ/2OtWhtFJoTJb/G10eSCAxk4+ABnRLiF56RjQmznM0Ji5ugIG/kRU+/L5G/kLDJbug4ZIMQFlsoJoRr1ujL/GY6O3ibPNBbO0E9P+irqa88kEAAAAASUVORK5CYII="),auto; + cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAARUlEQVR4nGNgwAP+///f8P///w58aghphgHSDfmPBhgGL/hPIWCg2ICBB/9HwwAnoDi6/v//X46kv55kA6CGgHJkAz5FAC/MSs4ONuC0AAAAAElFTkSuQmCC"),auto; } .dropdownContainer { @@ -1237,4 +1237,4 @@ option { min-width: 78%; overflow-y: auto; } -} \ No newline at end of file +} From 29eb78c9606073baca9675cf3106ea23b0d27828 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs <93375423+prafull-opensignlabs@users.noreply.github.com> Date: Thu, 21 Mar 2024 17:01:18 +0530 Subject: [PATCH 11/36] Update signature.css --- apps/OpenSign/src/styles/signature.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/OpenSign/src/styles/signature.css b/apps/OpenSign/src/styles/signature.css index 447757e3a..89c470281 100644 --- a/apps/OpenSign/src/styles/signature.css +++ b/apps/OpenSign/src/styles/signature.css @@ -15,7 +15,7 @@ border-width: 0.2px; } .dragCursor{ - cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAARUlEQVR4nGNgwAP+///f8P///w58aghphgHSDfmPBhgGL/hPIWCg2ICBB/9HwwAnoDi6/v//X46kv55kA6CGgHJkAz5FAC/MSs4ONuC0AAAAAElFTkSuQmCC"),auto; + cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAABxElEQVR4nO2Z22rCQBCGf3LZQqWGHl4gF30ZFQ9BEcyNtbTFUtqLvkLfckFX0UaJ2vZK3ZQpW2iDh9wos3U/WEg2E/gn2f2jM4DFwpYMgBaAa31sFF6lUplIKVWn01F0THMwBK9Wq83m83n8w2KxiIMg+ARwBdPEm5SEt068CUkcl8vlKCmezlfNUSzdA0bcdLtdlRRar9dnNJJJ0MbWDsWGu36/r5LitfN4ySQolu4BIzKlUmlKT1YIsdRL5LdtejQnhPi21WKxSLZ6AmbQx6qtn+zRiuu05u91DDvxrMgCCAC8MBsNrW0jbqFQCGmtxswQQqh8Pv9GGjcl0KRNFjNFSknu1fzXCbj0msgKY2YIIZa5XG7rEoLeKLRhXpmNBoBTHAJZa6M7QFgbZYC0Ngpro3sha210BwhrowyQ1kZhbZQ15wAeAdyu6QfQb/kHAM8ALsGMMyrsjkYj1ev1VvUDPN/3J4PBQEVRRFW7dwAX4ILjOE9hGKYuLY7H49hxHHoTbGgPh8PUxV2K1RU6Nri+70/TltcpNs2f833jVavVNA2OD44Njq1JmCB+bRImif/TZqWujYlt1mSju2Vio9tyMHwBGSS45zv5FxgAAAAASUVORK5CYII="),auto; } .dropdownContainer { From 72c2b2dde6554bd3b0181598bc31d989ceb96ced Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs <93375423+prafull-opensignlabs@users.noreply.github.com> Date: Thu, 21 Mar 2024 17:11:56 +0530 Subject: [PATCH 12/36] change size of custom cursor icon --- apps/OpenSign/src/styles/signature.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/OpenSign/src/styles/signature.css b/apps/OpenSign/src/styles/signature.css index 89c470281..d1aaf3d7a 100644 --- a/apps/OpenSign/src/styles/signature.css +++ b/apps/OpenSign/src/styles/signature.css @@ -15,7 +15,7 @@ border-width: 0.2px; } .dragCursor{ - cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAABxElEQVR4nO2Z22rCQBCGf3LZQqWGHl4gF30ZFQ9BEcyNtbTFUtqLvkLfckFX0UaJ2vZK3ZQpW2iDh9wos3U/WEg2E/gn2f2jM4DFwpYMgBaAa31sFF6lUplIKVWn01F0THMwBK9Wq83m83n8w2KxiIMg+ARwBdPEm5SEt068CUkcl8vlKCmezlfNUSzdA0bcdLtdlRRar9dnNJJJ0MbWDsWGu36/r5LitfN4ySQolu4BIzKlUmlKT1YIsdRL5LdtejQnhPi21WKxSLZ6AmbQx6qtn+zRiuu05u91DDvxrMgCCAC8MBsNrW0jbqFQCGmtxswQQqh8Pv9GGjcl0KRNFjNFSknu1fzXCbj0msgKY2YIIZa5XG7rEoLeKLRhXpmNBoBTHAJZa6M7QFgbZYC0Ngpro3sha210BwhrowyQ1kZhbZQ15wAeAdyu6QfQb/kHAM8ALsGMMyrsjkYj1ev1VvUDPN/3J4PBQEVRRFW7dwAX4ILjOE9hGKYuLY7H49hxHHoTbGgPh8PUxV2K1RU6Nri+70/TltcpNs2f833jVavVNA2OD44Njq1JmCB+bRImif/TZqWujYlt1mSju2Vio9tyMHwBGSS45zv5FxgAAAAASUVORK5CYII="),auto; + cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAABxElEQVR4nO2Z22rCQBCGf3LZQqWGHl4gF30ZFQ9BEcyNtbTFUtqLvkLfckFX0UaJ2vZK3ZQpW2iDh9wos3U/WEg2E/gn2f2jM4DFwpYMgBaAa31sFF6lUplIKVWn01F0THMwBK9Wq83m83n8w2KxiIMg+ARwBdPEm5SEt068CUkcl8vlKCmezlfNUSzdA0bcdLtdlRRar9dnNJJJ0MbWDsWGu36/r5LitfN4ySQolu4BIzKlUmlKT1YIsdRL5LdtejQnhPi21WKxSLZ6AmbQx6qtn+zRiuu05u91DDvxrMgCCAC8MBsNrW0jbqFQCGmtxswQQqh8Pv9GGjcl0KRNFjNFSknu1fzXCbj0msgKY2YIIZa5XG7rEoLeKLRhXpmNBoBTHAJZa6M7QFgbZYC0Ngpro3sha210BwhrowyQ1kZhbZQ15wAeAdyu6QfQb/kHAM8ALsGMMyrsjkYj1ev1VvUDPN/3J4PBQEVRRFW7dwAX4ILjOE9hGKYuLY7H49hxHHoTbGgPh8PUxV2K1RU6Nri+70/TltcpNs2f833jVavVNA2OD44Njq1JmCB+bRImif/TZqWujYlt1mSju2Vio9tyMHwBGSS45zv5FxgAAAAASUVORK5CYII=") 18 18,auto; } .dropdownContainer { From 2c616300178ec249c7f245b8deb3f18869e880d1 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs <93375423+prafull-opensignlabs@users.noreply.github.com> Date: Thu, 21 Mar 2024 17:19:25 +0530 Subject: [PATCH 13/36] Update signature.css --- apps/OpenSign/src/styles/signature.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/OpenSign/src/styles/signature.css b/apps/OpenSign/src/styles/signature.css index d1aaf3d7a..5e1f39f42 100644 --- a/apps/OpenSign/src/styles/signature.css +++ b/apps/OpenSign/src/styles/signature.css @@ -15,7 +15,7 @@ border-width: 0.2px; } .dragCursor{ - cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAABxElEQVR4nO2Z22rCQBCGf3LZQqWGHl4gF30ZFQ9BEcyNtbTFUtqLvkLfckFX0UaJ2vZK3ZQpW2iDh9wos3U/WEg2E/gn2f2jM4DFwpYMgBaAa31sFF6lUplIKVWn01F0THMwBK9Wq83m83n8w2KxiIMg+ARwBdPEm5SEt068CUkcl8vlKCmezlfNUSzdA0bcdLtdlRRar9dnNJJJ0MbWDsWGu36/r5LitfN4ySQolu4BIzKlUmlKT1YIsdRL5LdtejQnhPi21WKxSLZ6AmbQx6qtn+zRiuu05u91DDvxrMgCCAC8MBsNrW0jbqFQCGmtxswQQqh8Pv9GGjcl0KRNFjNFSknu1fzXCbj0msgKY2YIIZa5XG7rEoLeKLRhXpmNBoBTHAJZa6M7QFgbZYC0Ngpro3sha210BwhrowyQ1kZhbZQ15wAeAdyu6QfQb/kHAM8ALsGMMyrsjkYj1ev1VvUDPN/3J4PBQEVRRFW7dwAX4ILjOE9hGKYuLY7H49hxHHoTbGgPh8PUxV2K1RU6Nri+70/TltcpNs2f833jVavVNA2OD44Njq1JmCB+bRImif/TZqWujYlt1mSju2Vio9tyMHwBGSS45zv5FxgAAAAASUVORK5CYII=") 18 18,auto; + cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAASFBMVEVHcEzU1NShoaHZ2dkAAAC8vLylpaV9fX3u7u5ZWVnw8PCAgIBra2uurq63t7e2trZ1dXXR0dF5eXnT09Ovr6/S0tIArGXu7u7KmXzuAAAAFnRSTlMAx5HDBaKOPPMV8UslfJCPZ9Ri1XzVO1WbSQAAAGZJREFUGNN9j90OgCAIha08paGlVvP93zTU2nBtfRcw/g6gVENr1WH3zXYxcobMuAhE91YXJhGl4rlLw6yMaRasTaOAuMNPglNzYhD4MjILqIoKimhdG4jCs7YddgGH+zv985x4/wZrBwSQ37Wh/wAAAABJRU5ErkJggg=="),auto; } .dropdownContainer { From 0512f27e2e9a3ecc5f063bbe6241b511de99ac5d Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Thu, 21 Mar 2024 17:41:48 +0530 Subject: [PATCH 14/36] change drag icon --- apps/OpenSign/src/styles/signature.css | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/OpenSign/src/styles/signature.css b/apps/OpenSign/src/styles/signature.css index 5e1f39f42..5b1543298 100644 --- a/apps/OpenSign/src/styles/signature.css +++ b/apps/OpenSign/src/styles/signature.css @@ -14,8 +14,9 @@ justify-content: center; border-width: 0.2px; } -.dragCursor{ - cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAASFBMVEVHcEzU1NShoaHZ2dkAAAC8vLylpaV9fX3u7u5ZWVnw8PCAgIBra2uurq63t7e2trZ1dXXR0dF5eXnT09Ovr6/S0tIArGXu7u7KmXzuAAAAFnRSTlMAx5HDBaKOPPMV8UslfJCPZ9Ri1XzVO1WbSQAAAGZJREFUGNN9j90OgCAIha08paGlVvP93zTU2nBtfRcw/g6gVENr1WH3zXYxcobMuAhE91YXJhGl4rlLw6yMaRasTaOAuMNPglNzYhD4MjILqIoKimhdG4jCs7YddgGH+zv985x4/wZrBwSQ37Wh/wAAAABJRU5ErkJggg=="),auto; + +.dragCursor { + cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAASElEQVR4nGNgwAMkJSUbpKSkOvCpIaT5PxSTbogUQjMYMwxeIIXmVFIxA8UGDDyQGg0DnIDi6JKUlCxHMqCeZAOghjSAMD5FAKfeaURdUFxCAAAAAElFTkSuQmCC"), auto; } .dropdownContainer { @@ -304,7 +305,7 @@ z-index: 2; background: white; } - + .signCopy { position: absolute; @@ -1237,4 +1238,4 @@ option { min-width: 78%; overflow-y: auto; } -} +} \ No newline at end of file From 126b6ad3556891a023fe761c1a316de476beea82 Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Thu, 21 Mar 2024 18:01:02 +0530 Subject: [PATCH 15/36] fix: change text-input widget to text in signyour-self flow --- apps/OpenSign/src/components/pdf/WidgetComponent.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/OpenSign/src/components/pdf/WidgetComponent.js b/apps/OpenSign/src/components/pdf/WidgetComponent.js index f59ca7117..c40c029a8 100644 --- a/apps/OpenSign/src/components/pdf/WidgetComponent.js +++ b/apps/OpenSign/src/components/pdf/WidgetComponent.js @@ -233,14 +233,14 @@ function WidgetComponent({ (data) => data.type !== "dropdown" && data.type !== radioButtonWidget && - data.type !== textWidget + data.type !== textInputWidget ); const textWidgetData = widget.filter((data) => data.type !== textWidget); const updateWidgets = isSignYourself ? filterWidgets : isTemplateFlow - ? textWidgetData - : widget; + ? textWidgetData + : widget; return ( <> From 648d1224b3df71f801a148cf66005d7100b6dfcc Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Thu, 21 Mar 2024 18:30:46 +0530 Subject: [PATCH 16/36] fix: disable default menu open on press on drag icon in mobile view --- apps/OpenSign/src/components/pdf/RecipientList.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/apps/OpenSign/src/components/pdf/RecipientList.js b/apps/OpenSign/src/components/pdf/RecipientList.js index 10efff360..2cdb4679d 100644 --- a/apps/OpenSign/src/components/pdf/RecipientList.js +++ b/apps/OpenSign/src/components/pdf/RecipientList.js @@ -205,13 +205,12 @@ const RecipientList = (props) => { </div> </div> {isMobile && props.sendInOrder && ( - <div> - <img - alt="loader img" - src={dragIcon} - style={{ width: 20, height: 20 }} - /> - </div> + <img + alt="loader img" + src={dragIcon} + style={{ width: 20, height: 20 }} + onContextMenu={(e) => e.preventDefault()} + /> )} {props.handleDeleteUser && ( <div From 8684197d49606b838867f2966ae0c975157ee98b Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Fri, 22 Mar 2024 11:55:55 +0530 Subject: [PATCH 17/36] fix: drag icon image select issue in ios --- apps/OpenSign/src/components/pdf/RecipientList.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/apps/OpenSign/src/components/pdf/RecipientList.js b/apps/OpenSign/src/components/pdf/RecipientList.js index 2cdb4679d..bfc266e88 100644 --- a/apps/OpenSign/src/components/pdf/RecipientList.js +++ b/apps/OpenSign/src/components/pdf/RecipientList.js @@ -111,6 +111,17 @@ const RecipientList = (props) => { props.handleModal(); } }} + onTouchEnd={(e) => { + props.setSignerObjId(obj?.objectId || ""); + props.setIsSelectId(ind); + props.setContractName(obj?.className || ""); + props.setUniqueId(obj.Id); + props.setRoleName(obj.Role); + props.setBlockColor(obj?.blockColor); + if (props.handleModal) { + props.handleModal(); + } + }} > <div style={{ @@ -208,8 +219,11 @@ const RecipientList = (props) => { <img alt="loader img" src={dragIcon} + className="widgets" style={{ width: 20, height: 20 }} onContextMenu={(e) => e.preventDefault()} + draggable="false" + onTouchEnd={(e) => e.preventDefault()} /> )} {props.handleDeleteUser && ( From bf70fa0b11208889ea2ad5520452eca19735810f Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Fri, 22 Mar 2024 12:01:27 +0530 Subject: [PATCH 18/36] fix: drag icon image select issue in ios --- apps/OpenSign/src/components/pdf/RecipientList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/OpenSign/src/components/pdf/RecipientList.js b/apps/OpenSign/src/components/pdf/RecipientList.js index bfc266e88..3a6759fe3 100644 --- a/apps/OpenSign/src/components/pdf/RecipientList.js +++ b/apps/OpenSign/src/components/pdf/RecipientList.js @@ -223,7 +223,7 @@ const RecipientList = (props) => { style={{ width: 20, height: 20 }} onContextMenu={(e) => e.preventDefault()} draggable="false" - onTouchEnd={(e) => e.preventDefault()} + onTouchStart={(e) => e.preventDefault()} /> )} {props.handleDeleteUser && ( From ed613c34243a861a2c6015c1a5a24d83fd900f0d Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Fri, 22 Mar 2024 12:30:53 +0530 Subject: [PATCH 19/36] fix: set default option field value oftextInput widget issue in signyourself --- apps/OpenSign/src/pages/SignyourselfPdf.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/OpenSign/src/pages/SignyourselfPdf.js b/apps/OpenSign/src/pages/SignyourselfPdf.js index 1d4803e9f..078aca580 100644 --- a/apps/OpenSign/src/pages/SignyourselfPdf.js +++ b/apps/OpenSign/src/pages/SignyourselfPdf.js @@ -26,7 +26,7 @@ import { contactBook, randomId, getDate, - textInputWidget + textWidget } from "../constant/Utils"; import { useParams } from "react-router-dom"; import Tour from "reactour"; @@ -342,8 +342,7 @@ function SignYourSelf() { return { name: "checkbox" }; - - case textInputWidget: + case textWidget: return { name: "text" }; @@ -528,7 +527,6 @@ function SignYourSelf() { checkSigned = requiredWidgets[i]?.options?.response; if (!checkSigned) { const checkSignUrl = requiredWidgets[i]?.pos?.SignUrl; - let checkDefaultSigned = requiredWidgets[i]?.options?.defaultValue; if (!checkSignUrl) { if (!checkDefaultSigned) { @@ -587,11 +585,12 @@ function SignYourSelf() { flag, containerWH ); - // console.log('pdf',pdfBytes) + // console.log("pdf", pdfBytes); //function for call to embed signature in pdf and get digital signature pdf await signPdfFun(pdfBytes, documentId); } } + // console.log("signyourself", xyPostion); //function for get digital signature const signPdfFun = async (base64Url, documentId) => { let singleSign = { From 99b3436c8cd7899ec558178d2bdbd88d0e14e42f Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Fri, 22 Mar 2024 16:29:08 +0530 Subject: [PATCH 20/36] feat: add up and down key to change sequence of recipient's list --- apps/OpenSign/package-lock.json | 6 + apps/OpenSign/package.json | 1 + apps/OpenSign/src/assets/images/dragIcon.png | Bin 185 -> 0 bytes .../src/components/pdf/RecipientList.js | 112 ++++++++++++------ 4 files changed, 81 insertions(+), 38 deletions(-) delete mode 100644 apps/OpenSign/src/assets/images/dragIcon.png diff --git a/apps/OpenSign/package-lock.json b/apps/OpenSign/package-lock.json index b9ebab7a7..fd8283e31 100644 --- a/apps/OpenSign/package-lock.json +++ b/apps/OpenSign/package-lock.json @@ -8,6 +8,7 @@ "name": "open_sign", "version": "0.1.0", "dependencies": { + "@formkit/auto-animate": "^0.8.1", "@radix-ui/themes": "^2.0.3", "@react-pdf/renderer": "^3.4.0", "@reduxjs/toolkit": "^2.2.1", @@ -2984,6 +2985,11 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==" }, + "node_modules/@formkit/auto-animate": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-0.8.1.tgz", + "integrity": "sha512-0/Z2cuNXWVVIG/l0SpcHAWFhGdvLJ8DRvEfRWvmojtmRWfEy+LWNwgDazbZqY0qQYtkHcoEK3jBLkhiZaB/4Ig==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", diff --git a/apps/OpenSign/package.json b/apps/OpenSign/package.json index 11127525c..c225dc77e 100644 --- a/apps/OpenSign/package.json +++ b/apps/OpenSign/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@formkit/auto-animate": "^0.8.1", "@radix-ui/themes": "^2.0.3", "@react-pdf/renderer": "^3.4.0", "@reduxjs/toolkit": "^2.2.1", diff --git a/apps/OpenSign/src/assets/images/dragIcon.png b/apps/OpenSign/src/assets/images/dragIcon.png deleted file mode 100644 index fe6ec76e6e1783ffc9ee2a96b4cab70264d14a89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX1|+Qw)-3{3oCO|{#S9GG!XV7ZFl&wkP%zum z#WAE}&f9B-Tnz>SE*JM6JL9UGJhOOavnz{W_l^$3n`v@6lb<b)3^1<bJm6&%?XYFu zWaUMrUNUcA+)<yNr_x>AAHUqCb^E_?rTT@_yxo9Ui6LT+en3~p@`V@Mf6RIDxBv5u d*A8d4GfU67^6+T3d=k)F22WQ%mvv4FO#qQ+LYe>o diff --git a/apps/OpenSign/src/components/pdf/RecipientList.js b/apps/OpenSign/src/components/pdf/RecipientList.js index 3a6759fe3..60f28e22a 100644 --- a/apps/OpenSign/src/components/pdf/RecipientList.js +++ b/apps/OpenSign/src/components/pdf/RecipientList.js @@ -1,4 +1,5 @@ import React, { useRef, useState } from "react"; +import { useAutoAnimate } from "@formkit/auto-animate/react"; import { color, darkenColor, @@ -6,9 +7,9 @@ import { isMobile, nameColor } from "../../constant/Utils"; -import dragIcon from "../../assets/images/dragIcon.png"; const RecipientList = (props) => { + const [animationParent] = useAutoAnimate(); const [isHover, setIsHover] = useState(); const [isEdit, setIsEdit] = useState(false); //function for onhover signer name change background color @@ -53,24 +54,39 @@ const RecipientList = (props) => { e.preventDefault(); }; - //handle draggable element drop - const handleDrop = (e, index) => { + //handle draggable element drop and also used in mobile view on up and down key to chnage sequence of recipient's list + const handleChangeSequence = (e, ind, isUp, isDown) => { e.preventDefault(); - //`e.dataTransfer.getData('text/plain')` is used to get data thet you have save. - const draggedItemId = e.dataTransfer.getData("text/plain"); + let draggedItemId; + let index = ind; + + //if isUp true then set item's id and index in mobile view + if (isUp) { + draggedItemId = index; + index = index - 1; + } + //if isDown true then set item's id and index in mobile view + else if (isDown) { + draggedItemId = index; + index = index + 1; + } //else set id on drag element in desktop viiew + else { + //`e.dataTransfer.getData('text/plain')` is used to get data that you have saved. + draggedItemId = e.dataTransfer.getData("text/plain"); + } + //convert string to number const intDragId = parseInt(draggedItemId); - const draggedItem = props.signersdata.filter( - (item) => item.Id === intDragId - ); + //get that item to change position + const draggedItem = props.signersdata.filter((_, ind) => ind === intDragId); const remainingItems = props.signersdata.filter( - (item) => item.Id !== intDragId + (_, ind) => ind !== intDragId ); //splice method is used to replace or add new value in array at specific index remainingItems.splice(index, 0, ...draggedItem); - props.setSignersData(remainingItems); - //set current draggable recipient details after replace recipient list + //set current draggable recipient details,objectId,index,contract_className ... after replace recipient list + props.setSignersData(remainingItems); props.setSignerObjId(remainingItems[index]?.objectId || ""); props.setIsSelectId(index); props.setContractName(remainingItems[index]?.className || ""); @@ -78,40 +94,36 @@ const RecipientList = (props) => { props.setRoleName(remainingItems[index]?.Role); props.setBlockColor(remainingItems[index]?.blockColor); }; + return ( <> {props.signersdata.length > 0 && props.signersdata.map((obj, ind) => { return ( <div + ref={animationParent} key={ind} - draggable={props.sendInOrder ? true : false} + draggable={props.sendInOrder && !isMobile ? true : false} onDragStart={(e) => - props.sendInOrder && handleDragStart(e, obj.Id) + props.sendInOrder && !isMobile && handleDragStart(e, ind) + } + onDragOver={(e) => + props.sendInOrder && !isMobile && handleDragOver(e) + } + onDrop={(e) => + props.sendInOrder && !isMobile && handleChangeSequence(e, ind) } - onDragOver={(e) => props.sendInOrder && handleDragOver(e)} - onDrop={(e) => props.sendInOrder && handleDrop(e, ind, obj.Id)} data-tut="reactourFirst" onMouseEnter={() => setIsHover(ind)} onMouseLeave={() => setIsHover(null)} className={props.sendInOrder && "dragCursor"} style={ - isHover === ind || props.isSelectListId === ind + (!isMobile && isHover === ind) || props.isSelectListId === ind ? onHoverStyle(ind, obj?.blockColor) : nonHoverStyle(ind) } - onClick={() => { - props.setSignerObjId(obj?.objectId || ""); - props.setIsSelectId(ind); - props.setContractName(obj?.className || ""); - props.setUniqueId(obj.Id); - props.setRoleName(obj.Role); - props.setBlockColor(obj?.blockColor); - if (props.handleModal) { - props.handleModal(); - } - }} - onTouchEnd={(e) => { + onClick={(e) => { + e.preventDefault(); props.setSignerObjId(obj?.objectId || ""); props.setIsSelectId(ind); props.setContractName(obj?.className || ""); @@ -207,7 +219,7 @@ const RecipientList = (props) => { }} /> ) : ( - obj.Role + <span style={{ padding: "3px" }}>{obj.Role}</span> )} </span> </> @@ -216,15 +228,39 @@ const RecipientList = (props) => { </div> </div> {isMobile && props.sendInOrder && ( - <img - alt="loader img" - src={dragIcon} - className="widgets" - style={{ width: 20, height: 20 }} - onContextMenu={(e) => e.preventDefault()} - draggable="false" - onTouchStart={(e) => e.preventDefault()} - /> + <div + style={{ + display: "flex", + flexDirection: "row", + alignItems: "center" + }} + > + <div + onClick={(e) => { + if (ind !== 0) { + e.stopPropagation(); + handleChangeSequence(e, ind, "up"); + } + }} + style={{ color: ind === 0 ? "gray" : "black" }} + > + ▲ + </div> + <div + onClick={(e) => { + if (ind !== props.signersdata.length - 1) { + e.stopPropagation(); + handleChangeSequence(e, ind, null, "down"); + } + }} + style={{ + color: + ind === props.signersdata.length - 1 ? "gray" : "black" + }} + > + ▼ + </div> + </div> )} {props.handleDeleteUser && ( <div From d9da25e9080c1169fdde2f2379641d6ea6bd4146 Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Fri, 22 Mar 2024 16:42:51 +0530 Subject: [PATCH 21/36] fix: increase gap between up and down arrow icon --- apps/OpenSign/src/components/pdf/RecipientList.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/OpenSign/src/components/pdf/RecipientList.js b/apps/OpenSign/src/components/pdf/RecipientList.js index 60f28e22a..08643b388 100644 --- a/apps/OpenSign/src/components/pdf/RecipientList.js +++ b/apps/OpenSign/src/components/pdf/RecipientList.js @@ -232,7 +232,8 @@ const RecipientList = (props) => { style={{ display: "flex", flexDirection: "row", - alignItems: "center" + alignItems: "center", + gap: 5 }} > <div From 4f056cc9d3379be734477e1bb7169b2ab997ddfd Mon Sep 17 00:00:00 2001 From: Raktima <110812506+raktima-opensignlabs@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:06:18 +0530 Subject: [PATCH 22/36] Update RecipientList.js --- apps/OpenSign/src/components/pdf/RecipientList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/OpenSign/src/components/pdf/RecipientList.js b/apps/OpenSign/src/components/pdf/RecipientList.js index 08643b388..e608da1f8 100644 --- a/apps/OpenSign/src/components/pdf/RecipientList.js +++ b/apps/OpenSign/src/components/pdf/RecipientList.js @@ -44,7 +44,7 @@ const RecipientList = (props) => { //handle drag start const handleDragStart = (e, id) => { - // `e.dataTransfer.getData('text/plain')`is used to set the data to be transferred during a drag operation. + // `e.dataTransfer.setData('text/plain')`is used to set the data to be transferred during a drag operation. // The first argument specifies the type of data being set, and the second argument is the actual data you want to transfer. e.dataTransfer.setData("text/plain", id); }; From 276fc974fae11fd4632ea3ddf1546d48e3b089d1 Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Fri, 22 Mar 2024 21:20:49 +0530 Subject: [PATCH 23/36] fix: change dashboard icon of signyour-self & request sign,other minor issue fixed --- .../src/components/dashboard/GetDashboard.js | 11 +- apps/OpenSign/src/components/pdf/SignPad.js | 112 +++++++++++------- apps/OpenSign/src/pages/PlaceHolderSign.js | 2 +- 3 files changed, 76 insertions(+), 49 deletions(-) diff --git a/apps/OpenSign/src/components/dashboard/GetDashboard.js b/apps/OpenSign/src/components/dashboard/GetDashboard.js index 5d8ed5989..c78abcb01 100644 --- a/apps/OpenSign/src/components/dashboard/GetDashboard.js +++ b/apps/OpenSign/src/components/dashboard/GetDashboard.js @@ -6,16 +6,18 @@ const buttonList = [ { label: "Sign yourself", redirectId: "sHAnZphf69", - redirectType: "Form" + redirectType: "Form", + icon: "fas fa-pen-nib" }, { label: "Request signature", redirectId: "8mZzFxbG1z", - redirectType: "Form" + redirectType: "Form", + icon: "fa-solid fa-paper-plane" } ]; const GetDashboard = (props) => { - const Button = ({ label, redirectId, redirectType }) => ( + const Button = ({ label, redirectId, redirectType, icon }) => ( <div className={"bg-white rounded-md shadow w-full"}> <Suspense fallback={ @@ -33,7 +35,7 @@ const GetDashboard = (props) => { } > <DashboardButton - Icon={"fa-solid fa-plus"} + Icon={icon} Label={label} Data={{ Redirect_type: redirectType, Redirect_id: redirectId }} /> @@ -136,6 +138,7 @@ const GetDashboard = (props) => { label={btn.label} redirectType={btn.redirectType} redirectId={btn.redirectId} + icon={btn.icon} /> ))} </div> diff --git a/apps/OpenSign/src/components/pdf/SignPad.js b/apps/OpenSign/src/components/pdf/SignPad.js index 6557ecd7e..719bafac1 100644 --- a/apps/OpenSign/src/components/pdf/SignPad.js +++ b/apps/OpenSign/src/components/pdf/SignPad.js @@ -76,7 +76,6 @@ function SignPad({ }; //function for set signature url const handleSignatureChange = () => { - // canvasRef.current.backgroundColor = 'rgb(165, 26, 26)' setSignature(canvasRef.current.toDataURL()); setIsSignImg(canvasRef.current.toDataURL()); }; @@ -114,7 +113,6 @@ function SignPad({ setIsSignImg(""); onSaveSign(false, textWidth, textHeight); } else { - setIsSignImg(""); onSaveSign(); } } @@ -153,6 +151,18 @@ function SignPad({ ); }; + useEffect(() => { + if (canvasRef.current && isSignImg) { + canvasRef.current.fromDataURL(isSignImg); + } + const trimmedName = currentUserName.trim(); + const firstCharacter = trimmedName.charAt(0); + const userName = isInitial ? firstCharacter : currentUserName; + setSignValue(userName); + setFontSelect("Fasthand"); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isSignPad]); useEffect(() => { const loadFont = async () => { try { @@ -186,7 +196,7 @@ function SignPad({ }, [isTab]); //function for convert input text value in image - const convertToImg = async (fontStyle, text) => { + const convertToImg = async (fontStyle, text, color) => { //get text content to convert in image const textContent = text; const fontfamily = fontStyle @@ -199,6 +209,7 @@ function SignPad({ const span = document.createElement("span"); span.textContent = textContent; span.style.font = `20px ${fontfamily}`; // here put your text size and font family + span.style.color = color ? color : penColor; span.style.display = "hidden"; document.body.appendChild(span); // Replace 'container' with the ID of the container element @@ -216,13 +227,9 @@ function SignPad({ canvasElement.width = width * pixelRatio; canvasElement.height = height * pixelRatio; - // Render the content of the span onto the canvas - // ctx.fillStyle = "white"; // Set the background color of the canvas - // ctx.fillRect(0, 0, width*pixelRatio, height*pixelRatio); - // You can customize text styles if needed ctx.font = font; - ctx.fillStyle = "black"; // Set the text color + ctx.fillStyle = color ? color : penColor; // Set the text color ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.scale(pixelRatio, pixelRatio); @@ -235,6 +242,44 @@ function SignPad({ setSignature(dataUrl); }; + const PenColorComponent = (props) => { + return ( + <div style={{ display: "flex", flexDirection: "row" }}> + {allColor.map((data, key) => { + return ( + <i + style={{ + margin: "5px", + color: data, + borderBottom: + key === 0 && penColor === "blue" + ? "2px solid blue" + : key === 1 && penColor === "red" + ? "2px solid red" + : key === 2 && penColor === "black" + ? "2px solid black" + : "2px solid white" + }} + onClick={() => { + props?.convertToImg(fontSelect, signValue, data); + if (key === 0) { + setPenColor("blue"); + } else if (key === 1) { + setPenColor("red"); + } else if (key === 2) { + setPenColor("black"); + } + }} + key={key} + className="fa solid fa-pen-nib" + width={20} + height={20} + ></i> + ); + })} + </div> + ); + }; return ( <div> {isSignPad && ( @@ -457,6 +502,7 @@ function SignPad({ background: "rgb(255, 255, 255)", objectFit: "contain" }} + draggable="false" src={isInitial ? myInitial : defaultSign} /> </div> @@ -517,6 +563,7 @@ function SignPad({ alt="print img" ref={imageRef} src={image.src} + draggable="false" style={{ objectFit: "contain", height: "100%", @@ -547,7 +594,7 @@ function SignPad({ <input maxLength={isInitial ? 3 : 30} - style={{ fontFamily: fontSelect }} + style={{ fontFamily: fontSelect, color: penColor }} type="text" className="signatureInput" placeholder="Your signature" @@ -578,7 +625,8 @@ function SignPad({ <div style={{ padding: "5px 10px 5px 10px", - fontSize: "20px" + fontSize: "20px", + color: penColor }} > {signValue ? signValue : "Your signature"} @@ -588,7 +636,15 @@ function SignPad({ })} </div> - <div style={{ display: "flex", justifyContent: "flex-end" }}> + <div + style={{ + display: "flex", + flexDirection: "row", + justifyContent: "space-between", + marginTop: "10px" + }} + > + <PenColorComponent convertToImg={convertToImg} /> <SaveBtn /> </div> </div> @@ -622,39 +678,7 @@ function SignPad({ marginTop: "10px" }} > - <div style={{ display: "flex", flexDirection: "row" }}> - {allColor.map((data, key) => { - return ( - <i - style={{ - margin: "5px", - color: data, - borderBottom: - key === 0 && penColor === "blue" - ? "2px solid blue" - : key === 1 && penColor === "red" - ? "2px solid red" - : key === 2 && penColor === "black" - ? "2px solid black" - : "2px solid white" - }} - onClick={() => { - if (key === 0) { - setPenColor("blue"); - } else if (key === 1) { - setPenColor("red"); - } else if (key === 2) { - setPenColor("black"); - } - }} - key={key} - className="fa solid fa-pen-nib" - width={20} - height={20} - ></i> - ); - })} - </div> + <PenColorComponent /> <SaveBtn /> </div> </> diff --git a/apps/OpenSign/src/pages/PlaceHolderSign.js b/apps/OpenSign/src/pages/PlaceHolderSign.js index 56a8c641b..3228e963b 100644 --- a/apps/OpenSign/src/pages/PlaceHolderSign.js +++ b/apps/OpenSign/src/pages/PlaceHolderSign.js @@ -1026,7 +1026,7 @@ function PlaceHolderSign() { selector: '[data-tut="reactourSecond"]', content: () => ( <TourContentWithBtn - message={`Drag the signature or stamp placeholder onto the PDF to choose your desired signing location.`} + message={`Drag or click on a field to add it to the document.`} isChecked={handleDontShow} /> ), From 91f3bdb2997f0c0fa730adb0ffe1a6f32400040c Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs <prafull.navkar@nxglabs.com> Date: Sat, 23 Mar 2024 17:06:40 +0530 Subject: [PATCH 24/36] fix: issue of cannot post /login in local docker setup --- .env.local_dev | 2 +- Makefile | 2 +- apps/OpenSign/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.env.local_dev b/.env.local_dev index 05b67ea82..e8ecd6df1 100644 --- a/.env.local_dev +++ b/.env.local_dev @@ -20,7 +20,7 @@ appName=open_sign_server # A 12 character long random secret key that allows access to all the data. It is used in Parse dashboard config to view all the data in the database. MASTER_KEY=XnAadwKxxByMr # Mongodb URI to connect to -MONGODB_URI=mongodb://localhost:27017/OpenSignDB +MONGODB_URI=mongodb://host.docker.internal:27017/OpenSignDB # Path on which APIs should be mounted. Do not change this. This variable shall be removed & value hardcoded in the source code in coming versions. PARSE_MOUNT=/app # Set it to the URL from where APIs will be accessible to the NodeJS functions, for local development it should be localhost:3000/api/app (use your local port number instead) diff --git a/Makefile b/Makefile index ad60da3d3..7c70890cf 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ build: cp .env.local_dev .env - cd apps/OpenSign && npm install && npm run build + cd apps/OpenSign && cp ../../.env.local_dev .env && npm install && npm run build docker compose up --build --force-recreate run: diff --git a/apps/OpenSign/Dockerfile b/apps/OpenSign/Dockerfile index 051503d52..e916c2679 100644 --- a/apps/OpenSign/Dockerfile +++ b/apps/OpenSign/Dockerfile @@ -21,5 +21,5 @@ EXPOSE 3000 # ENV NODE_ENV production # Run the application -ENTRYPOINT npm run start-dev +ENTRYPOINT npm run start From 34c99edf1a01335d72abf0bf371c47be696eb6ff Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Sat, 23 Mar 2024 17:08:09 +0530 Subject: [PATCH 25/36] fix: increase text area height on press enter and fix text widget embeding issue on finished button --- .../src/components/pdf/PlaceholderType.js | 18 +++ apps/OpenSign/src/constant/Utils.js | 115 +++++++++++++++++- 2 files changed, 128 insertions(+), 5 deletions(-) diff --git a/apps/OpenSign/src/components/pdf/PlaceholderType.js b/apps/OpenSign/src/components/pdf/PlaceholderType.js index 03e79efb6..d61c8bbca 100644 --- a/apps/OpenSign/src/components/pdf/PlaceholderType.js +++ b/apps/OpenSign/src/components/pdf/PlaceholderType.js @@ -3,6 +3,7 @@ import { getMonth, getYear, isMobile, + onChangeHeightOfTextArea, onChangeInput, radioButtonWidget, range, @@ -285,6 +286,22 @@ function PlaceholderType(props) { }; props.handleSaveDate(dateObj, isDateChange); }; + //handle height on enter press in text area + const handleEnterPress = (e) => { + const height = 15; + if (e.key === "Enter") { + //function to save height of text area + onChangeHeightOfTextArea( + height, + props.pos.type, + props.pos.key, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data?.Id + ); + } + }; switch (type) { case "signature": return props.pos.SignUrl ? ( @@ -741,6 +758,7 @@ function PlaceholderType(props) { <textarea placeholder="Enter label" rows={1} + onKeyDown={handleEnterPress} value={textValue} onBlur={handleInputBlur} onChange={(e) => { diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js index 883238dea..67b1f9d7f 100644 --- a/apps/OpenSign/src/constant/Utils.js +++ b/apps/OpenSign/src/constant/Utils.js @@ -760,6 +760,82 @@ export const onChangeInput = ( } }; +//function to increase height of text area on press enter +export const onChangeHeightOfTextArea = ( + height, + widgetType, + signKey, + xyPostion, + index, + setXyPostion, + userId +) => { + const isSigners = xyPostion.some((data) => data.signerPtr); + let filterSignerPos; + if (isSigners) { + if (userId) { + filterSignerPos = xyPostion.filter((data) => data.Id === userId); + } + 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((position) => { + if (position.key === signKey) { + return { + ...position, + Height: position.Height + ? position.Height + height + : defaultWidthHeight(widgetType).height + height + }; + } + return position; + }); + const newUpdateSignPos = getPlaceHolder.map((obj) => { + if (obj.pageNumber === index) { + return { ...obj, pos: addSignPos }; + } + return obj; + }); + + const newUpdateSigner = xyPostion.map((obj) => { + if (obj.Id === userId) { + return { ...obj, placeHolder: newUpdateSignPos }; + } + return obj; + }); + + setXyPostion(newUpdateSigner); + } + } else { + let getXYdata = xyPostion[index].pos; + + const updatePosition = getXYdata.map((position) => { + if (position.key === signKey) { + return { + ...position, + Height: position.Height + ? position.Height + height + : defaultWidthHeight(widgetType).height + height + }; + } + return position; + }); + + const updatePlaceholder = xyPostion.map((obj, ind) => { + if (ind === index) { + return { ...obj, pos: updatePosition }; + } + return obj; + }); + setXyPostion(updatePlaceholder); + } +}; + export const addInitialData = (signerPos, setXyPostion, value, userId) => { function widgetDataValue(type) { switch (type) { @@ -1234,10 +1310,11 @@ export const multiSignEmbed = async ( } else if (position?.options?.defaultValue) { textContent = position?.options?.defaultValue; } - const fixedWidth = scaleWidth; // Set your fixed width + const isNewOnEnterLineExist = textContent.includes("\n"); + // Function to break text into lines based on the fixed width - const breakTextIntoLines = (textContent, width) => { + const NewbreakTextIntoLines = (textContent, width) => { const lines = []; let currentLine = ""; @@ -1257,7 +1334,37 @@ export const multiSignEmbed = async ( lines.push(currentLine.trim()); return lines; }; - const lines = breakTextIntoLines(textContent, fixedWidth); + + // Function to break text into lines based on when user go next line on press enter button + const breakTextIntoLines = (textContent, width) => { + const lines = []; + let currentLine = ""; + + for (const word of textContent.split("\n")) { + const lineWidth = font.widthOfTextAtSize( + `${currentLine} ${word}`, + fontSize + ); + //checking string length to container width + //if string length is less then container width it means user press enter button + if (lineWidth <= width) { + lines.push(word); + } + //else adjust text content according to width and send it in new line + else { + const newLine = NewbreakTextIntoLines(word, width); + lines.push(...newLine); + } + } + + return lines; + }; + + //check if text content have `\n` string it means user press enter to go next line and handle condition + //else auto adjust text content according to container width + const lines = isNewOnEnterLineExist + ? breakTextIntoLines(textContent, fixedWidth) + : NewbreakTextIntoLines(textContent, fixedWidth); // Set initial y-coordinate for the first line const labelDefaultHeight = defaultWidthHeight(position.type).height; @@ -1358,9 +1465,7 @@ export const multiSignEmbed = async ( } }); } - const pdfBytes = await pdfDoc.saveAsBase64({ useObjectStreams: false }); - return pdfBytes; }; From f2b1a5469574418cc41932dca32df7ef190365f7 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs <93375423+prafull-opensignlabs@users.noreply.github.com> Date: Sat, 23 Mar 2024 19:33:14 +0530 Subject: [PATCH 26/36] change mongdb url in .env.local_dev --- .env.local_dev | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.local_dev b/.env.local_dev index e8ecd6df1..71635fd48 100644 --- a/.env.local_dev +++ b/.env.local_dev @@ -20,7 +20,7 @@ appName=open_sign_server # A 12 character long random secret key that allows access to all the data. It is used in Parse dashboard config to view all the data in the database. MASTER_KEY=XnAadwKxxByMr # Mongodb URI to connect to -MONGODB_URI=mongodb://host.docker.internal:27017/OpenSignDB +MONGODB_URI=mongodb://mongo:27017/OpenSignDB # Path on which APIs should be mounted. Do not change this. This variable shall be removed & value hardcoded in the source code in coming versions. PARSE_MOUNT=/app # Set it to the URL from where APIs will be accessible to the NodeJS functions, for local development it should be localhost:3000/api/app (use your local port number instead) From 593a8499f48865616eff89fba1242c9e7605edb9 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs <prafull.navkar@nxglabs.com> Date: Mon, 25 Mar 2024 22:12:58 +0530 Subject: [PATCH 27/36] refactor: add premium features warning --- .../components/pdf/DropdownWidgetOption.js | 14 +++++++- .../src/components/pdf/WidgetNameModal.js | 19 ++++++++++- apps/OpenSign/src/pages/GenerateToken.js | 2 ++ apps/OpenSign/src/pages/UserProfile.js | 34 +++++++++++-------- apps/OpenSign/src/pages/Webhook.js | 2 ++ .../src/primitives/PremiumAlertHeader.js | 11 ++++++ 6 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 apps/OpenSign/src/primitives/PremiumAlertHeader.js diff --git a/apps/OpenSign/src/components/pdf/DropdownWidgetOption.js b/apps/OpenSign/src/components/pdf/DropdownWidgetOption.js index 09abff5d4..cd23f221f 100644 --- a/apps/OpenSign/src/components/pdf/DropdownWidgetOption.js +++ b/apps/OpenSign/src/components/pdf/DropdownWidgetOption.js @@ -2,6 +2,7 @@ import React, { useEffect, useState } from "react"; import { themeColor } from "../../constant/const"; import ModalUi from "../../primitives/ModalUi"; import { radioButtonWidget } from "../../constant/Utils"; +import PremiumAlertHeader from "../../primitives/PremiumAlertHeader"; function DropdownWidgetOption(props) { const [dropdownOptionList, setDropdownOptionList] = useState([ "option-1", @@ -151,7 +152,18 @@ function DropdownWidgetOption(props) { title={props.title} showClose={false} > - <div style={{ height: "100%", padding: 20 }}> + {props.type === "checkbox" && !props.isSignYourself && ( + <PremiumAlertHeader + message={ + "Field validations are free in beta, this feature will incur a fee later." + } + /> + )} + <div + className={`${ + props.type === "checkbox" && !props.isSignYourself ? "pt-0" : "" + } h-full p-[20px]`} + > <form onSubmit={(e) => { e.preventDefault(); diff --git a/apps/OpenSign/src/components/pdf/WidgetNameModal.js b/apps/OpenSign/src/components/pdf/WidgetNameModal.js index 4471af317..388265962 100644 --- a/apps/OpenSign/src/components/pdf/WidgetNameModal.js +++ b/apps/OpenSign/src/components/pdf/WidgetNameModal.js @@ -3,6 +3,7 @@ import ModalUi from "../../primitives/ModalUi"; import "../../styles/AddUser.css"; import RegexParser from "regex-parser"; import { textInputWidget } from "../../constant/Utils"; +import PremiumAlertHeader from "../../primitives/PremiumAlertHeader"; const WidgetNameModal = (props) => { const [formdata, setFormdata] = useState({ @@ -98,7 +99,23 @@ const WidgetNameModal = (props) => { handleClose={props.handleClose && props.handleClose} title={"Widget info"} > - <form onSubmit={handleSubmit} style={{ padding: 20 }}> + {(props.defaultdata?.type === textInputWidget || + props.widgetName === textInputWidget) && ( + <PremiumAlertHeader + message={ + "Field validations are free in beta, this feature will incur a fee later." + } + /> + )} + <form + onSubmit={handleSubmit} + className={`${ + props.defaultdata?.type === textInputWidget || + props.widgetName === textInputWidget + ? "pt-0" + : "" + } p-[20px]`} + > <div className="form-section"> <label htmlFor="name" style={{ fontSize: 13 }}> Name diff --git a/apps/OpenSign/src/pages/GenerateToken.js b/apps/OpenSign/src/pages/GenerateToken.js index d112f15c3..2093ff250 100644 --- a/apps/OpenSign/src/pages/GenerateToken.js +++ b/apps/OpenSign/src/pages/GenerateToken.js @@ -5,6 +5,7 @@ import Alert from "../primitives/Alert"; import ModalUi from "../primitives/ModalUi"; import { rejectBtn, submitBtn } from "../constant/const"; import { openInNewTab } from "../constant/Utils"; +import PremiumAlertHeader from "../primitives/PremiumAlertHeader"; function GenerateToken() { const [parseBaseUrl] = useState(localStorage.getItem("baseUrl")); @@ -115,6 +116,7 @@ function GenerateToken() { </div> ) : ( <div className="bg-white flex flex-col justify-center shadow rounded"> + <PremiumAlertHeader /> <h1 className="ml-4 mt-3 mb-2 font-semibold">API Token</h1> <ul className="w-full flex flex-col p-2 text-sm"> <li diff --git a/apps/OpenSign/src/pages/UserProfile.js b/apps/OpenSign/src/pages/UserProfile.js index 186415e98..f09d2f2db 100644 --- a/apps/OpenSign/src/pages/UserProfile.js +++ b/apps/OpenSign/src/pages/UserProfile.js @@ -6,6 +6,7 @@ import dp from "../assets/images/dp.png"; import Title from "../components/Title"; import sanitizeFileName from "../primitives/sanitizeFileName"; import axios from "axios"; +import PremiumAlertHeader from "../primitives/PremiumAlertHeader"; function UserProfile() { const navigate = useNavigate(); @@ -258,21 +259,24 @@ function UserProfile() { : "Not verified"} </span> </li> - <li className="flex justify-between items-center border-y-[1px] border-gray-300 py-2 break-all"> - <span className="font-semibold">Disable DocumentId :</span>{" "} - <span> - <label className="relative inline-flex items-center cursor-pointer mb-0"> - <input - disabled={editmode ? false : true} - checked={isDisableDocId} - onChange={handleDisableDocId} - type="checkbox" - value="" - className="sr-only peer" - /> - <div className="w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div> - </label> - </span> + <li className="border-y-[1px] border-gray-300 break-all"> + <PremiumAlertHeader message={"Disable documentId is free in beta, this feature will incur a fee later."} /> + <div className="flex justify-between items-center py-2"> + <span className="font-semibold">Disable DocumentId :</span>{" "} + <span> + <label className="relative inline-flex items-center cursor-pointer mb-0"> + <input + disabled={editmode ? false : true} + checked={isDisableDocId} + onChange={handleDisableDocId} + type="checkbox" + value="" + className="sr-only peer" + /> + <div className="w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div> + </label> + </span> + </div> </li> </ul> <div className="flex justify-center pt-2 pb-3 md:pt-3 md:pb-4"> diff --git a/apps/OpenSign/src/pages/Webhook.js b/apps/OpenSign/src/pages/Webhook.js index 22cf04ec5..809a47539 100644 --- a/apps/OpenSign/src/pages/Webhook.js +++ b/apps/OpenSign/src/pages/Webhook.js @@ -6,6 +6,7 @@ import ModalUi from "../primitives/ModalUi"; import { rejectBtn, submitBtn } from "../constant/const"; import { openInNewTab } from "../constant/Utils"; import Parse from "parse"; +import PremiumAlertHeader from "../primitives/PremiumAlertHeader"; function Webhook() { const [parseBaseUrl] = useState(localStorage.getItem("baseUrl")); @@ -101,6 +102,7 @@ function Webhook() { </div> ) : ( <div className="bg-white flex flex-col justify-center shadow rounded"> + <PremiumAlertHeader /> <h1 className="ml-4 mt-3 mb-2 font-semibold">Webhook</h1> <ul className="w-full flex flex-col p-2 text-sm"> <li diff --git a/apps/OpenSign/src/primitives/PremiumAlertHeader.js b/apps/OpenSign/src/primitives/PremiumAlertHeader.js new file mode 100644 index 000000000..c1e1ceb00 --- /dev/null +++ b/apps/OpenSign/src/primitives/PremiumAlertHeader.js @@ -0,0 +1,11 @@ +import React from "react"; + +const PremiumAlertHeader = ({ message }) => ( + <marquee className="bg-yellow-300 text-black px-2"> + {message + ? message + : "Currently free in Beta, this feature will incur a fee later."} + </marquee> +); + +export default PremiumAlertHeader; From e78a3991f03a6097b25670182526920318a7129b Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Tue, 26 Mar 2024 09:50:46 +0530 Subject: [PATCH 28/36] fix: remoove unnecessary code --- apps/OpenSign/src/constant/Utils.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js index 67b1f9d7f..19a8662ab 100644 --- a/apps/OpenSign/src/constant/Utils.js +++ b/apps/OpenSign/src/constant/Utils.js @@ -1319,11 +1319,12 @@ export const multiSignEmbed = async ( let currentLine = ""; for (const word of textContent.split(" ")) { + //get text line width const lineWidth = font.widthOfTextAtSize( `${currentLine} ${word}`, fontSize ); - + //check text content line width is less or equal to container width if (lineWidth <= width) { currentLine += ` ${word}`; } else { @@ -1338,13 +1339,9 @@ export const multiSignEmbed = async ( // Function to break text into lines based on when user go next line on press enter button const breakTextIntoLines = (textContent, width) => { const lines = []; - let currentLine = ""; for (const word of textContent.split("\n")) { - const lineWidth = font.widthOfTextAtSize( - `${currentLine} ${word}`, - fontSize - ); + const lineWidth = font.widthOfTextAtSize(`${word}`, fontSize); //checking string length to container width //if string length is less then container width it means user press enter button if (lineWidth <= width) { From a94e67cd7c6d65e271fb61419f8ccfb8332c891a Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Tue, 26 Mar 2024 10:12:07 +0530 Subject: [PATCH 29/36] fix:signature pad pen color issue --- apps/OpenSign/src/components/pdf/SignPad.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/OpenSign/src/components/pdf/SignPad.js b/apps/OpenSign/src/components/pdf/SignPad.js index 719bafac1..32f29bdfe 100644 --- a/apps/OpenSign/src/components/pdf/SignPad.js +++ b/apps/OpenSign/src/components/pdf/SignPad.js @@ -261,7 +261,8 @@ function SignPad({ : "2px solid white" }} onClick={() => { - props?.convertToImg(fontSelect, signValue, data); + props?.convertToImg && + props?.convertToImg(fontSelect, signValue, data); if (key === 0) { setPenColor("blue"); } else if (key === 1) { From 899678d98af30d37087e9f3ef08ed7f284ae4c7a Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Tue, 26 Mar 2024 14:31:48 +0530 Subject: [PATCH 30/36] feat: implement feature of copy widget to next of that widget for any widgets except signature,text,stamp,initial widgets --- .../src/components/pdf/Placeholder.js | 37 +++++++--- apps/OpenSign/src/constant/Utils.js | 72 +++++++++++++++++-- 2 files changed, 95 insertions(+), 14 deletions(-) diff --git a/apps/OpenSign/src/components/pdf/Placeholder.js b/apps/OpenSign/src/components/pdf/Placeholder.js index 41f96a550..45261deaf 100644 --- a/apps/OpenSign/src/components/pdf/Placeholder.js +++ b/apps/OpenSign/src/components/pdf/Placeholder.js @@ -4,6 +4,7 @@ import PlaceholderBorder from "./PlaceholderBorder"; import { Rnd } from "react-rnd"; import { defaultWidthHeight, + handleCopyNextToWidget, isMobile, onChangeInput, radioButtonWidget, @@ -302,19 +303,35 @@ function Placeholder(props) { props.setWidgetType(props.pos.type); props.setCurrWidgetsDetails(props.pos); }; - //function ro set state value of onclick on widget's copy icon + //function to set required state value onclick on widget's copy icon const handleCopyPlaceholder = (e) => { - if (props.data && props?.pos?.type !== textWidget) { - props.setSignerObjId(props?.data?.signerObjId); - props.setUniqueId(props?.data?.Id); - } else if (props.data && props.pos.type === textWidget) { + e.stopPropagation(); + //condition to handle text widget signer obj id and unique id + //when user click on copy icon of text widget in that condition text widget does not have any signerObjId + //in that case i have to save in tempSignerId as a unique id of previous select signer's unique id + //and on save or cancel button of copy all page popup i have set this temp signer Id in unique id + if (props.data && props.pos.type === textWidget) { props.setTempSignerId(props.uniqueId); - props.setSignerObjId(props?.data?.signerObjId); - props.setUniqueId(props?.data?.Id); } - e.stopPropagation(); - props.setIsPageCopy(true); - props.setSignKey(props.pos.key); + props.setSignerObjId(props?.data?.signerObjId); + props.setUniqueId(props?.data?.Id); + //checking widget's type and open widget copy modal for required widgets + if ( + ["signature", textWidget, "stamp", "initial"].includes(props.pos.type) + ) { + props.setIsPageCopy(true); + props.setSignKey(props.pos.key); + } else { + //function to create new widget next to just widget + handleCopyNextToWidget( + props.pos, + props.pos.type, + props.xyPostion, + props.index, + props.setXyPostion, + props.data && props.data?.Id + ); + } }; //function to save date and format on local array onchange date and onclick format diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js index 19a8662ab..a458e2813 100644 --- a/apps/OpenSign/src/constant/Utils.js +++ b/apps/OpenSign/src/constant/Utils.js @@ -1255,13 +1255,14 @@ export const multiSignEmbed = async ( "email" ].includes(position.type); if (position.type === "checkbox") { - let addYPosition, isCheck; + let addYPosition = 0, + isCheck; if (position?.options?.values.length > 0) { position?.options?.values.forEach((item, ind) => { const checkboxRandomId = "checkbox" + randomId(); let yPosition; - const height = 10; + const height = 13; if ( position?.options?.response && position?.options?.response?.length > 0 @@ -1282,14 +1283,14 @@ export const multiSignEmbed = async ( if (!position?.options?.isHideLabel) { // below line of code is used to embed label with radio button in pdf page.drawText(item, { - x: xPos(position) + 15, + x: xPos(position) + 17, y: yPosition + 2, size: height }); } checkbox.addToPage(page, { x: xPos(position), - y: yPosition, + y: yPosition - 2, width: height, height: height }); @@ -1702,3 +1703,66 @@ export const getYear = (date) => { const newYear = new Date(date).getFullYear(); return newYear; }; + +//function to create/copy widget next to already dropped widget +export const handleCopyNextToWidget = ( + position, + widgetType, + xyPostion, + index, + setXyPostion, + userId +) => { + const isSigners = xyPostion.some((data) => data.signerPtr); + let filterSignerPos; + //get position of previous widget and create new widget next to that widget on same data except + // xPosition and key + let newpos = position; + const calculateXPosition = + parseInt(position.xPosition) + + defaultWidthHeight(widgetType).width + + resizeBorderExtraWidth(); + const newId = randomId(); + newpos = { ...newpos, xPosition: calculateXPosition, key: newId }; + //if condition to create widget in request-sign flow + if (isSigners) { + if (userId) { + filterSignerPos = xyPostion.filter((data) => data.Id === userId); + } + const getPlaceHolder = filterSignerPos[0]?.placeHolder; + const getPageNumer = getPlaceHolder.filter( + (data) => data.pageNumber === index + ); + const getXYdata = getPageNumer[0].pos; + getXYdata.push(newpos); + if (getPageNumer.length > 0) { + const newUpdateSignPos = getPlaceHolder.map((obj) => { + if (obj.pageNumber === index) { + return { ...obj, pos: getXYdata }; + } + return obj; + }); + + const newUpdateSigner = xyPostion.map((obj) => { + if (obj.Id === userId) { + return { ...obj, placeHolder: newUpdateSignPos }; + } + return obj; + }); + + setXyPostion(newUpdateSigner); + } + } else { + // else condition to create widget in sign-yourself flow + let getXYdata = xyPostion[index].pos; + getXYdata.push(newpos); + const updatePlaceholder = xyPostion.map((obj, ind) => { + if (ind === index) { + return { ...obj, pos: getXYdata }; + } + return obj; + }); + + setXyPostion(updatePlaceholder); + } +}; From c2a45c230b348d5fb67aa542dba4e49e75f6d387 Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Tue, 26 Mar 2024 16:02:03 +0530 Subject: [PATCH 31/36] fix: widget copy issue in sign-yourself flow --- apps/OpenSign/src/components/pdf/Placeholder.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/OpenSign/src/components/pdf/Placeholder.js b/apps/OpenSign/src/components/pdf/Placeholder.js index 45261deaf..0b292b58f 100644 --- a/apps/OpenSign/src/components/pdf/Placeholder.js +++ b/apps/OpenSign/src/components/pdf/Placeholder.js @@ -310,11 +310,16 @@ function Placeholder(props) { //when user click on copy icon of text widget in that condition text widget does not have any signerObjId //in that case i have to save in tempSignerId as a unique id of previous select signer's unique id //and on save or cancel button of copy all page popup i have set this temp signer Id in unique id - if (props.data && props.pos.type === textWidget) { + + if (props.data && props?.pos?.type !== textWidget) { + props.setSignerObjId(props?.data?.signerObjId); + props.setUniqueId(props?.data?.Id); + } else if (props.data && props.pos.type === textWidget) { props.setTempSignerId(props.uniqueId); + props.setSignerObjId(props?.data?.signerObjId); + props.setUniqueId(props?.data?.Id); } - props.setSignerObjId(props?.data?.signerObjId); - props.setUniqueId(props?.data?.Id); + //checking widget's type and open widget copy modal for required widgets if ( ["signature", textWidget, "stamp", "initial"].includes(props.pos.type) From 6161e975fb24a9729ef69d99b49e10496d956987 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs <prafull.navkar@nxglabs.com> Date: Tue, 26 Mar 2024 17:03:08 +0530 Subject: [PATCH 32/36] refactor: add help buttons for all sections --- .../src/components/dashboard/DashboardCard.js | 6 +- .../components/pdf/DropdownWidgetOption.js | 44 +++----- .../src/components/pdf/WidgetNameModal.js | 35 +++--- .../components/shared/fields/SignersInput.js | 7 ++ apps/OpenSign/src/json/ReportJson.js | 27 +++-- apps/OpenSign/src/pages/Form.js | 13 ++- apps/OpenSign/src/pages/GenerateToken.js | 8 +- apps/OpenSign/src/pages/Managesign.js | 102 +++--------------- apps/OpenSign/src/pages/Report.js | 3 + apps/OpenSign/src/pages/UserProfile.js | 42 +++++--- apps/OpenSign/src/pages/Webhook.js | 8 +- .../src/primitives/GetReportDisplay.js | 13 ++- apps/OpenSign/src/primitives/Tooltip.js | 38 +++++-- apps/OpenSign/src/styles/AddUser.css | 58 ++++++++++ apps/OpenSign/src/styles/managesign.css | 21 ---- apps/OpenSign/src/styles/signature.css | 11 -- 16 files changed, 230 insertions(+), 206 deletions(-) diff --git a/apps/OpenSign/src/components/dashboard/DashboardCard.js b/apps/OpenSign/src/components/dashboard/DashboardCard.js index bc131213f..9b54c273e 100644 --- a/apps/OpenSign/src/components/dashboard/DashboardCard.js +++ b/apps/OpenSign/src/components/dashboard/DashboardCard.js @@ -4,6 +4,7 @@ import Parse from "parse"; import getReplacedHashQuery from "../../constant/getReplacedHashQuery"; import "../../styles/loader.css"; import { useNavigate } from "react-router-dom"; +import Tooltip from "../../primitives/Tooltip"; const DashboardCard = (props) => { const navigate = useNavigate(); @@ -335,7 +336,7 @@ const DashboardCard = (props) => { props.Data && props.Data.Redirect_type ? "cursor-pointer" : "cursor-default" - } w-full h-[140px] px-3 pt-4 pb-10 text-white rounded-md shadow overflow-hidden`} + } w-full h-[140px] px-3 pt-4 pb-10 text-white rounded-md shadow overflow-hidden relative`} > <div className="flex items-center justify-start gap-5"> <span className="rounded-full bg-black bg-opacity-20 w-[60px] h-[60px] self-start flex justify-center items-center"> @@ -352,6 +353,9 @@ const DashboardCard = (props) => { </div> </div> </div> + <div className="text-xs absolute top-1 right-1"> + <Tooltip id={props.Label} iconColor={"white"} message={props?.Data?.tourMessage} /> + </div> </div> ); }; diff --git a/apps/OpenSign/src/components/pdf/DropdownWidgetOption.js b/apps/OpenSign/src/components/pdf/DropdownWidgetOption.js index cd23f221f..7d80efd9e 100644 --- a/apps/OpenSign/src/components/pdf/DropdownWidgetOption.js +++ b/apps/OpenSign/src/components/pdf/DropdownWidgetOption.js @@ -145,32 +145,15 @@ function DropdownWidgetOption(props) { }; return ( - //props.showDropdown - <ModalUi - // styleClass={"dropdownModal"} - isOpen={props.showDropdown} - title={props.title} - showClose={false} - > - {props.type === "checkbox" && !props.isSignYourself && ( - <PremiumAlertHeader - message={ - "Field validations are free in beta, this feature will incur a fee later." - } - /> - )} - <div - className={`${ - props.type === "checkbox" && !props.isSignYourself ? "pt-0" : "" - } h-full p-[20px]`} - > + <ModalUi isOpen={props.showDropdown} title={props.title} showClose={false}> + <div className="h-full p-[15px]"> <form onSubmit={(e) => { e.preventDefault(); handleSaveOption(); }} > - <div className="dropdownContainer"> + <div> <label style={{ fontSize: "13px", fontWeight: "600" }}> Name<span style={{ color: "red", fontSize: 13 }}> *</span> </label> @@ -395,17 +378,22 @@ function DropdownWidgetOption(props) { </div> )} </div> + {props.type === "checkbox" && !props.isSignYourself && ( + <PremiumAlertHeader + message={ + "Field validations are free in beta, this feature will incur a fee later." + } + /> + )} <div - style={{ - height: "1px", - backgroundColor: "#9f9f9f", - width: "100%", - marginTop: "15px", - marginBottom: "15px" - }} + className={`${ + props.type === "checkbox" && !props.isSignYourself + ? "mb-[15px]" + : "my-[15px]" + } w-full h-[1px] bg-[#9f9f9f]`} ></div> + <button - // onClick={() => handleSaveOption()} disabled={dropdownOptionList.length === 0 && true} style={{ background: themeColor, diff --git a/apps/OpenSign/src/components/pdf/WidgetNameModal.js b/apps/OpenSign/src/components/pdf/WidgetNameModal.js index 388265962..71c433afc 100644 --- a/apps/OpenSign/src/components/pdf/WidgetNameModal.js +++ b/apps/OpenSign/src/components/pdf/WidgetNameModal.js @@ -15,7 +15,7 @@ const WidgetNameModal = (props) => { }); const [isValid, setIsValid] = useState(true); const statusArr = ["Required", "Optional"]; - const inputOpt = ["email", "number"]; + const inputOpt = ["text", "email", "number"]; useEffect(() => { if (props.defaultdata) { @@ -71,7 +71,7 @@ const WidgetNameModal = (props) => { return "/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/"; case "number": return "/^\\d+$/"; - case textInputWidget: + case "text": return "/^[a-zA-Zs]+$/"; default: return type; @@ -187,25 +187,22 @@ const WidgetNameModal = (props) => { name="defaultValue" value={formdata.defaultValue} onChange={(e) => handledefaultChange(e)} - onBlur={() => - isValid === false && - setFormdata({ ...formdata, defaultValue: "" }) - } + autoComplete="off" + onBlur={() => { + if (isValid === false) { + setFormdata({ ...formdata, defaultValue: "" }); + setIsValid(true); + } + }} /> - {isValid === false ? ( - <p style={{ color: "Red", fontSize: 8 }}> + {isValid === false && ( + <div className="warning defaultvalueWarning" style={{ fontSize: 12 }}> + <i + className="fas fa-exclamation-circle" + style={{ color: "#fab005", fontSize: 15 }} + ></i>{" "} invalid default value - </p> - ) : ( - <p - style={{ - color: "transparent", - fontSize: 10, - margin: "3px 8px" - }} - > - . - </p> + </div> )} </div> </> diff --git a/apps/OpenSign/src/components/shared/fields/SignersInput.js b/apps/OpenSign/src/components/shared/fields/SignersInput.js index 5f00dbfb0..2b2648db6 100644 --- a/apps/OpenSign/src/components/shared/fields/SignersInput.js +++ b/apps/OpenSign/src/components/shared/fields/SignersInput.js @@ -3,6 +3,7 @@ import Select from "react-select"; import AddSigner from "../../AddSigner"; import Modal from "react-modal"; import Parse from "parse"; +import Tooltip from "../../../primitives/Tooltip"; function arrayMove(array, from, to) { array = array.slice(); array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]); @@ -107,6 +108,12 @@ const SignersInput = (props) => { <label className="block"> Signers {props.required && <span className="text-red-500 text-[13px]">*</span>} + <span className="ml-1 text-xs z-[999]"> + <Tooltip + id={"signer-tooltip"} + message={"This is a list of contacts/signers added by you"} + /> + </span> </label> <div style={{ display: "flex", gap: 5 }}> <div style={{ flexWrap: "wrap", width: "100%" }}> diff --git a/apps/OpenSign/src/json/ReportJson.js b/apps/OpenSign/src/json/ReportJson.js index 0f0edc38c..37d0c94bb 100644 --- a/apps/OpenSign/src/json/ReportJson.js +++ b/apps/OpenSign/src/json/ReportJson.js @@ -18,7 +18,8 @@ export default function reportJson(id) { btnIcon: "fa fa-plus", redirectUrl: "draftDocument" } - ] + ], + helpMsg: "This are documents you have started but have not finalized for sending." }; // Need your sign report case "4Hhwbp482K": @@ -33,7 +34,9 @@ export default function reportJson(id) { btnIcon: "fa fa-eye", redirectUrl: "pdfRequestFiles" } - ] + ], + helpMsg: + "This is a list of documents that are waiting for your signature" }; // In progess report case "1MwEuxLEkF": @@ -48,7 +51,9 @@ export default function reportJson(id) { btnIcon: "fa fa-eye", redirectUrl: "pdfRequestFiles" } - ] + ], + helpMsg: + "This is a list of documents you've sent to other parties for signature." }; // completed documents report case "kQUoW4hUXz": @@ -63,7 +68,8 @@ export default function reportJson(id) { btnIcon: "fa fa-eye", redirectUrl: "draftDocument" } - ] + ], + helpMsg: "This is a list of documents that have been signed by all parties." }; // declined documents report case "UPr2Fm5WY3": @@ -78,7 +84,8 @@ export default function reportJson(id) { btnIcon: "fa fa-eye", redirectUrl: "draftDocument" } - ] + ], + helpMsg: "This is a list of documents that have been declined by one of the signers." }; // Expired Documents report case "zNqBHXHsYH": @@ -93,7 +100,8 @@ export default function reportJson(id) { btnIcon: "fa fa-eye", redirectUrl: "draftDocument" } - ] + ], + helpMsg: "This is a list of documents that have reached their expiration date." }; // Recently sent for signatures report show on dashboard case "d9k3UfYHBc": @@ -153,7 +161,8 @@ export default function reportJson(id) { btnIcon: "fa-solid fa-trash" } ], - form: "ContactBook" + form: "ContactBook", + helpMsg: "This is a list of contacts/signers that have been added by you." }; // template report case "6TeaPr321t": @@ -175,7 +184,9 @@ export default function reportJson(id) { btnIcon: "fa fa-plus", redirectUrl: "template" } - ] + ], + helpMsg: + "This is a list of templates that are used to create documents" }; default: return null; diff --git a/apps/OpenSign/src/pages/Form.js b/apps/OpenSign/src/pages/Form.js index 1e2afcae9..4ab1a09f2 100644 --- a/apps/OpenSign/src/pages/Form.js +++ b/apps/OpenSign/src/pages/Form.js @@ -35,7 +35,7 @@ const Forms = (props) => { const [formData, setFormData] = useState({ Name: "", Description: "", - Note: "Please review and sign this document", + Note: "", TimeToCompleteDays: 15, SendinOrder: "false" }); @@ -51,6 +51,7 @@ const Forms = (props) => { }; useEffect(() => { handleReset(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [props.title]); const handleFileInput = (e) => { setpercentage(0); @@ -235,7 +236,10 @@ const Forms = (props) => { setFormData({ Name: "", Description: "", - Note: "Please review and sign this document", + Note: + props.title === "Sign Yourself" + ? "Note to myself" + : "Please review and sign this document", TimeToCompleteDays: 15, SendinOrder: "true" }); @@ -326,7 +330,10 @@ const Forms = (props) => { </div> <div className="text-xs mt-2"> <label className="block"> - Title<span className="text-red-500 text-[13px]">*</span> + {props.title === "New Template" + ? "Template Title" + : "Document Title"} + <span className="text-red-500 text-[13px]">*</span> </label> <input name="Name" diff --git a/apps/OpenSign/src/pages/GenerateToken.js b/apps/OpenSign/src/pages/GenerateToken.js index 2093ff250..65b2c0f4f 100644 --- a/apps/OpenSign/src/pages/GenerateToken.js +++ b/apps/OpenSign/src/pages/GenerateToken.js @@ -6,6 +6,7 @@ import ModalUi from "../primitives/ModalUi"; import { rejectBtn, submitBtn } from "../constant/const"; import { openInNewTab } from "../constant/Utils"; import PremiumAlertHeader from "../primitives/PremiumAlertHeader"; +import Tooltip from "../primitives/Tooltip"; function GenerateToken() { const [parseBaseUrl] = useState(localStorage.getItem("baseUrl")); @@ -117,7 +118,12 @@ function GenerateToken() { ) : ( <div className="bg-white flex flex-col justify-center shadow rounded"> <PremiumAlertHeader /> - <h1 className="ml-4 mt-3 mb-2 font-semibold">API Token</h1> + <h1 className="ml-4 mt-3 mb-2 font-semibold"> + API Token{" "} + <Tooltip + url={"https://docs.opensignlabs.com/docs/API-docs/opensign-api-v-1"} + /> + </h1> <ul className="w-full flex flex-col p-2 text-sm"> <li className={`flex justify-between items-center border-y-[1px] border-gray-300 break-all py-2`} diff --git a/apps/OpenSign/src/pages/Managesign.js b/apps/OpenSign/src/pages/Managesign.js index 49f1aae04..e3efd39c9 100644 --- a/apps/OpenSign/src/pages/Managesign.js +++ b/apps/OpenSign/src/pages/Managesign.js @@ -13,7 +13,6 @@ const ManageSign = () => { const [signName, setSignName] = useState(""); const [signature, setSignature] = useState(""); const [warning, setWarning] = useState(false); - const [nameWarning, setNameWarning] = useState(false); const [isvalue, setIsValue] = useState(false); const allColor = ["blue", "red", "black"]; const [isLoader, setIsLoader] = useState(true); @@ -105,9 +104,7 @@ const ManageSign = () => { e.preventDefault(); const isUrl = image.includes("https"); - if (!signName) { - setNameWarning(true); - } else if (!isvalue) { + if (!isvalue) { setWarning(true); setTimeout(() => setWarning(false), 1000); } else { @@ -222,26 +219,13 @@ const ManageSign = () => { setIsValue(true); }; return ( - <div - style={{ - backgroundColor: "white", - maxHeight: "500px", - overflow: "auto" - }} - > + <div className="relative h-full bg-white flex shadow rounded overflow-auto"> {isLoader && ( - <div className="absolute bg-black bg-opacity-75 inset-0 z-50 flex justify-center items-center"> - <div style={{ height: "300px" }}> - <div - style={{ - marginLeft: "45%", - marginTop: "150px", - fontSize: "45px", - color: "#3dd3e0" - }} - className="loader-37" - ></div> - </div> + <div className="absolute bg-black bg-opacity-75 z-50 w-full h-full flex justify-center items-center"> + <div + style={{ color: "#3dd3e0" }} + className="loader-37 text-[45px]" + ></div> </div> )} {isSuccess && ( @@ -269,61 +253,9 @@ const ManageSign = () => { paddingBottom: 8 }} > - Manage Signature - </div> - <div style={{ display: "flex", flexDirection: "column" }}> - <label - htmlFor="signName" - style={{ - fontSize: 12, - position: "relative", - paddingBottom: 5 - }} - > - Signer's Name - {nameWarning && ( - <div - className="warning nameWarning" - style={{ fontSize: 12 }} - onAnimationEnd={() => setNameWarning(false)} - > - <i - className="fas fa-exclamation-circle" - style={{ color: "#fab005", fontSize: 15 }} - ></i>{" "} - Please fill input field - </div> - )} - </label> - <input - id="signName" - className="signInputManage" - value={signName} - style={{ - border: "1px solid #ccc", - borderRadius: 4, - - height: 35, - padding: "6px 12px", - marginBottom: 10, - fontSize: 12 - }} - required - onFocus={() => setNameWarning(false)} - onChange={(e) => setSignName(e.target.value)} - /> - - <label - htmlFor="imgoverview" - style={{ - fontSize: 12, - paddingBottom: 5 - }} - > - Signature/Image - </label> + My Signature </div> - <div className="signBlock"> + <div className="signBlock mt-4"> <div> <div style={{ position: "relative" }}> <div @@ -429,10 +361,10 @@ const ManageSign = () => { key === 0 && penColor === "blue" ? "2px solid blue" : key === 1 && penColor === "red" - ? "2px solid red" - : key === 2 && penColor === "black" - ? "2px solid black" - : "2px solid white" + ? "2px solid red" + : key === 2 && penColor === "black" + ? "2px solid black" + : "2px solid white" }} onClick={() => { if (key === 0) { @@ -537,10 +469,10 @@ const ManageSign = () => { key === 0 && initialPen === "blue" ? "2px solid blue" : key === 1 && initialPen === "red" - ? "2px solid red" - : key === 2 && initialPen === "black" - ? "2px solid black" - : "2px solid white" + ? "2px solid red" + : key === 2 && initialPen === "black" + ? "2px solid black" + : "2px solid white" }} onClick={() => { if (key === 0) { diff --git a/apps/OpenSign/src/pages/Report.js b/apps/OpenSign/src/pages/Report.js index 1868dab8e..10765260a 100644 --- a/apps/OpenSign/src/pages/Report.js +++ b/apps/OpenSign/src/pages/Report.js @@ -12,6 +12,7 @@ const Report = () => { const [List, setList] = useState([]); const [isLoader, setIsLoader] = useState(true); const [reportName, setReportName] = useState(""); + const [reporthelp, setReportHelp] = useState(""); const [actions, setActions] = useState([]); const [heading, setHeading] = useState([]); const [isNextRecord, setIsNextRecord] = useState(false); @@ -53,6 +54,7 @@ const Report = () => { setHeading(json.heading); setReportName(json.reportName); setForm(json.form); + setReportHelp(json?.helpMsg) const currentUser = Parse.User.current().id; const headers = { @@ -156,6 +158,7 @@ const Report = () => { isMoreDocs={isMoreDocs} docPerPage={docPerPage} form={form} + report_help={reporthelp} /> ) : ( <PageNotFound prefix={"Report"} /> diff --git a/apps/OpenSign/src/pages/UserProfile.js b/apps/OpenSign/src/pages/UserProfile.js index f09d2f2db..842f8129b 100644 --- a/apps/OpenSign/src/pages/UserProfile.js +++ b/apps/OpenSign/src/pages/UserProfile.js @@ -7,6 +7,7 @@ import Title from "../components/Title"; import sanitizeFileName from "../primitives/sanitizeFileName"; import axios from "axios"; import PremiumAlertHeader from "../primitives/PremiumAlertHeader"; +import Tooltip from "../primitives/Tooltip"; function UserProfile() { const navigate = useNavigate(); @@ -251,7 +252,7 @@ function UserProfile() { <span className="font-semibold">Email:</span>{" "} <span>{UserProfile && UserProfile.email}</span> </li> - <li className="flex justify-between items-center border-y-[1px] border-gray-300 py-2 break-all"> + <li className="flex justify-between items-center border-t-[1px] border-gray-300 py-2 break-all"> <span className="font-semibold">Is Email verified:</span>{" "} <span> {UserProfile && UserProfile.emailVerified @@ -260,23 +261,32 @@ function UserProfile() { </span> </li> <li className="border-y-[1px] border-gray-300 break-all"> - <PremiumAlertHeader message={"Disable documentId is free in beta, this feature will incur a fee later."} /> <div className="flex justify-between items-center py-2"> - <span className="font-semibold">Disable DocumentId :</span>{" "} - <span> - <label className="relative inline-flex items-center cursor-pointer mb-0"> - <input - disabled={editmode ? false : true} - checked={isDisableDocId} - onChange={handleDisableDocId} - type="checkbox" - value="" - className="sr-only peer" - /> - <div className="w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div> - </label> - </span> + <span className="font-semibold"> + Disable DocumentId :{" "} + <Tooltip url={"https://docs.opensignlabs.com/docs/help/Settings/profile/"} />{" "} + </span>{" "} + <label + className={`${ + editmode ? "cursor-pointer" : "" + } relative inline-flex items-center mb-0`} + > + <input + disabled={editmode ? false : true} + checked={isDisableDocId} + onChange={handleDisableDocId} + type="checkbox" + value="" + className="sr-only peer" + /> + <div className="w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-1 peer-focus:ring-black rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-black peer-checked:bg-blue-600"></div> + </label> </div> + <PremiumAlertHeader + message={ + "Disable documentId is free in beta, this feature will incur a fee later." + } + /> </li> </ul> <div className="flex justify-center pt-2 pb-3 md:pt-3 md:pb-4"> diff --git a/apps/OpenSign/src/pages/Webhook.js b/apps/OpenSign/src/pages/Webhook.js index 809a47539..fb7fe0616 100644 --- a/apps/OpenSign/src/pages/Webhook.js +++ b/apps/OpenSign/src/pages/Webhook.js @@ -7,6 +7,7 @@ import { rejectBtn, submitBtn } from "../constant/const"; import { openInNewTab } from "../constant/Utils"; import Parse from "parse"; import PremiumAlertHeader from "../primitives/PremiumAlertHeader"; +import Tooltip from "../primitives/Tooltip"; function Webhook() { const [parseBaseUrl] = useState(localStorage.getItem("baseUrl")); @@ -103,7 +104,12 @@ function Webhook() { ) : ( <div className="bg-white flex flex-col justify-center shadow rounded"> <PremiumAlertHeader /> - <h1 className="ml-4 mt-3 mb-2 font-semibold">Webhook</h1> + <h1 className="ml-4 mt-3 mb-2 font-semibold"> + Webhook{" "} + <Tooltip + url={"https://docs.opensignlabs.com/docs/API-docs/get-webhook"} + /> + </h1> <ul className="w-full flex flex-col p-2 text-sm"> <li className={`flex justify-between items-center border-y-[1px] border-gray-300 break-all py-2`} diff --git a/apps/OpenSign/src/primitives/GetReportDisplay.js b/apps/OpenSign/src/primitives/GetReportDisplay.js index e11ac0a31..d0d6bd428 100644 --- a/apps/OpenSign/src/primitives/GetReportDisplay.js +++ b/apps/OpenSign/src/primitives/GetReportDisplay.js @@ -6,6 +6,7 @@ import ModalUi from "./ModalUi"; import AddSigner from "../components/AddSigner"; import { modalSubmitBtnColor, modalCancelBtnColor } from "../constant/const"; import Alert from "./Alert"; +import Tooltip from "./Tooltip"; const ReportTable = ({ ReportName, List, @@ -15,7 +16,8 @@ const ReportTable = ({ setIsNextRecord, isMoreDocs, docPerPage, - form + form, + report_help }) => { const navigate = useNavigate(); const [currentPage, setCurrentPage] = useState(1); @@ -255,7 +257,14 @@ const ReportTable = ({ </Alert> )} <div className="flex flex-row items-center justify-between my-2 mx-3 text-[20px] md:text-[23px]"> - <div className="font-light">{ReportName}</div> + <div className="font-light"> + {ReportName}{" "} + {report_help && ( + <span className="text-xs md:text-[13px] font-normal"> + <Tooltip message={report_help} /> + </span> + )} + </div> {ReportName === "Templates" && ( <i onClick={() => navigate("/form/template")} diff --git a/apps/OpenSign/src/primitives/Tooltip.js b/apps/OpenSign/src/primitives/Tooltip.js index 2d1edcd82..323afc3d5 100644 --- a/apps/OpenSign/src/primitives/Tooltip.js +++ b/apps/OpenSign/src/primitives/Tooltip.js @@ -1,18 +1,36 @@ import React from "react"; -// import * as HoverCard from "@radix-ui/react-hover-card"; -// import "../styles/opensigndrive.css"; import { Tooltip as ReactTooltip } from "react-tooltip"; -const Tooltip = ({ children, message }) => ( - <> - <a data-tooltip-id="my-tooltip" data-tooltip-content={message}> +import { openInNewTab } from "../constant/Utils"; +const Tooltip = ({ children, id, message, url, iconColor }) => + url ? ( + <button onClick={() => openInNewTab(url)}> {children ? ( children ) : ( - <i className="fa-solid fa-question border-[1.5px] px-1.5 py-0.5 rounded-full border-[#33bbff] text-xs text-[#33bbff]"></i> + <i className="fa-solid fa-question border-[1.5px] px-1.5 py-0.5 rounded-full border-[#33bbff] text-xs text-[#33bbff]"></i> )} - </a> - <ReactTooltip id="my-tooltip" className="max-w-[200px]" /> - </> -); + </button> + ) : ( + <> + <a + data-tooltip-id={id ? id : "my-tooltip"} + data-tooltip-content={message} + className="z-50" + > + {children ? ( + children + ) : ( + <i + className="fa-solid fa-question z-50 border-[1.5px] px-1.5 py-0.5 rounded-full text-xs" + style={{ + borderColor: iconColor ? iconColor : "#33bbff", + color: iconColor ? iconColor : "#33bbff" + }} + ></i> + )} + </a> + <ReactTooltip id={id ? id : "my-tooltip"} className="max-w-[200px]" /> + </> + ); export default Tooltip; diff --git a/apps/OpenSign/src/styles/AddUser.css b/apps/OpenSign/src/styles/AddUser.css index d8daf6d46..c83395db4 100644 --- a/apps/OpenSign/src/styles/AddUser.css +++ b/apps/OpenSign/src/styles/AddUser.css @@ -101,4 +101,62 @@ .validationlist { background-position: right 1rem top 50%; } +} + +.warning { + position: absolute; + padding: 5px; + border: 1px solid black; + background: white; + width: 250px; + border-radius: 5px; + animation: inAnimation 1s ease-in-out; + z-index: 1; +} + +.defaultvalueWarning { + position: absolute; + left: 20px; +} + +.defaultvalueWarning::before { + content: ""; + width: 0px; + height: 0px; + border-style: outset; + border-width: 0px 10px 10px 10px; + border-color: transparent transparent black transparent; + display: inline-block; + position: absolute; + top: -29%; + left: 0; + right: 75%; + margin: 0 auto; +} + +@keyframes inAnimation { + 0% { + opacity: 0; + visibility: hidden; + } + + 25% { + opacity: 1; + visibility: visible; + } + + 50% { + opacity: 1; + visibility: visible; + } + + 75% { + opacity: 1; + visibility: visible; + } + + 100% { + opacity: 1; + visibility: visible; + } } \ No newline at end of file diff --git a/apps/OpenSign/src/styles/managesign.css b/apps/OpenSign/src/styles/managesign.css index 901f66ae0..94747ef51 100644 --- a/apps/OpenSign/src/styles/managesign.css +++ b/apps/OpenSign/src/styles/managesign.css @@ -18,27 +18,6 @@ z-index: 1; } -.nameWarning { - position: absolute; - bottom: -70px; - left: 10px; -} - -.nameWarning::before { - content: ""; - width: 0px; - height: 0px; - border-style: outset; - border-width: 0px 10px 10px 10px; - border-color: transparent transparent black transparent; - display: inline-block; - position: absolute; - top: -29%; - left: 0; - right: 75%; - margin: 0 auto; -} - .signWarning { bottom: 70px; left: 50px; diff --git a/apps/OpenSign/src/styles/signature.css b/apps/OpenSign/src/styles/signature.css index 5b1543298..5e2ad5078 100644 --- a/apps/OpenSign/src/styles/signature.css +++ b/apps/OpenSign/src/styles/signature.css @@ -19,17 +19,6 @@ cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAASElEQVR4nGNgwAMkJSUbpKSkOvCpIaT5PxSTbogUQjMYMwxeIIXmVFIxA8UGDDyQGg0DnIDi6JKUlCxHMqCeZAOghjSAMD5FAKfeaURdUFxCAAAAAElFTkSuQmCC"), auto; } -.dropdownContainer { - display: flex; - flex-direction: column; - overflow-y: scroll; - max-height: 250px; -} - -.dropdownContainer::-webkit-scrollbar { - display: none; -} - .react-datepicker__input-container { position: initial !important; } From 3e664bf6778d287d4c765418401e2fd959fe4e02 Mon Sep 17 00:00:00 2001 From: RaktimaNXG <raktima.c@nxglabs.com> Date: Tue, 26 Mar 2024 17:29:26 +0530 Subject: [PATCH 33/36] fix: checkbox position issue --- apps/OpenSign/src/components/pdf/PlaceholderType.js | 2 +- apps/OpenSign/src/constant/Utils.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/OpenSign/src/components/pdf/PlaceholderType.js b/apps/OpenSign/src/components/pdf/PlaceholderType.js index d61c8bbca..00e927429 100644 --- a/apps/OpenSign/src/components/pdf/PlaceholderType.js +++ b/apps/OpenSign/src/components/pdf/PlaceholderType.js @@ -353,7 +353,7 @@ function PlaceholderType(props) { <div key={ind} className="flex items-center text-center gap-0.5"> <input style={{ - width: props.pos.Width, + // width: props.pos.Width, display: "flex", justifyContent: "center", marginTop: ind === 0 ? 0 : "5px" diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js index a458e2813..40b71434b 100644 --- a/apps/OpenSign/src/constant/Utils.js +++ b/apps/OpenSign/src/constant/Utils.js @@ -1290,7 +1290,7 @@ export const multiSignEmbed = async ( } checkbox.addToPage(page, { x: xPos(position), - y: yPosition - 2, + y: yPosition - 3, width: height, height: height }); From 49cd30de96d897e109a95db926d8e21e1e1fa49b Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs <prafull.navkar@nxglabs.com> Date: Tue, 26 Mar 2024 19:00:51 +0530 Subject: [PATCH 34/36] refactor: update help message --- apps/OpenSign/src/components/shared/fields/SignersInput.js | 4 ++-- apps/OpenSign/src/json/ReportJson.js | 2 +- apps/OpenSign/src/pages/UserProfile.js | 2 +- apps/OpenSign/src/primitives/Tooltip.js | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/OpenSign/src/components/shared/fields/SignersInput.js b/apps/OpenSign/src/components/shared/fields/SignersInput.js index 2b2648db6..de06665d2 100644 --- a/apps/OpenSign/src/components/shared/fields/SignersInput.js +++ b/apps/OpenSign/src/components/shared/fields/SignersInput.js @@ -108,10 +108,10 @@ const SignersInput = (props) => { <label className="block"> Signers {props.required && <span className="text-red-500 text-[13px]">*</span>} - <span className="ml-1 text-xs z-[999]"> + <span className="absolute ml-1 text-xs z-50"> <Tooltip id={"signer-tooltip"} - message={"This is a list of contacts/signers added by you"} + message={"Begin typing a contact's name to see suggested signers from your saved contacts or add new ones. Arrange the signing order by adding signers in the desired sequence. Use the '+' button to include signers and the 'x' to remove them. Each signer will receive an email prompt to sign the document in the order listed."} /> </span> </label> diff --git a/apps/OpenSign/src/json/ReportJson.js b/apps/OpenSign/src/json/ReportJson.js index 37d0c94bb..39768e75e 100644 --- a/apps/OpenSign/src/json/ReportJson.js +++ b/apps/OpenSign/src/json/ReportJson.js @@ -186,7 +186,7 @@ export default function reportJson(id) { } ], helpMsg: - "This is a list of templates that are used to create documents" + "This is a list of templates that are available to you for creating documents. You can click the 'use' button to create a new document using a template, modify the document & add signers in the next step." }; default: return null; diff --git a/apps/OpenSign/src/pages/UserProfile.js b/apps/OpenSign/src/pages/UserProfile.js index 842f8129b..b8d9da22c 100644 --- a/apps/OpenSign/src/pages/UserProfile.js +++ b/apps/OpenSign/src/pages/UserProfile.js @@ -264,7 +264,7 @@ function UserProfile() { <div className="flex justify-between items-center py-2"> <span className="font-semibold"> Disable DocumentId :{" "} - <Tooltip url={"https://docs.opensignlabs.com/docs/help/Settings/profile/"} />{" "} + <Tooltip url={"https://docs.opensignlabs.com/docs/help/Settings/disabledocumentid"} />{" "} </span>{" "} <label className={`${ diff --git a/apps/OpenSign/src/primitives/Tooltip.js b/apps/OpenSign/src/primitives/Tooltip.js index 323afc3d5..41e685d7c 100644 --- a/apps/OpenSign/src/primitives/Tooltip.js +++ b/apps/OpenSign/src/primitives/Tooltip.js @@ -3,11 +3,11 @@ import { Tooltip as ReactTooltip } from "react-tooltip"; import { openInNewTab } from "../constant/Utils"; const Tooltip = ({ children, id, message, url, iconColor }) => url ? ( - <button onClick={() => openInNewTab(url)}> + <button onClick={() => openInNewTab(url)} className="text-center"> {children ? ( children ) : ( - <i className="fa-solid fa-question border-[1.5px] px-1.5 py-0.5 rounded-full border-[#33bbff] text-xs text-[#33bbff]"></i> + <i className="fa-solid fa-question text-xs border-[1.5px] px-1 rounded-full border-[#33bbff] text-[#33bbff]"></i> )} </button> ) : ( @@ -21,7 +21,7 @@ const Tooltip = ({ children, id, message, url, iconColor }) => children ) : ( <i - className="fa-solid fa-question z-50 border-[1.5px] px-1.5 py-0.5 rounded-full text-xs" + className="fa-solid fa-question text-xs border-[1.5px] px-1 rounded-full border-[#33bbff] text-[#33bbff]" style={{ borderColor: iconColor ? iconColor : "#33bbff", color: iconColor ? iconColor : "#33bbff" From cd4fd6e3de5ca716dd5761299e4665a31e1371ba Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs <prafull.navkar@nxglabs.com> Date: Tue, 26 Mar 2024 19:12:38 +0530 Subject: [PATCH 35/36] refactor: change help message of contact report --- apps/OpenSign/src/json/ReportJson.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/OpenSign/src/json/ReportJson.js b/apps/OpenSign/src/json/ReportJson.js index 39768e75e..1c002c8ab 100644 --- a/apps/OpenSign/src/json/ReportJson.js +++ b/apps/OpenSign/src/json/ReportJson.js @@ -162,7 +162,7 @@ export default function reportJson(id) { } ], form: "ContactBook", - helpMsg: "This is a list of contacts/signers that have been added by you." + helpMsg: "This is a list of contacts/signers added by you. These will appear as suggestions when you try to add signers to a new document." }; // template report case "6TeaPr321t": From 1f350fc45933c575d0c0a5bb25e3f6d7521845e3 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs <prafull.navkar@nxglabs.com> Date: Tue, 26 Mar 2024 20:48:41 +0530 Subject: [PATCH 36/36] fix: move document to folder in opensigndrive not working --- .../src/components/opensigndrive/DriveBody.js | 9 +- .../components/shared/fields/FolderModal.js | 234 ++++++++++++++++++ 2 files changed, 239 insertions(+), 4 deletions(-) create mode 100644 apps/OpenSign/src/components/shared/fields/FolderModal.js diff --git a/apps/OpenSign/src/components/opensigndrive/DriveBody.js b/apps/OpenSign/src/components/opensigndrive/DriveBody.js index a550e8eef..b8c2bdd56 100644 --- a/apps/OpenSign/src/components/opensigndrive/DriveBody.js +++ b/apps/OpenSign/src/components/opensigndrive/DriveBody.js @@ -8,9 +8,9 @@ import { saveAs } from "file-saver"; import { useNavigate } from "react-router-dom"; import Table from "react-bootstrap/Table"; import * as HoverCard from "@radix-ui/react-hover-card"; -import SelectFolder from "../shared/fields/SelectFolder"; //check this one import ModalUi from "../../primitives/ModalUi"; import { themeColor } from "../../constant/const"; +import FolderModal from "../shared/fields/FolderModal"; function DriveBody(props) { const [rename, setRename] = useState(""); @@ -214,8 +214,8 @@ function DriveBody(props) { ? true : false : selecFolderId - ? false - : true; + ? false + : true; if (!checkExist) { if (moveFolderId) { updateData = { @@ -594,8 +594,9 @@ function DriveBody(props) { })} </div> )} + {isOpenMoveModal && ( - <SelectFolder + <FolderModal onSuccess={handleMoveFolder} isOpenModal={isOpenMoveModal} folderCls={"contracts_Document"} diff --git a/apps/OpenSign/src/components/shared/fields/FolderModal.js b/apps/OpenSign/src/components/shared/fields/FolderModal.js new file mode 100644 index 000000000..8bc46403c --- /dev/null +++ b/apps/OpenSign/src/components/shared/fields/FolderModal.js @@ -0,0 +1,234 @@ +import React, { useEffect, useState } from "react"; +import Parse from "parse"; +import CreateFolder from "./CreateFolder"; +import ModalUi from "../../../primitives/ModalUi"; + +const FolderModal = (props) => { + const [clickFolder, setClickFolder] = useState(""); + const [folderList, setFolderList] = useState([]); + const [tabList, setTabList] = useState([]); + const [isLoader, setIsLoader] = useState(false); + const [isAdd, setIsAdd] = useState(false); + // below useEffect is called when user open popup + useEffect(() => { + if (props.isOpenModal) { + fetchFolder(); + } + // eslint-disable-next-line + }, [props.isOpenModal]); + + // `fetchFolder` is used to fetch of folder list created by user on basis of folderPtr or without folderPtr + const fetchFolder = async (folderPtr) => { + setIsLoader(true); + try { + const FolderQuery = new Parse.Query(props.folderCls); + if (folderPtr) { + FolderQuery.equalTo("Folder", folderPtr); + FolderQuery.equalTo("Type", "Folder"); + } else { + FolderQuery.doesNotExist("Folder"); + FolderQuery.equalTo("Type", "Folder"); + } + + const res = await FolderQuery.find(); + if (res) { + const result = JSON.parse(JSON.stringify(res)); + if (result) { + setFolderList(result); + setIsLoader(false); + } + setIsLoader(false); + } + } catch (error) { + setIsLoader(false); + } + }; + + // `handleSelect` is used to save pointer of folder selected by user and it's path in state + const handleSelect = (item) => { + setFolderList([]); + setClickFolder({ ObjectId: item.objectId, Name: item.Name }); + if (tabList.length > 0) { + const tab = tabList.some((x) => x.objectId === item.objectId); + if (!tab) { + setTabList((tabs) => [...tabs, item]); + const folderPtr = { + __type: "Pointer", + className: props.folderCls, + objectId: item.objectId + }; + fetchFolder(folderPtr); + } + } else { + setTabList((tabs) => [...tabs, item]); + const folderPtr = { + __type: "Pointer", + className: props.folderCls, + objectId: item.objectId + }; + + fetchFolder(folderPtr); + } + }; + + // `handleSubmit` is used to pass folderPtr to parent component + const handleSubmit = () => { + let url = "OpenSign™ Drive"; + tabList.forEach((t) => { + url = url + " / " + t.Name; + }); + if (props.onSuccess) { + props.onSuccess(clickFolder); + } + // SetIsOpen(false); + props.setIsOpenMoveModal(false); + }; + + // `handleCancel` is used to clear list of folder, close popup and folderUrl + const handleCancel = () => { + // SetIsOpen(false); + props.setIsOpenMoveModal(false); + setClickFolder({}); + setFolderList([]); + setTabList([]); + }; + + // `handleCancel` is call when user click on folder name from path/tab in popup + const removeTabListItem = async (e, i) => { + e.preventDefault(); + // setEditable(false); + if (!isAdd) { + setIsLoader(true); + let folderPtr; + if (i) { + setFolderList([]); + let list = tabList.filter((itm, j) => { + if (j <= i) { + return itm; + } + }); + let _len = list.length - 1; + folderPtr = { + __type: "Pointer", + className: props.folderCls, + objectId: list[_len].objectId + }; + setTabList(list); + } else { + setClickFolder({}); + setFolderList([]); + setTabList([]); + } + fetchFolder(folderPtr); + } + }; + // `handleCreate` is used to open folder creation form in popup + const handleCreate = () => { + setIsAdd(!isAdd); + }; + // `handleAddFolder` is call when user folder created successfully and it fetch folder list on the basis of folderPtr or without folderPtr + const handleAddFolder = (newFolder) => { + props.setPdfData((prev) => [...prev, newFolder?.toJSON()]); + if (clickFolder && clickFolder.ObjectId) { + fetchFolder({ + __type: "Pointer", + className: props.folderCls, + objectId: clickFolder.ObjectId + }); + } else { + fetchFolder(); + } + handleCreate(); + }; + return ( + <div className="text-xs mt-2 "> + <ModalUi + title={"Select Folder"} + isOpen={props.isOpenModal} + handleClose={handleCancel} + > + <div className="w-full min-w-[300px] md:min-w-[500px] max-w-[500px] px-3"> + <div className="py-2 text-[#ac4848] text-[14px] font-[500]"> + <span + className="cursor-pointer" + title="OpenSign™ Drive" + onClick={(e) => removeTabListItem(e)} + > + OpenSign™ Drive /{" "} + </span> + {tabList && + tabList.map((tab, i) => ( + <React.Fragment key={`${tab.objectId}-${i}`}> + <span + className="cursor-pointer" + title={tab.Name} + onClick={(e) => removeTabListItem(e, i)} + > + {tab.Name} + </span> + {" / "} + </React.Fragment> + ))} + <hr /> + </div> + <div className="mt-2 mb-3"> + <div className="max-h-[210px] overflow-auto"> + {!isAdd && + folderList.length > 0 && + folderList.map((folder) => ( + <div + key={folder.Name} + className="border-[1px] border-[#8a8a8a] px-2 py-2 mb-2 cursor-pointer " + onClick={() => handleSelect(folder)} + > + <div className="flex items-center gap-2"> + <i + className="fa fa-folder text-[#33bbff] text-[1.4rem]" + aria-hidden="true" + ></i> + <span className="font-semibold">{folder.Name}</span> + </div> + </div> + ))} + </div> + {isAdd && ( + <CreateFolder + parentFolderId={clickFolder && clickFolder.ObjectId} + folderCls={props.folderCls} + onSuccess={handleAddFolder} + /> + )} + {isLoader && ( + <div className="flex justify-center"> + <i className="fa-solid fa-spinner fa-spin-pulse text-[30px]"></i> + </div> + )} + </div> + </div> + <hr /> + <div className="flex justify-between items-center py-[.75rem] px-[1.25rem]"> + <div + className="text-[30px] cursor-pointer text-[#32a3ac]" + title="Save Here" + onClick={handleCreate} + > + {isAdd ? ( + <i className="fa-solid fa-arrow-left" aria-hidden="true"></i> + ) : ( + <i className="fa-solid fa-square-plus" aria-hidden="true"></i> + )} + </div> + <div + className="text-[30px] cursor-pointer" + title="Save Here" + onClick={handleSubmit} + > + <i className="fas fa-save" aria-hidden="true"></i> + </div> + </div> + </ModalUi> + </div> + ); +}; + +export default FolderModal;