mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-13 13:17:39 +02:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c522c04868 | ||
|
|
38f8561d18 | ||
|
|
10e6ab58a5 | ||
|
|
39fc2daa19 | ||
|
|
c38f59642f | ||
|
|
e9d0af7abb | ||
|
|
b39d845cd6 |
Generated
+1228
-442
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,7 @@
|
|||||||
"@react-pdf/renderer": "^4.1.6",
|
"@react-pdf/renderer": "^4.1.6",
|
||||||
"@reduxjs/toolkit": "^2.5.1",
|
"@reduxjs/toolkit": "^2.5.1",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
|
"css-minimizer-webpack-plugin": "^7.0.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"i18next": "^23.16.8",
|
"i18next": "^23.16.8",
|
||||||
"i18next-browser-languagedetector": "^8.0.2",
|
"i18next-browser-languagedetector": "^8.0.2",
|
||||||
@@ -101,7 +102,6 @@
|
|||||||
"@babel/runtime-corejs2": "^7.26.7",
|
"@babel/runtime-corejs2": "^7.26.7",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"babel-loader": "^9.2.1",
|
"babel-loader": "^9.2.1",
|
||||||
"clean-webpack-plugin": "^4.0.0",
|
|
||||||
"commitizen": "^4.3.1",
|
"commitizen": "^4.3.1",
|
||||||
"concurrently": "^9.1.2",
|
"concurrently": "^9.1.2",
|
||||||
"css-loader": "^7.1.2",
|
"css-loader": "^7.1.2",
|
||||||
|
|||||||
@@ -666,11 +666,11 @@
|
|||||||
"insufficient-credits": "Nicht genügend Signatur-Credits",
|
"insufficient-credits": "Nicht genügend Signatur-Credits",
|
||||||
"insufficient-credits-mssg": "Der Besitzer dieses Dokuments verfügt derzeit nicht über die notwendigen OpenSign-Credits, damit Sie unterzeichnen können. Bitte wenden Sie sich an den Besitzer, wenn Sie weitere Informationen benötigen.",
|
"insufficient-credits-mssg": "Der Besitzer dieses Dokuments verfügt derzeit nicht über die notwendigen OpenSign-Credits, damit Sie unterzeichnen können. Bitte wenden Sie sich an den Besitzer, wenn Sie weitere Informationen benötigen.",
|
||||||
"angular-npm-mssg-1": "Um OpenSign in Ihr Angular-Projekt zu integrieren, führen Sie einfach den folgenden Befehl aus:",
|
"angular-npm-mssg-1": "Um OpenSign in Ihr Angular-Projekt zu integrieren, führen Sie einfach den folgenden Befehl aus:",
|
||||||
"quota-mail-info-head": "Monatliches Limit für Signaturanfragen per E-Mail",
|
"quota-mail-info-head": "Monatliches E-Mail-Limit",
|
||||||
"quota-mail-info": "Sie können bis zu 15 Signaturanfragen per E-Mail pro Monat senden. Jetzt upgraden, um unbegrenzt Signaturanfragen direkt zu senden.",
|
"quota-mail-info": "Um die Servicequalität aufrechtzuerhalten und Spam zu verhindern, erlaubt OpenSign bis zu 15 E-Mails pro Monat im kostenlosen Plan. Upgraden Sie jetzt für unbegrenzten E-Mail-Versand.",
|
||||||
"quota-mail-reset": "Ihre Credits für Signaturanfragen per E-Mail werden zurückgesetzt am",
|
"quota-mail-reset": "Ihre Credits für Signaturanfragen per E-Mail werden zurückgesetzt am",
|
||||||
"quota-mail": "Sie haben Ihr monatliches Limit von 15 Signaturanfragen per E-Mail erreicht. Jetzt upgraden, um weiter E-Mails direkt zu senden.",
|
"quota-mail": "Sie haben Ihr monatliches Limit von 15 Signaturanfragen per E-Mail erreicht. Jetzt upgraden, um weiter E-Mails direkt zu senden.",
|
||||||
"quota-mail-tip": "Tipp: Sie können weiterhin <1>unbegrenzt Dokumente</1> signieren, indem Sie die Signaturanfragelinks manuell teilen.",
|
"quota-mail-tip": "Tipp: Sie können weiterhin <1>unbegrenzt Dokumente</1> signieren, indem Sie den Signaturanfragelink manuell teilen.",
|
||||||
"quota-mail-head": "Kontingent erreicht",
|
"quota-mail-head": "Kontingent erreicht",
|
||||||
"unauthorized-modal": "Sie haben keine Berechtigung, diese Aktion auszuführen. Bitte kontaktieren Sie {{adminEmail}}.",
|
"unauthorized-modal": "Sie haben keine Berechtigung, diese Aktion auszuführen. Bitte kontaktieren Sie {{adminEmail}}.",
|
||||||
"sent-this-month": "Diesen Monat gesendet",
|
"sent-this-month": "Diesen Monat gesendet",
|
||||||
@@ -833,5 +833,6 @@
|
|||||||
"variables-use": "Zu verwendende Variablen",
|
"variables-use": "Zu verwendende Variablen",
|
||||||
"send-to-sign": "hat Sie gebeten zu unterschreiben",
|
"send-to-sign": "hat Sie gebeten zu unterschreiben",
|
||||||
"use-template": "Vorlage verwenden",
|
"use-template": "Vorlage verwenden",
|
||||||
"contact-already-exists": "Der Kontakt existiert bereits."
|
"contact-already-exists": "Der Kontakt existiert bereits.",
|
||||||
|
"agreement-note": "Hinweis: Durch Ihre Zustimmung unterzeichnen Sie das Dokument nicht sofort. Sie können das Dokument nur elektronisch einsehen. Sie haben die Möglichkeit, es vollständig zu lesen und anschließend zu entscheiden, ob Sie es unterzeichnen möchten."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -667,11 +667,11 @@
|
|||||||
"insufficient-credits": "Insufficient signing credits",
|
"insufficient-credits": "Insufficient signing credits",
|
||||||
"insufficient-credits-mssg": "The owner of this document currently lacks the necessary OpenSign credits for you to sign. Please reach out to the owner if you require further details.",
|
"insufficient-credits-mssg": "The owner of this document currently lacks the necessary OpenSign credits for you to sign. Please reach out to the owner if you require further details.",
|
||||||
"angular-npm-mssg-1": "To integrate OpenSign into your Angular project, simply run the following command:",
|
"angular-npm-mssg-1": "To integrate OpenSign into your Angular project, simply run the following command:",
|
||||||
"quota-mail-info-head": "Monthly request signatures email limit",
|
"quota-mail-info-head": "Monthly Email Limit",
|
||||||
"quota-mail-info": "You can send upto 15 signature request emails every month. Upgrade now to send unlimited signing requests directly.",
|
"quota-mail-info": "To maintain service quality and prevent spam, OpenSign allows up to 15 emails per month on the free plan. Upgrade now for unlimited email sending.",
|
||||||
"quota-mail-reset": "Your signature request email credits will be reset on",
|
"quota-mail-reset": "Your signature request email credits will be reset on",
|
||||||
"quota-mail": "You've reached your limit of 15 signature request emails for this month. Upgrade now to continue sending emails directly.",
|
"quota-mail": "You've reached your limit of 15 signature request emails for this month. Upgrade now to continue sending emails directly.",
|
||||||
"quota-mail-tip": "Tip: You can still sign <1>unlimited documents</1> by manually sharing the signing request links.",
|
"quota-mail-tip": "Tip: You can still sign <1>unlimited documents</1> by manually sharing the signing request link.",
|
||||||
"quota-mail-head": "Quota reached",
|
"quota-mail-head": "Quota reached",
|
||||||
"unauthorized-modal": "You don't have permission to perform this action, please contact {{adminEmail}}.",
|
"unauthorized-modal": "You don't have permission to perform this action, please contact {{adminEmail}}.",
|
||||||
"sent-this-month": "Sent this month",
|
"sent-this-month": "Sent this month",
|
||||||
@@ -834,5 +834,6 @@
|
|||||||
"variables-use": "Variables to use",
|
"variables-use": "Variables to use",
|
||||||
"send-to-sign": "has requested you to sign",
|
"send-to-sign": "has requested you to sign",
|
||||||
"use-template": "Use Template",
|
"use-template": "Use Template",
|
||||||
"contact-already-exists": "contact already exists."
|
"contact-already-exists": "contact already exists.",
|
||||||
|
"agreement-note": "Note: Agreeing to this does not mean you are signing the document immediately. This only allows you to review the document electronically. You will have the opportunity to read it in full and decide whether to sign it afterward."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -667,11 +667,11 @@
|
|||||||
"insufficient-credits": "Créditos de firma insuficientes",
|
"insufficient-credits": "Créditos de firma insuficientes",
|
||||||
"insufficient-credits-mssg": "El propietario de este documento actualmente carece de los créditos OpenSign necesarios para que puedas firmarlo. Por favor, contacta al propietario si necesitas más detalles.",
|
"insufficient-credits-mssg": "El propietario de este documento actualmente carece de los créditos OpenSign necesarios para que puedas firmarlo. Por favor, contacta al propietario si necesitas más detalles.",
|
||||||
"angular-npm-mssg-1": "Para integrar OpenSign a tu proyecto Angular, simplemente ejecuta los siguientes comandos:",
|
"angular-npm-mssg-1": "Para integrar OpenSign a tu proyecto Angular, simplemente ejecuta los siguientes comandos:",
|
||||||
"quota-mail-info-head": "Límite mensual de solicitudes de firma por correo",
|
"quota-mail-info-head": "Límite mensual de correos electrónicos",
|
||||||
"quota-mail-info": "Puedes enviar hasta 15 solicitudes de firma por correo cada mes. Mejora ahora para enviar solicitudes de firma sin límite.",
|
"quota-mail-info": "Para mantener la calidad del servicio y prevenir el spam, OpenSign permite hasta 15 correos electrónicos por mes en el plan gratuito. Mejora tu plan ahora para envíos ilimitados de correos electrónicos.",
|
||||||
"quota-mail-reset": "Los créditos de tu correo electrónico de solicitud de firma se restablecerán el",
|
"quota-mail-reset": "Los créditos de tu correo electrónico de solicitud de firma se restablecerán el",
|
||||||
"quota-mail": "Has alcanzado tu límite de 15 solicitudes de firma por correo para este mes. Mejora ahora para continuar enviando correos.",
|
"quota-mail": "Has alcanzado tu límite de 15 solicitudes de firma por correo para este mes. Mejora ahora para continuar enviando correos.",
|
||||||
"quota-mail-tip": "Consejo: Todavía puedes solciitar la firma de <1>documentos ilimitados</1> compartiendo manualmente los enlaces de solicitud de firma.",
|
"quota-mail-tip": "Consejo: Aún puedes firmar <1>documentos ilimitados</1> compartiendo manualmente el enlace de solicitud de firma.",
|
||||||
"quota-mail-head": "Cuota alcanzada",
|
"quota-mail-head": "Cuota alcanzada",
|
||||||
"unauthorized-modal": "No tienes permisos para realizar esta acción, por favor, contacta a {{adminEmail}}.",
|
"unauthorized-modal": "No tienes permisos para realizar esta acción, por favor, contacta a {{adminEmail}}.",
|
||||||
"sent-this-month": "Enviados este mes",
|
"sent-this-month": "Enviados este mes",
|
||||||
@@ -834,5 +834,6 @@
|
|||||||
"variables-use": "Variables para usar",
|
"variables-use": "Variables para usar",
|
||||||
"send-to-sign": "le ha solicitado que firme",
|
"send-to-sign": "le ha solicitado que firme",
|
||||||
"use-template": "Usar plantilla",
|
"use-template": "Usar plantilla",
|
||||||
"contact-already-exists": "El contacto ya existe."
|
"contact-already-exists": "El contacto ya existe.",
|
||||||
|
"agreement-note": "Nota: Aceptar esto no significa que esté firmando el documento de inmediato. Esto solo le permite revisar el documento electrónicamente. Tendrá la oportunidad de leerlo en su totalidad y decidir si desea firmarlo después."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -666,11 +666,11 @@
|
|||||||
"insufficient-credits": "Crédits de signature insuffisants",
|
"insufficient-credits": "Crédits de signature insuffisants",
|
||||||
"insufficient-credits-mssg": "Le propriétaire de ce document ne dispose actuellement pas des crédits OpenSign nécessaires pour que vous puissiez le signer. Veuillez contacter le propriétaire si vous avez besoin de plus de détails.",
|
"insufficient-credits-mssg": "Le propriétaire de ce document ne dispose actuellement pas des crédits OpenSign nécessaires pour que vous puissiez le signer. Veuillez contacter le propriétaire si vous avez besoin de plus de détails.",
|
||||||
"angular-npm-mssg-1": "Pour intégrer OpenSign dans votre projet Angular, exécutez simplement la commande suivante :",
|
"angular-npm-mssg-1": "Pour intégrer OpenSign dans votre projet Angular, exécutez simplement la commande suivante :",
|
||||||
"quota-mail-info-head": "Limite mensuelle d'e-mails de signatures de demandes",
|
"quota-mail-info-head": "Limite mensuelle d'e-mails",
|
||||||
"quota-mail-info": "Vous pouvez envoyer jusqu'à 15 e-mails de demande de signature chaque mois. Mettez à niveau maintenant pour envoyer directement des demandes de signature illimitées.",
|
"quota-mail-info": "Pour maintenir la qualité du service et prévenir le spam, OpenSign permet jusqu'à 15 e-mails par mois avec le plan gratuit. Passez à l'offre supérieure pour un envoi illimité d'e-mails.",
|
||||||
"quota-mail-reset": "Les crédits de votre email de demande de signature seront réinitialisés le",
|
"quota-mail-reset": "Les crédits de votre email de demande de signature seront réinitialisés le",
|
||||||
"quota-mail": "Vous avez atteint votre limite de 15 e-mails de demande de signature pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.",
|
"quota-mail": "Vous avez atteint votre limite de 15 e-mails de demande de signature pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.",
|
||||||
"quota-mail-tip-tip": "Astuce : Vous pouvez toujours signer un nombre <1>illimité de documents</1> en partageant manuellement les liens de demande de signature.",
|
"quota-mail-tip-tip": "Astuce: Vous pouvez toujours signer un nombre <1>illimité de documents</1> en partageant manuellement le lien de demande de signature.",
|
||||||
"quota-mail-head": "Quota atteint",
|
"quota-mail-head": "Quota atteint",
|
||||||
"unauthorized-modal": "Vous n'êtes pas autorisé à effectuer cette action, veuillez contacter {{adminEmail}}.",
|
"unauthorized-modal": "Vous n'êtes pas autorisé à effectuer cette action, veuillez contacter {{adminEmail}}.",
|
||||||
"sent-this-month": "envoyé ce mois-ci",
|
"sent-this-month": "envoyé ce mois-ci",
|
||||||
@@ -833,5 +833,7 @@
|
|||||||
"variables-use": "Variables à utiliser",
|
"variables-use": "Variables à utiliser",
|
||||||
"send-to-sign": "vous a demandé de signer",
|
"send-to-sign": "vous a demandé de signer",
|
||||||
"use-template": "Utiliser le modèle",
|
"use-template": "Utiliser le modèle",
|
||||||
"contact-already-exists": "Le contact existe déjà."
|
"contact-already-exists": "Le contact existe déjà.",
|
||||||
|
"agreement-note": "Remarque : Accepter cela ne signifie pas que vous signez immédiatement le document. Cela vous permet uniquement de consulter le document électroniquement. Vous aurez l'opportunité de le lire entièrement et de décider ensuite si vous souhaitez le signer."
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -666,11 +666,11 @@
|
|||||||
"insufficient-credits": "Crediti di firma insufficienti",
|
"insufficient-credits": "Crediti di firma insufficienti",
|
||||||
"insufficient-credits-mssg": "Il proprietario di questo documento non dispone attualmente dei crediti OpenSign necessari affinché tu possa firmare. Contatta il proprietario per ulteriori dettagli.",
|
"insufficient-credits-mssg": "Il proprietario di questo documento non dispone attualmente dei crediti OpenSign necessari affinché tu possa firmare. Contatta il proprietario per ulteriori dettagli.",
|
||||||
"angular-npm-mssg-1": "Per integrare OpenSign nel tuo progetto Angular, esegui semplicemente il seguente comando:",
|
"angular-npm-mssg-1": "Per integrare OpenSign nel tuo progetto Angular, esegui semplicemente il seguente comando:",
|
||||||
"quota-mail-info-head": "Limite mensile email per richieste di firma",
|
"quota-mail-info-head": "Limite mensile di email",
|
||||||
"quota-mail-info": "Puoi inviare fino a 15 email di richiesta di firma ogni mese. Passa al piano superiore per inviare richieste di firma illimitate direttamente.",
|
"quota-mail-info": "Per mantenere la qualità del servizio e prevenire lo spam, OpenSign consente fino a 15 email al mese con il piano gratuito. Esegui l'upgrade ora per l'invio illimitato di email.",
|
||||||
"quota-mail-reset": "I tuoi crediti email per richieste di firma saranno ripristinati il",
|
"quota-mail-reset": "I tuoi crediti email per richieste di firma saranno ripristinati il",
|
||||||
"quota-mail": "Hai raggiunto il limite di 15 email di richiesta di firma per questo mese. Passa al piano superiore per continuare a inviare email direttamente.",
|
"quota-mail": "Hai raggiunto il limite di 15 email di richiesta di firma per questo mese. Passa al piano superiore per continuare a inviare email direttamente.",
|
||||||
"quota-mail-tip": "Suggerimento: Puoi comunque firmare <1>documenti illimitati</1> condividendo manualmente i link per le richieste di firma.",
|
"quota-mail-tip": "Suggerimento: Puoi ancora firmare un numero <1>illimitato de documenti</1> condividendo manualmente il link della richiesta di firma.",
|
||||||
"quota-mail-head": "Quota Raggiunta",
|
"quota-mail-head": "Quota Raggiunta",
|
||||||
"unauthorized-modal": "Non hai l'autorizzazione per eseguire questa azione, contatta {{adminEmail}}.",
|
"unauthorized-modal": "Non hai l'autorizzazione per eseguire questa azione, contatta {{adminEmail}}.",
|
||||||
"sent-this-month": "Inviati questo mese",
|
"sent-this-month": "Inviati questo mese",
|
||||||
@@ -833,5 +833,6 @@
|
|||||||
"variables-use": "Variabili da utilizzare",
|
"variables-use": "Variabili da utilizzare",
|
||||||
"send-to-sign": "ha richiesto la tua firma",
|
"send-to-sign": "ha richiesto la tua firma",
|
||||||
"use-template": "Usa modello",
|
"use-template": "Usa modello",
|
||||||
"contact-already-exists": "Il contatto esiste già."
|
"contact-already-exists": "Il contatto esiste già.",
|
||||||
|
"agreement-note": "Nota: Accettare questo non significa che stai firmando immediatamente il documento. Questo ti consente solo di esaminare il documento elettronicamente. Avrai l'opportunità di leggerlo per intero e decidere successivamente se firmarlo."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const BulkSendUi = (props) => {
|
|||||||
const [scrollOnNextUpdate, setScrollOnNextUpdate] = useState(false);
|
const [scrollOnNextUpdate, setScrollOnNextUpdate] = useState(false);
|
||||||
const [isSubmit, setIsSubmit] = useState(false);
|
const [isSubmit, setIsSubmit] = useState(false);
|
||||||
const [isSignatureExist, setIsSignatureExist] = useState();
|
const [isSignatureExist, setIsSignatureExist] = useState();
|
||||||
const [isBulkAvailable, setIsBulkAvailable] = useState(false);
|
const [isDisableBulkSend, setIsDisableBulkSend] = useState(false);
|
||||||
const [isLoader, setIsLoader] = useState(false);
|
const [isLoader, setIsLoader] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
signatureExist();
|
signatureExist();
|
||||||
@@ -22,7 +22,7 @@ const BulkSendUi = (props) => {
|
|||||||
|
|
||||||
//function to check atleast one signature field exist
|
//function to check atleast one signature field exist
|
||||||
const signatureExist = async () => {
|
const signatureExist = async () => {
|
||||||
setIsBulkAvailable(true);
|
setIsDisableBulkSend(false);
|
||||||
const getPlaceholder = props?.Placeholders;
|
const getPlaceholder = props?.Placeholders;
|
||||||
const checkIsSignatureExistt = getPlaceholder?.every((placeholderObj) =>
|
const checkIsSignatureExistt = getPlaceholder?.every((placeholderObj) =>
|
||||||
placeholderObj?.placeHolder?.some((holder) =>
|
placeholderObj?.placeHolder?.some((holder) =>
|
||||||
@@ -95,70 +95,70 @@ const BulkSendUi = (props) => {
|
|||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setIsSubmit(true);
|
setIsSubmit(true);
|
||||||
if (validateEmails(forms)) {
|
if (validateEmails(forms)) {
|
||||||
// Create a copy of Placeholders array from props.item
|
// Create a copy of Placeholders array from props.item
|
||||||
let Placeholders = [...props.Placeholders];
|
let Placeholders = [...props.Placeholders];
|
||||||
// Initialize an empty array to store updated documents
|
// Initialize an empty array to store updated documents
|
||||||
let Documents = [];
|
let Documents = [];
|
||||||
// Loop through each form
|
// Loop through each form
|
||||||
forms.forEach((form) => {
|
forms.forEach((form) => {
|
||||||
//checking if user enter email which already exist as a signer then add user in a signers array
|
//checking if user enter email which already exist as a signer then add user in a signers array
|
||||||
let existSigner = [];
|
let existSigner = [];
|
||||||
form.fields.map((data) => {
|
form.fields.map((data) => {
|
||||||
if (data.signer) {
|
if (data.signer) {
|
||||||
existSigner.push(data.signer);
|
existSigner.push(data.signer);
|
||||||
}
|
|
||||||
});
|
|
||||||
// Map through the copied Placeholders array to update email values
|
|
||||||
const updatedPlaceholders = Placeholders.map((placeholder) => {
|
|
||||||
// Find the field in the current form that matches the placeholder Id
|
|
||||||
const field = form.fields.find(
|
|
||||||
(element) => parseInt(element.fieldId) === placeholder.Id
|
|
||||||
);
|
|
||||||
// If a matching field is found, update the email value in the placeholder
|
|
||||||
const signer = field?.signer?.objectId ? field.signer : "";
|
|
||||||
if (field) {
|
|
||||||
if (signer) {
|
|
||||||
return {
|
|
||||||
...placeholder,
|
|
||||||
signerObjId: field?.signer?.objectId || "",
|
|
||||||
signerPtr: signer
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
...placeholder,
|
|
||||||
email: field.email,
|
|
||||||
signerObjId: field?.signer?.objectId || "",
|
|
||||||
signerPtr: signer
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
// If no matching field is found, keep the placeholder as is
|
// Map through the copied Placeholders array to update email values
|
||||||
return placeholder;
|
const updatedPlaceholders = Placeholders.map((placeholder) => {
|
||||||
});
|
// Find the field in the current form that matches the placeholder Id
|
||||||
|
const field = form.fields.find(
|
||||||
|
(element) => parseInt(element.fieldId) === placeholder.Id
|
||||||
|
);
|
||||||
|
// If a matching field is found, update the email value in the placeholder
|
||||||
|
const signer = field?.signer?.objectId ? field.signer : "";
|
||||||
|
if (field) {
|
||||||
|
if (signer) {
|
||||||
|
return {
|
||||||
|
...placeholder,
|
||||||
|
signerObjId: field?.signer?.objectId || "",
|
||||||
|
signerPtr: signer
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
...placeholder,
|
||||||
|
email: field.email,
|
||||||
|
signerObjId: field?.signer?.objectId || "",
|
||||||
|
signerPtr: signer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If no matching field is found, keep the placeholder as is
|
||||||
|
return placeholder;
|
||||||
|
});
|
||||||
|
|
||||||
// Push a new document object with updated Placeholders into the Documents array
|
// Push a new document object with updated Placeholders into the Documents array
|
||||||
if (existSigner?.length > 0) {
|
if (existSigner?.length > 0) {
|
||||||
Documents.push({
|
Documents.push({
|
||||||
...props.item,
|
...props.item,
|
||||||
Placeholders: updatedPlaceholders,
|
Placeholders: updatedPlaceholders,
|
||||||
Signers: props.item.Signers
|
Signers: props.item.Signers
|
||||||
? [...props.item.Signers, ...existSigner]
|
? [...props.item.Signers, ...existSigner]
|
||||||
: [...existSigner]
|
: [...existSigner]
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Documents.push({
|
Documents.push({
|
||||||
...props.item,
|
...props.item,
|
||||||
Placeholders: updatedPlaceholders,
|
Placeholders: updatedPlaceholders,
|
||||||
SignatureType: props.signatureType
|
SignatureType: props.signatureType
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await batchQuery(Documents);
|
await batchQuery(Documents);
|
||||||
} else {
|
} else {
|
||||||
setIsSubmit(false);
|
setIsSubmit(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const batchQuery = async (Documents) => {
|
const batchQuery = async (Documents) => {
|
||||||
@@ -199,7 +199,7 @@ const BulkSendUi = (props) => {
|
|||||||
<Loader />
|
<Loader />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{isBulkAvailable ? (
|
{!isDisableBulkSend ? (
|
||||||
<>
|
<>
|
||||||
{props.Placeholders?.length > 0 ? (
|
{props.Placeholders?.length > 0 ? (
|
||||||
isSignatureExist ? (
|
isSignatureExist ? (
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ function AgreementSign(props) {
|
|||||||
{t("agrre-button")}
|
{t("agrre-button")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mt-2">
|
||||||
|
<span className="text-[11px]">{t("agreement-note")}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{isShowAgreeTerms && (
|
{isShowAgreeTerms && (
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ const EditTemplate = ({
|
|||||||
: false,
|
: false,
|
||||||
Bcc: template?.Bcc,
|
Bcc: template?.Bcc,
|
||||||
RedirectUrl: template?.RedirectUrl || "",
|
RedirectUrl: template?.RedirectUrl || "",
|
||||||
AllowModifications: template?.AllowModifications || false
|
AllowModifications: template?.AllowModifications || false,
|
||||||
|
TimeToCompleteDays: template?.TimeToCompleteDays || 15
|
||||||
});
|
});
|
||||||
|
|
||||||
// `isValidURL` is used to check valid webhook url
|
// `isValidURL` is used to check valid webhook url
|
||||||
@@ -228,14 +229,13 @@ const EditTemplate = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs mt-3">
|
<div className="text-xs mt-3">
|
||||||
<label
|
<label>
|
||||||
>
|
|
||||||
{t("notify-on-signatures")}
|
{t("notify-on-signatures")}
|
||||||
<a data-tooltip-id="nos-tooltip" className="ml-1">
|
<a data-tooltip-id="nos-tooltip" className="ml-1">
|
||||||
<sup>
|
<sup>
|
||||||
<i className="fa-light fa-question rounded-full border-[#33bbff] text-[#33bbff] text-[13px] border-[1px] py-[1.5px] px-[4px]"></i>
|
<i className="fa-light fa-question rounded-full border-[#33bbff] text-[#33bbff] text-[13px] border-[1px] py-[1.5px] px-[4px]"></i>
|
||||||
</sup>
|
</sup>
|
||||||
</a>
|
</a>{" "}
|
||||||
<Tooltip id="nos-tooltip" className="z-[999]">
|
<Tooltip id="nos-tooltip" className="z-[999]">
|
||||||
<div className="max-w-[200px] md:max-w-[450px] text-[11px]">
|
<div className="max-w-[200px] md:max-w-[450px] text-[11px]">
|
||||||
<p className="font-bold">{t("notify-on-signatures")}</p>
|
<p className="font-bold">{t("notify-on-signatures")}</p>
|
||||||
@@ -247,7 +247,7 @@ const EditTemplate = ({
|
|||||||
<div className="flex flex-col md:flex-row md:gap-4">
|
<div className="flex flex-col md:flex-row md:gap-4">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
"flex items-center gap-2 ml-2 mb-1"
|
`flex items-center gap-2 ml-2 mb-1`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
@@ -260,7 +260,7 @@ const EditTemplate = ({
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
"flex items-center gap-2 ml-2 mb-1"
|
`flex items-center gap-2 ml-2 mb-1`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
@@ -294,6 +294,22 @@ const EditTemplate = ({
|
|||||||
onInput={(e) => e.target.setCustomValidity("")}
|
onInput={(e) => e.target.setCustomValidity("")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<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 className="mt-[1rem] flex justify-start">
|
<div className="mt-[1rem] flex justify-start">
|
||||||
<button type="submit" className="op-btn op-btn-primary">
|
<button type="submit" className="op-btn op-btn-primary">
|
||||||
{t("submit")}
|
{t("submit")}
|
||||||
|
|||||||
@@ -125,10 +125,7 @@ function Placeholder(props) {
|
|||||||
const [clickonWidget, setClickonWidget] = useState({});
|
const [clickonWidget, setClickonWidget] = useState({});
|
||||||
const [startDate, setStartDate] = useState(
|
const [startDate, setStartDate] = useState(
|
||||||
props.pos.type === "date" &&
|
props.pos.type === "date" &&
|
||||||
getDefaultdate(
|
getDefaultdate(new Date(), props.pos?.options?.validation?.format)
|
||||||
props?.pos?.options?.response,
|
|
||||||
props.pos?.options?.validation?.format
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
const [getCheckboxRenderWidth, setGetCheckboxRenderWidth] = useState({
|
const [getCheckboxRenderWidth, setGetCheckboxRenderWidth] = useState({
|
||||||
width: null,
|
width: null,
|
||||||
@@ -785,7 +782,8 @@ function Placeholder(props) {
|
|||||||
//enable dragging functionality only if isAlllowModify true on tab that widget and hold 1sec
|
//enable dragging functionality only if isAlllowModify true on tab that widget and hold 1sec
|
||||||
if (
|
if (
|
||||||
props.isAlllowModify &&
|
props.isAlllowModify &&
|
||||||
props?.assignedWidgetId.includes(props.pos.key)
|
props?.assignedWidgetId.includes(props.pos.key) &&
|
||||||
|
props.data?.signerObjId === props.signerObjId
|
||||||
) {
|
) {
|
||||||
//if 'isTouchDevice' then handle dragging functionality conditionaly
|
//if 'isTouchDevice' then handle dragging functionality conditionaly
|
||||||
if (isTouchDevice) {
|
if (isTouchDevice) {
|
||||||
@@ -797,7 +795,8 @@ function Placeholder(props) {
|
|||||||
} else if (
|
} else if (
|
||||||
//condition when 'isAlllowModify' is true and user add new widgets then handle dragging functionality like signyourself flow
|
//condition when 'isAlllowModify' is true and user add new widgets then handle dragging functionality like signyourself flow
|
||||||
props.isAlllowModify &&
|
props.isAlllowModify &&
|
||||||
!props?.assignedWidgetId.includes(props.pos.key)
|
!props?.assignedWidgetId.includes(props.pos.key) &&
|
||||||
|
props.data?.signerObjId === props.signerObjId
|
||||||
) {
|
) {
|
||||||
return !isDraggingEnabled;
|
return !isDraggingEnabled;
|
||||||
} else {
|
} else {
|
||||||
@@ -808,8 +807,10 @@ function Placeholder(props) {
|
|||||||
else if (props.isPlaceholder && ![textWidget].includes(props.pos.type)) {
|
else if (props.isPlaceholder && ![textWidget].includes(props.pos.type)) {
|
||||||
return false;
|
return false;
|
||||||
} //dragging depend on 'isDraggingEnabled' variable in self sign and signyourself flow
|
} //dragging depend on 'isDraggingEnabled' variable in self sign and signyourself flow
|
||||||
else {
|
else if (isTouchDevice) {
|
||||||
return !isDraggingEnabled;
|
return !isDraggingEnabled;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//function to handle widget background color
|
//function to handle widget background color
|
||||||
@@ -868,183 +869,93 @@ function Placeholder(props) {
|
|||||||
}
|
}
|
||||||
}, 1000); // Hold for 1 second before vibrating
|
}, 1000); // Hold for 1 second before vibrating
|
||||||
};
|
};
|
||||||
|
const fontSize = calculateFont(props.pos.options?.fontSize);
|
||||||
|
const fontColor = props.pos.options?.fontColor || "black";
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Rnd
|
{/* Check if a text widget (prefill type) exists. Once the user enters a value and clicks outside or the widget becomes non-selectable, it should appear as plain text (just like embedded text in a document). When the user clicks on the text again, it should become editable. */}
|
||||||
id={props.pos.key}
|
{props.pos?.options?.response &&
|
||||||
data-tut={props.pos.key === props.unSignedWidgetId ? "IsSigned" : ""}
|
props.pos.key !== props.selectWidgetId &&
|
||||||
key={props.pos.key}
|
props.pos.type === textWidget ? (
|
||||||
lockAspectRatio={
|
<span
|
||||||
!props.isFreeResize &&
|
onClick={() => {
|
||||||
![
|
props.setSelectWidgetId && props.setSelectWidgetId(props.pos.key);
|
||||||
textWidget,
|
}}
|
||||||
"email",
|
|
||||||
"name",
|
|
||||||
"company",
|
|
||||||
"job title",
|
|
||||||
textInputWidget
|
|
||||||
].includes(props.pos.type) &&
|
|
||||||
(props.pos.Width
|
|
||||||
? props.pos.Width / props.pos.Height
|
|
||||||
: defaultWidthHeight(props.pos.type).width /
|
|
||||||
defaultWidthHeight(props.pos.type).height)
|
|
||||||
}
|
|
||||||
enableResizing={{
|
|
||||||
top: false,
|
|
||||||
right: false,
|
|
||||||
bottom: false,
|
|
||||||
left: false,
|
|
||||||
topRight: false,
|
|
||||||
bottomRight:
|
|
||||||
props.data && props.isNeedSign
|
|
||||||
? props.data?.signerObjId === props.signerObjId &&
|
|
||||||
props.pos.type !== "checkbox" &&
|
|
||||||
props.pos.type !== radioButtonWidget
|
|
||||||
? true
|
|
||||||
: false
|
|
||||||
: props.pos.type !== radioButtonWidget &&
|
|
||||||
props.pos.type !== "checkbox" &&
|
|
||||||
props.pos.key === props.selectWidgetId &&
|
|
||||||
true,
|
|
||||||
bottomLeft: false,
|
|
||||||
topLeft: false
|
|
||||||
}}
|
|
||||||
bounds="parent"
|
|
||||||
className="signYourselfBlock"
|
|
||||||
style={{
|
|
||||||
border: "1px solid #007bff",
|
|
||||||
borderRadius: "2px",
|
|
||||||
cursor: getCursor(),
|
|
||||||
zIndex:
|
|
||||||
props.pos.type === "date"
|
|
||||||
? props.pos.key === props.selectWidgetId
|
|
||||||
? 99 + 1
|
|
||||||
: 99
|
|
||||||
: props?.pos?.zIndex
|
|
||||||
? props.pos.zIndex
|
|
||||||
: "5",
|
|
||||||
opacity:
|
|
||||||
props.isNeedSign && props.data?.Id !== props?.uniqueId && "0.4",
|
|
||||||
background: handleBackground()
|
|
||||||
}}
|
|
||||||
onDrag={() => {
|
|
||||||
setDraggingEnabled(true);
|
|
||||||
props.handleTabDrag && props.handleTabDrag(props.pos.key);
|
|
||||||
}}
|
|
||||||
size={{
|
|
||||||
width:
|
|
||||||
props.pos.type === radioButtonWidget ||
|
|
||||||
props.pos.type === "checkbox"
|
|
||||||
? "auto"
|
|
||||||
: props.posWidth(props.pos, props.isSignYourself),
|
|
||||||
height:
|
|
||||||
props.pos.type === radioButtonWidget ||
|
|
||||||
props.pos.type === "checkbox"
|
|
||||||
? "auto"
|
|
||||||
: props.posHeight(props.pos, props.isSignYourself)
|
|
||||||
}}
|
|
||||||
minHeight={calculateFont(props.pos.options?.fontSize, true)}
|
|
||||||
maxHeight="auto"
|
|
||||||
onResizeStart={() => {
|
|
||||||
setDraggingEnabled(true);
|
|
||||||
props.setIsResize && props.setIsResize(true);
|
|
||||||
}}
|
|
||||||
onResizeStop={(e, direction, ref) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
props.setIsResize && props.setIsResize(false);
|
|
||||||
}, 50);
|
|
||||||
props.handleSignYourselfImageResize &&
|
|
||||||
props.handleSignYourselfImageResize(
|
|
||||||
ref,
|
|
||||||
props.pos.key,
|
|
||||||
props.xyPosition,
|
|
||||||
props.setXyPosition,
|
|
||||||
props.index,
|
|
||||||
containerScale,
|
|
||||||
props.scale,
|
|
||||||
props.data && props.data.Id,
|
|
||||||
props.isResize
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
disableDragging={handleDragging()}
|
|
||||||
onDragStop={(event, dragElement) => {
|
|
||||||
setIsDisableDragging(true);
|
|
||||||
props.handleStop &&
|
|
||||||
props.handleStop(
|
|
||||||
event,
|
|
||||||
dragElement,
|
|
||||||
props.data?.Id,
|
|
||||||
props.pos?.key
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
position={{
|
|
||||||
x: xPos(props.pos, props.isSignYourself),
|
|
||||||
y: yPos(props.pos, props.isSignYourself)
|
|
||||||
}}
|
|
||||||
onResize={(e, direction, ref) => {
|
|
||||||
setPlaceholderBorder({
|
|
||||||
w: ref.offsetWidth / (props.scale * containerScale),
|
|
||||||
h: ref.offsetHeight / (props.scale * containerScale)
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
// onClick={() =>
|
|
||||||
// !props.isResize && !isMobile && handleOnClickPlaceholder()
|
|
||||||
// }
|
|
||||||
>
|
|
||||||
{props.pos.key === props.selectWidgetId &&
|
|
||||||
((props.isShowBorder &&
|
|
||||||
![radioButtonWidget, "checkbox"].includes(props.pos.type)) ||
|
|
||||||
(props?.isAlllowModify &&
|
|
||||||
!props?.assignedWidgetId.includes(props.pos.key))) ? (
|
|
||||||
<BorderResize
|
|
||||||
right={-12}
|
|
||||||
top={-11}
|
|
||||||
pos={props.pos}
|
|
||||||
posHeight={props.posHeight}
|
|
||||||
isSignYourself={props.isSignYourself || props.isSelfSign}
|
|
||||||
/>
|
|
||||||
) : props.data && props.isNeedSign && props.pos.type !== "checkbox" ? (
|
|
||||||
props.data?.signerObjId === props.signerObjId &&
|
|
||||||
![radioButtonWidget, "checkbox"].includes(props.pos.type) ? (
|
|
||||||
<BorderResize
|
|
||||||
posHeight={props.posHeight}
|
|
||||||
isSignYourself={props.isSignYourself || props.isSelfSign}
|
|
||||||
pos={props.pos}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
![radioButtonWidget, "checkbox"].includes(props.pos.type) &&
|
|
||||||
props.pos.key === props.selectWidgetId && <BorderResize />
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 1- Show a border if props.pos.key === props.selectWidgetId, indicating the current user's selected widget.
|
|
||||||
2- If props.isShowBorder is true, display borders for all widgets.
|
|
||||||
3- Use the combination of props?.isAlllowModify and !props?.assignedWidgetId.includes(props.pos.key) to determine when to show borders:
|
|
||||||
1- When isAlllowModify is true, show borders.
|
|
||||||
2- Do not display border for widgets already assigned (props.assignedWidgetId.includes(props.pos.key) is true).
|
|
||||||
*/}
|
|
||||||
{props.pos.key === props.selectWidgetId &&
|
|
||||||
(props.isShowBorder ||
|
|
||||||
!isDisableDragging ||
|
|
||||||
(props?.isAlllowModify &&
|
|
||||||
!props?.assignedWidgetId.includes(props.pos.key))) && (
|
|
||||||
<PlaceholderBorder
|
|
||||||
setDraggingEnabled={setDraggingEnabled}
|
|
||||||
pos={props.pos}
|
|
||||||
isPlaceholder={props.isPlaceholder}
|
|
||||||
getCheckboxRenderWidth={getCheckboxRenderWidth}
|
|
||||||
scale={props.scale}
|
|
||||||
containerScale={containerScale}
|
|
||||||
placeholderBorder={placeholderBorder}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<div
|
|
||||||
className="flex items-stretch justify-center"
|
|
||||||
style={{
|
style={{
|
||||||
|
fontFamily: "Arial, sans-serif",
|
||||||
|
position: "absolute",
|
||||||
left: xPos(props.pos, props.isSignYourself),
|
left: xPos(props.pos, props.isSignYourself),
|
||||||
top: yPos(props.pos, props.isSignYourself),
|
top: yPos(props.pos, props.isSignYourself),
|
||||||
|
fontSize: fontSize,
|
||||||
|
color: fontColor,
|
||||||
|
zIndex: 99
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.pos?.options?.response}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<Rnd
|
||||||
|
id={props.pos.key}
|
||||||
|
data-tut={props.pos.key === props.unSignedWidgetId ? "IsSigned" : ""}
|
||||||
|
key={props.pos.key}
|
||||||
|
lockAspectRatio={
|
||||||
|
!props.isFreeResize &&
|
||||||
|
![
|
||||||
|
textWidget,
|
||||||
|
"email",
|
||||||
|
"name",
|
||||||
|
"company",
|
||||||
|
"job title",
|
||||||
|
textInputWidget
|
||||||
|
].includes(props.pos.type) &&
|
||||||
|
(props.pos.Width
|
||||||
|
? props.pos.Width / props.pos.Height
|
||||||
|
: defaultWidthHeight(props.pos.type).width /
|
||||||
|
defaultWidthHeight(props.pos.type).height)
|
||||||
|
}
|
||||||
|
enableResizing={{
|
||||||
|
top: false,
|
||||||
|
right: false,
|
||||||
|
bottom: false,
|
||||||
|
left: false,
|
||||||
|
topRight: false,
|
||||||
|
bottomRight:
|
||||||
|
props.data && props.isNeedSign
|
||||||
|
? props.data?.signerObjId === props.signerObjId &&
|
||||||
|
props.pos.type !== "checkbox" &&
|
||||||
|
props.pos.type !== radioButtonWidget
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
: props.pos.type !== radioButtonWidget &&
|
||||||
|
props.pos.type !== "checkbox" &&
|
||||||
|
props.pos.key === props.selectWidgetId &&
|
||||||
|
true,
|
||||||
|
bottomLeft: false,
|
||||||
|
topLeft: false
|
||||||
|
}}
|
||||||
|
bounds="parent"
|
||||||
|
className="signYourselfBlock"
|
||||||
|
style={{
|
||||||
|
border: "1px solid #007bff",
|
||||||
|
borderRadius: "2px",
|
||||||
|
cursor: getCursor(),
|
||||||
|
zIndex:
|
||||||
|
props.pos.type === "date"
|
||||||
|
? props.pos.key === props.selectWidgetId
|
||||||
|
? 99 + 1
|
||||||
|
: 99
|
||||||
|
: props?.pos?.zIndex
|
||||||
|
? props.pos.zIndex
|
||||||
|
: "5",
|
||||||
|
opacity:
|
||||||
|
props.isNeedSign && props.data?.Id !== props?.uniqueId && "0.4",
|
||||||
|
background: handleBackground()
|
||||||
|
}}
|
||||||
|
onDrag={() => {
|
||||||
|
setDraggingEnabled(true);
|
||||||
|
props.handleTabDrag && props.handleTabDrag(props.pos.key);
|
||||||
|
}}
|
||||||
|
size={{
|
||||||
width:
|
width:
|
||||||
props.pos.type === radioButtonWidget ||
|
props.pos.type === radioButtonWidget ||
|
||||||
props.pos.type === "checkbox"
|
props.pos.type === "checkbox"
|
||||||
@@ -1054,40 +965,157 @@ function Placeholder(props) {
|
|||||||
props.pos.type === radioButtonWidget ||
|
props.pos.type === radioButtonWidget ||
|
||||||
props.pos.type === "checkbox"
|
props.pos.type === "checkbox"
|
||||||
? "auto"
|
? "auto"
|
||||||
: props.posHeight(props.pos, props.isSignYourself),
|
: props.posHeight(props.pos, props.isSignYourself)
|
||||||
zIndex: "10"
|
|
||||||
}}
|
}}
|
||||||
onTouchEnd={() => handleTouchEnd()}
|
minHeight={calculateFont(props.pos.options?.fontSize, true)}
|
||||||
onClick={() => handleOnClickPlaceholder()}
|
maxHeight="auto"
|
||||||
onTouchStart={() => handleTouchStart()}
|
onResizeStart={() => {
|
||||||
|
setDraggingEnabled(true);
|
||||||
|
props.setIsResize && props.setIsResize(true);
|
||||||
|
}}
|
||||||
|
onResizeStop={(e, direction, ref) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
props.setIsResize && props.setIsResize(false);
|
||||||
|
}, 50);
|
||||||
|
props.handleSignYourselfImageResize &&
|
||||||
|
props.handleSignYourselfImageResize(
|
||||||
|
ref,
|
||||||
|
props.pos.key,
|
||||||
|
props.xyPosition,
|
||||||
|
props.setXyPosition,
|
||||||
|
props.index,
|
||||||
|
containerScale,
|
||||||
|
props.scale,
|
||||||
|
props.data && props.data.Id,
|
||||||
|
props.isResize
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
disableDragging={handleDragging()}
|
||||||
|
onDragStop={(event, dragElement) => {
|
||||||
|
setIsDisableDragging(true);
|
||||||
|
props.handleStop &&
|
||||||
|
props.handleStop(
|
||||||
|
event,
|
||||||
|
dragElement,
|
||||||
|
props.data?.Id,
|
||||||
|
props.pos?.key
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
position={{
|
||||||
|
x: xPos(props.pos, props.isSignYourself),
|
||||||
|
y: yPos(props.pos, props.isSignYourself)
|
||||||
|
}}
|
||||||
|
onResize={(e, direction, ref) => {
|
||||||
|
setPlaceholderBorder({
|
||||||
|
w: ref.offsetWidth / (props.scale * containerScale),
|
||||||
|
h: ref.offsetHeight / (props.scale * containerScale)
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
// onClick={() =>
|
||||||
|
// !props.isResize && !isMobile && handleOnClickPlaceholder()
|
||||||
|
// }
|
||||||
>
|
>
|
||||||
{props.pos.key === props.selectWidgetId && <PlaceholderIcon />}
|
{props.pos.key === props.selectWidgetId &&
|
||||||
<PlaceholderType
|
((props.isShowBorder &&
|
||||||
pos={props.pos}
|
![radioButtonWidget, "checkbox"].includes(props.pos.type)) ||
|
||||||
xyPosition={props.xyPosition}
|
(props?.isAlllowModify &&
|
||||||
index={props.index}
|
!props?.assignedWidgetId.includes(props.pos.key))) ? (
|
||||||
setXyPosition={props.setXyPosition}
|
<BorderResize
|
||||||
data={props.data}
|
right={-12}
|
||||||
setSignKey={props.setSignKey}
|
top={-11}
|
||||||
isShowDropdown={props?.isShowDropdown}
|
pos={props.pos}
|
||||||
isPlaceholder={props.isPlaceholder}
|
posHeight={props.posHeight}
|
||||||
isSignYourself={props.isSignYourself}
|
isSignYourself={props.isSignYourself || props.isSelfSign}
|
||||||
isSelfSign={props.isSelfSign}
|
/>
|
||||||
signerObjId={props.signerObjId}
|
) : props.data &&
|
||||||
handleUserName={props.handleUserName}
|
props.isNeedSign &&
|
||||||
pdfDetails={props?.pdfDetails && props?.pdfDetails[0]}
|
props.pos.type !== "checkbox" ? (
|
||||||
isNeedSign={props.isNeedSign}
|
props.data?.signerObjId === props.signerObjId &&
|
||||||
setSelectDate={setSelectDate}
|
![radioButtonWidget, "checkbox"].includes(props.pos.type) ? (
|
||||||
selectDate={selectDate}
|
<BorderResize
|
||||||
setValidateAlert={props.setValidateAlert}
|
posHeight={props.posHeight}
|
||||||
setStartDate={setStartDate}
|
isSignYourself={props.isSignYourself || props.isSelfSign}
|
||||||
startDate={startDate}
|
pos={props.pos}
|
||||||
handleSaveDate={handleSaveDate}
|
/>
|
||||||
xPos={props.xPos}
|
) : (
|
||||||
calculateFont={calculateFont}
|
<></>
|
||||||
/>
|
)
|
||||||
</div>
|
) : (
|
||||||
</Rnd>
|
![radioButtonWidget, "checkbox"].includes(props.pos.type) &&
|
||||||
|
props.pos.key === props.selectWidgetId && <BorderResize />
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 1- Show a border if props.pos.key === props.selectWidgetId, indicating the current user's selected widget.
|
||||||
|
2- If props.isShowBorder is true, display borders for all widgets.
|
||||||
|
3- Use the combination of props?.isAlllowModify and !props?.assignedWidgetId.includes(props.pos.key) to determine when to show borders:
|
||||||
|
1- When isAlllowModify is true, show borders.
|
||||||
|
2- Do not display border for widgets already assigned (props.assignedWidgetId.includes(props.pos.key) is true).
|
||||||
|
*/}
|
||||||
|
{props.pos.key === props.selectWidgetId &&
|
||||||
|
(props.isShowBorder ||
|
||||||
|
!isDisableDragging ||
|
||||||
|
(props?.isAlllowModify &&
|
||||||
|
!props?.assignedWidgetId.includes(props.pos.key))) && (
|
||||||
|
<PlaceholderBorder
|
||||||
|
setDraggingEnabled={setDraggingEnabled}
|
||||||
|
pos={props.pos}
|
||||||
|
isPlaceholder={props.isPlaceholder}
|
||||||
|
getCheckboxRenderWidth={getCheckboxRenderWidth}
|
||||||
|
scale={props.scale}
|
||||||
|
containerScale={containerScale}
|
||||||
|
placeholderBorder={placeholderBorder}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
className="flex items-stretch justify-center"
|
||||||
|
style={{
|
||||||
|
left: xPos(props.pos, props.isSignYourself),
|
||||||
|
top: yPos(props.pos, props.isSignYourself),
|
||||||
|
width:
|
||||||
|
props.pos.type === radioButtonWidget ||
|
||||||
|
props.pos.type === "checkbox"
|
||||||
|
? "auto"
|
||||||
|
: props.posWidth(props.pos, props.isSignYourself),
|
||||||
|
height:
|
||||||
|
props.pos.type === radioButtonWidget ||
|
||||||
|
props.pos.type === "checkbox"
|
||||||
|
? "auto"
|
||||||
|
: props.posHeight(props.pos, props.isSignYourself),
|
||||||
|
zIndex: "10"
|
||||||
|
}}
|
||||||
|
onTouchEnd={() => handleTouchEnd()}
|
||||||
|
onClick={() => handleOnClickPlaceholder()}
|
||||||
|
onTouchStart={() => handleTouchStart()}
|
||||||
|
>
|
||||||
|
{props.pos.key === props.selectWidgetId && <PlaceholderIcon />}
|
||||||
|
<PlaceholderType
|
||||||
|
pos={props.pos}
|
||||||
|
xyPosition={props.xyPosition}
|
||||||
|
index={props.index}
|
||||||
|
setXyPosition={props.setXyPosition}
|
||||||
|
data={props.data}
|
||||||
|
setSignKey={props.setSignKey}
|
||||||
|
isShowDropdown={props?.isShowDropdown}
|
||||||
|
isPlaceholder={props.isPlaceholder}
|
||||||
|
isSignYourself={props.isSignYourself}
|
||||||
|
isSelfSign={props.isSelfSign}
|
||||||
|
signerObjId={props.signerObjId}
|
||||||
|
handleUserName={props.handleUserName}
|
||||||
|
pdfDetails={props?.pdfDetails && props?.pdfDetails[0]}
|
||||||
|
isNeedSign={props.isNeedSign}
|
||||||
|
setSelectDate={setSelectDate}
|
||||||
|
selectDate={selectDate}
|
||||||
|
setValidateAlert={props.setValidateAlert}
|
||||||
|
setStartDate={setStartDate}
|
||||||
|
startDate={startDate}
|
||||||
|
handleSaveDate={handleSaveDate}
|
||||||
|
xPos={props.xPos}
|
||||||
|
calculateFont={calculateFont}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Rnd>
|
||||||
|
)}
|
||||||
|
|
||||||
<ModalUi isOpen={isDateModal} title={t("widget-info")} showClose={false}>
|
<ModalUi isOpen={isDateModal} title={t("widget-info")} showClose={false}>
|
||||||
<div className="h-[100%] p-[20px]">
|
<div className="h-[100%] p-[20px]">
|
||||||
<div className="flex flex-row items-center">
|
<div className="flex flex-row items-center">
|
||||||
|
|||||||
@@ -513,10 +513,14 @@ function PlaceholderType(props) {
|
|||||||
})}
|
})}
|
||||||
</select>
|
</select>
|
||||||
) : (
|
) : (
|
||||||
<div style={textWidgetStyle} className="select-none-cls">
|
<div
|
||||||
|
style={textWidgetStyle}
|
||||||
|
className="select-none-cls flex justify-between items-center"
|
||||||
|
>
|
||||||
{props.pos?.options?.name
|
{props.pos?.options?.name
|
||||||
? props.pos.options.name
|
? props.pos.options.name
|
||||||
: widgetTypeTraslation}
|
: widgetTypeTraslation}
|
||||||
|
<i className="fa-light fa-circle-chevron-down mr-1 "></i>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
case "initials":
|
case "initials":
|
||||||
@@ -672,12 +676,7 @@ function PlaceholderType(props) {
|
|||||||
onBlur={handleInputBlur}
|
onBlur={handleInputBlur}
|
||||||
closeOnScroll={true}
|
closeOnScroll={true}
|
||||||
className={`${selectWidgetCls} outline-[#007bff]`}
|
className={`${selectWidgetCls} outline-[#007bff]`}
|
||||||
selected={
|
selected={props?.startDate}
|
||||||
props?.startDate
|
|
||||||
? props?.startDate
|
|
||||||
: props.pos.options?.response &&
|
|
||||||
new Date(props.pos.options.response)
|
|
||||||
}
|
|
||||||
onChange={(date) => handleOnDateChange(date)}
|
onChange={(date) => handleOnDateChange(date)}
|
||||||
popperPlacement="top-end"
|
popperPlacement="top-end"
|
||||||
customInput={<ExampleCustomInput />}
|
customInput={<ExampleCustomInput />}
|
||||||
|
|||||||
@@ -14,53 +14,53 @@ function TextFontSetting(props) {
|
|||||||
handleClose={() => props.setIsTextSetting(false)}
|
handleClose={() => props.setIsTextSetting(false)}
|
||||||
>
|
>
|
||||||
<div className="h-full p-[20px]">
|
<div className="h-full p-[20px]">
|
||||||
<div className="flex items-center">
|
<div className="flex flex-col md:flex-row md:items-center gap-3">
|
||||||
<span>{t("font-size")} :</span>
|
{/* Font Size Selector */}
|
||||||
<select
|
<div className="flex items-center gap-2">
|
||||||
className="ml-[7px] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
<span className="whitespace-nowrap">{t("font-size")}:</span>
|
||||||
value={
|
<select
|
||||||
props.fontSize ||
|
className="ml-[7px] w-[60%] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
||||||
props.currWidgetsDetails?.options?.fontSize ||
|
value={
|
||||||
12
|
props.fontSize ||
|
||||||
}
|
props.currWidgetsDetails?.options?.fontSize ||
|
||||||
onChange={(e) => {
|
12
|
||||||
props.setFontSize(parseInt(e.target.value));
|
}
|
||||||
}}
|
onChange={(e) => props.setFontSize(parseInt(e.target.value))}
|
||||||
>
|
>
|
||||||
{fontsizeArr.map((size, ind) => {
|
{fontsizeArr.map((size, ind) => (
|
||||||
return (
|
<option key={ind} className="text-[13px]" value={size}>
|
||||||
<option className="text-[13px]" value={size} key={ind}>
|
|
||||||
{size}
|
{size}
|
||||||
</option>
|
</option>
|
||||||
);
|
))}
|
||||||
})}
|
</select>
|
||||||
</select>
|
</div>
|
||||||
<div className="flex flex-row gap-1 items-center ml-4">
|
{/* Font Color Selector */}
|
||||||
<span>{t("color")}: </span>
|
<div className="flex items-center">
|
||||||
|
<span className="whitespace-nowrap">{t("color")}:</span>
|
||||||
<select
|
<select
|
||||||
|
className="ml-[33px] md:ml-4 w-[65%] md:w-[full] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
||||||
value={
|
value={
|
||||||
props.fontColor ||
|
props.fontColor ||
|
||||||
props.currWidgetsDetails?.options?.fontColor ||
|
props.currWidgetsDetails?.options?.fontColor ||
|
||||||
"black"
|
"black"
|
||||||
}
|
}
|
||||||
onChange={(e) => props.setFontColor(e.target.value)}
|
onChange={(e) => props.setFontColor(e.target.value)}
|
||||||
className="ml-[7px] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
|
||||||
>
|
>
|
||||||
{fontColorArr.map((color, ind) => {
|
{fontColorArr.map((color, ind) => (
|
||||||
return (
|
<option key={ind} value={color}>
|
||||||
<option value={color} key={ind}>
|
{t(`color-type.${color}`)}
|
||||||
{t(`color-type.${color}`)}
|
</option>
|
||||||
</option>
|
))}
|
||||||
);
|
|
||||||
})}
|
|
||||||
</select>
|
</select>
|
||||||
|
{/* Color Preview Box */}
|
||||||
<span
|
<span
|
||||||
|
className="w-5 h-5 ml-2 rounded border border-gray-300"
|
||||||
style={{
|
style={{
|
||||||
background:
|
backgroundColor:
|
||||||
props.fontColor ||
|
props.fontColor ||
|
||||||
props.currWidgetsDetails?.options?.fontColor
|
props.currWidgetsDetails?.options?.fontColor ||
|
||||||
|
"black"
|
||||||
}}
|
}}
|
||||||
className="w-5 h-[19px] ml-1"
|
|
||||||
></span>
|
></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -293,24 +293,26 @@ const WidgetNameModal = (props) => {
|
|||||||
"job title",
|
"job title",
|
||||||
"email"
|
"email"
|
||||||
].includes(props.defaultdata?.type) && (
|
].includes(props.defaultdata?.type) && (
|
||||||
<div className="flex items-center mb-[0.75rem]">
|
<div className="flex flex-col md:flex-row md:items-center gap-3 mb-3">
|
||||||
<span>{t("font-size")}:</span>
|
<div className="flex items-center gap-2 ">
|
||||||
<select
|
<span>{t("font-size")}:</span>
|
||||||
className="ml-[7px] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
<select
|
||||||
value={
|
className="ml-[7px] w-[60%] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
||||||
props.fontSize || props.defaultdata?.options?.fontSize || 12
|
value={
|
||||||
}
|
props.fontSize || props.defaultdata?.options?.fontSize || 12
|
||||||
onChange={(e) => props.setFontSize(parseInt(e.target.value))}
|
}
|
||||||
>
|
onChange={(e) => props.setFontSize(parseInt(e.target.value))}
|
||||||
{fontsizeArr.map((size, ind) => {
|
>
|
||||||
return (
|
{fontsizeArr.map((size, ind) => {
|
||||||
<option className="text-[13px]" value={size} key={ind}>
|
return (
|
||||||
{size}
|
<option className="text-[13px]" value={size} key={ind}>
|
||||||
</option>
|
{size}
|
||||||
);
|
</option>
|
||||||
})}
|
);
|
||||||
</select>
|
})}
|
||||||
<div className="flex flex-row gap-1 items-center ml-4">
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center">
|
||||||
<span>{t("color")}: </span>
|
<span>{t("color")}: </span>
|
||||||
<select
|
<select
|
||||||
value={
|
value={
|
||||||
@@ -319,7 +321,7 @@ const WidgetNameModal = (props) => {
|
|||||||
"black"
|
"black"
|
||||||
}
|
}
|
||||||
onChange={(e) => props.setFontColor(e.target.value)}
|
onChange={(e) => props.setFontColor(e.target.value)}
|
||||||
className="ml-[7px] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
className="ml-[33px] md:ml-4 w-[65%] md:w-[full] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
|
||||||
>
|
>
|
||||||
{fontColorArr.map((color, ind) => {
|
{fontColorArr.map((color, ind) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -491,7 +491,7 @@ export const signPdfFun = async (
|
|||||||
documentId,
|
documentId,
|
||||||
signerObjectId,
|
signerObjectId,
|
||||||
objectId,
|
objectId,
|
||||||
widgets
|
widgets,
|
||||||
) => {
|
) => {
|
||||||
let isCustomCompletionMail = false;
|
let isCustomCompletionMail = false;
|
||||||
try {
|
try {
|
||||||
@@ -632,6 +632,7 @@ export const createDocument = async (
|
|||||||
IsEnableOTP: Doc?.IsEnableOTP || false,
|
IsEnableOTP: Doc?.IsEnableOTP || false,
|
||||||
IsTourEnabled: Doc?.IsTourEnabled || false,
|
IsTourEnabled: Doc?.IsTourEnabled || false,
|
||||||
AllowModifications: Doc?.AllowModifications || false,
|
AllowModifications: Doc?.AllowModifications || false,
|
||||||
|
TimeToCompleteDays: parseInt(Doc?.TimeToCompleteDays) || 15,
|
||||||
...SignatureType,
|
...SignatureType,
|
||||||
...NotifyOnSignatures,
|
...NotifyOnSignatures,
|
||||||
...Bcc,
|
...Bcc,
|
||||||
|
|||||||
@@ -360,10 +360,6 @@ const Forms = (props) => {
|
|||||||
object.set("Description", formData?.Description);
|
object.set("Description", formData?.Description);
|
||||||
object.set("Note", formData?.Note);
|
object.set("Note", formData?.Note);
|
||||||
if (props.title === "Request Signatures") {
|
if (props.title === "Request Signatures") {
|
||||||
object.set(
|
|
||||||
"TimeToCompleteDays",
|
|
||||||
parseInt(formData?.TimeToCompleteDays)
|
|
||||||
);
|
|
||||||
if (
|
if (
|
||||||
extUserData?.TenantId?.RequestBody &&
|
extUserData?.TenantId?.RequestBody &&
|
||||||
extUserData?.TenantId?.RequestSubject
|
extUserData?.TenantId?.RequestSubject
|
||||||
@@ -380,6 +376,10 @@ const Forms = (props) => {
|
|||||||
object.set("AutomaticReminders", formData.autoreminder);
|
object.set("AutomaticReminders", formData.autoreminder);
|
||||||
object.set("RemindOnceInEvery", parseInt(formData.remindOnceInEvery));
|
object.set("RemindOnceInEvery", parseInt(formData.remindOnceInEvery));
|
||||||
object.set("IsTourEnabled", isTourEnabled);
|
object.set("IsTourEnabled", isTourEnabled);
|
||||||
|
object.set(
|
||||||
|
"TimeToCompleteDays",
|
||||||
|
parseInt(formData?.TimeToCompleteDays)
|
||||||
|
);
|
||||||
object.set("AllowModifications", false);
|
object.set("AllowModifications", false);
|
||||||
object.set("IsEnableOTP", false);
|
object.set("IsEnableOTP", false);
|
||||||
if (formData.NotifyOnSignatures !== undefined) {
|
if (formData.NotifyOnSignatures !== undefined) {
|
||||||
@@ -449,11 +449,6 @@ const Forms = (props) => {
|
|||||||
setFileUpload("");
|
setFileUpload("");
|
||||||
setpercentage(0);
|
setpercentage(0);
|
||||||
navigate(`/${props?.redirectRoute}/${res.id}`);
|
navigate(`/${props?.redirectRoute}/${res.id}`);
|
||||||
setIsAlert((obj) => ({
|
|
||||||
...obj,
|
|
||||||
type: "success",
|
|
||||||
message: `${props.msgVar} created successfully!`
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("err ", err);
|
console.log("err ", err);
|
||||||
@@ -991,7 +986,7 @@ const Forms = (props) => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<div className="overflow-y-auto z-[40] transition-all">
|
<div className="overflow-y-auto z-[40] transition-all">
|
||||||
{props.title === "Request Signatures" && (
|
{props.title !== "Sign yourself" && (
|
||||||
<div className="text-xs mt-2">
|
<div className="text-xs mt-2">
|
||||||
<label className="block">
|
<label className="block">
|
||||||
{t("time-to-complete")}
|
{t("time-to-complete")}
|
||||||
@@ -1123,11 +1118,7 @@ const Forms = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs mt-3">
|
<div className="text-xs mt-3">
|
||||||
<label
|
<label className="block">
|
||||||
className={
|
|
||||||
"block"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{t("notify-on-signatures")}
|
{t("notify-on-signatures")}
|
||||||
<a data-tooltip-id="nos-tooltip" className="ml-1">
|
<a data-tooltip-id="nos-tooltip" className="ml-1">
|
||||||
<sup>
|
<sup>
|
||||||
@@ -1147,7 +1138,7 @@ const Forms = (props) => {
|
|||||||
<div className="flex flex-col md:flex-row md:gap-4">
|
<div className="flex flex-col md:flex-row md:gap-4">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
"flex items-center gap-2 ml-2 mb-1"
|
`flex items-center gap-2 ml-2 mb-1`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
@@ -1160,7 +1151,7 @@ const Forms = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
"flex items-center gap-2 ml-2 mb-1"
|
`flex items-center gap-2 ml-2 mb-1`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
|
|||||||
@@ -453,35 +453,9 @@ function PdfRequestFiles(
|
|||||||
setRequestSignTour(true);
|
setRequestSignTour(true);
|
||||||
} else {
|
} else {
|
||||||
const isEnableOTP = documentData?.[0]?.IsEnableOTP || false;
|
const isEnableOTP = documentData?.[0]?.IsEnableOTP || false;
|
||||||
if (!isEnableOTP) {
|
const sessionToken = localStorage.getItem("accesstoken");
|
||||||
try {
|
if (sessionToken) {
|
||||||
const resContact = await axios.post(
|
//condition to check current user exist in contracts_Users class and check tour message status
|
||||||
`${localStorage.getItem("baseUrl")}functions/getcontact`,
|
|
||||||
{ contactId: currUserId },
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const contact = resContact?.data?.result;
|
|
||||||
setContractName("_Contactbook");
|
|
||||||
setSignerUserId(contact?.objectId);
|
|
||||||
const tourData = contact?.TourStatus && contact?.TourStatus;
|
|
||||||
if (tourData && tourData.length > 0) {
|
|
||||||
const checkTourRequest =
|
|
||||||
tourData?.some((data) => data?.requestSign) || false;
|
|
||||||
setTourStatus(tourData);
|
|
||||||
setRequestSignTour(checkTourRequest);
|
|
||||||
} else {
|
|
||||||
setRequestSignTour(false);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.log("err while getting tourstatus", err);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//else condition to check current user exist in contracts_Users class and check tour message status
|
|
||||||
//if not then check user exist in contracts_Contactbook class and check tour message status
|
//if not then check user exist in contracts_Contactbook class and check tour message status
|
||||||
const res = await contractUsers();
|
const res = await contractUsers();
|
||||||
if (res === "Error: Something went wrong!") {
|
if (res === "Error: Something went wrong!") {
|
||||||
@@ -538,6 +512,33 @@ function PdfRequestFiles(
|
|||||||
setHandleError(t("user-not-exist"));
|
setHandleError(t("user-not-exist"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (!isEnableOTP) {
|
||||||
|
try {
|
||||||
|
const resContact = await axios.post(
|
||||||
|
`${localStorage.getItem("baseUrl")}functions/getcontact`,
|
||||||
|
{ contactId: currUserId },
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const contact = resContact?.data?.result;
|
||||||
|
setContractName("_Contactbook");
|
||||||
|
setSignerUserId(contact?.objectId);
|
||||||
|
const tourData = contact?.TourStatus && contact?.TourStatus;
|
||||||
|
if (tourData && tourData.length > 0) {
|
||||||
|
const checkTourRequest =
|
||||||
|
tourData?.some((data) => data?.requestSign) || false;
|
||||||
|
setTourStatus(tourData);
|
||||||
|
setRequestSignTour(checkTourRequest);
|
||||||
|
} else {
|
||||||
|
setRequestSignTour(false);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("err while getting tourstatus", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setIsUiLoading(false);
|
setIsUiLoading(false);
|
||||||
|
|||||||
@@ -246,12 +246,15 @@ function PlaceHolderSign() {
|
|||||||
if (documentData && documentData.length > 0) {
|
if (documentData && documentData.length > 0) {
|
||||||
if (documentData[0]?.Placeholders?.length > 0) {
|
if (documentData[0]?.Placeholders?.length > 0) {
|
||||||
const signerNotExist = documentData[0]?.Placeholders.some(
|
const signerNotExist = documentData[0]?.Placeholders.some(
|
||||||
(data) => !data.signerObjId
|
(data) => !data.signerObjId && data.Role !== "prefill"
|
||||||
);
|
);
|
||||||
//condition to check any role does not attach signer
|
//condition to check any role does not attach signer
|
||||||
if (signerNotExist) {
|
if (signerNotExist) {
|
||||||
|
const filterPrefill = documentData[0]?.Placeholders?.filter(
|
||||||
|
(x) => x.Role !== "prefill"
|
||||||
|
);
|
||||||
let users = [];
|
let users = [];
|
||||||
documentData[0]?.Placeholders?.forEach((element) => {
|
filterPrefill?.forEach((element) => {
|
||||||
let label = "";
|
let label = "";
|
||||||
const signerData = documentData[0]?.Signers.find(
|
const signerData = documentData[0]?.Signers.find(
|
||||||
(x) => element.signerObjId && element.signerObjId === x.objectId
|
(x) => element.signerObjId && element.signerObjId === x.objectId
|
||||||
@@ -272,6 +275,7 @@ function PlaceHolderSign() {
|
|||||||
setForms(users);
|
setForms(users);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = documentData[0] && documentData[0]?.URL;
|
const url = documentData[0] && documentData[0]?.URL;
|
||||||
//convert document url in array buffer format to use embed widgets in pdf using pdf-lib
|
//convert document url in array buffer format to use embed widgets in pdf using pdf-lib
|
||||||
const arrayBuffer = await convertPdfArrayBuffer(url);
|
const arrayBuffer = await convertPdfArrayBuffer(url);
|
||||||
@@ -1003,7 +1007,7 @@ function PlaceHolderSign() {
|
|||||||
docCls.set("URL", pdfUrl);
|
docCls.set("URL", pdfUrl);
|
||||||
}
|
}
|
||||||
const res = await docCls.save();
|
const res = await docCls.save();
|
||||||
if (res) {
|
if (res && pdfUrl) {
|
||||||
pdfDetails[0] = { ...pdfDetails[0], URL: pdfUrl };
|
pdfDetails[0] = { ...pdfDetails[0], URL: pdfUrl };
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -1058,31 +1062,24 @@ function PlaceHolderSign() {
|
|||||||
if (updateExpiryDate) {
|
if (updateExpiryDate) {
|
||||||
data["ExpiryDate"] = { iso: updateExpiryDate, __type: "Date" };
|
data["ExpiryDate"] = { iso: updateExpiryDate, __type: "Date" };
|
||||||
}
|
}
|
||||||
await axios
|
await axios.put(
|
||||||
.put(
|
`${localStorage.getItem(
|
||||||
`${localStorage.getItem(
|
"baseUrl"
|
||||||
"baseUrl"
|
)}classes/contracts_Document/${documentId}`,
|
||||||
)}classes/contracts_Document/${documentId}`,
|
data,
|
||||||
data,
|
{
|
||||||
{
|
headers: {
|
||||||
headers: {
|
"Content-Type": "application/json",
|
||||||
"Content-Type": "application/json",
|
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
.then(() => {
|
);
|
||||||
setIsMailSend(true);
|
setIsMailSend(true);
|
||||||
setIsLoading({ isLoad: false });
|
setIsLoading({ isLoad: false });
|
||||||
setIsUiLoading(false);
|
setIsUiLoading(false);
|
||||||
setSignerPos([]);
|
setSignerPos([]);
|
||||||
setIsSendAlert({ mssg: "confirm", alert: true });
|
setIsSendAlert({ mssg: "confirm", alert: true });
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log("axois err ", err);
|
|
||||||
alert(t("something-went-wrong-mssg"));
|
|
||||||
});
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("error", e);
|
console.log("error", e);
|
||||||
alert(t("something-went-wrong-mssg"));
|
alert(t("something-went-wrong-mssg"));
|
||||||
@@ -1934,7 +1931,9 @@ function PlaceHolderSign() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleDisable = () => {
|
const handleDisable = () => {
|
||||||
const isAllSigner = signerPos.some((x) => !x.signerObjId);
|
const isAllSigner = signerPos.some(
|
||||||
|
(x) => !x.signerObjId && x.Role !== "prefill"
|
||||||
|
);
|
||||||
return isAllSigner;
|
return isAllSigner;
|
||||||
};
|
};
|
||||||
const handleCloseAttachSigner = () => {
|
const handleCloseAttachSigner = () => {
|
||||||
@@ -2133,7 +2132,7 @@ function PlaceHolderSign() {
|
|||||||
{pdfDetails[0].SendinOrder ? (
|
{pdfDetails[0].SendinOrder ? (
|
||||||
<p>
|
<p>
|
||||||
{t("placeholder-mail-alert", {
|
{t("placeholder-mail-alert", {
|
||||||
name: pdfDetails[0]?.Signers[0]?.Name
|
name: signersdata[0]?.Name
|
||||||
})}
|
})}
|
||||||
</p>
|
</p>
|
||||||
) : (
|
) : (
|
||||||
@@ -2217,7 +2216,7 @@ function PlaceHolderSign() {
|
|||||||
<>
|
<>
|
||||||
{/* grid grid-cols-1 md:grid-cols-2 */}
|
{/* grid grid-cols-1 md:grid-cols-2 */}
|
||||||
<div className="min-h-max max-h-[250px] overflow-y-auto">
|
<div className="min-h-max max-h-[250px] overflow-y-auto">
|
||||||
<div className="p-3 op-card border-[1px] border-gray-400 mt-3 mx-4 mb-4 bg-base-200 text-base-content flex flex-col gap-2 relative">
|
<div className="py-3 px-[10px] op-card border-[1px] border-gray-400 mt-3 md:mx-3 mb-4 bg-base-200 text-base-content flex flex-col gap-2 relative">
|
||||||
{forms?.map((field, id) => {
|
{forms?.map((field, id) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -2225,7 +2224,7 @@ function PlaceHolderSign() {
|
|||||||
key={field?.value}
|
key={field?.value}
|
||||||
>
|
>
|
||||||
<label>{field?.role}</label>
|
<label>{field?.role}</label>
|
||||||
<div className="flex justify-between items-center gap-2">
|
<div className="flex justify-between items-center gap-1">
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<AsyncSelect
|
<AsyncSelect
|
||||||
cacheOptions
|
cacheOptions
|
||||||
|
|||||||
@@ -410,11 +410,7 @@ const Preferences = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-[0.75rem]">
|
<div className="mb-[0.75rem]">
|
||||||
<label
|
<label className="text-[14px] mb-[0.7rem] font-medium">
|
||||||
className={
|
|
||||||
"text-[14px] mb-[0.7rem] font-medium"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{t("notify-on-signatures")}
|
{t("notify-on-signatures")}
|
||||||
<a data-tooltip-id="nos-tooltip" className="ml-1">
|
<a data-tooltip-id="nos-tooltip" className="ml-1">
|
||||||
<sup>
|
<sup>
|
||||||
|
|||||||
@@ -791,7 +791,7 @@ function SignYourSelf() {
|
|||||||
pdfFile: base64Url,
|
pdfFile: base64Url,
|
||||||
docId: documentId,
|
docId: documentId,
|
||||||
isCustomCompletionMail: isCustomCompletionMail,
|
isCustomCompletionMail: isCustomCompletionMail,
|
||||||
signature: suffixbase64
|
signature: suffixbase64,
|
||||||
};
|
};
|
||||||
const resSignPdf = await Parse.Cloud.run("signPdf", params);
|
const resSignPdf = await Parse.Cloud.run("signPdf", params);
|
||||||
if (resSignPdf) {
|
if (resSignPdf) {
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import Tour from "reactour";
|
|||||||
import SignerListPlace from "../components/pdf/SignerListPlace";
|
import SignerListPlace from "../components/pdf/SignerListPlace";
|
||||||
import Header from "../components/pdf/PdfHeader";
|
import Header from "../components/pdf/PdfHeader";
|
||||||
import WidgetNameModal from "../components/pdf/WidgetNameModal";
|
import WidgetNameModal from "../components/pdf/WidgetNameModal";
|
||||||
|
import { PDFDocument } from "pdf-lib";
|
||||||
|
import { SaveFileSize } from "../constant/saveFileSize";
|
||||||
import {
|
import {
|
||||||
pdfNewWidthFun,
|
pdfNewWidthFun,
|
||||||
contractUsers,
|
contractUsers,
|
||||||
@@ -34,7 +36,9 @@ import {
|
|||||||
handleSignatureType,
|
handleSignatureType,
|
||||||
getBase64FromUrl,
|
getBase64FromUrl,
|
||||||
convertPdfArrayBuffer,
|
convertPdfArrayBuffer,
|
||||||
generatePdfName
|
generatePdfName,
|
||||||
|
textWidget,
|
||||||
|
multiSignEmbed
|
||||||
} from "../constant/Utils";
|
} from "../constant/Utils";
|
||||||
import RenderPdf from "../components/pdf/RenderPdf";
|
import RenderPdf from "../components/pdf/RenderPdf";
|
||||||
import "../styles/AddUser.css";
|
import "../styles/AddUser.css";
|
||||||
@@ -132,6 +136,9 @@ const TemplatePlaceholder = () => {
|
|||||||
const [scale, setScale] = useState(1);
|
const [scale, setScale] = useState(1);
|
||||||
const [signatureType, setSignatureType] = useState([]);
|
const [signatureType, setSignatureType] = useState([]);
|
||||||
const [pdfArrayBuffer, setPdfArrayBuffer] = useState("");
|
const [pdfArrayBuffer, setPdfArrayBuffer] = useState("");
|
||||||
|
const [updatedPdfUrl, setUpdatedPdfUrl] = useState("");
|
||||||
|
const [tempSignerId, setTempSignerId] = useState("");
|
||||||
|
const [unSignedWidgetId, setUnSignedWidgetId] = useState("");
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchTemplate();
|
fetchTemplate();
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
@@ -238,9 +245,22 @@ const TemplatePlaceholder = () => {
|
|||||||
documentData[0].Placeholders &&
|
documentData[0].Placeholders &&
|
||||||
documentData[0].Placeholders.length > 0
|
documentData[0].Placeholders.length > 0
|
||||||
) {
|
) {
|
||||||
setSignerPos(documentData[0].Placeholders);
|
const placeholder = documentData[0]?.Placeholders.filter(
|
||||||
|
(data) => data.Role !== "prefill"
|
||||||
|
);
|
||||||
|
setSignerPos(placeholder);
|
||||||
|
signersdata.forEach((x) => {
|
||||||
|
if (x.objectId) {
|
||||||
|
const obj = {
|
||||||
|
__type: "Pointer",
|
||||||
|
className: "contracts_Contactbook",
|
||||||
|
objectId: x.objectId
|
||||||
|
};
|
||||||
|
signers.push(obj);
|
||||||
|
}
|
||||||
|
});
|
||||||
let signers = [...documentData[0].Signers];
|
let signers = [...documentData[0].Signers];
|
||||||
let updatedSigners = documentData[0].Placeholders.map((x) => {
|
let updatedSigners = placeholder.map((x) => {
|
||||||
let matchingSigner = signers.find(
|
let matchingSigner = signers.find(
|
||||||
(y) => x.signerObjId && x.signerObjId === y.objectId
|
(y) => x.signerObjId && x.signerObjId === y.objectId
|
||||||
);
|
);
|
||||||
@@ -275,10 +295,13 @@ const TemplatePlaceholder = () => {
|
|||||||
documentData[0].Placeholders &&
|
documentData[0].Placeholders &&
|
||||||
documentData[0].Placeholders.length > 0
|
documentData[0].Placeholders.length > 0
|
||||||
) {
|
) {
|
||||||
let updatedSigners = documentData[0].Placeholders.map((x) => {
|
const placeholder = documentData[0]?.Placeholders.filter(
|
||||||
|
(data) => data.Role !== "prefill"
|
||||||
|
);
|
||||||
|
let updatedSigners = placeholder.map((x) => {
|
||||||
return { Role: x.Role, Id: x.Id, blockColor: x.blockColor };
|
return { Role: x.Role, Id: x.Id, blockColor: x.blockColor };
|
||||||
});
|
});
|
||||||
setSignerPos(documentData[0].Placeholders);
|
setSignerPos(placeholder);
|
||||||
setUniqueId(updatedSigners[0].Id);
|
setUniqueId(updatedSigners[0].Id);
|
||||||
setSignersData(updatedSigners);
|
setSignersData(updatedSigners);
|
||||||
setIsSelectId(0);
|
setIsSelectId(0);
|
||||||
@@ -353,7 +376,8 @@ const TemplatePlaceholder = () => {
|
|||||||
const widgetHeight =
|
const widgetHeight =
|
||||||
defaultWidthHeight(dragTypeValue).height * containerScale;
|
defaultWidthHeight(dragTypeValue).height * containerScale;
|
||||||
let dropData = [],
|
let dropData = [],
|
||||||
currentPagePosition;
|
currentPagePosition,
|
||||||
|
filterSignerPos;
|
||||||
let placeHolder;
|
let placeHolder;
|
||||||
if (item === "onclick") {
|
if (item === "onclick") {
|
||||||
// `getBoundingClientRect()` is used to get accurate measurement height of the div
|
// `getBoundingClientRect()` is used to get accurate measurement height of the div
|
||||||
@@ -406,7 +430,11 @@ const TemplatePlaceholder = () => {
|
|||||||
dropData.push(dropObj);
|
dropData.push(dropObj);
|
||||||
placeHolder = { pageNumber: pageNumber, pos: dropData };
|
placeHolder = { pageNumber: pageNumber, pos: dropData };
|
||||||
}
|
}
|
||||||
let filterSignerPos = signerPos.find((data) => data.Id === uniqueId);
|
if (dragTypeValue === textWidget) {
|
||||||
|
filterSignerPos = signerPos.find((data) => data.Role === "prefill");
|
||||||
|
} else {
|
||||||
|
filterSignerPos = signerPos.find((data) => data.Id === uniqueId);
|
||||||
|
}
|
||||||
const getPlaceHolder = filterSignerPos?.placeHolder;
|
const getPlaceHolder = filterSignerPos?.placeHolder;
|
||||||
if (getPlaceHolder) {
|
if (getPlaceHolder) {
|
||||||
//checking exist placeholder on same page
|
//checking exist placeholder on same page
|
||||||
@@ -423,20 +451,53 @@ const TemplatePlaceholder = () => {
|
|||||||
const newSignPos = getPos.concat(dropData);
|
const newSignPos = getPos.concat(dropData);
|
||||||
let xyPos = { pageNumber: pageNumber, pos: newSignPos };
|
let xyPos = { pageNumber: pageNumber, pos: newSignPos };
|
||||||
updatePlace.push(xyPos);
|
updatePlace.push(xyPos);
|
||||||
const updatesignerPos = signerPos.map((x) =>
|
let updatesignerPos;
|
||||||
x.Id === uniqueId ? { ...x, placeHolder: updatePlace } : x
|
if (dragTypeValue === textWidget) {
|
||||||
);
|
updatesignerPos = signerPos.map((x) =>
|
||||||
|
x.Role === "prefill" ? { ...x, placeHolder: updatePlace } : x
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
updatesignerPos = signerPos.map((x) =>
|
||||||
|
x.Id === uniqueId ? { ...x, placeHolder: updatePlace } : x
|
||||||
|
);
|
||||||
|
}
|
||||||
setSignerPos(updatesignerPos);
|
setSignerPos(updatesignerPos);
|
||||||
} else {
|
} else {
|
||||||
//else condition to add placeholder widgets on multiple page first time
|
//if condition when widget type is prefill label text widget
|
||||||
const updatesignerPos = signerPos.map((x) =>
|
if (dragTypeValue === textWidget) {
|
||||||
x.Id === uniqueId && x?.placeHolder
|
//check text widgets data (prefill) already exist then and want to add text widget on new page
|
||||||
? { ...x, placeHolder: [...x.placeHolder, placeHolder] }
|
//create new page entry with old data and update placeholder
|
||||||
: x.Id === uniqueId
|
if (filterSignerPos) {
|
||||||
? { ...x, placeHolder: [placeHolder] }
|
const addPrefillData =
|
||||||
: x
|
filterSignerPos && filterSignerPos?.placeHolder;
|
||||||
);
|
addPrefillData.push(placeHolder);
|
||||||
setSignerPos(updatesignerPos);
|
const updatePrefillPos = signerPos.map((x) =>
|
||||||
|
x.Role === "prefill" ? { ...x, placeHolder: addPrefillData } : x
|
||||||
|
);
|
||||||
|
setSignerPos(updatePrefillPos);
|
||||||
|
} //else condition if user do not have any text widget data
|
||||||
|
else {
|
||||||
|
const prefillTextWidget = {
|
||||||
|
signerPtr: {},
|
||||||
|
signerObjId: "",
|
||||||
|
blockColor: "#f58f8c",
|
||||||
|
placeHolder: [placeHolder],
|
||||||
|
Role: "prefill",
|
||||||
|
Id: key
|
||||||
|
};
|
||||||
|
setSignerPos((prev) => [...prev, prefillTextWidget]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//else condition to add placeholder widgets on multiple page first time
|
||||||
|
const updatesignerPos = signerPos.map((x) =>
|
||||||
|
x.Id === uniqueId && x?.placeHolder
|
||||||
|
? { ...x, placeHolder: [...x.placeHolder, placeHolder] }
|
||||||
|
: x.Id === uniqueId
|
||||||
|
? { ...x, placeHolder: [placeHolder] }
|
||||||
|
: x
|
||||||
|
);
|
||||||
|
setSignerPos(updatesignerPos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dragTypeValue === "dropdown") {
|
if (dragTypeValue === "dropdown") {
|
||||||
@@ -446,9 +507,14 @@ const TemplatePlaceholder = () => {
|
|||||||
} else if (dragTypeValue === radioButtonWidget) {
|
} else if (dragTypeValue === radioButtonWidget) {
|
||||||
setIsRadio(true);
|
setIsRadio(true);
|
||||||
} else if (
|
} else if (
|
||||||
[textInputWidget, "name", "company", "job title", "email"].includes(
|
[
|
||||||
dragTypeValue
|
textInputWidget,
|
||||||
)
|
textWidget,
|
||||||
|
"name",
|
||||||
|
"company",
|
||||||
|
"job title",
|
||||||
|
"email"
|
||||||
|
].includes(dragTypeValue)
|
||||||
) {
|
) {
|
||||||
setFontSize(12);
|
setFontSize(12);
|
||||||
setFontColor("black");
|
setFontColor("black");
|
||||||
@@ -509,20 +575,22 @@ const TemplatePlaceholder = () => {
|
|||||||
containerWH
|
containerWH
|
||||||
);
|
);
|
||||||
if (keyValue >= 0) {
|
if (keyValue >= 0) {
|
||||||
const filterSignerPos = updateSignPos.filter(
|
let filterSignerPos;
|
||||||
(data) => data.Id === signId
|
if (signId) {
|
||||||
);
|
filterSignerPos = updateSignPos.filter((data) => data.Id === signId);
|
||||||
|
} else {
|
||||||
|
filterSignerPos = updateSignPos.filter(
|
||||||
|
(data) => data.Role === "prefill"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (filterSignerPos.length > 0) {
|
if (filterSignerPos.length > 0) {
|
||||||
const getPlaceHolder = filterSignerPos[0].placeHolder;
|
const getPlaceHolder = filterSignerPos[0].placeHolder;
|
||||||
|
|
||||||
const getPageNumer = getPlaceHolder.filter(
|
const getPageNumer = getPlaceHolder.filter(
|
||||||
(data) => data.pageNumber === pageNumber
|
(data) => data.pageNumber === pageNumber
|
||||||
);
|
);
|
||||||
|
|
||||||
if (getPageNumer.length > 0) {
|
if (getPageNumer.length > 0) {
|
||||||
const getXYdata = getPageNumer[0].pos;
|
const getXYdata = getPageNumer[0].pos;
|
||||||
|
|
||||||
const getPosData = getXYdata;
|
const getPosData = getXYdata;
|
||||||
const addSignPos = getPosData.map((url) => {
|
const addSignPos = getPosData.map((url) => {
|
||||||
if (url.key === keyValue) {
|
if (url.key === keyValue) {
|
||||||
@@ -542,12 +610,17 @@ const TemplatePlaceholder = () => {
|
|||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
const newUpdateSigner = updateSignPos.map((obj) => {
|
const newUpdateSigner = updateSignPos.map((obj) => {
|
||||||
if (obj.Id === signId) {
|
if (signId) {
|
||||||
return { ...obj, placeHolder: newUpdateSignPos };
|
if (obj.Id === signId) {
|
||||||
|
return { ...obj, placeHolder: newUpdateSignPos };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (obj.Role === "prefill") {
|
||||||
|
return { ...obj, placeHolder: newUpdateSignPos };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
|
|
||||||
setSignerPos(newUpdateSigner);
|
setSignerPos(newUpdateSigner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -654,10 +727,34 @@ const TemplatePlaceholder = () => {
|
|||||||
};
|
};
|
||||||
const alertSendEmail = async () => {
|
const alertSendEmail = async () => {
|
||||||
const isPlaceholderExist = signerPos.every((data) => data.placeHolder);
|
const isPlaceholderExist = signerPos.every((data) => data.placeHolder);
|
||||||
if (isPlaceholderExist) {
|
const getPrefill = signerPos?.find((data) => data.Role === "prefill");
|
||||||
|
const prefillPlaceholder = getPrefill?.placeHolder;
|
||||||
|
let isLabel = false;
|
||||||
|
let unfilledTextWidgetId = "";
|
||||||
|
//condition is used to check text widget data is empty or have response
|
||||||
|
if (getPrefill) {
|
||||||
|
if (prefillPlaceholder) {
|
||||||
|
prefillPlaceholder.map((data) => {
|
||||||
|
if (!isLabel) {
|
||||||
|
const unfilledTextWidgets = data.pos.find(
|
||||||
|
(position) => !position.options.response
|
||||||
|
);
|
||||||
|
if (unfilledTextWidgets) {
|
||||||
|
isLabel = true;
|
||||||
|
unfilledTextWidgetId = unfilledTextWidgets.key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (getPrefill && isLabel) {
|
||||||
|
setUnSignedWidgetId(unfilledTextWidgetId);
|
||||||
|
} else if (isPlaceholderExist) {
|
||||||
handleSaveTemplate();
|
handleSaveTemplate();
|
||||||
} else {
|
} else {
|
||||||
const signerList = signerPos.filter((data) => !data.placeHolder);
|
const signerList = signerPos.filter(
|
||||||
|
(data) => !data.placeHolder && data.Role !== "prefill"
|
||||||
|
);
|
||||||
const getSigner = signerList.map((x) => {
|
const getSigner = signerList.map((x) => {
|
||||||
return signersdata.find((y) => y.Id === x.Id).Role;
|
return signersdata.find((y) => y.Id === x.Id).Role;
|
||||||
});
|
});
|
||||||
@@ -673,7 +770,7 @@ const TemplatePlaceholder = () => {
|
|||||||
}, 2000);
|
}, 2000);
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [signerPos, signatureType, pdfBase64Url]);
|
}, [signerPos, signersdata, signatureType, pdfBase64Url]);
|
||||||
|
|
||||||
// `autosavedetails` is used to save template details after every 2 sec when changes are happern in placeholder like drag-drop widgets, remove signers
|
// `autosavedetails` is used to save template details after every 2 sec when changes are happern in placeholder like drag-drop widgets, remove signers
|
||||||
const autosavedetails = async () => {
|
const autosavedetails = async () => {
|
||||||
@@ -703,13 +800,20 @@ const TemplatePlaceholder = () => {
|
|||||||
const templateCls = new Parse.Object("contracts_Template");
|
const templateCls = new Parse.Object("contracts_Template");
|
||||||
templateCls.id = templateId;
|
templateCls.id = templateId;
|
||||||
if (signerPos?.length > 0) {
|
if (signerPos?.length > 0) {
|
||||||
templateCls.set("Placeholders", signerPos);
|
const removePrefill = signerPos.filter((x) => x.Role !== "prefill");
|
||||||
|
if (removePrefill.length > 0) {
|
||||||
|
templateCls.set("Placeholders", removePrefill);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
templateCls.set("Signers", signers);
|
templateCls.set("Signers", signers);
|
||||||
templateCls.set("SignatureType", signatureType);
|
templateCls.set("SignatureType", signatureType);
|
||||||
if (pdfUrl) {
|
if (pdfUrl) {
|
||||||
templateCls.set("URL", pdfUrl);
|
templateCls.set("URL", pdfUrl);
|
||||||
}
|
}
|
||||||
|
templateCls.set(
|
||||||
|
"TimeToCompleteDays",
|
||||||
|
parseInt(pdfDetails?.[0]?.TimeToCompleteDays) || 15
|
||||||
|
);
|
||||||
if (pdfDetails[0]?.Bcc?.length) {
|
if (pdfDetails[0]?.Bcc?.length) {
|
||||||
const Bcc = pdfDetails[0]?.Bcc.map((x) => ({
|
const Bcc = pdfDetails[0]?.Bcc.map((x) => ({
|
||||||
__type: "Pointer",
|
__type: "Pointer",
|
||||||
@@ -727,11 +831,60 @@ const TemplatePlaceholder = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//embed prefill label widget data
|
||||||
|
const embedPrefilllData = async () => {
|
||||||
|
const prefillExist = signerPos.filter((data) => data.Role === "prefill");
|
||||||
|
if (prefillExist && prefillExist.length > 0) {
|
||||||
|
const placeholder = prefillExist[0].placeHolder;
|
||||||
|
const existingPdfBytes = pdfArrayBuffer;
|
||||||
|
const pdfDoc = await PDFDocument.load(existingPdfBytes, {
|
||||||
|
ignoreEncryption: true
|
||||||
|
});
|
||||||
|
const isSignYourSelfFlow = false;
|
||||||
|
try {
|
||||||
|
const pdfBase64 = await multiSignEmbed(
|
||||||
|
placeholder,
|
||||||
|
pdfDoc,
|
||||||
|
isSignYourSelfFlow,
|
||||||
|
scale
|
||||||
|
);
|
||||||
|
const pdfName = generatePdfName(16);
|
||||||
|
const pdfUrl = await convertBase64ToFile(
|
||||||
|
pdfName,
|
||||||
|
pdfBase64,
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
const tenantId = localStorage.getItem("TenantId");
|
||||||
|
const buffer = atob(pdfBase64);
|
||||||
|
SaveFileSize(buffer.length, pdfUrl, tenantId);
|
||||||
|
return pdfUrl;
|
||||||
|
} catch (err) {
|
||||||
|
console.log("error to convertBase64ToFile in placeholder flow", err);
|
||||||
|
alert(err?.message);
|
||||||
|
}
|
||||||
|
} else if (pdfBase64Url) {
|
||||||
|
try {
|
||||||
|
const pdfName = generatePdfName(16);
|
||||||
|
const pdfUrl = await convertBase64ToFile(
|
||||||
|
pdfName,
|
||||||
|
pdfBase64Url,
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
return pdfUrl;
|
||||||
|
} catch (err) {
|
||||||
|
console.log("error to convertBase64ToFile in placeholder flow", err);
|
||||||
|
alert(err?.message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return pdfDetails[0].URL;
|
||||||
|
}
|
||||||
|
};
|
||||||
const handleSaveTemplate = async () => {
|
const handleSaveTemplate = async () => {
|
||||||
if (signersdata?.length) {
|
if (signersdata?.length) {
|
||||||
setIsLoading({ isLoad: true, message: t("loading-mssg") });
|
setIsLoading({ isLoad: true, message: t("loading-mssg") });
|
||||||
setIsSendAlert(false);
|
setIsSendAlert(false);
|
||||||
let signers = [];
|
let signers = [],
|
||||||
|
pdfUrl;
|
||||||
if (signersdata?.length > 0) {
|
if (signersdata?.length > 0) {
|
||||||
signersdata.forEach((x) => {
|
signersdata.forEach((x) => {
|
||||||
if (x.objectId) {
|
if (x.objectId) {
|
||||||
@@ -744,15 +897,10 @@ const TemplatePlaceholder = () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let pdfUrl = pdfDetails[0]?.URL;
|
|
||||||
if (pdfBase64Url) {
|
if (pdfBase64Url) {
|
||||||
try {
|
try {
|
||||||
const pdfName = generatePdfName(16);
|
pdfUrl = await embedPrefilllData();
|
||||||
pdfUrl = await convertBase64ToFile(
|
setUpdatedPdfUrl(pdfUrl);
|
||||||
pdfName,
|
|
||||||
pdfBase64Url,
|
|
||||||
"",
|
|
||||||
);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("error to convertBase64ToFile in placeholder flow", e);
|
console.log("error to convertBase64ToFile in placeholder flow", e);
|
||||||
}
|
}
|
||||||
@@ -770,8 +918,9 @@ const TemplatePlaceholder = () => {
|
|||||||
const RedirectUrl = pdfDetails[0]?.RedirectUrl
|
const RedirectUrl = pdfDetails[0]?.RedirectUrl
|
||||||
? { RedirectUrl: pdfDetails[0]?.RedirectUrl }
|
? { RedirectUrl: pdfDetails[0]?.RedirectUrl }
|
||||||
: {};
|
: {};
|
||||||
|
const removePrefill = signerPos.filter((x) => x?.Role !== "prefill");
|
||||||
const data = {
|
const data = {
|
||||||
Placeholders: signerPos,
|
Placeholders: removePrefill,
|
||||||
Signers: signers,
|
Signers: signers,
|
||||||
Name: pdfDetails[0]?.Name || "",
|
Name: pdfDetails[0]?.Name || "",
|
||||||
Note: pdfDetails[0]?.Note || "",
|
Note: pdfDetails[0]?.Note || "",
|
||||||
@@ -789,6 +938,8 @@ const TemplatePlaceholder = () => {
|
|||||||
pdfDetails[0]?.NotifyOnSignatures !== undefined
|
pdfDetails[0]?.NotifyOnSignatures !== undefined
|
||||||
? pdfDetails[0]?.NotifyOnSignatures
|
? pdfDetails[0]?.NotifyOnSignatures
|
||||||
: false,
|
: false,
|
||||||
|
TimeToCompleteDays:
|
||||||
|
parseInt(pdfDetails?.[0]?.TimeToCompleteDays) || 15,
|
||||||
...Bcc,
|
...Bcc,
|
||||||
...RedirectUrl
|
...RedirectUrl
|
||||||
};
|
};
|
||||||
@@ -921,25 +1072,13 @@ const TemplatePlaceholder = () => {
|
|||||||
const handleCreateDocModal = async () => {
|
const handleCreateDocModal = async () => {
|
||||||
setIsCreateDocModal(false);
|
setIsCreateDocModal(false);
|
||||||
setIsCreateDoc(true);
|
setIsCreateDoc(true);
|
||||||
let pdfUrl = pdfDetails[0]?.URL;
|
const removePrefill = signerPos.filter((x) => x.Role !== "prefill");
|
||||||
if (pdfBase64Url) {
|
|
||||||
try {
|
|
||||||
const pdfName = generatePdfName(16);
|
|
||||||
pdfUrl = await convertBase64ToFile(
|
|
||||||
pdfName,
|
|
||||||
pdfBase64Url,
|
|
||||||
"",
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
console.log("error to convertBase64ToFile in placeholder flow", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// handle create document
|
// handle create document
|
||||||
const res = await createDocument(
|
const res = await createDocument(
|
||||||
pdfDetails,
|
pdfDetails,
|
||||||
signerPos,
|
removePrefill,
|
||||||
signersdata,
|
signersdata,
|
||||||
pdfUrl
|
updatedPdfUrl
|
||||||
);
|
);
|
||||||
if (res.status === "success") {
|
if (res.status === "success") {
|
||||||
navigate(`/placeHolderSign/${res.id}`, {
|
navigate(`/placeHolderSign/${res.id}`, {
|
||||||
@@ -1126,6 +1265,8 @@ const TemplatePlaceholder = () => {
|
|||||||
updateTemplate?.[0]?.NotifyOnSignatures !== undefined
|
updateTemplate?.[0]?.NotifyOnSignatures !== undefined
|
||||||
? updateTemplate?.[0]?.NotifyOnSignatures
|
? updateTemplate?.[0]?.NotifyOnSignatures
|
||||||
: false,
|
: false,
|
||||||
|
TimeToCompleteDays:
|
||||||
|
parseInt(updateTemplate?.[0]?.TimeToCompleteDays) || 15,
|
||||||
...Bcc,
|
...Bcc,
|
||||||
...RedirectUrl
|
...RedirectUrl
|
||||||
};
|
};
|
||||||
@@ -1378,6 +1519,13 @@ const TemplatePlaceholder = () => {
|
|||||||
setShowDropdown(false);
|
setShowDropdown(false);
|
||||||
setIsRadio(false);
|
setIsRadio(false);
|
||||||
setIsCheckbox(false);
|
setIsCheckbox(false);
|
||||||
|
//condition for text widget type after set all values for text widget
|
||||||
|
//change setUniqueId which is set in tempsignerId
|
||||||
|
//because textwidget do not have signer user so for selected signers we have to do
|
||||||
|
if (currWidgetsDetails.type === textWidget) {
|
||||||
|
setUniqueId(tempSignerId);
|
||||||
|
setTempSignerId("");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const clickOnZoomIn = () => {
|
const clickOnZoomIn = () => {
|
||||||
@@ -1425,7 +1573,14 @@ const TemplatePlaceholder = () => {
|
|||||||
style: { fontSize: "13px" }
|
style: { fontSize: "13px" }
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
const textFieldTour = [
|
||||||
|
{
|
||||||
|
selector: '[data-tut="IsSigned"]',
|
||||||
|
content: t("text-field-tour"),
|
||||||
|
position: "top",
|
||||||
|
style: { fontSize: "13px" }
|
||||||
|
}
|
||||||
|
];
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Title title={"Template"} />
|
<Title title={"Template"} />
|
||||||
@@ -1460,13 +1615,25 @@ const TemplatePlaceholder = () => {
|
|||||||
closeWithMask={false}
|
closeWithMask={false}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Tour
|
{isSendAlert && (
|
||||||
onRequestClose={() => setIsSendAlert(false)}
|
<Tour
|
||||||
steps={signatureWidgetTour}
|
onRequestClose={() => setIsSendAlert(false)}
|
||||||
isOpen={isSendAlert}
|
steps={signatureWidgetTour}
|
||||||
rounded={5}
|
isOpen={true}
|
||||||
closeWithMask={false}
|
rounded={5}
|
||||||
/>
|
closeWithMask={false}
|
||||||
|
/> // this is the tour for add signature widget for all role
|
||||||
|
)}
|
||||||
|
{unSignedWidgetId && (
|
||||||
|
<Tour
|
||||||
|
onRequestClose={() => setUnSignedWidgetId("")}
|
||||||
|
steps={textFieldTour}
|
||||||
|
isOpen={true}
|
||||||
|
rounded={5}
|
||||||
|
closeWithMask={false}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* this component used to render all pdf pages in left side */}
|
{/* this component used to render all pdf pages in left side */}
|
||||||
<RenderAllPdfPage
|
<RenderAllPdfPage
|
||||||
allPages={allPages}
|
allPages={allPages}
|
||||||
@@ -1606,6 +1773,10 @@ const TemplatePlaceholder = () => {
|
|||||||
pageNumber={pageNumber}
|
pageNumber={pageNumber}
|
||||||
signKey={signKey}
|
signKey={signKey}
|
||||||
Id={uniqueId}
|
Id={uniqueId}
|
||||||
|
widgetType={widgetType}
|
||||||
|
setUniqueId={setUniqueId}
|
||||||
|
tempSignerId={tempSignerId}
|
||||||
|
setTempSignerId={setTempSignerId}
|
||||||
/>
|
/>
|
||||||
{/* pdf header which contain funish back button */}
|
{/* pdf header which contain funish back button */}
|
||||||
<Header
|
<Header
|
||||||
@@ -1683,6 +1854,9 @@ const TemplatePlaceholder = () => {
|
|||||||
setFontColor={setFontColor}
|
setFontColor={setFontColor}
|
||||||
isResize={isResize}
|
isResize={isResize}
|
||||||
divRef={divRef}
|
divRef={divRef}
|
||||||
|
setTempSignerId={setTempSignerId}
|
||||||
|
uniqueId={uniqueId}
|
||||||
|
unSignedWidgetId={unSignedWidgetId}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -1713,7 +1887,6 @@ const TemplatePlaceholder = () => {
|
|||||||
handleOnBlur={handleOnBlur}
|
handleOnBlur={handleOnBlur}
|
||||||
title={t("roles")}
|
title={t("roles")}
|
||||||
initial={true}
|
initial={true}
|
||||||
isTemplateFlow={true}
|
|
||||||
sendInOrder={pdfDetails[0].SendinOrder}
|
sendInOrder={pdfDetails[0].SendinOrder}
|
||||||
setSignersData={setSignersData}
|
setSignersData={setSignersData}
|
||||||
blockColor={blockColor}
|
blockColor={blockColor}
|
||||||
@@ -1721,6 +1894,7 @@ const TemplatePlaceholder = () => {
|
|||||||
setSignerPos={setSignerPos}
|
setSignerPos={setSignerPos}
|
||||||
uniqueId={uniqueId}
|
uniqueId={uniqueId}
|
||||||
setSelectWidgetId={setSelectWidgetId}
|
setSelectWidgetId={setSelectWidgetId}
|
||||||
|
isTemplateFlow={true}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -312,6 +312,7 @@ const ReportTable = (props) => {
|
|||||||
AutomaticReminders: Doc?.AutomaticReminders || false,
|
AutomaticReminders: Doc?.AutomaticReminders || false,
|
||||||
RemindOnceInEvery: Doc?.RemindOnceInEvery || 5,
|
RemindOnceInEvery: Doc?.RemindOnceInEvery || 5,
|
||||||
IsEnableOTP: Doc?.IsEnableOTP || false,
|
IsEnableOTP: Doc?.IsEnableOTP || false,
|
||||||
|
TimeToCompleteDays: parseInt(Doc?.TimeToCompleteDays) || 15,
|
||||||
AllowModifications: Doc?.AllowModifications || false,
|
AllowModifications: Doc?.AllowModifications || false,
|
||||||
...SignatureType,
|
...SignatureType,
|
||||||
...NotifyOnSignatures,
|
...NotifyOnSignatures,
|
||||||
|
|||||||
@@ -71,12 +71,6 @@ export default async function createDuplicate(request) {
|
|||||||
if (_templateRes?.SharedWith?.length > 0) {
|
if (_templateRes?.SharedWith?.length > 0) {
|
||||||
newTemplate.set('SharedWith', _templateRes.SharedWith);
|
newTemplate.set('SharedWith', _templateRes.SharedWith);
|
||||||
}
|
}
|
||||||
if (_templateRes?.IsPublic) {
|
|
||||||
newTemplate.set('IsPublic', _templateRes?.IsPublic);
|
|
||||||
}
|
|
||||||
if (_templateRes?.PublicRole?.length > 0) {
|
|
||||||
newTemplate.set('PublicRole', _templateRes?.PublicRole);
|
|
||||||
}
|
|
||||||
if (_templateRes?.IsTourEnabled) {
|
if (_templateRes?.IsTourEnabled) {
|
||||||
newTemplate.set('IsTourEnabled', _templateRes?.IsTourEnabled);
|
newTemplate.set('IsTourEnabled', _templateRes?.IsTourEnabled);
|
||||||
}
|
}
|
||||||
@@ -91,6 +85,9 @@ export default async function createDuplicate(request) {
|
|||||||
if (_templateRes?.RedirectUrl) {
|
if (_templateRes?.RedirectUrl) {
|
||||||
newTemplate.set('RedirectUrl', _templateRes?.RedirectUrl);
|
newTemplate.set('RedirectUrl', _templateRes?.RedirectUrl);
|
||||||
}
|
}
|
||||||
|
if (_templateRes?.TimeToCompleteDays) {
|
||||||
|
newTemplate.set('TimeToCompleteDays', parseInt(_templateRes?.TimeToCompleteDays));
|
||||||
|
}
|
||||||
const acl = templateRes.getACL();
|
const acl = templateRes.getACL();
|
||||||
if (acl) {
|
if (acl) {
|
||||||
newTemplate.setACL(acl);
|
newTemplate.setACL(acl);
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ async function sendMailsaveCertifcate(
|
|||||||
P12Buffer,
|
P12Buffer,
|
||||||
isCustomMail,
|
isCustomMail,
|
||||||
mailProvider,
|
mailProvider,
|
||||||
filename
|
filename,
|
||||||
) {
|
) {
|
||||||
const certificate = await GenerateCertificate(doc);
|
const certificate = await GenerateCertificate(doc);
|
||||||
const certificatePdf = await PDFDocument.load(certificate);
|
const certificatePdf = await PDFDocument.load(certificate);
|
||||||
@@ -440,7 +440,7 @@ async function PDF(req) {
|
|||||||
P12Buffer,
|
P12Buffer,
|
||||||
isCustomMail,
|
isCustomMail,
|
||||||
mailProvider,
|
mailProvider,
|
||||||
name
|
name,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// `fs.unlinkSync` is used to remove exported signed pdf file from exports folder
|
// `fs.unlinkSync` is used to remove exported signed pdf file from exports folder
|
||||||
|
|||||||
Reference in New Issue
Block a user