Progress bar label now displays "Confirmations" if isReadAndConfirm is true, otherwise it shows "Signatures". This improves clarity for users based on the envelope's required action.
241 lines
12 KiB
Plaintext
241 lines
12 KiB
Plaintext
@{
|
|
var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string;
|
|
var cImg = _cImgOpt.Value;
|
|
}
|
|
@using DigitalData.Core.Abstraction.Application;
|
|
@using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver
|
|
@using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiverReadOnly
|
|
@using EnvelopeGenerator.Application.Common.Dto;
|
|
@using EnvelopeGenerator.Web.Extensions
|
|
@using Newtonsoft.Json
|
|
@using Newtonsoft.Json.Serialization
|
|
@using EnvelopeGenerator.Domain.Interfaces
|
|
@model EnvelopeReceiverDto;
|
|
@{
|
|
var userCulture = ViewData["UserCulture"] as Culture;
|
|
var envelope = Model.Envelope;
|
|
var receiver_name = Model.Name;
|
|
var document = Model.Envelope?.Documents?.FirstOrDefault();
|
|
var sender = Model.Envelope?.User;
|
|
var pages = document?.Elements?.Select(e => e.Page) ?? Array.Empty<int>();
|
|
int? signatureCount = document?.Elements?.Count();
|
|
var stPageIndexes = string.Join(pages.Count() > 1 ? ", " : "", pages.Take(pages.Count() - 1))
|
|
+ (pages.Count() > 1 ? $" {_localizer.And()} " : "") + pages.LastOrDefault();
|
|
var isReadOnly = false;
|
|
if (ViewData["IsReadOnly"] is bool isReadOnly_bool)
|
|
isReadOnly = isReadOnly_bool;
|
|
|
|
var isReadAndConfirm = envelope.IsReadAndConfirm();
|
|
|
|
ViewData["Title"] = isReadOnly
|
|
? _localizer.ViewDoc()
|
|
: isReadAndConfirm
|
|
? _localizer.ConfirmDoc()
|
|
: _localizer.SignDoc();
|
|
}
|
|
<div class="envelope-view">
|
|
@if (!isReadOnly)
|
|
{
|
|
<div id="flex-action-panel" class="btn-group btn_group position-fixed bottom-0 end-0 d-flex align-items-center" role="group" aria-label="Basic mixed styles example">
|
|
<button class="btn_complete btn btn-success btn-desktop" type="button">
|
|
<svg class="icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 16">
|
|
<path d="m10.036 8.278 9.258-7.79A1.979 1.979 0 0 0 18 0H2A1.987 1.987 0 0 0 .641.541l9.395 7.737Z" />
|
|
<path d="M11.241 9.817c-.36.275-.801.425-1.255.427-.428 0-.845-.138-1.187-.395L0 2.6V14a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V2.5l-8.759 7.317Z" />
|
|
</svg>
|
|
<span>@_localizer.Complete()</span>
|
|
</button>
|
|
<button class="btn_reject btn btn-danger btn-desktop" type="button">
|
|
<svg width="25px" height="25px" viewBox="43.5 43.5 512 512" version="1.1" fill="currentColor" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<path class="st0" d="M263.24,43.5c-117.36,0-212.5,95.14-212.5,212.5s95.14,212.5,212.5,212.5s212.5-95.14,212.5-212.5 S380.6,43.5,263.24,43.5z M367.83,298.36c17.18,17.18,17.18,45.04,0,62.23v0c-17.18,17.18-45.04,17.18-62.23,0l-42.36-42.36 l-42.36,42.36c-17.18,17.18-45.04,17.18-62.23,0v0c-17.18-17.18-17.18-45.04,0-62.23L201.01,256l-42.36-42.36 c-17.18-17.18-17.18-45.04,0-62.23v0c17.18-17.18,45.04-17.18,62.23,0l42.36,42.36l42.36-42.36c17.18-17.18,45.04-17.18,62.23,0v0 c17.18,17.18,17.18,45.04,0,62.23L325.46,256L367.83,298.36z" />
|
|
</svg>
|
|
<span>@_localizer.Reject()</span>
|
|
</button>
|
|
@if(!Model.Envelope!.ReadOnly){
|
|
<button class="btn_refresh btn btn-secondary btn-desktop" type="button">
|
|
<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>
|
|
</button>
|
|
}
|
|
</div>
|
|
}
|
|
<div class="dd-cards-container">
|
|
<div class="dd-card">
|
|
<div class="dd-card-preview">
|
|
<img src="~/img/sign_flow_horizontal.svg" class="app-logo">
|
|
@if (!isReadOnly)
|
|
{
|
|
<div class="progress-container">
|
|
<div id="signed-count-bar" class="progress"></div>
|
|
<span class="progress-text">
|
|
<span id="signed-count">0</span>/<span id="signature-count">@signatureCount</span> @(isReadAndConfirm
|
|
? _localizer["Confirmations"]
|
|
: _localizer["Signatures"])
|
|
</span>
|
|
</div>
|
|
}
|
|
</div>
|
|
<div class="dd-card-info">
|
|
<div class="logo">
|
|
<img class="@cImg["Company"].GetClassIn("Show")" src="@cImg["Company"].Src" alt="logo">
|
|
</div>
|
|
<h2>@($"{envelope?.Title}")</h2>
|
|
@if (isReadOnly)
|
|
{
|
|
var dateTimeSt = string.Empty;
|
|
if (ViewData["ReadOnly"] is EnvelopeReceiverReadOnlyDto readOnly)
|
|
dateTimeSt = readOnly.DateValid.ToLongDateString();
|
|
<h6>@string.Format(_localizer["ReadOnlyMessage"], receiver_name, dateTimeSt)</h6>
|
|
}
|
|
else
|
|
{
|
|
<div class="markdown">@(envelope?.Message)</div>
|
|
}
|
|
<p>
|
|
<small class="text-body-secondary">
|
|
@Html.Raw(_localizer.EnvelopeInfo2().Format(
|
|
envelope?.AddedWhen.ToString(userCulture?.Info.DateTimeFormat),
|
|
$"{sender?.Prename} {sender?.Name}",
|
|
sender?.Email,
|
|
envelope?.Title,
|
|
sender?.Prename,
|
|
sender?.Name,
|
|
sender?.Email))
|
|
</small>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@if (!isReadOnly)
|
|
{
|
|
<div class="modal fade" id="shareBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="shareBackdropLabel" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<small class="modal-title text-body-secondary" id="shareBackdropLabel">@_localizer["EnterRecipientToShareDocument"]:</small>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="input-group mb-3">
|
|
<span class="input-group-text">@_localizer["Email"]</span>
|
|
<input type="text" class="form-control email-input" placeholder="user@mail.com" id="readonly-receiver-mail" aria-label="">
|
|
</div>
|
|
<div class="input-group">
|
|
<span class="input-group-text">@_localizer["ValidUntil"]</span>
|
|
<input type="date" name="expiration" class="form-control" lang="de" id="readonly-date-valid" onkeydown="return false;" onclick="this.showPicker()"
|
|
min="@DateTime.Today.AddDays(1).ToString("yyyy-MM-dd")"
|
|
max="@DateTime.Today.AddDays(90).ToString("yyyy-MM-dd")"
|
|
value="@DateTime.Today.AddDays(7).ToString("yyyy-MM-dd")">
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary" id="readonly-send">
|
|
<span class="material-symbols-outlined">
|
|
send
|
|
</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
<div id='app'></div>
|
|
</div>
|
|
@if (!isReadOnly)
|
|
{
|
|
<script nonce="@nonce">
|
|
document.getElementById('readonly-send').addEventListener('click', async () => {
|
|
const receiverMail = document.getElementById('readonly-receiver-mail');
|
|
const dateValid = document.getElementById('readonly-date-valid');
|
|
|
|
const receiverMail_value = receiverMail.value;
|
|
const dateValid_value = dateValid.value;
|
|
|
|
const shrEnvLocalizedTexts = {
|
|
invalidEmailTitle: '@_localizer["ShrEnvInvalidEmailTitle"]',
|
|
invalidEmailText: '@_localizer["ShrEnvInvalidEmailText"]',
|
|
invalidDateTitle: '@_localizer["ShrEnvInvalidDateTitle"]',
|
|
invalidDateText: '@_localizer["ShrEnvInvalidDateText"]',
|
|
sentTitle: '@_localizer["ShrEnvSentTitle"]',
|
|
errorTitle: '@_localizer["ShrEnvErrorTitle"]',
|
|
unexpectedErrorTitle: '@_localizer["UnexpectedErrorTitle"]',
|
|
operationFailedText: '@_localizer["ShrEnvOperationFailedText"]'
|
|
};
|
|
|
|
//check email
|
|
if (!receiverMail_value || receiverMail.classList.contains('is-invalid')) {
|
|
Swal.fire({
|
|
icon: "error",
|
|
title: shrEnvLocalizedTexts.invalidEmailTitle,
|
|
text: shrEnvLocalizedTexts.invalidEmailText
|
|
});
|
|
return;
|
|
}
|
|
|
|
//check the date
|
|
const tomorrow = new Date(Date.now() + 86400000);
|
|
if (new Date(dateValid_value) < tomorrow) {
|
|
Swal.fire({
|
|
icon: "error",
|
|
title: shrEnvLocalizedTexts.invalidDateTitle,
|
|
text: shrEnvLocalizedTexts.invalidDateText
|
|
});
|
|
return;
|
|
}
|
|
|
|
shareEnvelope(receiverMail_value, dateValid_value)
|
|
.then(res => {
|
|
if (res.ok) {
|
|
Swal.fire({
|
|
title: shrEnvLocalizedTexts.sentTitle,
|
|
icon: "success"
|
|
});
|
|
}
|
|
else {
|
|
Swal.fire({
|
|
icon: "error",
|
|
title: `${shrEnvLocalizedTexts.errorTitle} ${res.status}`,
|
|
text: shrEnvLocalizedTexts.operationFailedText
|
|
});
|
|
}
|
|
})
|
|
.catch(err => {
|
|
Swal.fire({
|
|
icon: "error",
|
|
title: shrEnvLocalizedTexts.unexpectedErrorTitle,
|
|
text: shrEnvLocalizedTexts.operationFailedText
|
|
});
|
|
})
|
|
|
|
receiverMail.value = '';
|
|
dateValid.valueAsDate = new Date(new Date().setDate(new Date().getDate() + 8));
|
|
});
|
|
</script>
|
|
}
|
|
<script nonce="@nonce">
|
|
const collapseNav = () => {
|
|
document.addEventListener('click', function (event) {
|
|
var navbarToggle = document.getElementById('navbarToggleExternalContent');
|
|
var navbarButton = document.querySelector('[data-bs-target="#navbarToggleExternalContent"]');
|
|
var isCollapsed = new bootstrap.Collapse(navbarToggle)._isTransitioning;
|
|
|
|
if (!navbarToggle.contains(event.target) && !navbarButton.contains(event.target) && !isCollapsed) {
|
|
new bootstrap.Collapse(navbarToggle).hide();
|
|
}
|
|
});
|
|
}
|
|
@if (ViewData["DocumentBytes"] is byte[] documentBytes)
|
|
{
|
|
var settings = new JsonSerializerSettings
|
|
{
|
|
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
|
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
|
|
};
|
|
var envelopeReceiverJson = JsonConvert.SerializeObject(Model, settings);
|
|
var documentBase64String = Convert.ToBase64String(documentBytes);
|
|
var envelopeKey = ViewData["EnvelopeKey"] as string;
|
|
|
|
@:document.addEventListener("DOMContentLoaded", async () => await new App("@envelopeKey", @Html.Raw(envelopeReceiverJson), B64ToBuff("@Html.Raw(documentBase64String)"), "@ViewData["PSPDFKitLicenseKey"]", "@userCulture?.Info.TwoLetterISOLanguageName").init())
|
|
}
|
|
</script> |