diff --git a/EnvelopeGenerator.Web/wwwroot/js/annotation.js b/EnvelopeGenerator.Web/wwwroot/js/annotation.js index 793c00f6..628583d9 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/annotation.js +++ b/EnvelopeGenerator.Web/wwwroot/js/annotation.js @@ -1,32 +1,8 @@ -class Annotation { - static async createAnnotations(document, instance) { - const signatures = [] + +async function createAnnotations(document, instance) { + const signatures = []; - for (var element of document.elements) { - const [annotation, formField, annotation_date, formFieldDate, annotation_city, formFieldCity, annotation_position, formFieldPosition, annotation_date_label, formFieldDateLabel, annotation_city_label, formFieldCityLabel, annotation_position_label, formFieldPositionLabel] = await Annotation.createSignature(element) - signatures.push(annotation) - signatures.push(formField) - signatures.push(annotation_date) - signatures.push(formFieldDate) - signatures.push(annotation_city) - signatures.push(formFieldCity) - signatures.push(annotation_position) - signatures.push(formFieldPosition) - - signatures.push(annotation_date_label) - signatures.push(formFieldDateLabel) - - signatures.push(annotation_city_label) - signatures.push(formFieldCityLabel) - - signatures.push(annotation_position_label) - signatures.push(formFieldPositionLabel) - } - - await instance.create(signatures) - } - - static async createSignature(element) { + for(var element of document.elements) { const annotParams = await getAnnotationParams(element.left, element.top); const page = element.page - 1 @@ -179,167 +155,148 @@ readOnly: true }) - return [annotation, formField, annotation_date, formFieldDate, annotation_city, formFieldCity, annotation_position, formFieldPosition, annotation_date_label, formFieldDateLabel, annotation_city_label, formFieldCityLabel, annotation_position_label, formFieldPositionLabel] + signatures.push(annotation) + signatures.push(formField) + signatures.push(annotation_date) + signatures.push(formFieldDate) + signatures.push(annotation_city) + signatures.push(formFieldCity) + signatures.push(annotation_position) + signatures.push(formFieldPosition) + + signatures.push(annotation_date_label) + signatures.push(formFieldDateLabel) + + signatures.push(annotation_city_label) + signatures.push(formFieldCityLabel) + + signatures.push(annotation_position_label) + signatures.push(formFieldPositionLabel) } - static createTextBox(element) { - const id = PSPDFKit.generateInstantId() - const width = Annotation.inchToPoint(element.width) - const height = Annotation.inchToPoint(element.height) - const top = Annotation.inchToPoint(element.top) - height / 2 - const left = Annotation.inchToPoint(element.left) - width / 2 - const page = element.page - 1 + await instance.create(signatures); +} - //shift - top += height + 10 - - const annotation = new PSPDFKit.Annotations.WidgetAnnotation({ - id: id, - pageIndex: page, - formFieldName: id, - backgroundColor: PSPDFKit.Color.YELLOW, - blendMode: 'multiply', - boundingBox: new PSPDFKit.Geometry.Rect({ - width, - height, - top, - left, - }), - }) - - const formField = new PSPDFKit.FormFields.SignatureFormField({ - name: id, - annotationIds: PSPDFKit.Immutable.List([annotation.id]), - }) - - return [annotation, formField] - } - - static async getAnnotations(instance) { - const array = await Promise.all( - Array.from({ length: instance.totalPageCount }).map((_, pageIndex) => - instance.getAnnotations(pageIndex) - ) +async function getAnnotations(instance) { + const array = await Promise.all( + Array.from({ length: instance.totalPageCount }).map((_, pageIndex) => + instance.getAnnotations(pageIndex) ) + ) - return array.flatMap((annotations) => - annotations.reduce((acc, annotation) => acc.concat(annotation), []) - ) - } + return array.flatMap((annotations) => + annotations.reduce((acc, annotation) => acc.concat(annotation), []) + ) +} - static async deleteAnnotations(instance) { - const allAnnotations = await Annotation.getAnnotations(instance) - const pageAnnotations = allAnnotations.filter(Annotation.isSignature) - //deleting all Annotations - return await instance.delete(pageAnnotations) - } +async function deleteAnnotations(instance) { + const allAnnotations = await getAnnotations(instance) + const pageAnnotations = allAnnotations.filter(isSignature) + //deleting all Annotations + return await instance.delete(pageAnnotations) +} - static async validateAnnotations(instance) { - const allAnnotations = await Annotation.getAnnotations(instance) - const pageAnnotations = allAnnotations - .map((annotation) => { - return annotation - }) - - return true - } - - static isSignature(annotation) { - return !!annotation.isSignature || annotation.description == 'FRAME' - } - - static createImageAnnotation(boundingBox, pageIndex, imageAttachmentId) { - const frameAnnotation = new PSPDFKit.Annotations.ImageAnnotation({ - pageIndex: pageIndex, - isSignature: false, - readOnly: true, - locked: true, - lockedContents: true, - contentType: 'image/png', - imageAttachmentId, - description: 'FRAME', - boundingBox: boundingBox, +async function validateAnnotations(instance) { + const allAnnotations = await getAnnotations(instance) + const pageAnnotations = allAnnotations + .map((annotation) => { + return annotation }) - return frameAnnotation - } - static async createAnnotationFrameBlob(receiverName, receiverSignature, timestamp, width, height) { - Comp.SignatureProgress.SignedCount += 1; - const canvas = document.createElement('canvas') - const scale = 4 - const fontSize = 10 + return true +} - canvas.width = width * scale - canvas.height = height * scale +function isSignature(annotation) { + return !!annotation.isSignature || annotation.description == 'FRAME' +} - const ctx = canvas.getContext('2d') - // This supposedly makes the lines and text less blurry - // See: https://stackoverflow.com/questions/8696631/canvas-drawings-like-lines-are-blurry - ctx.translate(0.5, 0.5) +function createImageAnnotation(boundingBox, pageIndex, imageAttachmentId) { + const frameAnnotation = new PSPDFKit.Annotations.ImageAnnotation({ + pageIndex: pageIndex, + isSignature: false, + readOnly: true, + locked: true, + lockedContents: true, + contentType: 'image/png', + imageAttachmentId, + description: 'FRAME', + boundingBox: boundingBox, + }) + return frameAnnotation +} - // This also should make the lines and text less blurry - ctx.textRendering = "geometricPrecision" +async function createAnnotationFrameBlob(receiverName, receiverSignature, timestamp, width, height) { + Comp.SignatureProgress.SignedCount += 1; + const canvas = document.createElement('canvas') + const scale = 4 + const fontSize = 10 - const date = timestamp - const dateString = date.toLocaleString('de-DE') + canvas.width = width * scale + canvas.height = height * scale - const signatureLength = 100 * scale - const signatureString = receiverSignature.substring(0, 15) + "…" + const ctx = canvas.getContext('2d') + // This supposedly makes the lines and text less blurry + // See: https://stackoverflow.com/questions/8696631/canvas-drawings-like-lines-are-blurry + ctx.translate(0.5, 0.5) - ctx.beginPath() + // This also should make the lines and text less blurry + ctx.textRendering = "geometricPrecision" - ctx.moveTo(30 * scale, 10 * scale) - ctx.lineTo(signatureLength, 10 * scale) + const date = timestamp + const dateString = date.toLocaleString('de-DE') - ctx.moveTo(30 * scale, 10 * scale) - ctx.arcTo(10 * scale, 10 * scale, 10 * scale, 30 * scale, 20 * scale) + const signatureLength = 100 * scale + const signatureString = receiverSignature.substring(0, 15) + "…" - ctx.moveTo(10 * scale, 30 * scale) - ctx.arcTo(10 * scale, 50 * scale, 30 * scale, 50 * scale, 20 * scale) + ctx.beginPath() - ctx.moveTo(30 * scale, 50 * scale) - ctx.lineTo(signatureLength, 50 * scale) + ctx.moveTo(30 * scale, 10 * scale) + ctx.lineTo(signatureLength, 10 * scale) - ctx.strokeStyle = 'darkblue' - ctx.stroke() + ctx.moveTo(30 * scale, 10 * scale) + ctx.arcTo(10 * scale, 10 * scale, 10 * scale, 30 * scale, 20 * scale) - ctx.fillStyle = 'black' - ctx.font = `${fontSize * scale}px sans-serif` - ctx.fillText('Signed by', 15 * scale, 10 * scale) - ctx.fillText(receiverName, 15 * scale, 60 * scale) - ctx.fillText(signatureString, 15 * scale, 70 * scale) + ctx.moveTo(10 * scale, 30 * scale) + ctx.arcTo(10 * scale, 50 * scale, 30 * scale, 50 * scale, 20 * scale) - return new Promise((resolve) => { - canvas.toBlob((blob) => { - const url = URL.createObjectURL(blob) - resolve(url) - }) + ctx.moveTo(30 * scale, 50 * scale) + ctx.lineTo(signatureLength, 50 * scale) + + ctx.strokeStyle = 'darkblue' + ctx.stroke() + + ctx.fillStyle = 'black' + ctx.font = `${fontSize * scale}px sans-serif` + ctx.fillText('Signed by', 15 * scale, 10 * scale) + ctx.fillText(receiverName, 15 * scale, 60 * scale) + ctx.fillText(signatureString, 15 * scale, 70 * scale) + + return new Promise((resolve) => { + canvas.toBlob((blob) => { + const url = URL.createObjectURL(blob) + resolve(url) }) - } + }) +} - static inchToPoint(inch) { - return inch * 72 - } +//required +requiredFieldNames = new Array() - //required - static #requiredFieldNames = new Array() +function markFieldAsRequired(formField) { + requiredFieldNames.push(formField.name) +} - static markFieldAsRequired(formField) { - this.#requiredFieldNames.push(formField.name) - } +function isFieldRequired(formField) { + return requiredFieldNames.includes(formField.name) +} - static isFieldRequired(formField) { - return this.#requiredFieldNames.includes(formField.name) - } +//city +cityFieldNames = new Array() - //city - static #cityFieldNames = new Array() +function markFieldAsCity(formField) { + cityFieldNames.push(formField.name) +} - static markFieldAsCity(formField) { - this.#cityFieldNames.push(formField.name) - } - - static isCityField(formField) { - return this.#cityFieldNames.includes(formField.name) - } +function isCityField(formField) { + return cityFieldNames.includes(formField.name) } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/wwwroot/js/app.js b/EnvelopeGenerator.Web/wwwroot/js/app.js index 883f171f..93e21526 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/app.js +++ b/EnvelopeGenerator.Web/wwwroot/js/app.js @@ -70,7 +70,7 @@ class App { // Load annotations into PSPDFKit try { this.signatureCount = this.currentDocument.elements.length - await Annotation.createAnnotations(this.currentDocument, this.Instance) + await createAnnotations(this.currentDocument, this.Instance) const openResponse = await this.Network.openDocument(this.envelopeKey) @@ -109,7 +109,7 @@ class App { const height = 75 const timestamp = new Date() - const imageUrl = await Annotation.createAnnotationFrameBlob( + const imageUrl = await createAnnotationFrameBlob( this.envelopeReceiver.name, this.currentReceiver.signature, timestamp, @@ -121,7 +121,7 @@ class App { const blob = await request.blob() const imageAttachmentId = await this.Instance.createAttachment(blob) - const frameAnnotation = Annotation.createImageAnnotation( + const frameAnnotation = createImageAnnotation( new PSPDFKit.Geometry.Rect({ left: left, top: top, @@ -222,7 +222,7 @@ class App { const iFormFieldValues = await iJSON.formFieldValues; //check required - const iReqFields = iFormFieldValues.filter(f => Annotation.isFieldRequired(f)) + const iReqFields = iFormFieldValues.filter(f => isFieldRequired(f)) const hasEmptyReq = iReqFields.some(f => (f.value === undefined || f.value === null || f.value === "")) if (hasEmptyReq) { @@ -236,7 +236,7 @@ class App { //check city const city_regex = new RegExp("^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$") - const iCityFields = iFormFieldValues.filter(f => Annotation.isCityField(f)) + const iCityFields = iFormFieldValues.filter(f => isCityField(f)) for (var f of iCityFields) if (!IS_MOBILE_DEVICE && !city_regex.test(f.value)) { Swal.fire({ @@ -322,7 +322,7 @@ class App { async validateAnnotations(totalSignatures) { - const annotations = await Annotation.getAnnotations(this.Instance) + const annotations = await getAnnotations(this.Instance) const filtered = annotations .map(a => a.toJS()) .filter(a => a.isSignature) @@ -343,7 +343,7 @@ class App { }) if (result.isConfirmed) { - const result = await Annotation.deleteAnnotations(this.Instance) + const result = await deleteAnnotations(this.Instance) } return result diff --git a/EnvelopeGenerator.Web/wwwroot/js/app.min.js b/EnvelopeGenerator.Web/wwwroot/js/app.min.js index ba32108f..b2e22c52 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/app.min.js +++ b/EnvelopeGenerator.Web/wwwroot/js/app.min.js @@ -1,3 +1,3 @@ -const ActionType={Created:0,Saved:1,Sent:2,EmailSent:3,Delivered:4,Seen:5,Signed:6,Rejected:7};class App{constructor(n,t,i,r,u,f){this.container=f??`#${this.constructor.name.toLowerCase()}`;this.envelopeKey=n;this.Network=new Network;this.Instance=null;this.currentDocument=null;this.currentReceiver=null;this.signatureCount=0;this.envelopeReceiver=t;this.documentBytes=i;this.licenseKey=r;this.locale=u}async init(){this.currentDocument=this.envelopeReceiver.envelope.documents[0];this.currentReceiver=this.envelopeReceiver.receiver;const n=this.documentBytes;if(n.fatal||n.error)return Swal.fire({title:"Fehler",text:"Dokument konnte nicht geladen werden!",icon:"error"});const t=this.documentBytes;this.Instance=await UI.loadPSPDFKit(t,this.container,this.licenseKey,this.locale);UI.addToolbarItems(this.Instance,this.handleClick.bind(this));this.Instance.addEventListener("annotations.load",this.handleAnnotationsLoad.bind(this));this.Instance.addEventListener("annotations.change",this.handleAnnotationsChange.bind(this));this.Instance.addEventListener("annotations.create",this.handleAnnotationsCreate.bind(this));this.Instance.addEventListener("annotations.willChange",()=>{Comp.ActPanel.Toggle()});try{this.signatureCount=this.currentDocument.elements.length;await Annotation.createAnnotations(this.currentDocument,this.Instance);const n=await this.Network.openDocument(this.envelopeKey);if(n.fatal||n.error)return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht geöffnet werden!",icon:"error"})}catch(i){}[...document.getElementsByClassName("btn_refresh")].forEach(n=>n.addEventListener("click",()=>this.handleClick("RESET")));[...document.getElementsByClassName("btn_complete")].forEach(n=>n.addEventListener("click",()=>this.handleClick("FINISH")));[...document.getElementsByClassName("btn_reject")].forEach(n=>n.addEventListener("click",()=>this.handleClick("REJECT")))}handleAnnotationsLoad(n){n.toJS()}handleAnnotationsChange(){}async handleAnnotationsCreate(n){const t=n.toJS()[0],i=!!t.formFieldName,r=!!t.isSignature;if(i===!1&&r===!0){const r=t.boundingBox.left-20,u=t.boundingBox.top-20,n=150,i=75,f=new Date,e=await Annotation.createAnnotationFrameBlob(this.envelopeReceiver.name,this.currentReceiver.signature,f,n,i),o=await fetch(e),s=await o.blob(),h=await this.Instance.createAttachment(s),c=Annotation.createImageAnnotation(new PSPDFKit.Geometry.Rect({left:r,top:u,width:n,height:i}),t.pageIndex,h);this.Instance.create(c)}}async handleClick(n){let t=!1;switch(n){case"RESET":t=await this.handleReset(null);Comp.SignatureProgress.SignedCount=0;t.isConfirmed&&Swal.fire({title:"Erfolg",text:"Dokument wurde zurückgesetzt",icon:"info"});break;case"FINISH":t=await this.handleFinish(null);t==!0&&(window.location.href=`/EnvelopeKey/${this.envelopeKey}/Success`);break;case"REJECT":Swal.fire({title:localized.rejection,html:`
${localized.rejectionReasonQ}
`,icon:"question",input:"text",inputAttributes:{autocapitalize:"off"},showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.complete,cancelButtonText:localized.back,showLoaderOnConfirm:!0,preConfirm:async n=>{try{return await rejectEnvelope(n)}catch(t){Swal.showValidationMessage(` +const ActionType={Created:0,Saved:1,Sent:2,EmailSent:3,Delivered:4,Seen:5,Signed:6,Rejected:7};class App{constructor(n,t,i,r,u,f){this.container=f??`#${this.constructor.name.toLowerCase()}`;this.envelopeKey=n;this.Network=new Network;this.Instance=null;this.currentDocument=null;this.currentReceiver=null;this.signatureCount=0;this.envelopeReceiver=t;this.documentBytes=i;this.licenseKey=r;this.locale=u}async init(){this.currentDocument=this.envelopeReceiver.envelope.documents[0];this.currentReceiver=this.envelopeReceiver.receiver;const n=this.documentBytes;if(n.fatal||n.error)return Swal.fire({title:"Fehler",text:"Dokument konnte nicht geladen werden!",icon:"error"});const t=this.documentBytes;this.Instance=await UI.loadPSPDFKit(t,this.container,this.licenseKey,this.locale);UI.addToolbarItems(this.Instance,this.handleClick.bind(this));this.Instance.addEventListener("annotations.load",this.handleAnnotationsLoad.bind(this));this.Instance.addEventListener("annotations.change",this.handleAnnotationsChange.bind(this));this.Instance.addEventListener("annotations.create",this.handleAnnotationsCreate.bind(this));this.Instance.addEventListener("annotations.willChange",()=>{Comp.ActPanel.Toggle()});try{this.signatureCount=this.currentDocument.elements.length;await createAnnotations(this.currentDocument,this.Instance);const n=await this.Network.openDocument(this.envelopeKey);if(n.fatal||n.error)return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht geöffnet werden!",icon:"error"})}catch(i){}[...document.getElementsByClassName("btn_refresh")].forEach(n=>n.addEventListener("click",()=>this.handleClick("RESET")));[...document.getElementsByClassName("btn_complete")].forEach(n=>n.addEventListener("click",()=>this.handleClick("FINISH")));[...document.getElementsByClassName("btn_reject")].forEach(n=>n.addEventListener("click",()=>this.handleClick("REJECT")))}handleAnnotationsLoad(n){n.toJS()}handleAnnotationsChange(){}async handleAnnotationsCreate(n){const t=n.toJS()[0],i=!!t.formFieldName,r=!!t.isSignature;if(i===!1&&r===!0){const r=t.boundingBox.left-20,u=t.boundingBox.top-20,n=150,i=75,f=new Date,e=await createAnnotationFrameBlob(this.envelopeReceiver.name,this.currentReceiver.signature,f,n,i),o=await fetch(e),s=await o.blob(),h=await this.Instance.createAttachment(s),c=createImageAnnotation(new PSPDFKit.Geometry.Rect({left:r,top:u,width:n,height:i}),t.pageIndex,h);this.Instance.create(c)}}async handleClick(n){let t=!1;switch(n){case"RESET":t=await this.handleReset(null);Comp.SignatureProgress.SignedCount=0;t.isConfirmed&&Swal.fire({title:"Erfolg",text:"Dokument wurde zurückgesetzt",icon:"info"});break;case"FINISH":t=await this.handleFinish(null);t==!0&&(window.location.href=`/EnvelopeKey/${this.envelopeKey}/Success`);break;case"REJECT":Swal.fire({title:localized.rejection,html:`
${localized.rejectionReasonQ}
`,icon:"question",input:"text",inputAttributes:{autocapitalize:"off"},showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.complete,cancelButtonText:localized.back,showLoaderOnConfirm:!0,preConfirm:async n=>{try{return await rejectEnvelope(n)}catch(t){Swal.showValidationMessage(` Request failed: ${t} - `)}},allowOutsideClick:()=>!Swal.isLoading()}).then(n=>{if(n.isConfirmed){const t=n.value;t.ok?redirRejected():Swal.showValidationMessage(`Request failed: ${t.message}`)}});break;case"COPY_URL":const n=window.location.href.replace(/\/readonly/gi,"");navigator.clipboard.writeText(n).then(function(){bsNotify("Kopiert",{alert_type:"success",delay:4,icon_name:"check_circle"})}).catch(function(){bsNotify("Unerwarteter Fehler",{alert_type:"danger",delay:4,icon_name:"error"})});break;case"SHARE":Comp.ShareBackdrop.show();break;case"LOGOUT":await logout()}}async handleFinish(){const n=await this.Instance.exportInstantJSON(),t=await n.formFieldValues,r=t.filter(n=>Annotation.isFieldRequired(n)),u=r.some(n=>n.value===undefined||n.value===null||n.value==="");if(u)return Swal.fire({title:"Warnung",text:"Bitte füllen Sie alle Standortinformationen vollständig aus!",icon:"warning"}),!1;const f=new RegExp("^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$"),e=t.filter(n=>Annotation.isCityField(n));for(var i of e)if(!IS_MOBILE_DEVICE&&!f.test(i.value))return Swal.fire({title:"Warnung",text:`Bitte überprüfen Sie die eingegebene Ortsangabe "${i.value}" auf korrekte Formatierung. Beispiele für richtige Formate sind: München, Île-de-France, Sauðárkrókur, San Francisco, St. Catharines usw.`,icon:"warning"}),!1;const o=await this.validateAnnotations(this.signatureCount);return o===!1?(Swal.fire({title:"Warnung",text:"Es wurden nicht alle Signaturfelder ausgefüllt!",icon:"warning"}),!1):Swal.fire({title:localized.confirmation,html:`
${localized.sigAgree}
`,icon:"question",showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.finalize,cancelButtonText:localized.back}).then(async t=>{if(t.isConfirmed){try{await this.Instance.save()}catch(i){return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1}try{const i=await n,t=await this.Network.postEnvelope(this.envelopeKey,this.currentDocument.id,i);return t.fatal?(Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1):t.error?(Swal.fire({title:"Warnung",text:"Umschlag ist nicht mehr verfügbar.",icon:"warning"}),!1):!0}catch(i){return!1}}else return!1})}async validateAnnotations(n){const t=await Annotation.getAnnotations(this.Instance),i=t.map(n=>n.toJS()).filter(n=>n.isSignature);return n>i.length?!1:!0}async handleReset(){const n=await Swal.fire({title:"Sind sie sicher?",text:"Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?",icon:"question",showCancelButton:!0});if(n.isConfirmed){const n=await Annotation.deleteAnnotations(this.Instance)}return n}} \ No newline at end of file + `)}},allowOutsideClick:()=>!Swal.isLoading()}).then(n=>{if(n.isConfirmed){const t=n.value;t.ok?redirRejected():Swal.showValidationMessage(`Request failed: ${t.message}`)}});break;case"COPY_URL":const n=window.location.href.replace(/\/readonly/gi,"");navigator.clipboard.writeText(n).then(function(){bsNotify("Kopiert",{alert_type:"success",delay:4,icon_name:"check_circle"})}).catch(function(){bsNotify("Unerwarteter Fehler",{alert_type:"danger",delay:4,icon_name:"error"})});break;case"SHARE":Comp.ShareBackdrop.show();break;case"LOGOUT":await logout()}}async handleFinish(){const n=await this.Instance.exportInstantJSON(),t=await n.formFieldValues,r=t.filter(n=>isFieldRequired(n)),u=r.some(n=>n.value===undefined||n.value===null||n.value==="");if(u)return Swal.fire({title:"Warnung",text:"Bitte füllen Sie alle Standortinformationen vollständig aus!",icon:"warning"}),!1;const f=new RegExp("^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$"),e=t.filter(n=>isCityField(n));for(var i of e)if(!IS_MOBILE_DEVICE&&!f.test(i.value))return Swal.fire({title:"Warnung",text:`Bitte überprüfen Sie die eingegebene Ortsangabe "${i.value}" auf korrekte Formatierung. Beispiele für richtige Formate sind: München, Île-de-France, Sauðárkrókur, San Francisco, St. Catharines usw.`,icon:"warning"}),!1;const o=await this.validateAnnotations(this.signatureCount);return o===!1?(Swal.fire({title:"Warnung",text:"Es wurden nicht alle Signaturfelder ausgefüllt!",icon:"warning"}),!1):Swal.fire({title:localized.confirmation,html:`
${localized.sigAgree}
`,icon:"question",showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.finalize,cancelButtonText:localized.back}).then(async t=>{if(t.isConfirmed){try{await this.Instance.save()}catch(i){return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1}try{const i=await n,t=await this.Network.postEnvelope(this.envelopeKey,this.currentDocument.id,i);return t.fatal?(Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1):t.error?(Swal.fire({title:"Warnung",text:"Umschlag ist nicht mehr verfügbar.",icon:"warning"}),!1):!0}catch(i){return!1}}else return!1})}async validateAnnotations(n){const t=await getAnnotations(this.Instance),i=t.map(n=>n.toJS()).filter(n=>n.isSignature);return n>i.length?!1:!0}async handleReset(){const n=await Swal.fire({title:"Sind sie sicher?",text:"Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?",icon:"question",showCancelButton:!0});if(n.isConfirmed){const n=await deleteAnnotations(this.Instance)}return n}} \ No newline at end of file