From 2b345ff840aa203b443fa5d51d7b5ef6d3155f67 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs Date: Tue, 12 Dec 2023 17:57:11 +0530 Subject: [PATCH 01/37] add new template form --- .../src/components/AppendFormInForm.js | 1 + apps/OpenSign/src/components/TreeWidget.js | 4 +- .../src/components/fields/CreateFolder.js | 148 +++++++++ .../src/components/fields/FileUpload.js | 20 +- .../src/components/fields/SelectFolder.js | 271 ++++++++++++++++ .../src/components/fields/SignersInput.js | 190 +++++++++++ apps/OpenSign/src/constant/const.js | 2 + apps/OpenSign/src/json/ReportJson.js | 12 +- apps/OpenSign/src/primitives/Alert.js | 30 ++ .../src/primitives/GetReportDisplay.js | 21 +- apps/OpenSign/src/primitives/Modal.js | 28 ++ apps/OpenSign/src/primitives/TemplateForm.js | 304 ++++++++++++++++++ apps/OpenSign/src/routes/Form.js | 23 +- apps/OpenSignServer/cloud/main.js | 10 +- .../cloud/parsefunction/TemplateAfterSave.js | 83 +++++ .../cloud/parsefunction/reportsJson.js | 13 +- .../migrations/20231129103946-update_menu.cjs | 8 + .../20231208132950-create_template_cls.cjs | 40 +++ apps/OpenSignServer/index.js | 4 +- 19 files changed, 1165 insertions(+), 47 deletions(-) create mode 100644 apps/OpenSign/src/components/fields/CreateFolder.js create mode 100644 apps/OpenSign/src/components/fields/SelectFolder.js create mode 100644 apps/OpenSign/src/components/fields/SignersInput.js create mode 100644 apps/OpenSign/src/constant/const.js create mode 100644 apps/OpenSign/src/primitives/Alert.js create mode 100644 apps/OpenSign/src/primitives/Modal.js create mode 100644 apps/OpenSign/src/primitives/TemplateForm.js create mode 100644 apps/OpenSignServer/cloud/parsefunction/TemplateAfterSave.js create mode 100644 apps/OpenSignServer/databases/migrations/20231208132950-create_template_cls.cjs diff --git a/apps/OpenSign/src/components/AppendFormInForm.js b/apps/OpenSign/src/components/AppendFormInForm.js index 22017e423..f5c1d51c2 100644 --- a/apps/OpenSign/src/components/AppendFormInForm.js +++ b/apps/OpenSign/src/components/AppendFormInForm.js @@ -46,6 +46,7 @@ const AppendFormInForm = (props) => { // Define a function to handle form submission const handleSubmit = async (e) => { e.preventDefault(); + e.stopPropagation(); setIsLoader(true); Parse.serverURL = parseBaseUrl; Parse.initialize(parseAppId); diff --git a/apps/OpenSign/src/components/TreeWidget.js b/apps/OpenSign/src/components/TreeWidget.js index ecbce7af4..569112d71 100644 --- a/apps/OpenSign/src/components/TreeWidget.js +++ b/apps/OpenSign/src/components/TreeWidget.js @@ -5,7 +5,7 @@ import Parse from "parse"; import axios from "axios"; import "../styles/spinner.css"; import TreeFormComponent from "./TreeFormComponent"; -import TreeEditForm from "./TreeEditForm"; +// import TreeEditForm from "./TreeEditForm"; import "../styles/modal.css"; import Modal from "react-modal"; @@ -22,7 +22,7 @@ const TreeWidget = (props) => { const [schemaState, setSchemaState] = useState({}); const [TabURL, setTabURL] = useState(""); const [editable, setEditable] = useState(false); - const [editId, setEditId] = useState(""); + // const [editId, setEditId] = useState(""); const [defaultState, setDefaultState] = useState(false); const [isShowModal, setIsShowModal] = useState(false); const selectFolderHandle = async () => { diff --git a/apps/OpenSign/src/components/fields/CreateFolder.js b/apps/OpenSign/src/components/fields/CreateFolder.js new file mode 100644 index 000000000..9b6f4beec --- /dev/null +++ b/apps/OpenSign/src/components/fields/CreateFolder.js @@ -0,0 +1,148 @@ +import React, { useEffect, useState } from "react"; +import Parse from "parse"; +import { templateCls } from "../../constant/const"; +import Alert from "../../primitives/Alert"; + +const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => { + const folderPtr = { + __type: "Pointer", + className: folderCls, + objectId: parentFolderId + }; + const [name, setName] = useState(""); + const [folderList, setFolderList] = useState([]); + const [isAlert, setIsAlert] = useState(false); + const [selectedParent, setSelectedParent] = useState(); + const [alert, setAlert] = useState({ type: "info", message: "" }); + useEffect(() => { + fetchFolder(); + // eslint-disable-next-line + }, []); + + const fetchFolder = async () => { + try { + const fetchFolder = new Parse.Query(folderCls); + if (parentFolderId) { + fetchFolder.equalTo("Folder", folderPtr); + fetchFolder.equalTo("Type", "Folder"); + } else { + fetchFolder.doesNotExist("Folder"); + fetchFolder.equalTo("Type", "Folder"); + } + + const res = await fetchFolder.find(); + if (res) { + const result = JSON.parse(JSON.stringify(res)); + if (result) { + setFolderList(result); + } + } + } catch (error) { + console.log("Err ", error); + } + }; + const handleCreateFolder = async (event) => { + event.preventDefault(); + if (name) { + const currentUser = Parse.User.current(); + const exsitQuery = new Parse.Query(templateCls); + exsitQuery.equalTo("Name", name); + exsitQuery.equalTo("Type", "Folder"); + if (parentFolderId) { + exsitQuery.equalTo("Folder", folderPtr); + } + const templExist = await exsitQuery.first(); + if (templExist) { + setAlert({ type: "dange", message: "Folder already exist!" }); + setIsAlert(true); + setTimeout(() => { + setIsAlert(false); + }, 1000); + } else { + const template = new Parse.Object(templateCls); + template.set("Name", name); + template.set("Type", "Folder"); + + if (selectedParent) { + template.set("Folder", { + __type: "Pointer", + className: folderCls, + objectId: selectedParent + }); + } else if (parentFolderId) { + template.set("Folder", folderPtr); + } + template.set("CreatedBy", Parse.User.createWithoutData(currentUser.id)); + const res = await template.save(); + if (res) { + if (onSuccess) { + setAlert({ + type: "success", + message: "Folder created successfully!" + }); + setIsAlert(true); + setTimeout(() => { + setIsAlert(false); + }, 1000); + onSuccess(res); + } + } + } + } else { + setAlert({ type: "info", message: "Please fill folder name" }); + setIsAlert(true); + setTimeout(() => { + setIsAlert(false); + }, 1000); + } + }; + const handleOptions = (e) => { + setSelectedParent(e.target.value); + }; + return ( +
+ {isAlert && {alert.message}} +
+

Create Folder

+
+ + setName(e.target.value)} + required + /> +
+
+ + +
+
+ +
+
+
+ ); +}; + +export default CreateFolder; diff --git a/apps/OpenSign/src/components/fields/FileUpload.js b/apps/OpenSign/src/components/fields/FileUpload.js index 09a11e8d2..66eca92b0 100644 --- a/apps/OpenSign/src/components/fields/FileUpload.js +++ b/apps/OpenSign/src/components/fields/FileUpload.js @@ -271,10 +271,12 @@ const FileUpload = (props) => { - + {process.env.DROPBOX_APP_KEY && ( + + )} ) : (
@@ -294,10 +296,12 @@ const FileUpload = (props) => { accept="application/pdf,application/vnd.ms-excel" onChange={onChange} /> - + {process.env.DROPBOX_APP_KEY && ( + + )}
)} diff --git a/apps/OpenSign/src/components/fields/SelectFolder.js b/apps/OpenSign/src/components/fields/SelectFolder.js new file mode 100644 index 000000000..434bbed7d --- /dev/null +++ b/apps/OpenSign/src/components/fields/SelectFolder.js @@ -0,0 +1,271 @@ +import React, { useEffect, useState } from "react"; +import Parse from "parse"; +import CreateFolder from "./CreateFolder"; +import { templateCls } from "../../constant/const"; + +const SelectFolder = ({ required, onSuccess }) => { + const [isOpen, SetIsOpen] = useState(false); + const [clickFolder, setClickFolder] = useState(""); + const [selectFolder, setSelectedFolder] = useState({}); + const [folderList, setFolderList] = useState([]); + const [tabList, setTabList] = useState([]); + const [isLoader, setIsLoader] = useState(false); + const [folderPath, setFolderPath] = useState(""); + const [isAdd, setIsAdd] = useState(false); + useEffect(() => { + if (isOpen) { + setIsAdd(false); + setClickFolder({}); + setFolderList([]); + setTabList([]); + fetchFolder(); + } + }, [isOpen]); + const fetchFolder = async (folderPtr) => { + setIsLoader(true); + try { + const fetchFolder = new Parse.Query(templateCls); + if (folderPtr) { + fetchFolder.equalTo("Folder", folderPtr); + fetchFolder.equalTo("Type", "Folder"); + } else { + fetchFolder.doesNotExist("Folder"); + fetchFolder.equalTo("Type", "Folder"); + } + + const res = await fetchFolder.find(); + if (res) { + const result = JSON.parse(JSON.stringify(res)); + if (result) { + setFolderList(result); + setIsLoader(false); + } + setIsLoader(false); + } + } catch (error) { + setIsLoader(false); + } + }; + const handleSelect = (item) => { + setFolderList([]); + setClickFolder({ ObjectId: item.objectId, Name: item.Name }); + if (tabList.length > 0) { + const tab = tabList.some((x) => x.objectId === item.objectId); + if (!tab) { + setTabList((tabs) => [...tabs, item]); + const folderPtr = { + __type: "Pointer", + className: templateCls, + objectId: item.objectId + }; + fetchFolder(folderPtr); + } + } else { + setTabList((tabs) => [...tabs, item]); + const folderPtr = { + __type: "Pointer", + className: templateCls, + objectId: item.objectId + }; + + fetchFolder(folderPtr); + } + }; + + const handleSubmit = () => { + let url = "Root"; + tabList.forEach((t) => { + url = url + " / " + t.Name; + }); + setFolderPath(url); + setSelectedFolder(clickFolder); + if (onSuccess) { + onSuccess(clickFolder); + } + SetIsOpen(false); + }; + const handleCancel = () => { + SetIsOpen(false); + setClickFolder({}); + setFolderList([]); + setTabList([]); + }; + + const removeTabListItem = async (e, i) => { + e.preventDefault(); + // setEditable(false); + if (!isAdd) { + setIsLoader(true); + let folderPtr; + if (i) { + setFolderList([]); + let list = tabList.filter((itm, j) => { + if (j <= i) { + return itm; + } + }); + let _len = list.length - 1; + folderPtr = { + __type: "Pointer", + className: templateCls, + objectId: list[_len].objectId + }; + setTabList(list); + } else { + setClickFolder({}); + setSelectedFolder({}); + setFolderList([]); + setTabList([]); + } + fetchFolder(folderPtr); + } + }; + const handleCreate = () => { + setIsAdd(!isAdd); + }; + const handleAddFolder = () => { + setFolderList([]); + if (clickFolder && clickFolder.ObjectId) { + fetchFolder({ + __type: "Pointer", + className: templateCls, + objectId: clickFolder.ObjectId + }); + } else { + fetchFolder(); + } + }; + return ( +
+
+ +
+
+
+ +
+
+
+

+ {selectFolder && selectFolder.Name ? selectFolder.Name : "Root"} +

+
SetIsOpen(true)}> + +
+
+

+ {selectFolder && selectFolder.Name ? `(${folderPath})` : ""} +

+
+
+ {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 ? ( + + ) : ( + + )} +
+
+ +
+
+
+ )} +
+ ); +}; + +export default SelectFolder; diff --git a/apps/OpenSign/src/components/fields/SignersInput.js b/apps/OpenSign/src/components/fields/SignersInput.js new file mode 100644 index 000000000..0e9697965 --- /dev/null +++ b/apps/OpenSign/src/components/fields/SignersInput.js @@ -0,0 +1,190 @@ +import React, { useState, useEffect } from "react"; +import Select from "react-select"; +import AppendFormInForm from "../AppendFormInForm"; +import Modal from "react-modal"; +import Parse from "parse"; +function arrayMove(array, from, to) { + array = array.slice(); + array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]); + return array; +} + +/** + * react-sortable-hoc is depcreated not usable from react 18.x.x + * need to replace it with @dnd-kit + * code changes required + */ + +const SignersInput = (props) => { + Modal.setAppElement("body"); + const [state, setState] = useState(undefined); + // const [editFormData, setEditFormData] = useState([]); + const [selected, setSelected] = React.useState([]); + const [isModal, setIsModel] = useState(false); + const onChange = (selectedOptions) => setSelected(selectedOptions); + const [modalIsOpen, setModalIsOpen] = useState(false); + + const onSortEnd = ({ oldIndex, newIndex }) => { + const newValue = arrayMove(selected, oldIndex, newIndex); + setSelected(newValue); + }; + + const GetSelectListData = async () => { + try { + const currentUser = Parse.User.current(); + const contactbook = new Parse.Query("contracts_Contactbook"); + contactbook.equalTo( + "CreatedBy", + Parse.User.createWithoutData(currentUser.id) + ); + contactbook.notEqualTo("IsDeleted", true); + const contactRes = await contactbook.find(); + if (contactRes) { + const res = JSON.parse(JSON.stringify(contactRes)); + let list = []; + + // let _selected = []; + res.forEach((x) => { + let obj = { + label: x.Name, + value: x.objectId, + isChecked: true + }; + + list.push(obj); + }); + setState(list); + } + } catch (error) { + console.log("err", error); + } + }; + + useEffect(() => { + GetSelectListData(); + }, []); + + useEffect(() => { + if (selected && selected.length) { + let newData = []; + selected.forEach((x) => { + newData.push(x.value); + }); + if (props.onChange) { + props.onChange(newData); + } + } + + // eslint-disable-next-line + }, [selected]); + + const handleModalCloseClick = () => { + setIsModel(false); + setModalIsOpen(false); + }; + + const openModal = () => { + setModalIsOpen(true); + }; + + // `handleNewDetails` is used to set just save from quick form to selected option in dropdown + const handleNewDetails = (data) => { + setState([...state, data]); + if (selected.length > 0) { + setSelected([...selected, data]); + } else { + setSelected([data]); + } + }; + + return ( +
+ +
+
+ handleFileInput(e)} + accept="application/pdf,application/vnd.ms-excel" + required + /> + {process.env.DROPBOX_APP_KEY && ( + + )} +
+ )} +
+
+ + handleStrInput(e)} + required + /> +
+
+ + handleStrInput(e)} + /> +
+
+ + handleStrInput(e)} + /> +
+ + +
+ +
handleReset()} + > + Reset +
+
+ +
+ ); +}; + +export default TemplateForm; diff --git a/apps/OpenSign/src/routes/Form.js b/apps/OpenSign/src/routes/Form.js index fd5c67449..2c6c67709 100644 --- a/apps/OpenSign/src/routes/Form.js +++ b/apps/OpenSign/src/routes/Form.js @@ -25,6 +25,7 @@ import TreeWidget from "../components/TreeWidget"; import parse from "html-react-parser"; import Title from "../components/Title"; import { formJson } from "../json/FormJson"; +import TemplateForm from "../primitives/TemplateForm"; const widget = { TimeWidget: TimeWidget }; @@ -41,15 +42,19 @@ const fields = () => { function FormBuilderFn(props) { const { id } = useParams(); const navigate = useNavigate(); - return ( - - ); + if (id === "template") { + return ; + } else { + return ( + + ); + } } class FormBuilder extends Component { state = { diff --git a/apps/OpenSignServer/cloud/main.js b/apps/OpenSignServer/cloud/main.js index e42ee38e5..ee8cac810 100644 --- a/apps/OpenSignServer/cloud/main.js +++ b/apps/OpenSignServer/cloud/main.js @@ -17,6 +17,7 @@ import getUserDetails from './parsefunction/getUserDetails.js'; import getDocument from './parsefunction/getDocument.js'; import getDrive from './parsefunction/getDrive.js'; import getReport from './parsefunction/getReport.js'; +import TemplateAfterSave from './parsefunction/TemplateAfterSave.js'; Parse.Cloud.define('AddUserToRole', addUserToGroups); Parse.Cloud.define('UserGroups', getUserGroups); @@ -26,9 +27,6 @@ Parse.Cloud.define('googlesign', GoogleSign); Parse.Cloud.define('zohodetails', ZohoDetails); Parse.Cloud.define('usersignup', usersignup); Parse.Cloud.define('facebooksign', FacebookSign); -Parse.Cloud.afterSave('contracts_Document', DocumentAftersave); -Parse.Cloud.afterSave('contracts_Contactbook', ContactbookAftersave); -Parse.Cloud.afterSave('contracts_Users', ContractUsersAftersave); Parse.Cloud.define('SendOTPMailV1', sendMailOTPv1); Parse.Cloud.define('sendmail', SendMailv1); Parse.Cloud.define('AuthLoginAsMail', AuthLoginAsMail); @@ -36,4 +34,8 @@ Parse.Cloud.define('getUserId', getUserId); Parse.Cloud.define('getUserDetails', getUserDetails); Parse.Cloud.define('getDocument', getDocument); Parse.Cloud.define('getDrive', getDrive) -Parse.Cloud.define('getReport', getReport) \ No newline at end of file +Parse.Cloud.define('getReport', getReport) +Parse.Cloud.afterSave('contracts_Document', DocumentAftersave); +Parse.Cloud.afterSave('contracts_Contactbook', ContactbookAftersave); +Parse.Cloud.afterSave('contracts_Users', ContractUsersAftersave); +Parse.Cloud.afterSave("contracts_Template", TemplateAfterSave) \ No newline at end of file diff --git a/apps/OpenSignServer/cloud/parsefunction/TemplateAfterSave.js b/apps/OpenSignServer/cloud/parsefunction/TemplateAfterSave.js new file mode 100644 index 000000000..7d22ccb86 --- /dev/null +++ b/apps/OpenSignServer/cloud/parsefunction/TemplateAfterSave.js @@ -0,0 +1,83 @@ +export default async function TemplateAfterSave(request) { + try { + if (!request.original) { + console.log('new entry is insert in contracts_Template'); + // update acl of New Document If There are signers present in array + const signers = request.object.get('Signers'); + + if (signers && signers.length > 0) { + await updateAclDoc(request.object.id); + } else { + await updateSelfDoc(request.object.id); + } + } else { + if (request.user) { + const signers = request.object.get('Signers'); + if (signers && signers.length > 0) { + await updateAclDoc(request.object.id); + } else { + await updateSelfDoc(request.object.id); + } + } + } + } catch (err) { + console.log('err in aftersave of contracts_Template'); + console.log(err); + } + + async function updateAclDoc(objId) { + // console.log("In side updateAclDoc func") + // console.log(objId) + const Query = new Parse.Query('contracts_Template'); + Query.include('Signers'); + const updateACL = await Query.get(objId, { useMasterKey: true }); + const res = JSON.parse(JSON.stringify(updateACL)); + // console.log("res"); + // console.log(JSON.stringify(res)); + const UsersPtr = res.Signers.map(item => item.UserId); + + if (res.Signers[0].ExtUserPtr) { + const ExtUserSigners = res.Signers.map(item => { + return { + __type: 'Pointer', + className: 'contracts_Users', + objectId: item.ExtUserPtr.objectId, + }; + }); + updateACL.set('Signers', ExtUserSigners); + } + + // console.log("UsersPtr") + // console.log(JSON.stringify(UsersPtr)) + const newACL = new Parse.ACL(); + newACL.setPublicReadAccess(false); + newACL.setPublicWriteAccess(false); + newACL.setReadAccess(request.user, true); + newACL.setWriteAccess(request.user, true); + + UsersPtr.forEach(x => { + newACL.setReadAccess(x.objectId, true); + newACL.setWriteAccess(x.objectId, true); + }); + + updateACL.setACL(newACL); + updateACL.save(null, { useMasterKey: true }); + } + + async function updateSelfDoc(objId) { + // console.log("Inside updateSelfDoc func") + + const Query = new Parse.Query('contracts_Template'); + const updateACL = await Query.get(objId, { useMasterKey: true }); + // const res = JSON.parse(JSON.stringify(updateACL)); + // console.log("res"); + // console.log(JSON.stringify(res)); + const newACL = new Parse.ACL(); + newACL.setPublicReadAccess(false); + newACL.setPublicWriteAccess(false); + newACL.setReadAccess(request.user, true); + newACL.setWriteAccess(request.user, true); + updateACL.setACL(newACL); + updateACL.save(null, { useMasterKey: true }); + } +} diff --git a/apps/OpenSignServer/cloud/parsefunction/reportsJson.js b/apps/OpenSignServer/cloud/parsefunction/reportsJson.js index 8ad9c47df..66d743a6a 100644 --- a/apps/OpenSignServer/cloud/parsefunction/reportsJson.js +++ b/apps/OpenSignServer/cloud/parsefunction/reportsJson.js @@ -154,7 +154,7 @@ export default function reportJson(id, userId) { $gt: { __type: 'Date', iso: new Date().toISOString() }, }, }, - keys: ['Name', 'Note', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'], + keys: ['Name', 'Folder.Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name'], }; // Recent signature requests report show on dashboard case '5Go51Q7T8r': @@ -169,16 +169,7 @@ export default function reportJson(id, userId) { }, Placeholders: { $ne: null }, }, - keys: [ - 'Name', - 'Note', - 'Folder.Name', - 'URL', - 'ExtUserPtr.Name', - 'Signers.Name', - 'Signers.UserId', - 'AuditTrail', - ], + keys: ['Name', 'URL', 'ExtUserPtr.Name', 'Signers.Name', 'Signers.UserId', 'AuditTrail'], }; // Drafts report show on dashboard case 'kC5mfynCi4': diff --git a/apps/OpenSignServer/databases/migrations/20231129103946-update_menu.cjs b/apps/OpenSignServer/databases/migrations/20231129103946-update_menu.cjs index 9581be3a8..c897aefac 100644 --- a/apps/OpenSignServer/databases/migrations/20231129103946-update_menu.cjs +++ b/apps/OpenSignServer/databases/migrations/20231129103946-update_menu.cjs @@ -39,6 +39,14 @@ exports.up = async Parse => { description: '', objectId: '8mZzFxbG1z', }, + { + icon: 'fas fa-file-signature', + title: 'New template', + target: '_self', + pageType: 'form', + description: '', + objectId: 'template', + }, ], }, { diff --git a/apps/OpenSignServer/databases/migrations/20231208132950-create_template_cls.cjs b/apps/OpenSignServer/databases/migrations/20231208132950-create_template_cls.cjs new file mode 100644 index 000000000..47fe71b87 --- /dev/null +++ b/apps/OpenSignServer/databases/migrations/20231208132950-create_template_cls.cjs @@ -0,0 +1,40 @@ +/** + * + * @param {Parse} Parse + */ +exports.up = async Parse => { + const className = 'contracts_Template'; + const schema = new Parse.Schema(className); + + schema.addString('Name'); + schema.addString('URL'); + schema.addString('Note'); + schema.addString('Description'); + schema.addArray('Signers'); + schema.addBoolean('IsArchive'); + schema.addArray('Placeholders'); + schema.addPointer('Folder', 'contracts_Template'); + schema.addString('Type'); + schema.addPointer('CreatedBy', '_User'); + schema.addPointer('ExtUserPtr', 'contracts_Users'); + schema.addBoolean('EnablePhoneOTP') + schema.addBoolean('EnableEmailOTP') + schema.addBoolean('SendinOrder') + schema.addBoolean('SentToOthers') + schema.addBoolean('AutomaticReminders') + + + + return schema.save(); +}; + +/** + * + * @param {Parse} Parse + */ +exports.down = async Parse => { + const className = 'contracts_Template'; + const schema = new Parse.Schema(className); + + return schema.purge().then(() => schema.delete()); +}; diff --git a/apps/OpenSignServer/index.js b/apps/OpenSignServer/index.js index 819940954..d8944d8d3 100644 --- a/apps/OpenSignServer/index.js +++ b/apps/OpenSignServer/index.js @@ -69,7 +69,9 @@ if (process.env.SMTP_ENABLE) { export const config = { databaseURI: process.env.DATABASE_URI || process.env.MONGODB_URI || 'mongodb://localhost:27017/dev', - cloud: process.env.CLOUD || __dirname + '/cloud/main.js', + cloud: function () { + import('./cloud/main.js'); + }, appId: process.env.APP_ID || 'myAppId', masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret! masterKeyIps: ['0.0.0.0/0', '::1'], // '::1' From c4507dd06bf40cf8abaec6d8cbf045138ca7c178 Mon Sep 17 00:00:00 2001 From: jeremyito07 Date: Fri, 15 Dec 2023 18:35:18 +0530 Subject: [PATCH 02/37] fix: removed "/test" route from application --- apps/OpenSignServer/index.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/OpenSignServer/index.js b/apps/OpenSignServer/index.js index 819940954..8d515416b 100644 --- a/apps/OpenSignServer/index.js +++ b/apps/OpenSignServer/index.js @@ -172,9 +172,6 @@ app.get('/', function (req, res) { // There will be a test page available on the /test path of your server url // Remove this before launching your app -app.get('/test', function (req, res) { - res.sendFile(path.join(__dirname, '/public/test.html')); -}); if (!process.env.TESTING) { const port = process.env.PORT || 8080; From 3e741ac2f91f771d5b54e5e305c01c13f439c4c5 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs Date: Fri, 15 Dec 2023 19:01:05 +0530 Subject: [PATCH 03/37] add functionality of add placholder in template --- .../src/components/fields/CreateFolder.js | 5 +- .../src/components/fields/SelectFolder.js | 15 +- apps/OpenSign/src/constant/const.js | 4 +- apps/OpenSign/src/json/ReportJson.js | 14 + apps/OpenSign/src/primitives/TemplateForm.js | 18 +- .../src/Component/TemplatePlaceholder.js | 1146 +++++++++++++++++ .../Component/component/fieldsComponent.js | 82 +- .../src/Component/component/header.js | 8 +- .../Component/component/renderAllPdfPage.js | 132 +- .../src/Component/component/renderPdf.js | 34 +- .../Component/component/signerListPlace.js | 168 ++- microfrontends/SignDocuments/src/Routes.js | 2 + .../SignDocuments/src/css/signerListPlace.css | 16 + .../SignDocuments/src/utils/Utils.js | 2 + 14 files changed, 1442 insertions(+), 204 deletions(-) create mode 100644 microfrontends/SignDocuments/src/Component/TemplatePlaceholder.js create mode 100644 microfrontends/SignDocuments/src/css/signerListPlace.css diff --git a/apps/OpenSign/src/components/fields/CreateFolder.js b/apps/OpenSign/src/components/fields/CreateFolder.js index 9b6f4beec..2aa0c2432 100644 --- a/apps/OpenSign/src/components/fields/CreateFolder.js +++ b/apps/OpenSign/src/components/fields/CreateFolder.js @@ -1,6 +1,5 @@ import React, { useEffect, useState } from "react"; import Parse from "parse"; -import { templateCls } from "../../constant/const"; import Alert from "../../primitives/Alert"; const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => { @@ -45,7 +44,7 @@ const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => { event.preventDefault(); if (name) { const currentUser = Parse.User.current(); - const exsitQuery = new Parse.Query(templateCls); + const exsitQuery = new Parse.Query(folderCls); exsitQuery.equalTo("Name", name); exsitQuery.equalTo("Type", "Folder"); if (parentFolderId) { @@ -59,7 +58,7 @@ const CreateFolder = ({ parentFolderId, onSuccess, folderCls }) => { setIsAlert(false); }, 1000); } else { - const template = new Parse.Object(templateCls); + const template = new Parse.Object(folderCls); template.set("Name", name); template.set("Type", "Folder"); diff --git a/apps/OpenSign/src/components/fields/SelectFolder.js b/apps/OpenSign/src/components/fields/SelectFolder.js index 434bbed7d..878bb269b 100644 --- a/apps/OpenSign/src/components/fields/SelectFolder.js +++ b/apps/OpenSign/src/components/fields/SelectFolder.js @@ -1,9 +1,8 @@ import React, { useEffect, useState } from "react"; import Parse from "parse"; import CreateFolder from "./CreateFolder"; -import { templateCls } from "../../constant/const"; -const SelectFolder = ({ required, onSuccess }) => { +const SelectFolder = ({ required, onSuccess, folderCls }) => { const [isOpen, SetIsOpen] = useState(false); const [clickFolder, setClickFolder] = useState(""); const [selectFolder, setSelectedFolder] = useState({}); @@ -24,7 +23,7 @@ const SelectFolder = ({ required, onSuccess }) => { const fetchFolder = async (folderPtr) => { setIsLoader(true); try { - const fetchFolder = new Parse.Query(templateCls); + const fetchFolder = new Parse.Query(folderCls); if (folderPtr) { fetchFolder.equalTo("Folder", folderPtr); fetchFolder.equalTo("Type", "Folder"); @@ -55,7 +54,7 @@ const SelectFolder = ({ required, onSuccess }) => { setTabList((tabs) => [...tabs, item]); const folderPtr = { __type: "Pointer", - className: templateCls, + className: folderCls, objectId: item.objectId }; fetchFolder(folderPtr); @@ -64,7 +63,7 @@ const SelectFolder = ({ required, onSuccess }) => { setTabList((tabs) => [...tabs, item]); const folderPtr = { __type: "Pointer", - className: templateCls, + className: folderCls, objectId: item.objectId }; @@ -107,7 +106,7 @@ const SelectFolder = ({ required, onSuccess }) => { let _len = list.length - 1; folderPtr = { __type: "Pointer", - className: templateCls, + className: folderCls, objectId: list[_len].objectId }; setTabList(list); @@ -128,7 +127,7 @@ const SelectFolder = ({ required, onSuccess }) => { if (clickFolder && clickFolder.ObjectId) { fetchFolder({ __type: "Pointer", - className: templateCls, + className: folderCls, objectId: clickFolder.ObjectId }); } else { @@ -230,7 +229,7 @@ const SelectFolder = ({ required, onSuccess }) => { {isAdd && ( )} diff --git a/apps/OpenSign/src/constant/const.js b/apps/OpenSign/src/constant/const.js index 2e5e40948..4f2ea585b 100644 --- a/apps/OpenSign/src/constant/const.js +++ b/apps/OpenSign/src/constant/const.js @@ -1,2 +1,2 @@ -export const contactCls = "contracts_Contactbook" -export const templateCls = "contracts_Template" +export const contactCls = "contracts_Contactbook"; +export const templateCls = "contracts_Template"; diff --git a/apps/OpenSign/src/json/ReportJson.js b/apps/OpenSign/src/json/ReportJson.js index b538cd34f..d3d6148ba 100644 --- a/apps/OpenSign/src/json/ReportJson.js +++ b/apps/OpenSign/src/json/ReportJson.js @@ -163,6 +163,20 @@ export default function reportJson(id) { } ] }; + // template report + case "23jk45slhj": + return { + reportName: "Templates", + heading: contactbook, + actions: [ + { + btnLabel: "", + btnColor: "#f55a42", + textColor: "white", + btnIcon: "fa-solid fa-trash" + } + ] + }; default: return null; } diff --git a/apps/OpenSign/src/primitives/TemplateForm.js b/apps/OpenSign/src/primitives/TemplateForm.js index 66c431bbb..fe433af24 100644 --- a/apps/OpenSign/src/primitives/TemplateForm.js +++ b/apps/OpenSign/src/primitives/TemplateForm.js @@ -6,7 +6,11 @@ import Alert from "./Alert"; import SelectFolder from "../components/fields/SelectFolder"; import SignersInput from "../components/fields/SignersInput"; import Title from "../components/Title"; +import { useNavigate } from "react-router-dom"; +import { templateCls } from '../constant/const' + const TemplateForm = () => { + const navigate = useNavigate() const [signers, setSigners] = useState([]); const [folder, setFolder] = useState({ ObjectId: "", Name: "" }); const [formData, setFormData] = useState({ @@ -126,7 +130,7 @@ const TemplateForm = () => { e.preventDefault(); try { const currentUser = Parse.User.current(); - const template = new Parse.Object("contracts_Template"); + const template = new Parse.Object(templateCls); Object.entries(formData).forEach((item) => template.set(item[0], item[1]) ); @@ -135,13 +139,20 @@ const TemplateForm = () => { if (folder && folder.ObjectId) { template.set("Folder", { __type: "Pointer", - className: "contracts_Template", + className: templateCls, objectId: folder.ObjectId }); } if (signers && signers.length > 0) { template.set("Signers", signers); } + const ExtCls = JSON.parse(localStorage.getItem("Extand_Class")); + template.set("ExtUserPtr", { + __type: "Pointer", + className: "contracts_Users", + objectId: ExtCls[0].objectId + }); + const res = await template.save(); if (res) { setIsAlert(true); @@ -157,6 +168,7 @@ const TemplateForm = () => { }); setFileUpload([]); setpercentage(0); + navigate('/asmf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/template/' +res.id) } } catch (err) { console.log("err ", err); @@ -281,7 +293,7 @@ const TemplateForm = () => { /> - +
+ + + {/* this modal is used show send mail message and after send mail success message */} + + {/* signature modal */} + +

Do you want to create document right now ?

+
+ + {currentEmail.length > 0 && ( + <> + + + + + )} + +
+ + {/* pdf header which contain funish back button */} +
+
+ {containerWH && ( + + )} +
+
+ + {/* signature button */} + {isMobile ? ( +
+ +
+ ) : ( +
+
+ +
+ +
+
+
+ )} + + )} + +
+ + + Add Role + + +
+ setRoleName(e.target.value)} + style={{ borderRadiu: 20 }} + placeholder={ + signersdata.length > 0 + ? "User " + (signersdata.length + 1) + : "User 1" + } + /> +
+
+ + +
+
+
+
+
+ + ); +}; + +export default TemplatePlaceholder; diff --git a/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js b/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js index 71280710f..916e29005 100644 --- a/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js +++ b/microfrontends/SignDocuments/src/Component/component/fieldsComponent.js @@ -32,12 +32,12 @@ function FieldsComponent({ setIsShowEmail, isMailSend, selectedEmail, - setSelectedEmail, + setSelectedEmail }) { const signStyle = pdfUrl ? "disableSign" : "signatureBtn"; - const isMobile = window.innerWidth <767; - + const isMobile = window.innerWidth < 767; + const SelectItem = React.forwardRef( ({ children, className, ...props }, forwardedRef) => { return ( @@ -65,7 +65,7 @@ function FieldsComponent({ "#cc99ff", "#ffcc99", "#66ccff", - "#ffffcc", + "#ffffcc" ]; return ( @@ -88,7 +88,7 @@ function FieldsComponent({ padding: "10px 20px", display: "flex", alignItems: "center", - justifyContent: "center", + justifyContent: "center" }} > @@ -107,30 +107,29 @@ function FieldsComponent({ }} > - - {!selectedEmail && - - - } + + {!selectedEmail && ( + + + + )}