diff --git a/EnvelopeGenerator.Web/wwwroot/js/app.js b/EnvelopeGenerator.Web/wwwroot/js/app.js index 69b0a82f..99988412 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/app.js +++ b/EnvelopeGenerator.Web/wwwroot/js/app.js @@ -14,8 +14,8 @@ class App { async init() { // Load PSPDFKit - this.pdfKit = await UI.loadPSPDFKit(this.documentBytes, this.container, this.licenseKey, this.locale) - UI.addToolbarItems(this.pdfKit, this.handleClick.bind(this)) + this.pdfKit = await loadPSPDFKit(this.documentBytes, this.container, this.licenseKey, this.locale) + addToolbarItems(this.pdfKit, this.handleClick.bind(this)) this.pdfKit.addEventListener( 'annotations.load', diff --git a/EnvelopeGenerator.Web/wwwroot/js/app.min.js b/EnvelopeGenerator.Web/wwwroot/js/app.min.js index 802af7b4..fa0498b9 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/app.min.js +++ b/EnvelopeGenerator.Web/wwwroot/js/app.min.js @@ -1,3 +1,3 @@ -class App{constructor(n,t,i,r,u,f){this.container=f??`#${this.constructor.name.toLowerCase()}`;this.envelopeKey=n;this.pdfKit=null;this.currentDocument=t.envelope.documents[0];this.currentReceiver=t.receiver;this.signatureCount=t.envelope.documents[0].elements.length;this.envelopeReceiver=t;this.documentBytes=i;this.licenseKey=r;this.locale=u}async init(){this.pdfKit=await UI.loadPSPDFKit(this.documentBytes,this.container,this.licenseKey,this.locale);UI.addToolbarItems(this.pdfKit,this.handleClick.bind(this));this.pdfKit.addEventListener("annotations.load",this.handleAnnotationsLoad.bind(this));this.pdfKit.addEventListener("annotations.change",this.handleAnnotationsChange.bind(this));this.pdfKit.addEventListener("annotations.create",this.handleAnnotationsCreate.bind(this));this.pdfKit.addEventListener("annotations.willChange",()=>{Comp.ActPanel.Toggle()});try{await createAnnotations(this.currentDocument,this.pdfKit)}catch(n){console.error("Error loading annotations:",n)}[...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.pdfKit.createAttachment(s),c=createImageAnnotation(new PSPDFKit.Geometry.Rect({left:r,top:u,width:n,height:i}),t.pageIndex,h);this.pdfKit.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=`/Envelope/${this.envelopeKey}`);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(` +class App{constructor(n,t,i,r,u,f){this.container=f??`#${this.constructor.name.toLowerCase()}`;this.envelopeKey=n;this.pdfKit=null;this.currentDocument=t.envelope.documents[0];this.currentReceiver=t.receiver;this.signatureCount=t.envelope.documents[0].elements.length;this.envelopeReceiver=t;this.documentBytes=i;this.licenseKey=r;this.locale=u}async init(){this.pdfKit=await loadPSPDFKit(this.documentBytes,this.container,this.licenseKey,this.locale);addToolbarItems(this.pdfKit,this.handleClick.bind(this));this.pdfKit.addEventListener("annotations.load",this.handleAnnotationsLoad.bind(this));this.pdfKit.addEventListener("annotations.change",this.handleAnnotationsChange.bind(this));this.pdfKit.addEventListener("annotations.create",this.handleAnnotationsCreate.bind(this));this.pdfKit.addEventListener("annotations.willChange",()=>{Comp.ActPanel.Toggle()});try{await createAnnotations(this.currentDocument,this.pdfKit)}catch(n){console.error("Error loading annotations:",n)}[...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.pdfKit.createAttachment(s),c=createImageAnnotation(new PSPDFKit.Geometry.Rect({left:r,top:u,width:n,height:i}),t.pageIndex,h);this.pdfKit.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=`/Envelope/${this.envelopeKey}`);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?reload():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.pdfKit.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.pdfKit.save()}catch(i){return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1}try{const t=await signEnvelope(await n);if(t.ok)return!0;if(t.status===403)return Swal.fire({title:"Warnung",text:"Umschlag ist nicht mehr verfügbar.",icon:"warning"}),!1;throw new Error;}catch(i){return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1}}else return!1})}async validateAnnotations(n){const t=await getAnnotations(this.pdfKit),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.pdfKit)}return n}} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/wwwroot/js/ui.js b/EnvelopeGenerator.Web/wwwroot/js/ui.js index df127c46..6e2401c9 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/ui.js +++ b/EnvelopeGenerator.Web/wwwroot/js/ui.js @@ -1,188 +1,181 @@ -class UI { - static allowedToolbarItems = [ - 'sidebar-thumbnails', - 'sidebar-document-ouline', - 'sidebar-bookmarks', - 'pager', - 'pan', - 'zoom-out', - 'zoom-in', - 'zoom-mode', - 'spacer', - 'search', - 'export-pdf' - ] +function loadPSPDFKit(arrayBuffer, container, licenseKey, locale) { + return PSPDFKit.load({ + inlineWorkers: false, + locale: locale, + licenseKey: licenseKey, + styleSheets: ['/css/site.css'], + container: container, + document: arrayBuffer, + annotationPresets: getPresets(), + electronicSignatures: { + creationModes: ['DRAW', 'TYPE', 'IMAGE'], + }, + initialViewState: new PSPDFKit.ViewState({ + sidebarMode: PSPDFKit.SidebarMode.THUMBNAILS, + }), + isEditableAnnotation: function (annotation) { + // Check if the annotation is a signature + // This will allow new signatures, but not allow edits. + if (annotation.isSignature || annotation.description == 'FRAME') { + return false + } - // Load the PSPDFKit UI by setting a target element as the container to render in - // and a arraybuffer which represents the document that should be displayed. - static Instance - static loadPSPDFKit(arrayBuffer, container, licenseKey, locale) { - UI.Instance = PSPDFKit.load({ - inlineWorkers: false, - locale: locale, - licenseKey: licenseKey, - styleSheets: ['/css/site.css'], - container: container, - document: arrayBuffer, - annotationPresets: UI.getPresets(), - electronicSignatures: { - creationModes: ['DRAW', 'TYPE', 'IMAGE'], + return true + + //return !annotation.isSignature; + }, + customRenderers: { + Annotation: annotationRenderer, + }, + }); +} + +const allowedToolbarItems = [ + 'sidebar-thumbnails', + 'sidebar-document-ouline', + 'sidebar-bookmarks', + 'pager', + 'pan', + 'zoom-out', + 'zoom-in', + 'zoom-mode', + 'spacer', + 'search', + 'export-pdf' +] + +function addToolbarItems(instance, handler) { + var toolbarItems = instance.toolbarItems.filter((item) => allowedToolbarItems.includes(item.type)); + + if (IS_READONLY) + toolbarItems = toolbarItems.concat(getReadOnlyItems(handler)); + else + toolbarItems = toolbarItems.concat(getWritableItems(handler)); + + if (!IS_DESKTOP_SIZE && !IS_READONLY) + toolbarItems = toolbarItems.concat(getMobileWritableItems(handler)); + + instance.setToolbarItems(toolbarItems) +} + +function annotationRenderer(data) { + // leave everything as is + return null +} + +function createElementFromHTML(html) { + const el = document.createElement('div') + el.innerHTML = html.trim() + + return el.firstChild +} + +const getWritableItems = function (callback) { + return [ + { + type: 'custom', + id: 'button-share', + className: 'button-share', + title: 'Teilen', + onPress() { + callback('SHARE') }, - initialViewState: new PSPDFKit.ViewState({ - sidebarMode: PSPDFKit.SidebarMode.THUMBNAILS, - }), - isEditableAnnotation: function (annotation) { - // Check if the annotation is a signature - // This will allow new signatures, but not allow edits. - if (annotation.isSignature || annotation.description == 'FRAME') { - return false - } - - return true - - //return !annotation.isSignature; - }, - customRenderers: { - Annotation: UI.annotationRenderer, - }, - }) - - return UI.Instance; - } - - static addToolbarItems(instance, handler) { - var toolbarItems = instance.toolbarItems.filter((item) => UI.allowedToolbarItems.includes(item.type)); - - if (IS_READONLY) - toolbarItems = toolbarItems.concat(UI.getReadOnlyItems(handler)); - else - toolbarItems = toolbarItems.concat(UI.getWritableItems(handler)); - - if (!IS_DESKTOP_SIZE && !IS_READONLY) - toolbarItems = toolbarItems.concat(UI.getMobileWritableItems(handler)); - - instance.setToolbarItems(toolbarItems) - } - - static annotationRenderer(data) { - // leave everything as is - return null - } - - static createElementFromHTML(html) { - const el = document.createElement('div') - el.innerHTML = html.trim() - - return el.firstChild - } - - static getWritableItems = function (callback) { - return [ - { - type: 'custom', - id: 'button-share', - className: 'button-share', - title: 'Teilen', - onPress() { - callback('SHARE') - }, - icon: ` + icon: ` `, + }, + { + type: 'custom', + id: 'button-logout', + className: 'button-logout', + title: 'logout', + onPress() { + callback('LOGOUT') }, - { - type: 'custom', - id: 'button-logout', - className: 'button-logout', - title: 'logout', - onPress() { - callback('LOGOUT') - }, - icon: ` + icon: ` ` - }, - { - type: 'custom', - id: 'mock', - className: 'mock', - title: 'Mock', - icon: `` - } - ]; - } + }, + { + type: 'custom', + id: 'mock', + className: 'mock', + title: 'Mock', + icon: `` + } + ]; +} - static getReadOnlyItems = function (callback) { - return [ - { - type: 'custom', - id: 'button-copy-url', - className: 'button-copy-url', - title: 'Teilen', - onPress() { - callback('COPY_URL') - }, - icon: ` +const getReadOnlyItems = function (callback) { + return [ + { + type: 'custom', + id: 'button-copy-url', + className: 'button-copy-url', + title: 'Teilen', + onPress() { + callback('COPY_URL') + }, + icon: ` `, - } - ]; - } + } + ]; +} - static getMobileWritableItems = function (callback) { - return [ - { - type: 'custom', - id: 'button-finish', - className: 'button-finish', - onPress() { - callback('FINISH') - }, - icon: `