diff --git a/src/Application/Features/Documents/DTOs/DocumentDto.cs b/src/Application/Features/Documents/DTOs/DocumentDto.cs index e824b918..cade49c5 100644 --- a/src/Application/Features/Documents/DTOs/DocumentDto.cs +++ b/src/Application/Features/Documents/DTOs/DocumentDto.cs @@ -6,7 +6,7 @@ namespace Cfo.Cats.Application.Features.Documents.DTOs; [Description("Documents")] public class DocumentDto { - [Description("Id")] public int Id { get; set; } + [Description("Id")] public Guid? Id { get; set; } [Description("Title")] public string? Title { get; set; } @@ -23,6 +23,8 @@ public class DocumentDto [Description("Tenant Name")] public string? TenantName { get; set; } [Description("Content")] public string? Content { get; set; } + [Description("Created By")] public string CreatedBy { get; set; } = string.Empty; + [Description("Created Date")] public DateTime Created { get; set; } [Description("Owner")] public ApplicationUserDto? Owner { get; set; } diff --git a/src/Application/Features/Documents/Queries/GetByParticipantId.cs b/src/Application/Features/Documents/Queries/GetByParticipantId.cs new file mode 100644 index 00000000..cf2b1005 --- /dev/null +++ b/src/Application/Features/Documents/Queries/GetByParticipantId.cs @@ -0,0 +1,47 @@ +using Cfo.Cats.Application.Common.Security; +using Cfo.Cats.Application.Common.Validators; +using Cfo.Cats.Application.Features.Documents.DTOs; +using Cfo.Cats.Application.Features.Participants.DTOs; +using Cfo.Cats.Application.SecurityConstants; +using DocumentFormat.OpenXml.InkML; +using System.Threading.Tasks; + +namespace Cfo.Cats.Application.Features.Documents.Queries; +public static class GetByParticipantId +{ + [RequestAuthorize(Policy = SecurityPolicies.AuthorizedUser)] + + public class Query : IRequest> + { + public required string ParticipantId { get; set; } + } + + public class Handler(IUnitOfWork unitOfWork, IMapper mapper) : IRequestHandler> + { + public async Task> Handle(Query request, CancellationToken cancellationToken) + { + string likeCriteria = string.Format(@"Files/{0}%", request.ParticipantId); + var query = unitOfWork.DbContext.Documents + .Where(d => EF.Functions.Like(d.URL, likeCriteria)); + + var documents = await query.ProjectTo(mapper.ConfigurationProvider) + .ToArrayAsync(cancellationToken) ?? []; + + return Result.Success(documents); + } + } + public class Validator : AbstractValidator + { + public Validator() + { + RuleFor(x => x.ParticipantId.ToString()) + .NotEmpty() + .MinimumLength(9) + .MaximumLength(9) + .Matches(ValidationConstants.AlphaNumeric) + .WithMessage(string.Format(ValidationConstants.AlphaNumericMessage, "Participant Id")); + + } + } +} + diff --git a/src/Server.UI/Pages/Participants/Components/CaseDocuments.razor b/src/Server.UI/Pages/Participants/Components/CaseDocuments.razor new file mode 100644 index 00000000..2686e150 --- /dev/null +++ b/src/Server.UI/Pages/Participants/Components/CaseDocuments.razor @@ -0,0 +1,102 @@ +@using Cfo.Cats.Application.Common.Interfaces.Identity +@using Cfo.Cats.Server.UI.Pages.Participants.Components +@using Cfo.Cats.Application.Features.Participants.DTOs +@using Cfo.Cats.Application.Features.Documents.DTOs +@using Cfo.Cats.Application.Features.Participants.Queries +@using Cfo.Cats.Application.Features.Documents.Queries +@using Cfo.Cats.Application.SecurityConstants +@using System.Net.Http.Json + +@inherits CatsComponentBase + +@inject IUserService UserService +@inject IStringLocalizer L + + +@attribute [Authorize(Policy = SecurityPolicies.AuthorizedUser)] + + + +@if (_notFound) +{ + + No documents yet. + +} +else +{ + + + + + + + + + + Open + + + + +} + +@code { + bool _loading = true; + bool _notFound = false; + private DocumentDto[] _documents = []; + private DocumentDto _currentDto = new() { Id = Guid.Empty }; + + [Parameter] + [EditorRequired] + public string ParticipantId { get; set; } = default!; + + [CascadingParameter] + public UserProfile? UserProfile { get; set; } = null!; + + protected Guid SelectedDocument { get; set; } = Guid.Empty; + + + protected override async Task OnInitializedAsync() + { + try + { + if (String.IsNullOrWhiteSpace(ParticipantId) == false) + { + _documents = await GetNewMediator().Send(new GetByParticipantId.Query() + { + ParticipantId = ParticipantId + }); + _notFound = _documents.Count() == 0; + } + }finally{ + _loading = false; + } + } + + public async Task OpenDocumentDialog(DocumentDto item) + { + await DialogService.ShowAsync( + "View Document Dialog", + new DialogParameters() + { + { x => x.Model, item } + }, + new DialogOptions + { + MaxWidth = MaxWidth.ExtraExtraLarge, + Position=DialogPosition.Center, + FullWidth = true, + CloseButton = true + }); + } +} \ No newline at end of file diff --git a/src/Server.UI/Pages/Participants/Components/ViewDocumentDialog.razor b/src/Server.UI/Pages/Participants/Components/ViewDocumentDialog.razor new file mode 100644 index 00000000..8462547c --- /dev/null +++ b/src/Server.UI/Pages/Participants/Components/ViewDocumentDialog.razor @@ -0,0 +1,86 @@ +@using Cfo.Cats.Application.Common.Interfaces.Identity +@using Cfo.Cats.Server.UI.Pages.Participants.Components +@using Cfo.Cats.Application.Features.Participants.DTOs +@using Cfo.Cats.Application.Features.Documents.DTOs +@using Cfo.Cats.Application.Features.Participants.Queries +@using Cfo.Cats.Application.Features.Documents.Queries +@using Cfo.Cats.Application.SecurityConstants +@inherits CatsComponentBase + +@inject IValidationService Validator + + + + + + @if (Model is not null) + { + @if (fileBase64 != null && extension!.Equals("pdf", StringComparison.CurrentCultureIgnoreCase)) + { + +

PDF cannot be displayed.

+
+ } + else if (IsFileRejected) + { + + File cannot be displayed. Please contact support. + + } + else + { + + } + } +
+ + @ConstantString.Close + +
+ +@code { + [CascadingParameter] private MudDialogInstance MudDialog { get; set; } = default!; + + [Parameter, EditorRequired] + public required DocumentDto Model { get; set; } + private bool IsFileRejected { get; set; } + private string? fileBase64; + private string? extension; + private void Cancel() + { + MudDialog.Cancel(); + } + protected override async Task OnInitializedAsync() + { + Guid documentId = Model.Id!.Value; + if (documentId != Guid.Empty) + { + var query = new GetDocumentById.Query() + { + Id = documentId + }; + + var result = await GetNewMediator().Send(query); + if (result.Succeeded) + { + IsFileRejected = false; + using (var memoryStream = new MemoryStream()) + { + await result.Data!.FileStream.CopyToAsync(memoryStream); + var bytes = memoryStream.ToArray(); + fileBase64 = Convert.ToBase64String(bytes); + } + extension = result.Data!.FileExtension; + } + else + { + IsFileRejected = true; + } + } + } +} diff --git a/src/Server.UI/Pages/Participants/Participant.razor b/src/Server.UI/Pages/Participants/Participant.razor index de16f593..963b1084 100644 --- a/src/Server.UI/Pages/Participants/Participant.razor +++ b/src/Server.UI/Pages/Participants/Participant.razor @@ -107,6 +107,9 @@ + + +