From d9fcc69ca4efb36859fd54b28aca21918edcaa69 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs Date: Mon, 29 Sep 2025 04:47:23 +0000 Subject: [PATCH] v2.29.0 --- .../public/locales/de/translation.json | 17 +- .../public/locales/en/translation.json | 21 +- .../public/locales/es/translation.json | 17 +- .../public/locales/fr/translation.json | 17 +- .../public/locales/hi/translation.json | 18 +- .../public/locales/it/translation.json | 17 +- .../OpenSign/src/components/pdf/PdfHeader.jsx | 16 +- apps/OpenSign/src/components/pdf/PdfTools.jsx | 16 +- .../src/components/pdf/Placeholder.jsx | 445 ++++-- .../src/components/pdf/PlaceholderType.jsx | 24 +- .../components/pdf/PrefillWidgetsModal.jsx | 7 +- .../src/components/pdf/RenderAllPdfPage.jsx | 16 +- .../src/components/pdf/WidgetsValueModal.jsx | 131 +- apps/OpenSign/src/constant/Utils.js | 77 +- apps/OpenSign/src/constant/const.js | 2 +- apps/OpenSign/src/pages/DebugPdf.jsx | 2 +- apps/OpenSign/src/pages/Form.jsx | 12 +- apps/OpenSign/src/pages/PdfRequestFiles.jsx | 2 + apps/OpenSign/src/pages/PlaceHolderSign.jsx | 9 +- apps/OpenSign/src/pages/Report.jsx | 1 + apps/OpenSign/src/pages/SignyourselfPdf.jsx | 3 +- .../src/pages/TemplatePlaceholder.jsx | 19 +- apps/OpenSign/src/primitives/ModalUi.jsx | 6 +- .../src/reports/document/DocumentsReport.jsx | 3 + .../src/reports/template/TemplatesReport.jsx | 21 +- apps/OpenSignServer/Utils.js | 1 + .../cloud/customRoute/customApp.js | 4 +- .../generateCertificatebydocId.js | 17 +- .../cloud/parsefunction/getTenant.js | 27 +- .../cloud/parsefunction/pdf/PDF.js | 16 +- .../cloud/parsefunction/saveFile.js | 28 +- apps/OpenSignServer/index.js | 6 +- apps/OpenSignServer/package-lock.json | 1368 ++++++++--------- apps/OpenSignServer/package.json | 6 +- apps/OpenSignServer/utils/fileUtils.js | 23 + 35 files changed, 1372 insertions(+), 1043 deletions(-) diff --git a/apps/OpenSign/public/locales/de/translation.json b/apps/OpenSign/public/locales/de/translation.json index d36ebe99f5..7374eb7b9d 100644 --- a/apps/OpenSign/public/locales/de/translation.json +++ b/apps/OpenSign/public/locales/de/translation.json @@ -901,6 +901,10 @@ "thanks-for-feedback": "Danke für Ihr Feedback 🙏", "share-your-feedback": "Teilen Sie Ihr Feedback", "share-your-review": "Teilen Sie Ihre Bewertung", + "please-select-rating": "Bitte wählen Sie eine Bewertung aus", + "feedback-optional": "Feedback (optional)", + "feedback-saved": "Feedback wurde gespeichert.", + "feedback-save-error": "Feedback konnte nicht gespeichert werden, bitte versuchen Sie es erneut.", "date-format": "Datumsformat", "document-deleted": "Das Dokument wurde gelöscht oder Sie haben keinen Zugriff. Bitte kontaktieren Sie den Absender.", "save-as-template-?": "Sind Sie sicher, dass Sie dieses Dokument als Vorlage speichern möchten?", @@ -1216,6 +1220,15 @@ "p1": "Dies stellt sicher, dass das Abschlusszertifikat im endgültigen PDF-Dokument enthalten ist. Bitte beachten Sie jedoch, dass das Zertifikat nach dem Zusammenführen nicht mehr vom Hauptdokument getrennt werden kann.", "p2": "Wenn Sie sich entscheiden, nicht zusammenzuführen, wird das Abschlusszertifikat als separate PDF-Datei zusammen mit dem unterzeichneten Dokument bereitgestellt." }, + "read-only-date-error": "Das schreibgeschützte Datums-Widget muss ein Standarddatum haben.", + "set-date": "Datum festlegen", + "set-today": "Unterzeichnungsdatum", "enter-name": "Name eingeben", - "enter-email": "E-Mail eingeben" -} + "enter-email": "E-Mail eingeben", + "subscribe-to-opensign-msg": "Abonnieren Sie {{appName}} und genießen Sie unbegrenzt kostenlose digitale Signaturen.", + "duplicate-subscribe-msg": "Mit Duplizieren können Sie eine exakte Kopie der ausgewählten Vorlage erstellen, die Sie wiederverwenden oder ändern können, ohne das Original zu beeinflussen.", + "save-as-template-msg": "Speichern Sie dieses Dokument als wiederverwendbare Vorlage, die Sie für zukünftige Dokumente erneut nutzen können.", + "public-credit-alert": "Das Signieren über diesen Link verbraucht Ihre kostenlosen E-Mail-Credits. Als kostenloser Nutzer erhalten Sie 15 E-Mail-Credits pro Monat, um zu verhindern, dass Spammer unsere Systeme missbrauchen. Um höhere Limits und ununterbrochenen Zugriff zu genießen, abonnieren Sie die <1>OpenSign™-Bezahlpläne.", + "know-more-about": "Mehr erfahren über", + "free-unlimited-signatures": "Kostenlose unbegrenzte Signaturen" +} \ No newline at end of file diff --git a/apps/OpenSign/public/locales/en/translation.json b/apps/OpenSign/public/locales/en/translation.json index e3768d9f4e..8f5cbfd54e 100644 --- a/apps/OpenSign/public/locales/en/translation.json +++ b/apps/OpenSign/public/locales/en/translation.json @@ -902,6 +902,10 @@ "thanks-for-feedback": "Thanks for your feedback 🙏", "share-your-feedback": "Share your feedback", "share-your-review": "Share your review", + "please-select-rating": "Please select a rating", + "feedback-optional": "Feedback (Optional)", + "feedback-saved": "Feedback has been saved.", + "feedback-save-error": "Unable to save feedback, please try again.", "date-format": "Date format", "document-deleted": "The document has been deleted or you don't have access. Please contact the sender.", "save-as-template-?": "Are you sure you want to save this document as template?", @@ -1208,8 +1212,8 @@ "enter-region-of-space": "Enter region of space", "enter-access-key": "Enter access key", "enter-secret-access-key": "Enter secret access key", - "otp-email":"We’ve sent a verification code to", - "save-as-temp-warn":"Note: This document includes prefilled widgets, which will be automatically removed as they are already incorporated into the base document.", + "otp-email": "We've sent a verification code to", + "save-as-temp-warn": "Note: This document includes prefilled widgets, which will be automatically removed as they are already incorporated into the base document.", "edit-document": "Edit document", "modify": "Modify", "merge-certificate-to-pdf": "Merge Certificate to PDF", @@ -1217,6 +1221,15 @@ "p1": "This will ensure that the completion certificate is included in the final PDF document. However, please note that once merged, the certificate cannot be separated from the main document.", "p2": "If you choose not to merge, the completion certificate will be provided as a separate PDF file along with the signed document." }, + "read-only-date-error": "Read-only date widget must have a default date.", + "set-date": "Set Date", + "set-today": "Signing Date", "enter-name": "Enter name", - "enter-email": "Enter email" -} + "enter-email": "Enter email", + "subscribe-to-opensign-msg": "Subscribe to {{appName}} and enjoy unlimited free digital signatures.", + "duplicate-subscribe-msg": "Duplicate lets you create an exact copy of the selected template, allowing you to reuse or modify it without affecting the original.", + "save-as-template-msg": "Save this document as a reusable template that you can use again for future documents.", + "public-credit-alert": "Signing through this link consumes your free email credits. As a Free user, you are allotted 15 email credits per month to prevent spammers from abusing our systems. To enjoy higher limits and uninterrupted access, Subscribe to <1>OpenSign™ Paid plans.", + "know-more-about": "Know more about", + "free-unlimited-signatures": "Free Unlimited Signatures" +} \ No newline at end of file diff --git a/apps/OpenSign/public/locales/es/translation.json b/apps/OpenSign/public/locales/es/translation.json index d3986d38b4..744652fab9 100644 --- a/apps/OpenSign/public/locales/es/translation.json +++ b/apps/OpenSign/public/locales/es/translation.json @@ -902,6 +902,10 @@ "thanks-for-feedback": "Gracias por su comentario 🙏", "share-your-feedback": "Comparta sus comentarios", "share-your-review": "Comparta su reseña", + "please-select-rating": "Por favor seleccione una calificación", + "feedback-optional": "Comentarios (opcional)", + "feedback-saved": "Los comentarios han sido guardados.", + "feedback-save-error": "No se pudieron guardar los comentarios, inténtelo de nuevo.", "date-format": "Formato de fecha", "document-deleted": "El documento ha sido eliminado o no tiene acceso. Por favor, contacte al remitente.", "save-as-template-?": "¿Está seguro de que desea guardar este documento como plantilla?", @@ -1217,6 +1221,15 @@ "p1": "Esto garantizará que el certificado de finalización esté incluido en el documento PDF final. Sin embargo, tenga en cuenta que una vez combinado, el certificado no se podrá separar del documento principal.", "p2": "Si elige no combinar, el certificado de finalización se proporcionará como un archivo PDF separado junto con el documento firmado." }, + "read-only-date-error": "El widget de fecha de solo lectura debe tener una fecha predeterminada.", + "set-date": "Establecer fecha", + "set-today": "Fecha de firma", "enter-name": "Ingrese nombre", - "enter-email": "Ingrese correo electrónico" -} + "enter-email": "Ingrese correo electrónico", + "subscribe-to-opensign-msg": "Suscríbase a {{appName}} y disfrute de firmas digitales gratuitas ilimitadas.", + "duplicate-subscribe-msg": "Duplicar le permite crear una copia exacta de la plantilla seleccionada, lo que le permite reutilizarla o modificarla sin afectar al original.", + "save-as-template-msg": "Guarde este documento como una plantilla reutilizable que podrá usar nuevamente para futuros documentos.", + "public-credit-alert": "Firmar a través de este enlace consumirá sus créditos de correo electrónico gratuitos. Como usuario gratuito, se le asignan 15 créditos de correo electrónico por mes para evitar que los spammers abusen de nuestros sistemas. Para disfrutar de límites más altos y acceso ininterrumpido, suscríbase a los planes de pago de <1>OpenSign™.", + "know-more-about": "Saber más sobre", + "free-unlimited-signatures": "¿Firmas ilimitadas gratis" +} \ No newline at end of file diff --git a/apps/OpenSign/public/locales/fr/translation.json b/apps/OpenSign/public/locales/fr/translation.json index d3635ff601..d7a1e2f036 100644 --- a/apps/OpenSign/public/locales/fr/translation.json +++ b/apps/OpenSign/public/locales/fr/translation.json @@ -901,6 +901,10 @@ "thanks-for-feedback": "Merci pour votre retour 🙏", "share-your-feedback": "Partagez votre avis", "share-your-review": "Partagez votre avis", + "please-select-rating": "Veuillez sélectionner une note", + "feedback-optional": "Retour (optionnel)", + "feedback-saved": "Le retour a été enregistré.", + "feedback-save-error": "Impossible d'enregistrer le retour, veuillez réessayer.", "date-format": "Format de date", "document-deleted": "Le document a été supprimé ou vous n'y avez pas accès. Veuillez contacter l'expéditeur.", "save-as-template-?": "Êtes-vous sûr de vouloir enregistrer ce document comme modèle ?", @@ -1216,6 +1220,15 @@ "p1": "Cela garantira que le certificat de finalisation est inclus dans le document PDF final. Cependant, veuillez noter qu'une fois fusionné, le certificat ne peut plus être séparé du document principal.", "p2": "Si vous choisissez de ne pas fusionner, le certificat de finalisation sera fourni sous forme de fichier PDF distinct accompagné du document signé." }, + "read-only-date-error": "Le widget de date en lecture seule doit avoir une date par défaut.", + "set-date": "Définir la date", + "set-today": "Date de signature", "enter-name": "Saisir le nom", - "enter-email": "Saisir l'e-mail" -} + "enter-email": "Saisir l'e-mail", + "subscribe-to-opensign-msg": "Abonnez-vous à {{appName}} et profitez de signatures numériques gratuites illimitées.", + "duplicate-subscribe-msg": "Dupliquer vous permet de créer une copie exacte du modèle sélectionné, que vous pouvez réutiliser ou modifier sans affecter l'original.", + "save-as-template-msg": "Enregistrez ce document comme modèle réutilisable que vous pourrez utiliser à nouveau pour de futurs documents.", + "public-credit-alert": "Signer via ce lien consomme vos crédits e-mail gratuits. En tant qu'utilisateur gratuit, vous disposez de 15 crédits e-mail par mois afin d’empêcher les spammeurs d’abuser de nos systèmes. Pour profiter de limites plus élevées et d'un accès ininterrompu, abonnez-vous aux forfaits payants de <1>OpenSign™.", + "know-more-about": "En savoir plus sur", + "free-unlimited-signatures": "Signatures illimitées gratuites" +} \ No newline at end of file diff --git a/apps/OpenSign/public/locales/hi/translation.json b/apps/OpenSign/public/locales/hi/translation.json index 75bd6cf309..76be44849f 100644 --- a/apps/OpenSign/public/locales/hi/translation.json +++ b/apps/OpenSign/public/locales/hi/translation.json @@ -901,6 +901,10 @@ "thanks-for-feedback": "आपकी प्रतिक्रिया के लिए धन्यवाद 🙏", "share-your-feedback": "अपनी प्रतिक्रिया साझा करें", "share-your-review": "अपनी समीक्षा साझा करें", + "please-select-rating": "कृपया एक रेटिंग चुनें", + "feedback-optional": "प्रतिक्रिया (वैकल्पिक)", + "feedback-saved": "प्रतिक्रिया सहेज ली गई है।", + "feedback-save-error": "प्रतिक्रिया सहेजी नहीं जा सकी, कृपया पुनः प्रयास करें।", "date-format": "दिनांक प्रारूप", "document-deleted": "दस्तावेज़ हटा दिया गया है या आपके पास पहुंच नहीं है। कृपया प्रेषक से संपर्क करें।", "save-as-template-?": "क्या आप वाकई इस दस्तावेज़ को टेम्पलेट के रूप में सहेजना चाहते हैं?", @@ -1216,7 +1220,15 @@ "p1": "यह सुनिश्चित करेगा कि पूर्णता प्रमाणपत्र अंतिम PDF दस्तावेज़ में शामिल हो। हालाँकि, कृपया ध्यान दें कि एक बार मिलाने के बाद, प्रमाणपत्र को मुख्य दस्तावेज़ से अलग नहीं किया जा सकता।", "p2": "यदि आप मिलाना नहीं चुनते हैं, तो पूर्णता प्रमाणपत्र हस्ताक्षरित दस्तावेज़ के साथ एक अलग PDF फ़ाइल के रूप में प्रदान किया जाएगा।" }, + "read-only-date-error": "रीड-ओनली दिनांक विजेट में एक डिफ़ॉल्ट दिनांक होना आवश्यक है।", + "set-date": "दिनांक सेट करें", + "set-today": "हस्ताक्षर की तिथि", "enter-name": "नाम दर्ज करें", - "enter-email": "ईमेल दर्ज करें" - -} + "enter-email": "ईमेल दर्ज करें", + "subscribe-to-opensign-msg": "{{appName}} की सदस्यता लें और असीमित निःशुल्क डिजिटल हस्ताक्षरों का आनंद लें।", + "duplicate-subscribe-msg": "डुप्लिकेट करने से आप चयनित टेम्पलेट की एक सटीक प्रति बना सकते हैं, जिसे आप पुनः उपयोग या संशोधित कर सकते हैं बिना मूल को प्रभावित किए।", + "save-as-template-msg": "इस दस्तावेज़ को एक पुन: प्रयोज्य टेम्पलेट के रूप में सहेजें जिसे आप भविष्य के दस्तावेज़ों के लिए फिर से उपयोग कर सकते हैं।", + "public-credit-alert": "इस लिंक के माध्यम से हस्ताक्षर करने पर आपके निःशुल्क ईमेल क्रेडिट का उपभोग होगा। एक निःशुल्क उपयोगकर्ता के रूप में, आपको स्पैमर्स को हमारी प्रणाली का दुरुपयोग करने से रोकने के लिए प्रति माह 15 ईमेल क्रेडिट आवंटित किए जाते हैं। उच्च सीमा और निर्बाध पहुँच का आनंद लेने के लिए, <1>OpenSign™ पेड प्लान की सदस्यता लें।", + "know-more-about": "इसके बारे में और जानें", + "free-unlimited-signatures": "मुफ़्त असीमित हस्ताक्षर" +} \ No newline at end of file diff --git a/apps/OpenSign/public/locales/it/translation.json b/apps/OpenSign/public/locales/it/translation.json index d9bfa47373..30c1884dd0 100644 --- a/apps/OpenSign/public/locales/it/translation.json +++ b/apps/OpenSign/public/locales/it/translation.json @@ -901,6 +901,10 @@ "thanks-for-feedback": "Grazie per il tuo feedback 🙏", "share-your-feedback": "Condividi il tuo feedback", "share-your-review": "Condividi la tua recensione", + "please-select-rating": "Si prega di selezionare una valutazione", + "feedback-optional": "Feedback (opzionale)", + "feedback-saved": "Il feedback è stato salvato.", + "feedback-save-error": "Impossibile salvare il feedback, riprova.", "date-format": "Formato data", "document-deleted": "Il documento è stato eliminato o non hai accesso. Si prega di contattare il mittente.", "save-as-template-?": "Sei sicuro di voler salvare questo documento come modello?", @@ -1216,6 +1220,15 @@ "p1": "Questo garantirà che il certificato di completamento sia incluso nel documento PDF finale. Tuttavia, si noti che una volta unito, il certificato non può essere separato dal documento principale.", "p2": "Se scegli di non unire, il certificato di completamento sarà fornito come file PDF separato insieme al documento firmato." }, + "read-only-date-error": "Il widget data di sola lettura deve avere una data predefinita.", + "set-date": "Imposta data", + "set-today": "Data di firma", "enter-name": "Inserisci nome", - "enter-email": "Inserisci e-mail" -} + "enter-email": "Inserisci e-mail", + "subscribe-to-opensign-msg": "Abbonati a {{appName}} e goditi firme digitali gratuite illimitate.", + "duplicate-subscribe-msg": "Duplicare consente di creare una copia esatta del modello selezionato, permettendoti di riutilizzarlo o modificarlo senza influire sull'originale.", + "save-as-template-msg": "Salva questo documento come modello riutilizzabile che potrai usare di nuovo per documenti futuri.", + "public-credit-alert": "Firmare tramite questo link consumerà i tuoi crediti e-mail gratuiti. Come utente gratuito, ti vengono assegnati 15 crediti e-mail al mese per impedire agli spammer di abusare dei nostri sistemi. Per usufruire di limiti più elevati e accesso ininterrotto, abbonati ai piani a pagamento di <1>OpenSign™.", + "know-more-about": "Scopri di più su", + "free-unlimited-signatures": "Firme illimitate gratuite" +} \ No newline at end of file diff --git a/apps/OpenSign/src/components/pdf/PdfHeader.jsx b/apps/OpenSign/src/components/pdf/PdfHeader.jsx index 1c0d2f7537..caef19c6e4 100644 --- a/apps/OpenSign/src/components/pdf/PdfHeader.jsx +++ b/apps/OpenSign/src/components/pdf/PdfHeader.jsx @@ -75,9 +75,12 @@ function Header(props) { alert(t("only-pdf-allowed")); return; } - const mb = Math.round(file?.size / Math.pow(1024, 2)); - if (mb > maxFileSize) { - alert(`${t("file-alert-1")} ${maxFileSize} MB`); + const fileSize = + maxFileSize; + const pdfsize = file?.size; + const fileSizeBytes = fileSize * 1024 * 1024; + if (pdfsize > fileSizeBytes) { + alert(`${t("file-alert-1")} ${fileSize} MB`); removeFile(e); return; } @@ -134,6 +137,13 @@ function Header(props) { useObjectStreams: false }); const pdfBuffer = base64ToArrayBuffer(pdfBase64); + const pdfsize = pdfBuffer?.byteLength; + const fileSizeBytes = fileSize * 1024 * 1024; + if (pdfsize > fileSizeBytes) { + alert(`${t("file-alert-1")} ${fileSize} MB`); + removeFile(e); + return; + } props.setPdfArrayBuffer(pdfBuffer); props.setPdfBase64Url(pdfBase64); props.setIsUploadPdf && props.setIsUploadPdf(true); diff --git a/apps/OpenSign/src/components/pdf/PdfTools.jsx b/apps/OpenSign/src/components/pdf/PdfTools.jsx index 8a3e55ab1e..7434d6891b 100644 --- a/apps/OpenSign/src/components/pdf/PdfTools.jsx +++ b/apps/OpenSign/src/components/pdf/PdfTools.jsx @@ -67,9 +67,12 @@ function PdfTools(props) { alert(t("only-pdf-allowed")); return; } - const mb = Math.round(file?.size / Math.pow(1024, 2)); - if (mb > maxFileSize) { - alert(`${t("file-alert-1")} ${maxFileSize} MB`); + const fileSize = + maxFileSize; + const pdfsize = file?.size; + const fileSizeBytes = fileSize * 1024 * 1024; + if (pdfsize > fileSizeBytes) { + alert(`${t("file-alert-1")} ${fileSize} MB`); removeFile(e); return; } @@ -126,6 +129,13 @@ function PdfTools(props) { useObjectStreams: false }); const pdfBuffer = base64ToArrayBuffer(pdfBase64); + const pdfsize = pdfBuffer?.byteLength; + const fileSizeBytes = fileSize * 1024 * 1024; + if (pdfsize > fileSizeBytes) { + alert(`${t("file-alert-1")} ${fileSize} MB`); + removeFile(e); + return; + } props.setPdfArrayBuffer(pdfBuffer); props.setPdfBase64Url(pdfBase64); props.setIsUploadPdf && props.setIsUploadPdf(true); diff --git a/apps/OpenSign/src/components/pdf/Placeholder.jsx b/apps/OpenSign/src/components/pdf/Placeholder.jsx index 00f5ed186a..4116956680 100644 --- a/apps/OpenSign/src/components/pdf/Placeholder.jsx +++ b/apps/OpenSign/src/components/pdf/Placeholder.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from "react"; +import { useState, useEffect, forwardRef } from "react"; import BorderResize from "./BorderResize"; import { Rnd } from "react-rnd"; import { @@ -15,7 +15,13 @@ import { cellsWidget, textWidget, selectFormat, - randomId + randomId, + getYear, + getMonth, + months, + years, + getDefaultDate, + getDefaultFormat } from "../../constant/Utils"; import PlaceholderType from "./PlaceholderType"; import moment from "moment"; @@ -29,47 +35,34 @@ import { } from "../../redux/reducers/widgetSlice"; import { themeColor } from "../../constant/const"; import { useGuidelinesContext } from "../../context/GuidelinesContext"; - -//function to get default format -const getDefaultFormat = (dateFormat) => dateFormat || "MM/dd/yyyy"; - -//function to convert formated date to new Date() format -const getDefaultDate = (dateStr, format) => { - //get valid date format for moment to convert formated date to new Date() format - const formats = changeDateToMomentFormat(format); - const parsedDate = moment(dateStr, formats); - let date; - if (parsedDate.isValid()) { - date = new Date(parsedDate.toISOString()); - return date; - } else { - date = new Date(); - return date; - } -}; +import DatePicker from "react-datepicker"; function Placeholder(props) { const { t } = useTranslation(); const dispatch = useDispatch(); const prefillImg = useSelector((state) => state.widget.prefillImg); const { showGuidelines } = useGuidelinesContext(); + const statusArr = ["Required", "Optional"]; const widgetData = props.pos?.options?.defaultValue || props.pos?.options?.response; const [isDateModal, setIsDateModal] = useState(false); const [containerScale, setContainerScale] = useState(); const [selectDate, setSelectDate] = useState({}); - const [dateFormat, setDateFormat] = useState([]); + const [dateFormatList, setDateFormatList] = useState([]); const [clickonWidget, setClickonWidget] = useState({}); - const [isDateReadOnly, setIsDateReadOnly] = useState( - props?.pos?.options?.isReadOnly || false + const [formdata, setFormdata] = useState({ + status: props?.pos?.options?.status || "required", + isReadOnly: props?.pos?.options?.isReadOnly || false + }); + const [isToday, setIsToday] = useState( + props.pos?.options?.response === "today" ? true : false ); const startDate = props?.pos?.options?.response ? getDefaultDate( props?.pos?.options?.response, props.pos?.options?.validation?.format ) - : new Date(); - + : ""; useEffect(() => { const getPdfPageWidth = props.pdfOriginalWH.find( (data) => data.pageNumber === props.pageNumber @@ -102,29 +95,87 @@ function Placeholder(props) { } }, [widgetData]); + //function is used to convert date according to selected format + const handleGetFormatDate = (data, isDateChange) => { + const isSpecialDateFormat = + data?.format && + ["dd-MM-yyyy", "dd.MM.yyyy", "dd/MM/yyyy"].includes(data?.format); + let updateDate = data.date; + let date = ""; + if (isSpecialDateFormat && updateDate) { + date = isDateChange + ? moment(updateDate).format(changeDateToMomentFormat(data.format)) + : updateDate; + } else if (updateDate) { + //using moment package is used to change date as per the format provided in selectDate obj e.g. - MM/dd/yyyy -> 03/12/2024 + const newDate = new Date(updateDate); + date = moment(newDate.getTime()).format( + changeDateToMomentFormat(data?.format) + ); + } + setSelectDate({ date: date, format: data?.format }); + return date; + }; + const saveDateSetting = (data) => { + if (formdata?.isReadOnly && !selectDate.date && !isToday) { + alert(t("read-only-date-error")); + return; + } + handleSaveDate(data); + setIsDateModal(false); + props.setFontColor(""); + props.setFontSize(""); + }; + //function to save date and format on local array onchange date and onclick format + const handleSaveDate = (data, isDateChange) => { + const date = isToday ? "today" : handleGetFormatDate(data, isDateChange); + //`onChangeInput` is used to save data related to date in a placeholder field + onChangeInput( + date, + props.pos, + props.xyPosition, + props.index, + props.setXyPosition, + props.data && props.data.Id, + false, + data?.format, + props.fontSize || props.pos?.options?.fontSize || 12, + props.fontColor || props.pos?.options?.fontColor || "black", + formdata + ); + }; + + //Date-picker- accept date - Thu Dec 30 2025 00:00:00 GMT+0530 (India Standard Time) + //if date have in this format - "30/12/2025" + //then first need to be convert in this format - Tue Dec 30 2025 00:00:00 GMT+0530 (India Standard Time) + //Using moment - moment("30/12/2025", "DD/MM/YYYY").toDate(); + + //moment package where we show date according to format in list + //it support date in this type - "2025-09-11"// ISO string, "2025-09-11T14:30:00" // ISO datetime //function change format array list with selected date and format const changeDateFormat = () => { const updateDate = []; dateFormatArr.map((data) => { - let date; - if (selectDate && selectDate.format === "dd-MM-yyyy") { - const [day, month, year] = selectDate.date.split("-"); + let date = selectDate?.date || new Date(); + const isString = typeof date === "string"; + if (selectDate.format === "dd-MM-yyyy" && isString) { + const [day, month, year] = date.split("-"); date = new Date(`${year}-${month}-${day}`); - } else if (selectDate && selectDate.format === "dd.MM.yyyy") { - const [day, month, year] = selectDate.date.split("."); + } else if (selectDate.format === "dd.MM.yyyy" && isString) { + const [day, month, year] = date.split("."); date = new Date(`${year}.${month}.${day}`); - } else if (selectDate && selectDate.format === "dd/MM/yyyy") { - const [day, month, year] = selectDate.date.split("/"); + } else if (selectDate.format === "dd/MM/yyyy" && isString) { + const [day, month, year] = date.split("/"); date = new Date(`${year}/${month}/${day}`); } else { - date = new Date(selectDate?.date); + date = selectDate?.date ? new Date(selectDate?.date) : new Date(); } const milliseconds = date.getTime(); const newDate = moment(milliseconds).format(data); const dateObj = { date: newDate, format: selectFormat(data) }; updateDate.push(dateObj); }); - setDateFormat(updateDate); + setDateFormatList(updateDate); }; useEffect(() => { @@ -287,41 +338,6 @@ function Placeholder(props) { } }; - //function to save date and format on local array onchange date and onclick format - const handleSaveDate = (data, isDateChange) => { - const isSpecialDateFormat = - data?.format && - ["dd-MM-yyyy", "dd.MM.yyyy", "dd/MM/yyyy"].includes(data?.format); - let updateDate = data.date; - let date; - if (isSpecialDateFormat) { - date = isDateChange - ? moment(updateDate).format(changeDateToMomentFormat(data.format)) - : updateDate; - } else { - //using moment package is used to change date as per the format provided in selectDate obj e.g. - MM/dd/yyyy -> 03/12/2024 - const newDate = new Date(updateDate); - date = moment(newDate.getTime()).format( - changeDateToMomentFormat(data?.format) - ); - } - //`onChangeInput` is used to save data related to date in a placeholder field - onChangeInput( - date, - props.pos, - props.xyPosition, - props.index, - props.setXyPosition, - props.data && props.data.Id, - false, - data?.format, - props.fontSize || props.pos?.options?.fontSize || 12, - props.fontColor || props.pos?.options?.fontColor || "black", - isDateReadOnly || false - ); - setSelectDate({ date: date, format: data?.format }); - }; - const setCellCount = (key, newCount) => { props.setXyPosition((prev) => { const isSignerList = prev.some((d) => d.signerPtr); @@ -650,6 +666,40 @@ function Placeholder(props) { return false; } }; + const ExampleCustomInput = forwardRef(({ value, onClick }, ref) => ( +
+ {value} + +
+ )); + ExampleCustomInput.displayName = "ExampleCustomInput"; + const handleChangeFormat = (e) => { + const selectedIndex = e.target.value; + e.stopPropagation(); + if ( + props?.isPlaceholder && + props?.data?.Role !== "prefill" && + !selectDate?.date + ) { + setSelectDate((prev) => ({ + ...prev, + format: dateFormatList[selectedIndex]?.format + })); + } else { + setSelectDate(dateFormatList[selectedIndex]); + } + }; + const handleClearDate = () => { + setIsToday(false); + setSelectDate((prev) => ({ + ...prev, + date: "" + })); + }; return ( <> {/* 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. */} @@ -889,10 +939,8 @@ function Placeholder(props) { (props?.isAlllowModify && !props?.assignedWidgetId.includes(props.pos.key)) } - setSelectDate={setSelectDate} selectDate={selectDate} startDate={startDate} - handleSaveDate={handleSaveDate} xPos={props.xPos} calculateFont={calculateFont} setCellCount={setCellCount} @@ -902,22 +950,18 @@ function Placeholder(props) { )}
-
-
+
+
{t("format")} : + + {selectDate.format} +
- - {selectDate.format} - -
-
-
- {t("font-size")} : - -
-
- {t("color")} : - - + {props?.data?.Role !== "prefill" && props?.isPlaceholder && ( + <> +
+ {t("set-date")} : + ( +
+ + +
+ )} + closeOnScroll={true} + selected={getDefaultDate( + selectDate?.date, + selectDate?.format + )} + popperPlacement="top-end" + customInput={} + onChange={(date) => { + setIsToday(false); + const isDateChange = true; + const dateObj = { + date: date, + format: selectDate.format + }; + handleGetFormatDate(dateObj, isDateChange); + }} + dateFormat={ + selectDate + ? selectDate?.format + : props.pos?.options?.validation?.format + ? props.pos?.options?.validation?.format + : "MM/dd/yyyy" + } + portalId="root-portal" + /> + + handleClearDate()} + className="underline text-blue-500 cursor-pointer md:ml-2" + > + {t("clear")} + +
+
+ {statusArr.map((data, ind) => { + return ( +
+ + setFormdata({ + ...formdata, + status: data.toLowerCase() + }) + } + checked={ + formdata.status.toLowerCase() === data.toLowerCase() + } + /> +
+ {t(`widget-status.${data}`)} +
+
+ ); + })} +
+ + )} + +
+
+ {t("font-size")} : + +
+
+ {t("color")} : + + +
-
- {props?.isPlaceholder && props?.data?.Role !== "prefill" && ( -
- setIsDateReadOnly(!isDateReadOnly)} - /> -
- )} + )} +
); diff --git a/apps/OpenSign/src/components/pdf/PrefillWidgetsModal.jsx b/apps/OpenSign/src/components/pdf/PrefillWidgetsModal.jsx index 07e7735764..c5acf973ba 100644 --- a/apps/OpenSign/src/components/pdf/PrefillWidgetsModal.jsx +++ b/apps/OpenSign/src/components/pdf/PrefillWidgetsModal.jsx @@ -53,7 +53,6 @@ function PrefillWidgetModal(props) { const loadedSet = useRef(new Set()); const initializedRef = useRef(false); // prevent rerun on state updates const prefillImg = useSelector((state) => state.widget.prefillImg); - const [uniqueWidget, setUniqueWidget] = useState([]); const [image, setImage] = useState(null); const [imageLoaders, setImageLoaders] = useState({}); const [currentWidget, setCurrentWidget] = useState(""); @@ -68,7 +67,7 @@ function PrefillWidgetModal(props) { ); // useMemo to memoize the calculation of unique widgets - const memoizedUniqueWidget = useMemo(() => { + const uniqueWidget = useMemo(() => { //functions to used remove duplicate name values across all pages if (!props.prefillData) return []; //This will help us track which name values have already been encountered across all pages. @@ -119,10 +118,6 @@ function PrefillWidgetModal(props) { savePrefillImg(); }, [props.xyPosition]); - useEffect(() => { - setUniqueWidget(memoizedUniqueWidget); - }, [memoizedUniqueWidget]); - useEffect(() => { if (totalImages > 0 && loadedImages === totalImages) { setLoading(false); diff --git a/apps/OpenSign/src/components/pdf/RenderAllPdfPage.jsx b/apps/OpenSign/src/components/pdf/RenderAllPdfPage.jsx index fdcf159793..879f1cacf6 100644 --- a/apps/OpenSign/src/components/pdf/RenderAllPdfPage.jsx +++ b/apps/OpenSign/src/components/pdf/RenderAllPdfPage.jsx @@ -85,9 +85,12 @@ function RenderAllPdfPage(props) { alert(t("only-pdf-allowed")); return; } - const mb = Math.round(file?.size / Math.pow(1024, 2)); - if (mb > maxFileSize) { - alert(`${t("file-alert-1")} ${maxFileSize} MB`); + const fileSize = + maxFileSize; + const pdfsize = file?.size; + const fileSizeBytes = fileSize * 1024 * 1024; + if (pdfsize > fileSizeBytes) { + alert(`${t("file-alert-1")} ${fileSize} MB`); removeFile(e); return; } @@ -144,6 +147,13 @@ function RenderAllPdfPage(props) { useObjectStreams: false }); const pdfBuffer = base64ToArrayBuffer(pdfBase64); + const pdfsize = pdfBuffer?.byteLength; + const fileSizeBytes = fileSize * 1024 * 1024; + if (pdfsize > fileSizeBytes) { + alert(`${t("file-alert-1")} ${fileSize} MB`); + removeFile(e); + return; + } props.setPdfArrayBuffer(pdfBuffer); props.setPdfBase64Url(pdfBase64); props.setIsUploadPdf && props.setIsUploadPdf(true); diff --git a/apps/OpenSign/src/components/pdf/WidgetsValueModal.jsx b/apps/OpenSign/src/components/pdf/WidgetsValueModal.jsx index 24c5bbb21f..fc89126a89 100644 --- a/apps/OpenSign/src/components/pdf/WidgetsValueModal.jsx +++ b/apps/OpenSign/src/components/pdf/WidgetsValueModal.jsx @@ -21,7 +21,9 @@ import { convertTextToImg, convertJpegToPng, convertBase64ToFile, - generatePdfName + generatePdfName, + getDefaultDate, + getDefaultFormat } from "../../constant/Utils"; import CellsWidget from "./CellsWidget"; import DatePicker from "react-datepicker"; @@ -45,22 +47,6 @@ import { emailRegex } from "../../constant/const"; import RegexParser from "regex-parser"; import { saveToMySign } from "../../utils/widgetUtils"; -//function to get default format -const getDefaultFormat = (dateFormat) => dateFormat || "MM/dd/yyyy"; -//function to convert formatted date to new Date() format -const getDefaultDate = (dateStr, format) => { - //get valid date format for moment to convert formatted date to new Date() format - const formats = changeDateToMomentFormat(format); - const parsedDate = moment(dateStr, formats); - let date; - if (parsedDate.isValid()) { - date = new Date(parsedDate.toISOString()); - return date; - } else { - date = new Date(); - return date; - } -}; const fontOptions = [ { value: "Fasthand" }, { value: "Dancing Script" }, @@ -175,7 +161,7 @@ function WidgetsValueModal(props) { currWidgetsDetails?.options?.response, currWidgetsDetails?.options?.validation?.format ) - : new Date() + : "" ); useEffect(() => { dispatch(setScrollTriggerId(currWidgetsDetails?.key)); @@ -256,9 +242,7 @@ function WidgetsValueModal(props) { setXyPosition, uniqueId, false, - data?.format, - currWidgetsDetails?.options?.fontSize || 12, - currWidgetsDetails?.options?.fontColor || "black" + data?.format ); setSelectDate({ date: date, format: data?.format }); }; @@ -880,13 +864,14 @@ function WidgetsValueModal(props) { onClick={onClick} ref={ref} > - {value} + {value ? value : "Select date"}
)); ExampleCustomInput.displayName = "ExampleCustomInput"; //function to set onchange date const handleOnDateChange = (date) => { + setWidgetValue(date); setStartDate(date); }; const handleOnchangeTextBox = (e) => { @@ -1470,52 +1455,59 @@ function WidgetsValueModal(props) { ); case "date": return ( -
- ( -
- - -
- )} - closeOnScroll={true} - selected={startDate} - onChange={(date) => handleOnDateChange(date)} - popperPlacement="top-end" - customInput={} - dateFormat={ - selectDate - ? selectDate?.format - : currWidgetsDetails?.options?.validation?.format - ? currWidgetsDetails?.options?.validation?.format - : "MM/dd/yyyy" - } - portalId="root-portal" - /> +
+
+ ( +
+ + +
+ )} + closeOnScroll={true} + selected={startDate} + onChange={(date) => handleOnDateChange(date)} + popperPlacement="top-end" + customInput={} + dateFormat={ + selectDate + ? selectDate?.format + : currWidgetsDetails?.options?.validation?.format + ? currWidgetsDetails?.options?.validation?.format + : "MM/dd/yyyy" + } + portalId="root-portal" + /> +
+
+ + {currWidgetsDetails?.options?.validation?.format} + +
); case "email": @@ -1595,9 +1587,6 @@ function WidgetsValueModal(props) { const isCheckBox = !currWidgetsDetails.options?.isReadOnly && currWidgetsDetails.type === "checkbox"; - const isRadio = - !currWidgetsDetails?.options?.isReadOnly && - currWidgetsDetails?.type === radioButtonWidget; if (isCheckBox) { //get minimum required count if exist const minCount = diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js index e479b1fcf1..8c69311991 100644 --- a/apps/OpenSign/src/constant/Utils.js +++ b/apps/OpenSign/src/constant/Utils.js @@ -410,9 +410,14 @@ export const changeDateToMomentFormat = (format) => { return "L"; } }; -export const addWidgetOptions = (type, signer, placeholder, widgetValue) => { +export const addWidgetOptions = ( + type, + signer, + placeholder, + role, + widgetValue +) => { let defaultOpt; - //condition to handle widgets name field if (placeholder) { const countSameWidget = placeholder?.reduce((count, page) => { return count + page.pos.filter((item) => item.type === type).length; @@ -472,7 +477,7 @@ export const addWidgetOptions = (type, signer, placeholder, widgetValue) => { : "MM/dd/yyyy"; return { ...defaultOpt, - response: getDate(signer?.DateFormat), + response: role === "prefill" ? getDate(signer?.DateFormat) : "", validation: { format: dateFormat, type: "date-format" } }; } @@ -1002,7 +1007,7 @@ export const onChangeInput = ( dateFormat, fontSize, fontColor, - isDateReadOnly + dateDetails ) => { const isSigners = xyPosition.some( (data) => data.signerPtr || data.Role === "prefill" @@ -1034,9 +1039,18 @@ export const onChangeInput = ( options: { ...position.options, response: value, - fontSize: fontSize, - fontColor: fontColor, - isReadOnly: isDateReadOnly || false, + fontSize: fontSize ? fontSize : position.options?.fontSize, + fontColor: fontColor + ? fontColor + : position.options?.fontColor, + isReadOnly: + dateDetails?.isReadOnly !== "undefined" + ? dateDetails?.isReadOnly + : position.options?.isReadOnly, + status: + dateDetails?.status !== "undefined" + ? dateDetails?.status + : position.options?.status, validation: { type: "date-format", format: dateFormat // This indicates the required date format explicitly. @@ -1996,7 +2010,17 @@ export const embedWidgetsToDoc = async ( } else if (isTextTypeWidget) { let textContent = ""; if (position?.options?.response) { - textContent = position.options?.response; + if ( + position.type === "date" && + position.options?.response === "today" + ) { + const getFormat = changeDateToMomentFormat( + position?.options?.validation?.format + ); + textContent = moment().format(getFormat); + } else { + textContent = position.options?.response; + } } else if (position?.options?.defaultValue) { textContent = position?.options?.defaultValue; } @@ -3448,18 +3472,7 @@ export const updateDateWidgetsRes = ( placeHolder: item?.placeHolder?.map((ph) => ({ ...ph, pos: ph?.pos?.map((widget) => { - // only for date widgets *and* missing response - if (widget.type === "date" && !widget.options.response) { - return { - ...widget, - options: { - ...widget.options, - response: getDate( - changeDateToMomentFormat(widget.options.validation.format) - ) - } - }; - } else if ( + if ( ["name", "email", "job title", "company"].includes(widget.type) && !widget.options.defaultValue && !widget.options.response @@ -3593,6 +3606,7 @@ export const handleCheckResponse = (checkUser, setminRequiredCount) => { //in `defaultValue` variable is used to get how many checkbox checked by default const defaultValue = requiredCheckbox[i].options?.defaultValue?.length; + const checkboxValue = response ? response : defaultValue; //condition to check parseMin and parseMax greater than 0 then consider it as a required check box if ( parseMin > 0 && @@ -3607,7 +3621,10 @@ export const handleCheckResponse = (checkUser, setminRequiredCount) => { setminRequiredCount(parseMin); } //else condition to validate minimum required checkbox - else if (parseMin > 0 && (parseMin > response || !response)) { + else if ( + parseMin > 0 && + (parseMin > checkboxValue || !checkboxValue) + ) { if (!showAlert) { showAlert = true; widgetKey = requiredCheckbox[i].key; @@ -3806,7 +3823,7 @@ export const sendEmailToSigners = async ( htmlReqBody, variables ); - } else if (defaultMail) { + } else if (defaultMail?.body && defaultMail?.subject) { const mailBody = defaultMail?.body; const mailSubject = defaultMail.subject; const replacedRequestBody = mailBody.replace(/"/g, "'"); @@ -4034,3 +4051,19 @@ export const handleDeleteWidget = (key, Id, pageNumber, signerPos) => { } } }; +//function to convert formatted date to new Date() format +export const getDefaultDate = (dateStr, format) => { + //get valid date format for moment to convert formatted date to new Date() format + const formats = changeDateToMomentFormat(format); + const parsedDate = moment(dateStr, formats); + let date; + if (parsedDate.isValid()) { + date = new Date(parsedDate.toISOString()); + return date; + } else if (dateStr === "today") { + date = new Date(); + return date; + } +}; +//function to get default format +export const getDefaultFormat = (dateFormat) => dateFormat || "MM/dd/yyyy"; diff --git a/apps/OpenSign/src/constant/const.js b/apps/OpenSign/src/constant/const.js index dc3c1fe674..8a213716ad 100644 --- a/apps/OpenSign/src/constant/const.js +++ b/apps/OpenSign/src/constant/const.js @@ -9,7 +9,7 @@ export const getThemeIconColor = () => { return theme === "opensigndark" ? "#CCCCCC" : "#686968"; }; export const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; -export const maxFileSize = 10; // 10MB export const maxTitleLength = 250; // 250 characters export const maxNoteLength = 200; // 200 characters export const maxDescriptionLength = 500; // 500 characters +export const maxFileSize = 80; // for cloud 10MB / 80MB for self-hosted diff --git a/apps/OpenSign/src/pages/DebugPdf.jsx b/apps/OpenSign/src/pages/DebugPdf.jsx index 1b45c40331..461427b5bb 100644 --- a/apps/OpenSign/src/pages/DebugPdf.jsx +++ b/apps/OpenSign/src/pages/DebugPdf.jsx @@ -27,7 +27,7 @@ function processDimensions(x, y, width, height) { }; } const DebugPdf = () => { - const {t} = useTranslation() + const { t } = useTranslation(); const { width } = useWindowSize(); const [pdf, setPdf] = useState(""); const [isModal, setIsModal] = useState(true); diff --git a/apps/OpenSign/src/pages/Form.jsx b/apps/OpenSign/src/pages/Form.jsx index db680bfca2..495bc76d7c 100644 --- a/apps/OpenSign/src/pages/Form.jsx +++ b/apps/OpenSign/src/pages/Form.jsx @@ -98,6 +98,8 @@ const Forms = (props) => { extUserData?.IsTourEnabled === false ? "false" : "true"; + const fileSize = + maxFileSize; useEffect(() => { handleReset(); return () => abortController.abort(); @@ -136,11 +138,10 @@ const Forms = (props) => { return; } // setFormData((prev) => ({ ...prev, file: files[0] })); - const totalMb = Math.round( - files.reduce((sum, f) => sum + f.size, 0) / Math.pow(1024, 2) - ); - if (totalMb > maxFileSize) { - alert(`${t("file-alert-1")} ${maxFileSize} MB`); + const totalBytes = Math.round(files.reduce((sum, f) => sum + f.size, 0)); // in bytes + const fileSizeBytes = fileSize * 1024 * 1024; + if (totalBytes > fileSizeBytes) { + alert(`${t("file-alert-1")} ${fileSize} MB`); setFileUpload(""); setSelectedFiles([]); removeFile(e); @@ -336,6 +337,7 @@ const Forms = (props) => { } catch (error) { alert(error.message); setSelectedFiles([]); + removeFile(e); } }; // `isValidURL` is used to check valid webhook url diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.jsx b/apps/OpenSign/src/pages/PdfRequestFiles.jsx index 05c1516173..27ce4f7551 100644 --- a/apps/OpenSign/src/pages/PdfRequestFiles.jsx +++ b/apps/OpenSign/src/pages/PdfRequestFiles.jsx @@ -1512,6 +1512,7 @@ function PdfRequestFiles( dragTypeValue, owner, filterSignerPos?.placeHolder, + null, widgetValue ), Width: widgetWidth / (containerScale * scale), @@ -1548,6 +1549,7 @@ function PdfRequestFiles( dragTypeValue, owner, filterSignerPos?.placeHolder, + null, widgetValue ), Width: widgetWidth / (containerScale * scale), diff --git a/apps/OpenSign/src/pages/PlaceHolderSign.jsx b/apps/OpenSign/src/pages/PlaceHolderSign.jsx index b77051098c..d058c69ea5 100644 --- a/apps/OpenSign/src/pages/PlaceHolderSign.jsx +++ b/apps/OpenSign/src/pages/PlaceHolderSign.jsx @@ -553,7 +553,8 @@ function PlaceHolderSign() { options: addWidgetOptions( dragTypeValue, owner, - filterSignerPos?.placeHolder + filterSignerPos?.placeHolder, + roleName ), Width: widgetWidth / (containerScale * scale), Height: widgetHeight / (containerScale * scale) @@ -588,7 +589,8 @@ function PlaceHolderSign() { options: addWidgetOptions( dragTypeValue, owner, - filterSignerPos?.placeHolder + filterSignerPos?.placeHolder, + roleName ), Width: widgetWidth / (containerScale * scale), Height: widgetHeight / (containerScale * scale) @@ -2045,12 +2047,12 @@ function PlaceHolderSign() { setSignBtnPosition={setSignBtnPosition} pageNumber={pageNumber} pdfBase64Url={pdfBase64Url} - signedUrl={pdfDetails?.[0]?.SignedUrl || ""} setPdfArrayBuffer={setPdfArrayBuffer} setPdfBase64Url={setPdfBase64Url} setIsUploadPdf={setIsUploadPdf} pdfArrayBuffer={pdfArrayBuffer} isMergePdfBtn={true} + pdfDetails={pdfDetails} /> {/* pdf render view */}
@@ -2070,6 +2072,7 @@ function PlaceHolderSign() { setAllPages={setAllPages} setPageNumber={setPageNumber} setIsTour={setPlaceholderTour} + pdfDetails={pdfDetails} />
{/* this modal is used show alert set placeholder for all signers before send mail */} diff --git a/apps/OpenSign/src/pages/Report.jsx b/apps/OpenSign/src/pages/Report.jsx index c5caf1acae..8d89eb7f68 100644 --- a/apps/OpenSign/src/pages/Report.jsx +++ b/apps/OpenSign/src/pages/Report.jsx @@ -37,6 +37,7 @@ const Report = () => { // Number of documents to fetch per API call const docLimit = 20; + // below useEffect is call when id param change useEffect(() => { setReportName(""); diff --git a/apps/OpenSign/src/pages/SignyourselfPdf.jsx b/apps/OpenSign/src/pages/SignyourselfPdf.jsx index 2399caac8d..1c3a3d8838 100644 --- a/apps/OpenSign/src/pages/SignyourselfPdf.jsx +++ b/apps/OpenSign/src/pages/SignyourselfPdf.jsx @@ -1250,12 +1250,12 @@ function SignYourSelf() { pageNumber={pageNumber} containerWH={containerWH} pdfBase64Url={pdfBase64Url} - signedUrl={pdfDetails?.[0]?.SignedUrl || ""} setPdfArrayBuffer={setPdfArrayBuffer} setPdfBase64Url={setPdfBase64Url} setIsUploadPdf={setIsUploadPdf} pdfArrayBuffer={pdfArrayBuffer} isMergePdfBtn={!pdfDetails?.[0]?.IsCompleted} + pdfDetails={pdfDetails} />
{ setPrefillSigner([utils?.prefillObj()]); } setSignersData(updatedSigners); - setUniqueId(updatedSigners[0].Id); - setBlockColor(updatedSigners[0].blockColor); + setUniqueId(updatedSigners[0]?.Id); + setBlockColor(updatedSigners[0]?.blockColor); setIsSelectId(0); } else { const updatedSigners = documentData[0].Signers.map((x, index) => ({ @@ -358,8 +358,8 @@ const TemplatePlaceholder = () => { Role: "Role " + (index + 1) })); setSignersData(updatedSigners); - setUniqueId(updatedSigners[0].Id); - setBlockColor(updatedSigners[0].blockColor); + setUniqueId(updatedSigners[0]?.Id); + setBlockColor(updatedSigners[0]?.blockColor); setPrefillSigner([utils?.prefillObj()]); } } else { @@ -437,7 +437,6 @@ const TemplatePlaceholder = () => { const addPositionOfSignature = (item, monitor) => { getSignerPos(item, monitor); }; - // `getSignerPos` is used to get placeholder position when user place it and save it in array const getSignerPos = (item, monitor) => { if (uniqueId) { @@ -483,7 +482,8 @@ const TemplatePlaceholder = () => { options: addWidgetOptions( dragTypeValue, owner, - filterSignerPos?.placeHolder + filterSignerPos?.placeHolder, + roleName ), Width: widgetWidth / (containerScale * scale), Height: widgetHeight / (containerScale * scale) @@ -517,7 +517,8 @@ const TemplatePlaceholder = () => { options: addWidgetOptions( dragTypeValue, owner, - filterSignerPos?.placeHolder + filterSignerPos?.placeHolder, + roleName ), Width: widgetWidth / (containerScale * scale), Height: widgetHeight / (containerScale * scale) @@ -614,7 +615,6 @@ const TemplatePlaceholder = () => { setIsAddRole(true); } }; - const tourAddRole = [ { selector: '[data-tut="reactourAddbtn"]', @@ -1774,12 +1774,12 @@ const TemplatePlaceholder = () => { setSignBtnPosition={setSignBtnPosition} pageNumber={pageNumber} pdfBase64Url={pdfBase64Url} - signedUrl={pdfDetails?.[0]?.SignedUrl || ""} setPdfArrayBuffer={setPdfArrayBuffer} setPdfBase64Url={setPdfBase64Url} setIsUploadPdf={setIsUploadPdf} pdfArrayBuffer={pdfArrayBuffer} isMergePdfBtn={true} + pdfDetails={pdfDetails} /> {/* pdf render view */} @@ -1799,6 +1799,7 @@ const TemplatePlaceholder = () => { allPages={allPages} setAllPages={setAllPages} setPageNumber={setPageNumber} + pdfDetails={pdfDetails} />
{ const width = reduceWidth; const isBottom = position === "bottom" ? "items-end pb-2 !bg-black/10" : ""; + const crossBtnColor = crossColor ?? "text-base-content"; return ( <> {isOpen && ( @@ -38,7 +40,7 @@ const ModalUi = ({ )} {showClose && (