mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-17 21:25:54 +02:00
Merge pull request #1302 from OpenSignLabs/react-tour
feat: add enable tour option in request signature and template form
This commit is contained in:
@@ -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")}
|
||||
|
||||
@@ -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
@@ -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={`${
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
Reference in New Issue
Block a user