const ActionType = { Created: 0, Saved: 1, Sent: 2, EmailSent: 3, Delivered: 4, Seen: 5, Signed: 6, Rejected: 7, } class App { constructor(container, envelopeKey) { this.container = container this.envelopeKey = envelopeKey // Initialize classes console.debug('Initializing classes..') this.UI = new UI() this.Network = new Network() this.Annotation = new Annotation() this.Instance = null this.currentDocument = null this.currentReceiver = null this.signatureCount = 0 } // 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 console.debug('Loading envelope from database..') const envelopeResponse = await this.Network.getEnvelope(this.envelopeKey) if (envelopeResponse.fatal) { return Swal.fire({ title: 'Fehler', text: 'Umschlag konnte nicht geladen werden!', icon: 'error', }) } if (envelopeResponse.error) { return Swal.fire({ title: 'Warnung', text: 'Umschlag ist nicht mehr verfügbar.', icon: 'warning', }) } this.currentDocument = envelopeResponse.data.envelope.documents[0] this.currentReceiver = envelopeResponse.data.receiver // Load the document from the filestore console.debug('Loading document from filestore') const documentResponse = await this.Network.getDocument( this.envelopeKey, this.currentDocument.id ) if (documentResponse.fatal || documentResponse.error) { console.error(documentResponse.error) return Swal.fire({ title: 'Fehler', text: 'Dokument konnte nicht geladen werden!', icon: 'error', }) } const arrayBuffer = documentResponse.data // Load PSPDFKit console.debug('Loading PSPDFKit..') this.Instance = await this.UI.loadPSPDFKit(arrayBuffer, this.container) this.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) ) // Load annotations into PSPDFKit console.debug('Loading annotations..') try { this.signatureCount = this.currentDocument.elements.length const annotations = this.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) { console.error(e) } } handleAnnotationsLoad(loadedAnnotations) { console.debug('annotations loaded', 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 this.Annotation.createAnnotationFrameBlob( this.currentReceiver.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 = this.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 } // Save changes before doing anything try { await this.Instance.save() } catch (e) { console.error(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) { console.error(e) return false } } async validateAnnotations(totalSignatures) { const annotations = await this.Annotation.getAnnotations(this.Instance) const filtered = annotations .map(a => a.toJS()) .filter(a => a.isSignature) console.log(annotations.length,"Signatures total!") console.log(filtered.length,"Signatures signed!") if (totalSignatures > filtered.length) { return false } else { return true } /*this.Instance.getFormFields().then(formFields => { formFields.forEach(formField => { console.log(formField.name, formField.toJS()); }); // Filter form fields by type formFields.filter(formField => ( formField instanceof PSPDFKit.FormFields.TextFormField )); // Get the total number of form fields const totalFormFields = formFields.size; console.log(totalFormFields) })*/ } 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 this.Annotation.deleteAnnotations(this.Instance) } return result } }