Refined the logic for setting ViewData["Title"] in ShowEnvelope.cshtml. Now, if the envelope requires read and confirm, the title displays "Confirm Document" instead of just "Sign Document" or "View Document", providing clearer context for users.
237 lines
12 KiB
Plaintext
237 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;
|
|
|
|
ViewData["Title"] = isReadOnly
|
|
? _localizer.ViewDoc()
|
|
: envelope.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> @_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> |