diff --git a/apps/OpenSign/src/App.js b/apps/OpenSign/src/App.js index 500e00808..cbfc5141a 100644 --- a/apps/OpenSign/src/App.js +++ b/apps/OpenSign/src/App.js @@ -15,6 +15,7 @@ import ForgetPassword from "./routes/ForgetPassword"; import ChangePassword from "./routes/ChangePassword"; import ReportMicroapp from "./components/ReportMicroapp"; import LoadMf from "./routes/LoadMf"; +import ValidateRoute from "./primitives/ValidateRoute"; function App() { const [isloading, setIsLoading] = useState(true); @@ -58,8 +59,24 @@ function App() { ) : ( - } /> - } /> + + + + } + /> + + + + } + /> } /> } /> {process.env.REACT_APP_ENABLE_SUBSCRIPTION && ( diff --git a/apps/OpenSign/src/components/LoginFacebook.js b/apps/OpenSign/src/components/LoginFacebook.js index 1dd0297a4..033208d57 100644 --- a/apps/OpenSign/src/components/LoginFacebook.js +++ b/apps/OpenSign/src/components/LoginFacebook.js @@ -86,7 +86,7 @@ const LoginFacebook = ({ email: userDetails.Email, // "passsword":userDetails.Phone, phone: userDetails.Phone, - role: "contracts_Admin", + role: "contracts_User", company: userDetails.Company } }; diff --git a/apps/OpenSign/src/components/LoginGoogle.js b/apps/OpenSign/src/components/LoginGoogle.js index e0b3ed6c1..a95f903bf 100644 --- a/apps/OpenSign/src/components/LoginGoogle.js +++ b/apps/OpenSign/src/components/LoginGoogle.js @@ -148,7 +148,7 @@ const GoogleSignInBtn = ({ email: userDetails.Email, // "passsword":userDetails.Phone, phone: userDetails.Phone, - role: "contracts_Admin", + role: "contracts_User", company: userDetails.Company, jobTitle: userDetails.Destination } diff --git a/apps/OpenSign/src/components/fields/CreateFolder.js b/apps/OpenSign/src/components/fields/CreateFolder.js index 1f921e904..7c13e6145 100644 --- a/apps/OpenSign/src/components/fields/CreateFolder.js +++ b/apps/OpenSign/src/components/fields/CreateFolder.js @@ -74,15 +74,15 @@ const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => { template.set("CreatedBy", Parse.User.createWithoutData(currentUser.id)); const res = await template.save(); if (res) { + setAlert({ + type: "success", + message: "Folder created successfully!" + }); + setIsAlert(true); + setTimeout(() => { + setIsAlert(false); + }, 1000); if (onSuccess) { - setAlert({ - type: "success", - message: "Folder created successfully!" - }); - setIsAlert(true); - setTimeout(() => { - setIsAlert(false); - }, 1000); onSuccess(res); } } diff --git a/apps/OpenSign/src/components/fields/SelectFolder.js b/apps/OpenSign/src/components/fields/SelectFolder.js index 13c2ff157..38694b740 100644 --- a/apps/OpenSign/src/components/fields/SelectFolder.js +++ b/apps/OpenSign/src/components/fields/SelectFolder.js @@ -135,6 +135,7 @@ const SelectFolder = ({ required, onSuccess, folderCls }) => { } else { fetchFolder(); } + handleCreate(); }; return (
@@ -253,101 +254,6 @@ const SelectFolder = ({ required, onSuccess, folderCls }) => {
- {/* {isOpen && ( -
-
-
- Select Folder -
-
- -
-
-
-
-
- removeTabListItem(e)} - > - Root /{" "} - - {tabList && - tabList.map((tab, i) => ( - - removeTabListItem(e, i)} - > - {tab.Name} - - {" / "} - - ))} -
-
-
- {!isAdd && - folderList.length > 0 && - folderList.map((folder) => ( -
handleSelect(folder)} - > -
- - {folder.Name} -
-
- ))} - {isAdd && ( - - )} - {isLoader && ( -
- -
- )} -
-
-
-
-
- {isAdd ? ( - - ) : ( - - )} -
-
- -
-
-
- )} */} ); }; diff --git a/apps/OpenSign/src/layout/HomeLayout.js b/apps/OpenSign/src/layout/HomeLayout.js index 5583df9c5..a0ca72170 100644 --- a/apps/OpenSign/src/layout/HomeLayout.js +++ b/apps/OpenSign/src/layout/HomeLayout.js @@ -7,10 +7,35 @@ import Tour from "reactour"; import axios from "axios"; import { useSelector } from "react-redux"; import Parse from "parse"; +import ModalUi from "../primitives/ModalUi"; +import { useNavigate } from "react-router-dom"; + const HomeLayout = ({ children }) => { + const navigate = useNavigate(); const { width } = useWindowSize(); const [isOpen, setIsOpen] = useState(true); const arr = useSelector((state) => state.TourSteps); + const [isUserValid, setIsUserValid] = useState(true); + + useEffect(() => { + (async () => { + try { + // Use the session token to validate the user + const userQuery = new Parse.Query(Parse.User); + const user = await userQuery.get(Parse.User.current().id, { + sessionToken: localStorage.getItem("accesstoken") + }); + if (user) { + setIsUserValid(true); + } else { + setIsUserValid(false); + } + } catch (error) { + // Session token is invalid or there was an error + setIsUserValid(false); + } + })(); + }, []); // reactour state const [isCloseBtn, setIsCloseBtn] = useState(true); @@ -19,7 +44,7 @@ const HomeLayout = ({ children }) => { const [tourConfigs, setTourConfigs] = useState([]); const showSidebar = () => { - setIsOpen(value => !value); + setIsOpen((value) => !value); }; useEffect(() => { if (width && width <= 768) { @@ -28,9 +53,7 @@ const HomeLayout = ({ children }) => { }, [width]); useEffect(() => { - if (localStorage.getItem("domain") === "sign" && arr && arr.length > 0) { - handleDynamicSteps(); - } else if ( + if ( localStorage.getItem("domain") === "contracts" && arr && arr.length > 0 @@ -153,32 +176,59 @@ const HomeLayout = ({ children }) => { setIsOpen(false); } }; + + const handleLoginBtn = () => { + try { + Parse.User.logOut(); + } catch (err) { + console.log("err ", err); + } finally { + localStorage.removeItem("accesstoken"); + navigate("/", { replace: true }); + } + }; return (
-
- + {isUserValid ? ( + <> +
+ -
-
{children}
-
-
+
+
{children}
+
+
+
+
-
-
- + + + ) : ( + +
+

Your session has expired.

+ +
+
+ )}
); }; diff --git a/apps/OpenSign/src/primitives/GetReportDisplay.js b/apps/OpenSign/src/primitives/GetReportDisplay.js index fed2f1d48..c6d5d04ad 100644 --- a/apps/OpenSign/src/primitives/GetReportDisplay.js +++ b/apps/OpenSign/src/primitives/GetReportDisplay.js @@ -21,7 +21,11 @@ const ReportTable = ({ const [actLoader, setActLoader] = useState({}); const [isAlert, setIsAlert] = useState(false); const [isErr, setIsErr] = useState(false); - const [isPopup, setIsPopup] = useState(false); + const [isDocErr, setIsDocErr] = useState(false); + const [isContactform, setIsContactform] = useState(false); + const [isDeleteModal, setIsDeleteModal] = useState({}); + const startIndex = (currentPage - 1) * docPerPage; + // For loop is used to calculate page numbers visible below table // Initialize pageNumbers using useMemo to avoid unnecessary re-creation const pageNumbers = useMemo(() => { @@ -64,7 +68,7 @@ const ReportTable = ({ if (btnLabel === "Edit") { navigate(`/asmf/${url}/${item.objectId}`); } else { - setActLoader({ [item.objectId]: true }); + setActLoader({ [`${item.objectId}_${btnLabel}`]: true }); try { const params = { templateId: item.objectId @@ -87,10 +91,6 @@ const ReportTable = ({ if (!templateData.error) { const Doc = templateData; - let placeholdersArr = []; - if (Doc.Placeholders?.length > 0) { - placeholdersArr = Doc.Placeholders; - } let signers = []; if (Doc.Signers?.length > 0) { Doc.Signers?.forEach((x) => { @@ -104,45 +104,63 @@ const ReportTable = ({ } }); } - const data = { - Name: Doc.Name, - URL: Doc.URL, - SignedUrl: Doc.SignedUrl, - Description: Doc.Description, - Note: Doc.Note, - Placeholders: placeholdersArr, - ExtUserPtr: { - __type: "Pointer", - className: "contracts_Users", - objectId: Doc.ExtUserPtr.objectId - }, - CreatedBy: { - __type: "Pointer", - className: "_User", - objectId: Doc.CreatedBy.objectId - }, - Signers: signers - }; - const res = await axios.post( - `${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( - "_appName" - )}_Document`, - data, - { - headers: { - "Content-Type": "application/json", - "X-Parse-Application-Id": localStorage.getItem("parseAppId"), - "X-Parse-Session-Token": localStorage.getItem("accesstoken") + let placeholdersArr = []; + if (Doc.Placeholders?.length > 0) { + placeholdersArr = Doc.Placeholders; + const data = { + Name: Doc.Name, + URL: Doc.URL, + SignedUrl: Doc.SignedUrl, + Description: Doc.Description, + Note: Doc.Note, + Placeholders: placeholdersArr, + ExtUserPtr: { + __type: "Pointer", + className: "contracts_Users", + objectId: Doc.ExtUserPtr.objectId + }, + CreatedBy: { + __type: "Pointer", + className: "_User", + objectId: Doc.CreatedBy.objectId + }, + Signers: signers + }; + try { + const res = await axios.post( + `${localStorage.getItem( + "baseUrl" + )}classes/${localStorage.getItem("_appName")}_Document`, + data, + { + headers: { + "Content-Type": "application/json", + "X-Parse-Application-Id": + localStorage.getItem("parseAppId"), + "X-Parse-Session-Token": + localStorage.getItem("accesstoken") + } + } + ); + + // console.log("Res ", res.data); + if (res.data && res.data.objectId) { + setActLoader({}); + setIsAlert(true); + navigate(`/asmf/${url}/${res.data.objectId}`, { + state: { title: "Use Template" } + }); } + } catch (err) { + console.log("Err", err); + setIsAlert(true); + setIsErr(true); + setActLoader({}); } - ); - - // console.log("Res ", res.data); - if (res.data && res.data.objectId) { + } else { + setIsDocErr(true); setActLoader({}); - setIsAlert(true); - navigate(`/asmf/${url}/${res.data.objectId}`); } } else { setIsAlert(true); @@ -166,31 +184,7 @@ const ReportTable = ({ }; const handlebtn = async (item) => { if (ReportName === "Contactbook") { - setActLoader({ [item.objectId]: true }); - try { - const url = - process.env.REACT_APP_SERVERURL + "/classes/contracts_Contactbook/"; - const body = { IsDeleted: true }; - const res = await axios.put(url + item.objectId, body, { - headers: { - "Content-Type": "application/json", - "X-Parse-Application-Id": localStorage.getItem("AppID12"), - "X-Parse-Session-Token": localStorage.getItem("accesstoken") - } - }); - // console.log("Res ", res.data); - if (res.data && res.data.updatedAt) { - setActLoader({}); - setIsAlert(true); - const upldatedList = List.filter((x) => x.objectId !== item.objectId); - setList(upldatedList); - } - } catch (err) { - console.log("err", err); - setIsAlert(true); - setIsErr(true); - setActLoader({}); - } + setIsDeleteModal({ [item.objectId]: true }); } }; @@ -204,13 +198,44 @@ const ReportTable = ({ const paginateFront = () => setCurrentPage(currentPage + 1); const paginateBack = () => setCurrentPage(currentPage - 1); - const handlePopup = () => { - setIsPopup(!isPopup); + const handleContactFormModal = () => { + setIsContactform(!isContactform); }; const handleUserData = (data) => { setList((prevData) => [data, ...prevData]); }; + + const handleDelete = async (item) => { + setIsDeleteModal({}); + setActLoader({ [item.objectId]: true }); + try { + const url = + process.env.REACT_APP_SERVERURL + "/classes/contracts_Contactbook/"; + const body = { IsDeleted: true }; + const res = await axios.put(url + item.objectId, body, { + headers: { + "Content-Type": "application/json", + "X-Parse-Application-Id": localStorage.getItem("AppID12"), + "X-Parse-Session-Token": localStorage.getItem("accesstoken") + } + }); + // console.log("Res ", res.data); + if (res.data && res.data.updatedAt) { + setActLoader({}); + setIsAlert(true); + const upldatedList = List.filter((x) => x.objectId !== item.objectId); + setList(upldatedList); + } + } catch (err) { + console.log("err", err); + setIsAlert(true); + setIsErr(true); + setActLoader({}); + } + }; + const handleCloseDeleteModal = () => setIsDeleteModal({}); + return (
{isAlert && ( @@ -228,7 +253,10 @@ const ReportTable = ({
{ReportName}
{form && ( -
handlePopup()}> +
handleContactFormModal()} + >
)} @@ -253,12 +281,12 @@ const ReportTable = ({ ReportName === "Contactbook" ? ( {heading.includes("Sr.No") && ( - {index + 1} + {startIndex + index + 1} )} {item?.Name} {item?.Email || "-"} {item?.Phone || "-"} - + {actions?.length > 0 && actions.map((act, index) => ( + +
+
+ + )} ) : ( {heading.includes("Sr.No") && ( - {index + 1} + {startIndex + index + 1} )} - {item?.Name} + + {item?.Name}{" "} + {heading.includes("Note") && ( {item?.Note || "-"} )} @@ -327,7 +385,7 @@ const ReportTable = ({ {item?.Signers ? formatRow(item?.Signers) : "-"} - + {actions?.length > 0 && actions.map((act, index) => (
)} - + + setIsDocErr(false)} + > +
+

Please add receipent in template!

+
+
); }; diff --git a/apps/OpenSign/src/primitives/ModalUi.js b/apps/OpenSign/src/primitives/ModalUi.js index f5926e081..a00a28b61 100644 --- a/apps/OpenSign/src/primitives/ModalUi.js +++ b/apps/OpenSign/src/primitives/ModalUi.js @@ -1,21 +1,35 @@ import React from "react"; -const ModalUi = ({ children, title, isOpen, handleClose }) => { - +const ModalUi = ({ + children, + title, + isOpen, + headColor, + handleClose, + showHeader = true, + showClose = true +}) => { return ( <> {isOpen && (
-
-
-
{title}
+
+ {showHeader && (
handleClose && handleClose()} + className="flex justify-between rounded-t items-center py-[15px] px-[20px] text-white" + style={{ background: headColor ? headColor : "#32a3ac" }} > - × +
{title}
+ {showClose && ( +
handleClose && handleClose()} + > + × +
+ )}
-
-
{children}
+ )} +
{children}
)} diff --git a/apps/OpenSign/src/primitives/ValidateRoute.js b/apps/OpenSign/src/primitives/ValidateRoute.js new file mode 100644 index 000000000..62202dfe6 --- /dev/null +++ b/apps/OpenSign/src/primitives/ValidateRoute.js @@ -0,0 +1,34 @@ +import React, { useEffect } from "react"; +import Parse from "parse"; + +const ValidateRoute = ({ children }) => { + useEffect(() => { + (async () => { + try { + // Use the session token to validate the user + const userQuery = new Parse.Query(Parse.User); + const user = await userQuery.get(Parse.User.current().id, { + sessionToken: localStorage.getItem("accesstoken") + }); + if (!user) { + handlelogout(); + } + } catch (error) { + handlelogout(); + } + })(); + }, []); + const handlelogout = async () => { + try { + Parse.User.logOut(); + localStorage.removeItem("accesstoken"); + } catch (err) { + console.log("err ", err); + } finally { + localStorage.removeItem("accesstoken"); + } + }; + return
{children}
; +}; + +export default ValidateRoute; diff --git a/apps/OpenSign/src/routes/Pgsignup.js b/apps/OpenSign/src/routes/Pgsignup.js index 5a48be5f8..af4cc0108 100644 --- a/apps/OpenSign/src/routes/Pgsignup.js +++ b/apps/OpenSign/src/routes/Pgsignup.js @@ -74,8 +74,8 @@ const PgSignUp = (props) => { const res = await Parse.Cloud.run("getUserDetails", params); // console.log("res", res); if (res) { - const checkUser = new Parse.Query(extClass); - const updateQuery = await checkUser.get(res.id); + const updateQuery = new Parse.Object(extClass); + updateQuery.id = res.id; updateQuery.set( "Next_billing_date", new Date(zohoRes.data.result.nextBillingDate) diff --git a/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js b/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js index 3bbabdad2..b6f989cb7 100644 --- a/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js +++ b/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js @@ -2,7 +2,7 @@ import SignPDF from './SignPDF.min.cjs'; import fs from 'node:fs'; import axios from 'axios'; import FormData from 'form-data'; -import plainplaceholder from './customSignPdf/plainplaceholder.min.js'; +// import plainplaceholder from './customSignPdf/plainplaceholder.min.js'; import { plainAddPlaceholder } from 'node-signpdf/dist/helpers/index.js'; const serverUrl = process.env.SERVER_URL, APPID = process.env.APP_ID, @@ -19,20 +19,20 @@ async function uploadFile(a) { console.log('err ', e), fs.unlinkSync(a); } } -async function updateDoc(t, s, r, i, o, n) { +async function updateDoc(t, s, r, i, n, o) { try { var d = { - UserPtr: { __type: 'Pointer', className: n, objectId: r }, + UserPtr: { __type: 'Pointer', className: o, objectId: r }, SignedUrl: s, Activity: 'Signed', ipAddress: i, }; let e; - var l = (e = o.AuditTrail && 0 < o.AuditTrail.length ? [...o.AuditTrail, d] : [d]).filter( + var l = (e = n.AuditTrail && 0 < n.AuditTrail.length ? [...n.AuditTrail, d] : [d]).filter( e => 'Signed' === e.Activity ); let a = !1; - !((o.Signers && 0 < o.Signers.length && l.length !== o.Signers.length) || !(a = !0)); + !((n.Signers && 0 < n.Signers.length && l.length !== n.Signers.length) || !(a = !0)); var p = { SignedUrl: s, AuditTrail: e, IsCompleted: a }; await axios.put(serverUrl + '/classes/contracts_Document/' + t, p, { headers: { @@ -61,7 +61,7 @@ async function sendMail(e) { s + ' Standard is attached to this email. Kindly download the document from the attachment.

This is an automated email from Open Sign. For any queries regarding this email, please contact the sender ' + t.Mail + - ' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.

', + ' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.

' }; await axios.post(serverUrl + '/functions/sendmailv3', a, { headers: { @@ -86,7 +86,7 @@ async function sendCompletedMail(e) { s + '. Kindly download the document from the attachment.

This is an automated email from Open Sign. For any queries regarding this email, please contact the sender ' + t.Mail + - ' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.

', + ' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.

', }; await axios.post(serverUrl + '/functions/sendmailv3', a, { headers: { @@ -96,115 +96,135 @@ async function sendCompletedMail(e) { }, }); } -async function PDF(s, r) { +async function PDF(i, n) { try { - var i = s.params.sign, - e = s.params.docId, - o = s.params.userId, - n = await axios.get(serverUrl + '/classes/contracts_Document/' + e + '?include=ExtUserPtr', { - headers: { - 'Content-Type': 'application/json', - 'X-Parse-Application-Id': APPID, - 'X-Parse-Master-Key': masterKEY, - }, - }), - d = await axios.get(serverUrl + '/users/me', { + i.params.sign; + var e = i.params.docId, + a = i.params.userId, + o = await axios.get( + serverUrl + '/classes/contracts_Document/' + e + '?include=ExtUserPtr,Signers', + { + headers: { + 'Content-Type': 'application/json', + 'X-Parse-Application-Id': APPID, + 'X-Parse-Master-Key': masterKEY, + }, + } + ), + t = await axios.get(serverUrl + '/users/me', { headers: { 'X-Parse-Application-Id': APPID, - 'X-Parse-Session-Token': s.headers.sessiontoken, + 'X-Parse-Session-Token': i.headers.sessiontoken, }, }); - if (!d.data || !d.data.objectId) return { status: 'error', message: 'this user not allowed!' }; + if (!t.data || !t.data.objectId) return { status: 'error', message: 'this user not allowed!' }; { - var l, + var d, + l, p, - c, - m = JSON.stringify({ objectId: o }); - let a, t; - t = o - ? (l = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + m, { + c = JSON.stringify({ objectId: a }); + let s, r; + r = a + ? (d = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + c, { headers: { 'X-Parse-Application-Id': APPID, - 'X-Parse-Session-Token': s.headers.sessiontoken, + 'X-Parse-Session-Token': i.headers.sessiontoken, }, - })).data && 0 < l.data.results.length - ? ((a = l), 'contracts_Contactbook') - : ((a = await axios.get(serverUrl + '/classes/contracts_Users?where=' + m, { - headers: { - 'X-Parse-Application-Id': APPID, - 'X-Parse-Master-Key': masterKEY, - }, + })).data && 0 < d.data.results.length + ? ((s = d), 'contracts_Contactbook') + : ((s = await axios.get(serverUrl + '/classes/contracts_Users?where=' + c, { + headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY }, })), 'contracts_Users') - : ((p = JSON.stringify({ - UserId: { __type: 'Pointer', className: '_User', objectId: d.data.objectId }, + : ((l = JSON.stringify({ + UserId: { __type: 'Pointer', className: '_User', objectId: t.data.objectId }, })), - (c = await axios.get(serverUrl + '/classes/contracts_Users?where=' + p, { - headers: { - 'X-Parse-Application-Id': APPID, - 'X-Parse-Master-Key': masterKEY, - }, - })).data && 0 < c.data.results.length - ? ((a = c), 'contracts_Users') - : ((a = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + p, { + (p = await axios.get(serverUrl + '/classes/contracts_Users?where=' + l, { + headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY }, + })).data && 0 < p.data.results.length + ? ((s = p), 'contracts_Users') + : ((s = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + l, { headers: { 'X-Parse-Application-Id': APPID, - 'X-Parse-Session-Token': s.headers.sessiontoken, + 'X-Parse-Session-Token': i.headers.sessiontoken, }, })), 'contracts_Contactbook')); - var g = a.data.results[0].Name, - h = a.data.results[0].Email; - if (!s.params.pdfFile) return { status: 'error', message: 'pdf file not present!' }; + var m = s.data.results[0].Name, + g = s.data.results[0].Email; + if (!i.params.pdfFile) return { status: 'error', message: 'pdf file not present!' }; { - let e = Buffer.from(s.params.pdfFile, 'base64'); + let e = Buffer.from(i.params.pdfFile, 'base64'); var u = process.env.PFX_BASE64, - f = Buffer.from(u, 'base64'); - e = i - ? plainplaceholder({ - pdfBuffer: e, - reason: 'Digitally signed by Open sign for ' + g + ' <' + h + '>', - location: 'test location', - signatureLength: 1e4, - sign: i, - }) - : plainAddPlaceholder({ - pdfBuffer: e, - reason: 'Digitally signed by Open sign for ' + g + ' <' + h + '>', - location: 'test location', - signatureLength: 1e4, - }); - var y = await new SignPDF(e, f).signPDF(), - v = `./exports/exported_file_${Math.floor(5e3 * Math.random())}.pdf`, - P = (fs.writeFileSync(v, y), await uploadFile(v)); - if (P && P.imageUrl) { - const r = await updateDoc( - s.params.docId, - P.imageUrl, - a.data.results[0].objectId, - s.headers['x-real-ip'], - n.data, - t + h = Buffer.from(u, 'base64'), + f = { + UserPtr: { __type: 'Pointer', className: r, objectId: s.data.results[0].objectId }, + SignedUrl: '', + Activity: 'Signed', + ipAddress: i.headers['x-real-ip'], + }; + let a; + var y = (a = + o.data.AuditTrail && 0 < o.data.AuditTrail.length + ? [...o.data.AuditTrail, f] + : [f]).filter(e => 'Signed' === e.Activity); + let t = !1; + !( + (o.data.Signers && 0 < o.data.Signers.length && y.length !== o.data.Signers.length) || + !(t = !0) + ); + var v, + P, + x = `./exports/exported_file_${Math.floor(5e3 * Math.random())}.pdf`, + A = + (t + ? ((v = o.data.Signers?.map(e => e.Name + ' <' + e.Email + '>')), + (e = + v && 0 < v.length + ? plainAddPlaceholder({ + pdfBuffer: e, + reason: 'Digitally signed by Open sign for ' + v?.join(', '), + location: 'location', + signatureLength: 1e4, + }) + : plainAddPlaceholder({ + pdfBuffer: e, + reason: 'Digitally signed by Open sign for ' + m + ' <' + g + '>', + location: 'location', + signatureLength: 1e4, + })), + (P = await new SignPDF(e, h).signPDF()), + fs.writeFileSync(x, P)) + : fs.writeFileSync(x, e), + await uploadFile(x)); + if (A && A.imageUrl) { + const n = await updateDoc( + i.params.docId, + A.imageUrl, + s.data.results[0].objectId, + i.headers['x-real-ip'], + o.data, + r ); return ( sendMail({ - url: P.imageUrl, - sender: { Mail: n.data.ExtUserPtr.Email, Name: n.data.ExtUserPtr.Name }, - pdfName: n.data.Name, - receiver: h, + url: A.imageUrl, + sender: { Mail: o.data.ExtUserPtr.Email, Name: o.data.ExtUserPtr.Name }, + pdfName: o.data.Name, + receiver: g, }), - r && - r.isCompleted && + n && + n.isCompleted && sendCompletedMail({ - url: P.imageUrl, - sender: { Mail: n.data.ExtUserPtr.Email, Name: 'Open sign' }, - pdfName: n.data.Name, - receiver: n.data.ExtUserPtr.Email, + url: A.imageUrl, + sender: { Mail: o.data.ExtUserPtr.Email, Name: 'Open sign' }, + pdfName: o.data.Name, + receiver: o.data.ExtUserPtr.Email, }), - fs.unlinkSync(v), - console.log('New Signed PDF created called: ' + v), - 'success' === r.message - ? { status: 'success', data: P.imageUrl } + fs.unlinkSync(x), + console.log('New Signed PDF created called: ' + x), + 'success' === n.message + ? { status: 'success', data: A.imageUrl } : { status: 'error', message: 'please provide required parameters!' } ); } diff --git a/apps/OpenSignServer/cloud/parsefunction/reportsJson.js b/apps/OpenSignServer/cloud/parsefunction/reportsJson.js index 238846b83..12adf13a8 100644 --- a/apps/OpenSignServer/cloud/parsefunction/reportsJson.js +++ b/apps/OpenSignServer/cloud/parsefunction/reportsJson.js @@ -62,7 +62,7 @@ export default function reportJson(id, userId) { reportName: 'In-progress documents', params: { Type: { $ne: 'Folder' }, - Signers: { $ne: null }, + Signers: { $exists: true, $ne: [] }, Placeholders: { $ne: null }, IsCompleted: { $ne: true }, IsDeclined: { $ne: true }, @@ -153,7 +153,7 @@ export default function reportJson(id, userId) { reportName: 'Recently sent for signatures', params: { Type: { $ne: 'Folder' }, - Signers: { $ne: null }, + Signers: { $exists: true, $ne: [] }, Placeholders: { $ne: null }, IsCompleted: { $ne: true }, IsDeclined: { $ne: true }, diff --git a/apps/OpenSignServer/databases/migrations/20231208132950-update_template_menu.cjs b/apps/OpenSignServer/databases/migrations/20231208132950-update_template_menu.cjs index 9c33a5102..774855dc6 100644 --- a/apps/OpenSignServer/databases/migrations/20231208132950-update_template_menu.cjs +++ b/apps/OpenSignServer/databases/migrations/20231208132950-update_template_menu.cjs @@ -32,7 +32,7 @@ exports.up = async Parse => { objectId: 'sHAnZphf69', }, { - icon: 'fas fa-file-signature', + icon: 'fa-solid fa-paper-plane', title: 'Request signatures', target: '_self', pageType: 'form', @@ -50,7 +50,7 @@ exports.up = async Parse => { ], }, { - icon: 'fas fa-file-signature', + icon: 'fa-solid fa-file-contract', title: 'Templates', target: '_self', pageType: 'report', @@ -181,23 +181,30 @@ exports.up = async Parse => { objectId: 'sHAnZphf69', }, { - icon: 'fas fa-file-signature', + icon: 'fa-solid fa-paper-plane', title: 'Request signatures', target: '_self', pageType: 'form', description: '', objectId: '8mZzFxbG1z', }, + { + icon: 'fas fa-file-signature', + title: 'New template', + target: '_self', + pageType: 'form', + description: '', + objectId: 'template', + }, ], }, { - icon: 'fas fa-folder', - title: 'OpenSignDrive™', + icon: 'fa-solid fa-file-contract', + title: 'Templates', target: '_self', - pageType: 'mf', + pageType: 'report', description: '', - objectId: - 'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive', + objectId: '6TeaPr321t', }, { icon: 'fas fa-address-card', diff --git a/apps/OpenSignServer/exports/exported_file_2928.pdf b/apps/OpenSignServer/exports/exported_file_2928.pdf deleted file mode 100644 index 1602a4456..000000000 Binary files a/apps/OpenSignServer/exports/exported_file_2928.pdf and /dev/null differ diff --git a/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js b/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js index ce80021c8..1e9a4e5c5 100644 --- a/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js +++ b/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js @@ -32,6 +32,7 @@ import Header from "./component/header"; import RenderPdf from "./component/renderPdf"; import CustomModal from "./component/CustomModal"; import AlertComponent from "./component/alertComponent"; +import Title from "./component/Title"; function PdfRequestFiles() { const { docId } = useParams(); @@ -625,6 +626,7 @@ function PdfRequestFiles() { return ( + {isLoading.isLoad ? ( <Loader isLoading={isLoading} /> ) : handleError ? ( diff --git a/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js b/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js index 45178e6e9..a934a07bb 100644 --- a/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js +++ b/microfrontends/SignDocuments/src/Component/SignYourselfPdf.js @@ -39,6 +39,8 @@ import { contractUsers, contactBook, urlValidator } from "../utils/Utils"; import { modalAlign } from "../utils/Utils"; import AlertComponent from "./component/alertComponent"; import PlaceholderCopy from "./component/PlaceholderCopy"; +import TourContentWithBtn from "../premitives/TourContentWithBtn"; +import Title from "./component/Title"; //For signYourself inProgress section signer can add sign and complete doc sign. function SignYourSelf() { @@ -91,6 +93,7 @@ function SignYourSelf() { type: "load" }); const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" }); + const [isDontShow, setIsDontShow] = useState(false); const divRef = useRef(null); const nodeRef = useRef(null); const [{ isOver }, drop] = useDrop({ @@ -748,16 +751,31 @@ function SignYourSelf() { setXyPostion(getXyData); setShowAlreadySignDoc({ status: false }); }; + + const handleDontShow = (isChecked) => { + setIsDontShow(isChecked); + }; + const tourConfig = [ { selector: '[data-tut="reactourFirst"]', - content: `Drag the signature or stamp placeholder onto the PDF to choose your desired signing location.`, + content: () => ( + <TourContentWithBtn + message={`Drag the signature or stamp placeholder onto the PDF to choose your desired signing location.`} + isChecked={handleDontShow} + /> + ), position: "top", style: { fontSize: "13px" } }, { selector: '[data-tut="reactourSecond"]', - content: `Drag and drop anywhere in this area. You can resize and move it later.`, + content: () => ( + <TourContentWithBtn + message={`Drag and drop anywhere in this area. You can resize and move it later.`} + isChecked={handleDontShow} + /> + ), position: "top", style: { fontSize: "13px" } } @@ -766,47 +784,49 @@ function SignYourSelf() { //function for update TourStatus const closeTour = async () => { setSignTour(false); - - let updatedTourStatus = []; - if (tourStatus.length > 0) { - updatedTourStatus = [...tourStatus]; - const signyourselfIndex = tourStatus.findIndex( - (obj) => obj["signyourself"] === false || obj["signyourself"] === true - ); - if (signyourselfIndex !== -1) { - updatedTourStatus[signyourselfIndex] = { signyourself: true }; - } else { - updatedTourStatus.push({ signyourself: true }); - } - } else { - updatedTourStatus = [{ signyourself: true }]; - } - await axios - .put( - `${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( - "_appName" - )}${contractName}/${signerUserId}`, - { - TourStatus: updatedTourStatus - }, - { - headers: { - "Content-Type": "application/json", - "X-Parse-Application-Id": localStorage.getItem("parseAppId"), - sessionToken: localStorage.getItem("accesstoken") - } + if (isDontShow) { + let updatedTourStatus = []; + if (tourStatus.length > 0) { + updatedTourStatus = [...tourStatus]; + const signyourselfIndex = tourStatus.findIndex( + (obj) => obj["signyourself"] === false || obj["signyourself"] === true + ); + if (signyourselfIndex !== -1) { + updatedTourStatus[signyourselfIndex] = { signyourself: true }; + } else { + updatedTourStatus.push({ signyourself: true }); } - ) - .then((Listdata) => { - // const json = Listdata.data; - }) - .catch((err) => { - console.log("axois err ", err); - }); + } else { + updatedTourStatus = [{ signyourself: true }]; + } + await axios + .put( + `${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( + "_appName" + )}${contractName}/${signerUserId}`, + { + TourStatus: updatedTourStatus + }, + { + headers: { + "Content-Type": "application/json", + "X-Parse-Application-Id": localStorage.getItem("parseAppId"), + sessionToken: localStorage.getItem("accesstoken") + } + } + ) + .then((Listdata) => { + // const json = Listdata.data; + }) + .catch((err) => { + console.log("axois err ", err); + }); + } }; return ( <DndProvider backend={HTML5Backend}> + <Title title={"Self Sign"} /> {isLoading.isLoad ? ( <Loader isLoading={isLoading} /> ) : handleError ? ( diff --git a/microfrontends/SignDocuments/src/Component/TemplatePlaceholder.js b/microfrontends/SignDocuments/src/Component/TemplatePlaceholder.js index 13cc69416..28860f5e3 100644 --- a/microfrontends/SignDocuments/src/Component/TemplatePlaceholder.js +++ b/microfrontends/SignDocuments/src/Component/TemplatePlaceholder.js @@ -33,7 +33,7 @@ import ModalUi from "../premitives/ModalUi"; import AddRoleModal from "./component/AddRoleModal"; import PlaceholderCopy from "./component/PlaceholderCopy"; import ModalComponent from "./component/modalComponent"; - +import TourContentWithBtn from "../premitives/TourContentWithBtn"; const TemplatePlaceholder = () => { const navigate = useNavigate(); const { templateId } = useParams(); @@ -157,6 +157,7 @@ const TemplatePlaceholder = () => { const [isPageCopy, setIsPageCopy] = useState(false); const [signKey, setSignKey] = useState(); const [IsReceipent, setIsReceipent] = useState(true); + const [isDontShow, setIsDontShow] = useState(false); const senderUser = localStorage.getItem( `Parse/${localStorage.getItem("parseAppId")}/currentUser` @@ -197,7 +198,6 @@ const TemplatePlaceholder = () => { } } ); - // console.log("templateDeatils.data ", templateDeatils.data); const documentData = templateDeatils.data && templateDeatils.data.result ? [templateDeatils.data.result] @@ -327,201 +327,136 @@ const TemplatePlaceholder = () => { //function for setting position after drop signature button over pdf const addPositionOfSignature = (item, monitor) => { - getSignerPos(item, monitor); + getSignerPos(item, monitor); }; // `getSignerPos` is used to get placeholder position when user place it and save it in array const getSignerPos = (item, monitor) => { - const signer = signersdata.find((x) => x.Id === uniqueId); - if (signer) { - const posZIndex = zIndex + 1; - setZIndex(posZIndex); - const newWidth = containerWH.width; - const scale = pdfOriginalWidth / newWidth; - const key = randomId(); - // let filterSignerPos = signerPos.filter( - // (data) => data.signerObjId === signerObjId - // ); - let filterSignerPos = signerPos.filter((data) => data.Id === uniqueId); - let dropData = []; - let xyPosArr = []; - let xyPos = {}; - if (item === "onclick") { - const dropObj = { - xPosition: window.innerWidth / 2 - 100, - yPosition: window.innerHeight / 2 - 60, - isStamp: monitor, - key: key, - isDrag: false, - scale: scale, - isMobile: isMobile, - yBottom: window.innerHeight / 2 - 60, - zIndex: posZIndex - }; - dropData.push(dropObj); - xyPos = { - pageNumber: pageNumber, - pos: dropData - }; - - xyPosArr.push(xyPos); - } else if (item.type === "BOX") { - const offset = monitor.getClientOffset(); - //adding and updating drop position in array when user drop signature button in div - const containerRect = document - .getElementById("container") - .getBoundingClientRect(); - const x = offset.x - containerRect.left; - const y = offset.y - containerRect.top; - const ybottom = containerRect.bottom - offset.y; - - const dropObj = { - xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x, - yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y, - isStamp: isDragStamp || isDragStampSS ? true : false, - key: key, - isDrag: false, - firstXPos: signBtnPosition[0] && signBtnPosition[0].xPos, - firstYPos: signBtnPosition[0] && signBtnPosition[0].yPos, - yBottom: ybottom, - scale: scale, - isMobile: isMobile, - zIndex: posZIndex - }; - - dropData.push(dropObj); - xyPos = { - pageNumber: pageNumber, - pos: dropData - }; - - xyPosArr.push(xyPos); - } - const { blockColor, Role } = signersdata.find((x) => x.Id === uniqueId); - //adding placholder in existing signer pos array (placaholder) - if (filterSignerPos.length > 0) { - // const colorIndex = signerPos - // .map((e) => e.signerObjId) - // .indexOf(signerObjId); - - const colorIndex = signerPos.map((e) => e.Id).indexOf(uniqueId); - const getPlaceHolder = filterSignerPos[0].placeHolder; - const updatePlace = getPlaceHolder.filter( - (data) => data.pageNumber !== pageNumber - ); - const getPageNumer = getPlaceHolder.filter( - (data) => data.pageNumber === pageNumber - ); - - //add entry of position for same signer on multiple page - if (getPageNumer.length > 0) { - const getPos = getPageNumer[0].pos; - const newSignPos = getPos.concat(dropData); - let xyPos = { + if (uniqueId) { + const signer = signersdata.find((x) => x.Id === uniqueId); + if (signer) { + const posZIndex = zIndex + 1; + setZIndex(posZIndex); + const newWidth = containerWH.width; + const scale = pdfOriginalWidth / newWidth; + const key = randomId(); + // let filterSignerPos = signerPos.filter( + // (data) => data.signerObjId === signerObjId + // ); + let filterSignerPos = signerPos.filter((data) => data.Id === uniqueId); + let dropData = []; + let placeHolder; + if (item === "onclick") { + const dropObj = { + xPosition: window.innerWidth / 2 - 100, + yPosition: window.innerHeight / 2 - 60, + isStamp: monitor, + key: key, + isDrag: false, + scale: scale, + isMobile: isMobile, + yBottom: window.innerHeight / 2 - 60, + zIndex: posZIndex + }; + dropData.push(dropObj); + placeHolder = { pageNumber: pageNumber, - pos: newSignPos + pos: dropData }; - updatePlace.push(xyPos); - let placeHolderPos; - if (contractName) { - placeHolderPos = { - blockColor: blockColor ? blockColor : color[isSelectListId], - signerObjId: signerObjId, - placeHolder: updatePlace, - signerPtr: { - __type: "Pointer", - className: `${contractName}`, - objectId: signerObjId - }, - Role: Role ? Role : roleName, - Id: uniqueId - }; - } else { - placeHolderPos = { - blockColor: blockColor ? blockColor : color[isSelectListId], - signerObjId: "", - placeHolder: updatePlace, - signerPtr: {}, - Role: Role ? Role : roleName, - Id: uniqueId - }; - } - // signerPos.splice(colorIndex, 1, placeHolderPos); - const newArry = [placeHolderPos]; - const newArray = [ - ...signerPos.slice(0, colorIndex), - ...newArry, - ...signerPos.slice(colorIndex + 1) - ]; - setSignerPos(newArray); - } else { - const newSignPoss = getPlaceHolder.concat(xyPosArr[0]); - let placeHolderPos; - if (contractName) { - placeHolderPos = { - blockColor: color[isSelectListId], - signerObjId: signerObjId, - placeHolder: newSignPoss, - signerPtr: { - __type: "Pointer", - className: `${contractName}`, - objectId: signerObjId - }, - Role: Role ? Role : roleName, - Id: uniqueId - }; - } else { - placeHolderPos = { - blockColor: color[isSelectListId], - signerObjId: "", - placeHolder: newSignPoss, - signerPtr: {}, - Role: Role ? Role : roleName, - Id: uniqueId - }; - } + } else if (item.type === "BOX") { + const offset = monitor.getClientOffset(); + //adding and updating drop position in array when user drop signature button in div + const containerRect = document + .getElementById("container") + .getBoundingClientRect(); + const x = offset.x - containerRect.left; + const y = offset.y - containerRect.top; + const ybottom = containerRect.bottom - offset.y; - const newArry = [placeHolderPos]; - const newArray = [ - ...signerPos.slice(0, colorIndex), - ...newArry, - ...signerPos.slice(colorIndex + 1) - ]; + const dropObj = { + xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x, + yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y, + isStamp: isDragStamp || isDragStampSS ? true : false, + key: key, + isDrag: false, + firstXPos: signBtnPosition[0] && signBtnPosition[0].xPos, + firstYPos: signBtnPosition[0] && signBtnPosition[0].yPos, + yBottom: ybottom, + scale: scale, + isMobile: isMobile, + zIndex: posZIndex + }; - setSignerPos(newArray); + dropData.push(dropObj); + placeHolder = { + pageNumber: pageNumber, + pos: dropData + }; } + const { blockColor, Role } = signer; + //adding placholder in existing signer pos array (placaholder) + if (filterSignerPos.length > 0) { + const getPlaceHolder = filterSignerPos[0].placeHolder; + const updatePlace = getPlaceHolder.filter( + (data) => data.pageNumber !== pageNumber + ); + const getPageNumer = getPlaceHolder.filter( + (data) => data.pageNumber === pageNumber + ); + + //add entry of position for same signer on multiple page + if (getPageNumer.length > 0) { + const getPos = getPageNumer[0].pos; + const newSignPos = getPos.concat(dropData); + let xyPos = { + pageNumber: pageNumber, + pos: newSignPos + }; + updatePlace.push(xyPos); + const updatesignerPos = signerPos.map((x) => + x.Id === uniqueId ? { ...x, placeHolder: updatePlace } : x + ); + setSignerPos(updatesignerPos); + } else { + const updatesignerPos = signerPos.map((x) => + x.Id === uniqueId + ? { ...x, placeHolder: [...x.placeHolder, placeHolder] } + : x + ); + setSignerPos(updatesignerPos); + } + } else { + //adding new placeholder for selected signer in pos array (placeholder) + let placeHolderPos; + if (contractName) { + placeHolderPos = { + signerPtr: { + __type: "Pointer", + className: `${contractName}`, + objectId: signerObjId + }, + signerObjId: signerObjId, + blockColor: blockColor ? blockColor : color[isSelectListId], + placeHolder: [placeHolder], + Role: Role ? Role : roleName, + Id: uniqueId + }; + } else { + placeHolderPos = { + signerPtr: {}, + signerObjId: "", + blockColor: blockColor ? blockColor : color[isSelectListId], + placeHolder: [placeHolder], + Role: Role ? Role : roleName, + Id: uniqueId + }; + } + setSignerPos((prev) => [...prev, placeHolderPos]); + } + setIsMailSend(false); } else { - //adding new placeholder for selected signer in pos array (placeholder) - let placeHolderPos; - if (contractName) { - placeHolderPos = { - signerPtr: { - __type: "Pointer", - className: `${contractName}`, - objectId: signerObjId - }, - signerObjId: signerObjId, - blockColor: blockColor ? blockColor : color[isSelectListId], - placeHolder: xyPosArr, - Role: Role ? Role : roleName, - Id: uniqueId - }; - } else { - placeHolderPos = { - signerPtr: {}, - signerObjId: "", - blockColor: blockColor ? blockColor : color[isSelectListId], - placeHolder: xyPosArr, - Role: Role ? Role : roleName, - Id: uniqueId - }; - } - - setSignerPos((prev) => [...prev, placeHolderPos]); + setIsReceipent(false); } - setIsMailSend(false); - } else { - setIsReceipent(false); } }; //function for get pdf page details @@ -760,38 +695,67 @@ const TemplatePlaceholder = () => { setIsReceipent(false); } }; - //here you can add your messages in content and selector is key of particular steps + const handleDontShow = (isChecked) => { + setIsDontShow(isChecked); + }; + + //here you can add your messages in content and selector is key of particular steps const tourConfig = [ { selector: '[data-tut="reactourAddbtn"]', - content: `Clicking "Add role" button will allow you to add various signer roles. You can attach users to each role in subsequent steps.`, + content: () => ( + <TourContentWithBtn + message={`Clicking "Add role" button will allow you to add various signer roles. You can attach users to each role in subsequent steps.`} + isChecked={handleDontShow} + /> + ), position: "top", observe: '[data-tut="reactourAddbtn--observe"]', style: { fontSize: "13px" } }, { selector: '[data-tut="reactourFirst"]', - content: `Select a recipient from this list to add a place-holder where he is supposed to sign.The placeholder will appear in the same colour as the recipient name once you drop it on the document.`, + content: () => ( + <TourContentWithBtn + message={`Select a recipient from this list to add a place-holder where he is supposed to sign.The placeholder will appear in the same colour as the recipient name once you drop it on the document.`} + isChecked={handleDontShow} + /> + ), position: "top", style: { fontSize: "13px" }, action: () => handleCloseRoleModal() }, { selector: '[data-tut="reactourSecond"]', - content: `Drag the signature or stamp placeholder onto the PDF to choose your desired signing location.`, + content: () => ( + <TourContentWithBtn + message={`Drag the signature or stamp placeholder onto the PDF to choose your desired signing location.`} + isChecked={handleDontShow} + /> + ), position: "top", style: { fontSize: "13px" } }, { selector: '[data-tut="reactourThird"]', - content: `Drag the placeholder for a recipient anywhere on the document.Remember, it will appear in the same colour as the name of the recipient for easy reference.`, + content: () => ( + <TourContentWithBtn + message={`Drag the placeholder for a recipient anywhere on the document.Remember, it will appear in the same colour as the name of the recipient for easy reference.`} + isChecked={handleDontShow} + /> + ), position: "top", style: { fontSize: "13px" } }, { selector: '[data-tut="reactourFour"]', - content: `Clicking "Save" button will save the template and will ask you for creating new document.`, + content: () => ( + <TourContentWithBtn + message={`Clicking "Save" button will save the template and will ask you for creating new document.`} + isChecked={handleDontShow} + /> + ), position: "top", style: { fontSize: "13px" } } @@ -800,44 +764,46 @@ const TemplatePlaceholder = () => { //function for update TourStatus const closeTour = async () => { setTemplateTour(false); - const extUserClass = localStorage.getItem("extended_class"); - let updatedTourStatus = []; - if (tourStatus.length > 0) { - updatedTourStatus = [...tourStatus]; - const templatetourIndex = tourStatus.findIndex( - (obj) => obj["templatetour"] === false || obj["templatetour"] === true - ); - if (templatetourIndex !== -1) { - updatedTourStatus[templatetourIndex] = { templatetour: true }; - } else { - updatedTourStatus.push({ templatetour: true }); - } - } else { - updatedTourStatus = [{ templatetour: true }]; - } - await axios - .put( - `${localStorage.getItem( - "baseUrl" - )}classes/${extUserClass}/${signerUserId}`, - { - TourStatus: updatedTourStatus - }, - { - headers: { - "Content-Type": "application/json", - "X-Parse-Application-Id": localStorage.getItem("parseAppId"), - sessionToken: localStorage.getItem("accesstoken") - } + if (isDontShow) { + const extUserClass = localStorage.getItem("extended_class"); + let updatedTourStatus = []; + if (tourStatus.length > 0) { + updatedTourStatus = [...tourStatus]; + const templatetourIndex = tourStatus.findIndex( + (obj) => obj["templatetour"] === false || obj["templatetour"] === true + ); + if (templatetourIndex !== -1) { + updatedTourStatus[templatetourIndex] = { templatetour: true }; + } else { + updatedTourStatus.push({ templatetour: true }); } - ) - .then((Listdata) => { - // const json = Listdata.data; - // const res = json.results; - }) - .catch((err) => { - console.log("axois err ", err); - }); + } else { + updatedTourStatus = [{ templatetour: true }]; + } + await axios + .put( + `${localStorage.getItem( + "baseUrl" + )}classes/${extUserClass}/${signerUserId}`, + { + TourStatus: updatedTourStatus + }, + { + headers: { + "Content-Type": "application/json", + "X-Parse-Application-Id": localStorage.getItem("parseAppId"), + sessionToken: localStorage.getItem("accesstoken") + } + } + ) + .then((Listdata) => { + // const json = Listdata.data; + // const res = json.results; + }) + .catch((err) => { + console.log("axois err ", err); + }); + } }; // `handleCreateDocModal` is used to create Document from template when user click on yes from modal @@ -848,7 +814,9 @@ const TemplatePlaceholder = () => { // handle create document const res = await createDocument(pdfDetails, signerPos, signersdata); if (res.status === "success") { - navigate(`${hostUrl}placeHolderSign/${res.id}`); + navigate(`${hostUrl}placeHolderSign/${res.id}`, { + state: { title: "Use Template" } + }); setIsCreateDoc(false); } else { setHandleError("Error: Something went wrong!"); @@ -866,6 +834,8 @@ const TemplatePlaceholder = () => { // save Role in entry in signerList and user const handleAddRole = (e) => { e.preventDefault(); + setSignerObjId('') + setContractName('') const count = signersdata.length > 0 ? signersdata.length + 1 : 1; const Id = randomId(); const index = signersdata.length; @@ -884,18 +854,18 @@ const TemplatePlaceholder = () => { // `handleDeleteUser` function is used to delete record and placeholder when user click on delete which is place next user name in recipients list const handleDeleteUser = (Id) => { const updateSigner = signersdata - .filter((x) => x.Id !== Id) - .map((x, i) => ({ ...x, blockColor: color[i] })); + .filter((x) => x.Id !== Id) + .map((x, i) => ({ ...x, blockColor: color[i] })); setSignersData(updateSigner); const updatePlaceholderUser = signerPos - .filter((x) => x.Id !== Id) - .map((x, i) => ({ ...x, blockColor: color[i] })); - const index = signersdata.findIndex((x)=> x.Id === Id) - if(index === signersdata.length - 1){ - setUniqueId(updateSigner[updateSigner.length - 1]?.Id ||""); - setIsSelectId(0); - }else{ - setUniqueId(updateSigner[index]?.Id ||""); + .filter((x) => x.Id !== Id) + .map((x, i) => ({ ...x, blockColor: color[i] })); + const index = signersdata.findIndex((x) => x.Id === Id); + if (index === signersdata.length - 1) { + setUniqueId(updateSigner[updateSigner.length - 1]?.Id || ""); + setIsSelectId(index - 1|| 0); + } else { + setUniqueId(updateSigner[index]?.Id || ""); setIsSelectId(index); } @@ -924,12 +894,14 @@ const TemplatePlaceholder = () => { const updateSigner = signersdata.map((x) => { if (x.Id === uniqueId) { - return { ...x, ...data }; + return { ...x, ...data, className: "contracts_Contactbook" }; } return { ...x }; }); setSignersData(updateSigner); setIsMailSend(false); + const index = signersdata.findIndex((x) => x.Id === uniqueId); + setIsSelectId(index); }; // `closePopup` is used to close Add/Choose signer modal @@ -1054,7 +1026,10 @@ const TemplatePlaceholder = () => { handleClose={() => setIsCreateDocModal(false)} > <div style={{ height: "100%", padding: 20 }}> - <p>Do you want to create a document using the template you just created ?</p> + <p> + Do you want to create a document using the template you just + created ? + </p> <div style={{ height: "1px", diff --git a/microfrontends/SignDocuments/src/Component/component/EditTemplate.js b/microfrontends/SignDocuments/src/Component/component/EditTemplate.js index 883051507..f60091c6d 100644 --- a/microfrontends/SignDocuments/src/Component/component/EditTemplate.js +++ b/microfrontends/SignDocuments/src/Component/component/EditTemplate.js @@ -43,7 +43,7 @@ const EditTemplate = ({ template, onSuccess }) => { fontWeight: "700" }} > - file selected : {template.URL?.split("/")[3]?.split("_")[1]} + {template.URL?.split("/")[3]?.split("_")[1]} </div> </div> <div className="form-section"> diff --git a/microfrontends/SignDocuments/src/Component/component/LinkUserModal.js b/microfrontends/SignDocuments/src/Component/component/LinkUserModal.js index 5b14264bb..b7a5cac97 100644 --- a/microfrontends/SignDocuments/src/Component/component/LinkUserModal.js +++ b/microfrontends/SignDocuments/src/Component/component/LinkUserModal.js @@ -10,12 +10,12 @@ const LinkUserModal = (props) => { details={props.handleAddUser} closePopup={props.closePopup} /> - <div style={{ display: "flex", alignItems: "center", gap: 5, margin:"0px 25px" }}> + <div style={{ display: "flex", alignItems: "center", gap: 5, margin:"0 30%", color:"#808080" }}> <span style={{ height: 1, width: "100%", - backgroundColor: "grey" + backgroundColor: "#ccc" }} ></span> <span>or</span> @@ -23,7 +23,7 @@ const LinkUserModal = (props) => { style={{ height: 1, width: "100%", - backgroundColor: "grey" + backgroundColor: "#ccc" }} ></span> </div> diff --git a/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js b/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js index b3cb187bc..189946bc7 100644 --- a/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js +++ b/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js @@ -83,22 +83,56 @@ function FieldsComponent({ justifyContent: "center" }} onClick={() => { - if (signersdata?.length) { - handleModal(); - } + // if (signersdata?.length) { + handleModal(); + // } }} > - <span style={{ fontSize: "13px", fontWeight: "700" }}> + <span + style={{ + fontSize: "13px", + fontWeight: "700", + textAlign: "center" + }} + > Recipient </span> - <span style={{ fontSize: "13px", fontWeight: "700" }}> + <span + style={{ + fontSize: "13px", + fontWeight: "700", + display: "flex", + alignItems: "center" + }} + > {signersdata[isSelectListId]?.Role && ( <div> - {signersdata[isSelectListId]?.Name - ? ` : ${signersdata[isSelectListId]?.Name}` - : ` : ${signersdata[isSelectListId]?.Role}`} + {signersdata[isSelectListId]?.Name ? ( + <> + :{" "} + {signersdata[isSelectListId]?.Name?.length > 12 + ? `${signersdata[isSelectListId].Name.slice( + 0, + 12 + )}...` + : signersdata[isSelectListId]?.Name} + </> + ) : ( + <> + :{" "} + {signersdata[isSelectListId]?.Role?.length > 12 + ? `${signersdata[isSelectListId].Role.slice( + 0, + 12 + )}...` + : signersdata[isSelectListId]?.Role} + </> + )} </div> )} + <div style={{ marginLeft: 6, fontSize: 16 }}> + <i className="fa-solid fa-angle-down"></i> + </div> </span> </div> )} @@ -333,25 +367,41 @@ function FieldsComponent({ </div> </div> )} - <ModalUi - title={"Recipients"} - isOpen={isSignersModal} - handleClose={handleModal} - > - <RecipientList - signerPos={signerPos} - signersdata={signersdata} - isSelectListId={isSelectListId} - setSignerObjId={setSignerObjId} - setIsSelectId={setIsSelectId} - setContractName={setContractName} - setUniqueId={setUniqueId} - setRoleName={setRoleName} - handleDeleteUser={handleDeleteUser} - handleRoleChange={handleRoleChange} - handleOnBlur={handleOnBlur} - /> - </ModalUi> + {isSignersModal && ( + <ModalUi + title={"Recipients"} + isOpen={isSignersModal} + 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={{ + padding: 20, + fontSize: 15, + fontWeight: "500", + textAlign: "center" + }} + > + Please add Recipient + </div> + )} + </ModalUi> + )} </> ); } diff --git a/microfrontends/SignDocuments/src/Component/component/renderPdf.js b/microfrontends/SignDocuments/src/Component/component/renderPdf.js index 808e12c9b..1c595f7c8 100644 --- a/microfrontends/SignDocuments/src/Component/component/renderPdf.js +++ b/microfrontends/SignDocuments/src/Component/component/renderPdf.js @@ -381,14 +381,12 @@ function RenderPdf({ }; const handleUserName = (signerId, Role) => { if (signerId) { - const checkSign = signersdata.filter( - (sign) => sign.objectId === signerId - ); - if (checkSign.length > 0) { + const checkSign = signersdata.find((sign) => sign.objectId === signerId); + if (checkSign?.Name) { return ( <> <div style={{ color: "black", fontSize: 11 }}> - {checkSign[0].Name} + {checkSign?.Name} </div> <div style={{ color: "black", fontSize: 11 }}> {`(${Role})`} </div> </> @@ -479,7 +477,7 @@ function RenderPdf({ onClick={() => { setIsSignPad(true); setSignKey(pos.key); - setIsStamp(false); + setIsStamp(pos?.isStamp ? pos.isStamp : false); }} > <BorderResize /> @@ -647,6 +645,7 @@ function RenderPdf({ }} > <i + data-tut="reactourLinkUser" className="fa-regular fa-user signUserIcon" onTouchEnd={(e) => { e.stopPropagation(); @@ -788,7 +787,6 @@ function RenderPdf({ xyPostion, index, setXyPostion - ); }} > @@ -1008,7 +1006,7 @@ function RenderPdf({ onClick={() => { setIsSignPad(true); setSignKey(pos.key); - setIsStamp(false); + setIsStamp(pos?.isStamp ? pos.isStamp : false); }} > <div style={{ pointerEvents: "none" }}> @@ -1173,6 +1171,7 @@ function RenderPdf({ /> <div> <i + data-tut="reactourLinkUser" className="fa-regular fa-user signUserIcon" onClick={(e) => { e.stopPropagation(); diff --git a/microfrontends/SignDocuments/src/Component/placeHolderSign.js b/microfrontends/SignDocuments/src/Component/placeHolderSign.js index 32e1f3607..6187f716b 100644 --- a/microfrontends/SignDocuments/src/Component/placeHolderSign.js +++ b/microfrontends/SignDocuments/src/Component/placeHolderSign.js @@ -11,7 +11,7 @@ import { useDrag, useDrop } from "react-dnd"; import RenderAllPdfPage from "./component/renderAllPdfPage"; import FieldsComponent from "./component/fieldsComponent"; import Tour from "reactour"; -import { useParams } from "react-router-dom"; +import { useLocation, useParams } from "react-router-dom"; import Loader from "./component/loader"; import HandleError from "./component/HandleError"; import Nodata from "./component/Nodata"; @@ -31,9 +31,11 @@ import { useNavigate } from "react-router-dom"; import PlaceholderCopy from "./component/PlaceholderCopy"; import LinkUserModal from "./component/LinkUserModal"; import Title from "./component/Title"; +import TourContentWithBtn from "../premitives/TourContentWithBtn"; function PlaceHolderSign() { const navigate = useNavigate(); + const { state } = useLocation(); const [pdfDetails, setPdfDetails] = useState([]); const [isMailSend, setIsMailSend] = useState(false); const [allPages, setAllPages] = useState(null); @@ -53,7 +55,7 @@ function PlaceHolderSign() { message: "This might take some time" }); const [handleError, setHandleError] = useState(); - const [currentEmail, setCurrentEmail] = useState(); + const [currentId, setCurrentId] = useState(""); const [pdfNewWidth, setPdfNewWidth] = useState(); const [placeholderTour, setPlaceholderTour] = useState(true); const [checkTourStatus, setCheckTourStatus] = useState(false); @@ -81,6 +83,7 @@ function PlaceHolderSign() { const [roleName, setRoleName] = useState(""); const [isAddUser, setIsAddUser] = useState({}); const [signerExistModal, setSignerExistModal] = useState(false); + const [isDontShow, setIsDontShow] = useState(false); const color = [ "#93a3db", "#e6c3db", @@ -202,10 +205,7 @@ function PlaceHolderSign() { if (documentData[0].Signers && documentData[0].Signers.length > 0) { const currEmail = documentData[0].ExtUserPtr.Email; - const filterCurrEmail = documentData[0].Signers.filter( - (data) => data.Email === currEmail - ); - setCurrentEmail(filterCurrEmail); + setCurrentId(currEmail); setSignerObjId(documentData[0].Signers[0].objectId); setContractName(documentData[0].Signers[0].className); setIsSelectId(0); @@ -317,208 +317,136 @@ function PlaceHolderSign() { //function for setting position after drop signature button over pdf const addPositionOfSignature = (item, monitor) => { - if (isMobile) { - if (selectedEmail) { - getSignerPos(item, monitor); - } else { - setIsShowEmail(true); - } - } else { - getSignerPos(item, monitor); - } + getSignerPos(item, monitor); }; const getSignerPos = (item, monitor) => { - const posZIndex = zIndex + 1; - setZIndex(posZIndex); - const newWidth = containerWH.width; - const scale = pdfOriginalWidth / newWidth; - const key = Math.floor(1000 + Math.random() * 9000); - // let filterSignerPos = signerPos.filter( - // (data) => data.signerObjId === signerObjId - // ); - let filterSignerPos = signerPos.filter((data) => data.Id === uniqueId); - - let dropData = []; - let xyPosArr = []; - let xyPos = {}; - if (item === "onclick") { - const dropObj = { - //onclick put placeholder center on pdf - xPosition: window.innerWidth / 2 - 100, - yPosition: window.innerHeight / 2 - 60, - isStamp: monitor, - key: key, - isDrag: false, - scale: scale, - isMobile: isMobile, - yBottom: window.innerHeight / 2 - 60, - zIndex: posZIndex - }; - dropData.push(dropObj); - xyPos = { - pageNumber: pageNumber, - pos: dropData - }; - - xyPosArr.push(xyPos); - } else if (item.type === "BOX") { - const offset = monitor.getClientOffset(); - //adding and updating drop position in array when user drop signature button in div - const containerRect = document - .getElementById("container") - .getBoundingClientRect(); - const x = offset.x - containerRect.left; - const y = offset.y - containerRect.top; - const ybottom = containerRect.bottom - offset.y; - - const dropObj = { - xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x, - yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y, - isStamp: isDragStamp || isDragStampSS ? true : false, - key: key, - isDrag: false, - firstXPos: signBtnPosition[0] && signBtnPosition[0].xPos, - firstYPos: signBtnPosition[0] && signBtnPosition[0].yPos, - yBottom: ybottom, - scale: scale, - isMobile: isMobile, - zIndex: posZIndex - }; - dropData.push(dropObj); - xyPos = { - pageNumber: pageNumber, - pos: dropData - }; - - xyPosArr.push(xyPos); - } - - //add signers objId first inseretion - if (filterSignerPos.length > 0) { - // const colorIndex = signerPos - // .map((e) => e.signerObjId) - // .indexOf(signerObjId); - - const colorIndex = signerPos.map((e) => e.Id).indexOf(uniqueId); - - const getPlaceHolder = filterSignerPos[0].placeHolder; - const updatePlace = getPlaceHolder.filter( - (data) => data.pageNumber !== pageNumber - ); - const getPageNumer = getPlaceHolder.filter( - (data) => data.pageNumber === pageNumber - ); - - //add entry of position for same signer on multiple page - if (getPageNumer.length > 0) { - const getPos = getPageNumer[0].pos; - const newSignPos = getPos.concat(dropData); - let xyPos = { + setSignerObjId('') + setContractName('') + if (uniqueId) { + const signer = signersdata.find((x) => x.Id === uniqueId); + if (signer) { + const posZIndex = zIndex + 1; + setZIndex(posZIndex); + const newWidth = containerWH.width; + const scale = pdfOriginalWidth / newWidth; + const key = randomId(); + // let filterSignerPos = signerPos.filter( + // (data) => data.signerObjId === signerObjId + // ); + let filterSignerPos = signerPos.filter((data) => data.Id === uniqueId); + let dropData = []; + let placeHolder; + if (item === "onclick") { + const dropObj = { + xPosition: window.innerWidth / 2 - 100, + yPosition: window.innerHeight / 2 - 60, + isStamp: monitor, + key: key, + isDrag: false, + scale: scale, + isMobile: isMobile, + yBottom: window.innerHeight / 2 - 60, + zIndex: posZIndex + }; + dropData.push(dropObj); + placeHolder = { pageNumber: pageNumber, - pos: newSignPos + pos: dropData }; - updatePlace.push(xyPos); + } else if (item.type === "BOX") { + const offset = monitor.getClientOffset(); + //adding and updating drop position in array when user drop signature button in div + const containerRect = document + .getElementById("container") + .getBoundingClientRect(); + const x = offset.x - containerRect.left; + const y = offset.y - containerRect.top; + const ybottom = containerRect.bottom - offset.y; + + const dropObj = { + xPosition: signBtnPosition[0] ? x - signBtnPosition[0].xPos : x, + yPosition: signBtnPosition[0] ? y - signBtnPosition[0].yPos : y, + isStamp: isDragStamp || isDragStampSS ? true : false, + key: key, + isDrag: false, + firstXPos: signBtnPosition[0] && signBtnPosition[0].xPos, + firstYPos: signBtnPosition[0] && signBtnPosition[0].yPos, + yBottom: ybottom, + scale: scale, + isMobile: isMobile, + zIndex: posZIndex + }; + + dropData.push(dropObj); + placeHolder = { + pageNumber: pageNumber, + pos: dropData + }; + } + const { blockColor, Role } = signer; + //adding placholder in existing signer pos array (placaholder) + if (filterSignerPos.length > 0) { + const getPlaceHolder = filterSignerPos[0].placeHolder; + const updatePlace = getPlaceHolder.filter( + (data) => data.pageNumber !== pageNumber + ); + const getPageNumer = getPlaceHolder.filter( + (data) => data.pageNumber === pageNumber + ); + + //add entry of position for same signer on multiple page + if (getPageNumer.length > 0) { + const getPos = getPageNumer[0].pos; + const newSignPos = getPos.concat(dropData); + let xyPos = { + pageNumber: pageNumber, + pos: newSignPos + }; + updatePlace.push(xyPos); + const updatesignerPos = signerPos.map((x) => + x.Id === uniqueId ? { ...x, placeHolder: updatePlace } : x + ); + setSignerPos(updatesignerPos); + } else { + const updatesignerPos = signerPos.map((x) => + x.Id === uniqueId + ? { ...x, placeHolder: [...x.placeHolder, placeHolder] } + : x + ); + setSignerPos(updatesignerPos); + } + } else { + //adding new placeholder for selected signer in pos array (placeholder) let placeHolderPos; if (contractName) { placeHolderPos = { - blockColor: color[isSelectListId], - signerObjId: signerObjId, - placeHolder: updatePlace, signerPtr: { __type: "Pointer", className: `${contractName}`, objectId: signerObjId }, - Role: roleName, - Id: uniqueId - }; - } else { - placeHolderPos = { - blockColor: color[isSelectListId], - signerObjId: "", - placeHolder: updatePlace, - signerPtr: {}, - Role: roleName, - Id: uniqueId - }; - } - // signerPos.splice(colorIndex, 1, placeHolderPos); - const newArry = [placeHolderPos]; - const newArray = [ - ...signerPos.slice(0, colorIndex), - ...newArry, - ...signerPos.slice(colorIndex + 1) - ]; - setSignerPos(newArray); - } else { - const newSignPoss = getPlaceHolder.concat(xyPosArr[0]); - let placeHolderPos; - if (contractName) { - placeHolderPos = { - blockColor: color[isSelectListId], signerObjId: signerObjId, - placeHolder: newSignPoss, - signerPtr: { - __type: "Pointer", - className: `${contractName}`, - objectId: signerObjId - }, - Role: roleName, + blockColor: blockColor ? blockColor : color[isSelectListId], + placeHolder: [placeHolder], + Role: Role ? Role : roleName, Id: uniqueId }; } else { placeHolderPos = { - blockColor: color[isSelectListId], - signerObjId: "", - placeHolder: newSignPoss, signerPtr: {}, - Role: roleName, + signerObjId: "", + blockColor: blockColor ? blockColor : color[isSelectListId], + placeHolder: [placeHolder], + Role: Role ? Role : roleName, Id: uniqueId }; } - - // signerPos.splice(colorIndex, 1, placeHolderPos); - const newArry = [placeHolderPos]; - const newArray = [ - ...signerPos.slice(0, colorIndex), - ...newArry, - ...signerPos.slice(colorIndex + 1) - ]; - - setSignerPos(newArray); + setSignerPos((prev) => [...prev, placeHolderPos]); } - } else { - let placeHolderPos; - if (contractName) { - placeHolderPos = { - signerPtr: { - __type: "Pointer", - className: `${contractName}`, - objectId: signerObjId - }, - signerObjId: signerObjId, - blockColor: color[isSelectListId], - placeHolder: xyPosArr, - Role: roleName, - Id: uniqueId - }; - } else { - placeHolderPos = { - signerPtr: {}, - signerObjId: "", - blockColor: color[isSelectListId], - placeHolder: xyPosArr, - Role: roleName, - Id: uniqueId - }; - } - - setSignerPos((prev) => [...prev, placeHolderPos]); } - setIsMailSend(false); + } }; - //function for get pdf page details const pageDetails = async (pdf) => { const load = { @@ -791,6 +719,8 @@ function PlaceHolderSign() { objectId: x.objectId }; }); + const currentUser = signersdata.find((x) => x.Email === currentId); + setCurrentId(currentUser?.objectId); // console.log("signers ", signers); try { const data = { @@ -829,31 +759,65 @@ function PlaceHolderSign() { } } }; - //here you can add your messages in content and selector is key of particular steps + const handleDontShow = (isChecked) => { + setIsDontShow(isChecked); + }; + + //here you can add your messages in content and selector is key of particular steps const tourConfig = [ { selector: '[data-tut="reactourFirst"]', - content: `Select a recipient from this list to add a place-holder where he is supposed to sign.The placeholder will appear in the same colour as the recipient name once you drop it on the document.`, + content: () => ( + <TourContentWithBtn + message={`Select a recipient from this list to add a place-holder where he is supposed to sign.The placeholder will appear in the same colour as the recipient name once you drop it on the document.`} + isChecked={handleDontShow} + /> + ), position: "top", - style: { fontSize: "13px" } }, { selector: '[data-tut="reactourSecond"]', - content: `Drag the signature or stamp placeholder onto the PDF to choose your desired signing location.`, + content: () => ( + <TourContentWithBtn + message={`Drag the signature or stamp placeholder onto the PDF to choose your desired signing location.`} + isChecked={handleDontShow} + /> + ), position: "top", style: { fontSize: "13px" } }, { selector: '[data-tut="reactourThird"]', - content: `Drag the placeholder for a recipient anywhere on the document.Remember, it will appear in the same colour as the name of the recipient for easy reference.`, + content: () => ( + <TourContentWithBtn + message={`Drag the placeholder for a recipient anywhere on the document.Remember, it will appear in the same colour as the name of the recipient for easy reference.`} + isChecked={handleDontShow} + /> + ), + position: "top", + style: { fontSize: "13px" } + }, + { + selector: '[data-tut="reactourLinkUser"]', + content: () => ( + <TourContentWithBtn + message={`Click to this icon to assign or replace signer for the placeholder.`} + isChecked={handleDontShow} + /> + ), position: "top", style: { fontSize: "13px" } }, { selector: '[data-tut="reactourFour"]', - content: `Clicking "Send" button will share the document with all the recipients.It will also send out emails to everyone on the recipients list.`, + content: () => ( + <TourContentWithBtn + message={`Clicking "Send" button will share the document with all the recipients.It will also send out emails to everyone on the recipients list.`} + isChecked={handleDontShow} + /> + ), position: "top", style: { fontSize: "13px" } } @@ -862,81 +826,82 @@ function PlaceHolderSign() { //function for update TourStatus const closeTour = async () => { setPlaceholderTour(false); - const extUserClass = localStorage.getItem("extended_class"); - let updatedTourStatus = []; - if (tourStatus.length > 0) { - updatedTourStatus = [...tourStatus]; - const placeholderIndex = tourStatus.findIndex( - (obj) => obj["placeholder"] === false || obj["placeholder"] === true - ); - if (placeholderIndex !== -1) { - updatedTourStatus[placeholderIndex] = { placeholder: true }; - } else { - updatedTourStatus.push({ placeholder: true }); - } - } else { - updatedTourStatus = [{ placeholder: true }]; - } - await axios - .put( - `${localStorage.getItem( - "baseUrl" - )}classes/${extUserClass}/${signerUserId}`, - { - TourStatus: updatedTourStatus - }, - { - headers: { - "Content-Type": "application/json", - "X-Parse-Application-Id": localStorage.getItem("parseAppId"), - sessionToken: localStorage.getItem("accesstoken") - } + if (isDontShow) { + const extUserClass = localStorage.getItem("extended_class"); + let updatedTourStatus = []; + if (tourStatus.length > 0) { + updatedTourStatus = [...tourStatus]; + const placeholderIndex = tourStatus.findIndex( + (obj) => obj["placeholder"] === false || obj["placeholder"] === true + ); + if (placeholderIndex !== -1) { + updatedTourStatus[placeholderIndex] = { placeholder: true }; + } else { + updatedTourStatus.push({ placeholder: true }); } - ) - .then((Listdata) => { - // const json = Listdata.data; - // const res = json.results; - }) - .catch((err) => { - console.log("axois err ", err); - }); + } else { + updatedTourStatus = [{ placeholder: true }]; + } + await axios + .put( + `${localStorage.getItem( + "baseUrl" + )}classes/${extUserClass}/${signerUserId}`, + { + TourStatus: updatedTourStatus + }, + { + headers: { + "Content-Type": "application/json", + "X-Parse-Application-Id": localStorage.getItem("parseAppId"), + sessionToken: localStorage.getItem("accesstoken") + } + } + ) + .then((Listdata) => { + // const json = Listdata.data; + // const res = json.results; + }) + .catch((err) => { + console.log("axois err ", err); + }); + } }; const handleRecipientSign = () => { const hostUrl = getHostUrl(); - navigate( - `${hostUrl}recipientSignPdf/${documentId}/${currentEmail[0].objectId}` - ); + navigate(`${hostUrl}recipientSignPdf/${documentId}/${currentId}`); }; const handleLinkUser = (id) => { setIsAddUser({ [id]: true }); }; const handleAddUser = (data) => { - if(data && data.objectId){ - const signerPtr = { - __type: "Pointer", - className: "contracts_Contactbook", - objectId: data.objectId - }; - const updatePlaceHolder = signerPos.map((x) => { - if (x.Id === uniqueId) { - return { ...x, signerPtr: signerPtr, signerObjId: data.objectId }; - } - return { ...x }; - }); - // console.log("updatePlaceHolder ", updatePlaceHolder); - setSignerPos(updatePlaceHolder); + if (data && data.objectId) { + const signerPtr = { + __type: "Pointer", + className: "contracts_Contactbook", + objectId: data.objectId + }; + const updatePlaceHolder = signerPos.map((x) => { + if (x.Id === uniqueId) { + return { ...x, signerPtr: signerPtr, signerObjId: data.objectId }; + } + return { ...x }; + }); + // console.log("updatePlaceHolder ", updatePlaceHolder); + setSignerPos(updatePlaceHolder); - const updateSigner = signersdata.map((x) => { - if (x.Id === uniqueId) { - return { ...x, ...data }; - } - return { ...x }; - }); - // console.log("updateSigner ", updateSigner); - - setSignersData(updateSigner); - } + const updateSigner = signersdata.map((x) => { + if (x.Id === uniqueId) { + return { ...x, ...data, className: "contracts_Contactbook" }; + } + return { ...x }; + }); + // console.log("updateSigner ", updateSigner); + setSignersData(updateSigner); + const index = signersdata.findIndex((x) => x.Id === uniqueId); + setIsSelectId(index); + } }; const closePopup = () => { @@ -944,7 +909,7 @@ function PlaceHolderSign() { }; return ( <> - <Title title={"placeholder"} /> + <Title title={state?.title ? state.title : "New Document"} /> <DndProvider backend={HTML5Backend}> {isLoading.isLoad ? ( <Loader isLoading={isLoading} /> @@ -1056,13 +1021,13 @@ function PlaceHolderSign() { {/* signature modal */} <Modal.Body> <p>You have successfully sent mails to all recipients!</p> - {currentEmail?.length > 0 && ( + {currentId && ( <p>Do you want to sign documents right now ?</p> )} </Modal.Body> <Modal.Footer> - {currentEmail?.length > 0 ? ( + {currentId ? ( <> <button onClick={() => { diff --git a/microfrontends/SignDocuments/src/Component/recipientSignPdf.js b/microfrontends/SignDocuments/src/Component/recipientSignPdf.js index 3c79eb685..b3b758527 100644 --- a/microfrontends/SignDocuments/src/Component/recipientSignPdf.js +++ b/microfrontends/SignDocuments/src/Component/recipientSignPdf.js @@ -37,6 +37,8 @@ import RenderPdf from "./component/renderPdf"; import CustomModal from "./component/CustomModal"; import { modalAlign } from "../utils/Utils"; import AlertComponent from "./component/alertComponent"; +import TourContentWithBtn from "../premitives/TourContentWithBtn"; +import Title from "./component/Title"; function EmbedPdfImage() { const { id, contactBookId } = useParams(); const [isSignPad, setIsSignPad] = useState(false); @@ -84,6 +86,7 @@ function EmbedPdfImage() { }); const [containerWH, setContainerWH] = useState({}); const [isAlert, setIsAlert] = useState({ isShow: false, alertMessage: "" }); + const [isDontShow, setIsDontShow] = useState(false); const docId = id && id; const isMobile = window.innerWidth < 767; const index = xyPostion.findIndex((object) => { @@ -645,66 +648,86 @@ function EmbedPdfImage() { //function for update TourStatus const closeTour = async () => { setSignTour(false); - - let updatedTourStatus = []; - if (tourStatus.length > 0) { - updatedTourStatus = [...tourStatus]; - const recipientssignIndex = tourStatus.findIndex( - (obj) => - obj["recipientssign"] === false || obj["recipientssign"] === true - ); - if (recipientssignIndex !== -1) { - updatedTourStatus[recipientssignIndex] = { recipientssign: true }; - } else { - updatedTourStatus.push({ recipientssign: true }); - } - } else { - updatedTourStatus = [{ recipientssign: true }]; - } - - await axios - .put( - `${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( - "_appName" - )}${contractName}/${signerUserId}`, - { - TourStatus: updatedTourStatus - }, - { - headers: { - "Content-Type": "application/json", - "X-Parse-Application-Id": localStorage.getItem("parseAppId"), - "X-Parse-Session-Token": localStorage.getItem("accesstoken") - } + if (isDontShow) { + let updatedTourStatus = []; + if (tourStatus.length > 0) { + updatedTourStatus = [...tourStatus]; + const recipientssignIndex = tourStatus.findIndex( + (obj) => + obj["recipientssign"] === false || obj["recipientssign"] === true + ); + if (recipientssignIndex !== -1) { + updatedTourStatus[recipientssignIndex] = { recipientssign: true }; + } else { + updatedTourStatus.push({ recipientssign: true }); } - ) - .then((Listdata) => { - // const json = Listdata.data; - // const res = json.results; - // console.log("res", json); - }) - .catch((err) => { - console.log("axois err ", err); - }); + } else { + updatedTourStatus = [{ recipientssign: true }]; + } + + await axios + .put( + `${localStorage.getItem("baseUrl")}classes/${localStorage.getItem( + "_appName" + )}${contractName}/${signerUserId}`, + { + TourStatus: updatedTourStatus + }, + { + headers: { + "Content-Type": "application/json", + "X-Parse-Application-Id": localStorage.getItem("parseAppId"), + "X-Parse-Session-Token": localStorage.getItem("accesstoken") + } + } + ) + .then((Listdata) => { + // const json = Listdata.data; + // const res = json.results; + // console.log("res", json); + }) + .catch((err) => { + console.log("axois err ", err); + }); + } + }; + + const handleDontShow = (isChecked) => { + setIsDontShow(isChecked); }; const tourFunction = () => { const tourConfig = [ { selector: '[data-tut="reactourFirst"]', - content: `You can click "Auto Sign All" to automatically sign at all the locations meant to be signed by you.Make sure that you review the document properly before you click this button.`, + content: () => ( + <TourContentWithBtn + message={`You can click "Auto Sign All" to automatically sign at all the locations meant to be signed by you.Make sure that you review the document properly before you click this button.`} + isChecked={handleDontShow} + /> + ), position: "top", style: { fontSize: "13px" } }, { selector: '[data-tut="reactourSecond"]', - content: `Click any of such placeholders appearing on the document to sign.You will see the options to draw sign or upload an image once you click here.`, + content: () => ( + <TourContentWithBtn + message={`Click any of such placeholders appearing on the document to sign.You will see the options to draw sign or upload an image once you click here.`} + isChecked={handleDontShow} + /> + ), position: "top", style: { fontSize: "13px" } }, { selector: '[data-tut="reactourThird"]', - content: `Click here to finish & download the signed document.You will also receive a copy on your email.`, + content: () => ( + <TourContentWithBtn + message={`Click here to finish & download the signed document.You will also receive a copy on your email.`} + isChecked={handleDontShow} + /> + ), position: "top", style: { fontSize: "13px" } } @@ -730,6 +753,7 @@ function EmbedPdfImage() { return ( <DndProvider backend={HTML5Backend}> + <Title title={"Sign Document"} /> {isLoading.isLoad ? ( <Loader isLoading={isLoading} /> ) : handleError ? ( diff --git a/microfrontends/SignDocuments/src/css/AddUser.css b/microfrontends/SignDocuments/src/css/AddUser.css index 0e52ba2a0..00576a9fc 100644 --- a/microfrontends/SignDocuments/src/css/AddUser.css +++ b/microfrontends/SignDocuments/src/css/AddUser.css @@ -1,6 +1,6 @@ .addusercontainer { height: 100%; - padding: 20px; + padding: 10px 20px 10px 20px; } .loaderdiv { diff --git a/microfrontends/SignDocuments/src/premitives/AddUser.js b/microfrontends/SignDocuments/src/premitives/AddUser.js index 07b6b1217..8590ba0df 100644 --- a/microfrontends/SignDocuments/src/premitives/AddUser.js +++ b/microfrontends/SignDocuments/src/premitives/AddUser.js @@ -158,10 +158,10 @@ const AddUser = (props) => { const res = await contactQuery.save(); const parseData = JSON.parse(JSON.stringify(res)); - props.details({ - value: parseData[props.valueKey], - label: parseData[props.displayKey] - }); + if(props.details){ + props.details(parseData); + } + if (props.closePopup) { props.closePopup(); } diff --git a/microfrontends/SignDocuments/src/premitives/RecipientList.js b/microfrontends/SignDocuments/src/premitives/RecipientList.js index 9f533a849..9dc74f861 100644 --- a/microfrontends/SignDocuments/src/premitives/RecipientList.js +++ b/microfrontends/SignDocuments/src/premitives/RecipientList.js @@ -80,11 +80,14 @@ const RecipientList = (props) => { : nonHoverStyle(ind) } onClick={() => { - props.setSignerObjId(obj?.objectId); + props.setSignerObjId(obj?.objectId || ""); props.setIsSelectId(ind); - props.setContractName(obj?.className); + props.setContractName(obj?.className || ""); props.setUniqueId(obj.Id); props.setRoleName(obj.Role); + if(props.handleModal){ + props.handleModal() + } }} > <div diff --git a/microfrontends/SignDocuments/src/premitives/SelectSigners.js b/microfrontends/SignDocuments/src/premitives/SelectSigners.js index 88b188842..959b28af2 100644 --- a/microfrontends/SignDocuments/src/premitives/SelectSigners.js +++ b/microfrontends/SignDocuments/src/premitives/SelectSigners.js @@ -26,9 +26,9 @@ const SelectSigners = (props) => { // `handleOptions` is used to set just save from quick form to selected option in dropdown const handleOptions = (item) => { setSelected(item); - const userData = userList.filter((x) => x.objectId === item.value); - if (userData.length > 0) { - setUserData(userData[0]); + const userData = userList.find((x) => x.objectId === item.value); + if (userData) { + setUserData(userData); } }; const handleAdd = () => { @@ -87,10 +87,9 @@ const SelectSigners = (props) => { /> </div> {isError ? <p style={{color:'red', fontSize: "12px", margin:"5px"}}>Please select signer</p>: <p style={{color:'transparent', fontSize: "12px", margin:"5px"}}>.</p>} - - <div > + <div> <button className="submitbutton" onClick={() => handleAdd()}> - Add Signer + Submit </button> </div> </div> diff --git a/microfrontends/SignDocuments/src/premitives/TourContentWithBtn.js b/microfrontends/SignDocuments/src/premitives/TourContentWithBtn.js new file mode 100644 index 000000000..54295b43d --- /dev/null +++ b/microfrontends/SignDocuments/src/premitives/TourContentWithBtn.js @@ -0,0 +1,26 @@ +import React, { useState } from "react"; + +export default function TourContentWithBtn({ message, isChecked }) { + const [isCheck, setIsCheck] = useState(false); + + const handleCheck = () => { + setIsCheck(!isCheck); + if (isChecked) { + isChecked(!isCheck); + } + }; + return ( + <div> + <p>{message}</p> + <label style={{ textAlign: "center", display: "flex", "justifyContent":'center' }}> + <input + type="checkbox" + style={{ marginRight: 3 }} + checked={isCheck} + onChange={handleCheck} + />{" "} + <span style={{color:"#787878", fontSize: 12}}>Don't show this again</span> + </label> + </div> + ); +} diff --git a/microfrontends/SignDocuments/src/utils/Utils.js b/microfrontends/SignDocuments/src/utils/Utils.js index 6f93e1237..8721933d7 100644 --- a/microfrontends/SignDocuments/src/utils/Utils.js +++ b/microfrontends/SignDocuments/src/utils/Utils.js @@ -764,7 +764,8 @@ export const handleSignYourselfImageResize = ( key, xyPostion, index, - setXyPostion + setXyPostion, + ) => { // const updateFilter = xyPostion[index].pos.filter( // (data) => data.key === key && data.Width && data.Height