From 6de7ec0050e717b6ed077a24375fa8de25118250 Mon Sep 17 00:00:00 2001 From: Jonathan Jenne Date: Wed, 4 Oct 2023 11:44:26 +0200 Subject: [PATCH] 04-10-2023 --- .../Entities/EnvelopeHistoryEntry.vb | 2 +- EnvelopeGenerator.Web/Handler/FileHandler.cs | 192 ++++++++++----- EnvelopeGenerator.Web/Program.cs | 7 +- EnvelopeGenerator.Web/Scripts/app.ts | 207 ++++++++-------- EnvelopeGenerator.Web/tsconfig.json | 2 +- EnvelopeGenerator.Web/wwwroot/js/app.js | 224 +++++++++--------- EnvelopeGenerator.Web/wwwroot/js/app.js.map | 2 +- 7 files changed, 358 insertions(+), 278 deletions(-) diff --git a/EnvelopeGenerator.Common/Entities/EnvelopeHistoryEntry.vb b/EnvelopeGenerator.Common/Entities/EnvelopeHistoryEntry.vb index 0814c9be..a1c91509 100644 --- a/EnvelopeGenerator.Common/Entities/EnvelopeHistoryEntry.vb +++ b/EnvelopeGenerator.Common/Entities/EnvelopeHistoryEntry.vb @@ -4,6 +4,6 @@ Public UserReference As String Public ActionDescription As String Public ActionDate As DateTime - + Public UserEmailAddress As String End Class diff --git a/EnvelopeGenerator.Web/Handler/FileHandler.cs b/EnvelopeGenerator.Web/Handler/FileHandler.cs index f5be8167..2b9ada41 100644 --- a/EnvelopeGenerator.Web/Handler/FileHandler.cs +++ b/EnvelopeGenerator.Web/Handler/FileHandler.cs @@ -1,8 +1,10 @@ -using EnvelopeGenerator.Common; +using DigitalData.Modules.Logging; +using EnvelopeGenerator.Common; using EnvelopeGenerator.Common.My.Resources; using EnvelopeGenerator.Web.Services; using Microsoft.Extensions.Primitives; using System.IO.Pipelines; +using System.Reflection.Metadata.Ecma335; namespace EnvelopeGenerator.Web.Handler { @@ -10,34 +12,30 @@ namespace EnvelopeGenerator.Web.Handler { public async static Task HandleFileDownload(HttpContext ctx, DatabaseService database, LoggingService logging) { - var logger = logging.LogConfig.GetLogger("FileHandler"); - string envelopeKey = (string)ctx.Request.RouteValues["envelopeKey"]; - - logger.Info("Downloading file with EnvelopeKey [{0}]", envelopeKey); - Tuple result = Helpers.DecodeEnvelopeReceiverId(envelopeKey); - logger.Info("EnvelopeUUID: [{0}]", result.Item1); - logger.Info("ReceiverSignature: [{0}]", result.Item2); + try + { + logger.Info("Handling file download."); - EnvelopeResponse response = database.LoadEnvelope(envelopeKey); - var envelope = response.Envelope; - logger.Info("Envelope [{0}] loaded", envelope.Id); - logger.Info("Contains [{0}] documents", envelope.Documents.Count); - logger.Info("Contains [{0}] receivers", envelope.Receivers.Count); + // Load Envelope from EnvelopeKey + string envelopeKey = EnsureValidEnvelopeKey(logger, ctx.Request); + EnvelopeResponse r = database.LoadEnvelope(envelopeKey); - int documentId = getDocumentIndex(ctx); - var document = getDocument(envelope, documentId); + // Get the document Index + int documentId = EnsureValidDocumentIndex(logger, ctx.Request); + var document = GetDocument(r.Envelope, documentId); - try - { + // Load the document from disk var bytes = await File.ReadAllBytesAsync(document.Filepath); logger.Info("Serving file, size: [{0}]", bytes.Length); + // Return the document as bytes return Results.File(bytes); } catch (Exception e) { + // Better error handling & reporting logger.Error(e); return Results.Problem(); @@ -47,89 +45,155 @@ namespace EnvelopeGenerator.Web.Handler public async static Task HandleFileUpload(HttpContext ctx, DatabaseService database, LoggingService logging) { var logger = logging.LogConfig.GetLogger("FileHandler"); - string envelopeKey = (string)ctx.Request.RouteValues["envelopeKey"]; - int documentId = int.Parse((string)ctx.Request.RouteValues["documentId"]); - logger.Info("Uploading file with EnvelopeKey [{0}]", envelopeKey); - - Tuple result = Helpers.DecodeEnvelopeReceiverId(envelopeKey); - logger.Info("EnvelopeUUID: [{0}]", result.Item1); - logger.Info("ReceiverSignature: [{0}]", result.Item2); - - EnvelopeResponse response = database.LoadEnvelope(envelopeKey); - var envelope = response.Envelope; - logger.Info("Envelope [{0}] loaded", envelope.Id); - logger.Info("Contains [{0}] documents", envelope.Documents.Count); - logger.Info("Contains [{0}] receivers", envelope.Receivers.Count); + try + { + logger.Info("Handling file upload."); - var document = envelope.Documents.Where(d => d.Id == documentId).FirstOrDefault(); + // Load Envelope from EnvelopeKey + string envelopeKey = EnsureValidEnvelopeKey(logger, ctx.Request); + EnvelopeResponse r = database.LoadEnvelope(envelopeKey); - if (document != null) - { - var path = document.Filepath; + // Get the document Index + int documentId = EnsureValidDocumentIndex(logger, ctx.Request); + var document = GetDocument(r.Envelope, documentId); - using FileStream fs = new(path, FileMode.Open); + using FileStream fs = new(document.Filepath, FileMode.Open); await ctx.Request.Body.CopyToAsync(fs); fs.Flush(); return Results.Ok(); } - else + catch (Exception e) { + // Better error handling & reporting + logger.Error(e); return Results.Problem(); } } - private static int getDocumentIndex(HttpContext ctx) + public async static Task HandleGetData(HttpContext ctx, DatabaseService database, LoggingService logging) { - int documentId = 0; - StringValues documentIndexString; - if (ctx.Request.Query.TryGetValue("index", out documentIndexString)) + var logger = logging.LogConfig.GetLogger("FileHandler"); + + try { - int.TryParse(documentIndexString.First(), out documentId); + logger.Info("Handling file download."); + + // Load Envelope from EnvelopeKey + string envelopeKey = EnsureValidEnvelopeKey(logger, ctx.Request); + EnvelopeResponse r = database.LoadEnvelope(envelopeKey); + + // Get the document Index + int documentId = EnsureValidDocumentIndex(logger, ctx.Request); + var document = GetDocument(r.Envelope, documentId); + + // Load the document from disk + var bytes = await File.ReadAllBytesAsync(document.Filepath); + logger.Info("Serving file, size: [{0}]", bytes.Length); + + // Return the envelope and additional data as json + return Results.Json(r); + } + catch (Exception e) + { + // Better error handling & reporting + logger.Error(e); + return Results.Problem(); - return documentId; + } } - private static EnvelopeDocument getDocument(Common.Envelope envelope, int documentId) + public async static Task HandlePostData(HttpContext ctx, DatabaseService database, LoggingService logging) { - var document = envelope.Documents.First(); - if (documentId > 0) + var logger = logging.LogConfig.GetLogger("FileHandler"); + + try { - var documentById = envelope.Documents. - Where(d => d.Id == documentId). - FirstOrDefault(); + logger.Info("Handling file download."); + + // Load Envelope from EnvelopeKey + string envelopeKey = EnsureValidEnvelopeKey(logger, ctx.Request); + EnvelopeResponse r = database.LoadEnvelope(envelopeKey); + + // Get the document Index + int documentId = EnsureValidDocumentIndex(logger, ctx.Request); + var document = GetDocument(r.Envelope, documentId); + } + catch (Exception e) + { + // Better error handling & reporting + logger.Error(e); + return Results.Problem(); + } + + var envelopeKey = ctx.Request.RouteValues["envelopeKey"] as string; + var documentIdString = ctx.Request.RouteValues["documentId"] as string; + + if (int.TryParse(documentIdString, out int documentId) == false) + { + return Results.Problem(); + } + + database.LoadDocument(documentId); + + return Results.Ok(); + } - if (documentById != null) + private static int EnsureValidDocumentIndex(Logger logger, HttpRequest request) + { + if (request.Query.TryGetValue("index", out StringValues documentIndexString)) + { + try { - document = documentById; + return int.Parse(documentIndexString.First()); } + catch (Exception e) + { + throw new ArgumentNullException("DocumentIndex", e); + } + } + else + { + throw new ArgumentNullException("DocumentIndex"); } - - return document; } - public static Task HandleGetData(HttpContext ctx, DatabaseService database, LoggingService logging) + private static string EnsureValidEnvelopeKey(Logger logger, HttpRequest request) { - var logger = logging.LogConfig.GetLogger("FileHandler"); - string envelopeKey = (string)ctx.Request.RouteValues["envelopeKey"]; + logger.Debug("Parsing EnvelopeKey.."); + var envelopeKey = request.RouteValues["envelopeKey"] as string; - logger.Info("Fetching data for envelope with EnvelopeKey [{0}]", envelopeKey); + if (string.IsNullOrEmpty(envelopeKey)) + throw new ArgumentNullException("EnvelopeKey"); Tuple result = Helpers.DecodeEnvelopeReceiverId(envelopeKey); - logger.Info("EnvelopeUUID: [{0}]", result.Item1); - logger.Info("ReceiverSignature: [{0}]", result.Item2); + logger.Debug("EnvelopeUUID: [{0}]", result.Item1); + logger.Debug("ReceiverSignature: [{0}]", result.Item2); + + if (string.IsNullOrEmpty(result.Item1)) + throw new ArgumentNullException("EnvelopeUUID"); + + if (string.IsNullOrEmpty(result.Item2)) + throw new ArgumentNullException("ReceiverSignature"); + + return envelopeKey; + } - var response = database.LoadEnvelope(envelopeKey); - var envelope = response.Envelope; - logger.Info("Envelope [{0}] loaded", envelope.Id); - logger.Info("Contains [{0}] documents", envelope.Documents.Count); - logger.Info("Contains [{0}] receivers", envelope.Receivers.Count); + private static EnvelopeDocument GetDocument(Common.Envelope envelope, int documentId) + { + var document = envelope.Documents. + Where(d => d.Id == documentId). + FirstOrDefault(); + if (document == null) + throw new ArgumentException("DocumentId"); - return Task.FromResult(Results.Json(response)); + return document; } + + } } diff --git a/EnvelopeGenerator.Web/Program.cs b/EnvelopeGenerator.Web/Program.cs index 84080bed..d2582264 100644 --- a/EnvelopeGenerator.Web/Program.cs +++ b/EnvelopeGenerator.Web/Program.cs @@ -35,9 +35,10 @@ app.UseStaticFiles(); app.UseRouting(); // Add file download endpoint -app.MapGet("/api/download/{envelopeKey}", FileHandler.HandleFileDownload); -app.MapPost("/api/upload/{envelopeKey}/{documentId}", FileHandler.HandleFileUpload); -app.MapGet("/api/get-data/{envelopeKey}", FileHandler.HandleGetData); +app.MapGet("/api/document/{envelopeKey}", FileHandler.HandleFileDownload); +app.MapPost("/api/document/{envelopeKey}/{documentId}", FileHandler.HandleFileUpload); +app.MapGet("/api/envelope/{envelopeKey}", FileHandler.HandleGetData); +app.MapPost("/api/envelope/{envelopeKey}/{documentId}", FileHandler.HandlePostData); // Blazor plumbing app.MapBlazorHub(); diff --git a/EnvelopeGenerator.Web/Scripts/app.ts b/EnvelopeGenerator.Web/Scripts/app.ts index 4c0ba4a6..1f86975f 100644 --- a/EnvelopeGenerator.Web/Scripts/app.ts +++ b/EnvelopeGenerator.Web/Scripts/app.ts @@ -15,28 +15,32 @@ export class App { public static currentDocument: Document; public static envelopeKey: string; - public static ui: UI; + public static UI: UI; + public static Network: Network; + public static Annotation: Annotation; // This function will be called in the ShowEnvelope.razor page // and will trigger loading of the Editor Interface public static async loadPDFFromUrl(container: string, envelopeKey: string) { - App.ui = new UI(); + App.UI = new UI(); + App.Network = new Network(); + App.Annotation = new Annotation(); console.debug("Loading PSPDFKit.."); - const envelopeObject: EnvelopeResponse = await App.loadData(`/api/get-data/${envelopeKey}`); + const envelopeObject: EnvelopeResponse = await App.Network.loadData(envelopeKey); App.envelopeKey = envelopeKey; App.currentDocument = envelopeObject.envelope.documents[0]; let arrayBuffer try { - arrayBuffer = await App.loadDocument(`/api/download/${envelopeKey}?id=${App.currentDocument.id}`); + arrayBuffer = await App.Network.loadDocument(envelopeKey, App.currentDocument.id); } catch (e) { console.error(e) } - App.Instance = await App.loadPSPDFKit(arrayBuffer, container) - App.configurePSPDFKit(this.Instance) + App.Instance = await App.UI.loadPSPDFKit(arrayBuffer, container) + App.UI.configurePSPDFKit(this.Instance, App.handleClick) console.debug(envelopeObject.envelope); console.debug("PSPDFKit configured!"); @@ -46,7 +50,7 @@ export class App { App.currentDocument.elements.forEach(function (element: Element) { console.log("Creating annotation for element", element.id) - const [annotation, formField] = App.createAnnotationFromElement(element) + const [annotation, formField] = App.Annotation.createAnnotationFromElement(element) annotations.push(annotation); annotations.push(formField); }) @@ -56,73 +60,15 @@ export class App { console.debug(createdAnnotations) } - private static inchToPoint(inch: number): number { - return inch * 72; - } - - // Makes a call to the supplied url and fetches the binary response as an array buffer - private static loadDocument(url: string): Promise { - return fetch(url, { credentials: "include" }) - .then(res => res.arrayBuffer()); - } - - // Makes a call to the supplied url and fetches the json response as an object - private static loadData(url: string): Promise { - return fetch(url, { credentials: "include" }) - .then(res => res.json()); - } - - private static postDocument(url: string, buffer: ArrayBuffer): Promise { - return fetch(url, { credentials: "include", method: "POST", body: buffer }) - .then(res => res.json()); - } - - // 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. - private static loadPSPDFKit(arrayBuffer: ArrayBuffer, container: string): Promise { - return PSPDFKit.load({ - container: container, - document: arrayBuffer, - autoSaveMode: DISABLED, - annotationPresets: App.ui.getPresets(), - electronicSignatures: { - creationModes: [DRAW, TYPE] - }, - isEditableAnnotation: function (annotation: WidgetAnnotation) { - // Check if the annotation is a signature - // This will allow new signatures, but not allow edits. - return !annotation.isSignature; - } - }) - } - - private static configurePSPDFKit(instance: Instance) { - instance.addEventListener("annotations.load", (loadedAnnotations) => { - console.log("annotations loaded", loadedAnnotations.toJS()); - }) - - instance.addEventListener("annotations.change", () => { - console.log("annotations changed") - }) - - instance.addEventListener("annotations.create", async (createdAnnotations) => { - console.log("annotations created", createdAnnotations.toJS()); - }) - - const filteredItems: Array = instance.toolbarItems - .filter((item) => App.ui.allowedToolbarItems.includes(item.type)) - - instance.setToolbarItems(filteredItems.concat(App.ui.getToolbarItems(App.handleClick))) - } - public static async handleClick(eventType: string) { switch (eventType) { case "RESET": - await App.handleReset(null) - break; + await App.handleReset(null) + break; + case "FINISH": - await App.handleFinish(null) - break; + await App.handleFinish(null) + break; } } @@ -133,31 +79,17 @@ export class App { console.log(json); const buffer = await App.Instance.exportPDF({ flatten: true }); - await App.uploadDocument(buffer, App.envelopeKey, App.currentDocument.id); + const result = await App.Network.postDocument(App.envelopeKey, App.currentDocument.id, buffer); + console.log(result) - alert("Signatur wird gespeichert!") } public static async handleReset(event: any) { if (confirm("Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?")) { - for (let i = 0; i < App.Instance.totalPageCount; i++) { - const annotations = await App.Instance.getAnnotations(i) - annotations.forEach((annotation) => { - //console.log(annotation) - // TODO: Delete only create signatures - //App.Instance.delete(annotation.id) - }) - } + const result = App.Annotation.deleteAnnotations(App.Instance) } } - private static async uploadDocument(buffer: ArrayBuffer, envelopeKey: string, documentId: number) { - - const result = await App.postDocument(`/api/upload/${envelopeKey}/${documentId}`, buffer); - - console.log(result) - } - private static async downloadDocument() { const buffer = await App.Instance.exportPDF({ flatten: true }); const supportsDownloadAttribute = HTMLAnchorElement.prototype.hasOwnProperty("download"); @@ -186,17 +118,17 @@ export class App { document.body.removeChild(a); } } +} - private static createAnnotationFromElement(element: Element): [annotation: WidgetAnnotation, formField: SignatureFormFieldType] { +class Annotation { + public createAnnotationFromElement(element: Element): [annotation: WidgetAnnotation, formField: SignatureFormFieldType] { const id = PSPDFKit.generateInstantId() - console.log("Creating Annotation", id) - - const width = App.inchToPoint(element.width) - const height = App.inchToPoint(element.height) - const top = App.inchToPoint(element.top) - (height / 2) - const left = App.inchToPoint(element.left) - (width / 2) + const width = this.inchToPoint(element.width) + const height = this.inchToPoint(element.height) + const top = this.inchToPoint(element.top) - (height / 2) + const left = this.inchToPoint(element.left) - (width / 2) const page = element.page - 1 - const annotation: WidgetAnnotation = App.createSignatureAnnotation(id, width, height, top, left, page) + const annotation: WidgetAnnotation = this.createSignatureAnnotation(id, width, height, top, left, page) console.log(annotation) const formField = new SignatureFormField({ @@ -208,8 +140,19 @@ export class App { return [annotation, formField] } + public async deleteAnnotations(instance: Instance): Promise { + let pageAnnotations = ( + await Promise.all(Array.from({ length: instance.totalPageCount }).map((_, pageIndex) => + instance.getAnnotations(pageIndex) + )) + ).flatMap((annotations) => + annotations.reduce((acc, annotation) => acc.concat(annotation), []) + ).filter((annotation) => !!annotation.isSignature); + //deleting all Annotations + return await instance.delete(pageAnnotations); + } - private static createSignatureAnnotation(id: string, width: number, height: number, top: number, left: number, pageIndex: number): WidgetAnnotation { + private createSignatureAnnotation(id: string, width: number, height: number, top: number, left: number, pageIndex: number): WidgetAnnotation { const annotation = new PSPDFKit.Annotations.WidgetAnnotation({ id: id, pageIndex: pageIndex, @@ -220,14 +163,32 @@ export class App { return annotation } + private inchToPoint(inch: number): number { + return inch * 72; + } } +class Network { + // Makes a call to the supplied url and fetches the binary response as an array buffer + public loadDocument(envelopeKey: string, documentId: number): Promise { + return fetch(`/api/file/${envelopeKey}?id=${documentId}`, { credentials: "include" }) + .then(res => res.arrayBuffer()); + } -class UI { - constructor() { + // Makes a call to the supplied url and fetches the json response as an object + public loadData(envelopeKey): Promise { + return fetch(`/api/envelope/${envelopeKey}`, { credentials: "include" }) + .then(res => res.json()); + } + public postDocument(envelopeKey: string, documentId: number, buffer: ArrayBuffer): Promise { + return fetch(`/api/upload/${envelopeKey}/${documentId}`, { credentials: "include", method: "POST", body: buffer }) + .then(res => res.json()); } +} + +class UI { public allowedToolbarItems: string[] = [ "sidebar-thumbnails", "sidebar-document-ouline", @@ -241,7 +202,49 @@ class UI { "search" ] - public getToolbarItems = function (callback: any) { + // 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. + public loadPSPDFKit(arrayBuffer: ArrayBuffer, container: string): Promise { + return PSPDFKit.load({ + container: container, + document: arrayBuffer, + autoSaveMode: DISABLED, + annotationPresets: this.getPresets(), + electronicSignatures: { + creationModes: [DRAW, TYPE] + }, + isEditableAnnotation: function (annotation: WidgetAnnotation) { + // Check if the annotation is a signature + // This will allow new signatures, but not allow edits. + return !annotation.isSignature; + } + }) + } + + public configurePSPDFKit(instance: Instance, handler: any) { + instance.addEventListener("annotations.load", (loadedAnnotations) => { + console.log("annotations loaded", loadedAnnotations.toJS()); + }) + + instance.addEventListener("annotations.change", () => { + console.log("annotations changed") + }) + + instance.addEventListener("annotations.create", async (createdAnnotations) => { + console.log("annotations created"); + }) + + const toolbarItems = this.getToolbarItems(instance, handler) + instance.setToolbarItems(toolbarItems) + } + + public getToolbarItems(instance: Instance, handler: any): ToolbarItem[] { + const customItems = this.getCustomItems(handler) + const defaultItems: Array = this.getDefaultItems(instance.toolbarItems) + return defaultItems.concat(customItems) + } + + private getCustomItems = function (callback: any) { const customItems: ToolbarItem[] = [ { type: "custom", @@ -271,7 +274,11 @@ class UI { return customItems } - public getPresets() { + private getDefaultItems(items: ToolbarItem[]): ToolbarItem[] { + return items.filter((item) => this.allowedToolbarItems.includes(item.type)) + } + + private getPresets() { const annotationPresets = PSPDFKit.defaultAnnotationPresets; annotationPresets.ink = { lineWidth: 10 diff --git a/EnvelopeGenerator.Web/tsconfig.json b/EnvelopeGenerator.Web/tsconfig.json index 12f9c4ea..982e5d33 100644 --- a/EnvelopeGenerator.Web/tsconfig.json +++ b/EnvelopeGenerator.Web/tsconfig.json @@ -9,7 +9,7 @@ "moduleResolution": "Classic", "sourceMap": true, "target": "es5", - "lib": [ "ES2016", "DOM" ] + "lib": [ "ES2019", "DOM" ] }, "include": [ "Scripts/**/*.ts" diff --git a/EnvelopeGenerator.Web/wwwroot/js/app.js b/EnvelopeGenerator.Web/wwwroot/js/app.js index 86bd6700..463c230d 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/app.js +++ b/EnvelopeGenerator.Web/wwwroot/js/app.js @@ -50,9 +50,11 @@ var App = /** @class */ (function () { return __generator(this, function (_b) { switch (_b.label) { case 0: - App.ui = new UI(); + App.UI = new UI(); + App.Network = new Network(); + App.Annotation = new Annotation(); console.debug("Loading PSPDFKit.."); - return [4 /*yield*/, App.loadData("/api/get-data/".concat(envelopeKey))]; + return [4 /*yield*/, App.Network.loadData(envelopeKey)]; case 1: envelopeObject = _b.sent(); App.envelopeKey = envelopeKey; @@ -60,7 +62,7 @@ var App = /** @class */ (function () { _b.label = 2; case 2: _b.trys.push([2, 4, , 5]); - return [4 /*yield*/, App.loadDocument("/api/download/".concat(envelopeKey, "?id=").concat(App.currentDocument.id))]; + return [4 /*yield*/, App.Network.loadDocument(envelopeKey, App.currentDocument.id)]; case 3: arrayBuffer = _b.sent(); return [3 /*break*/, 5]; @@ -70,16 +72,16 @@ var App = /** @class */ (function () { return [3 /*break*/, 5]; case 5: _a = App; - return [4 /*yield*/, App.loadPSPDFKit(arrayBuffer, container)]; + return [4 /*yield*/, App.UI.loadPSPDFKit(arrayBuffer, container)]; case 6: _a.Instance = _b.sent(); - App.configurePSPDFKit(this.Instance); + App.UI.configurePSPDFKit(this.Instance, App.handleClick); console.debug(envelopeObject.envelope); console.debug("PSPDFKit configured!"); annotations = []; App.currentDocument.elements.forEach(function (element) { console.log("Creating annotation for element", element.id); - var _a = App.createAnnotationFromElement(element), annotation = _a[0], formField = _a[1]; + var _a = App.Annotation.createAnnotationFromElement(element), annotation = _a[0], formField = _a[1]; annotations.push(annotation); annotations.push(formField); }); @@ -92,59 +94,6 @@ var App = /** @class */ (function () { }); }); }; - App.inchToPoint = function (inch) { - return inch * 72; - }; - // Makes a call to the supplied url and fetches the binary response as an array buffer - App.loadDocument = function (url) { - return fetch(url, { credentials: "include" }) - .then(function (res) { return res.arrayBuffer(); }); - }; - // Makes a call to the supplied url and fetches the json response as an object - App.loadData = function (url) { - return fetch(url, { credentials: "include" }) - .then(function (res) { return res.json(); }); - }; - App.postDocument = function (url, buffer) { - return fetch(url, { credentials: "include", method: "POST", body: buffer }) - .then(function (res) { return res.json(); }); - }; - // 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. - App.loadPSPDFKit = function (arrayBuffer, container) { - return PSPDFKit.load({ - container: container, - document: arrayBuffer, - autoSaveMode: DISABLED, - annotationPresets: App.ui.getPresets(), - electronicSignatures: { - creationModes: [DRAW, TYPE] - }, - isEditableAnnotation: function (annotation) { - // Check if the annotation is a signature - // This will allow new signatures, but not allow edits. - return !annotation.isSignature; - } - }); - }; - App.configurePSPDFKit = function (instance) { - var _this = this; - instance.addEventListener("annotations.load", function (loadedAnnotations) { - console.log("annotations loaded", loadedAnnotations.toJS()); - }); - instance.addEventListener("annotations.change", function () { - console.log("annotations changed"); - }); - instance.addEventListener("annotations.create", function (createdAnnotations) { return __awaiter(_this, void 0, void 0, function () { - return __generator(this, function (_a) { - console.log("annotations created", createdAnnotations.toJS()); - return [2 /*return*/]; - }); - }); }); - var filteredItems = instance.toolbarItems - .filter(function (item) { return App.ui.allowedToolbarItems.includes(item.type); }); - instance.setToolbarItems(filteredItems.concat(App.ui.getToolbarItems(App.handleClick))); - }; App.handleClick = function (eventType) { return __awaiter(this, void 0, void 0, function () { var _a; @@ -172,7 +121,7 @@ var App = /** @class */ (function () { }; App.handleFinish = function (event) { return __awaiter(this, void 0, void 0, function () { - var json, buffer; + var json, buffer, result; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, App.Instance.save()]; @@ -185,54 +134,23 @@ var App = /** @class */ (function () { return [4 /*yield*/, App.Instance.exportPDF({ flatten: true })]; case 3: buffer = _a.sent(); - return [4 /*yield*/, App.uploadDocument(buffer, App.envelopeKey, App.currentDocument.id)]; + return [4 /*yield*/, App.Network.postDocument(App.envelopeKey, App.currentDocument.id, buffer)]; case 4: - _a.sent(); - alert("Signatur wird gespeichert!"); + result = _a.sent(); + console.log(result); return [2 /*return*/]; } }); }); }; App.handleReset = function (event) { - return __awaiter(this, void 0, void 0, function () { - var i, annotations; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - if (!confirm("Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?")) return [3 /*break*/, 4]; - i = 0; - _a.label = 1; - case 1: - if (!(i < App.Instance.totalPageCount)) return [3 /*break*/, 4]; - return [4 /*yield*/, App.Instance.getAnnotations(i)]; - case 2: - annotations = _a.sent(); - annotations.forEach(function (annotation) { - //console.log(annotation) - // TODO: Delete only create signatures - //App.Instance.delete(annotation.id) - }); - _a.label = 3; - case 3: - i++; - return [3 /*break*/, 1]; - case 4: return [2 /*return*/]; - } - }); - }); - }; - App.uploadDocument = function (buffer, envelopeKey, documentId) { return __awaiter(this, void 0, void 0, function () { var result; return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, App.postDocument("/api/upload/".concat(envelopeKey, "/").concat(documentId), buffer)]; - case 1: - result = _a.sent(); - console.log(result); - return [2 /*return*/]; + if (confirm("Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?")) { + result = App.Annotation.deleteAnnotations(App.Instance); } + return [2 /*return*/]; }); }); }; @@ -274,15 +192,20 @@ var App = /** @class */ (function () { }); }); }; - App.createAnnotationFromElement = function (element) { + return App; +}()); +export { App }; +var Annotation = /** @class */ (function () { + function Annotation() { + } + Annotation.prototype.createAnnotationFromElement = function (element) { var id = PSPDFKit.generateInstantId(); - console.log("Creating Annotation", id); - var width = App.inchToPoint(element.width); - var height = App.inchToPoint(element.height); - var top = App.inchToPoint(element.top) - (height / 2); - var left = App.inchToPoint(element.left) - (width / 2); + var width = this.inchToPoint(element.width); + var height = this.inchToPoint(element.height); + var top = this.inchToPoint(element.top) - (height / 2); + var left = this.inchToPoint(element.left) - (width / 2); var page = element.page - 1; - var annotation = App.createSignatureAnnotation(id, width, height, top, left, page); + var annotation = this.createSignatureAnnotation(id, width, height, top, left, page); console.log(annotation); var formField = new SignatureFormField({ name: id, @@ -291,7 +214,27 @@ var App = /** @class */ (function () { console.log(formField); return [annotation, formField]; }; - App.createSignatureAnnotation = function (id, width, height, top, left, pageIndex) { + Annotation.prototype.deleteAnnotations = function (instance) { + return __awaiter(this, void 0, void 0, function () { + var pageAnnotations; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, Promise.all(Array.from({ length: instance.totalPageCount }).map(function (_, pageIndex) { + return instance.getAnnotations(pageIndex); + }))]; + case 1: + pageAnnotations = (_a.sent()).flatMap(function (annotations) { + return annotations.reduce(function (acc, annotation) { return acc.concat(annotation); }, []); + }).filter(function (annotation) { return !!annotation.isSignature; }); + return [4 /*yield*/, instance.delete(pageAnnotations)]; + case 2: + //deleting all Annotations + return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + Annotation.prototype.createSignatureAnnotation = function (id, width, height, top, left, pageIndex) { var annotation = new PSPDFKit.Annotations.WidgetAnnotation({ id: id, pageIndex: pageIndex, @@ -300,9 +243,30 @@ var App = /** @class */ (function () { }); return annotation; }; - return App; + Annotation.prototype.inchToPoint = function (inch) { + return inch * 72; + }; + return Annotation; +}()); +var Network = /** @class */ (function () { + function Network() { + } + // Makes a call to the supplied url and fetches the binary response as an array buffer + Network.prototype.loadDocument = function (envelopeKey, documentId) { + return fetch("/api/file/".concat(envelopeKey, "?id=").concat(documentId), { credentials: "include" }) + .then(function (res) { return res.arrayBuffer(); }); + }; + // Makes a call to the supplied url and fetches the json response as an object + Network.prototype.loadData = function (envelopeKey) { + return fetch("/api/envelope/".concat(envelopeKey), { credentials: "include" }) + .then(function (res) { return res.json(); }); + }; + Network.prototype.postDocument = function (envelopeKey, documentId, buffer) { + return fetch("/api/upload/".concat(envelopeKey, "/").concat(documentId), { credentials: "include", method: "POST", body: buffer }) + .then(function (res) { return res.json(); }); + }; + return Network; }()); -export { App }; var UI = /** @class */ (function () { function UI() { this.allowedToolbarItems = [ @@ -317,7 +281,7 @@ var UI = /** @class */ (function () { "spacer", "search" ]; - this.getToolbarItems = function (callback) { + this.getCustomItems = function (callback) { var customItems = [ { type: "custom", @@ -341,6 +305,50 @@ var UI = /** @class */ (function () { return customItems; }; } + // 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. + UI.prototype.loadPSPDFKit = function (arrayBuffer, container) { + return PSPDFKit.load({ + container: container, + document: arrayBuffer, + autoSaveMode: DISABLED, + annotationPresets: this.getPresets(), + electronicSignatures: { + creationModes: [DRAW, TYPE] + }, + isEditableAnnotation: function (annotation) { + // Check if the annotation is a signature + // This will allow new signatures, but not allow edits. + return !annotation.isSignature; + } + }); + }; + UI.prototype.configurePSPDFKit = function (instance, handler) { + var _this = this; + instance.addEventListener("annotations.load", function (loadedAnnotations) { + console.log("annotations loaded", loadedAnnotations.toJS()); + }); + instance.addEventListener("annotations.change", function () { + console.log("annotations changed"); + }); + instance.addEventListener("annotations.create", function (createdAnnotations) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + console.log("annotations created"); + return [2 /*return*/]; + }); + }); }); + var toolbarItems = this.getToolbarItems(instance, handler); + instance.setToolbarItems(toolbarItems); + }; + UI.prototype.getToolbarItems = function (instance, handler) { + var customItems = this.getCustomItems(handler); + var defaultItems = this.getDefaultItems(instance.toolbarItems); + return defaultItems.concat(customItems); + }; + UI.prototype.getDefaultItems = function (items) { + var _this = this; + return items.filter(function (item) { return _this.allowedToolbarItems.includes(item.type); }); + }; UI.prototype.getPresets = function () { var annotationPresets = PSPDFKit.defaultAnnotationPresets; annotationPresets.ink = { diff --git a/EnvelopeGenerator.Web/wwwroot/js/app.js.map b/EnvelopeGenerator.Web/wwwroot/js/app.js.map index b809c583..5c464fd5 100644 --- a/EnvelopeGenerator.Web/wwwroot/js/app.js.map +++ b/EnvelopeGenerator.Web/wwwroot/js/app.js.map @@ -1 +1 @@ -{"version":3,"file":"app.js","sourceRoot":"","sources":["../../Scripts/app.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"app.js","sourceRoot":"","sources":["../../Scripts/app.ts"],"names":[],"mappings":"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"} \ No newline at end of file