04-10-2023

This commit is contained in:
Jonathan Jenne 2023-10-04 11:44:26 +02:00
parent d7d457b82a
commit 6de7ec0050
7 changed files with 373 additions and 293 deletions

View File

@ -4,6 +4,6 @@
Public UserReference As String Public UserReference As String
Public ActionDescription As String Public ActionDescription As String
Public ActionDate As DateTime Public ActionDate As DateTime
Public UserEmailAddress As String
End Class End Class

View File

@ -1,8 +1,10 @@
using EnvelopeGenerator.Common; using DigitalData.Modules.Logging;
using EnvelopeGenerator.Common;
using EnvelopeGenerator.Common.My.Resources; using EnvelopeGenerator.Common.My.Resources;
using EnvelopeGenerator.Web.Services; using EnvelopeGenerator.Web.Services;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
using System.IO.Pipelines; using System.IO.Pipelines;
using System.Reflection.Metadata.Ecma335;
namespace EnvelopeGenerator.Web.Handler namespace EnvelopeGenerator.Web.Handler
{ {
@ -10,34 +12,30 @@ namespace EnvelopeGenerator.Web.Handler
{ {
public async static Task<IResult> HandleFileDownload(HttpContext ctx, DatabaseService database, LoggingService logging) public async static Task<IResult> HandleFileDownload(HttpContext ctx, DatabaseService database, LoggingService logging)
{ {
var logger = logging.LogConfig.GetLogger("FileHandler"); var logger = logging.LogConfig.GetLogger("FileHandler");
string envelopeKey = (string)ctx.Request.RouteValues["envelopeKey"];
logger.Info("Downloading file with EnvelopeKey [{0}]", envelopeKey);
Tuple<string, string> 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);
int documentId = getDocumentIndex(ctx);
var document = getDocument(envelope, documentId);
try try
{ {
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); var bytes = await File.ReadAllBytesAsync(document.Filepath);
logger.Info("Serving file, size: [{0}]", bytes.Length); logger.Info("Serving file, size: [{0}]", bytes.Length);
// Return the document as bytes
return Results.File(bytes); return Results.File(bytes);
} }
catch (Exception e) catch (Exception e)
{ {
// Better error handling & reporting
logger.Error(e); logger.Error(e);
return Results.Problem(); return Results.Problem();
@ -47,89 +45,155 @@ namespace EnvelopeGenerator.Web.Handler
public async static Task<IResult> HandleFileUpload(HttpContext ctx, DatabaseService database, LoggingService logging) public async static Task<IResult> HandleFileUpload(HttpContext ctx, DatabaseService database, LoggingService logging)
{ {
var logger = logging.LogConfig.GetLogger("FileHandler"); 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); try
Tuple<string, string> 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);
var document = envelope.Documents.Where(d => d.Id == documentId).FirstOrDefault();
if (document != null)
{ {
var path = document.Filepath; logger.Info("Handling file upload.");
using FileStream fs = new(path, FileMode.Open); // 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);
using FileStream fs = new(document.Filepath, FileMode.Open);
await ctx.Request.Body.CopyToAsync(fs); await ctx.Request.Body.CopyToAsync(fs);
fs.Flush(); fs.Flush();
return Results.Ok(); return Results.Ok();
} }
else catch (Exception e)
{ {
// Better error handling & reporting
logger.Error(e);
return Results.Problem(); return Results.Problem();
} }
} }
private static int getDocumentIndex(HttpContext ctx) public async static Task<IResult> HandleGetData(HttpContext ctx, DatabaseService database, LoggingService logging)
{ {
int documentId = 0; var logger = logging.LogConfig.GetLogger("FileHandler");
StringValues documentIndexString;
if (ctx.Request.Query.TryGetValue("index", out documentIndexString))
{
int.TryParse(documentIndexString.First(), out documentId);
}
return documentId; try
{
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();
}
} }
private static EnvelopeDocument getDocument(Common.Envelope envelope, int documentId) public async static Task<IResult> HandlePostData(HttpContext ctx, DatabaseService database, LoggingService logging)
{ {
var document = envelope.Documents.First(); var logger = logging.LogConfig.GetLogger("FileHandler");
if (documentId > 0)
{
var documentById = envelope.Documents.
Where(d => d.Id == documentId).
FirstOrDefault();
if (documentById != null) try
{
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();
}
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");
}
}
private static string EnsureValidEnvelopeKey(Logger logger, HttpRequest request)
{
logger.Debug("Parsing EnvelopeKey..");
var envelopeKey = request.RouteValues["envelopeKey"] as string;
if (string.IsNullOrEmpty(envelopeKey))
throw new ArgumentNullException("EnvelopeKey");
Tuple<string, string> result = Helpers.DecodeEnvelopeReceiverId(envelopeKey);
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;
}
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 document; return document;
} }
public static Task<IResult> HandleGetData(HttpContext ctx, DatabaseService database, LoggingService logging)
{
var logger = logging.LogConfig.GetLogger("FileHandler");
string envelopeKey = (string)ctx.Request.RouteValues["envelopeKey"];
logger.Info("Fetching data for envelope with EnvelopeKey [{0}]", envelopeKey);
Tuple<string, string> result = Helpers.DecodeEnvelopeReceiverId(envelopeKey);
logger.Info("EnvelopeUUID: [{0}]", result.Item1);
logger.Info("ReceiverSignature: [{0}]", result.Item2);
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);
return Task.FromResult(Results.Json(response));
}
} }
} }

View File

@ -35,9 +35,10 @@ app.UseStaticFiles();
app.UseRouting(); app.UseRouting();
// Add file download endpoint // Add file download endpoint
app.MapGet("/api/download/{envelopeKey}", FileHandler.HandleFileDownload); app.MapGet("/api/document/{envelopeKey}", FileHandler.HandleFileDownload);
app.MapPost("/api/upload/{envelopeKey}/{documentId}", FileHandler.HandleFileUpload); app.MapPost("/api/document/{envelopeKey}/{documentId}", FileHandler.HandleFileUpload);
app.MapGet("/api/get-data/{envelopeKey}", FileHandler.HandleGetData); app.MapGet("/api/envelope/{envelopeKey}", FileHandler.HandleGetData);
app.MapPost("/api/envelope/{envelopeKey}/{documentId}", FileHandler.HandlePostData);
// Blazor plumbing // Blazor plumbing
app.MapBlazorHub(); app.MapBlazorHub();

View File

@ -15,28 +15,32 @@ export class App {
public static currentDocument: Document; public static currentDocument: Document;
public static envelopeKey: string; 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 // This function will be called in the ShowEnvelope.razor page
// and will trigger loading of the Editor Interface // and will trigger loading of the Editor Interface
public static async loadPDFFromUrl(container: string, envelopeKey: string) { 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.."); 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.envelopeKey = envelopeKey;
App.currentDocument = envelopeObject.envelope.documents[0]; App.currentDocument = envelopeObject.envelope.documents[0];
let arrayBuffer let arrayBuffer
try { try {
arrayBuffer = await App.loadDocument(`/api/download/${envelopeKey}?id=${App.currentDocument.id}`); arrayBuffer = await App.Network.loadDocument(envelopeKey, App.currentDocument.id);
} catch (e) { } catch (e) {
console.error(e) console.error(e)
} }
App.Instance = await App.loadPSPDFKit(arrayBuffer, container) App.Instance = await App.UI.loadPSPDFKit(arrayBuffer, container)
App.configurePSPDFKit(this.Instance) App.UI.configurePSPDFKit(this.Instance, App.handleClick)
console.debug(envelopeObject.envelope); console.debug(envelopeObject.envelope);
console.debug("PSPDFKit configured!"); console.debug("PSPDFKit configured!");
@ -46,7 +50,7 @@ export class App {
App.currentDocument.elements.forEach(function (element: Element) { App.currentDocument.elements.forEach(function (element: Element) {
console.log("Creating annotation for element", element.id) 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(annotation);
annotations.push(formField); annotations.push(formField);
}) })
@ -56,73 +60,15 @@ export class App {
console.debug(createdAnnotations) 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<ArrayBuffer> {
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<any> {
return fetch(url, { credentials: "include" })
.then(res => res.json());
}
private static postDocument(url: string, buffer: ArrayBuffer): Promise<any> {
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<Instance> {
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<ToolbarItem> = 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) { public static async handleClick(eventType: string) {
switch (eventType) { switch (eventType) {
case "RESET": case "RESET":
await App.handleReset(null) await App.handleReset(null)
break; break;
case "FINISH": case "FINISH":
await App.handleFinish(null) await App.handleFinish(null)
break; break;
} }
} }
@ -133,31 +79,17 @@ export class App {
console.log(json); console.log(json);
const buffer = await App.Instance.exportPDF({ flatten: true }); 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) { public static async handleReset(event: any) {
if (confirm("Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?")) { if (confirm("Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?")) {
for (let i = 0; i < App.Instance.totalPageCount; i++) { const result = App.Annotation.deleteAnnotations(App.Instance)
const annotations = await App.Instance.getAnnotations(i)
annotations.forEach((annotation) => {
//console.log(annotation)
// TODO: Delete only create signatures
//App.Instance.delete(annotation.id)
})
}
} }
} }
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() { private static async downloadDocument() {
const buffer = await App.Instance.exportPDF({ flatten: true }); const buffer = await App.Instance.exportPDF({ flatten: true });
const supportsDownloadAttribute = HTMLAnchorElement.prototype.hasOwnProperty("download"); const supportsDownloadAttribute = HTMLAnchorElement.prototype.hasOwnProperty("download");
@ -186,17 +118,17 @@ export class App {
document.body.removeChild(a); 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() const id = PSPDFKit.generateInstantId()
console.log("Creating Annotation", id) const width = this.inchToPoint(element.width)
const height = this.inchToPoint(element.height)
const width = App.inchToPoint(element.width) const top = this.inchToPoint(element.top) - (height / 2)
const height = App.inchToPoint(element.height) const left = this.inchToPoint(element.left) - (width / 2)
const top = App.inchToPoint(element.top) - (height / 2)
const left = App.inchToPoint(element.left) - (width / 2)
const page = element.page - 1 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) console.log(annotation)
const formField = new SignatureFormField({ const formField = new SignatureFormField({
@ -208,8 +140,19 @@ export class App {
return [annotation, formField] return [annotation, formField]
} }
public async deleteAnnotations(instance: Instance): Promise<any> {
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({ const annotation = new PSPDFKit.Annotations.WidgetAnnotation({
id: id, id: id,
pageIndex: pageIndex, pageIndex: pageIndex,
@ -220,14 +163,32 @@ export class App {
return annotation 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<ArrayBuffer> {
return fetch(`/api/file/${envelopeKey}?id=${documentId}`, { credentials: "include" })
.then(res => res.arrayBuffer());
}
// Makes a call to the supplied url and fetches the json response as an object
public loadData(envelopeKey): Promise<any> {
return fetch(`/api/envelope/${envelopeKey}`, { credentials: "include" })
.then(res => res.json());
}
public postDocument(envelopeKey: string, documentId: number, buffer: ArrayBuffer): Promise<any> {
return fetch(`/api/upload/${envelopeKey}/${documentId}`, { credentials: "include", method: "POST", body: buffer })
.then(res => res.json());
}
} }
class UI { class UI {
constructor() {
}
public allowedToolbarItems: string[] = [ public allowedToolbarItems: string[] = [
"sidebar-thumbnails", "sidebar-thumbnails",
"sidebar-document-ouline", "sidebar-document-ouline",
@ -241,7 +202,49 @@ class UI {
"search" "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<Instance> {
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<ToolbarItem> = this.getDefaultItems(instance.toolbarItems)
return defaultItems.concat(customItems)
}
private getCustomItems = function (callback: any) {
const customItems: ToolbarItem[] = [ const customItems: ToolbarItem[] = [
{ {
type: "custom", type: "custom",
@ -271,7 +274,11 @@ class UI {
return customItems return customItems
} }
public getPresets() { private getDefaultItems(items: ToolbarItem[]): ToolbarItem[] {
return items.filter((item) => this.allowedToolbarItems.includes(item.type))
}
private getPresets() {
const annotationPresets = PSPDFKit.defaultAnnotationPresets; const annotationPresets = PSPDFKit.defaultAnnotationPresets;
annotationPresets.ink = { annotationPresets.ink = {
lineWidth: 10 lineWidth: 10

View File

@ -9,7 +9,7 @@
"moduleResolution": "Classic", "moduleResolution": "Classic",
"sourceMap": true, "sourceMap": true,
"target": "es5", "target": "es5",
"lib": [ "ES2016", "DOM" ] "lib": [ "ES2019", "DOM" ]
}, },
"include": [ "include": [
"Scripts/**/*.ts" "Scripts/**/*.ts"

View File

@ -50,9 +50,11 @@ var App = /** @class */ (function () {
return __generator(this, function (_b) { return __generator(this, function (_b) {
switch (_b.label) { switch (_b.label) {
case 0: case 0:
App.ui = new UI(); App.UI = new UI();
App.Network = new Network();
App.Annotation = new Annotation();
console.debug("Loading PSPDFKit.."); console.debug("Loading PSPDFKit..");
return [4 /*yield*/, App.loadData("/api/get-data/".concat(envelopeKey))]; return [4 /*yield*/, App.Network.loadData(envelopeKey)];
case 1: case 1:
envelopeObject = _b.sent(); envelopeObject = _b.sent();
App.envelopeKey = envelopeKey; App.envelopeKey = envelopeKey;
@ -60,7 +62,7 @@ var App = /** @class */ (function () {
_b.label = 2; _b.label = 2;
case 2: case 2:
_b.trys.push([2, 4, , 5]); _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: case 3:
arrayBuffer = _b.sent(); arrayBuffer = _b.sent();
return [3 /*break*/, 5]; return [3 /*break*/, 5];
@ -70,16 +72,16 @@ var App = /** @class */ (function () {
return [3 /*break*/, 5]; return [3 /*break*/, 5];
case 5: case 5:
_a = App; _a = App;
return [4 /*yield*/, App.loadPSPDFKit(arrayBuffer, container)]; return [4 /*yield*/, App.UI.loadPSPDFKit(arrayBuffer, container)];
case 6: case 6:
_a.Instance = _b.sent(); _a.Instance = _b.sent();
App.configurePSPDFKit(this.Instance); App.UI.configurePSPDFKit(this.Instance, App.handleClick);
console.debug(envelopeObject.envelope); console.debug(envelopeObject.envelope);
console.debug("PSPDFKit configured!"); console.debug("PSPDFKit configured!");
annotations = []; annotations = [];
App.currentDocument.elements.forEach(function (element) { App.currentDocument.elements.forEach(function (element) {
console.log("Creating annotation for element", element.id); 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(annotation);
annotations.push(formField); 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) { App.handleClick = function (eventType) {
return __awaiter(this, void 0, void 0, function () { return __awaiter(this, void 0, void 0, function () {
var _a; var _a;
@ -172,7 +121,7 @@ var App = /** @class */ (function () {
}; };
App.handleFinish = function (event) { App.handleFinish = function (event) {
return __awaiter(this, void 0, void 0, function () { return __awaiter(this, void 0, void 0, function () {
var json, buffer; var json, buffer, result;
return __generator(this, function (_a) { return __generator(this, function (_a) {
switch (_a.label) { switch (_a.label) {
case 0: return [4 /*yield*/, App.Instance.save()]; case 0: return [4 /*yield*/, App.Instance.save()];
@ -185,54 +134,23 @@ var App = /** @class */ (function () {
return [4 /*yield*/, App.Instance.exportPDF({ flatten: true })]; return [4 /*yield*/, App.Instance.exportPDF({ flatten: true })];
case 3: case 3:
buffer = _a.sent(); 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: case 4:
_a.sent(); result = _a.sent();
alert("Signatur wird gespeichert!"); console.log(result);
return [2 /*return*/]; return [2 /*return*/];
} }
}); });
}); });
}; };
App.handleReset = function (event) { 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 () { return __awaiter(this, void 0, void 0, function () {
var result; var result;
return __generator(this, function (_a) { return __generator(this, function (_a) {
switch (_a.label) { if (confirm("Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?")) {
case 0: return [4 /*yield*/, App.postDocument("/api/upload/".concat(envelopeKey, "/").concat(documentId), buffer)]; result = App.Annotation.deleteAnnotations(App.Instance);
case 1:
result = _a.sent();
console.log(result);
return [2 /*return*/];
} }
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(); var id = PSPDFKit.generateInstantId();
console.log("Creating Annotation", id); var width = this.inchToPoint(element.width);
var width = App.inchToPoint(element.width); var height = this.inchToPoint(element.height);
var height = App.inchToPoint(element.height); var top = this.inchToPoint(element.top) - (height / 2);
var top = App.inchToPoint(element.top) - (height / 2); var left = this.inchToPoint(element.left) - (width / 2);
var left = App.inchToPoint(element.left) - (width / 2);
var page = element.page - 1; 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); console.log(annotation);
var formField = new SignatureFormField({ var formField = new SignatureFormField({
name: id, name: id,
@ -291,7 +214,27 @@ var App = /** @class */ (function () {
console.log(formField); console.log(formField);
return [annotation, 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({ var annotation = new PSPDFKit.Annotations.WidgetAnnotation({
id: id, id: id,
pageIndex: pageIndex, pageIndex: pageIndex,
@ -300,9 +243,30 @@ var App = /** @class */ (function () {
}); });
return annotation; 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 () { var UI = /** @class */ (function () {
function UI() { function UI() {
this.allowedToolbarItems = [ this.allowedToolbarItems = [
@ -317,7 +281,7 @@ var UI = /** @class */ (function () {
"spacer", "spacer",
"search" "search"
]; ];
this.getToolbarItems = function (callback) { this.getCustomItems = function (callback) {
var customItems = [ var customItems = [
{ {
type: "custom", type: "custom",
@ -341,6 +305,50 @@ var UI = /** @class */ (function () {
return customItems; 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 () { UI.prototype.getPresets = function () {
var annotationPresets = PSPDFKit.defaultAnnotationPresets; var annotationPresets = PSPDFKit.defaultAnnotationPresets;
annotationPresets.ink = { annotationPresets.ink = {

File diff suppressed because one or more lines are too long