mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-21 07:02:32 +02:00
feat: add share with functionality of template
This commit is contained in:
@@ -346,6 +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: "2434",
|
||||
btnLabel: "Edit",
|
||||
|
||||
@@ -24,6 +24,7 @@ import ReactQuill from "react-quill";
|
||||
import "react-quill/dist/quill.snow.css";
|
||||
import BulkSendUi from "../components/BulkSendUi";
|
||||
import Loader from "./Loader";
|
||||
import Select from "react-select";
|
||||
|
||||
const ReportTable = (props) => {
|
||||
const navigate = useNavigate();
|
||||
@@ -52,6 +53,10 @@ const ReportTable = (props) => {
|
||||
const [templateDeatils, setTemplateDetails] = useState({});
|
||||
const [placeholders, setPlaceholders] = useState([]);
|
||||
const [isLoader, setIsLoader] = useState({});
|
||||
const [isShareWith, setIsShareWith] = useState({});
|
||||
const [departmentList, setDepartmentList] = useState([]);
|
||||
const [selectedDepartments, setSelectedDepartments] = useState([]);
|
||||
const onChange = (selectedOptions) => setSelectedDepartments(selectedOptions);
|
||||
// const [selectedPublicRole, setSelectedPublicRole] = useState("");
|
||||
// const [isCelebration, setIsCelebration] = useState(false);
|
||||
// const [currentLists, setCurrentLists] = useState([]);
|
||||
@@ -125,9 +130,37 @@ const ReportTable = (props) => {
|
||||
// below useEffect reset currenpage to 1 if user change route
|
||||
useEffect(() => {
|
||||
checkTourStatus();
|
||||
fetchDepartmentList();
|
||||
return () => setCurrentPage(1);
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
// `fetchDepartmentList` is used to fetch department list for share with functionality
|
||||
const fetchDepartmentList = async () => {
|
||||
if (props.ReportName === "Templates") {
|
||||
try {
|
||||
const extUser = JSON.parse(localStorage.getItem("Extand_Class"))?.[0];
|
||||
const department = new Parse.Query("contracts_Departments");
|
||||
department.equalTo("OrganizationId", {
|
||||
__type: "Pointer",
|
||||
className: "contracts_Organizations",
|
||||
objectId: extUser.OrganizationId.objectId
|
||||
});
|
||||
department.equalTo("IsActive", true);
|
||||
const departmentRes = await department.find();
|
||||
if (departmentRes.length > 0) {
|
||||
const _departmentRes = JSON.parse(JSON.stringify(departmentRes));
|
||||
const formatedList = _departmentRes.map((x) => ({
|
||||
label: x.Name,
|
||||
value: x.objectId
|
||||
}));
|
||||
setDepartmentList(formatedList);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log("Err in fetch top level departmentlist", err);
|
||||
}
|
||||
}
|
||||
};
|
||||
// `formatRow` is used to show data in poper manner like
|
||||
// if data is of array type then it will join array items with ","
|
||||
// if data is of object type then it Name values will be show in row
|
||||
@@ -297,6 +330,16 @@ const ReportTable = (props) => {
|
||||
setIsResendMail({ [item.objectId]: true });
|
||||
} else if (act.action === "bulksend") {
|
||||
handleBulkSend(item);
|
||||
} else if (act.action === "sharewith") {
|
||||
if (item?.SharedWith && item?.SharedWith.length > 0) {
|
||||
// below code is used to get existing sharewith departments and formated them as per react-select
|
||||
const formatedList = item?.SharedWith.map((x) => ({
|
||||
label: x.Name,
|
||||
value: x.objectId
|
||||
}));
|
||||
setSelectedDepartments(formatedList);
|
||||
}
|
||||
setIsShareWith({ [item.objectId]: true });
|
||||
}
|
||||
};
|
||||
// Get current list
|
||||
@@ -915,6 +958,41 @@ const ReportTable = (props) => {
|
||||
// setTimeout(() => setIsAlert(false), 1500);
|
||||
// };
|
||||
|
||||
// `handleShareWith` is used to save departments in sharedWith field
|
||||
const handleShareWith = async (e, template) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setIsShareWith({});
|
||||
setActLoader({ [template.objectId]: true });
|
||||
try {
|
||||
const templateCls = new Parse.Object("contracts_Template");
|
||||
templateCls.id = template.objectId;
|
||||
const departmentArr = selectedDepartments.map((x) => ({
|
||||
__type: "Pointer",
|
||||
className: "contracts_Departments",
|
||||
objectId: x.value
|
||||
}));
|
||||
templateCls.set("SharedWith", departmentArr);
|
||||
const res = await templateCls.save();
|
||||
if (res) {
|
||||
setIsAlert(true);
|
||||
setAlertMsg({
|
||||
type: "success",
|
||||
message: "Template Shared successfully."
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
setIsAlert(true);
|
||||
setAlertMsg({
|
||||
type: "danger",
|
||||
message: "Something went wrong, Please try again later."
|
||||
});
|
||||
} finally {
|
||||
setActLoader({});
|
||||
setTimeout(() => setIsAlert(false), 1500);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
{Object.keys(actLoader)?.length > 0 && (
|
||||
@@ -1276,7 +1354,7 @@ const ReportTable = (props) => {
|
||||
)}
|
||||
{isOption[item.objectId] &&
|
||||
act.action === "option" && (
|
||||
<ul className="absolute -right-2 top-6 z-[20] op-dropdown-content op-menu shadow bg-base-100 text-base-content rounded-box ">
|
||||
<ul className="absolute -right-2 top-6 z-[20] op-dropdown-content op-menu shadow bg-base-100 text-base-content rounded-box">
|
||||
{act.subaction?.map((subact) => (
|
||||
<li
|
||||
key={subact.btnId}
|
||||
@@ -1302,6 +1380,60 @@ const ReportTable = (props) => {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{isShareWith[item.objectId] && (
|
||||
<div className="op-modal op-modal-open">
|
||||
<div className="max-h-90 bg-base-100 w-[95%] md:max-w-[500px] rounded-box relative">
|
||||
<h3 className="text-base-content font-bold text-lg pt-[15px] px-[20px]">
|
||||
Share with
|
||||
</h3>
|
||||
<div
|
||||
className="op-btn op-btn-sm op-btn-circle op-btn-ghost text-base-content absolute right-2 top-2 z-40"
|
||||
onClick={() => setIsShareWith({})}
|
||||
>
|
||||
✕
|
||||
</div>
|
||||
<form
|
||||
className="h-full w-full z-[1300] px-2 mt-3"
|
||||
onSubmit={(e) => handleShareWith(e, item)}
|
||||
>
|
||||
<Select
|
||||
// onSortEnd={onSortEnd}
|
||||
distance={4}
|
||||
isMulti
|
||||
options={departmentList}
|
||||
value={selectedDepartments}
|
||||
onChange={onChange}
|
||||
closeMenuOnSelect={false}
|
||||
required={true}
|
||||
noOptionsMessage={() =>
|
||||
"Departments not found"
|
||||
}
|
||||
unstyled
|
||||
classNames={{
|
||||
control: () =>
|
||||
"op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full h-full text-[11px]",
|
||||
valueContainer: () =>
|
||||
"flex flex-row gap-x-[2px] gap-y-[2px] md:gap-y-0 w-full my-[2px]",
|
||||
multiValue: () =>
|
||||
"op-badge op-badge-primary h-full text-[11px]",
|
||||
multiValueLabel: () => "mb-[2px]",
|
||||
menu: () =>
|
||||
"mt-1 shadow-md rounded-lg bg-base-200 text-base-content",
|
||||
menuList: () =>
|
||||
"shadow-md rounded-lg overflow-hidden",
|
||||
option: () =>
|
||||
"bg-base-200 text-base-content rounded-lg m-1 hover:bg-base-300 p-2",
|
||||
noOptionsMessage: () =>
|
||||
"p-2 bg-base-200 rounded-lg m-1 p-2"
|
||||
}}
|
||||
/>
|
||||
<button className="op-btn op-btn-primary my-3">
|
||||
Submit
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{isViewShare[item.objectId] && (
|
||||
<ModalUi
|
||||
isOpen
|
||||
|
||||
@@ -8,7 +8,7 @@ export default async function getReport(request) {
|
||||
|
||||
const serverUrl = process.env.SERVER_URL;
|
||||
const appId = process.env.APP_ID;
|
||||
|
||||
const masterKey = process.env.MASTER_KEY;
|
||||
try {
|
||||
const userRes = await axios.get(serverUrl + '/users/me', {
|
||||
headers: {
|
||||
@@ -23,12 +23,49 @@ export default async function getReport(request) {
|
||||
if (json) {
|
||||
const { params, keys } = json;
|
||||
const orderBy = '-updatedAt';
|
||||
const strParams = JSON.stringify(params);
|
||||
const strKeys = keys.join();
|
||||
let strParams = JSON.stringify(params);
|
||||
if (reportId == '6TeaPr321t') {
|
||||
const extUserQuery = new Parse.Query('contracts_Users');
|
||||
extUserQuery.equalTo('Email', userRes.data.email);
|
||||
extUserQuery.include('DepartmentIds');
|
||||
const extUser = await extUserQuery.first({ useMasterKey: true });
|
||||
if (extUser) {
|
||||
const _extUser = JSON.parse(JSON.stringify(extUser));
|
||||
if (_extUser?.DepartmentIds && _extUser.DepartmentIds?.length > 0) {
|
||||
let departmentArr = [];
|
||||
_extUser?.DepartmentIds?.forEach(
|
||||
x => (departmentArr = [...departmentArr, ...x.Ancestors])
|
||||
);
|
||||
strParams = JSON.stringify({
|
||||
...params,
|
||||
$or: [
|
||||
{ SharedWith: { $in: departmentArr } },
|
||||
{
|
||||
CreatedBy: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: userId,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
} else {
|
||||
strParams = JSON.stringify({
|
||||
...params,
|
||||
CreatedBy: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: userId,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Parse-Application-Id': appId,
|
||||
'X-Parse-Master-Key': process.env.MASTER_KEY,
|
||||
'X-Parse-Master-Key': masterKey,
|
||||
};
|
||||
const url = `${serverUrl}/classes/${clsName}?where=${strParams}&keys=${strKeys}&order=${orderBy}&skip=${skip}&limit=${limit}&include=AuditTrail.UserPtr,Placeholders.signerPtr`;
|
||||
const res = await axios.get(url, { headers: headers });
|
||||
|
||||
@@ -318,11 +318,6 @@ export default function reportJson(id, userId) {
|
||||
params: {
|
||||
Type: { $ne: 'Folder' },
|
||||
IsArchive: { $ne: true },
|
||||
CreatedBy: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: currentUserId,
|
||||
},
|
||||
},
|
||||
keys: [
|
||||
'Name',
|
||||
@@ -335,6 +330,7 @@ export default function reportJson(id, userId) {
|
||||
'Signers.Phone',
|
||||
'Placeholders',
|
||||
'IsPublic',
|
||||
'SharedWith.Name',
|
||||
],
|
||||
};
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user