From 3b1d8a48b75003d759854119fe25b5053c19e43e Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs Date: Thu, 17 Apr 2025 06:34:06 +0000 Subject: [PATCH] v2.18.0 New Features: 1. Added support to recreate a new document from declined document without having to redo everything from scratch. 2. Added replace pdf file feature for Templates. PDF underlying a Template can now be replaced while keeping all the fields the same. 3. Introduced the ability to replace pdf file for in UpdateTemplate and CreateDocumentfromtemplate API. 4. Revamped the preferences menu UI. Bug Fixes: 1. Fixed issue with capital letters in contact emails via API. 2. Better validations & error handling in APIs --- .../public/locales/de/translation.json | 10 +- .../public/locales/en/translation.json | 10 +- .../public/locales/es/translation.json | 10 +- .../public/locales/fr/translation.json | 10 +- .../public/locales/it/translation.json | 10 +- .../src/assets/images/recreatedoc.png | Bin 0 -> 41662 bytes .../src/components/pdf/EditTemplate.js | 599 ++++++++++++------ .../shared/fields/DateFormatSelector.js | 2 +- apps/OpenSign/src/json/ReportJson.js | 10 +- apps/OpenSign/src/pages/Preferences.js | 563 ++++++++-------- .../OpenSign/src/pages/TemplatePlaceholder.js | 38 +- .../src/primitives/GetReportDisplay.js | 63 +- apps/OpenSignServer/Dockerhubfile | 2 +- apps/OpenSignServer/PDFDigitalSigner.jar | Bin 9216 -> 0 bytes apps/OpenSignServer/Utils.js | 39 ++ apps/OpenSignServer/cloud/main.js | 2 + .../cloud/parsefunction/pdf/DigitalSign.js | 35 - .../cloud/parsefunction/pdf/PDF.js | 28 +- .../cloud/parsefunction/recreateDocument.js | 36 ++ apps/OpenSignServer/pdfbox-app-3.0.4.jar | Bin 13454142 -> 0 bytes 20 files changed, 932 insertions(+), 535 deletions(-) create mode 100644 apps/OpenSign/src/assets/images/recreatedoc.png delete mode 100644 apps/OpenSignServer/PDFDigitalSigner.jar delete mode 100644 apps/OpenSignServer/cloud/parsefunction/pdf/DigitalSign.js create mode 100644 apps/OpenSignServer/cloud/parsefunction/recreateDocument.js delete mode 100644 apps/OpenSignServer/pdfbox-app-3.0.4.jar diff --git a/apps/OpenSign/public/locales/de/translation.json b/apps/OpenSign/public/locales/de/translation.json index e72a6d6b4e..e22aec5b4f 100644 --- a/apps/OpenSign/public/locales/de/translation.json +++ b/apps/OpenSign/public/locales/de/translation.json @@ -152,7 +152,8 @@ "Duplicate Template": "Vorlage duplizieren", "Duplicate": "Duplikat", "daily-mail-quota": "Tägliches E-Mail-Kontingent", - "Save as template": "Als Vorlage speichern" + "Save as template": "Als Vorlage speichern", + "Fix & resend": "Korrigieren und erneut senden" }, "report-heading": { "Sr.No": "Nr.", @@ -881,5 +882,10 @@ "contact-billing-at-opensign": "Um weitere Plätze hinzuzufügen, kontaktieren Sie bitte OpenSign™ unter <1>billing@opensignlabs.com für Unterstützung.", "title-length-alert": "Der Titel darf höchstens 250 Zeichen lang sein.", "note-length-alert": "Die Notiz darf höchstens 200 Zeichen lang sein.", - "description-length-alert": "Die Beschreibung darf höchstens 500 Zeichen lang sein." + "description-length-alert": "Die Beschreibung darf höchstens 500 Zeichen lang sein.", + "fix-&-resend-document": "Dokument korrigieren und erneut senden", + "do-you-want-recreate-document?": "Dadurch wird ein Entwurf aus diesem Dokument mit allen vorhandenen Feldern erstellt. Sind Sie sicher, dass Sie dieses Dokument neu erstellen möchten?", + "start-editing": "Bearbeitung starten", + "unsaved-changes-discard-them?": "Sie haben ungespeicherte Änderungen. Verwerfen?", + "yes-discard": "Ja, verwerfen" } diff --git a/apps/OpenSign/public/locales/en/translation.json b/apps/OpenSign/public/locales/en/translation.json index 2b2c3cd8e5..79b2635a82 100644 --- a/apps/OpenSign/public/locales/en/translation.json +++ b/apps/OpenSign/public/locales/en/translation.json @@ -152,7 +152,8 @@ "Duplicate Template": "Duplicate template", "Duplicate": "Duplicate", "daily-mail-quota": "Daily Email Quota", - "Save as template": "Save as template" + "Save as template": "Save as template", + "Fix & resend": "Fix & Resend" }, "report-heading": { "Sr.No": "Sr.No", @@ -881,5 +882,10 @@ "contact-billing-at-opensign": "To add more seats, please contact OpenSign™ at <1>billing@opensignlabs.com for assistance", "title-length-alert": "Title must be at most 250 characters long.", "note-length-alert": "Note must be at most 200 characters long.", - "description-length-alert": "Description must be at most 500 characters long." + "description-length-alert": "Description must be at most 500 characters long.", + "fix-&-resend-document": "Fix & Resend Document", + "do-you-want-recreate-document?": "This will create a draft from this document with all fields intact. Are you sure you want to recreate this document?", + "start-editing": "Start Editing", + "unsaved-changes-discard-them?": "You have unsaved changes. Discard them?", + "yes-discard": "Yes, Discard" } diff --git a/apps/OpenSign/public/locales/es/translation.json b/apps/OpenSign/public/locales/es/translation.json index c9605eb4b3..64bcb350f7 100644 --- a/apps/OpenSign/public/locales/es/translation.json +++ b/apps/OpenSign/public/locales/es/translation.json @@ -152,7 +152,8 @@ "Duplicate Template": "Plantilla duplicada", "Duplicate": "Duplicada", "daily-mail-quota": "Cuota diaria de correos electrónicos", - "Save as template": "Guardar como plantilla" + "Save as template": "Guardar como plantilla", + "Fix & resend": "Corregir y reenviar" }, "report-heading": { "Sr.No": "Nº", @@ -881,5 +882,10 @@ "contact-billing-at-opensign": "Para agregar más asientos, comuníquese con OpenSign™ a <1>billing@opensignlabs.com para obtener ayuda.", "title-length-alert": "El título debe tener como máximo 250 caracteres.", "note-length-alert": "La nota debe tener como máximo 200 caracteres.", - "description-length-alert": "La descripción debe tener como máximo 500 caracteres." + "description-length-alert": "La descripción debe tener como máximo 500 caracteres.", + "fix-&-resend-document": "Corregir y reenviar el documento", + "do-you-want-recreate-document?": "Esto creará un borrador a partir de este documento con todos los campos intactos. ¿Está seguro de que desea recrear este documento?", + "start-editing": "Comenzar a editar", + "unsaved-changes-discard-them?": "Tienes cambios sin guardar. ¿Deseas descartarlos?", + "yes-discard": "Sí, descartar" } diff --git a/apps/OpenSign/public/locales/fr/translation.json b/apps/OpenSign/public/locales/fr/translation.json index 7459aa7d92..e1b1883caa 100644 --- a/apps/OpenSign/public/locales/fr/translation.json +++ b/apps/OpenSign/public/locales/fr/translation.json @@ -173,7 +173,8 @@ "Duplicate Template": "dupliquer le modèle", "Duplicate": "Double", "daily-mail-quota": "Quota d'e-mails quotidien", - "Save as template": "Enregistrer comme modèle" + "Save as template": "Enregistrer comme modèle", + "Fix & resend": "Corriger et renvoyer" }, "report-help": { "Draft Documents": "Il s'agit de documents que vous avez commencés mais que vous n'avez pas finalisés pour envoi.", @@ -881,5 +882,10 @@ "contact-billing-at-opensign": "Pour ajouter plus de places, veuillez contacter OpenSign™ à l'adresse <1>billing@opensignlabs.com pour obtenir de l'aide.", "title-length-alert": "Le titre doit comporter au maximum 250 caractères.", "note-length-alert": "La note doit comporter au maximum 200 caractères.", - "description-length-alert": "La description doit comporter au maximum 500 caractères" + "description-length-alert": "La description doit comporter au maximum 500 caractères", + "fix-&-resend-document": "Corriger et renvoyer le document", + "do-you-want-recreate-document?": "Cela créera un brouillon à partir de ce document avec tous les champs intacts. Êtes-vous sûr de vouloir recréer ce document ?", + "start-editing": "Commencer l'édition", + "unsaved-changes-discard-them?": "Vous avez des modifications non enregistrées. Les supprimer ?", + "yes-discard": "Oui, supprimer" } diff --git a/apps/OpenSign/public/locales/it/translation.json b/apps/OpenSign/public/locales/it/translation.json index ea2f9e4dfc..2d81a2fad7 100644 --- a/apps/OpenSign/public/locales/it/translation.json +++ b/apps/OpenSign/public/locales/it/translation.json @@ -152,7 +152,8 @@ "Duplicate Template": "Duplica modello", "Duplicate": "Duplica", "daily-mail-quota": "Quota e-mail giornaliera", - "Save as template": "Salva come modello" + "Save as template": "Salva come modello", + "Fix & resend": "Correggi e reinvia" }, "report-heading": { "Sr.No": "Nr.", @@ -881,5 +882,10 @@ "contact-billing-at-opensign": " Per aggiungere altri posti, contattare OpenSign™ all'indirizzo <1>billing@opensignlabs.com per assistenza.", "title-length-alert": "Il titolo può contenere al massimo 250 caratteri.", "note-length-alert": "La nota può contenere al massimo 200 caratteri.", - "description-length-alert": " La descrizione può contenere al massimo 500 caratteri." + "description-length-alert": " La descrizione può contenere al massimo 500 caratteri.", + "fix-&-resend-document": "Correggi e reinvia il documento", + "do-you-want-recreate-document?": "Questo creerà una bozza da questo documento con tutti i campi intatti. Sei sicuro di voler ricreare questo documento?", + "start-editing": "Inizia a modificare", + "unsaved-changes-discard-them?": "Hai modifiche non salvate. Vuoi scartarle?", + "yes-discard": "Sì, scarta" } diff --git a/apps/OpenSign/src/assets/images/recreatedoc.png b/apps/OpenSign/src/assets/images/recreatedoc.png new file mode 100644 index 0000000000000000000000000000000000000000..3348345cc90eba29c68e212d998b3f18006d2a53 GIT binary patch literal 41662 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 { +const EditTemplate = ({ + title, + handleClose, + pdfbase64, + template, + onSuccess, + setPdfArrayBuffer, + setPdfBase64Url +}) => { const appName = "OpenSign™"; const { t } = useTranslation(); + const inputFileRef = useRef(null); const [formData, setFormData] = useState({ Name: template?.Name || "", Note: template?.Note || "", @@ -32,6 +49,31 @@ const EditTemplate = ({ template, onSuccess }) => { AllowModifications: template?.AllowModifications || false, TimeToCompleteDays: template?.TimeToCompleteDays || 15 }); + const [isUpdate, setIsUpdate] = useState(false); + const [showConfirm, setShowConfirm] = useState(false); + const [uploadPdf, setUploadPdf] = useState({ + name: "", + base64: "", + url: "" + }); + const handleDrop = (e) => { + e.preventDefault(); + const file = e.dataTransfer.files[0]; + handleFile(file); + }; + + const handleFile = (file) => { + if (file && file.type === "application/pdf") { + handleReplaceFileValdition(file); + // You can handle the file here + } else { + alert("Only pdf files are allowed."); + if (inputFileRef.current) inputFileRef.current.value = ""; + } + }; + const handleDragOver = (e) => { + e.preventDefault(); + }; // `isValidURL` is used to check valid webhook url function isValidURL(value) { @@ -44,9 +86,63 @@ const EditTemplate = ({ template, onSuccess }) => { } const handleStrInput = (e) => { + setIsUpdate(true); setFormData({ ...formData, [e.target.name]: e.target.value }); }; + const getPdfMetadataHash = async (pdfBytes) => { + const pdfDoc = await PDFDocument.load(pdfBytes); + const pages = pdfDoc.getPages(); + const metaString = pages + .map((page, index) => { + const { width, height } = page.getSize(); + return `${index + 1}:${Math.round(width)}x${Math.round(height)}`; + }) + .join("|"); + const encoder = new TextEncoder(); + const data = encoder.encode(metaString); + const hashBuffer = await crypto.subtle.digest("SHA-256", data); + return Array.from(new Uint8Array(hashBuffer)) + .map((b) => b.toString(16).padStart(2, "0")) + .join(""); + }; + + const handleFileInput = async (e) => { + const file = e.target.files[0]; + if (!file) return; + handleReplaceFileValdition(file); + }; + const handleReplaceFileValdition = async (file) => { + try { + const basePdfBytes = base64ToArrayBuffer(pdfbase64); + const expectedHash = await getPdfMetadataHash(basePdfBytes); + const fileReader = new FileReader(); + fileReader.onload = async (event) => { + const uploadedPdfBytes = event.target.result; + const uploadedHash = await getPdfMetadataHash(uploadedPdfBytes); + + if (expectedHash === uploadedHash) { + const arrayBuffer = uploadedPdfBytes; + const uint8Array = new Uint8Array(arrayBuffer); + const binaryString = Array.from(uint8Array) + .map((b) => String.fromCharCode(b)) + .join(""); + const base64 = btoa(binaryString); + const pdfName = generatePdfName(16); + setIsUpdate(true); + setUploadPdf((prev) => ({ ...prev, name: pdfName, base64: base64 })); + // alert("✅ PDFs match (based on page number, width, height)"); + } else { + alert("❌ PDF do NOT match based on page number, width, height"); + if (inputFileRef.current) inputFileRef.current.value = ""; + } + }; + fileReader.readAsArrayBuffer(file); + } catch (err) { + alert("Error: " + err.message); + if (inputFileRef.current) inputFileRef.current.value = ""; + } + }; // Define a function to handle form submission const handleSubmit = async (e) => { e.preventDefault(); @@ -67,6 +163,19 @@ const EditTemplate = ({ template, onSuccess }) => { alert(t("description-length-alert")); return; } + let pdfUrl; + if (uploadPdf?.base64) { + pdfUrl = await convertBase64ToFile(uploadPdf.name, uploadPdf.base64); + setUploadPdf((prev) => ({ ...prev, url: pdfUrl })); + const pdfBuffer = base64ToArrayBuffer(uploadPdf.base64); + setPdfArrayBuffer && setPdfArrayBuffer(pdfBuffer); + setPdfBase64Url && setPdfBase64Url(uploadPdf.base64); + const tenantId = + localStorage.getItem("TenantId") || + template?.ExtUserPtr?.TenantId?.objectId; + const buffer = atob(uploadPdf.base64); + SaveFileSize(buffer.length, pdfUrl, tenantId); + } const isChecked = formData.SendinOrder === "true" ? true : false; const isTourEnabled = formData?.IsTourEnabled === "false" ? false : true; const AutoReminder = formData?.AutomaticReminders || false; @@ -88,6 +197,7 @@ const EditTemplate = ({ template, onSuccess }) => { } const data = { ...formData, + ...(pdfUrl ? { URL: pdfUrl } : {}), SendinOrder: isChecked, IsEnableOTP: IsEnableOTP, IsTourEnabled: isTourEnabled, @@ -99,6 +209,7 @@ const EditTemplate = ({ template, onSuccess }) => { // `handleNotifySignChange` is trigger when user change radio of notify on signatures const handleNotifySignChange = (value) => { + setIsUpdate(true); setFormData((obj) => ({ ...obj, NotifyOnSignatures: value })); }; const handleBcc = (data) => { @@ -108,226 +219,304 @@ const EditTemplate = ({ template, onSuccess }) => { Name: item?.label, Email: item?.email })); + setIsUpdate(true); setFormData((prev) => ({ ...prev, Bcc: trimEmail })); } }; + + const handleEditTemplateClose = () => { + if (isUpdate) { + setShowConfirm(true); + } else { + handleClose(); + } + }; + const discardChanges = () => { + setShowConfirm(false); + handleClose(); + }; return ( -
-
-
-
- -
- {getFileName(template.URL)} -
-
-
- - handleStrInput(e)} - onInvalid={(e) => e.target.setCustomValidity(t("input-required"))} - onInput={(e) => e.target.setCustomValidity("")} - required - className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs" - /> -
-
- - handleStrInput(e)} - className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs" - /> -
-
- - handleStrInput(e)} - className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs" - /> + + +
+

+ {t("unsaved-changes-discard-them?")} +

+
+ +
-
- -
-
- -
{t("yes")}
+
+ +
+
+ +
+ +
inputFileRef?.current?.click()} + > +
-
- -
{t("no")}
+ handleFileInput(e)} + onInvalid={(e) => + e.target.setCustomValidity(t("input-required")) + } + onInput={(e) => e.target.setCustomValidity("")} + /> + {uploadPdf?.name && ( +
inputFileRef?.current?.click()} + className="mt-2 cursor-pointer op-input op-input-bordered op-input-sm focus:outline-none py-2 font-semibold w-full text-xs" + > + selected:{" "} + {uploadPdf?.url + ? `${uploadPdf?.name}.pdf` + : getFileName(template.URL)} +
+ )} +
+
+ + handleStrInput(e)} + onInvalid={(e) => + e.target.setCustomValidity(t("input-required")) + } + onInput={(e) => e.target.setCustomValidity("")} + required + className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs" + /> +
+
+ + handleStrInput(e)} + className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs" + /> +
+
+ + handleStrInput(e)} + className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs" + /> +
+
+ +
+
+ +
{t("yes")}
+
+
+ +
{t("no")}
+
-
-
-