diff --git a/EnvelopeGenerator.Application/Envelopes/Queries/ReadEnvelopeQuery.cs b/EnvelopeGenerator.Application/Envelopes/Queries/ReadEnvelopeQuery.cs index 8af36db6..a814a3e0 100644 --- a/EnvelopeGenerator.Application/Envelopes/Queries/ReadEnvelopeQuery.cs +++ b/EnvelopeGenerator.Application/Envelopes/Queries/ReadEnvelopeQuery.cs @@ -150,8 +150,9 @@ public class ReadEnvelopeQueryHandler : IRequestHandler e.EnvelopeReceivers).ThenInclude(er => er.Receiver) + .Include(e => e.Histories) .ToListAsync(cancel); return _mapper.Map>(envelopes); } -} \ No newline at end of file +} diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderPage.razor b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderPage.razor index e2f9feb9..0f968fdd 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderPage.razor +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderPage.razor @@ -7,7 +7,9 @@ @using DevExpress.Blazor.PdfViewer @using EnvelopeGenerator.Server.Client.Services @using EnvelopeGenerator.Application.Common.Dto +@using EnvelopeGenerator.Application.Common.Dto.History @using EnvelopeGenerator.Server.Services +@using Microsoft.Extensions.Localization @inject EnvelopeGenerator.Server.Client.Services.EnvelopeService EnvelopeService @inject EnvelopeGenerator.Server.Client.Services.AuthService AuthService @inject EnvelopeGenerator.Server.Client.Services.ThemeService ThemeService @@ -19,6 +21,7 @@ @inject NavigationManager Navigation @inject IJSRuntime JSRuntime @inject AppVersionService AppVersion +@inject IStringLocalizer ModelLocalizer @@ -329,6 +332,38 @@

Keine Empfänger

} } + +
Historie
+ @{ + var historyEntries = envelope is null + ? Enumerable.Empty() + : GetOrderedHistories(envelope); + if (historyEntries.Any()) + { +
+ @foreach (var history in historyEntries) + { + var statusInfo = GetStatusInfo(history.Status); +
+
+
+ + @statusInfo.Label +
+ @GetHistoryActor(history) +
+
+ @GetHistoryDate(history).ToString("dd.MM.yyyy HH:mm") +
+
+ } +
+ } + else + { +

Keine Historie vorhanden

+ } + } @@ -451,6 +486,38 @@

Keine Empfänger

} } + +
Historie
+ @{ + var historyEntries = envelope is null + ? Enumerable.Empty() + : GetOrderedHistories(envelope); + if (historyEntries.Any()) + { +
+ @foreach (var history in historyEntries) + { + var statusInfo = GetStatusInfo(history.Status); +
+
+
+ + @statusInfo.Label +
+ @GetHistoryActor(history) +
+
+ @GetHistoryDate(history).ToString("dd.MM.yyyy HH:mm") +
+
+ } +
+ } + else + { +

Keine Historie vorhanden

+ } + } @@ -806,21 +873,59 @@ (string Label, string CssClass, string DotColor) GetStatusInfo(EnvelopeStatus status) { + var label = GetStatusLabel(status); + return status switch { - EnvelopeStatus.EnvelopePartlySigned => ("Teilweise unterschrieben", "partly-signed", "green"), - EnvelopeStatus.EnvelopeQueued => ("In Warteschlange", "queued", "orange"), - EnvelopeStatus.EnvelopeSent => ("Gesendet", "sent", "orange"), - EnvelopeStatus.EnvelopeCompletelySigned => ("Vollständig unterschrieben", "completed", "green"), - EnvelopeStatus.EnvelopeDeleted => ("Gelöscht", "deleted", "red"), - EnvelopeStatus.EnvelopeRejected => ("Abgelehnt", "rejected", "red"), - EnvelopeStatus.EnvelopeWithdrawn => ("Zurückgezogen", "withdrawn", "red"), - EnvelopeStatus.EnvelopeCreated => ("Erstellt", "created", "blue"), - EnvelopeStatus.EnvelopeSaved => ("Gespeichert", "saved", "blue"), - _ => ("Unbekannt", "unknown", "blue") + EnvelopeStatus.EnvelopePartlySigned => (label, "partly-signed", "green"), + EnvelopeStatus.EnvelopeCompletelySigned => (label, "completed", "green"), + EnvelopeStatus.DocumentSigned => (label, "partly-signed", "green"), + EnvelopeStatus.MessageCompletionSent => (label, "completed", "green"), + + EnvelopeStatus.EnvelopeQueued => (label, "queued", "orange"), + EnvelopeStatus.EnvelopeSent => (label, "sent", "orange"), + EnvelopeStatus.MessageInvitationSent => (label, "queued", "orange"), + EnvelopeStatus.MessageAccessCodeSent => (label, "queued", "orange"), + EnvelopeStatus.MessageConfirmationSent => (label, "queued", "orange"), + + EnvelopeStatus.EnvelopeDeleted => (label, "deleted", "red"), + EnvelopeStatus.EnvelopeRejected => (label, "rejected", "red"), + EnvelopeStatus.EnvelopeWithdrawn => (label, "withdrawn", "red"), + EnvelopeStatus.DocumentRejected => (label, "rejected", "red"), + EnvelopeStatus.AccessCodeIncorrect => (label, "rejected", "red"), + EnvelopeStatus.MessageDeletionSent => (label, "deleted", "red"), + + _ => (label, "created", "blue") }; } + string GetStatusLabel(EnvelopeStatus status) + { + var key = status.ToString(); + var localized = ModelLocalizer[key]; + return localized.ResourceNotFound ? key : localized.Value; + } + + IEnumerable GetOrderedHistories(EnvelopeDto envelope) + { + return (envelope.Histories ?? Enumerable.Empty()) + .OrderByDescending(GetHistoryDate) + .Take(20); + } + + DateTime GetHistoryDate(HistoryDto history) + { + return history.ActionDate ?? history.AddedWhen; + } + + string GetHistoryActor(HistoryDto history) + { + if (!string.IsNullOrWhiteSpace(history.UserReference)) + return history.UserReference; + + return "System"; + } + void OnCustomizeElement(GridCustomizeElementEventArgs e) { // Future: Add custom row coloring based on status if needed diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/wwwroot/css/sender-page.css b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/wwwroot/css/sender-page.css index bb3d5084..e727bd23 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/wwwroot/css/sender-page.css +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/wwwroot/css/sender-page.css @@ -381,6 +381,44 @@ color: #c62828; } +.sender-history-list { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.sender-history-item { + display: flex; + justify-content: space-between; + align-items: center; + gap: 0.75rem; + padding: 0.5rem; + background: white; + border-radius: 6px; + border: 1px solid #e5e7eb; +} + +.sender-history-item__left { + display: flex; + align-items: center; + gap: 0.5rem; + min-width: 0; +} + +.sender-history-item__actor { + color: #4b5563; + font-size: 0.8rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.sender-history-item__right { + color: #6b7280; + font-size: 0.8rem; + white-space: nowrap; +} + @media (max-width: 1320px) { .sender-action-bar__inner { flex-wrap: wrap;