diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js
index 5db2c30ae..c1b53f17e 100644
--- a/apps/OpenSign/src/pages/PdfRequestFiles.js
+++ b/apps/OpenSign/src/pages/PdfRequestFiles.js
@@ -1578,7 +1578,10 @@ function PdfRequestFiles() {
handleClose={() => {
setIsCompleted((prev) => ({ ...prev, isModal: false }));
}}
- reduceWidth={!isCompleted?.message}
+ reduceWidth={
+ !isCompleted?.message &&
+ "md:min-w-[440px] md:max-w-[400px]"
+ }
>
{isCompleted?.message ? (
diff --git a/apps/OpenSign/src/pages/UserProfile.js b/apps/OpenSign/src/pages/UserProfile.js
index 6b7cd6172..fe27836eb 100644
--- a/apps/OpenSign/src/pages/UserProfile.js
+++ b/apps/OpenSign/src/pages/UserProfile.js
@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from "react";
+import React, { useState, useEffect, useRef } from "react";
import { Navigate, useNavigate } from "react-router-dom";
import Parse from "parse";
import { SaveFileSize } from "../constant/saveFileSize";
@@ -27,6 +27,10 @@ function UserProfile() {
const [percentage, setpercentage] = useState(0);
const [isDisableDocId, setIsDisableDocId] = useState(false);
const [isSubscribe, setIsSubscribe] = useState(false);
+ const [publicUserName, setPublicUserName] = useState(
+ extendUser && extendUser?.[0]?.UserName
+ );
+ const previousPublicUserName = useRef(publicUserName);
const [company, setCompany] = useState(
extendUser && extendUser?.[0]?.Company
);
@@ -37,6 +41,7 @@ function UserProfile() {
const [otp, setOtp] = useState("");
const [otpLoader, setOtpLoader] = useState(false);
const [isEmailVerified, setIsEmailVerified] = useState(false);
+ const [userNameError, setUserNameError] = useState("");
useEffect(() => {
getUserDetail();
}, []);
@@ -74,46 +79,72 @@ function UserProfile() {
}
}
};
+ //function to check public username already exist
+ const handleCheckPublicUserName = async () => {
+ try {
+ const res = await Parse.Cloud.run("getpublicusername", {
+ username: publicUserName
+ });
+ if (res) {
+ setIsLoader(false);
+ setUserNameError("user name already exist");
+ setTimeout(() => {
+ setUserNameError("");
+ }, 3000);
+ return res;
+ }
+ } catch (e) {
+ console.log("error in getpublicusername cloud function");
+ }
+ };
const handleSubmit = async (e) => {
e.preventDefault();
- setIsLoader(true);
- let phn = Phone;
-
- try {
- const tour = Parse.Object.extend("_User");
- const query = new Parse.Query(tour);
-
- await query.get(UserProfile.objectId).then((object) => {
- object.set("name", name);
- object.set("ProfilePic", Image);
- object.set("phone", phn || "");
-
- object.save().then(
- async (response) => {
- if (response) {
- let res = response.toJSON();
- let rr = JSON.stringify(res);
- localStorage.setItem("UserInformation", rr);
- SetName(res.name);
- SetPhone(res?.phone || "");
- setImage(res.ProfilePic);
- localStorage.setItem("username", res.name);
- localStorage.setItem("profileImg", res.ProfilePic);
- await updateExtUser({ Name: res.name, Phone: res?.phone || "" });
- alert("Profile updated successfully.");
- setEditMode(false);
- navigate("/dashboard/35KBoSgoAK");
+ let phn = Phone,
+ res;
+ //condition to call cloud function when user change publicUserName
+ if (previousPublicUserName.current !== publicUserName) {
+ res = await handleCheckPublicUserName();
+ }
+ if (!res) {
+ setIsLoader(true);
+ try {
+ const userQuery = Parse.Object.extend("_User");
+ const query = new Parse.Query(userQuery);
+ await query.get(UserProfile.objectId).then((object) => {
+ object.set("name", name);
+ object.set("ProfilePic", Image);
+ object.set("phone", phn || "");
+ object.save().then(
+ async (response) => {
+ if (response) {
+ let res = response.toJSON();
+ let rr = JSON.stringify(res);
+ localStorage.setItem("UserInformation", rr);
+ SetName(res.name);
+ SetPhone(res?.phone || "");
+ setImage(res.ProfilePic);
+ localStorage.setItem("username", res.name);
+ localStorage.setItem("profileImg", res.ProfilePic);
+ await updateExtUser({
+ Name: res.name,
+ Phone: res?.phone || ""
+ });
+ alert("Profile updated successfully.");
+ setEditMode(false);
+ setIsLoader(false);
+ //navigate("/dashboard/35KBoSgoAK");
+ }
+ },
+ (error) => {
+ alert("Something went wrong.");
+ console.error("Error while updating tour", error);
+ setIsLoader(false);
}
- },
- (error) => {
- alert("Something went wrong.");
- console.error("Error while updating tour", error);
- setIsLoader(false);
- }
- );
- });
- } catch (error) {
- console.log("err", error);
+ );
+ });
+ } catch (error) {
+ console.log("err", error);
+ }
}
};
@@ -122,14 +153,15 @@ function UserProfile() {
const extClass = localStorage.getItem("extended_class");
const extData = JSON.parse(localStorage.getItem("Extand_Class"));
const ExtUserId = extData[0].objectId;
-
const body = {
Phone: obj?.Phone || "",
Name: obj.Name,
HeaderDocId: isDisableDocId,
JobTitle: jobTitle,
- Company: company
+ Company: company,
+ UserName: publicUserName || ""
};
+
await axios.put(
parseBaseUrl + "classes/" + extClass + "/" + ExtUserId,
body,
@@ -147,7 +179,6 @@ function UserProfile() {
const json = JSON.parse(JSON.stringify([res]));
const extRes = JSON.stringify(json);
-
localStorage.setItem("Extand_Class", extRes);
// console.log("updateRes ", updateRes);
};
@@ -241,6 +272,27 @@ function UserProfile() {
setOtpLoader(false);
alert("OTP sent on you email");
};
+ //function to handle onchange username and restrict 6-characters username for free users
+ const handleOnchangeUserName = (e) => {
+ const value = e.target.value;
+ if (value.length > 6 && !isSubscribe) {
+ setUserNameError("Please upgrade to allow more than 6 characters.");
+ setTimeout(() => {
+ setUserNameError("");
+ }, 2000);
+ } else {
+ setPublicUserName(e.target.value);
+ }
+ };
+ const handleCancel = () => {
+ setEditMode(false);
+ SetName(localStorage.getItem("username"));
+ SetPhone(UserProfile && UserProfile.phone);
+ setImage(localStorage.getItem("profileImg"));
+ setPublicUserName(extendUser && extendUser?.[0]?.UserName);
+ setCompany(extendUser && extendUser?.[0]?.Company);
+ setJobTitle(extendUser?.[0]?.JobTitle);
+ };
return (
@@ -262,7 +314,14 @@ function UserProfile() {
>
) : (
-
+
+ {userNameError && (
+
+ {userNameError}
+
+ )}
@@ -390,6 +449,37 @@ function UserProfile() {
)}
+ {!isEnableSubscription && (
+
+
+ Public profile :{" "}
+
+
+
+ opensign-me.vercel.app/
+ {editmode ? (
+
+ ) : (
+
+ )}
+
+
+ )}
{
if (editmode) {
- setEditMode(false);
+ handleCancel();
} else {
navigate("/changepassword");
}
diff --git a/apps/OpenSign/src/primitives/GetReportDisplay.js b/apps/OpenSign/src/primitives/GetReportDisplay.js
index 2daf17a70..a20f72c55 100644
--- a/apps/OpenSign/src/primitives/GetReportDisplay.js
+++ b/apps/OpenSign/src/primitives/GetReportDisplay.js
@@ -4,14 +4,19 @@ import { useNavigate } from "react-router-dom";
import axios from "axios";
import ModalUi from "./ModalUi";
import AddSigner from "../components/AddSigner";
-import { modalSubmitBtnColor, modalCancelBtnColor } from "../constant/const";
+import {
+ modalSubmitBtnColor,
+ modalCancelBtnColor,
+ isEnableSubscription
+} from "../constant/const";
import Alert from "./Alert";
import Tooltip from "./Tooltip";
import { RWebShare } from "react-web-share";
import Tour from "reactour";
import Parse from "parse";
import { saveAs } from "file-saver";
-import { replaceMailVaribles } from "../constant/Utils";
+import { copytoData, replaceMailVaribles } from "../constant/Utils";
+import Confetti from "react-confetti";
import EditorToolbar, {
module1,
formats
@@ -36,6 +41,7 @@ const ReportTable = (props) => {
const [isTour, setIsTour] = useState(false);
const [tourStatusArr, setTourStatusArr] = useState([]);
const [isResendMail, setIsResendMail] = useState({});
+ const [isMakePublic, setIsMakePublic] = useState({});
const [mail, setMail] = useState({ subject: "", body: "" });
const [userDetails, setUserDetails] = useState({});
const [isNextStep, setIsNextStep] = useState({});
@@ -43,6 +49,12 @@ const ReportTable = (props) => {
const [templateDeatils, setTemplateDetails] = useState({});
const [placeholders, setPlaceholders] = useState([]);
const [isLoader, setIsLoader] = useState({});
+ const [selectedPublicRole, setSelectedPublicRole] = useState("");
+ const [isCelebration, setIsCelebration] = useState(false);
+ const [currentLists, setCurrentLists] = useState([]);
+ const [isPublic, setIsPublic] = useState({});
+ const [isPublicProfile, setIsPublicProfile] = useState({});
+ const [publicUserName, setIsPublicUserName] = useState("");
const [isViewShare, setIsViewShare] = useState({});
const startIndex = (currentPage - 1) * props.docPerPage;
const { isMoreDocs, setIsNextRecord } = props;
@@ -234,8 +246,19 @@ const ReportTable = (props) => {
// Get current list
const indexOfLastDoc = currentPage * props.docPerPage;
const indexOfFirstDoc = indexOfLastDoc - props.docPerPage;
- // `currentLists` is total record render on current page
- const currentLists = props.List?.slice(indexOfFirstDoc, indexOfLastDoc);
+ useEffect(() => {
+ // `currentLists` is total record render on current page
+ const currentList = props.List?.slice(indexOfFirstDoc, indexOfLastDoc);
+ //check public template and save in a object to show public and private template
+ setIsPublic(
+ currentList.reduce((acc, item) => {
+ acc[item.objectId] = item?.IsPublic || false;
+ return acc;
+ }, {})
+ );
+ setCurrentLists(currentList);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [indexOfLastDoc, indexOfFirstDoc]);
// Change page
const paginateFront = () => setCurrentPage(currentPage + 1);
@@ -297,9 +320,16 @@ const ReportTable = (props) => {
setActLoader({});
}
};
- const handleClose = () => {
+ const handleClose = (item) => {
setIsRevoke({});
setIsDeleteModal({});
+ setIsMakePublic({});
+ setSelectedPublicRole("");
+ setIsPublic((prevStates) => ({
+ ...prevStates,
+ [item.objectId]: !prevStates[item.objectId]
+ }));
+ setIsPublicProfile({});
};
const handleShare = (item) => {
@@ -687,9 +717,118 @@ const ReportTable = (props) => {
setTimeout(() => setIsAlert(false), 1500);
}
};
+
+ //function to make template public and set public role
+ const handlePublicTemplate = async (item) => {
+ if (selectedPublicRole || !isPublic[item.objectId]) {
+ setActLoader({ [item.objectId]: true });
+ setIsMakePublic(false);
+ try {
+ const res = await Parse.Cloud.run("createpublictemplate", {
+ templateid: item.objectId,
+ ispublic: isPublic[item.objectId],
+ publicrole: [selectedPublicRole]
+ });
+
+ if (res.status === "success") {
+ setIsAlert(true);
+ setTimeout(() => setIsAlert(false), 1500);
+ if (isPublic[item.objectId]) {
+ setAlertMsg({
+ type: "success",
+ message: "You have successfully made the template public."
+ });
+ setIsCelebration(true);
+ setTimeout(() => {
+ setIsCelebration(false);
+ }, 5000);
+ setIsPublicProfile({ [item.objectId]: isPublic[item.objectId] });
+ } else {
+ setAlertMsg({
+ type: "success",
+ message: "You have successfully made the template private."
+ });
+ setSelectedPublicRole("");
+ }
+ const updateList = props.List.map((x) =>
+ x.objectId === item.objectId
+ ? { ...x, IsPublic: isPublic[item.objectId] }
+ : x
+ );
+ props.setList(updateList);
+ setActLoader({});
+ }
+ } catch (e) {
+ console.log("error in createpublictemplate", e);
+ setIsAlert(true);
+ setAlertMsg({
+ type: "danger",
+ message: "Something went wrong, Please try again later!"
+ });
+ setTimeout(() => setIsAlert(false), 1500);
+ setIsPublic((prevStates) => ({
+ ...prevStates,
+ [item.objectId]: !prevStates[item.objectId]
+ }));
+ }
+ } else {
+ setIsAlert(true);
+ setAlertMsg({
+ type: "danger",
+ message: "You need to select a role for the public signers."
+ });
+ setTimeout(() => setIsAlert(false), 1500);
+ }
+ };
+
const handleViewSigners = (item) => {
setIsViewShare({ [item.objectId]: true });
};
+ //function to handle change template status is public or private
+ const handlePublicChange = async (e, item) => {
+ const getPlaceholder = item?.Placeholders;
+ //condiiton to check role is exist or not
+ if (getPlaceholder && getPlaceholder.length > 0) {
+ let extendUser = JSON.parse(localStorage.getItem("Extand_Class"));
+ const userName = extendUser[0]?.UserName;
+ setIsPublicUserName(extendUser[0]?.UserName);
+ //condition to check user have public url or not
+ if (userName) {
+ setIsPublic((prevStates) => ({
+ ...prevStates,
+ [item.objectId]: e.target.checked
+ }));
+ const getPlaceholder = item?.Placeholders;
+ if (getPlaceholder.length === 1) {
+ setSelectedPublicRole(getPlaceholder[0]?.Role);
+ }
+
+ setIsMakePublic({ [item.objectId]: true });
+ } else {
+ setIsPublicProfile({ [item.objectId]: true });
+ }
+ } else {
+ setIsAlert(true);
+ setAlertMsg({
+ type: "danger",
+ message: "Please assign at least one role to make this template public."
+ });
+ setTimeout(() => setIsAlert(false), 3000);
+ }
+ };
+
+ //function to copy public profile links
+ const copytoProfileLink = () => {
+ const url = `https://opensign-me.vercel.app/${publicUserName}`;
+ copytoData(url);
+ setIsAlert(true);
+ setAlertMsg({
+ type: "success",
+ message: "Copied."
+ });
+ setTimeout(() => setIsAlert(false), 1500);
+ };
+
return (
{Object.keys(actLoader)?.length > 0 && (
@@ -701,6 +840,11 @@ const ReportTable = (props) => {
)}
+ {isCelebration && (
+
+
+
+ )}
{isAlert &&
{alertMsg.message} }
{props.tourData && props.ReportName === "Templates" && (
{
{props.actions?.length > 0 && (
Action
)}
+ {props.ReportName === "Templates" && !isEnableSubscription && (
+ Public
+ )}
@@ -1186,6 +1333,170 @@ const ReportTable = (props) => {
)}
+ {!isEnableSubscription && (
+
+ {props.ReportName === "Templates" && (
+
+
+ handlePublicChange(e, item)}
+ type="checkbox"
+ value=""
+ className="sr-only peer"
+ />
+
+
+
+ )}
+ {isMakePublic[item.objectId] && (
+ {
+ setIsMakePublic({});
+ setSelectedPublicRole("");
+ setIsPublic((prevStates) => ({
+ ...prevStates,
+ [item.objectId]: !prevStates[item.objectId]
+ }));
+ }}
+ >
+
+
+
+ {" "}
+ {isPublic[item.objectId]
+ ? `Are you sure you want tof make this templat public ?`
+ : `Are you sure you want to make this template private? This will remove it from your public profile ?`}
+
+ {isPublic[item.objectId] && (
+
+
+ Public role :{" "}
+
+ {item?.Placeholders?.length > 1 ? (
+
+ setSelectedPublicRole(
+ e.target.value
+ )
+ }
+ >
+
+ Select...
+
+ {item?.Placeholders.map(
+ (data, ind) => {
+ return (
+
+ {data?.Role}
+
+ );
+ }
+ )}
+
+ ) : (
+
+ {item?.Placeholders[0]?.Role}
+
+ )}
+
+ )}
+
+
+
+
+ handlePublicTemplate(item)}
+ className="px-4 py-1.5 text-white rounded shadow-md text-center focus:outline-none "
+ style={{
+ backgroundColor: modalSubmitBtnColor
+ }}
+ >
+ Submit
+
+ handleClose(item)}
+ className="px-4 py-1.5 text-black border-[1px] border-[#ccc] shadow-md rounded focus:outline-none"
+ style={{
+ backgroundColor: modalCancelBtnColor
+ }}
+ >
+ No
+
+
+
+
+ )}
+ {isPublicProfile[item.objectId] && (
+ {
+ setIsPublicProfile({});
+ }}
+ reduceWidth={"md:min-w-[440px] md:max-w-[400px]"}
+ >
+
+ {publicUserName ? (
+
+
+ Here’s your public URL. Copy or share it
+ with the signer, and you will be able to
+ see all your publicly set templates.
+
+
+
+ Public URL :{" "}
+
+ copytoProfileLink()}
+ className="underline underline-offset-2 cursor-pointer"
+ >{`https://opensign.me/${publicUserName}`}
+
+
+ ) : (
+
+
+ Please add your public URL, and you will
+ be able to make a public template.
+
+
navigate("/profile")}
+ >
+ Add
+
+
+ )}
+
+
+ )}
+
+ )}
)
)}
diff --git a/apps/OpenSign/src/primitives/ModalUi.js b/apps/OpenSign/src/primitives/ModalUi.js
index 778d483d1..b0413b430 100644
--- a/apps/OpenSign/src/primitives/ModalUi.js
+++ b/apps/OpenSign/src/primitives/ModalUi.js
@@ -19,9 +19,7 @@ const ModalUi = ({
{showHeader && (
diff --git a/apps/OpenSignServer/cloud/main.js b/apps/OpenSignServer/cloud/main.js
index 0552d2930..6de2c181a 100644
--- a/apps/OpenSignServer/cloud/main.js
+++ b/apps/OpenSignServer/cloud/main.js
@@ -39,6 +39,9 @@ import encryptedpdf from './parsefunction/encryptedPdf.js';
import { getSignedUrl } from './parsefunction/getSignedUrl.js';
import createBatchDocs from './parsefunction/createBatchDocs.js';
import linkContactToDoc from './parsefunction/linkContactToDoc.js';
+import CreatePublicTemplate from './parsefunction/CreatePublicTemplate.js';
+import GetPublicUserName from './parsefunction/GetPublicUserName.js';
+import GetPublicTemplate from './parsefunction/GetPublicTemplate.js';
// This afterSave function triggers after an object is added or updated in the specified class, allowing for post-processing logic.
Parse.Cloud.afterSave('contracts_Document', DocumentAftersave);
@@ -88,3 +91,6 @@ Parse.Cloud.define('encryptedpdf', encryptedpdf);
Parse.Cloud.define('getsignedurl', getSignedUrl);
Parse.Cloud.define('batchdocuments', createBatchDocs);
Parse.Cloud.define('linkcontacttodoc', linkContactToDoc);
+Parse.Cloud.define('createpublictemplate', CreatePublicTemplate);
+Parse.Cloud.define('getpublicusername', GetPublicUserName);
+Parse.Cloud.define('getpublictemplate', GetPublicTemplate);
diff --git a/apps/OpenSignServer/cloud/parsefunction/CreatePublicTemplate.js b/apps/OpenSignServer/cloud/parsefunction/CreatePublicTemplate.js
new file mode 100644
index 000000000..1831b9f47
--- /dev/null
+++ b/apps/OpenSignServer/cloud/parsefunction/CreatePublicTemplate.js
@@ -0,0 +1,41 @@
+export default async function CreatePublicTemplate(request) {
+ const templateid = request.params.templateid;
+ const ispublic = request.params.ispublic;
+ const publicrole = request.params.publicrole;
+ try {
+ if (!request?.user) {
+ throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.');
+ } else {
+ const userId = request?.user && request?.user?.id;
+ if (templateid) {
+ const updateTemplate = new Parse.Object('contracts_Template');
+ updateTemplate.id = templateid;
+ if (ispublic) {
+ updateTemplate.set('PublicRole', publicrole);
+ }
+ updateTemplate.set('IsPublic', ispublic);
+ const Acl = new Parse.ACL();
+ if (ispublic) {
+ Acl.setPublicReadAccess(true);
+ }
+ Acl.setReadAccess(userId, true);
+ Acl.setWriteAccess(userId, true);
+ updateTemplate.setACL(Acl);
+ const savedObject = await updateTemplate.save(null, { useMasterKey: true });
+ const res = savedObject.toJSON();
+ if (res) {
+ return {
+ status: 'success',
+ };
+ }
+ } else {
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Please provide required parameters!');
+ }
+ }
+ } catch (err) {
+ const code = err.code || 400;
+ const msg = err.message;
+ const error = new Parse.Error(code, msg);
+ throw error;
+ }
+}
diff --git a/apps/OpenSignServer/cloud/parsefunction/GetPublicTemplate.js b/apps/OpenSignServer/cloud/parsefunction/GetPublicTemplate.js
new file mode 100644
index 000000000..2b356bd32
--- /dev/null
+++ b/apps/OpenSignServer/cloud/parsefunction/GetPublicTemplate.js
@@ -0,0 +1,32 @@
+async function GetPublicTemplate(request) {
+ try {
+ const username = request.params.username;
+ if (username) {
+ const extUserQuery = new Parse.Query('contracts_Users');
+ extUserQuery.equalTo('UserName', username);
+ const res = await extUserQuery.first({ useMasterKey: true });
+ const userId = res.get('UserId').id;
+ if (userId) {
+ const templatQuery = new Parse.Query('contracts_Template');
+ templatQuery.equalTo('CreatedBy', {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: userId,
+ });
+ templatQuery.equalTo('IsPublic', true);
+ const getTemplate = await templatQuery.find({ useMasterKey: true });
+ return getTemplate;
+ } else {
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Template not found');
+ }
+ } else {
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Please provide required parameters!');
+ }
+ } catch (err) {
+ const code = err.code || 400;
+ const msg = err.message;
+ const error = new Parse.Error(code, msg);
+ throw error;
+ }
+}
+export default GetPublicTemplate;
diff --git a/apps/OpenSignServer/cloud/parsefunction/GetPublicUserName.js b/apps/OpenSignServer/cloud/parsefunction/GetPublicUserName.js
new file mode 100644
index 000000000..94b08a330
--- /dev/null
+++ b/apps/OpenSignServer/cloud/parsefunction/GetPublicUserName.js
@@ -0,0 +1,23 @@
+async function GetPublicUserName(request) {
+ try {
+ if (!request?.user) {
+ throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.');
+ } else {
+ const username = request.params.username;
+ if (username) {
+ const userQuery = new Parse.Query('contracts_Users');
+ userQuery.equalTo('UserName', username);
+ const res = await userQuery.first({ useMasterKey: true });
+ return res;
+ } else {
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Please provide required parameters!');
+ }
+ }
+ } catch (err) {
+ const code = err.code || 400;
+ const msg = err.message;
+ const error = new Parse.Error(code, msg);
+ throw error;
+ }
+}
+export default GetPublicUserName;
diff --git a/apps/OpenSignServer/cloud/parsefunction/reportsJson.js b/apps/OpenSignServer/cloud/parsefunction/reportsJson.js
index 64c5cf522..37b53b95a 100644
--- a/apps/OpenSignServer/cloud/parsefunction/reportsJson.js
+++ b/apps/OpenSignServer/cloud/parsefunction/reportsJson.js
@@ -334,6 +334,7 @@ export default function reportJson(id, userId) {
'Signers.Email',
'Signers.Phone',
'Placeholders',
+ 'IsPublic',
],
};
default:
diff --git a/apps/OpenSignServer/databases/migrations/20240527194216-update_contracts_template_cls_cjs.cjs b/apps/OpenSignServer/databases/migrations/20240527194216-update_contracts_template_cls_cjs.cjs
new file mode 100644
index 000000000..94489b287
--- /dev/null
+++ b/apps/OpenSignServer/databases/migrations/20240527194216-update_contracts_template_cls_cjs.cjs
@@ -0,0 +1,35 @@
+/**
+ *
+ * @param {Parse} Parse
+ */
+exports.up = async Parse => {
+ // TODO: set className here
+ const className = 'contracts_Template';
+ const schema = new Parse.Schema(className);
+ schema.addArray('PublicRole');
+ schema.addBoolean('IsPublic');
+
+ // TODO: Set the schema here
+ // Example:
+ // schema.addString('name').addNumber('cash');
+
+ return schema.update();
+};
+
+/**
+ *
+ * @param {Parse} Parse
+ */
+exports.down = async Parse => {
+ // TODO: set className here
+ const className = 'contracts_Template';
+ const schema = new Parse.Schema(className);
+ schema.deleteField('PublicRole');
+ schema.deleteField('IsPublic');
+
+ // TODO: Set the schema here
+ // Example:
+ // schema.deleteField('name').deleteField('cash');
+
+ return schema.update();
+};
diff --git a/apps/OpenSignServer/test.pdf b/apps/OpenSignServer/test.pdf
index 5facc82df..dfe01c088 100644
Binary files a/apps/OpenSignServer/test.pdf and b/apps/OpenSignServer/test.pdf differ