configure for test case
This commit is contained in:
@@ -6,7 +6,6 @@ using EnvelopeGenerator.Domain.Constants;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Threading.Channels;
|
||||
|
||||
namespace EnvelopeGenerator.API.Controllers;
|
||||
|
||||
@@ -16,7 +15,6 @@ namespace EnvelopeGenerator.API.Controllers;
|
||||
/// <remarks>
|
||||
/// Initializes a new instance of the <see cref="DocumentController"/> class.
|
||||
/// </remarks>
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class DocumentController(IMediator mediator, IAuthorizationService authService, ILogger<DocumentController> logger) : ControllerBase, IAuthController
|
||||
@@ -70,20 +68,21 @@ public class DocumentController(IMediator mediator, IAuthorizationService authSe
|
||||
/// <param name="cancel"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{envelopeKey}")]
|
||||
[Authorize(Policy = AuthPolicy.Receiver)]
|
||||
public async Task<IActionResult> GetDocumentOfReceiver(string envelopeKey, CancellationToken cancel)
|
||||
{
|
||||
var envelopeIdStr = User.FindFirst(EnvelopeClaimNames.EnvelopeId)?.Value;
|
||||
var envelopeId = 2071;
|
||||
|
||||
if (!int.TryParse(envelopeIdStr, out int envelopeId))
|
||||
{
|
||||
logger.LogError(
|
||||
"Inner service error: Failed to parse Envelope ID from claims. Claim '{ClaimName}' had an invalid or missing value: '{ClaimValue}'.",
|
||||
EnvelopeClaimNames.EnvelopeId,
|
||||
envelopeIdStr ?? "null");
|
||||
//var envelopeIdStr = User.FindFirst(EnvelopeClaimNames.EnvelopeId)?.Value;
|
||||
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, "Inner service error: Invalid envelope claim.");
|
||||
}
|
||||
//if (!int.TryParse(envelopeIdStr, out int envelopeId))
|
||||
//{
|
||||
// logger.LogError(
|
||||
// "Inner service error: Failed to parse Envelope ID from claims. Claim '{ClaimName}' had an invalid or missing value: '{ClaimValue}'.",
|
||||
// EnvelopeClaimNames.EnvelopeId,
|
||||
// envelopeIdStr ?? "null");
|
||||
|
||||
// return StatusCode(StatusCodes.Status500InternalServerError, "Inner service error: Invalid envelope claim.");
|
||||
//}
|
||||
|
||||
var senderDoc = await mediator.Send(new ReadDocumentQuery() { EnvelopeId = envelopeId }, cancel);
|
||||
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DevExpress.Blazor.PdfViewer" Version="25.2.3" />
|
||||
<PackageReference Include="DevExpress.Blazor.Reporting.JSBasedControls" Version="25.2.3" />
|
||||
<PackageReference Include="DevExpress.Blazor.Reporting.Viewer" Version="25.2.3" />
|
||||
<PackageReference Include="DevExpress.Drawing.Skia" Version="25.2.3" />
|
||||
<PackageReference Include="HarfBuzzSharp.NativeAssets.WebAssembly" Version="8.3.1.2" />
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.WebAssembly" Version="3.119.1" />
|
||||
<PackageReference Include="SkiaSharp.Views.Blazor" Version="3.119.1" />
|
||||
@@ -32,10 +36,6 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.11" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.11" PrivateAssets="all" />
|
||||
<PackageReference Include="DevExpress.Drawing.Skia" Version="25.2.7" />
|
||||
<PackageReference Include="DevExpress.Blazor.PdfViewer" Version="25.2.7" />
|
||||
<PackageReference Include="DevExpress.Blazor.Reporting.JSBasedControls" Version="25.2.7" />
|
||||
<PackageReference Include="DevExpress.Blazor.Reporting.Viewer" Version="25.2.7" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\PublishProfiles\" />
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@page "/receiver"
|
||||
@page "/receiver/{EnvelopeKey}"
|
||||
@using System.Drawing
|
||||
@using DevExpress.Drawing
|
||||
@using DevExpress.Utils
|
||||
@@ -10,9 +11,11 @@
|
||||
@using XRPictureBox = DevExpress.XtraReports.UI.XRPictureBox
|
||||
@using XRControl = DevExpress.XtraReports.UI.XRControl
|
||||
@using ImageSizeMode = DevExpress.XtraPrinting.ImageSizeMode
|
||||
@using EnvelopeGenerator.ReceiverUI.Services;
|
||||
@using EnvelopeGenerator.ReceiverUI.Services
|
||||
@using DevExpress.Blazor.Reporting
|
||||
@inject IJSRuntime JSRuntime
|
||||
@inject InMemoryReportStorageWebExtension ReportStorage
|
||||
@inject EnvelopeGenerator.ReceiverUI.Services.DocumentService DocumentService
|
||||
|
||||
<link href="_content/DevExpress.Blazor.Themes/blazing-berry.bs5.min.css" rel="stylesheet" />
|
||||
<link href="_content/DevExpress.Blazor.Reporting.Viewer/css/dx-blazor-reporting-components.bs5.css" rel="stylesheet" />
|
||||
@@ -119,7 +122,9 @@
|
||||
</DxPopup>
|
||||
|
||||
<div class="receiver-viewer-wrapper">
|
||||
@if(Report is not null) {
|
||||
@if(!string.IsNullOrWhiteSpace(EnvelopeKey) && PdfBytes is { Length: > 0 }) {
|
||||
<DxPdfViewer @key="ViewerKey" CssClass="w-100 h-100" DocumentContent="PdfBytes" />
|
||||
} else if(Report is not null) {
|
||||
<DxReportViewer @key="ViewerKey" @ref="reportViewer" Report="Report" RootCssClasses="w-100 h-100" />
|
||||
}
|
||||
</div>
|
||||
@@ -127,6 +132,7 @@
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
const string SignatureTabDraw = "draw";
|
||||
const string SignatureTabText = "text";
|
||||
const string SignatureTabImage = "image";
|
||||
@@ -143,8 +149,13 @@
|
||||
("Cursive", "cursive")
|
||||
};
|
||||
|
||||
DxReportViewer reportViewer;
|
||||
[Parameter] public string? EnvelopeKey { get; set; }
|
||||
|
||||
DxReportViewer? reportViewer;
|
||||
XtraReport? Report;
|
||||
string PdfViewerUrl = string.Empty;
|
||||
byte[]? PdfBytes;
|
||||
byte[]? SignedPdfBytes;
|
||||
bool SignatureApplied;
|
||||
bool SignaturePopupVisible;
|
||||
string? SignatureValidationMessage;
|
||||
@@ -158,9 +169,35 @@
|
||||
int ViewerKey;
|
||||
|
||||
protected override async Task OnInitializedAsync() {
|
||||
Report = CreateReportInstance();
|
||||
|
||||
await Task.CompletedTask;
|
||||
EnvelopeKey = null; // Force report generation for testing. Remove this line to enable EnvelopeKey-based loading.
|
||||
if (!string.IsNullOrWhiteSpace(EnvelopeKey)) {
|
||||
(PdfBytes, _) = await DocumentService.GetDocumentAsync(EnvelopeKey);
|
||||
return;
|
||||
}
|
||||
|
||||
Report = CreateReportInstance();
|
||||
}
|
||||
|
||||
async Task<XtraReport?> BuildPdfReportAsync(string key) {
|
||||
Console.WriteLine("BuildPdfReportAsync is invoked..");
|
||||
var (pdfBytes, _) = await DocumentService.GetDocumentAsync(key);
|
||||
Console.WriteLine($"[BuildPdfReport] key={key}, pdfBytes={pdfBytes?.Length ?? 0}");
|
||||
|
||||
if (pdfBytes is not { Length: > 0 })
|
||||
return CreateReportInstance();
|
||||
|
||||
var report = new XtraReport();
|
||||
var detail = new DevExpress.XtraReports.UI.DetailBand();
|
||||
report.Bands.Add(detail);
|
||||
var pdfContent = new DevExpress.XtraReports.UI.XRPdfContent { Source = pdfBytes, GenerateOwnPages = true };
|
||||
detail.Controls.Add(pdfContent);
|
||||
Console.WriteLine($"[BuildPdfReport] XRPdfContent added, Source length={pdfContent.Source?.Length ?? 0}");
|
||||
|
||||
ReportStorage.SetData(report, key);
|
||||
var result = ReportStorage.TryGetReport(key, out var stored) ? stored : report;
|
||||
Console.WriteLine($"[BuildPdfReport] TryGetReport success={stored is not null}, bands={result?.Bands?.Count}");
|
||||
return result;
|
||||
}
|
||||
|
||||
async Task OpenSignaturePopupAsync() {
|
||||
@@ -244,10 +281,8 @@
|
||||
|
||||
PopupValidationMessage = null;
|
||||
SignatureValidationMessage = null;
|
||||
Report = CreateSignedReportInstance(signatureDataUrl, SignerFullName.Trim(), SignerPosition.Trim(), SignaturePlace.Trim());
|
||||
SignatureApplied = true;
|
||||
SignaturePopupVisible = false;
|
||||
ViewerKey++;
|
||||
}
|
||||
|
||||
async Task<string?> GetActiveSignatureDataUrlAsync() {
|
||||
@@ -263,13 +298,30 @@
|
||||
}
|
||||
|
||||
async Task ExportSignedPdfAsync() {
|
||||
if(!SignatureApplied || Report is null) {
|
||||
if(!SignatureApplied) {
|
||||
SignatureValidationMessage = "Bitte fuegen Sie die Unterschrift zuerst zum Bericht hinzu.";
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
SignatureValidationMessage = null;
|
||||
|
||||
var signatureDataUrl = await GetActiveSignatureDataUrlAsync();
|
||||
if(string.IsNullOrWhiteSpace(signatureDataUrl)) {
|
||||
SignatureValidationMessage = "Die Unterschrift konnte nicht gelesen werden.";
|
||||
return;
|
||||
}
|
||||
|
||||
var signedKey = $"{EnvelopeKey}_signed";
|
||||
var signedReport = new XtraReport();
|
||||
var detail = new DevExpress.XtraReports.UI.DetailBand();
|
||||
signedReport.Bands.Add(detail);
|
||||
detail.Controls.Add(new DevExpress.XtraReports.UI.XRPdfContent { Source = PdfBytes });
|
||||
ReportStorage.SetData(signedReport, signedKey);
|
||||
Report = ReportStorage.TryGetReport(signedKey, out var stored) ? stored : signedReport;
|
||||
ViewerKey++;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
await Task.Delay(300);
|
||||
await reportViewer.ExportToAsync(ExportFormat.Pdf);
|
||||
} catch(Exception) {
|
||||
SignatureValidationMessage = "Das signierte PDF konnte nicht exportiert werden. Bitte laden Sie die Seite neu und versuchen Sie es erneut.";
|
||||
@@ -283,7 +335,8 @@
|
||||
}
|
||||
|
||||
XtraReport CreateSignedReportInstance(string signatureDataUrl, string signerFullName, string signerPosition, string signaturePlace) {
|
||||
var report = CreateReportInstance();
|
||||
var baseReportName = string.IsNullOrWhiteSpace(EnvelopeKey) ? "LargeDatasetReport" : EnvelopeKey;
|
||||
var report = ReportStorage.TryGetReport(baseReportName, out var stored) ? stored : CreateReportInstance();
|
||||
AddSignature(report, signatureDataUrl, signerFullName, signerPosition, signaturePlace);
|
||||
return report;
|
||||
}
|
||||
@@ -358,3 +411,4 @@
|
||||
bottomMargin.Controls.Remove(control);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
81
EnvelopeGenerator.ReceiverUI/Pages/TestViewer.razor
Normal file
81
EnvelopeGenerator.ReceiverUI/Pages/TestViewer.razor
Normal file
@@ -0,0 +1,81 @@
|
||||
@page "/test"
|
||||
@using System.Drawing
|
||||
@using DevExpress.Drawing
|
||||
@using DevExpress.Utils
|
||||
@using DevExpress.XtraPrinting
|
||||
@using DevExpress.XtraPrinting.Drawing
|
||||
@using XtraReport = DevExpress.XtraReports.UI.XtraReport
|
||||
@using BottomMarginBand = DevExpress.XtraReports.UI.BottomMarginBand
|
||||
@using XRLabel = DevExpress.XtraReports.UI.XRLabel
|
||||
@using XRPictureBox = DevExpress.XtraReports.UI.XRPictureBox
|
||||
@using XRControl = DevExpress.XtraReports.UI.XRControl
|
||||
@using ImageSizeMode = DevExpress.XtraPrinting.ImageSizeMode
|
||||
@using EnvelopeGenerator.ReceiverUI.Services
|
||||
@using DevExpress.Blazor.Reporting
|
||||
@inject IJSRuntime JSRuntime
|
||||
@inject InMemoryReportStorageWebExtension ReportStorage
|
||||
@inject EnvelopeGenerator.ReceiverUI.Services.DocumentService DocumentService
|
||||
@inject Microsoft.Extensions.Configuration.IConfiguration Configuration
|
||||
@inject HttpClient Http
|
||||
@using System;
|
||||
|
||||
<link href="_content/DevExpress.Blazor.Themes/blazing-berry.bs5.min.css" rel="stylesheet" />
|
||||
<link href="_content/DevExpress.Blazor.Reporting.Viewer/css/dx-blazor-reporting-components.bs5.css" rel="stylesheet" />
|
||||
|
||||
<div class="receiver-page-layout">
|
||||
|
||||
<div class="receiver-viewer-wrapper">
|
||||
<embed class="w-100 h-50" src="/docs/Document.pdf" type="application/pdf" />
|
||||
@if (PdfBytes is { Length: > 0 }) {
|
||||
<DxPdfViewer DocumentContent="PdfBytes" CssClass="w-100 h-50" />
|
||||
}
|
||||
else{
|
||||
<div>Not found</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
const string SignatureTabDraw = "draw";
|
||||
const string SignatureTabText = "text";
|
||||
const string SignatureTabImage = "image";
|
||||
const string DrawCanvasId = "receiver-signature-pad";
|
||||
const string TypedCanvasId = "receiver-typed-signature-pad";
|
||||
const string ImageInputId = "receiver-signature-image-input";
|
||||
const string ImageCanvasId = "receiver-image-signature-pad";
|
||||
|
||||
readonly (string Text, string Value)[] TypedSignatureFonts = {
|
||||
("Brush Script", "'Brush Script MT', cursive"),
|
||||
("Segoe Script", "'Segoe Script', cursive"),
|
||||
("Lucida Handwriting", "'Lucida Handwriting', cursive"),
|
||||
("Comic Sans", "'Comic Sans MS', cursive"),
|
||||
("Cursive", "cursive")
|
||||
};
|
||||
|
||||
[Parameter] public string? EnvelopeKey { get; set; }
|
||||
|
||||
DxReportViewer? reportViewer;
|
||||
XtraReport? Report;
|
||||
string PdfViewerUrl = string.Empty;
|
||||
byte[]? PdfBytes;
|
||||
byte[]? SignedPdfBytes;
|
||||
bool SignatureApplied;
|
||||
bool SignaturePopupVisible;
|
||||
string? PopupValidationMessage;
|
||||
string ActiveSignatureTab = SignatureTabDraw;
|
||||
string TypedSignatureText = string.Empty;
|
||||
string TypedSignatureFont = "'Brush Script MT', cursive";
|
||||
string SignerFullName = string.Empty;
|
||||
string SignerPosition = string.Empty;
|
||||
string SignaturePlace = string.Empty;
|
||||
int ViewerKey;
|
||||
|
||||
protected override async Task OnInitializedAsync() {
|
||||
PdfBytes = await Http.GetByteArrayAsync("/docs/Document.pdf");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
BIN
EnvelopeGenerator.ReceiverUI/wwwroot/docs/Document.pdf
Normal file
BIN
EnvelopeGenerator.ReceiverUI/wwwroot/docs/Document.pdf
Normal file
Binary file not shown.
@@ -35,10 +35,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.Tests", "
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.API", "EnvelopeGenerator.API\EnvelopeGenerator.API.csproj", "{EC768913-6270-14F4-1DD3-69C87A659462}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.ReceiverUI", "EnvelopeGenerator.ReceiverUI\EnvelopeGenerator.ReceiverUI.csproj", "{FB2D306B-1042-4A70-31ED-F991A1599371}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.DependencyInjection", "EnvelopeGenerator.DependencyInjection\EnvelopeGenerator.DependencyInjection.csproj", "{5DCCF9A1-C03F-90E6-87D3-E96DB25250C2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.ReceiverUI", "EnvelopeGenerator.ReceiverUI\EnvelopeGenerator.ReceiverUI.csproj", "{FB2D306B-1042-4A70-31ED-F991A1599371}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -89,14 +89,14 @@ Global
|
||||
{EC768913-6270-14F4-1DD3-69C87A659462}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EC768913-6270-14F4-1DD3-69C87A659462}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EC768913-6270-14F4-1DD3-69C87A659462}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FB2D306B-1042-4A70-31ED-F991A1599371}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FB2D306B-1042-4A70-31ED-F991A1599371}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FB2D306B-1042-4A70-31ED-F991A1599371}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FB2D306B-1042-4A70-31ED-F991A1599371}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5DCCF9A1-C03F-90E6-87D3-E96DB25250C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5DCCF9A1-C03F-90E6-87D3-E96DB25250C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5DCCF9A1-C03F-90E6-87D3-E96DB25250C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5DCCF9A1-C03F-90E6-87D3-E96DB25250C2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FB2D306B-1042-4A70-31ED-F991A1599371}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FB2D306B-1042-4A70-31ED-F991A1599371}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FB2D306B-1042-4A70-31ED-F991A1599371}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FB2D306B-1042-4A70-31ED-F991A1599371}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -116,8 +116,8 @@ Global
|
||||
{211619F5-AE25-4BA5-A552-BACAFE0632D3} = {9943209E-1744-4944-B1BA-4F87FC1A0EEB}
|
||||
{224C4845-1CDE-22B7-F3A9-1FF9297F70E8} = {0CBC2432-A561-4440-89BC-671B66A24146}
|
||||
{EC768913-6270-14F4-1DD3-69C87A659462} = {E3C758DC-914D-4B7E-8457-0813F1FDB0CB}
|
||||
{FB2D306B-1042-4A70-31ED-F991A1599371} = {E3C758DC-914D-4B7E-8457-0813F1FDB0CB}
|
||||
{5DCCF9A1-C03F-90E6-87D3-E96DB25250C2} = {E3C758DC-914D-4B7E-8457-0813F1FDB0CB}
|
||||
{FB2D306B-1042-4A70-31ED-F991A1599371} = {E3C758DC-914D-4B7E-8457-0813F1FDB0CB}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {73E60370-756D-45AD-A19A-C40A02DACCC7}
|
||||
|
||||
Reference in New Issue
Block a user