Compare commits
4 Commits
56074c2b9f
...
6327fef2e0
| Author | SHA1 | Date | |
|---|---|---|---|
| 6327fef2e0 | |||
| d0bfe795d7 | |||
| 10b1de4cf0 | |||
| cf3535b4de |
@@ -76,7 +76,7 @@ public class HomeController : ViewControllerBase
|
||||
}
|
||||
|
||||
if(decoded.GetEncodeType() == EncodeType.EnvelopeReceiverReadOnly)
|
||||
return Redirect($"{envelopeReceiverId}/ReadOnly");
|
||||
return await EnvelopeReceiverReadOnly(decoded.ParseReadOnlyId());
|
||||
|
||||
ViewData["EnvelopeKey"] = envelopeReceiverId;
|
||||
|
||||
@@ -160,13 +160,17 @@ public class HomeController : ViewControllerBase
|
||||
var rejRcvrs = await _historyService.ReadRejectingReceivers(er.Envelope!.Id);
|
||||
if (rejRcvrs.Any())
|
||||
{
|
||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
ViewBag.IsExt = !rejRcvrs.Contains(er.Receiver); //external if the current user is not rejected
|
||||
return View("EnvelopeRejected", er);
|
||||
}
|
||||
|
||||
//check if it has already signed
|
||||
if (await _historyService.IsSigned(envelopeId: er.Envelope!.Id, userReference: er.Receiver!.EmailAddress))
|
||||
{
|
||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
return View("EnvelopeSigned");
|
||||
}
|
||||
|
||||
if (er.Envelope.Documents?.FirstOrDefault() is DocumentDto doc && doc.ByteData is not null)
|
||||
{
|
||||
@@ -365,138 +369,59 @@ public class HomeController : ViewControllerBase
|
||||
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, exception: ex);
|
||||
return this.ViewInnerServiceError();
|
||||
}
|
||||
}
|
||||
|
||||
[Authorize(Roles = ReceiverRole.FullyAuth)]
|
||||
[HttpGet("{envelopeReceiverId}/Success")]
|
||||
[Obsolete("Use DigitalData.Core.Exceptions and .Middleware")]
|
||||
public async Task<IActionResult> EnvelopeSigned([FromRoute] string envelopeReceiverId, CancellationToken cancel)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _envRcvService.IsExisting(envelopeReceiverId: envelopeReceiverId).ThenAsync(
|
||||
SuccessAsync: (Func<bool, Task<IActionResult>>)(async isExisting =>
|
||||
{
|
||||
if(!isExisting)
|
||||
return this.ViewEnvelopeNotFound();
|
||||
|
||||
var signed = await _mediator.IsSignedAsync(envelopeReceiverId, cancel);
|
||||
if (signed)
|
||||
return base.Redirect($"/Envelope/{envelopeReceiverId}/Locked");
|
||||
|
||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
ViewData["EnvelopeKey"] = envelopeReceiverId;
|
||||
return base.View();
|
||||
}),
|
||||
Fail: IActionResult (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return this.ViewEnvelopeNotFound();
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, exception: ex);
|
||||
return this.ViewInnerServiceError();
|
||||
}
|
||||
}
|
||||
|
||||
[Authorize(Roles = ReceiverRole.FullyAuth)]
|
||||
[HttpGet("{envelopeReceiverId}/Rejected")]
|
||||
[NonAction]
|
||||
[Obsolete("Use MediatR")]
|
||||
public async Task<IActionResult> EnvelopeRejected([FromRoute] string envelopeReceiverId)
|
||||
public async Task<IActionResult> EnvelopeReceiverReadOnly([FromRoute] long readOnlyId)
|
||||
{
|
||||
try
|
||||
var erro_res = await _readOnlyService.ReadByIdAsync(readOnlyId);
|
||||
if (erro_res.IsFailed)
|
||||
{
|
||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
return await _envRcvService.ReadByEnvelopeReceiverIdAsync(envelopeReceiverId).ThenAsync(
|
||||
SuccessAsync: async (er) =>
|
||||
{
|
||||
return await _historyService.IsRejected(envelopeId: er.EnvelopeId)
|
||||
? View(er)
|
||||
: Redirect($"/Envelope/{envelopeReceiverId}/Locked");
|
||||
|
||||
},
|
||||
Fail: IActionResult (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return this.ViewEnvelopeNotFound();
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, exception: ex);
|
||||
_logger.LogNotice(erro_res.Notices);
|
||||
return this.ViewInnerServiceError();
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("{readOnlyKey}/ReadOnly")]
|
||||
[Obsolete("Use MediatR")]
|
||||
public async Task<IActionResult> EnvelopeReceiverReadOnly([FromRoute] string readOnlyKey)
|
||||
{
|
||||
try
|
||||
var erro = erro_res.Data;
|
||||
|
||||
if (DateTime.Now > erro.DateValid)
|
||||
return View("EnvelopeExpired");
|
||||
|
||||
return await _envRcvService.ReadByUuidSignatureAsync(uuid: erro.Envelope!.Uuid, erro.Receiver!.Signature).ThenAsync(
|
||||
SuccessAsync: async er =>
|
||||
{
|
||||
// check if the readOnlyId is valid
|
||||
if (!readOnlyKey.TryDecode(out var decodedKeys) || decodedKeys.GetEncodeType() != EncodeType.EnvelopeReceiverReadOnly)
|
||||
var envelopeKey = (er.Envelope!.Uuid, er.Receiver!.Signature).ToEnvelopeKey();
|
||||
|
||||
//TODO: implement multi-threading to history process (Task)
|
||||
var hist_res = await _historyService.RecordAsync((int)erro.EnvelopeId, erro.AddedWho, EnvelopeStatus.EnvelopeViewed);
|
||||
if (hist_res.IsFailed)
|
||||
{
|
||||
Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||||
_logger.LogError(
|
||||
"Although the envelope was sent as read-only, the EnvelopeShared hisotry could not be saved. ReadOnly-Id: {readOnlyKey}\nEnvelope Receiver:\n{envelopeReceiver}",
|
||||
readOnlyId, JsonConvert.SerializeObject(er));
|
||||
_logger.LogNotice(hist_res.Notices);
|
||||
}
|
||||
|
||||
if (er.Envelope.Documents?.FirstOrDefault() is DocumentDto doc && doc.ByteData is not null)
|
||||
{
|
||||
ViewData["DocumentBytes"] = doc.ByteData;
|
||||
ViewData["EnvelopeKey"] = envelopeKey;
|
||||
ViewData["IsReadOnly"] = true;
|
||||
ViewData["ReadOnly"] = erro;
|
||||
ViewData["PSPDFKitLicenseKey"] = _configuration["PSPDFKitLicenseKey"];
|
||||
return View("ShowEnvelope", er);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogEnvelopeError(envelopeReceiverId: envelopeKey, message: "No document byte-data was found in ENVELOPE_DOCUMENT table.");
|
||||
return this.ViewDocumentNotFound();
|
||||
}
|
||||
|
||||
var readOnlyId = decodedKeys.ParseReadOnlyId();
|
||||
var erro_res = await _readOnlyService.ReadByIdAsync(readOnlyId);
|
||||
if (erro_res.IsFailed)
|
||||
{
|
||||
_logger.LogNotice(erro_res.Notices);
|
||||
return this.ViewInnerServiceError();
|
||||
}
|
||||
|
||||
var erro = erro_res.Data;
|
||||
|
||||
if (DateTime.Now > erro.DateValid)
|
||||
return View("EnvelopeExpired");
|
||||
|
||||
return await _envRcvService.ReadByUuidSignatureAsync(uuid: erro.Envelope!.Uuid, erro.Receiver!.Signature).ThenAsync(
|
||||
SuccessAsync: async er =>
|
||||
{
|
||||
var envelopeKey = (er.Envelope!.Uuid, er.Receiver!.Signature).ToEnvelopeKey();
|
||||
|
||||
//TODO: implement multi-threading to history process (Task)
|
||||
var hist_res = await _historyService.RecordAsync((int)erro.EnvelopeId, erro.AddedWho, EnvelopeStatus.EnvelopeViewed);
|
||||
if (hist_res.IsFailed)
|
||||
{
|
||||
_logger.LogError(
|
||||
"Although the envelope was sent as read-only, the EnvelopeShared hisotry could not be saved. ReadOnly-key: {readOnlyKey}\nEnvelope Receiver:\n{envelopeReceiver}",
|
||||
readOnlyKey, JsonConvert.SerializeObject(er));
|
||||
_logger.LogNotice(hist_res.Notices);
|
||||
}
|
||||
|
||||
if (er.Envelope.Documents?.FirstOrDefault() is DocumentDto doc && doc.ByteData is not null)
|
||||
{
|
||||
ViewData["DocumentBytes"] = doc.ByteData;
|
||||
ViewData["EnvelopeKey"] = envelopeKey;
|
||||
ViewData["IsReadOnly"] = true;
|
||||
ViewData["ReadOnly"] = erro;
|
||||
ViewData["PSPDFKitLicenseKey"] = _configuration["PSPDFKitLicenseKey"];
|
||||
return View("ShowEnvelope", er);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogEnvelopeError(envelopeReceiverId: envelopeKey, message: "No document byte-data was found in ENVELOPE_DOCUMENT table.");
|
||||
return this.ViewDocumentNotFound();
|
||||
}
|
||||
},
|
||||
Fail: (messages, notices) =>
|
||||
{
|
||||
_logger.LogNotice(notices);
|
||||
return this.ViewEnvelopeNotFound();
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
},
|
||||
Fail: (messages, notices) =>
|
||||
{
|
||||
_logger.LogError(ex, "An unexpected error occurred while displaying a read-only envelope. Read-only key is {readOnlyKey}. {message}", readOnlyKey, ex.Message);
|
||||
return this.ViewInnerServiceError();
|
||||
}
|
||||
_logger.LogNotice(notices);
|
||||
return this.ViewEnvelopeNotFound();
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet("Error404")]
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
<PackageTags>digital data envelope generator web</PackageTags>
|
||||
<Description>EnvelopeGenerator.Web is an ASP.NET MVC application developed to manage signing processes. It uses Entity Framework Core (EF Core) for database operations. The user interface for signing processes is developed with Razor View Engine (.cshtml files) and JavaScript under wwwroot, integrated with PSPDFKit. This integration allows users to view and sign documents seamlessly.</Description>
|
||||
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
||||
<Version>3.2.3</Version>
|
||||
<AssemblyVersion>3.2.3</AssemblyVersion>
|
||||
<FileVersion>3.2.3</FileVersion>
|
||||
<Version>3.3.0</Version>
|
||||
<AssemblyVersion>3.3.0</AssemblyVersion>
|
||||
<FileVersion>3.3.0</FileVersion>
|
||||
<Copyright>Copyright © 2025 Digital Data GmbH. All rights reserved.</Copyright>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ class API {
|
||||
}
|
||||
|
||||
static get REJECT_REDIR_URL() {
|
||||
return `/envelope/${API.ENV_KEY}/rejected`;
|
||||
return `/envelope/${API.ENV_KEY}`;
|
||||
}
|
||||
|
||||
static get SHARE_URL() {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
class Content{static get JSON(){return"application/json"}}class API{static get REJECT_URL(){return`/api/envelope/reject`}static get REJECT_REDIR_URL(){return`/envelope/${API.ENV_KEY}/rejected`}static get SHARE_URL(){return`/api/readonly`}static __XSRF_TOKEN
|
||||
class Content{static get JSON(){return"application/json"}}class API{static get REJECT_URL(){return`/api/envelope/reject`}static get REJECT_REDIR_URL(){return`/envelope/${API.ENV_KEY}`}static get SHARE_URL(){return`/api/readonly`}static __XSRF_TOKEN
|
||||
static get XSRF_TOKEN(){return API.__XSRF_TOKEN??=document.getElementsByName("__RequestVerificationToken")[0].value,API.__XSRF_TOKEN}static get ENV_KEY(){return ENV_KEY??document.querySelector('meta[name="env-key"]').getAttribute("content")}}const submitForm=async n=>await fetch(n.action,{method:n.method,body:new FormData(n),headers:{"X-Requested-With":"XMLHttpRequest"}}),createRequest=async(n,t,i,r)=>fetch(t,{credentials:"include",method:n,headers:{"Content-Type":r,"X-XSRF-TOKEN":API.XSRF_TOKEN},body:JSON.stringify(i)}),createPost=(n,t,i)=>createRequest("POST",n,t,i),rejectEnvelope=n=>createPost(API.REJECT_URL,n,Content.JSON),redirect=n=>window.location.href=n,redirRejected=()=>redirect(API.REJECT_REDIR_URL),shareEnvelope=(n,t)=>createPost(API.SHARE_URL,{receiverMail:n,dateValid:t},Content.JSON);
|
||||
@@ -145,7 +145,7 @@ class App {
|
||||
|
||||
if (result == true) {
|
||||
// Redirect to success page after saving to database
|
||||
window.location.href = `/Envelope/${this.envelopeKey}/Success`
|
||||
window.location.href = `/Envelope/${this.envelopeKey}`
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
2
EnvelopeGenerator.Web/wwwroot/js/app.min.js
vendored
2
EnvelopeGenerator.Web/wwwroot/js/app.min.js
vendored
@@ -1,3 +1,3 @@
|
||||
const ActionType={Created:0,Saved:1,Sent:2,EmailSent:3,Delivered:4,Seen:5,Signed:6,Rejected:7};class App{constructor(n,t,i,r,u,f){this.container=f??`#${this.constructor.name.toLowerCase()}`;this.envelopeKey=n;this.Instance=null;this.currentDocument=null;this.currentReceiver=null;this.signatureCount=0;this.envelopeReceiver=t;this.documentBytes=i;this.licenseKey=r;this.locale=u}async init(){this.currentDocument=this.envelopeReceiver.envelope.documents[0];this.currentReceiver=this.envelopeReceiver.receiver;const n=this.documentBytes;if(n.fatal||n.error)return Swal.fire({title:"Fehler",text:"Dokument konnte nicht geladen werden!",icon:"error"});const t=this.documentBytes;this.Instance=await UI.loadPSPDFKit(t,this.container,this.licenseKey,this.locale);UI.addToolbarItems(this.Instance,this.handleClick.bind(this));this.Instance.addEventListener("annotations.load",this.handleAnnotationsLoad.bind(this));this.Instance.addEventListener("annotations.change",this.handleAnnotationsChange.bind(this));this.Instance.addEventListener("annotations.create",this.handleAnnotationsCreate.bind(this));this.Instance.addEventListener("annotations.willChange",()=>{Comp.ActPanel.Toggle()});try{this.signatureCount=this.currentDocument.elements.length;await createAnnotations(this.currentDocument,this.Instance)}catch(i){console.error("Error loading annotations:",i)}[...document.getElementsByClassName("btn_refresh")].forEach(n=>n.addEventListener("click",()=>this.handleClick("RESET")));[...document.getElementsByClassName("btn_complete")].forEach(n=>n.addEventListener("click",()=>this.handleClick("FINISH")));[...document.getElementsByClassName("btn_reject")].forEach(n=>n.addEventListener("click",()=>this.handleClick("REJECT")))}handleAnnotationsLoad(n){n.toJS()}handleAnnotationsChange(){}async handleAnnotationsCreate(n){const t=n.toJS()[0],i=!!t.formFieldName,r=!!t.isSignature;if(i===!1&&r===!0){const r=t.boundingBox.left-20,u=t.boundingBox.top-20,n=150,i=75,f=new Date,e=await createAnnotationFrameBlob(this.envelopeReceiver.name,this.currentReceiver.signature,f,n,i),o=await fetch(e),s=await o.blob(),h=await this.Instance.createAttachment(s),c=createImageAnnotation(new PSPDFKit.Geometry.Rect({left:r,top:u,width:n,height:i}),t.pageIndex,h);this.Instance.create(c)}}async handleClick(n){let t=!1;switch(n){case"RESET":t=await this.handleReset(null);Comp.SignatureProgress.SignedCount=0;t.isConfirmed&&Swal.fire({title:"Erfolg",text:"Dokument wurde zurückgesetzt",icon:"info"});break;case"FINISH":t=await this.handleFinish(null);t==!0&&(window.location.href=`/Envelope/${this.envelopeKey}/Success`);break;case"REJECT":Swal.fire({title:localized.rejection,html:`<div class="text-start fs-6 p-0 m-0">${localized.rejectionReasonQ}</div>`,icon:"question",input:"text",inputAttributes:{autocapitalize:"off"},showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.complete,cancelButtonText:localized.back,showLoaderOnConfirm:!0,preConfirm:async n=>{try{return await rejectEnvelope(n)}catch(t){Swal.showValidationMessage(`
|
||||
const ActionType={Created:0,Saved:1,Sent:2,EmailSent:3,Delivered:4,Seen:5,Signed:6,Rejected:7};class App{constructor(n,t,i,r,u,f){this.container=f??`#${this.constructor.name.toLowerCase()}`;this.envelopeKey=n;this.Instance=null;this.currentDocument=null;this.currentReceiver=null;this.signatureCount=0;this.envelopeReceiver=t;this.documentBytes=i;this.licenseKey=r;this.locale=u}async init(){this.currentDocument=this.envelopeReceiver.envelope.documents[0];this.currentReceiver=this.envelopeReceiver.receiver;const n=this.documentBytes;if(n.fatal||n.error)return Swal.fire({title:"Fehler",text:"Dokument konnte nicht geladen werden!",icon:"error"});const t=this.documentBytes;this.Instance=await UI.loadPSPDFKit(t,this.container,this.licenseKey,this.locale);UI.addToolbarItems(this.Instance,this.handleClick.bind(this));this.Instance.addEventListener("annotations.load",this.handleAnnotationsLoad.bind(this));this.Instance.addEventListener("annotations.change",this.handleAnnotationsChange.bind(this));this.Instance.addEventListener("annotations.create",this.handleAnnotationsCreate.bind(this));this.Instance.addEventListener("annotations.willChange",()=>{Comp.ActPanel.Toggle()});try{this.signatureCount=this.currentDocument.elements.length;await createAnnotations(this.currentDocument,this.Instance)}catch(i){console.error("Error loading annotations:",i)}[...document.getElementsByClassName("btn_refresh")].forEach(n=>n.addEventListener("click",()=>this.handleClick("RESET")));[...document.getElementsByClassName("btn_complete")].forEach(n=>n.addEventListener("click",()=>this.handleClick("FINISH")));[...document.getElementsByClassName("btn_reject")].forEach(n=>n.addEventListener("click",()=>this.handleClick("REJECT")))}handleAnnotationsLoad(n){n.toJS()}handleAnnotationsChange(){}async handleAnnotationsCreate(n){const t=n.toJS()[0],i=!!t.formFieldName,r=!!t.isSignature;if(i===!1&&r===!0){const r=t.boundingBox.left-20,u=t.boundingBox.top-20,n=150,i=75,f=new Date,e=await createAnnotationFrameBlob(this.envelopeReceiver.name,this.currentReceiver.signature,f,n,i),o=await fetch(e),s=await o.blob(),h=await this.Instance.createAttachment(s),c=createImageAnnotation(new PSPDFKit.Geometry.Rect({left:r,top:u,width:n,height:i}),t.pageIndex,h);this.Instance.create(c)}}async handleClick(n){let t=!1;switch(n){case"RESET":t=await this.handleReset(null);Comp.SignatureProgress.SignedCount=0;t.isConfirmed&&Swal.fire({title:"Erfolg",text:"Dokument wurde zurückgesetzt",icon:"info"});break;case"FINISH":t=await this.handleFinish(null);t==!0&&(window.location.href=`/Envelope/${this.envelopeKey}`);break;case"REJECT":Swal.fire({title:localized.rejection,html:`<div class="text-start fs-6 p-0 m-0">${localized.rejectionReasonQ}</div>`,icon:"question",input:"text",inputAttributes:{autocapitalize:"off"},showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.complete,cancelButtonText:localized.back,showLoaderOnConfirm:!0,preConfirm:async n=>{try{return await rejectEnvelope(n)}catch(t){Swal.showValidationMessage(`
|
||||
Request failed: ${t}
|
||||
`)}},allowOutsideClick:()=>!Swal.isLoading()}).then(n=>{if(n.isConfirmed){const t=n.value;t.ok?redirRejected():Swal.showValidationMessage(`Request failed: ${t.message}`)}});break;case"COPY_URL":const n=window.location.href.replace(/\/readonly/gi,"");navigator.clipboard.writeText(n).then(function(){bsNotify("Kopiert",{alert_type:"success",delay:4,icon_name:"check_circle"})}).catch(function(){bsNotify("Unerwarteter Fehler",{alert_type:"danger",delay:4,icon_name:"error"})});break;case"SHARE":Comp.ShareBackdrop.show();break;case"LOGOUT":await logout()}}async handleFinish(){const n=await this.Instance.exportInstantJSON(),t=await n.formFieldValues,r=t.filter(n=>isFieldRequired(n)),u=r.some(n=>n.value===undefined||n.value===null||n.value==="");if(u)return Swal.fire({title:"Warnung",text:"Bitte füllen Sie alle Standortinformationen vollständig aus!",icon:"warning"}),!1;const f=new RegExp("^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$"),e=t.filter(n=>isCityField(n));for(var i of e)if(!IS_MOBILE_DEVICE&&!f.test(i.value))return Swal.fire({title:"Warnung",text:`Bitte überprüfen Sie die eingegebene Ortsangabe "${i.value}" auf korrekte Formatierung. Beispiele für richtige Formate sind: München, Île-de-France, Sauðárkrókur, San Francisco, St. Catharines usw.`,icon:"warning"}),!1;const o=await this.validateAnnotations(this.signatureCount);return o===!1?(Swal.fire({title:"Warnung",text:"Es wurden nicht alle Signaturfelder ausgefüllt!",icon:"warning"}),!1):Swal.fire({title:localized.confirmation,html:`<div class="text-start fs-6 p-0 m-0">${localized.sigAgree}</div>`,icon:"question",showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.finalize,cancelButtonText:localized.back}).then(async t=>{if(t.isConfirmed){try{await this.Instance.save()}catch(i){return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1}try{const t=await postAnnotation(await n);if(t.ok)return!0;if(t.status===403)return Swal.fire({title:"Warnung",text:"Umschlag ist nicht mehr verfügbar.",icon:"warning"}),!1;throw new Error;}catch(i){return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1}}else return!1})}async validateAnnotations(n){const t=await getAnnotations(this.Instance),i=t.map(n=>n.toJS()).filter(n=>n.isSignature);return n>i.length?!1:!0}async handleReset(){const n=await Swal.fire({title:"Sind sie sicher?",text:"Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?",icon:"question",showCancelButton:!0});if(n.isConfirmed){const n=await deleteAnnotations(this.Instance)}return n}}
|
||||
Reference in New Issue
Block a user