Merge pull request #1302 from OpenSignLabs/react-tour

feat: add enable tour option in request signature and template form
This commit is contained in:
prafull-opensignlabs
2024-10-08 14:15:19 +05:30
committed by GitHub
25 changed files with 544 additions and 131 deletions
@@ -672,6 +672,14 @@
"document-logs":"Document logs",
"server-down": "Unable to connect to the OpenSign server. If you are self-hosting OpenSign, please ensure that all the steps in the documentation have been followed correctly. If you're running OpenSign locally, you might be accessing it through an incorrect port number.",
"admin-exists": "Admin already exists. Please login to the application using admin credentials in order to manage users.",
"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."
},
"form-title-1":"Document Flow Setting",
"form-title-2":"Security Setting",
"public-tour-message":"The template needs to be public before you can generate a shareable link.",
"add-user-template": "You need to add a role before you can add fields for it.",
"pdf-uncompatible": "This pdf is not compatible with opensign, please contact <support@opensignlabs.com>"
@@ -674,6 +674,14 @@
"admin-exists": "El administrador ya existe. Por favor, inicia sesión en la aplicación usando las credenciales de administrador para poder administrar los usuarios.",
"public-tour-message": "Por favor, convierte la plantilla en pública para copiar la URL pública",
"add-user-template": "Es necesario agregar un rol antes de poder agregarle campos.",
"pdf-uncompatible": "Este pdf no es compatible con opensign, comuníquese con <support@opensignlabs.com>"
"pdf-uncompatible": "Este pdf no es compatible con opensign, comuníquese con <support@opensignlabs.com>",
"enable-tour": "Habilitar recorrido",
"istourenabled-help":{
"p1": "Esto permitirá realizar una visita guiada para los firmantes, brindando instrucciones durante el proceso de firma.",
"p2": "Esto desactivará la visita guiada, lo que garantizará una experiencia de firma más rápida e ininterrumpida.",
"p3": "Consejo: si sus firmantes están familiarizados con OpenSign y lo utilizan con frecuencia, es posible que desee desactivar la visita guiada para disfrutar de una experiencia más fluida. Elija la opción que mejor se adapte a sus necesidades de firma de documentos"
},
"form-title-1": "Configuración del flujo de documentos",
"form-title-2": "Configuración de seguridad"
}
@@ -671,6 +671,14 @@
"document-logs":"Journaux de documents",
"server-down": "Impossible de se connecter au serveur OpenSign. Si vous hébergez vous-même OpenSign, veuillez vous assurer que toutes les étapes de la documentation ont été correctement suivies. Si vous exécutez OpenSign localement, vous y accédez peut-être via un numéro de port incorrect.",
"admin-exists": "L'administrateur existe déjà. Veuillez vous connecter à l'application en utilisant les informations d'identification de l'administrateur afin de gérer les utilisateurs.",
"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."
},
"form-title-1": "Paramètre du flux de documents",
"form-title-2": "Paramètre de sécurité",
"public-tour-message": "Le modèle doit être public avant que vous puissiez générer un lien partageable.",
"add-user-template":"Vous devez ajouter un rôle avant de pouvoir lui ajouter des champs. ",
"pdf-uncompatible":"Ce pdf n'est pas compatible avec opensign, veuillez contacter <support@opensignlabs.com>"
@@ -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")}
+1
View File
@@ -711,6 +711,7 @@ export const createDocument = async (
AutomaticReminders: Doc?.AutomaticReminders || false,
RemindOnceInEvery: parseInt(Doc?.RemindOnceInEvery || 5),
IsEnableOTP: Doc?.IsEnableOTP || false,
IsTourEnabled: Doc?.IsTourEnabled || false,
IsFileAdapter: Doc?.IsFileAdapter || false
};
+372 -123
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);
@@ -524,9 +525,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;
@@ -573,7 +577,8 @@ const Forms = (props) => {
file: "",
remindOnceInEvery: 5,
autoreminder: false,
IsEnableOTP: "false"
IsEnableOTP: "false",
IsTourEnabled: "true"
});
setFileUpload("");
setpercentage(0);
@@ -623,7 +628,8 @@ const Forms = (props) => {
file: "",
remindOnceInEvery: 5,
autoreminder: false,
IsEnableOTP: "false"
IsEnableOTP: "false",
IsTourEnabled: "true"
});
setFileUpload("");
setpercentage(0);
@@ -923,92 +929,259 @@ const Forms = (props) => {
required
/>
</div>
{props.title !== "New Template" && (
{props.title === "Sign Yourself" ? (
<SelectFolder
onSuccess={handleFolder}
folderCls={props.Cls}
isReset={isReset}
/>
)}
{props.title !== "Sign Yourself" && (
<div className="text-xs mt-2">
<label className="block">
{t("send-in-order")}
<a data-tooltip-id="sendInOrder-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>
<Tooltip id="sendInOrder-tooltip" className="z-50">
<div className="max-w-[200px] md:max-w-[450px]">
<p className="font-bold">{t("send-in-order")}</p>
<p>{t("send-in-order-help.p1")}</p>
<p className="p-[5px]">
<ol className="list-disc">
<li>
<span className="font-bold">{t("yes")}: </span>
<span>{t("send-in-order-help.p2")}</span>
</li>
<li>
<span className="font-bold">{t("no")}: </span>
<span>{t("send-in-order-help.p3")}</span>
</li>
</ol>
</p>
<p>{t("send-in-order-help.p4")}</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="SendinOrder"
checked={formData.SendinOrder === "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="SendinOrder"
className="op-radio op-radio-xs"
checked={formData.SendinOrder === "false"}
onChange={handleStrInput}
/>
<div className="text-center">{t("no")}</div>
</div>
</div>
)}
{isAdvanceOpt && (
<div className="overflow-y-auto z-[500] transition-all">
{props.title === "Request Signatures" && (
<div className="text-xs mt-2">
<label className="block">
{t("time-to-complete")}
<span className="text-red-500 text-[13px]">*</span>
</label>
<input
type="number"
name="TimeToCompleteDays"
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
value={formData.TimeToCompleteDays}
onChange={(e) => handleStrInput(e)}
onInvalid={(e) =>
e.target.setCustomValidity(t("input-required"))
}
onInput={(e) => e.target.setCustomValidity("")}
required
) : (
<div className="flex flex-col md:flex-row w-full mt-4 md:mt-10 gap-3 ">
<div className="card bg-base-100 rounded-box flex-grow p-3 ">
{props.title !== "New Template" ? (
<SelectFolder
onSuccess={handleFolder}
folderCls={props.Cls}
isReset={isReset}
/>
</div>
) : (
<>
<span className=" mb-2 font-[400]">
{t("form-title-1")}
</span>
<div className="text-xs mt-3">
<label className="block">
{t("send-in-order")}
<a
data-tooltip-id="sendInOrder-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>
<Tooltip id="sendInOrder-tooltip" className="z-50">
<div className="max-w-[200px] md:max-w-[450px]">
<p className="font-bold">{t("send-in-order")}</p>
<p>{t("send-in-order-help.p1")}</p>
<p className="p-[5px]">
<ol className="list-disc">
<li>
<span className="font-bold">
{t("yes")}:{" "}
</span>
<span>{t("send-in-order-help.p2")}</span>
</li>
<li>
<span className="font-bold">
{t("no")}:{" "}
</span>
<span>{t("send-in-order-help.p3")}</span>
</li>
</ol>
</p>
<p>{t("send-in-order-help.p4")}</p>
</div>
</Tooltip>
</label>
<div className="flex flex-col md:flex-row md:gap-4">
<div className="flex items-center gap-2 ml-2 mb-1">
<input
type="radio"
value={"true"}
className="op-radio op-radio-xs"
name="SendinOrder"
checked={formData.SendinOrder === "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="SendinOrder"
className="op-radio op-radio-xs"
checked={formData.SendinOrder === "false"}
onChange={handleStrInput}
/>
<div className="text-center">{t("no")}</div>
</div>
</div>
</div>
</>
)}
{isAdvanceOpt && (
<>
{isEnableSubscription &&
props.title === "New Template" && (
<div className="text-xs mt-[15px]">
<span
className={isSubscribe ? "" : " text-gray-300"}
>
{t("auto-reminder")}{" "}
{!isSubscribe && isEnableSubscription && (
<Upgrade />
)}
</span>
<label
className={`${
isSubscribe
? "cursor-pointer "
: "pointer-events-none opacity-50"
} relative block items-center mb-0 mt-1.5`}
>
<input
type="checkbox"
className="op-toggle transition-all checked:[--tglbg:#3368ff] checked:bg-white"
checked={formData.autoreminder}
onChange={handleAutoReminder}
/>
</label>
</div>
)}
{formData?.autoreminder === true && (
<div className="text-xs mt-2">
<label className="block">
{t("remind-once")}
<span className="text-red-500 text-[13px]">*</span>
</label>
<input
type="number"
value={formData.remindOnceInEvery}
name="remindOnceInEvery"
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
onChange={handleStrInput}
onInvalid={(e) =>
e.target.setCustomValidity(t("input-required"))
}
onInput={(e) => e.target.setCustomValidity("")}
required
/>
</div>
)}
{props.title !== "New Template" && (
<>
<span className=" mt-2 font-[400]">
{t("form-title-1")}
</span>
<div className="text-xs mt-3">
<label className="block">
{t("send-in-order")}
<a
data-tooltip-id="sendInOrder-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>
<Tooltip
id="sendInOrder-tooltip"
className="z-50"
>
<div className="max-w-[200px] md:max-w-[450px]">
<p className="font-bold">
{t("send-in-order")}
</p>
<p>{t("send-in-order-help.p1")}</p>
<p className="p-[5px]">
<ol className="list-disc">
<li>
<span className="font-bold">
{t("yes")}:{" "}
</span>
<span>
{t("send-in-order-help.p2")}
</span>
</li>
<li>
<span className="font-bold">
{t("no")}:{" "}
</span>
<span>
{t("send-in-order-help.p3")}
</span>
</li>
</ol>
</p>
<p>{t("send-in-order-help.p4")}</p>
</div>
</Tooltip>
</label>
<div className="flex flex-col md:flex-row md:gap-4">
<div className="flex items-center gap-2 ml-2 mb-1">
<input
type="radio"
value={"true"}
className="op-radio op-radio-xs"
name="SendinOrder"
checked={formData.SendinOrder === "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="SendinOrder"
className="op-radio op-radio-xs"
checked={formData.SendinOrder === "false"}
onChange={handleStrInput}
/>
<div className="text-center">{t("no")}</div>
</div>
</div>
</div>
</>
)}
<div className="overflow-y-auto z-[500] transition-all">
{props.title === "Request Signatures" && (
<div className="text-xs mt-2">
<label className="block">
{t("time-to-complete")}
<span className="text-red-500 text-[13px]">
*
</span>
</label>
<input
type="number"
name="TimeToCompleteDays"
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
value={formData.TimeToCompleteDays}
onChange={(e) => handleStrInput(e)}
onInvalid={(e) =>
e.target.setCustomValidity(t("input-required"))
}
onInput={(e) => e.target.setCustomValidity("")}
required
/>
</div>
)}
</div>
</>
)}
</div>
{isAdvanceOpt && (
<div
style={{
height:
props.title === "New Template" && isEnableSubscription
? "220px"
: !isEnableSubscription &&
props.title === "New Template"
? "100px"
: "280px"
}}
className="w-[1px] bg-gray-300 m-auto hidden md:inline-block"
></div>
)}
{props.title !== "Sign Yourself" && (
<>
{isEnableSubscription && (
<div className="text-xs mt-2">
{isAdvanceOpt && (
<div className="card bg-base-100 rounded-box p-3 flex-grow ">
{isEnableSubscription && props.title !== "New Template" && (
<div className="text-xs mt-[10px]">
<span className={isSubscribe ? "" : " text-gray-300"}>
{t("auto-reminder")}{" "}
{!isSubscribe && isEnableSubscription && <Upgrade />}
@@ -1029,28 +1202,30 @@ const Forms = (props) => {
</label>
</div>
)}
{formData?.autoreminder === true && (
<div className="text-xs mt-2">
<label className="block">
{t("remind-once")}
<span className="text-red-500 text-[13px]">*</span>
</label>
<input
type="number"
value={formData.remindOnceInEvery}
name="remindOnceInEvery"
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
onChange={handleStrInput}
onInvalid={(e) =>
e.target.setCustomValidity(t("input-required"))
}
onInput={(e) => e.target.setCustomValidity("")}
required
/>
</div>
)}
{formData?.autoreminder === true &&
props.title !== "New Template" && (
<div className="text-xs mt-2">
<label className="block">
{t("remind-once")}
<span className="text-red-500 text-[13px]">*</span>
</label>
<input
type="number"
value={formData.remindOnceInEvery}
name="remindOnceInEvery"
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
onChange={handleStrInput}
onInvalid={(e) =>
e.target.setCustomValidity(t("input-required"))
}
onInput={(e) => e.target.setCustomValidity("")}
required
/>
</div>
)}
<span className="font-[400] mt-2">{t("form-title-2")}</span>
{isEnableSubscription && (
<div className="text-xs mt-2">
<div className="text-xs mt-4">
<label className="block">
<span className={isSubscribe ? "" : " text-gray-300"}>
{t("isenable-otp")}{" "}
@@ -1090,52 +1265,126 @@ const Forms = (props) => {
</div>
</Tooltip>
</label>
<div
className={`${
isSubscribe ? "" : "pointer-events-none opacity-50"
} flex items-center gap-2 ml-2 mb-1 `}
>
<div className="flex flex-col md:flex-row md:gap-4">
<div
className={`${
isSubscribe
? ""
: "pointer-events-none opacity-50"
} flex items-center gap-2 ml-2 mb-1 `}
>
<input
type="radio"
value={"true"}
className="op-radio op-radio-xs"
name="IsEnableOTP"
checked={formData.IsEnableOTP === "true"}
onChange={handleStrInput}
/>
<div className="text-center">{t("yes")}</div>
</div>
<div
className={`${
isSubscribe
? ""
: "pointer-events-none opacity-50"
} flex items-center gap-2 ml-2 mb-1 `}
>
<input
type="radio"
value={"false"}
name="IsEnableOTP"
className="op-radio op-radio-xs"
checked={formData.IsEnableOTP === "false"}
onChange={handleStrInput}
/>
<div className="text-center">{t("no")}</div>
</div>
</div>
</div>
)}
<div className="text-xs mt-3">
<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 flex-col md:flex-row md:gap-4">
<div className={` flex items-center gap-2 ml-2 mb-1 `}>
<input
type="radio"
value={"true"}
className="op-radio op-radio-xs"
name="IsEnableOTP"
checked={formData.IsEnableOTP === "true"}
name="IsTourEnabled"
checked={formData.IsTourEnabled === "true"}
onChange={handleStrInput}
/>
<div className="text-center">{t("yes")}</div>
</div>
<div
className={`${
isSubscribe ? "" : "pointer-events-none opacity-50"
} flex items-center gap-2 ml-2 mb-1 `}
>
<div className={` flex items-center gap-2 ml-2 mb-1 `}>
<input
type="radio"
value={"false"}
name="IsEnableOTP"
name="IsTourEnabled"
className="op-radio op-radio-xs"
checked={formData.IsEnableOTP === "false"}
checked={formData.IsTourEnabled === "false"}
onChange={handleStrInput}
/>
<div className="text-center">{t("no")}</div>
</div>
</div>
)}
</>
</div>
</div>
)}
</div>
)}
{props.title !== "Sign Yourself" && (
{isAdvanceOpt && props.title !== "Sign Yourself" ? (
<div
onClick={() => setIsAdvanceOpt(!isAdvanceOpt)}
className={`mt-2.5 op-link op-link-primary text-sm`}
>
{isAdvanceOpt
? t("hide-advanced-options")
: t("advanced-options")}
{t("hide-advanced-options")}
</div>
) : (
props.title !== "Sign Yourself" && (
<div
onClick={() => setIsAdvanceOpt(!isAdvanceOpt)}
className={`mt-2.5 op-link op-link-primary text-sm`}
>
{t("advanced-options")}
</div>
)
)}
<div className="flex items-center mt-3 gap-2">
<button
className={`${
+4 -1
View File
@@ -423,6 +423,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
);
@@ -598,7 +600,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");
@@ -275,7 +275,9 @@ const ReportTable = (props) => {
AutomaticReminders: Doc?.AutomaticReminders || false,
RemindOnceInEvery: Doc?.RemindOnceInEvery || 5,
IsEnableOTP: Doc?.IsEnableOTP || false,
IsTourEnabled: Doc?.IsTourEnabled || false,
IsFileAdapter: Doc?.IsFileAdapter || false
};
try {
const res = await axios.post(
@@ -672,7 +672,16 @@
"document-logs": "Document logs",
"server-down": "Unable to connect to the OpenSign server. If you are self-hosting OpenSign, please ensure that all the steps in the documentation have been followed correctly. If you're running OpenSign locally, you might be accessing it through an incorrect port number.",
"admin-exists": "Admin already exists. Please login to the application using admin credentials in order to manage users.",
"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."
},
"form-title-1": "Document Flow Setting",
"form-title-2": "Security Setting",
"public-tour-message": "The template needs to be public before you can generate a shareable link.",
"add-user-template": "You need to add a role before you can add fields for it.",
"pdf-uncompatible": "This pdf is not compatible with opensign, please contact <support@opensignlabs.com>"
}
@@ -674,5 +674,13 @@
"admin-exists": "El administrador ya existe. Por favor, inicia sesión en la aplicación usando las credenciales de administrador para poder administrar los usuarios.",
"public-tour-message": "Por favor, convierte la plantilla en pública para copiar la URL pública",
"add-user-template": "Es necesario agregar un rol antes de poder agregarle campos.",
"pdf-uncompatible": "Este pdf no es compatible con opensign, comuníquese con <support@opensignlabs.com>"
"pdf-uncompatible": "Este pdf no es compatible con opensign, comuníquese con <support@opensignlabs.com>",
"enable-tour": "Habilitar recorrido",
"istourenabled-help":{
"p1": "Esto permitirá realizar una visita guiada para los firmantes, brindando instrucciones durante el proceso de firma.",
"p2": "Esto desactivará la visita guiada, lo que garantizará una experiencia de firma más rápida e ininterrumpida.",
"p3": "Consejo: si sus firmantes están familiarizados con OpenSign y lo utilizan con frecuencia, es posible que desee desactivar la visita guiada para disfrutar de una experiencia más fluida. Elija la opción que mejor se adapte a sus necesidades de firma de documentos"
},
"form-title-1": "Configuración del flujo de documentos",
"form-title-2": "Configuración de seguridad"
}
@@ -671,6 +671,14 @@
"document-logs": "Journaux de documents",
"server-down": "Impossible de se connecter au serveur OpenSign. Si vous hébergez vous-même OpenSign, veuillez vous assurer que toutes les étapes de la documentation ont été correctement suivies. Si vous exécutez OpenSign localement, vous y accédez peut-être via un numéro de port incorrect.",
"admin-exists": "L'administrateur existe déjà. Veuillez vous connecter à l'application en utilisant les informations d'identification de l'administrateur afin de gérer les utilisateurs.",
"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."
},
"form-title-1": "Paramètre du flux de documents",
"form-title-2": "Paramètre de sécurité",
"public-tour-message": "Le modèle doit être public avant que vous puissiez générer un lien partageable.",
"add-user-template": "Vous devez ajouter un rôle avant de pouvoir lui ajouter des champs. ",
"pdf-uncompatible": "Ce pdf n'est pas compatible avec opensign, veuillez contacter <support@opensignlabs.com>"
@@ -199,6 +199,10 @@ export default async function createDocumentWithTemplate(request, response) {
const enableOTP = request.body?.enableOTP;
const IsEnableOTP =
enableOTP !== undefined ? 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', {
@@ -65,6 +65,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);
@@ -176,6 +177,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);
if (parseExtUser?.TenantId?.ActiveFileAdapter) {
object.set('IsFileAdapter', true);
@@ -19,6 +19,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();
@@ -99,6 +100,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));
@@ -51,7 +51,9 @@ export default async function updateDocument(request, response) {
if (request.body?.enableOTP !== undefined) {
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 !== undefined) {
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);
object.set('IsFileAdapter', template?.IsFileAdapter || false);
let signers = template?.Signers || [];
const signerobj = {
@@ -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,
IsFileAdapter: x?.IsFileAdapter || 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();
};