mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-20 06:35:54 +02:00
fix: handle getTemplate cloud function condition
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -43,10 +43,7 @@ function Header({
|
||||
|
||||
//function for show decline alert
|
||||
const handleDeclinePdfAlert = async () => {
|
||||
const currentDecline = {
|
||||
currnt: "Sure",
|
||||
isDeclined: true
|
||||
};
|
||||
const currentDecline = { currnt: "Sure", isDeclined: true };
|
||||
setIsDecline(currentDecline);
|
||||
};
|
||||
|
||||
@@ -208,7 +205,7 @@ function Header({
|
||||
</DropdownMenu.Trigger>
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content
|
||||
className="bg-white shadow-md rounded px-2 py-1"
|
||||
className="bg-white shadow-md rounded-full px-3 py-2"
|
||||
sideOffset={5}
|
||||
>
|
||||
<DropdownMenu.Item
|
||||
@@ -361,40 +358,16 @@ function Header({
|
||||
>
|
||||
Finish
|
||||
</button>
|
||||
<div className="op-dropdown op-dropdown-end">
|
||||
<div
|
||||
tabIndex={0}
|
||||
role="button"
|
||||
className="op-btn op-btn-info op-btn-sm shadow"
|
||||
>
|
||||
<i
|
||||
className="fa-light fa-ellipsis-v"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
</div>
|
||||
<ul
|
||||
tabIndex={0}
|
||||
className="op-dropdown-content z-[1] op-menu op-menu-sm p-1 shadow bg-base-100 rounded-box mt-1"
|
||||
>
|
||||
<li
|
||||
onClick={() =>
|
||||
handleDownloadPdf(
|
||||
pdfDetails,
|
||||
pdfUrl,
|
||||
setIsDownloading
|
||||
)
|
||||
}
|
||||
>
|
||||
<span className="font-semibold text-[12px]">
|
||||
<i
|
||||
className="fa-light fa-arrow-down"
|
||||
aria-hidden="true"
|
||||
></i>{" "}
|
||||
Download
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="op-btn op-btn-neutral op-btn-sm mr-[3px] shadow"
|
||||
onClick={() =>
|
||||
handleDownloadPdf(pdfDetails, pdfUrl, setIsDownloading)
|
||||
}
|
||||
>
|
||||
<i className="fa-light fa-arrow-down font-semibold lg:hidden"></i>
|
||||
<span className="hidden lg:block">Download</span>
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -346,14 +346,14 @@ export default function reportJson(id) {
|
||||
message:
|
||||
"This menu reveals more options such as Edit & Delete. Use the 'Edit' button to add signer roles, modify fields, and update your template. Changes will apply to all future documents created from this template but won’t affect existing documents.Use the Delete button you can delete template. ",
|
||||
subaction: [
|
||||
// {
|
||||
// btnId: "1873",
|
||||
// btnLabel: "Share-with",
|
||||
// hoverLabel: "Share-with",
|
||||
// btnIcon: "fa-light fa-share-nodes",
|
||||
// redirectUrl: "",
|
||||
// action: "sharewith"
|
||||
// },
|
||||
{
|
||||
btnId: "1873",
|
||||
btnLabel: "Share-with",
|
||||
hoverLabel: "Share-with",
|
||||
btnIcon: "fa-light fa-share-nodes",
|
||||
redirectUrl: "",
|
||||
action: "sharewith"
|
||||
},
|
||||
{
|
||||
btnId: "2434",
|
||||
btnLabel: "Edit",
|
||||
|
||||
@@ -1233,11 +1233,9 @@ function PdfRequestFiles(props) {
|
||||
});
|
||||
};
|
||||
//function for set decline true on press decline button
|
||||
const declineDoc = async () => {
|
||||
const declineDoc = async (reason) => {
|
||||
setIsDecline({ isDeclined: false });
|
||||
const data = {
|
||||
IsDeclined: true
|
||||
};
|
||||
const data = { IsDeclined: true, DeclineReason: reason };
|
||||
setIsUiLoading(true);
|
||||
|
||||
await axios
|
||||
@@ -1464,7 +1462,7 @@ function PdfRequestFiles(props) {
|
||||
try {
|
||||
const params = {
|
||||
...contact,
|
||||
tempid: pdfDetails[0]?.objectId,
|
||||
templateid: pdfDetails[0]?.objectId,
|
||||
role: pdfDetails[0]?.PublicRole[0]
|
||||
};
|
||||
const userRes = await axios.post(
|
||||
@@ -1854,12 +1852,9 @@ function PdfRequestFiles(props) {
|
||||
<ModalUi
|
||||
isOpen={defaultSignAlert.isShow}
|
||||
title={"Auto sign"}
|
||||
handleClose={() => {
|
||||
setDefaultSignAlert({
|
||||
isShow: false,
|
||||
alertMessage: ""
|
||||
});
|
||||
}}
|
||||
handleClose={() =>
|
||||
setDefaultSignAlert({ isShow: false, alertMessage: "" })
|
||||
}
|
||||
>
|
||||
<div className="h-full p-[20px]">
|
||||
<p>{defaultSignAlert.alertMessage}</p>
|
||||
@@ -1874,12 +1869,12 @@ function PdfRequestFiles(props) {
|
||||
Yes
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
onClick={() =>
|
||||
setDefaultSignAlert({
|
||||
isShow: false,
|
||||
alertMessage: ""
|
||||
});
|
||||
}}
|
||||
})
|
||||
}
|
||||
type="button"
|
||||
className="op-btn op-btn-secondary"
|
||||
>
|
||||
@@ -1888,12 +1883,9 @@ function PdfRequestFiles(props) {
|
||||
</>
|
||||
) : (
|
||||
<button
|
||||
onClick={() => {
|
||||
setIsAlert({
|
||||
isShow: false,
|
||||
alertMessage: ""
|
||||
});
|
||||
}}
|
||||
onClick={() =>
|
||||
setIsAlert({ isShow: false, alertMessage: "" })
|
||||
}
|
||||
type="button"
|
||||
className="op-btn op-btn-primary"
|
||||
>
|
||||
|
||||
@@ -65,6 +65,7 @@ const ReportTable = (props) => {
|
||||
const [publicUserName, setIsPublicUserName] = useState("");
|
||||
const [isViewShare, setIsViewShare] = useState({});
|
||||
const [isSubscribe, setIsSubscribe] = useState(true);
|
||||
const [reason, setReason] = useState("");
|
||||
const Extand_Class = localStorage.getItem("Extand_Class");
|
||||
const extClass = Extand_Class && JSON.parse(Extand_Class);
|
||||
const startIndex = (currentPage - 1) * props.docPerPage;
|
||||
@@ -143,21 +144,23 @@ const ReportTable = (props) => {
|
||||
if (props.ReportName === "Templates") {
|
||||
try {
|
||||
const extUser = JSON.parse(localStorage.getItem("Extand_Class"))?.[0];
|
||||
const team = new Parse.Query("contracts_Teams");
|
||||
team.equalTo("OrganizationId", {
|
||||
__type: "Pointer",
|
||||
className: "contracts_Organizations",
|
||||
objectId: extUser.OrganizationId.objectId
|
||||
});
|
||||
team.notEqualTo("IsActive", false);
|
||||
const teamtRes = await team.find();
|
||||
if (teamtRes.length > 0) {
|
||||
const _teamRes = JSON.parse(JSON.stringify(teamtRes));
|
||||
const formatedList = _teamRes.map((x) => ({
|
||||
label: x.Name,
|
||||
value: x.objectId
|
||||
}));
|
||||
setTeamList(formatedList);
|
||||
if (extUser?.OrganizationId?.objectId) {
|
||||
const team = new Parse.Query("contracts_Teams");
|
||||
team.equalTo("OrganizationId", {
|
||||
__type: "Pointer",
|
||||
className: "contracts_Organizations",
|
||||
objectId: extUser.OrganizationId.objectId
|
||||
});
|
||||
team.notEqualTo("IsActive", false);
|
||||
const teamtRes = await team.find();
|
||||
if (teamtRes.length > 0) {
|
||||
const _teamRes = JSON.parse(JSON.stringify(teamtRes));
|
||||
const formatedList = _teamRes.map((x) => ({
|
||||
label: x.Name,
|
||||
value: x.objectId
|
||||
}));
|
||||
setTeamList(formatedList);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log("Err in fetch top level teamlist", err);
|
||||
@@ -437,6 +440,7 @@ const ReportTable = (props) => {
|
||||
[item.objectId]: !prevStates[item.objectId]
|
||||
}));
|
||||
}
|
||||
setReason("");
|
||||
};
|
||||
|
||||
const handleShare = (item) => {
|
||||
@@ -471,10 +475,7 @@ const ReportTable = (props) => {
|
||||
const handleRevoke = async (item) => {
|
||||
setIsRevoke({});
|
||||
setActLoader({ [`${item.objectId}`]: true });
|
||||
const data = {
|
||||
IsDeclined: true
|
||||
};
|
||||
|
||||
const data = { IsDeclined: true, DeclineReason: reason };
|
||||
await axios
|
||||
.put(
|
||||
`${localStorage.getItem("baseUrl")}classes/contracts_Document/${
|
||||
@@ -492,6 +493,7 @@ const ReportTable = (props) => {
|
||||
.then(async (result) => {
|
||||
const res = result.data;
|
||||
if (res) {
|
||||
setReason("");
|
||||
setActLoader({});
|
||||
setIsAlert(true);
|
||||
setAlertMsg({
|
||||
@@ -507,6 +509,7 @@ const ReportTable = (props) => {
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("err", err);
|
||||
setReason("");
|
||||
setIsAlert(true);
|
||||
setAlertMsg({
|
||||
type: "danger",
|
||||
@@ -1706,20 +1709,28 @@ const ReportTable = (props) => {
|
||||
handleClose={handleClose}
|
||||
>
|
||||
<div className="m-[20px]">
|
||||
<div className="text-lg font-normal text-black">
|
||||
<div className="text-sm md:text-lg font-normal text-black">
|
||||
Are you sure you want to revoke this document?
|
||||
</div>
|
||||
<hr className="bg-[#ccc] mt-4" />
|
||||
<div className="mt-2">
|
||||
<textarea
|
||||
rows={3}
|
||||
placeholder="Reason (optional)"
|
||||
className="px-4 op-textarea op-textarea-bordered focus:outline-none hover:border-base-content w-full text-xs"
|
||||
value={reason}
|
||||
onChange={(e) => setReason(e.target.value)}
|
||||
></textarea>
|
||||
</div>
|
||||
<div className="flex items-center mt-3 gap-2">
|
||||
<button
|
||||
onClick={() => handleRevoke(item)}
|
||||
className="op-btn op-btn-primary"
|
||||
className="op-btn op-btn-primary px-6"
|
||||
>
|
||||
Yes
|
||||
</button>
|
||||
<button
|
||||
onClick={handleClose}
|
||||
className="op-btn op-btn-secondary"
|
||||
className="op-btn op-btn-secondary px-6"
|
||||
>
|
||||
No
|
||||
</button>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import "../styles/signature.css";
|
||||
|
||||
function CustomModal({
|
||||
@@ -9,10 +9,11 @@ function CustomModal({
|
||||
declineDoc,
|
||||
setIsDecline
|
||||
}) {
|
||||
const [reason, setReason] = useState("");
|
||||
return (
|
||||
show && (
|
||||
<dialog className="op-modal op-modal-open absolute z-[998]">
|
||||
<div className="w-[80%] md:w-[40%] op-modal-box p-0 overflow-y-auto hide-scrollbar text-sm">
|
||||
<dialog className="op-modal op-modal-open absolute z-[448]">
|
||||
<div className="w-[95%] md:w-[60%] lg:w-[40%] op-modal-box p-0 overflow-y-auto hide-scrollbar text-sm">
|
||||
<h3 className="text-[#de4337] font-bold text-lg pt-[15px] px-[20px]">
|
||||
{headMsg && headMsg}
|
||||
</h3>
|
||||
@@ -21,19 +22,34 @@ function CustomModal({
|
||||
</div>
|
||||
{footerMessage && (
|
||||
<>
|
||||
<div className="h-[1px] bg-[#9f9f9f] w-full"></div>
|
||||
<div className="m-[15px] ">
|
||||
<div className="mx-3">
|
||||
<textarea
|
||||
rows={3}
|
||||
placeholder="Reason (optional)"
|
||||
className="px-4 op-textarea op-textarea-bordered focus:outline-none hover:border-base-content w-full text-xs"
|
||||
value={reason}
|
||||
onChange={(e) => setReason(e.target.value)}
|
||||
></textarea>
|
||||
</div>
|
||||
{/* <div className="h-[1px] bg-[#9f9f9f] w-full"></div> */}
|
||||
<div className="m-[15px]">
|
||||
<button
|
||||
className="op-btn op-btn-primary mr-2"
|
||||
className="op-btn op-btn-primary mr-2 px-6"
|
||||
type="button"
|
||||
onClick={() => declineDoc()}
|
||||
onClick={() => {
|
||||
setReason("");
|
||||
declineDoc(reason);
|
||||
}}
|
||||
>
|
||||
Yes
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="op-btn op-btn-secondary"
|
||||
onClick={() => setIsDecline({ isDeclined: false })}
|
||||
onClick={() => {
|
||||
setReason("");
|
||||
setIsDecline({ isDeclined: false });
|
||||
}}
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
|
||||
@@ -24,7 +24,8 @@ const appId = process.env.REACT_APP_APPID
|
||||
const serverUrl = process.env.REACT_APP_SERVERURL
|
||||
? process.env.REACT_APP_SERVERURL
|
||||
: window.location.origin + "/api/app";
|
||||
|
||||
localStorage.setItem("baseUrl", `${serverUrl}/`);
|
||||
localStorage.setItem("parseAppId", appId);
|
||||
Parse.initialize(appId);
|
||||
Parse.serverURL = serverUrl;
|
||||
// Create a new div element and append it to the body
|
||||
|
||||
@@ -6,63 +6,60 @@ export default async function GetTemplate(request) {
|
||||
const ispublic = request.params.ispublic;
|
||||
|
||||
try {
|
||||
let userId, userRes;
|
||||
if (!ispublic) {
|
||||
userRes = await axios.get(serverUrl + '/users/me', {
|
||||
const userRes = await axios.get(serverUrl + '/users/me', {
|
||||
headers: {
|
||||
'X-Parse-Application-Id': process.env.APP_ID,
|
||||
'X-Parse-Session-Token': request.headers['sessiontoken'],
|
||||
},
|
||||
});
|
||||
userId = userRes.data && userRes.data.objectId;
|
||||
}
|
||||
// console.log("templateId ", templateId)
|
||||
// console.log("userId ",userId)
|
||||
if (templateId && userId) {
|
||||
try {
|
||||
let template = new Parse.Query('contracts_Template');
|
||||
template.equalTo('objectId', templateId);
|
||||
template.include('ExtUserPtr');
|
||||
template.include('Signers');
|
||||
template.include('CreatedBy');
|
||||
const userId = userRes.data && userRes.data.objectId;
|
||||
if (templateId && userId) {
|
||||
try {
|
||||
let template = new Parse.Query('contracts_Template');
|
||||
template.equalTo('objectId', templateId);
|
||||
template.include('ExtUserPtr');
|
||||
template.include('Signers');
|
||||
template.include('CreatedBy');
|
||||
|
||||
const extUserQuery = new Parse.Query('contracts_Users');
|
||||
extUserQuery.equalTo('Email', userRes.data.email);
|
||||
extUserQuery.include('TeamIds');
|
||||
const extUser = await extUserQuery.first({ useMasterKey: true });
|
||||
if (extUser) {
|
||||
const _extUser = JSON.parse(JSON.stringify(extUser));
|
||||
if (_extUser?.TeamIds && _extUser.TeamIds?.length > 0) {
|
||||
let teamsArr = [];
|
||||
_extUser?.TeamIds?.forEach(x => (teamsArr = [...teamsArr, ...x.Ancestors]));
|
||||
// Create the first query
|
||||
const sharedWithQuery = new Parse.Query('contracts_Template');
|
||||
sharedWithQuery.containedIn('SharedWith', teamsArr);
|
||||
const extUserQuery = new Parse.Query('contracts_Users');
|
||||
extUserQuery.equalTo('Email', userRes.data.email);
|
||||
extUserQuery.include('TeamIds');
|
||||
const extUser = await extUserQuery.first({ useMasterKey: true });
|
||||
if (extUser) {
|
||||
const _extUser = JSON.parse(JSON.stringify(extUser));
|
||||
if (_extUser?.TeamIds && _extUser.TeamIds?.length > 0) {
|
||||
let teamsArr = [];
|
||||
_extUser?.TeamIds?.forEach(x => (teamsArr = [...teamsArr, ...x.Ancestors]));
|
||||
// Create the first query
|
||||
const sharedWithQuery = new Parse.Query('contracts_Template');
|
||||
sharedWithQuery.containedIn('SharedWith', teamsArr);
|
||||
|
||||
// Create the second query
|
||||
const createdByQuery = new Parse.Query('contracts_Template');
|
||||
createdByQuery.equalTo('ExtUserPtr', {
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Users',
|
||||
objectId: extUser.id,
|
||||
});
|
||||
template = Parse.Query.or(sharedWithQuery, createdByQuery);
|
||||
template.equalTo('objectId', templateId);
|
||||
template.include('ExtUserPtr');
|
||||
template.include('Signers');
|
||||
template.include('CreatedBy');
|
||||
// Create the second query
|
||||
const createdByQuery = new Parse.Query('contracts_Template');
|
||||
createdByQuery.equalTo('ExtUserPtr', {
|
||||
__type: 'Pointer',
|
||||
className: 'contracts_Users',
|
||||
objectId: extUser.id,
|
||||
});
|
||||
template = Parse.Query.or(sharedWithQuery, createdByQuery);
|
||||
template.equalTo('objectId', templateId);
|
||||
template.include('ExtUserPtr');
|
||||
template.include('Signers');
|
||||
template.include('CreatedBy');
|
||||
}
|
||||
}
|
||||
const res = await template.first({ useMasterKey: true });
|
||||
if (res) {
|
||||
// console.log("res ",res)
|
||||
return res;
|
||||
} else {
|
||||
return { error: "You don't have access of this document!" };
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('err', err);
|
||||
return err;
|
||||
}
|
||||
const res = await template.first({ useMasterKey: true });
|
||||
if (res) {
|
||||
// console.log("res ",res)
|
||||
return res;
|
||||
} else {
|
||||
return { error: "You don't have access of this document!" };
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('err', err);
|
||||
return err;
|
||||
}
|
||||
} else if (templateId && ispublic) {
|
||||
try {
|
||||
|
||||
@@ -92,16 +92,16 @@ const createDocumentFromTemplate = async (template, existContact, index) => {
|
||||
// create new document from template and save contact pointer in placeholder, signers and ACL of Document
|
||||
export default async function PublicUserLinkContactToDoc(req) {
|
||||
const email = req.params.email;
|
||||
const tempid = req.params.tempid;
|
||||
const templateid = req.params.templateid;
|
||||
const name = req.params.name;
|
||||
const phone = req.params.phone;
|
||||
const role = req.params.role;
|
||||
try {
|
||||
if (tempid) {
|
||||
// Execute the query to get the template with the specified 'tempid'
|
||||
if (templateid) {
|
||||
// Execute the query to get the template with the specified 'templateid'
|
||||
const docQuery = new Parse.Query('contracts_Template');
|
||||
docQuery.include('ExtUserPtr');
|
||||
const tempRes = await docQuery.get(tempid, { useMasterKey: true });
|
||||
const tempRes = await docQuery.get(templateid, { useMasterKey: true });
|
||||
// Check if the template was found; if not, throw an error indicating the template was not found
|
||||
if (!tempRes) {
|
||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Template not found.');
|
||||
|
||||
@@ -65,7 +65,7 @@ export default async function SubscriptionAftersave(request) {
|
||||
const extUserRes = await extUserQuery.first({ useMasterKey: true });
|
||||
if (extUserRes) {
|
||||
const extUser = JSON.parse(JSON.stringify(extUserRes));
|
||||
if (extUser?.UserRole !== 'contracts_Admin') {
|
||||
if (!extUser?.OrganizationId) {
|
||||
await addTeamAndOrg(extUser);
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ export default async function SubscriptionAftersave(request) {
|
||||
const extUserRes = await extUserQuery.first({ useMasterKey: true });
|
||||
if (extUserRes) {
|
||||
const extUser = JSON.parse(JSON.stringify(extUserRes));
|
||||
if (extUser?.UserRole !== 'contracts_Admin') {
|
||||
if (!extUser?.OrganizationId) {
|
||||
await addTeamAndOrg(extUser);
|
||||
}
|
||||
}
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
*
|
||||
* @param {Parse} Parse
|
||||
*/
|
||||
exports.up = async Parse => {
|
||||
const className = 'contracts_Document';
|
||||
const schema = new Parse.Schema(className);
|
||||
schema.addString('DeclineReason');
|
||||
return schema.update();
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Parse} Parse
|
||||
*/
|
||||
exports.down = async Parse => {
|
||||
const className = 'contracts_Document';
|
||||
const schema = new Parse.Schema(className);
|
||||
schema.deleteField('DeclineReason');
|
||||
return schema.update();
|
||||
};
|
||||
Reference in New Issue
Block a user