27-09-2023

This commit is contained in:
Jonathan Jenne 2023-09-27 14:50:52 +02:00
parent e3a81bfdbf
commit 538a257848
1135 changed files with 4638 additions and 1758 deletions

View File

@ -42,6 +42,7 @@
<ItemGroup>
<Folder Include="Data\" />
<Folder Include="wwwroot\lib\NewFolder\" />
</ItemGroup>
</Project>

View File

@ -2,12 +2,13 @@
using EnvelopeGenerator.Common.My.Resources;
using EnvelopeGenerator.Web.Services;
using Microsoft.Extensions.Primitives;
using System.IO.Pipelines;
namespace EnvelopeGenerator.Web.Handler
{
public class FileHandler
{
public async static Task<IResult> HandleFile(HttpContext ctx, DatabaseService database, LoggingService logging)
public async static Task<IResult> HandleFileDownload(HttpContext ctx, DatabaseService database, LoggingService logging)
{
var logger = logging.LogConfig.GetLogger("FileHandler");
@ -43,6 +44,42 @@ namespace EnvelopeGenerator.Web.Handler
}
}
public async static Task<IResult> 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<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;
using FileStream fs = new(path, FileMode.Open);
await ctx.Request.Body.CopyToAsync(fs);
fs.Flush();
return Results.Ok();
}
else
{
return Results.Problem();
}
}
private static int getDocumentIndex(HttpContext ctx)
{
int documentId = 0;

View File

@ -35,7 +35,8 @@ app.UseStaticFiles();
app.UseRouting();
// Add file download endpoint
app.MapGet("/api/download/{envelopeKey}", FileHandler.HandleFile);
app.MapGet("/api/download/{envelopeKey}", FileHandler.HandleFileDownload);
app.MapPost("/api/upload/{envelopeKey}/{documentId}", FileHandler.HandleFileUpload);
app.MapGet("/api/get-data/{envelopeKey}", FileHandler.HandleGetData);
// Blazor plumbing

View File

@ -1,6 +1,6 @@
import PSPDFKitType, { AnnotationsUnion } from "./index";
import PSPDFKitType, { AnnotationsUnion, SignatureFormField as SignatureFormFieldType } from "./index";
import { Instance, WidgetAnnotation, ToolbarItem } from "./index";
import { EnvelopeResponse, Envelope, User, Element, Document } from "./interfaces";
import { EnvelopeResponse, Envelope, User, Element, Document, IFunction } from "./interfaces";
declare const PSPDFKit: typeof PSPDFKitType
@ -10,34 +10,27 @@ const { SignatureFormField } = PSPDFKit.FormFields;
const { DRAW, TYPE } = PSPDFKit.ElectronicSignatureCreationMode;
const { DISABLED } = PSPDFKit.AutoSaveMode;
const allowedToolbarItems: string[] = [
"sidebar-thumbnails",
"sidebar-document-ouline",
"sidebar-bookmarks",
"pager",
"pan",
"zoom-out",
"zoom-in",
"zoom-mode",
"spacer",
"search"
]
export class App {
public static Instance: Instance;
public static currentDocument
public static currentDocument: Document;
public static envelopeKey: string;
public static ui: UI;
// 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();
console.debug("Loading PSPDFKit..");
const envelopeObject: EnvelopeResponse = await App.loadData(`/api/get-data/${envelopeKey}`);
const document: Document = envelopeObject.envelope.documents[0];
App.envelopeKey = envelopeKey;
App.currentDocument = envelopeObject.envelope.documents[0];
let arrayBuffer
try {
arrayBuffer = await App.loadDocument(`/api/download/${envelopeKey}?id=${document.id}`);
arrayBuffer = await App.loadDocument(`/api/download/${envelopeKey}?id=${App.currentDocument.id}`);
} catch (e) {
console.error(e)
}
@ -50,29 +43,21 @@ export class App {
const annotations: any[] = [];
document.elements.forEach(function (element: Element) {
console.log("Loading element")
console.debug("Page", element.page)
console.debug("Width / Height", element.width, element.height)
console.debug("Top / Left", element.top, element.left)
const id = PSPDFKit.generateInstantId()
const annotation: WidgetAnnotation = App.createSignatureAnnotation(id, element.width, element.height, element.top, element.left, element.page)
const formField = new SignatureFormField({
name: id,
annotationIds: List([annotation.id])
})
App.currentDocument.elements.forEach(function (element: Element) {
console.log("Creating annotation for element", element.id)
const [annotation, formField] = App.createAnnotationFromElement(element)
annotations.push(annotation);
annotations.push(formField);
console.debug("Annotation created.")
})
const [createdAnnotation] = await App.Instance.create(annotations)
const createdAnnotations = await App.Instance.create(annotations)
console.debug(createdAnnotation)
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
@ -87,22 +72,26 @@ export class App {
.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> {
const annotationPresets = PSPDFKit.defaultAnnotationPresets;
console.log(annotationPresets)
annotationPresets.ink = {
lineWidth: 10
};
return PSPDFKit.load({
container: container,
document: arrayBuffer,
autoSaveMode: DISABLED,
annotationPresets,
annotationPresets: App.ui.getPresets(),
electronicSignatures: {
creationModes: [DRAW]
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;
}
})
}
@ -116,35 +105,57 @@ export class App {
console.log("annotations changed")
})
instance.addEventListener("annotations.create", (createdAnnotations) => {
const annotation: AnnotationsUnion = createdAnnotations[0];
instance.addEventListener("annotations.create", async (createdAnnotations) => {
console.log("annotations created", createdAnnotations.toJS());
})
const filteredItems: Array<ToolbarItem> = instance.toolbarItems
.filter((item) => allowedToolbarItems.includes(item.type))
.filter((item) => App.ui.allowedToolbarItems.includes(item.type))
const customItems: ToolbarItem[] = [
{
type: "custom",
id: "button-finish",
title: "Abschließen",
icon: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-check2-circle" viewBox="0 0 16 16">
<path d="M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0z"/>
<path d="M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l7-7z" />
</svg>`,
onPress: this.handleFinish
}
]
instance.setToolbarItems(filteredItems.concat(customItems))
instance.setToolbarItems(filteredItems.concat(App.ui.getToolbarItems(App.handleClick)))
}
private static async handleFinish(event: any) {
await App.Instance.applyOperations([{ type: "flattenAnnotations" }])
public static async handleClick(eventType: string) {
switch (eventType) {
case "RESET":
await App.handleReset(null)
break;
case "FINISH":
await App.handleFinish(null)
break;
}
}
//await downloadDocument();
public static async handleFinish(event: any) {
await App.Instance.save();
const json = await App.Instance.exportInstantJSON()
console.log(json);
const buffer = await App.Instance.exportPDF({ flatten: true });
await App.uploadDocument(buffer, App.envelopeKey, App.currentDocument.id);
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)
})
}
}
}
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() {
@ -176,6 +187,27 @@ export class App {
}
}
private static 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 page = element.page - 1
const annotation: WidgetAnnotation = App.createSignatureAnnotation(id, width, height, top, left, page)
console.log(annotation)
const formField = new SignatureFormField({
name: id,
annotationIds: List([annotation.id])
})
console.log(formField)
return [annotation, formField]
}
private static createSignatureAnnotation(id: string, width: number, height: number, top: number, left: number, pageIndex: number): WidgetAnnotation {
const annotation = new PSPDFKit.Annotations.WidgetAnnotation({
@ -190,3 +222,65 @@ export class App {
}
class UI {
constructor() {
}
public allowedToolbarItems: string[] = [
"sidebar-thumbnails",
"sidebar-document-ouline",
"sidebar-bookmarks",
"pager",
"pan",
"zoom-out",
"zoom-in",
"zoom-mode",
"spacer",
"search"
]
public getToolbarItems = function (callback: any) {
const customItems: ToolbarItem[] = [
{
type: "custom",
id: "button-reset",
title: "Zurücksetzen",
onPress() {
callback("RESET")
},
icon: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z"/>
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z"/>
</svg>`
},
{
type: "custom",
id: "button-finish",
title: "Abschließen",
onPress() {
callback("FINISH")
},
icon: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-check2-circle" viewBox="0 0 16 16">
<path d="M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0z"/>
<path d="M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l7-7z" />
</svg>`
}
]
return customItems
}
public getPresets() {
const annotationPresets = PSPDFKit.defaultAnnotationPresets;
annotationPresets.ink = {
lineWidth: 10
};
annotationPresets.widget = {
readOnly: true
}
return annotationPresets;
}
}

View File

@ -1,4 +1,4 @@
declare const SignatureSaveMode: {
declare const SignatureSaveMode: {
readonly ALWAYS: "ALWAYS";
readonly NEVER: "NEVER";
readonly USING_UI: "USING_UI";
@ -5531,7 +5531,7 @@ declare class MediaAnnotation<T extends IMediaAnnotation = IMediaAnnotation> ext
type SignatureInfo = {
type: 'pspdfkit/signature-info';
signatureType: SignatureTypeType | null | undefined;
signatureType?: SignatureTypeType | null | undefined;
signerName: string | null | undefined;
creationDate: Date | null | undefined;
signatureReason: string | null | undefined;
@ -6067,6 +6067,197 @@ type SerializedAdditionalActionsType = {
};
};
type Glyph = {
c: string;
rect: Rect;
};
declare const SearchType: {
readonly TEXT: "text";
readonly PRESET: "preset";
readonly REGEX: "regex";
};
type ISearchType = (typeof SearchType)[keyof typeof SearchType];
declare function toJSON(bookmark: Bookmark): BookmarkJSON;
type ID$1 = string;
type BookmarkProps = {
id: ID$1 | null;
pdfBookmarkId: ID$1 | null;
name: string | null;
sortKey: number | null;
action: Action | null;
};
declare const Bookmark_base: Record$1.Factory<BookmarkProps>;
declare class Bookmark extends Bookmark_base {
id: ID$1;
action: Action;
static toSerializableObject: typeof toJSON;
static fromSerializableObject: (bookmark: BookmarkJSON) => Bookmark;
}
type Rotation$1 = 0 | 90 | 180 | 270;
type AddPageConfiguration = {
backgroundColor: Color;
pageWidth: number;
pageHeight: number;
rotateBy: Rotation$1;
insets?: Rect;
};
type OperationAttachment = string | File | Blob;
type min = number;
type max = number;
type Range = [min, max];
type ImportPageIndex = Array<number | Range>;
type DocumentMetadata = {
title?: string;
author?: string;
};
type NonSerializableDocumentOperations = {
type: 'removePages';
pageIndexes: Array<number>;
} | {
type: 'duplicatePages';
pageIndexes: Array<number>;
} | {
type: 'movePages';
pageIndexes: Array<number>;
afterPageIndex: number;
} | {
type: 'movePages';
pageIndexes: Array<number>;
beforePageIndex: number;
} | {
type: 'rotatePages';
pageIndexes: Array<number>;
rotateBy: Rotation$1;
} | {
type: 'keepPages';
pageIndexes: Array<number>;
} | {
type: 'importDocument';
afterPageIndex: number;
treatImportedDocumentAsOnePage?: boolean;
document: OperationAttachment;
importedPageIndexes?: ImportPageIndex;
} | {
type: 'importDocument';
beforePageIndex: number;
treatImportedDocumentAsOnePage?: boolean;
document: OperationAttachment;
importedPageIndexes?: ImportPageIndex;
} | {
type: 'applyInstantJson';
instantJson: Record<string, any>;
dataFilePath: OperationAttachment;
} | {
type: 'applyXfdf';
xfdf: string;
ignorePageRotation?: boolean;
dataFilePath: OperationAttachment;
} | {
type: 'flattenAnnotations';
pageIndexes?: Array<number>;
annotationIds?: string[];
} | {
type: 'setPageLabel';
pageIndexes?: Array<number>;
pageLabel?: string;
} | {
type: 'performOcr';
pageIndexes?: Array<number> | 'all';
language: string;
} | {
type: 'applyRedactions';
} | {
type: 'updateMetadata';
metadata: DocumentMetadata;
};
type DocumentOperation = (AddPageConfiguration & {
type: 'addPage';
afterPageIndex: number;
}) | (AddPageConfiguration & {
type: 'addPage';
beforePageIndex: number;
}) | {
type: 'cropPages';
pageIndexes?: Array<number>;
cropBox: Rect;
} | NonSerializableDocumentOperations;
type BaseFormFieldJSON = {
v: 1;
pdfObjectId?: number | null;
annotationIds: Array<string>;
name: string;
label: string;
flags?: FormFieldFlags;
id: string;
additionalActions?: SerializedAdditionalActionsType;
group?: IGroup;
permissions?: IPermissions;
};
type ChoiceFormFieldJSON = BaseFormFieldJSON & {
type: 'pspdfkit/form-field/listbox' | 'pspdfkit/form-field/combobox';
options: Array<FormOptionJSON>;
multiSelect: boolean;
commitOnChange: boolean;
defaultValues: Array<string>;
};
type ListBoxFormFieldJSON = ChoiceFormFieldJSON & {
type: 'pspdfkit/form-field/listbox';
};
type DoNotSpellCheckPropertyPair = XOR<Record<'doNotSpellCheck', boolean>, Record<'doNotSpellcheck', boolean>>;
type ComboBoxFormFieldJSON = ChoiceFormFieldJSON & {
type: 'pspdfkit/form-field/combobox';
edit: boolean;
} & DoNotSpellCheckPropertyPair;
type CheckBoxFormFieldJSON = BaseFormFieldJSON & {
type: 'pspdfkit/form-field/checkbox';
options: Array<FormOptionJSON>;
defaultValues: Array<string>;
};
type RadioButtonFormFieldJSON = BaseFormFieldJSON & {
type: 'pspdfkit/form-field/radio';
options: Array<FormOptionJSON>;
noToggleToOff: boolean;
radiosInUnison: boolean;
defaultValue: string;
};
type TextFormFieldJSON = BaseFormFieldJSON & {
type: 'pspdfkit/form-field/text';
password: boolean;
maxLength?: number | null;
doNotScroll: boolean;
multiLine: boolean;
defaultValue: string;
comb: boolean;
} & DoNotSpellCheckPropertyPair;
type ButtonFormFieldJSON = BaseFormFieldJSON & {
type: 'pspdfkit/form-field/button';
buttonLabel: string | null;
};
type SignatureFormFieldJSON = BaseFormFieldJSON & {
type: 'pspdfkit/form-field/signature';
};
type FormFieldJSON = ListBoxFormFieldJSON | ComboBoxFormFieldJSON | RadioButtonFormFieldJSON | CheckBoxFormFieldJSON | TextFormFieldJSON | ButtonFormFieldJSON | SignatureFormFieldJSON;
type OCGLayer = {
name: string;
ocgId: number;
radioGroup?: number;
};
type OCGCollection = {
name?: string;
ocgId?: number;
layers: OCGLayer[];
};
type OCG = OCGLayer | OCGCollection;
type OCGVisibilityState = {
visibleOCGIds: number[];
};
type IRectJSON = [left: number, top: number, width: number, height: number];
type BaseAnnotationJSON = {
@ -6267,63 +6458,6 @@ type CommentMarkerAnnotationJSON = Omit<BaseAnnotationJSON, 'type'> & {
};
type AnnotationJSONUnion = TextMarkupAnnotationJSON | TextAnnotationJSON | WidgetAnnotationJSON | RedactionAnnotationJSON | StampAnnotationJSON | NoteAnnotationJSON | LinkAnnotationJSON | InkAnnotationJSON | RectangleAnnotationJSON | PolylineAnnotationJSON | PolygonAnnotationJSON | LineAnnotationJSON | EllipseAnnotationJSON | ImageAnnotationJSON | UnknownAnnotationJSON | MediaAnnotationJSON | CommentMarkerAnnotationJSON;
type BaseFormFieldJSON = {
v: 1;
pdfObjectId?: number | null;
annotationIds: Array<string>;
name: string;
label: string;
flags?: FormFieldFlags;
id: string;
additionalActions?: SerializedAdditionalActionsType;
group?: IGroup;
permissions?: IPermissions;
};
type ChoiceFormFieldJSON = BaseFormFieldJSON & {
type: 'pspdfkit/form-field/listbox' | 'pspdfkit/form-field/combobox';
options: Array<FormOptionJSON>;
multiSelect: boolean;
commitOnChange: boolean;
defaultValues: Array<string>;
};
type ListBoxFormFieldJSON = ChoiceFormFieldJSON & {
type: 'pspdfkit/form-field/listbox';
};
type DoNotSpellCheckPropertyPair = XOR<Record<'doNotSpellCheck', boolean>, Record<'doNotSpellcheck', boolean>>;
type ComboBoxFormFieldJSON = ChoiceFormFieldJSON & {
type: 'pspdfkit/form-field/combobox';
edit: boolean;
} & DoNotSpellCheckPropertyPair;
type CheckBoxFormFieldJSON = BaseFormFieldJSON & {
type: 'pspdfkit/form-field/checkbox';
options: Array<FormOptionJSON>;
defaultValues: Array<string>;
};
type RadioButtonFormFieldJSON = BaseFormFieldJSON & {
type: 'pspdfkit/form-field/radio';
options: Array<FormOptionJSON>;
noToggleToOff: boolean;
radiosInUnison: boolean;
defaultValue: string;
};
type TextFormFieldJSON = BaseFormFieldJSON & {
type: 'pspdfkit/form-field/text';
password: boolean;
maxLength?: number | null;
doNotScroll: boolean;
multiLine: boolean;
defaultValue: string;
comb: boolean;
} & DoNotSpellCheckPropertyPair;
type ButtonFormFieldJSON = BaseFormFieldJSON & {
type: 'pspdfkit/form-field/button';
buttonLabel: string | null;
};
type SignatureFormFieldJSON = BaseFormFieldJSON & {
type: 'pspdfkit/form-field/signature';
};
type FormFieldJSON = ListBoxFormFieldJSON | ComboBoxFormFieldJSON | RadioButtonFormFieldJSON | CheckBoxFormFieldJSON | TextFormFieldJSON | ButtonFormFieldJSON | SignatureFormFieldJSON;
type SerializedJSON = {
skippedPdfObjectIds?: number[];
annotations?: AnnotationJSONUnion[];
@ -6345,112 +6479,6 @@ type InstantJSON = SerializedJSON & {
};
};
type Rotation$1 = 0 | 90 | 180 | 270;
type AddPageConfiguration = {
backgroundColor: Color;
pageWidth: number;
pageHeight: number;
rotateBy: Rotation$1;
insets?: Rect;
};
type OperationAttachment = string | File | Blob;
type min = number;
type max = number;
type Range = [min, max];
type ImportPageIndex = Array<number | Range>;
type DocumentMetadata = {
title?: string;
author?: string;
};
type NonSerializableDocumentOperations = {
type: 'removePages';
pageIndexes: Array<number>;
} | {
type: 'duplicatePages';
pageIndexes: Array<number>;
} | {
type: 'movePages';
pageIndexes: Array<number>;
afterPageIndex: number;
} | {
type: 'movePages';
pageIndexes: Array<number>;
beforePageIndex: number;
} | {
type: 'rotatePages';
pageIndexes: Array<number>;
rotateBy: Rotation$1;
} | {
type: 'keepPages';
pageIndexes: Array<number>;
} | {
type: 'importDocument';
afterPageIndex: number;
treatImportedDocumentAsOnePage?: boolean;
document: OperationAttachment;
importedPageIndexes?: ImportPageIndex;
} | {
type: 'importDocument';
beforePageIndex: number;
treatImportedDocumentAsOnePage?: boolean;
document: OperationAttachment;
importedPageIndexes?: ImportPageIndex;
} | {
type: 'applyInstantJson';
instantJson: Record<string, any>;
dataFilePath: OperationAttachment;
} | {
type: 'applyXfdf';
xfdf: string;
dataFilePath: OperationAttachment;
} | {
type: 'flattenAnnotations';
pageIndexes?: Array<number>;
annotationIds?: string[];
} | {
type: 'setPageLabel';
pageIndexes?: Array<number>;
pageLabel?: string;
} | {
type: 'performOcr';
pageIndexes?: Array<number> | 'all';
language: string;
} | {
type: 'applyRedactions';
} | {
type: 'updateMetadata';
metadata: DocumentMetadata;
};
type DocumentOperation = (AddPageConfiguration & {
type: 'addPage';
afterPageIndex: number;
}) | (AddPageConfiguration & {
type: 'addPage';
beforePageIndex: number;
}) | {
type: 'cropPages';
pageIndexes?: Array<number>;
cropBox: Rect;
} | NonSerializableDocumentOperations;
declare function toJSON(bookmark: Bookmark): BookmarkJSON;
type ID$1 = string;
type BookmarkProps = {
id: ID$1 | null;
pdfBookmarkId: ID$1 | null;
name: string | null;
sortKey: number | null;
action: Action | null;
};
declare const Bookmark_base: Record$1.Factory<BookmarkProps>;
declare class Bookmark extends Bookmark_base {
id: ID$1;
action: Action;
static toSerializableObject: typeof toJSON;
static fromSerializableObject: (bookmark: BookmarkJSON) => Bookmark;
}
declare const SearchPattern: {
readonly CREDIT_CARD_NUMBER: "credit_card_number";
readonly DATE: "date";
@ -6468,13 +6496,6 @@ declare const SearchPattern: {
};
type ISearchPattern = (typeof SearchPattern)[keyof typeof SearchPattern];
declare const SearchType: {
readonly TEXT: "text";
readonly PRESET: "preset";
readonly REGEX: "regex";
};
type ISearchType = (typeof SearchType)[keyof typeof SearchType];
declare const ProductId: {
SharePoint: string;
Salesforce: string;
@ -6525,11 +6546,6 @@ type SignatureAppearance = {
watermarkImage?: Blob | File;
};
type Glyph = {
c: string;
rect: Rect;
};
declare const TextLineElementKind: {
P: string;
TH: string;
@ -7098,7 +7114,7 @@ declare class InstantClient {
userId: string | null | undefined;
}
declare const allowedToolbarTypes: ("distance" | "note" | "comment" | "text" | "zoom-in" | "zoom-out" | "link" | "search" | "ellipse" | "image" | "line" | "polygon" | "polyline" | "spacer" | "arrow" | "highlighter" | "undo" | "redo" | "callout" | "custom" | "print" | "rectangle" | "ink" | "stamp" | "cloudy-rectangle" | "dashed-rectangle" | "cloudy-ellipse" | "dashed-ellipse" | "cloudy-polygon" | "dashed-polygon" | "text-highlighter" | "perimeter" | "ellipse-area" | "rectangle-area" | "polygon-area" | "sidebar-thumbnails" | "sidebar-document-outline" | "sidebar-annotations" | "sidebar-bookmarks" | "pager" | "multi-annotations-selection" | "pan" | "zoom-mode" | "annotate" | "ink-eraser" | "signature" | "document-editor" | "document-crop" | "export-pdf" | "debug" | "layout-config" | "marquee-zoom" | "responsive-group" | "redact-text-highlighter" | "redact-rectangle" | "document-comparison" | "measure" | "form-creator" | "content-editor")[];
declare const allowedToolbarTypes: ("distance" | "note" | "comment" | "text" | "zoom-in" | "zoom-out" | "link" | "search" | "ellipse" | "image" | "line" | "polygon" | "polyline" | "spacer" | "arrow" | "highlighter" | "undo" | "redo" | "callout" | "debug" | "signature" | "custom" | "print" | "rectangle" | "ink" | "stamp" | "cloudy-rectangle" | "dashed-rectangle" | "cloudy-ellipse" | "dashed-ellipse" | "cloudy-polygon" | "dashed-polygon" | "text-highlighter" | "perimeter" | "ellipse-area" | "rectangle-area" | "polygon-area" | "sidebar-thumbnails" | "sidebar-document-outline" | "sidebar-annotations" | "sidebar-bookmarks" | "pager" | "multi-annotations-selection" | "pan" | "zoom-mode" | "annotate" | "ink-eraser" | "document-editor" | "document-crop" | "export-pdf" | "layout-config" | "marquee-zoom" | "responsive-group" | "redact-text-highlighter" | "redact-rectangle" | "document-comparison" | "measure" | "form-creator" | "content-editor")[];
type ToolbarItemType = ToolItemType | (typeof allowedToolbarTypes)[number];
type ToolbarItem = Omit<ToolItem, 'type'> & {
@ -7478,6 +7494,7 @@ declare class Instance {
textLinesForPageIndex: (pageIndex: number) => Promise<List<TextLine>>;
getMarkupAnnotationText: (annotation: TextMarkupAnnotationsUnion) => Promise<string>;
getTextFromRects: (pageIndex: number, rects: List<Rect>) => Promise<string>;
getDocumentPermissions: () => Promise<Record<IDocumentPermissions, boolean>>;
currentZoomLevel: number;
maximumZoomLevel: number;
minimumZoomLevel: number;
@ -7518,6 +7535,9 @@ declare class Instance {
setAnnotationCreatorName: (annotationCreatorName?: string | null) => void;
setOnWidgetAnnotationCreationStart: (callback: OnWidgetAnnotationCreationStartCallback) => void;
setOnCommentCreationStart: (callback: OnCommentCreationStartCallback) => void;
getOCGs: () => Promise<OCG[]>;
getOCGVisibilityState: () => Promise<OCGVisibilityState>;
setOCGVisibilityState: (visibilityState: OCGVisibilityState) => Promise<void>;
contentWindow: Window;
contentDocument: Document;
readonly viewState: ViewState;
@ -7583,7 +7603,7 @@ declare class Instance {
setDocumentEditorFooterItems: (stateOrFunction: DocumentEditorFooterItem[] | SetDocumentEditorFooterFunction) => void;
setDocumentEditorToolbarItems: (stateOrFunction: DocumentEditorToolbarItem[] | SetDocumentEditorToolbarFunction) => void;
getSignaturesInfo: () => Promise<SignaturesInfo>;
signDocument: (arg0: SignatureCreationData | null | undefined, arg1: TwoStepSignatureCallback | SigningServiceData | undefined) => Promise<void>;
signDocument: (arg0: SignatureCreationData | null, arg1?: TwoStepSignatureCallback | SigningServiceData) => Promise<void>;
applyOperations: (operations: Array<DocumentOperation>) => Promise<void>;
exportPDFWithOperations: (arg0: Array<DocumentOperation>) => Promise<ArrayBuffer>;
applyRedactions: () => Promise<void>;
@ -7647,13 +7667,21 @@ type AnnotationToolbarColorPresetsCallback = (options: {
type EnableRichTextCallback = (annotation: TextAnnotation) => boolean;
type TrustedCAsCallback = () => Promise<Array<ArrayBuffer | string>>;
type ElectronicSignaturesConfiguration = {
creationModes?: Readonly<IElectronicSignatureCreationMode[]>;
fonts?: Readonly<Font[]>;
setDefaultTypeText?: ElectronicSignatureDefaultTextCallback | string;
unstable_colorPresets?: Readonly<ColorPreset[]>;
};
type ElectronicSignatureDefaultTextCallback = () => string | undefined | void;
declare const ProcessorEngine: {
smallerSize: string;
fasterProcessing: string;
};
type IProcessorEngine = (typeof ProcessorEngine)[keyof typeof ProcessorEngine];
type TrustedCAsCallback = () => Promise<Array<ArrayBuffer | string>>;
declare const Theme: {
readonly LIGHT: "LIGHT";
@ -7745,6 +7773,7 @@ type StandaloneConfiguration = SharedConfiguration & {
instantJSON?: InstantJSON;
XFDF?: string;
XFDFKeepCurrentAnnotations?: boolean;
XFDFIgnorePageRotation?: boolean;
disableWebAssemblyStreaming?: boolean;
disableIndexedDBCaching?: boolean;
enableAutomaticLinkExtraction?: boolean;
@ -7757,6 +7786,8 @@ type StandaloneConfiguration = SharedConfiguration & {
isSharePoint?: boolean;
isSalesforce?: boolean;
productId?: IProductId;
processorEngine?: IProcessorEngine;
dynamicFonts?: string;
};
type Configuration = ServerConfiguration | StandaloneConfiguration;
@ -8436,6 +8467,10 @@ declare const PSPDFKit: {
Maui_MacCatalyst: string;
Maui_Windows: string;
};
ProcessorEngine: {
smallerSize: string;
fasterProcessing: string;
};
Conformance: {
readonly PDFA_1A: "pdfa-1a";
readonly PDFA_1B: "pdfa-1b";

View File

@ -44,4 +44,6 @@ interface User {
fullName: string;
}
export { EnvelopeResponse, Envelope, Document, Element, User }
type IFunction<T = void> = (...args: Array<any>) => T;
export { EnvelopeResponse, Envelope, Document, Element, User, IFunction }

View File

@ -39,18 +39,6 @@ var Rect = PSPDFKit.Geometry.Rect;
var SignatureFormField = PSPDFKit.FormFields.SignatureFormField;
var _a = PSPDFKit.ElectronicSignatureCreationMode, DRAW = _a.DRAW, TYPE = _a.TYPE;
var DISABLED = PSPDFKit.AutoSaveMode.DISABLED;
var allowedToolbarItems = [
"sidebar-thumbnails",
"sidebar-document-ouline",
"sidebar-bookmarks",
"pager",
"pan",
"zoom-out",
"zoom-in",
"zoom-mode",
"spacer",
"search"
];
var App = /** @class */ (function () {
function App() {
}
@ -58,19 +46,21 @@ var App = /** @class */ (function () {
// and will trigger loading of the Editor Interface
App.loadPDFFromUrl = function (container, envelopeKey) {
return __awaiter(this, void 0, void 0, function () {
var envelopeObject, document, arrayBuffer, e_1, _a, annotations, createdAnnotation;
var envelopeObject, arrayBuffer, e_1, _a, annotations, createdAnnotations;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
App.ui = new UI();
console.debug("Loading PSPDFKit..");
return [4 /*yield*/, App.loadData("/api/get-data/".concat(envelopeKey))];
case 1:
envelopeObject = _b.sent();
document = envelopeObject.envelope.documents[0];
App.envelopeKey = envelopeKey;
App.currentDocument = envelopeObject.envelope.documents[0];
_b.label = 2;
case 2:
_b.trys.push([2, 4, , 5]);
return [4 /*yield*/, App.loadDocument("/api/download/".concat(envelopeKey, "?id=").concat(document.id))];
return [4 /*yield*/, App.loadDocument("/api/download/".concat(envelopeKey, "?id=").concat(App.currentDocument.id))];
case 3:
arrayBuffer = _b.sent();
return [3 /*break*/, 5];
@ -87,30 +77,24 @@ var App = /** @class */ (function () {
console.debug(envelopeObject.envelope);
console.debug("PSPDFKit configured!");
annotations = [];
document.elements.forEach(function (element) {
console.log("Loading element");
console.debug("Page", element.page);
console.debug("Width / Height", element.width, element.height);
console.debug("Top / Left", element.top, element.left);
var id = PSPDFKit.generateInstantId();
var annotation = App.createSignatureAnnotation(id, element.width, element.height, element.top, element.left, element.page);
var formField = new SignatureFormField({
name: id,
annotationIds: List([annotation.id])
});
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];
annotations.push(annotation);
annotations.push(formField);
console.debug("Annotation created.");
});
return [4 /*yield*/, App.Instance.create(annotations)];
case 7:
createdAnnotation = (_b.sent())[0];
console.debug(createdAnnotation);
createdAnnotations = _b.sent();
console.debug(createdAnnotations);
return [2 /*return*/];
}
});
});
};
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" })
@ -121,57 +105,132 @@ var App = /** @class */ (function () {
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) {
var annotationPresets = PSPDFKit.defaultAnnotationPresets;
console.log(annotationPresets);
annotationPresets.ink = {
lineWidth: 10
};
return PSPDFKit.load({
container: container,
document: arrayBuffer,
autoSaveMode: DISABLED,
annotationPresets: annotationPresets,
annotationPresets: App.ui.getPresets(),
electronicSignatures: {
creationModes: [DRAW]
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) {
var annotation = createdAnnotations[0];
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 allowedToolbarItems.includes(item.type); });
var customItems = [
{
type: "custom",
id: "button-finish",
title: "Abschlie<69>en",
icon: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" fill=\"currentColor\" class=\"bi bi-check2-circle\" viewBox=\"0 0 16 16\">\n <path d=\"M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0z\"/>\n <path d=\"M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l7-7z\" />\n </svg>",
onPress: this.handleFinish
.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;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_a = eventType;
switch (_a) {
case "RESET": return [3 /*break*/, 1];
case "FINISH": return [3 /*break*/, 3];
}
];
instance.setToolbarItems(filteredItems.concat(customItems));
return [3 /*break*/, 5];
case 1: return [4 /*yield*/, App.handleReset(null)];
case 2:
_b.sent();
return [3 /*break*/, 5];
case 3: return [4 /*yield*/, App.handleFinish(null)];
case 4:
_b.sent();
return [3 /*break*/, 5];
case 5: return [2 /*return*/];
}
});
});
};
App.handleFinish = function (event) {
return __awaiter(this, void 0, void 0, function () {
var json, buffer;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, App.Instance.applyOperations([{ type: "flattenAnnotations" }])
//await downloadDocument();
];
case 0: return [4 /*yield*/, App.Instance.save()];
case 1:
_a.sent();
return [4 /*yield*/, App.Instance.exportInstantJSON()];
case 2:
json = _a.sent();
console.log(json);
return [4 /*yield*/, App.Instance.exportPDF({ flatten: true })];
case 3:
buffer = _a.sent();
return [4 /*yield*/, App.uploadDocument(buffer, App.envelopeKey, App.currentDocument.id)];
case 4:
_a.sent();
alert("Signatur wird gespeichert!");
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*/];
}
});
@ -215,6 +274,23 @@ var App = /** @class */ (function () {
});
});
};
App.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 page = element.page - 1;
var annotation = App.createSignatureAnnotation(id, width, height, top, left, page);
console.log(annotation);
var formField = new SignatureFormField({
name: id,
annotationIds: List([annotation.id])
});
console.log(formField);
return [annotation, formField];
};
App.createSignatureAnnotation = function (id, width, height, top, left, pageIndex) {
var annotation = new PSPDFKit.Annotations.WidgetAnnotation({
id: id,
@ -227,4 +303,54 @@ var App = /** @class */ (function () {
return App;
}());
export { App };
var UI = /** @class */ (function () {
function UI() {
this.allowedToolbarItems = [
"sidebar-thumbnails",
"sidebar-document-ouline",
"sidebar-bookmarks",
"pager",
"pan",
"zoom-out",
"zoom-in",
"zoom-mode",
"spacer",
"search"
];
this.getToolbarItems = function (callback) {
var customItems = [
{
type: "custom",
id: "button-reset",
title: "Zurücksetzen",
onPress: function () {
callback("RESET");
},
icon: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" fill=\"currentColor\" class=\"bi bi-arrow-counterclockwise\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z\"/>\n <path d=\"M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z\"/>\n </svg>"
},
{
type: "custom",
id: "button-finish",
title: "Abschließen",
onPress: function () {
callback("FINISH");
},
icon: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" fill=\"currentColor\" class=\"bi bi-check2-circle\" viewBox=\"0 0 16 16\">\n <path d=\"M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0z\"/>\n <path d=\"M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l7-7z\" />\n </svg>"
}
];
return customItems;
};
}
UI.prototype.getPresets = function () {
var annotationPresets = PSPDFKit.defaultAnnotationPresets;
annotationPresets.ink = {
lineWidth: 10
};
annotationPresets.widget = {
readOnly: true
};
return annotationPresets;
};
return UI;
}());
//# sourceMappingURL=app.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More