const ActionType = { Created: 0, Saved: 1, Sent: 2, EmailSent: 3, Delivered: 4, Seen: 5, Signed: 6, Rejected: 7, } class App { constructor(envelopeKey, envelopeReceiver, documentBytes, licenseKey, locale, container) { this.container = container ?? `#${this.constructor.name.toLowerCase()}`; this.envelopeKey = envelopeKey this.Network = new Network() this.Instance = null this.currentDocument = null this.currentReceiver = null this.signatureCount = 0; this.envelopeReceiver = envelopeReceiver; this.documentBytes = documentBytes; this.licenseKey = licenseKey; this.locale = locale; } // This function will be called from the ShowEnvelope.razor page // and will trigger loading of the Editor Interface async init() { // Load the envelope from the database this.currentDocument = this.envelopeReceiver.envelope.documents[0] this.currentReceiver = this.envelopeReceiver.receiver // Load the document from the filestore const documentResponse = this.documentBytes if (documentResponse.fatal || documentResponse.error) { return Swal.fire({ title: 'Fehler', text: 'Dokument konnte nicht geladen werden!', icon: 'error', }) } const arrayBuffer = this.documentBytes // Load PSPDFKit this.Instance = await UI.loadPSPDFKit(arrayBuffer, this.container, this.licenseKey, this.locale) UI.configurePSPDFKit(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(); }); // Load annotations into PSPDFKit try { this.signatureCount = this.currentDocument.elements.length const annotations = Annotation.createAnnotations(this.currentDocument) await this.Instance.create(annotations) const openResponse = await this.Network.openDocument(this.envelopeKey) if (openResponse.fatal || openResponse.error) { return Swal.fire({ title: 'Fehler', text: 'Umschlag konnte nicht geöffnet werden!', icon: 'error', }) } } catch (e) { } //add click events of external buttons [...document.getElementsByClassName('btn_refresh')].forEach(btn => btn.addEventListener('click', _ => this.handleClick('RESET'))); [...document.getElementsByClassName('btn_complete')].forEach(btn => btn.addEventListener('click', _ => this.handleClick('FINISH'))); } handleAnnotationsLoad(loadedAnnotations) { loadedAnnotations.toJS() } handleAnnotationsChange() { } async handleAnnotationsCreate(createdAnnotations) { const annotation = createdAnnotations.toJS()[0] const isFormField = !!annotation.formFieldName const isSignature = !!annotation.isSignature if (isFormField === false && isSignature === true) { const left = annotation.boundingBox.left - 20 const top = annotation.boundingBox.top - 20 const width = 150 const height = 75 const timestamp = new Date() const imageUrl = await Annotation.createAnnotationFrameBlob( this.envelopeReceiver.name, this.currentReceiver.signature, timestamp, width, height ) const request = await fetch(imageUrl) const blob = await request.blob() const imageAttachmentId = await this.Instance.createAttachment(blob) const frameAnnotation = Annotation.createImageAnnotation( new PSPDFKit.Geometry.Rect({ left: left, top: top, width: width, height: height, }), annotation.pageIndex, imageAttachmentId ) this.Instance.create(frameAnnotation) } } async handleClick(eventType) { let result = false switch (eventType) { case 'RESET': result = await this.handleReset(null) if (result.isConfirmed) { Swal.fire({ title: 'Erfolg', text: 'Dokument wurde zurückgesetzt', icon: 'info', }) } break case 'FINISH': result = await this.handleFinish(null) if (result == true) { // Redirect to success page after saving to database window.location.href = `/EnvelopeKey/${this.envelopeKey}/Success` } break case 'REJECT': alert('Dokument abgelent!') } } async handleFinish(event) { const validationResult = await this.validateAnnotations(this.signatureCount) if (validationResult === false) { Swal.fire({ title: 'Warnung', text: 'Es wurden nicht alle Signaturfelder ausgefüllt!', icon: 'warning', }) return false } return Swal.fire({ title: localized.confirmation, html: `
${localized.sigAgree}
`, icon: "question", showCancelButton: true, confirmButtonColor: "#3085d6", cancelButtonColor: "#d33", confirmButtonText: localized.finalize, cancelButtonText: localized.back }).then(async (result) => { if (result.isConfirmed) { //--- // Save changes before doing anything try { await this.Instance.save() } catch (e) { Swal.fire({ title: 'Fehler', text: 'Umschlag konnte nicht signiert werden!', icon: 'error', }) return false } // Export annotation data and save to database try { const json = await this.Instance.exportInstantJSON() const postEnvelopeResult = await this.Network.postEnvelope( this.envelopeKey, this.currentDocument.id, json ) if (postEnvelopeResult.fatal) { Swal.fire({ title: 'Fehler', text: 'Umschlag konnte nicht signiert werden!', icon: 'error', }) return false } if (postEnvelopeResult.error) { Swal.fire({ title: 'Warnung', text: 'Umschlag ist nicht mehr verfügbar.', icon: 'warning', }) return false } return true } catch (e) { return false } //--- } else return false; }); } async validateAnnotations(totalSignatures) { const annotations = await Annotation.getAnnotations(this.Instance) const filtered = annotations .map(a => a.toJS()) .filter(a => a.isSignature) if (totalSignatures > filtered.length) { return false } else { return true } } async handleReset(event) { const result = await Swal.fire({ title: 'Sind sie sicher?', text: 'Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?', icon: 'question', showCancelButton: true }) if (result.isConfirmed) { const result = await Annotation.deleteAnnotations(this.Instance) } return result } }