feat: add enable tour option in request signature and template form

This commit is contained in:
RaktimaNXG
2024-09-30 12:27:33 +05:30
parent eda6113792
commit 088ec5580a
24 changed files with 219 additions and 15 deletions
@@ -668,6 +668,12 @@
"download-files":"Download files",
"download-pdf":"Download Pdf",
"pdf-certificate":"Download Pdf + Certificate",
"document-logs":"Document logs"
"document-logs":"Document logs",
"enable-tour":"Enable Tour",
"istourenabled-help":{
"p1":"This will enable a guided tour for signers, providing instructions during the signing process.",
"p2":"This will disable the guided tour, ensuring a faster, uninterrupted signing experience.",
"p3":"Tip: If your signers are familiar with OpenSign and frequently use it, you may want to disable the guided tour for a more seamless experience. Choose the option that best fits your document signing needs."
}
}
@@ -667,6 +667,12 @@
"download-files" :"Télécharger des fichiers",
"download-pdf" :"Télécharger le PDF",
"pdf-certificate" :"Télécharger Pdf + Certificat",
"document-logs":"Journaux de documents"
"document-logs":"Journaux de documents",
"enable-tour": "Activer la visite",
"istourenabled-otp-help":{
"p1": "Cela permettra une visite guidée pour les signataires, fournissant des instructions pendant le processus de signature.",
"p2": "Cela désactivera la visite guidée, garantissant ainsi une expérience de signature plus rapide et ininterrompue.",
"p3": "Conseil : si vos signataires connaissent OpenSign et l'utilisent fréquemment, vous souhaiterez peut-être désactiver la visite guidée pour une expérience plus fluide. Choisissez l'option qui correspond le mieux à vos besoins en matière de signature de documents."
}
}
@@ -17,7 +17,10 @@ const EditTemplate = ({ template, onSuccess }) => {
SendinOrder: template?.SendinOrder ? `${template?.SendinOrder}` : "false",
AutomaticReminders: template?.AutomaticReminders || false,
RemindOnceInEvery: template?.RemindOnceInEvery || 5,
IsEnableOTP: template?.IsEnableOTP ? `${template?.IsEnableOTP}` : "false"
IsEnableOTP: template?.IsEnableOTP ? `${template?.IsEnableOTP}` : "false",
IsTourEnabled: template?.IsTourEnabled
? `${template?.IsTourEnabled}`
: "false"
});
const [isSubscribe, setIsSubscribe] = useState(false);
useEffect(() => {
@@ -43,6 +46,7 @@ const EditTemplate = ({ template, onSuccess }) => {
e.preventDefault();
e.stopPropagation();
const isChecked = formData.SendinOrder === "true" ? true : false;
const isTourEnabled = formData?.IsTourEnabled === "false" ? false : true;
const AutoReminder = formData?.AutomaticReminders || false;
const IsEnableOTP = formData.IsEnableOTP === "true" ? true : false;
let reminderDate = {};
@@ -56,6 +60,7 @@ const EditTemplate = ({ template, onSuccess }) => {
...formData,
SendinOrder: isChecked,
IsEnableOTP: IsEnableOTP,
IsTourEnabled: isTourEnabled,
...reminderDate
};
onSuccess(data);
@@ -256,6 +261,59 @@ const EditTemplate = ({ template, onSuccess }) => {
</div>
</div>
)}
<div className="text-xs mt-2">
<label className="block">
<span>
{t("enable-tour")}
<a data-tooltip-id="istourenabled-tooltip" className="ml-1">
<sup>
<i className="fa-light fa-question rounded-full border-[#33bbff] text-[#33bbff] text-[13px] border-[1px] py-[1.5px] px-[4px]"></i>
</sup>
</a>{" "}
</span>
<Tooltip id="istourenabled-tooltip" className="z-50">
<div className="max-w-[200px] md:max-w-[450px]">
<p className="font-bold">{t("enable-tour")}</p>
<p className="p-[5px]">
<ol className="list-disc">
<li>
<span className="font-bold">{t("yes")}: </span>
<span>{t("istourenabled-help.p1")}</span>
</li>
<li>
<span className="font-bold">{t("no")}: </span>
<span>{t("istourenabled-help.p2")}</span>
</li>
</ol>
</p>
<p>{t("istourenabled-help.p3")}</p>
</div>
</Tooltip>
</label>
<div className={` flex items-center gap-2 ml-2 mb-1 `}>
<input
type="radio"
value={"true"}
className="op-radio op-radio-xs"
name="IsTourEnabled"
checked={formData.IsTourEnabled === "true"}
onChange={handleStrInput}
/>
<div className="text-center">{t("yes")}</div>
</div>
<div className={` flex items-center gap-2 ml-2 mb-1 `}>
<input
type="radio"
value={"false"}
name="IsTourEnabled"
className="op-radio op-radio-xs"
checked={formData.IsTourEnabled === "false"}
onChange={handleStrInput}
/>
<div className="text-center">{t("no")}</div>
</div>
</div>
<div className="mt-[1rem] flex justify-start">
<button type="submit" className="op-btn op-btn-primary">
{t("submit")}
+2 -1
View File
@@ -710,7 +710,8 @@ export const createDocument = async (
SendinOrder: Doc?.SendinOrder || false,
AutomaticReminders: Doc?.AutomaticReminders || false,
RemindOnceInEvery: parseInt(Doc?.RemindOnceInEvery || 5),
IsEnableOTP: Doc?.IsEnableOTP || false
IsEnableOTP: Doc?.IsEnableOTP || false,
IsTourEnabled: Doc?.IsTourEnabled || false
};
try {
+66 -3
View File
@@ -67,7 +67,8 @@ const Forms = (props) => {
file: "",
remindOnceInEvery: 5,
autoreminder: false,
IsEnableOTP: "false"
IsEnableOTP: "false",
IsTourEnabled: "false"
});
const [fileupload, setFileUpload] = useState("");
const [fileload, setfileload] = useState(false);
@@ -418,9 +419,12 @@ const Forms = (props) => {
}
if (props.title !== "Sign Yourself") {
const isChecked = formData.SendinOrder === "false" ? false : true;
const isTourEnabled =
formData?.IsTourEnabled === "false" ? false : true;
object.set("SendinOrder", isChecked);
object.set("AutomaticReminders", formData.autoreminder);
object.set("RemindOnceInEvery", parseInt(formData.remindOnceInEvery));
object.set("IsTourEnabled", isTourEnabled);
if (isEnableSubscription) {
const IsEnableOTP =
formData?.IsEnableOTP === "false" ? false : true;
@@ -464,7 +468,8 @@ const Forms = (props) => {
file: "",
remindOnceInEvery: 5,
autoreminder: false,
IsEnableOTP: "false"
IsEnableOTP: "false",
IsTourEnabled: "true"
});
setFileUpload("");
setpercentage(0);
@@ -514,7 +519,8 @@ const Forms = (props) => {
file: "",
remindOnceInEvery: 5,
autoreminder: false,
IsEnableOTP: "false"
IsEnableOTP: "false",
IsTourEnabled: "true"
});
setFileUpload("");
setpercentage(0);
@@ -985,6 +991,63 @@ const Forms = (props) => {
</div>
</div>
)}
<div className="text-xs mt-2">
<label className="block">
<span>
{t("enable-tour")}
<a
data-tooltip-id="istourenabled-tooltip"
className="ml-1"
>
<sup>
<i className="fa-light fa-question rounded-full border-[#33bbff] text-[#33bbff] text-[13px] border-[1px] py-[1.5px] px-[4px]"></i>
</sup>
</a>{" "}
</span>
<Tooltip id="istourenabled-tooltip" className="z-50">
<div className="max-w-[200px] md:max-w-[450px]">
<p className="font-bold">{t("enable-tour")}</p>
<p className="p-[5px]">
<ol className="list-disc">
<li>
<span className="font-bold">
{t("yes")}:{" "}
</span>
<span>{t("istourenabled-help.p1")}</span>
</li>
<li>
<span className="font-bold">{t("no")}: </span>
<span>{t("istourenabled-help.p2")}</span>
</li>
</ol>
</p>
<p>{t("istourenabled-help.p3")}</p>
</div>
</Tooltip>
</label>
<div className={` flex items-center gap-2 ml-2 mb-1 `}>
<input
type="radio"
value={"true"}
className="op-radio op-radio-xs"
name="IsTourEnabled"
checked={formData.IsTourEnabled === "true"}
onChange={handleStrInput}
/>
<div className="text-center">{t("yes")}</div>
</div>
<div className={` flex items-center gap-2 ml-2 mb-1 `}>
<input
type="radio"
value={"false"}
name="IsTourEnabled"
className="op-radio op-radio-xs"
checked={formData.IsTourEnabled === "false"}
onChange={handleStrInput}
/>
<div className="text-center">{t("no")}</div>
</div>
</div>
</>
)}
</div>
+4 -1
View File
@@ -421,6 +421,8 @@ function PdfRequestFiles(props) {
const expireUpdateDate = new Date(expireDate).getTime();
const currDate = new Date().getTime();
const getSigners = documentData[0].Signers;
const isTourEnabled =
documentData[0]?.IsTourEnabled === true ? true : false;
const getCurrentSigner = getSigners?.find(
(data) => data.UserId.objectId === jsonSender?.objectId
);
@@ -596,7 +598,8 @@ function PdfRequestFiles(props) {
checkAlreadySign ||
!currUserId ||
declined ||
currDate > expireUpdateDate
currDate > expireUpdateDate ||
!isTourEnabled
) {
setRequestSignTour(true);
} else {
@@ -781,6 +781,7 @@ const TemplatePlaceholder = () => {
RemindOnceInEvery: parseInt(pdfDetails[0]?.RemindOnceInEvery),
NextReminderDate: pdfDetails[0]?.NextReminderDate,
IsEnableOTP: pdfDetails[0]?.IsEnableOTP === true ? true : false,
IsTourEnabled: pdfDetails[0]?.IsTourEnabled === true ? true : false,
URL: pdfUrl
};
const updateTemplate = new Parse.Object("contracts_Template");
@@ -273,7 +273,8 @@ const ReportTable = (props) => {
SendinOrder: Doc?.SendinOrder || false,
AutomaticReminders: Doc?.AutomaticReminders || false,
RemindOnceInEvery: Doc?.RemindOnceInEvery || 5,
IsEnableOTP: Doc?.IsEnableOTP || false
IsEnableOTP: Doc?.IsEnableOTP || false,
IsTourEnabled: Doc?.IsTourEnabled || false
};
try {
const res = await axios.post(
@@ -668,5 +668,12 @@
"download-files":"Download files",
"download-pdf":"Download Pdf",
"pdf-certificate":"Download Pdf + Certificate",
"document-logs":"Document logs"
"document-logs":"Document logs",
"enable-tour":"Enable Tour",
"istourenabled-help":{
"p1":"This will enable a guided tour for signers, providing instructions during the signing process.",
"p2":"This will disable the guided tour, ensuring a faster, uninterrupted signing experience.",
"p3":"Tip: If your signers are familiar with OpenSign and frequently use it, you may want to disable the guided tour for a more seamless experience. Choose the option that best fits your document signing needs."
}
}
@@ -667,6 +667,12 @@
"download-files" :"Télécharger des fichiers",
"download-pdf" :"Télécharger le PDF",
"pdf-certificate" :"Télécharger Pdf + Certificat",
"document-logs":"Journaux de documents"
"document-logs":"Journaux de documents",
"enable-tour": "Activer la visite",
"istourenabled-otp-help":{
"p1": "Cela permettra une visite guidée pour les signataires, fournissant des instructions pendant le processus de signature.",
"p2": "Cela désactivera la visite guidée, garantissant ainsi une expérience de signature plus rapide et ininterrompue.",
"p3": "Conseil : si vos signataires connaissent OpenSign et l'utilisent fréquemment, vous souhaiterez peut-être désactiver la visite guidée pour une expérience plus fluide. Choisissez l'option qui correspond le mieux à vos besoins en matière de signature de documents."
}
}
@@ -198,6 +198,10 @@ export default async function createDocumentWithTemplate(request, response) {
}
const enableOTP = request.body?.enableOTP === true ? true : false;
const IsEnableOTP = enableOTP || template?.IsEnableOTP || false;
const enableTour = request.body?.enableOTP;
const isTourEnabled =
enableTour !== undefined ? enableTour : template?.IsTourEnabled || false;
object.set('IsTourEnabled', isTourEnabled);
object.set('IsEnableOTP', IsEnableOTP);
object.set('CreatedBy', template.CreatedBy);
object.set('ExtUserPtr', {
@@ -64,6 +64,7 @@ export default async function createDocumentwithCoordinate(request, response) {
const sendInOrder = request.body.sendInOrder || false;
const TimeToCompleteDays = request.body.timeToCompleteDays || 15;
const IsEnableOTP = request.body?.enableOTP === true ? true : false;
const isTourEnabled = request.body?.enableTour || false;
// console.log('fileData ', fileData);
const protocol = customAPIurl();
const baseUrl = new URL(process.env.PUBLIC_URL);
@@ -164,6 +165,7 @@ export default async function createDocumentwithCoordinate(request, response) {
object.set('TimeToCompleteDays', TimeToCompleteDays);
}
object.set('IsEnableOTP', IsEnableOTP);
object.set('IsTourEnabled', isTourEnabled);
object.set('IsSendMail', send_email);
let contact = [];
if (signers && signers.length > 0) {
@@ -10,6 +10,7 @@ export default async function createTemplate(request, response) {
const fileData = request.files?.[0] ? request.files[0].buffer : null;
const baseUrl = new URL(process.env.PUBLIC_URL);
const isEnableOTP = request.body?.enableOTP === true ? true : false;
const isTourEnabled = request.body?.enableTour || false;
try {
const reqToken = request.headers['x-api-token'];
@@ -67,6 +68,7 @@ export default async function createTemplate(request, response) {
object.set('CreatedBy', userPtr);
object.set('ExtUserPtr', extUserPtr);
object.set('IsEnableOTP', isEnableOTP);
object.set('IsTourEnabled', isTourEnabled);
if (SendinOrder) {
object.set('SendinOrder', SendinOrder);
}
@@ -18,6 +18,7 @@ export default async function createTemplatewithCoordinate(request, response) {
const fileData = request.files?.[0] ? request.files[0].buffer : null;
const SendinOrder = request.body.sendInOrder || false;
const isEnableOTP = request.body?.enableOTP === true ? true : false;
const isTourEnabled = request.body?.enableTour || false;
// console.log('fileData ', fileData);
const protocol = customAPIurl();
@@ -83,6 +84,7 @@ export default async function createTemplatewithCoordinate(request, response) {
object.set('CreatedBy', userPtr);
object.set('ExtUserPtr', extUserPtr);
object.set('IsEnableOTP', isEnableOTP);
object.set('IsTourEnabled', isTourEnabled);
let contact = [];
if (signers && signers.length > 0) {
let parseSigners;
@@ -13,6 +13,7 @@ export default async function draftDocument(request, response) {
const fileData = request.files?.[0] ? request.files[0].buffer : null;
const SendinOrder = request.body.sendInOrder || false;
const isEnableOTP = request.body?.enableOTP === true ? true : false;
const isTourEnabled = request.body?.enableTour || false;
// console.log('fileData ', fileData);
const protocol = customAPIurl();
@@ -86,6 +87,7 @@ export default async function draftDocument(request, response) {
object.set('ExtUserPtr', extUserPtr);
object.set('IsSendMail', send_email);
object.set('IsEnableOTP', isEnableOTP);
object.set('IsTourEnabled', isTourEnabled);
if (signers && signers.length > 0) {
let parseSigners;
if (base64File) {
@@ -65,6 +65,7 @@ export default async function getDocument(request, response) {
enableOTP: document?.IsEnableOTP || false,
createdAt: document.createdAt,
updatedAt: document.updatedAt,
enableTour: document?.IsTourEnabled || false,
});
} else {
if (request.posthog) {
@@ -103,6 +103,7 @@ export default async function getDocumentList(request, response) {
enableOTP: x?.IsEnableOTP || false,
createdAt: x.createdAt,
updatedAt: x.updatedAt,
enableTour: x?.IsTourEnabled || false,
}));
return response.json({ result: updateRes });
} else {
@@ -64,6 +64,7 @@ export default async function getTemplate(request, response) {
enableOTP: template?.IsEnableOTP || false,
createdAt: template.createdAt,
updatedAt: template.updatedAt,
enableTour: template?.IsTourEnabled || false,
});
} else {
if (request.posthog) {
@@ -91,6 +91,7 @@ export default async function getTemplatetList(request, response) {
enableOTP: template?.IsEnableOTP || false,
createdAt: template.createdAt,
updatedAt: template.updatedAt,
enableTour: template?.IsTourEnabled || false,
}));
return response.json({ result: updateRes });
@@ -10,7 +10,7 @@ export default async function updateDocument(request, response) {
const token = await tokenQuery.first({ useMasterKey: true });
if (token !== undefined) {
// Valid Token then proceed request
const allowedKeys = ['name', 'note', 'description', 'folderId', 'enableOTP'];
const allowedKeys = ['name', 'note', 'description', 'folderId', 'enableOTP', 'enableTour'];
const objectKeys = Object.keys(request.body);
const isValid = objectKeys.every(key => allowedKeys.includes(key)) && objectKeys.length > 0;
const parseUser = JSON.parse(JSON.stringify(token));
@@ -48,10 +48,12 @@ export default async function updateDocument(request, response) {
objectId: request?.body?.folderId,
});
}
if (request.body?.enableOTP) {
updateQuery.set('IsEnableOTP', request.body?.enableOTP);
}
if (request.body?.enableTour !== undefined) {
updateQuery.set('IsTourEnabled', request.body?.enableTour);
}
const updatedRes = await updateQuery.save(null, { useMasterKey: true });
if (updatedRes) {
if (request.posthog) {
@@ -10,7 +10,7 @@ export default async function updateTemplate(request, response) {
const token = await tokenQuery.first({ useMasterKey: true });
if (token !== undefined) {
// Valid Token then proceed request
const allowedKeys = ['name', 'note', 'description', 'folderId', 'enableOTP'];
const allowedKeys = ['name', 'note', 'description', 'folderId', 'enableOTP', 'enableTour'];
const objectKeys = Object.keys(request.body);
const isValid = objectKeys.every(key => allowedKeys.includes(key)) && objectKeys.length > 0;
const parseUser = JSON.parse(JSON.stringify(token));
@@ -51,6 +51,9 @@ export default async function updateTemplate(request, response) {
if (request.body?.enableOTP) {
updateQuery.set('IsEnableOTP', request.body?.enableOTP);
}
if (request.body?.enableTour !== undefined) {
updateQuery.set('IsTourEnabled', request.body?.enableTour);
}
const updatedRes = await updateQuery.save(null, { useMasterKey: true });
if (updatedRes) {
if (request.posthog) {
@@ -55,7 +55,7 @@ const createDocumentFromTemplate = async (template, existContact, index) => {
object.set('Description', template?.Description);
object.set('Note', template?.Note);
object.set('TimeToCompleteDays', template?.TimeToCompleteDays || 15);
object.set('SendinOrder', template?.SendinOrder);
object.set('SendinOrder', template?.SendinOrder || false);
object.set('AutomaticReminders', template?.AutomaticReminders || false);
object.set('RemindOnceInEvery', template?.RemindOnceInEvery || 5);
object.set('URL', template?.URL);
@@ -63,6 +63,7 @@ const createDocumentFromTemplate = async (template, existContact, index) => {
object.set('ExtUserPtr', template?.ExtUserPtr);
object.set('OriginIp', template?.OriginIp || '');
object.set('IsEnableOTP', template?.IsEnableOTP || false);
object.set('IsTourEnabled', template?.IsTourEnabled || false);
let signers = template?.Signers || [];
const signerobj = {
__type: 'Pointer',
@@ -201,6 +201,7 @@ export default async function createBatchDocs(request) {
OriginIp: Ip,
DocSentAt: { __type: 'Date', iso: isoDate },
IsEnableOTP: x?.IsEnableOTP || false,
IsTourEnabled: x?.IsTourEnabled || false,
},
};
});
@@ -0,0 +1,29 @@
/**
*
* @param {Parse} Parse
*/
exports.up = async (Parse) => {
const templateSchema = new Parse.Schema('contracts_Template');
templateSchema.addBoolean('IsTourEnabled');
await templateSchema.update();
const className = 'contracts_Document';
const schema = new Parse.Schema(className);
schema.addBoolean('IsTourEnabled');
return schema.update();
};
/**
*
* @param {Parse} Parse
*/
exports.down = async (Parse) => {
const templateSchema = new Parse.Schema('contracts_Template');
templateSchema.deleteField('IsTourEnabled');
await templateSchema.update();
const className = 'contracts_Document';
const schema = new Parse.Schema(className);
schema.deleteField('IsTourEnabled');
return schema.update();
};