diff --git a/EnvelopeGenerator.Application/Contracts/IConfigService.cs b/EnvelopeGenerator.Application/Contracts/IConfigService.cs index d53f0bdd..80702fac 100644 --- a/EnvelopeGenerator.Application/Contracts/IConfigService.cs +++ b/EnvelopeGenerator.Application/Contracts/IConfigService.cs @@ -5,7 +5,7 @@ using EnvelopeGenerator.Domain.Entities; namespace EnvelopeGenerator.Application.Contracts { - public interface IConfigService : IBasicCRUDService + public interface IConfigService : IReadService { Task> ReadFirstAsync(); diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs index d6c5e671..b72bdec2 100644 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs +++ b/EnvelopeGenerator.Application/Contracts/IEnvelopeHistoryService.cs @@ -3,7 +3,6 @@ using DigitalData.Core.DTO; using EnvelopeGenerator.Application.DTOs.EnvelopeHistory; using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; using static EnvelopeGenerator.Common.Constants; namespace EnvelopeGenerator.Application.Contracts diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeMailService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeMailService.cs index f4b00369..f57967f2 100644 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeMailService.cs +++ b/EnvelopeGenerator.Application/Contracts/IEnvelopeMailService.cs @@ -1,6 +1,6 @@ using DigitalData.Core.DTO; using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts; -using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Common; namespace EnvelopeGenerator.Application.Contracts diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeReceiverService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeReceiverService.cs index 6403d207..75a897a2 100644 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeReceiverService.cs +++ b/EnvelopeGenerator.Application/Contracts/IEnvelopeReceiverService.cs @@ -1,15 +1,18 @@ using DigitalData.Core.Abstractions.Application; using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; +using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Domain.Entities; namespace EnvelopeGenerator.Application.Contracts { - public interface IEnvelopeReceiverService : IBasicCRUDService + public interface IEnvelopeReceiverService : IBasicCRUDService { Task>> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false); + Task>> ReadSecretByUuidAsync(string uuid, bool withEnvelope = false, bool withReceiver = true); + Task>> ReadBySignatureAsync(string signature, bool withEnvelope = false, bool withReceiver = true); Task> ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true); @@ -25,5 +28,7 @@ namespace EnvelopeGenerator.Application.Contracts Task> IsExisting(string envelopeReceiverId); Task>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses); + + Task> ReadLastUsedReceiverNameByMail(string mail); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IEnvelopeService.cs b/EnvelopeGenerator.Application/Contracts/IEnvelopeService.cs index 4a01e53d..a8cfbab1 100644 --- a/EnvelopeGenerator.Application/Contracts/IEnvelopeService.cs +++ b/EnvelopeGenerator.Application/Contracts/IEnvelopeService.cs @@ -2,7 +2,6 @@ using DigitalData.Core.DTO; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; namespace EnvelopeGenerator.Application.Contracts { @@ -11,5 +10,7 @@ namespace EnvelopeGenerator.Application.Contracts Task>> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false); Task> ReadByUuidAsync(string uuid, bool withDocuments = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withUser = false, bool withAll = false); + + Task>> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[]ignore_statuses); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Contracts/IUserReceiverService.cs b/EnvelopeGenerator.Application/Contracts/IUserReceiverService.cs index 17ae83c8..9c6f19fa 100644 --- a/EnvelopeGenerator.Application/Contracts/IUserReceiverService.cs +++ b/EnvelopeGenerator.Application/Contracts/IUserReceiverService.cs @@ -1,7 +1,6 @@ using DigitalData.Core.Abstractions.Application; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; -using EnvelopeGenerator.Infrastructure.Contracts; namespace EnvelopeGenerator.Application.Contracts { diff --git a/EnvelopeGenerator.Application/DTOs/ConfigDto.cs b/EnvelopeGenerator.Application/DTOs/ConfigDto.cs index 751ab329..f96f131d 100644 --- a/EnvelopeGenerator.Application/DTOs/ConfigDto.cs +++ b/EnvelopeGenerator.Application/DTOs/ConfigDto.cs @@ -1,4 +1,7 @@ -namespace EnvelopeGenerator.Application.DTOs +using DigitalData.Core.Abstractions; +using System.Text.Json.Serialization; + +namespace EnvelopeGenerator.Application.DTOs { public record ConfigDto( string DocumentPath, @@ -8,5 +11,10 @@ string ExportPath, string DocumentPathDmz, string ExportPathDmz, - string DocumentPathMoveAftsend); + string DocumentPathMoveAftsend) : IUnique + { + [JsonIgnore] + [Obsolete("Configuration does not have an ID; it represents a single table in the database.")] + public int Id => throw new InvalidOperationException("This configuration does not support an ID as it represents a single row in the database."); + }; } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/DocumentReceiverElementDto.cs b/EnvelopeGenerator.Application/DTOs/DocumentReceiverElementDto.cs index 6e109e68..aff23a33 100644 --- a/EnvelopeGenerator.Application/DTOs/DocumentReceiverElementDto.cs +++ b/EnvelopeGenerator.Application/DTOs/DocumentReceiverElementDto.cs @@ -1,4 +1,6 @@ -namespace EnvelopeGenerator.Application.DTOs +using DigitalData.Core.Abstractions; + +namespace EnvelopeGenerator.Application.DTOs { public record DocumentReceiverElementDto( int Id, @@ -18,5 +20,5 @@ DateTime? ChangedWhen, double Top, double Left - ); + ): IUnique; } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/DocumentStatusDto.cs b/EnvelopeGenerator.Application/DTOs/DocumentStatusDto.cs index 4037c064..2decac1f 100644 --- a/EnvelopeGenerator.Application/DTOs/DocumentStatusDto.cs +++ b/EnvelopeGenerator.Application/DTOs/DocumentStatusDto.cs @@ -1,4 +1,6 @@ -namespace EnvelopeGenerator.Application.DTOs +using DigitalData.Core.Abstractions; + +namespace EnvelopeGenerator.Application.DTOs { public record DocumentStatusDto( int Id, @@ -8,5 +10,5 @@ DateTime? StatusChangedWhen, string Value, DateTime AddedWhen, - DateTime? ChangedWhen); + DateTime? ChangedWhen) : IUnique; } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EmailTemplateDto.cs b/EnvelopeGenerator.Application/DTOs/EmailTemplateDto.cs index 5ec688ab..8eaa798f 100644 --- a/EnvelopeGenerator.Application/DTOs/EmailTemplateDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EmailTemplateDto.cs @@ -1,8 +1,10 @@ -namespace EnvelopeGenerator.Application.DTOs +using DigitalData.Core.Abstractions; + +namespace EnvelopeGenerator.Application.DTOs { public record EmailTemplateDto( int Id, string Name, string Body, - string Subject); + string Subject) : IUnique; } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeCertificateDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeCertificateDto.cs index 44547d1e..34d38990 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeCertificateDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeCertificateDto.cs @@ -1,4 +1,6 @@ -namespace EnvelopeGenerator.Application.DTOs +using DigitalData.Core.Abstractions; + +namespace EnvelopeGenerator.Application.DTOs { public record EnvelopeCertificateDto( int Id, @@ -8,5 +10,5 @@ int CreatorId, string CreatorName, string CreatorEmail, - int EnvelopeStatus); + int EnvelopeStatus) : IUnique; } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeDocumentDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeDocumentDto.cs index caa9c335..340b3a88 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeDocumentDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeDocumentDto.cs @@ -1,4 +1,6 @@ -namespace EnvelopeGenerator.Application.DTOs +using DigitalData.Core.Abstractions; + +namespace EnvelopeGenerator.Application.DTOs { public record EnvelopeDocumentDto ( @@ -6,5 +8,5 @@ int EnvelopeId, DateTime AddedWhen, IEnumerable? Elements - ); + ) : IUnique; } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs index 0413453a..02db9593 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeDto.cs @@ -1,10 +1,11 @@ -using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes; +using DigitalData.Core.Abstractions; +using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes; using DigitalData.UserManager.Application.DTOs.User; using EnvelopeGenerator.Domain.Entities; namespace EnvelopeGenerator.Application.DTOs { - public record EnvelopeDto() + public record EnvelopeDto() : IUnique { public int Id { get; set; } diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeHistory/EnvelopeHistoryDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeHistory/EnvelopeHistoryDto.cs index 7967ac3c..0de3f3fb 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeHistory/EnvelopeHistoryDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeHistory/EnvelopeHistoryDto.cs @@ -1,4 +1,5 @@ -using DigitalData.Core.DTO; +using DigitalData.Core.Abstractions; +using DigitalData.Core.DTO; using DigitalData.UserManager.Application.DTOs.User; using EnvelopeGenerator.Application.DTOs.Receiver; using static EnvelopeGenerator.Common.Constants; @@ -10,10 +11,11 @@ namespace EnvelopeGenerator.Application.DTOs.EnvelopeHistory int EnvelopeId, string UserReference, int Status, + string? StatusName, DateTime AddedWhen, DateTime? ActionDate, UserCreateDto? Sender, ReceiverReadDto? Receiver, ReferenceType ReferenceType, - string? Comment = null) : BaseDTO(Id); + string? Comment = null) : BaseDTO(Id), IUnique; } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverBasicDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverBasicDto.cs new file mode 100644 index 00000000..4dfdf6a8 --- /dev/null +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverBasicDto.cs @@ -0,0 +1,29 @@ +using DigitalData.Core.Abstractions; +using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes; + +namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver +{ + public record EnvelopeReceiverBasicDto() : IUnique<(int Envelope, int Receiver)> + { + public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId); + + public int EnvelopeId { get; init; } + + public int ReceiverId { get; init; } + + public int Sequence { get; init; } + + [TemplatePlaceholder("[NAME_RECEIVER]")] + public string? Name { get; init; } + + public string? JobTitle { get; init; } + + public string? CompanyName { get; init; } + + public string? PrivateMessage { get; init; } + + public DateTime AddedWhen { get; init; } + + public DateTime? ChangedWhen { get; init; } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverDto.cs new file mode 100644 index 00000000..49625eee --- /dev/null +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverDto.cs @@ -0,0 +1,11 @@ +using EnvelopeGenerator.Application.DTOs.Receiver; + +namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver +{ + public record EnvelopeReceiverDto() : EnvelopeReceiverBasicDto() + { + public EnvelopeDto? Envelope { get; set; } + + public ReceiverReadDto? Receiver { get; set; } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverSecretDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverSecretDto.cs new file mode 100644 index 00000000..511c6d42 --- /dev/null +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiver/EnvelopeReceiverSecretDto.cs @@ -0,0 +1,4 @@ +namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiver +{ + public record EnvelopeReceiverSecretDto(string? AccessCode) : EnvelopeReceiverDto; +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverDto.cs deleted file mode 100644 index e2fbcdca..00000000 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeReceiverDto.cs +++ /dev/null @@ -1,31 +0,0 @@ -using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes; -using EnvelopeGenerator.Application.DTOs.Receiver; - -namespace EnvelopeGenerator.Application.DTOs -{ - public record EnvelopeReceiverDto() - { - public int EnvelopeId { get; set; } - - public int ReceiverId { get; set; } - - public int Sequence { get; set; } - - [TemplatePlaceholder("[NAME_RECEIVER]")] - public string? Name { get; set; } - - public string? JobTitle { get; set; } - - public string? CompanyName { get; set; } - - public string? PrivateMessage { get; set; } - - public DateTime AddedWhen { get; set; } - - public DateTime? ChangedWhen { get; set; } - - public EnvelopeDto? Envelope { get; set; } - - public ReceiverReadDto? Receiver { get; set; } - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/EnvelopeTypeDto.cs b/EnvelopeGenerator.Application/DTOs/EnvelopeTypeDto.cs index 2342784d..f7f55ac3 100644 --- a/EnvelopeGenerator.Application/DTOs/EnvelopeTypeDto.cs +++ b/EnvelopeGenerator.Application/DTOs/EnvelopeTypeDto.cs @@ -1,4 +1,6 @@ -namespace EnvelopeGenerator.Application.DTOs +using DigitalData.Core.Abstractions; + +namespace EnvelopeGenerator.Application.DTOs { public record EnvelopeTypeDto( int Id, @@ -15,5 +17,5 @@ bool? SendReminderEmails, int? FirstReminderDays, int? ReminderIntervalDays, - int? ContractType); + int? ContractType) : IUnique; } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverReadDto.cs b/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverReadDto.cs index 4c5d5c69..ec6e5b76 100644 --- a/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverReadDto.cs +++ b/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverReadDto.cs @@ -1,4 +1,6 @@ using DigitalData.Core.DTO; +using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; +using System.Text.Json.Serialization; namespace EnvelopeGenerator.Application.DTOs.Receiver { @@ -6,6 +8,12 @@ namespace EnvelopeGenerator.Application.DTOs.Receiver int Id, string EmailAddress, string Signature, - DateTime AddedWhen - ) : BaseDTO(Id); + DateTime AddedWhen + ) : BaseDTO(Id) + { + [JsonIgnore] + public IEnumerable? EnvelopeReceivers { get; init; } + + public string? LastUsedName => EnvelopeReceivers?.LastOrDefault()?.Name; + }; } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverUpdateDto.cs b/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverUpdateDto.cs index a6818b3a..8f765667 100644 --- a/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverUpdateDto.cs +++ b/EnvelopeGenerator.Application/DTOs/Receiver/ReceiverUpdateDto.cs @@ -1,4 +1,6 @@ -namespace EnvelopeGenerator.Application.DTOs.Receiver +using DigitalData.Core.Abstractions; + +namespace EnvelopeGenerator.Application.DTOs.Receiver { - public record ReceiverUpdateDto(); + public record ReceiverUpdateDto(int Id) : IUnique; } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/DTOs/UserReceiverDto.cs b/EnvelopeGenerator.Application/DTOs/UserReceiverDto.cs index 8c80ecd8..8630838a 100644 --- a/EnvelopeGenerator.Application/DTOs/UserReceiverDto.cs +++ b/EnvelopeGenerator.Application/DTOs/UserReceiverDto.cs @@ -1,4 +1,6 @@ -namespace EnvelopeGenerator.Application.DTOs +using DigitalData.Core.Abstractions; + +namespace EnvelopeGenerator.Application.DTOs { public record UserReceiverDto( int Id, @@ -7,5 +9,5 @@ string Name, string CompanyName, string JobTitle, - DateTime AddedWhen); + DateTime AddedWhen) : IUnique; } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj b/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj index 1704c760..5ca8bdf4 100644 --- a/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj +++ b/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj @@ -12,13 +12,13 @@ - - - - + + + + - - + + diff --git a/EnvelopeGenerator.Application/MappingProfiles/BasicDtoMappingProfile.cs b/EnvelopeGenerator.Application/MappingProfiles/BasicDtoMappingProfile.cs index df3637da..820ddbc1 100644 --- a/EnvelopeGenerator.Application/MappingProfiles/BasicDtoMappingProfile.cs +++ b/EnvelopeGenerator.Application/MappingProfiles/BasicDtoMappingProfile.cs @@ -1,6 +1,7 @@ using AutoMapper; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application.DTOs.EnvelopeHistory; +using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Application.DTOs.Receiver; using EnvelopeGenerator.Domain.Entities; @@ -21,6 +22,7 @@ namespace EnvelopeGenerator.Application.MappingProfiles CreateMap(); CreateMap(); CreateMap(); + CreateMap(); CreateMap(); CreateMap(); CreateMap(); @@ -43,6 +45,7 @@ namespace EnvelopeGenerator.Application.MappingProfiles CreateMap(); CreateMap(); CreateMap(); + CreateMap(); } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/ConfigService.cs b/EnvelopeGenerator.Application/Services/ConfigService.cs index 57317fc1..1d164d4f 100644 --- a/EnvelopeGenerator.Application/Services/ConfigService.cs +++ b/EnvelopeGenerator.Application/Services/ConfigService.cs @@ -3,15 +3,13 @@ using DigitalData.Core.Application; using DigitalData.Core.DTO; using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; namespace EnvelopeGenerator.Application.Services { - public class ConfigService : BasicCRUDService, IConfigService + public class ConfigService : ReadService, IConfigService { private static readonly Guid DefaultConfigCacheId = Guid.NewGuid(); @@ -28,7 +26,7 @@ namespace EnvelopeGenerator.Application.Services var config = await _repository.ReadFirstAsync(); return config is null ? Result.Fail().Notice(LogLevel.Error, Flag.DataIntegrityIssue, "There is no configuration in DB.") - : Result.Success(_mapper.MapOrThrow(config)); + : Result.Success(_mapper.Map(config)); } /// diff --git a/EnvelopeGenerator.Application/Services/DocumentReceiverElementService.cs b/EnvelopeGenerator.Application/Services/DocumentReceiverElementService.cs index 0c8e0c3d..24c25a25 100644 --- a/EnvelopeGenerator.Application/Services/DocumentReceiverElementService.cs +++ b/EnvelopeGenerator.Application/Services/DocumentReceiverElementService.cs @@ -2,10 +2,8 @@ using DigitalData.Core.Application; using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; -using Microsoft.Extensions.Localization; namespace EnvelopeGenerator.Application.Services { diff --git a/EnvelopeGenerator.Application/Services/DocumentStatusService.cs b/EnvelopeGenerator.Application/Services/DocumentStatusService.cs index 019197ff..2a47922d 100644 --- a/EnvelopeGenerator.Application/Services/DocumentStatusService.cs +++ b/EnvelopeGenerator.Application/Services/DocumentStatusService.cs @@ -2,10 +2,8 @@ using DigitalData.Core.Application; using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; -using Microsoft.Extensions.Localization; namespace EnvelopeGenerator.Application.Services { diff --git a/EnvelopeGenerator.Application/Services/EmailTemplateService.cs b/EnvelopeGenerator.Application/Services/EmailTemplateService.cs index d31e1430..2f9947f4 100644 --- a/EnvelopeGenerator.Application/Services/EmailTemplateService.cs +++ b/EnvelopeGenerator.Application/Services/EmailTemplateService.cs @@ -1,11 +1,9 @@ using AutoMapper; using DigitalData.Core.Application; -using Microsoft.Extensions.Localization; using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; -using EnvelopeGenerator.Application.Resources; using static EnvelopeGenerator.Common.Constants; using DigitalData.Core.DTO; using Microsoft.Extensions.Logging; @@ -26,7 +24,7 @@ namespace EnvelopeGenerator.Application.Services ? Result.Fail() .Message(Key.InnerServiceError) .Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"EmailTemplateType '{type}' is not found in DB. Please, define required e-mail template.") - : Result.Success(_mapper.MapOrThrow(temp)); + : Result.Success(_mapper.Map(temp)); } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeHistoryService.cs b/EnvelopeGenerator.Application/Services/EnvelopeHistoryService.cs index d7a4a26a..db72280a 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeHistoryService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeHistoryService.cs @@ -1,11 +1,9 @@ using AutoMapper; using DigitalData.Core.Application; -using Microsoft.Extensions.Localization; using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; using static EnvelopeGenerator.Common.Constants; -using EnvelopeGenerator.Application.Resources; using DigitalData.Core.DTO; using EnvelopeGenerator.Application.DTOs.EnvelopeHistory; using EnvelopeGenerator.Application.DTOs.Receiver; @@ -14,7 +12,7 @@ namespace EnvelopeGenerator.Application.Services { public class EnvelopeHistoryService : CRUDService, IEnvelopeHistoryService { - public EnvelopeHistoryService(IEnvelopeHistoryRepository repository, IStringLocalizer localizer, IMapper mapper) + public EnvelopeHistoryService(IEnvelopeHistoryRepository repository, IMapper mapper) : base(repository, mapper) { } @@ -53,7 +51,7 @@ namespace EnvelopeGenerator.Application.Services public async Task> ReadAsync(int? envelopeId = null, string? userReference = null, ReferenceType? referenceType = null, int? status = null, bool withSender = false, bool withReceiver = false) { - var histDTOs = _mapper.MapOrThrow>( + var histDTOs = _mapper.Map>( await _repository.ReadAsync( envelopeId: envelopeId, userReference: userReference, diff --git a/EnvelopeGenerator.Application/Services/EnvelopeMailService.cs b/EnvelopeGenerator.Application/Services/EnvelopeMailService.cs index 59f83118..296ad932 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeMailService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeMailService.cs @@ -5,7 +5,7 @@ using DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut; using DigitalData.EmailProfilerDispatcher.Abstraction.Services; using DigitalData.UserManager.Application; using EnvelopeGenerator.Application.Contracts; -using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Common; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; @@ -14,7 +14,7 @@ using static EnvelopeGenerator.Common.Constants; namespace EnvelopeGenerator.Application.Services { - public class EnvelopeMailService : EmailOutService, IEnvelopeMailService + public class EnvelopeMailService : EmailOutService, IEnvelopeMailService { private readonly IEmailTemplateService _tempService; private readonly IEnvelopeReceiverService _envRcvService; diff --git a/EnvelopeGenerator.Application/Services/EnvelopeReceiverService.cs b/EnvelopeGenerator.Application/Services/EnvelopeReceiverService.cs index a244c19a..bd09cac4 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeReceiverService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeReceiverService.cs @@ -2,7 +2,7 @@ using DigitalData.Core.Application; using DigitalData.Core.DTO; using EnvelopeGenerator.Application.Contracts; -using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; @@ -11,7 +11,7 @@ using Microsoft.Extensions.Logging; namespace EnvelopeGenerator.Application.Services { - public class EnvelopeReceiverService : BasicCRUDService, IEnvelopeReceiverService + public class EnvelopeReceiverService : BasicCRUDService, IEnvelopeReceiverService { private readonly IStringLocalizer _localizer; @@ -24,13 +24,19 @@ namespace EnvelopeGenerator.Application.Services public async Task>> ReadBySignatureAsync(string signature, bool withEnvelope = false, bool withReceiver = true) { var env_rcvs = await _repository.ReadBySignatureAsync(signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver); - return Result.Success(_mapper.MapOrThrow>(env_rcvs)); + return Result.Success(_mapper.Map>(env_rcvs)); } public async Task>> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false) { var env_rcvs = await _repository.ReadByUuidAsync(uuid: uuid, withEnvelope: withEnvelope, withReceiver: withReceiver); - return Result.Success(_mapper.MapOrThrow>(env_rcvs)); + return Result.Success(_mapper.Map>(env_rcvs)); + } + + public async Task>> ReadSecretByUuidAsync(string uuid, bool withEnvelope = false, bool withReceiver = true) + { + var env_rcvs = await _repository.ReadByUuidAsync(uuid: uuid, withEnvelope: withEnvelope, withReceiver: withReceiver); + return Result.Success(_mapper.Map>(env_rcvs)); } public async Task> ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true) @@ -40,7 +46,7 @@ namespace EnvelopeGenerator.Application.Services return Result.Fail() .Message(Key.EnvelopeReceiverNotFound); - return Result.Success(_mapper.MapOrThrow(env_rcv)); + return Result.Success(_mapper.Map(env_rcv)); } public async Task> ReadByEnvelopeReceiverIdAsync(string envelopeReceiverId, bool withEnvelope = true, bool withReceiver = true) @@ -119,8 +125,14 @@ namespace EnvelopeGenerator.Application.Services public async Task>> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses) { var er_list = await _repository.ReadByUsernameAsync(username: username, min_status: min_status, max_status: max_status, ignore_statuses: ignore_statuses); - var dto_list = _mapper.MapOrThrow>(er_list); + var dto_list = _mapper.Map>(er_list); return Result.Success(dto_list); } + + public async Task> ReadLastUsedReceiverNameByMail(string mail) + { + var er = await _repository.ReadLastByReceiver(mail); + return er is null ? Result.Fail().Notice(LogLevel.None, Flag.NotFound) : Result.Success(er.Name); + } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/EnvelopeService.cs b/EnvelopeGenerator.Application/Services/EnvelopeService.cs index 2c394713..fc84d2f6 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeService.cs @@ -3,27 +3,22 @@ using DigitalData.Core.Application; using DigitalData.Core.DTO; using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs; -using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; -using Microsoft.Extensions.Localization; -using Microsoft.Extensions.Logging; namespace EnvelopeGenerator.Application.Services { public class EnvelopeService : BasicCRUDService, IEnvelopeService { - private readonly ILogger _logger; - public EnvelopeService(IEnvelopeRepository repository, IMapper mapper, ILogger logger) + public EnvelopeService(IEnvelopeRepository repository, IMapper mapper) : base(repository, mapper) { - _logger = logger; } public async Task>> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false) { var envelopes = await _repository.ReadAllWithAsync(documents: documents, history: history, documentReceiverElement: documentReceiverElement); - var readDto = _mapper.MapOrThrow>(envelopes); + var readDto = _mapper.Map>(envelopes); return Result.Success(readDto); } @@ -34,7 +29,14 @@ namespace EnvelopeGenerator.Application.Services if (envelope is null) return Result.Fail(); - var readDto = _mapper.MapOrThrow(envelope); + var readDto = _mapper.Map(envelope); + return Result.Success(readDto); + } + + public async Task>> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[] ignore_statuses) + { + var users = await _repository.ReadByUserAsync(userId: userId, min_status: min_status, max_status: max_status, ignore_statuses: ignore_statuses); + var readDto = _mapper.Map>(users); return Result.Success(readDto); } } diff --git a/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs b/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs index d8b00ebc..2bc3cc75 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs @@ -1,19 +1,30 @@ using AutoMapper; using DigitalData.Core.Application; -using Microsoft.Extensions.Localization; using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; -using EnvelopeGenerator.Application.Resources; +using Microsoft.Extensions.Caching.Memory; +using DigitalData.Core.DTO; +using Microsoft.Extensions.Logging; namespace EnvelopeGenerator.Application.Services { public class EnvelopeTypeService : BasicCRUDService, IEnvelopeTypeService { - public EnvelopeTypeService(IEnvelopeTypeRepository repository, IMapper mapper) + private static readonly Guid CacheKey = Guid.NewGuid(); + + private readonly IMemoryCache _cache; + + public EnvelopeTypeService(IEnvelopeTypeRepository repository, IMapper mapper, IMemoryCache cache) : base(repository, mapper) { + _cache = cache; } + + public override async Task>> ReadAllAsync() + => await _cache.GetOrCreateAsync(CacheKey, async entry => await base.ReadAllAsync()) + ?? Result.Fail>().Notice(LogLevel.Error, Flag.NotFound, "No cached envelope types are available in the database. If you have added any envelope types after the server started, please restart the server."); + } } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Services/ReceiverService.cs b/EnvelopeGenerator.Application/Services/ReceiverService.cs index edbe3d62..422f5c0f 100644 --- a/EnvelopeGenerator.Application/Services/ReceiverService.cs +++ b/EnvelopeGenerator.Application/Services/ReceiverService.cs @@ -1,10 +1,8 @@ using AutoMapper; using DigitalData.Core.Application; -using Microsoft.Extensions.Localization; using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; -using EnvelopeGenerator.Application.Resources; using EnvelopeGenerator.Application.DTOs.Receiver; using DigitalData.Core.DTO; @@ -12,7 +10,7 @@ namespace EnvelopeGenerator.Application.Services { public class ReceiverService : CRUDService, IReceiverService { - public ReceiverService(IReceiverRepository repository, IStringLocalizer localizer, IMapper mapper) + public ReceiverService(IReceiverRepository repository, IMapper mapper) : base(repository, mapper) { } @@ -24,7 +22,7 @@ namespace EnvelopeGenerator.Application.Services if (rcv is null) return Result.Fail(); - return Result.Success(_mapper.MapOrThrow(rcv)); + return Result.Success(_mapper.Map(rcv)); } public async Task DeleteByAsync(string? emailAddress = null, string? signature = null) diff --git a/EnvelopeGenerator.Application/Services/UserReceiverService.cs b/EnvelopeGenerator.Application/Services/UserReceiverService.cs index d241d5bf..08da1906 100644 --- a/EnvelopeGenerator.Application/Services/UserReceiverService.cs +++ b/EnvelopeGenerator.Application/Services/UserReceiverService.cs @@ -1,17 +1,15 @@ using AutoMapper; using DigitalData.Core.Application; -using Microsoft.Extensions.Localization; using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; -using EnvelopeGenerator.Application.Resources; namespace EnvelopeGenerator.Application.Services { public class UserReceiverService : BasicCRUDService, IUserReceiverService { - public UserReceiverService(IUserReceiverRepository repository, IStringLocalizer localizer, IMapper mapper) + public UserReceiverService(IUserReceiverRepository repository, IMapper mapper) : base(repository, mapper) { } diff --git a/EnvelopeGenerator.Common/Constants.vb b/EnvelopeGenerator.Common/Constants.vb index 2d7c26e5..16a19e08 100644 --- a/EnvelopeGenerator.Common/Constants.vb +++ b/EnvelopeGenerator.Common/Constants.vb @@ -26,6 +26,7 @@ MessageCompletionSent = 3005 End Enum + 'TODO: standardize in xwiki Public Enum ReferenceType Receiver Sender diff --git a/EnvelopeGenerator.Domain/Entities/Config.cs b/EnvelopeGenerator.Domain/Entities/Config.cs index 6c91262c..6621beb5 100644 --- a/EnvelopeGenerator.Domain/Entities/Config.cs +++ b/EnvelopeGenerator.Domain/Entities/Config.cs @@ -1,43 +1,41 @@ -using System.ComponentModel; +using DigitalData.Core.Abstractions; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace EnvelopeGenerator.Domain.Entities { [Table("TBSIG_CONFIG", Schema = "dbo")] - public class Config + public class Config : IUnique { [Column("DOCUMENT_PATH", TypeName = "nvarchar(256)")] - public string DocumentPath { get; set; } + public string? DocumentPath { get; init; } [Column("SENDING_PROFILE", TypeName = "int")] [Required] - [DatabaseGenerated(DatabaseGeneratedOption.None)] // Assuming SENDING_PROFILE is manually entered or controlled by the application logic - [DefaultValue(0)] // This sets the default value for SENDING_PROFILE - public int SendingProfile { get; set; } + public required int SendingProfile { get; init; } [Column("SIGNATURE_HOST", TypeName = "nvarchar(128)")] - public string SignatureHost { get; set; } + public string? SignatureHost { get; init; } [Column("EXTERNAL_PROGRAM_NAME", TypeName = "nvarchar(30)")] - public string ExternalProgramName { get; set; } + public string? ExternalProgramName { get; init; } [Column("EXPORT_PATH", TypeName = "nvarchar(256)")] - public string ExportPath { get; set; } + public string? ExportPath { get; init; } [Column("DOCUMENT_PATH_DMZ", TypeName = "nvarchar(512)")] [Required] - [DefaultValue("")] // This sets the default value for DOCUMENT_PATH_DMZ - public string DocumentPathDmz { get; set; } + public string? DocumentPathDmz { get; init; } [Column("EXPORT_PATH_DMZ", TypeName = "nvarchar(512)")] [Required] - [DefaultValue("")] // This sets the default value for EXPORT_PATH_DMZ - public string ExportPathDmz { get; set; } + public required string ExportPathDmz { get; init; } [Column("DOCUMENT_PATH_MOVE_AFTSEND", TypeName = "nvarchar(512)")] [Required] - [DefaultValue("")] // This sets the default value for DOCUMENT_PATH_MOVE_AFTSEND - public string DocumentPathMoveAftsend { get; set; } + public required string DocumentPathMoveAftsend { get; init; } + + [Obsolete("Configuration does not have an ID; it represents a single table in the database.")] + public int Id => throw new InvalidOperationException("This configuration does not support an ID as it represents a single table in the database."); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/DocumentReceiverElement.cs b/EnvelopeGenerator.Domain/Entities/DocumentReceiverElement.cs index 381b268d..6d165028 100644 --- a/EnvelopeGenerator.Domain/Entities/DocumentReceiverElement.cs +++ b/EnvelopeGenerator.Domain/Entities/DocumentReceiverElement.cs @@ -1,11 +1,12 @@ -using System.ComponentModel; +using DigitalData.Core.Abstractions; +using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace EnvelopeGenerator.Domain.Entities { [Table("TBSIG_DOCUMENT_RECEIVER_ELEMENT", Schema = "dbo")] - public class DocumentReceiverElement + public class DocumentReceiverElement : IUnique { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] diff --git a/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs b/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs index 7ee87a27..dd243b76 100644 --- a/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs +++ b/EnvelopeGenerator.Domain/Entities/DocumentStatus.cs @@ -1,10 +1,11 @@ -using System.ComponentModel.DataAnnotations; +using DigitalData.Core.Abstractions; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace EnvelopeGenerator.Domain.Entities { [Table("TBSIG_DOCUMENT_STATUS", Schema = "dbo")] - public class DocumentStatus + public class DocumentStatus : IUnique { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] @@ -27,7 +28,7 @@ namespace EnvelopeGenerator.Domain.Entities public DateTime? StatusChangedWhen { get; set; } [Column("VALUE", TypeName = "nvarchar(max)")] - public string Value { get; set; } + public string? Value { get; set; } [Required] [Column("ADDED_WHEN", TypeName = "datetime")] @@ -42,4 +43,4 @@ namespace EnvelopeGenerator.Domain.Entities [ForeignKey("ReceiverId")] public virtual Receiver? Receiver { get; set; } } -} +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/EmailTemplate.cs b/EnvelopeGenerator.Domain/Entities/EmailTemplate.cs index c82f3d4e..aef2df9d 100644 --- a/EnvelopeGenerator.Domain/Entities/EmailTemplate.cs +++ b/EnvelopeGenerator.Domain/Entities/EmailTemplate.cs @@ -1,10 +1,11 @@ -using System.ComponentModel.DataAnnotations; +using DigitalData.Core.Abstractions; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace EnvelopeGenerator.Domain.Entities { [Table("TBSIG_EMAIL_TEMPLATE", Schema = "dbo")] - public class EmailTemplate + public class EmailTemplate : IUnique { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] @@ -12,12 +13,12 @@ namespace EnvelopeGenerator.Domain.Entities public int Id { get; set; } [Column("NAME", TypeName = "nvarchar(64)")] - public string Name { get; set; } + public string? Name { get; set; } [Column("BODY", TypeName = "nvarchar(max)")] - public string Body { get; set; } + public string? Body { get; set; } [Column("SUBJECT", TypeName = "nvarchar(512)")] - public string Subject { get; set; } + public string? Subject { get; set; } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/Envelope.cs b/EnvelopeGenerator.Domain/Entities/Envelope.cs index b1ab8438..62f8dfd2 100644 --- a/EnvelopeGenerator.Domain/Entities/Envelope.cs +++ b/EnvelopeGenerator.Domain/Entities/Envelope.cs @@ -1,12 +1,12 @@ -using EnvelopeGenerator.Common; -using EnvelopeGenerator.Common.My.Resources; +using DigitalData.Core.Abstractions; +using EnvelopeGenerator.Common; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace EnvelopeGenerator.Domain.Entities { [Table("TBSIG_ENVELOPE", Schema = "dbo")] - public class Envelope + public class Envelope : IUnique { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] @@ -26,11 +26,11 @@ namespace EnvelopeGenerator.Domain.Entities [Required] [Column("ENVELOPE_UUID", TypeName = "nvarchar(36)")] - public string Uuid { get; set; } + public required string Uuid { get; init; } [Required] [Column("MESSAGE", TypeName = "nvarchar(max)")] - public string Message { get; set; } + public string? Message { get; set; } [Column("EXPIRES_WHEN", TypeName = "datetime")] public DateTime? ExpiresWhen { get; set; } @@ -46,13 +46,13 @@ namespace EnvelopeGenerator.Domain.Entities public DateTime? ChangedWhen { get; set; } [Column("TITLE", TypeName = "nvarchar(128)")] - public string Title { get; set; } + public string? Title { get; set; } [Column("CONTRACT_TYPE")] public int? ContractType { get; set; } [Column("LANGUAGE", TypeName = "nvarchar(5)")] - public string Language { get; set; } + public required string Language { get; set; } [Column("SEND_REMINDER_EMAILS")] public bool? SendReminderEmails { get; set; } diff --git a/EnvelopeGenerator.Domain/Entities/EnvelopeCertificate.cs b/EnvelopeGenerator.Domain/Entities/EnvelopeCertificate.cs index c8bd8c6e..f6450954 100644 --- a/EnvelopeGenerator.Domain/Entities/EnvelopeCertificate.cs +++ b/EnvelopeGenerator.Domain/Entities/EnvelopeCertificate.cs @@ -1,10 +1,11 @@ -using System.ComponentModel.DataAnnotations; +using DigitalData.Core.Abstractions; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace EnvelopeGenerator.Domain.Entities { [Table("TBSIG_ENVELOPE_CERTIFICATE", Schema = "dbo")] - public class EnvelopeCertificate + public class EnvelopeCertificate : IUnique { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] @@ -17,11 +18,11 @@ namespace EnvelopeGenerator.Domain.Entities [Required] [Column("ENVELOPE_UUID", TypeName = "nvarchar(36)")] - public string EnvelopeUuid { get; set; } + public required string EnvelopeUuid { get; set; } [Required] [Column("ENVELOPE_SUBJECT", TypeName = "nvarchar(512)")] - public string EnvelopeSubject { get; set; } + public required string EnvelopeSubject { get; set; } [Required] [Column("CREATOR_ID")] @@ -29,11 +30,11 @@ namespace EnvelopeGenerator.Domain.Entities [Required] [Column("CREATOR_NAME", TypeName = "nvarchar(128)")] - public string CreatorName { get; set; } + public required string CreatorName { get; set; } [Required] [Column("CREATOR_EMAIL", TypeName = "nvarchar(128)")] - public string CreatorEmail { get; set; } + public required string CreatorEmail { get; set; } [Required] [Column("ENVELOPE_STATUS")] diff --git a/EnvelopeGenerator.Domain/Entities/EnvelopeDocument.cs b/EnvelopeGenerator.Domain/Entities/EnvelopeDocument.cs index b5e64977..f90ddce2 100644 --- a/EnvelopeGenerator.Domain/Entities/EnvelopeDocument.cs +++ b/EnvelopeGenerator.Domain/Entities/EnvelopeDocument.cs @@ -1,10 +1,11 @@ -using System.ComponentModel.DataAnnotations; +using DigitalData.Core.Abstractions; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace EnvelopeGenerator.Domain.Entities { [Table("TBSIG_ENVELOPE_DOCUMENT", Schema = "dbo")] - public class EnvelopeDocument + public class EnvelopeDocument : IUnique { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] @@ -17,18 +18,18 @@ namespace EnvelopeGenerator.Domain.Entities [Required] [Column("FILENAME", TypeName = "nvarchar(256)")] - public string Filename { get; set; } + public required string Filename { get; set; } [Required] [Column("FILEPATH", TypeName = "nvarchar(256)")] - public string Filepath { get; set; } + public required string Filepath { get; set; } [Required] [Column("ADDED_WHEN", TypeName = "datetime")] - public DateTime AddedWhen { get; set; } + public required DateTime AddedWhen { get; set; } [Column("FILENAME_ORIGINAL", TypeName = "nvarchar(256)")] - public string FilenameOriginal { get; set; } + public required string FilenameOriginal { get; set; } public IEnumerable? Elements { get; set; } } diff --git a/EnvelopeGenerator.Domain/Entities/EnvelopeHistory.cs b/EnvelopeGenerator.Domain/Entities/EnvelopeHistory.cs index 5c0f0cd1..ef9f33be 100644 --- a/EnvelopeGenerator.Domain/Entities/EnvelopeHistory.cs +++ b/EnvelopeGenerator.Domain/Entities/EnvelopeHistory.cs @@ -1,4 +1,5 @@ -using DigitalData.UserManager.Domain.Entities; +using DigitalData.Core.Abstractions; +using DigitalData.UserManager.Domain.Entities; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using static EnvelopeGenerator.Common.Constants; @@ -6,7 +7,7 @@ using static EnvelopeGenerator.Common.Constants; namespace EnvelopeGenerator.Domain.Entities { [Table("TBSIG_ENVELOPE_HISTORY", Schema = "dbo")] - public class EnvelopeHistory + public class EnvelopeHistory : IUnique { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] @@ -19,7 +20,7 @@ namespace EnvelopeGenerator.Domain.Entities [Required] [Column("USER_REFERENCE", TypeName = "nvarchar(128)")] - public string UserReference { get; set; } + public required string UserReference { get; init; } [Required] [Column("STATUS")] @@ -43,11 +44,17 @@ namespace EnvelopeGenerator.Domain.Entities public virtual Receiver? Receiver { get; set; } [NotMapped] - public ReferenceType ReferenceType => (Status / 3) switch + public ReferenceType ReferenceType => (Status / 1000) switch { 1 => ReferenceType.Sender, 2 or 3 => ReferenceType.Receiver, _ => ReferenceType.Unknown, }; + + [NotMapped] + public string? StatusName + => (Enum.IsDefined(typeof(EnvelopeStatus), Status)) + ? Enum.GetName(typeof(EnvelopeStatus), Status) + : null; } } \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/EnvelopeReceiver.cs b/EnvelopeGenerator.Domain/Entities/EnvelopeReceiver.cs index beef339d..e1374b3e 100644 --- a/EnvelopeGenerator.Domain/Entities/EnvelopeReceiver.cs +++ b/EnvelopeGenerator.Domain/Entities/EnvelopeReceiver.cs @@ -1,45 +1,10 @@ -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations.Schema; namespace EnvelopeGenerator.Domain.Entities { [Table("TBSIG_ENVELOPE_RECEIVER", Schema = "dbo")] - public class EnvelopeReceiver + public class EnvelopeReceiver : EnvelopeReceiverBase { - [Key] - [Column("ENVELOPE_ID")] - public int EnvelopeId { get; set; } - - [Key] - [Column("RECEIVER_ID")] - public int ReceiverId { get; set; } - - [Required] - [Column("SEQUENCE")] - public int Sequence { get; set; } - - [Column("NAME", TypeName = "nvarchar(128)")] - public string? Name { get; set; } - - [Column("JOB_TITLE", TypeName = "nvarchar(128)")] - public string? JobTitle { get; set; } - - [Column("COMPANY_NAME", TypeName = "nvarchar(128)")] - public string? CompanyName { get; set; } - - [Column("PRIVATE_MESSAGE", TypeName = "nvarchar(max)")] - public string? PrivateMessage { get; set; } - - [Column("ACCESS_CODE", TypeName = "nvarchar(64)")] - public string? AccessCode { get; set; } - - [Required] - [Column("ADDED_WHEN", TypeName = "datetime")] - public DateTime AddedWhen { get; set; } - - [Column("CHANGED_WHEN", TypeName = "datetime")] - public DateTime? ChangedWhen { get; set; } - [ForeignKey("EnvelopeId")] public Envelope? Envelope { get; set; } diff --git a/EnvelopeGenerator.Domain/Entities/EnvelopeReceiverBase.cs b/EnvelopeGenerator.Domain/Entities/EnvelopeReceiverBase.cs new file mode 100644 index 00000000..ef934a19 --- /dev/null +++ b/EnvelopeGenerator.Domain/Entities/EnvelopeReceiverBase.cs @@ -0,0 +1,46 @@ +using DigitalData.Core.Abstractions; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace EnvelopeGenerator.Domain.Entities +{ + [Table("TBSIG_ENVELOPE_RECEIVER", Schema = "dbo")] + public class EnvelopeReceiverBase : IUnique<(int Envelope, int Receiver)> + { + [Key] + [Column("ENVELOPE_ID")] + public int EnvelopeId { get; set; } + + [Key] + [Column("RECEIVER_ID")] + public int ReceiverId { get; set; } + + [Required] + [Column("SEQUENCE")] + public int Sequence { get; set; } + + [Column("NAME", TypeName = "nvarchar(128)")] + public string? Name { get; set; } + + [Column("JOB_TITLE", TypeName = "nvarchar(128)")] + public string? JobTitle { get; set; } + + [Column("COMPANY_NAME", TypeName = "nvarchar(128)")] + public string? CompanyName { get; set; } + + [Column("PRIVATE_MESSAGE", TypeName = "nvarchar(max)")] + public string? PrivateMessage { get; set; } + + [Column("ACCESS_CODE", TypeName = "nvarchar(64)")] + public string? AccessCode { get; set; } + + [Required] + [Column("ADDED_WHEN", TypeName = "datetime")] + public DateTime AddedWhen { get; set; } + + [Column("CHANGED_WHEN", TypeName = "datetime")] + public DateTime? ChangedWhen { get; set; } + + public (int Envelope, int Receiver) Id => (Envelope: EnvelopeId, Receiver: ReceiverId); + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/EnvelopeType.cs b/EnvelopeGenerator.Domain/Entities/EnvelopeType.cs index c1684672..bd837e81 100644 --- a/EnvelopeGenerator.Domain/Entities/EnvelopeType.cs +++ b/EnvelopeGenerator.Domain/Entities/EnvelopeType.cs @@ -1,12 +1,11 @@ -using System; +using DigitalData.Core.Abstractions; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using EnvelopeGenerator.Domain.Entities; namespace EnvelopeGenerator.Domain.Entities { [Table("TBSIG_ENVELOPE_TYPE", Schema = "dbo")] - public class EnvelopeType + public class EnvelopeType : IUnique { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] @@ -15,10 +14,10 @@ namespace EnvelopeGenerator.Domain.Entities [Required] [Column("TITLE", TypeName = "nvarchar(128)")] - public string Title { get; set; } + public required string Title { get; set; } [Column("LANGUAGE", TypeName = "nvarchar(5)")] - public string Language { get; set; } + public string? Language { get; set; } [Column("EXPIRES_DAYS")] public int? ExpiresDays { get; set; } diff --git a/EnvelopeGenerator.Domain/Entities/Receiver.cs b/EnvelopeGenerator.Domain/Entities/Receiver.cs index bfb91c9c..ae39daf4 100644 --- a/EnvelopeGenerator.Domain/Entities/Receiver.cs +++ b/EnvelopeGenerator.Domain/Entities/Receiver.cs @@ -1,10 +1,11 @@ -using System.ComponentModel.DataAnnotations; +using DigitalData.Core.Abstractions; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace EnvelopeGenerator.Domain.Entities { [Table("TBSIG_RECEIVER", Schema = "dbo")] - public class Receiver + public class Receiver : IUnique { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] @@ -22,5 +23,7 @@ namespace EnvelopeGenerator.Domain.Entities [Required] [Column("ADDED_WHEN", TypeName = "datetime")] public DateTime AddedWhen { get; set; } + + public IEnumerable? EnvelopeReceivers { get; init; } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/Entities/UserReceiver.cs b/EnvelopeGenerator.Domain/Entities/UserReceiver.cs index 9b221297..c2fc7c0c 100644 --- a/EnvelopeGenerator.Domain/Entities/UserReceiver.cs +++ b/EnvelopeGenerator.Domain/Entities/UserReceiver.cs @@ -1,10 +1,11 @@ -using System.ComponentModel.DataAnnotations; +using DigitalData.Core.Abstractions; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace EnvelopeGenerator.Domain.Entities { [Table("TBSIG_USER_RECEIVER", Schema = "dbo")] - public class UserReceiver + public class UserReceiver : IUnique { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] @@ -21,16 +22,16 @@ namespace EnvelopeGenerator.Domain.Entities [Required] [Column("NAME", TypeName = "nvarchar(128)")] - public string Name { get; set; } + public required string Name { get; set; } [Column("COMPANY_NAME", TypeName = "nvarchar(128)")] - public string CompanyName { get; set; } + public string? CompanyName { get; set; } [Column("JOB_TITLE", TypeName = "nvarchar(128)")] - public string JobTitle { get; set; } + public string? JobTitle { get; set; } [Required] [Column("ADDED_WHEN", TypeName = "datetime")] - public DateTime AddedWhen { get; set; } + public required DateTime AddedWhen { get; init; } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj b/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj index 40acf713..3480802f 100644 --- a/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj +++ b/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj @@ -7,6 +7,7 @@ + diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/app.config.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/app.config.ts index 869ce43e..c23f1870 100644 --- a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/app.config.ts +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/app.config.ts @@ -1,4 +1,4 @@ -import { ApplicationConfig } from '@angular/core'; +import { ApplicationConfig, APP_INITIALIZER } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; import { provideClientHydration } from '@angular/platform-browser'; @@ -8,6 +8,7 @@ import { UrlService } from './services/url.service'; import { API_URL } from './tokens/index' import { HTTP_INTERCEPTORS, provideHttpClient, withFetch } from '@angular/common/http'; import { HttpRequestInterceptor } from './http.interceptor'; +import { ConfigurationService } from './services/configuration.service'; export const appConfig: ApplicationConfig = { providers: [ @@ -29,6 +30,12 @@ export const appConfig: ApplicationConfig = { provide: HTTP_INTERCEPTORS, useClass: HttpRequestInterceptor, multi: true + }, + { + provide: APP_INITIALIZER, + useFactory: (configService: ConfigurationService) => async () => await configService.ngOnInit(), + deps: [ConfigurationService], + multi: true } ] }; \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.html b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.html deleted file mode 100644 index f2d68c2d..00000000 --- a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.html +++ /dev/null @@ -1,48 +0,0 @@ - - - @for (colId of displayedColumns; track colId) { - - - - - } - - - - - - - - - - - - - - - -
{{schema[colId].header}} {{schema[colId].field(element)}}   - - -
-
-
{{"element.position"}}
-
{{"element.symbol"}}
-
{{"element.name"}}
-
{{"element.weight"}}
-
-
- {{"element.description"}} - -- Wikipedia -
-
-
\ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.scss b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.scss deleted file mode 100644 index 19d1304d..00000000 --- a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.scss +++ /dev/null @@ -1,31 +0,0 @@ -.example-element-row td { - border-bottom-width: 0; - } - - .example-element-detail { - overflow: hidden; - display: flex; - } - - .example-element-diagram { - min-width: 80px; - border: 2px solid black; - padding: 8px; - font-weight: lighter; - margin: 8px 0; - height: 104px; - } - - .example-element-symbol { - font-weight: bold; - font-size: 40px; - line-height: normal; - } - - .example-element-description { - padding: 16px; - } - - .example-element-description-attribution { - opacity: 0.5; - } \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.ts deleted file mode 100644 index 57c147a7..00000000 --- a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Component, Input, ViewChild } from '@angular/core'; -import { EnvelopeReceiverService } from '../../services/envelope-receiver.service'; -import { MatTable, MatTableModule } from '@angular/material/table'; -import { CommonModule } from '@angular/common' -import { MatIconModule } from '@angular/material/icon'; -import { MatButtonModule } from '@angular/material/button'; -import { animate, state, style, transition, trigger } from '@angular/animations'; - -@Component({ - selector: 'app-envelope-table', - standalone: true, - imports: [MatTableModule, CommonModule, MatTableModule, MatButtonModule, MatIconModule], - templateUrl: './envelope-table.component.html', - animations: [ - trigger('detailExpand', [ - state('collapsed,void', style({ height: '0px', minHeight: '0' })), - state('expanded', style({ height: '*' })), - transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')), - ]), - ], - styleUrl: './envelope-table.component.scss' -}) -export class EnvelopeTableComponent { - - @Input() data: Array = [] - - @Input() options?: { min_status?: number; max_status?: number; ignore_status?: number[] } - - @Input() displayedColumns: string[] = ['title', 'status', 'type', 'privateMessage', 'addedWhen']; - - @Input() schema: Record any; }> = { - 'title': { - header: 'Title', - field: (element: any) => element.envelope.title - }, - 'status': { - header: 'Status', - field: (element: any) => element.envelope.statusName - }, - 'type': { - header: 'Type', - field: (element: any) => element.envelope.contractType - }, - 'privateMessage': { - header: 'Private Message', - field: (element: any) => element.privateMessage - }, - 'addedWhen': { - header: 'Added When', - field: (element: any) => element.addedWhen - }, - } - - columnsToDisplayWithExpand = [...this.displayedColumns, 'expand']; - - expandedElement: any | null; - - @ViewChild(MatTable) table!: MatTable; - - constructor(private erService: EnvelopeReceiverService) { } - - async ngOnInit() { - if (this.data.length === 0) - this.data = await this.erService.getEnvelopeReceiverAsync(this.options); - } - - public updateTable() { - this.table.renderRows(); - } - - isExpandedRow(index: number, row: any): boolean { - return (row?.envelopeId === this.expandedElement?.envelopeId) && (row?.receiverId === this.expandedElement?.receiverId); - } -} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-input/receiver-input.component.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-input/receiver-input.component.ts index e01eb995..376cb002 100644 --- a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-input/receiver-input.component.ts +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-input/receiver-input.component.ts @@ -37,19 +37,19 @@ export class ReceiverInputComponent implements OnInit, OnChanges { private setupFiltering(): void { this.filteredOptions = this.control.valueChanges.pipe( startWith(''), - map(value => this.filter(value || '', this.options)), + map(value => this.filter(value || '', this.options, this.index)), ); } control = new FormControl(''); filteredOptions!: Observable; - @Input() options: string[] = []; - @Input() filter: (value: string, options: string[]) => string[] = value => { + @Input() filter: (value: string, options: string[], index?: number) => string[] = value => { const filterValue = value.toLowerCase(); return this.options.filter(option => option.toLowerCase().includes(filterValue)); } + @Input() index?: number; public get text(): string { return this.control.value || ''; diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-table/receiver-table.component.html b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-table/receiver-table.component.html index a7b69ac5..744d5711 100644 --- a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-table/receiver-table.component.html +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-table/receiver-table.component.html @@ -1,7 +1,7 @@ - diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/dd-table/dd-table.component.html b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/dd-table/dd-table.component.html new file mode 100644 index 00000000..6bdca454 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/dd-table/dd-table.component.html @@ -0,0 +1,59 @@ +@if(isFilterable) { + + {{filter.label}} + + +} + +
Email +
+ @for (column of __columnsToDisplay; track column) { + + @if(isSortable) { + + } + @else { + + } + + + } + + + @if(isExpandable) { + + + + + + + + } + @if(isExpandable) { + + + + + } + @else { + + + } +
{{schema[column].header}} {{schema[column].header}} {{schema[column].field(element)}}   + + +
+ @if(__expandedElement === element){ + + } +
+
+@if(paginatorSizeOptions && paginatorSizeOptions.length > 0) { + +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/dd-table/dd-table.component.scss b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/dd-table/dd-table.component.scss new file mode 100644 index 00000000..155617b3 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/dd-table/dd-table.component.scss @@ -0,0 +1,52 @@ +table { + width: 100%; +} + +tr.example-detail-row { + height: 0; +} + +tr.example-element-row:not(.example-expanded-row):hover { + background: whitesmoke; +} + +tr.example-element-row:not(.example-expanded-row):active { + background: #efefef; +} + +.example-element-row td { + border-bottom-width: 0; +} + +.example-element-detail { + overflow: hidden; + display: flex; +} + +.example-element-diagram { + min-width: 80px; + border: 2px solid black; + padding: 8px; + font-weight: lighter; + margin: 8px 0; + height: 104px; +} + +.example-element-symbol { + font-weight: bold; + font-size: 40px; + line-height: normal; +} + +.example-element-description { + padding: 16px; +} + +.example-element-description-attribution { + opacity: 0.5; +} + +.mat-mdc-form-field { + font-size: 14px; + width: 100%; +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/dd-table/dd-table.component.spec.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/dd-table/dd-table.component.spec.ts new file mode 100644 index 00000000..0c704ba9 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/dd-table/dd-table.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DDTable } from './dd-table.component'; + +describe('TableExpandableRowsExampleComponent', () => { + let component: DDTable; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [DDTable] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DDTable); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/dd-table/dd-table.component.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/dd-table/dd-table.component.ts new file mode 100644 index 00000000..4493ff6c --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/dd-table/dd-table.component.ts @@ -0,0 +1,103 @@ +import { AfterViewInit, Component, Input, ViewChild, inject } from '@angular/core'; +import { animate, state, style, transition, trigger } from '@angular/animations'; +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; +import { MatTable, MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { ConfigurationService } from '../../../services/configuration.service'; +import { MatInputModule } from '@angular/material/input'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatSort, MatSortModule } from '@angular/material/sort'; +import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; + +/** + * @title Table with expandable rows + */ +@Component({ + selector: 'dd-table', + styleUrl: 'dd-table.component.scss', + templateUrl: 'dd-table.component.html', + animations: [ + trigger('detailExpand', [ + state('collapsed,void', style({ height: '0px', minHeight: '0' })), + state('expanded', style({ height: '*' })), + transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')), + ]), + ], + standalone: true, + imports: [ + MatTableModule, + MatButtonModule, + MatIconModule, + MatFormFieldModule, + MatInputModule, + MatTableModule, + MatSort, + MatSortModule, + MatPaginator, + MatPaginatorModule + ], +}) +export class DDTable implements AfterViewInit { + public readonly dataSource: any = new MatTableDataSource(); + @Input() public set columnsToDisplay(value: string[]) { + this.__columnsToDisplay = value; + this.__columnsToDisplayWithExpand = [...value, 'expand']; + } + @Input() public set data(value: any[]) { + this.dataSource.data = value; + } + @Input() schema: Record any; }> = {} + + @Input() paginatorSizeOptions?: number[]; + + @Input() filter: { label: string, placeholder: string } = { label: '', placeholder: '' } + + @Input() isFilterable: boolean = false; + + @Input() isExpandable: boolean = false; + + @Input() isSortable: boolean = false; + + @Input() onToggleExpandedRow: (element: any, event: Event) => Promise = async (element: any, event: Event) => { } + + public get data(): any[] { + return this.dataSource.data; + } + __columnsToDisplay: string[] = []; + __columnsToDisplayWithExpand: string[] = []; + __expandedElement!: any; + + config: ConfigurationService = inject(ConfigurationService); + + @ViewChild(MatSort) sort!: MatSort; + @ViewChild(MatPaginator) paginator!: MatPaginator; + @ViewChild(MatTable) table!: MatTable; + + ngAfterViewInit(): void { + if (this.isSortable) + this.dataSource.sort = this.sort; + if (this.paginatorSizeOptions && this.paginatorSizeOptions.length > 0) + this.dataSource.paginator = this.paginator; + } + + applyFilter(event: Event) { + const filterValue = (event.target as HTMLInputElement).value; + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + update() { + this.table.renderRows(); + } + + async toggleExpandedRow(element: any, event: Event): Promise { + // first determine the new expanded element, thus it would be possible to use up-to-date + const newExpandedElement = this.__expandedElement === element ? null : element; + + // before update the expanded element call the call-back method to show up-to-date component + await this.onToggleExpandedRow(newExpandedElement, event); + + // assign expanded element + this.__expandedElement = newExpandedElement; + event.stopPropagation(); + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/envelope-table/envelope-table.component.html b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/envelope-table/envelope-table.component.html new file mode 100644 index 00000000..77a6daf9 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/envelope-table/envelope-table.component.html @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/envelope-table/envelope-table.component.scss b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/envelope-table/envelope-table.component.scss new file mode 100644 index 00000000..1272cd53 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/envelope-table/envelope-table.component.scss @@ -0,0 +1,59 @@ +/* Structure */ +table { + width: 100%; +} + +.mat-mdc-form-field { + font-size: 14px; + width: 100%; + margin-top: 10px; +} + +/* For expanding table */ +table { + width: 100%; +} + +tr.example-detail-row { + height: 0; +} + +tr.example-element-row:not(.example-expanded-row):hover { + background: whitesmoke; +} + +tr.example-element-row:not(.example-expanded-row):active { + background: #efefef; +} + +.example-element-row td { + border-bottom-width: 0; +} + +.example-element-detail { + overflow: hidden; + display: flex; +} + +.example-element-diagram { + min-width: 80px; + border: 2px solid black; + padding: 8px; + font-weight: lighter; + margin: 8px 0; + height: 104px; +} + +.example-element-symbol { + font-weight: bold; + font-size: 40px; + line-height: normal; +} + +.example-element-description { + padding: 16px; +} + +.example-element-description-attribution { + opacity: 0.5; +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.spec.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/envelope-table/envelope-table.component.spec.ts similarity index 100% rename from EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.spec.ts rename to EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/envelope-table/envelope-table.component.spec.ts diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/envelope-table/envelope-table.component.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/envelope-table/envelope-table.component.ts new file mode 100644 index 00000000..79adf50a --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/envelope-table/envelope-table.component.ts @@ -0,0 +1,82 @@ +import { AfterViewInit, Component, Input, ViewChild, inject, viewChild } from '@angular/core'; +import { EnvelopeService } from '../../../services/envelope.service'; +import { animate, state, style, transition, trigger } from '@angular/animations'; +import { ConfigurationService } from '../../../services/configuration.service'; +import { DDTable } from "../dd-table/dd-table.component"; +import { ClearableInputComponent } from '../../clearable-input/clearable-input.component' +import { MatTabsModule } from '@angular/material/tabs'; +import { ReceiverStatusTableComponent } from "../receiver-status-table/receiver-status-table.component"; +import { HistoryTableComponent } from "../history-table/history-table.component"; +import { EnvelopeReceiverService } from '../../../services/envelope-receiver.service'; +import { HistoryService } from '../../../services/history.service'; + +@Component({ + selector: 'envelope-table', + standalone: true, + imports: [DDTable, ClearableInputComponent, MatTabsModule, ReceiverStatusTableComponent, HistoryTableComponent], + templateUrl: './envelope-table.component.html', + animations: [ + trigger('detailExpand', [ + state('collapsed,void', style({ height: '0px', minHeight: '0' })), + state('expanded', style({ height: '*' })), + transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')), + ]), + ], + styleUrl: './envelope-table.component.scss' +}) +export class EnvelopeTableComponent implements AfterViewInit { + + @Input() options?: { min_status?: number; max_status?: number; ignore_status?: number[] } + + displayedColumns: string[] = ['title', 'status', 'type', 'addedWhen']; + + schema: Record any; }> = { + 'title': { + header: 'Title', + field: (element: any) => element.title + }, + 'status': { + header: 'Status', + field: (element: any) => element.statusName + }, + 'type': { + header: 'Type', + field: (element: any) => this.config.envelopeTypeTitles[element.contractType - 1] + }, + 'addedWhen': { + header: 'Added When', + field: (element: any) => element.addedWhen + } + } + + data: any[] = []; + + @ViewChild(ReceiverStatusTableComponent) rsTable!: ReceiverStatusTableComponent + + @ViewChild(HistoryTableComponent) histTable!: HistoryTableComponent + + onToggleExpandedRow: (envelope: any, event: Event) => Promise = async (envelope, event) => { + if (envelope === null || envelope === undefined) + return; + + var uuid: string = envelope.uuid; + this.rsTable.data = await this.erService.getSecretAsync(uuid); + + var id: number = envelope.id; + var refType: number = this.config.referenceType.receiver; + const histories = await this.histService.getHistoryAsync({ envelopeId: id, referenceType: refType, withReceiver: true }) + this.histTable.data = histories; + } + + private eService: EnvelopeService = inject(EnvelopeService); + + private config: ConfigurationService = inject(ConfigurationService); + + private readonly erService: EnvelopeReceiverService = inject(EnvelopeReceiverService); + + private readonly histService: HistoryService = inject(HistoryService); + + async ngAfterViewInit() { + this.data = await this.eService.getEnvelopeAsync(this.options); + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/history-table/history-table.component.html b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/history-table/history-table.component.html new file mode 100644 index 00000000..73206709 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/history-table/history-table.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-table/receiver-table.component.scss b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/history-table/history-table.component.scss similarity index 100% rename from EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-table/receiver-table.component.scss rename to EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/history-table/history-table.component.scss diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/history-table/history-table.component.spec.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/history-table/history-table.component.spec.ts new file mode 100644 index 00000000..4156b756 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/history-table/history-table.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HistoryTableComponent } from './history-table.component'; + +describe('HistoryTableComponent', () => { + let component: HistoryTableComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HistoryTableComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HistoryTableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/history-table/history-table.component.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/history-table/history-table.component.ts new file mode 100644 index 00000000..1d2cd2fd --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/history-table/history-table.component.ts @@ -0,0 +1,30 @@ +import { Component } from '@angular/core'; +import { DDTable } from '../dd-table/dd-table.component' + +@Component({ + selector: 'history-table', + standalone: true, + imports: [DDTable], + templateUrl: './history-table.component.html', + styleUrl: './history-table.component.scss' +}) +export class HistoryTableComponent { + data: any[] = []; + + schema: Record any; }> = { + "status": { + "header": "Status", + "field": hist => hist.statusName + }, + "user": { + "header": "Benutzer", + "field": hist => hist.userReference + }, + "date": { + "header": "Datum", + "field": hist => hist.actionDate + } + } + + columnsToDisplay: string[] = ["status", "user", "date"]; +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-status-table/receiver-status-table.component.html b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-status-table/receiver-status-table.component.html new file mode 100644 index 00000000..73206709 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-status-table/receiver-status-table.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-status-table/receiver-status-table.component.scss b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-status-table/receiver-status-table.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-status-table/receiver-status-table.component.spec.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-status-table/receiver-status-table.component.spec.ts new file mode 100644 index 00000000..98748987 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-status-table/receiver-status-table.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ReceiverStatusTableComponent } from './receiver-status-table.component'; + +describe('ReceiverStatusTableComponent', () => { + let component: ReceiverStatusTableComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ReceiverStatusTableComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ReceiverStatusTableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-status-table/receiver-status-table.component.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-status-table/receiver-status-table.component.ts new file mode 100644 index 00000000..b4a17350 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-status-table/receiver-status-table.component.ts @@ -0,0 +1,30 @@ +import { Component } from '@angular/core'; +import { DDTable } from '../dd-table/dd-table.component' + +@Component({ + selector: 'receiver-status-table', + standalone: true, + imports: [DDTable], + templateUrl: './receiver-status-table.component.html', + styleUrl: './receiver-status-table.component.scss' +}) +export class ReceiverStatusTableComponent { + data: any[] = []; + + schema: Record any; }> = { + "name": { + "header": "Email Anrede", + "field": (er) => er.name + }, + "email": { + "header": "Email", + "field": (er) => er.receiver.emailAddress + }, + "access_code": { + "header": "Email", + "field": (er) => er.accessCode + }, + } + + columnsToDisplay: string[] = ["name", "email", "access_code"]; +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-table/receiver-table.component.html b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-table/receiver-table.component.html new file mode 100644 index 00000000..b439f39e --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-table/receiver-table.component.html @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + +
Email + + Anrede Email + + Zugriffscode {{element.accessCode}}
\ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-table/receiver-table.component.scss b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-table/receiver-table.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-table/receiver-table.component.spec.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-table/receiver-table.component.spec.ts similarity index 100% rename from EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-table/receiver-table.component.spec.ts rename to EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-table/receiver-table.component.spec.ts diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-table/receiver-table.component.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-table/receiver-table.component.ts similarity index 56% rename from EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-table/receiver-table.component.ts rename to EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-table/receiver-table.component.ts index b45d343c..c1219a2b 100644 --- a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/receiver-table/receiver-table.component.ts +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/tables/receiver-table/receiver-table.component.ts @@ -1,15 +1,15 @@ -import { Component, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core'; -import { FormsModule, ReactiveFormsModule, FormControl } from '@angular/forms'; +import { Component, OnInit, QueryList, ViewChildren } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatInputModule } from '@angular/material/input'; import { MatTableModule } from '@angular/material/table'; import { AsyncPipe } from '@angular/common'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatFormFieldModule } from '@angular/material/form-field'; -import { ReceiverService } from '../../services/receiver.service' -import { ReceiverInputComponent } from '../receiver-input/receiver-input.component'; +import { ReceiverService } from '../../../services/receiver.service' +import { ReceiverInputComponent } from '../../receiver-input/receiver-input.component'; import { MatIconModule } from '@angular/material/icon'; import { MatButtonModule } from '@angular/material/button'; -import { ClearableInputComponent } from '../clearable-input/clearable-input.component' +import { ClearableInputComponent } from '../../clearable-input/clearable-input.component' import { v4 as uuidv4 } from 'uuid'; @Component({ @@ -34,24 +34,41 @@ export class ReceiverTableComponent implements OnInit { constructor(private receiverService: ReceiverService) { } async ngOnInit() { - this.receiver_mails = await this.receiverService.getReceiverAsync().then((receivers: any[]) => receivers.map(r => r.emailAddress)); + const receivers = await this.receiverService.getReceiverAsync(); + this.receiver_mails = receivers.map((r: any) => r.emailAddress); + this.last_used_name = receivers.reduce((acc: any, r: any) => { + acc[r.emailAddress] = r.lastUsedName; + return acc; + }, {} as { [key: string]: string | null }); } - receiver_filter: (value: string, options: string[]) => string[] = (value, options) => { + receiver_filter: (value: string, options: string[], index?: number) => string[] = (value, options, index) => { const filterValue = value.toLowerCase(); + // set the name if it is used before + const name = this.last_used_name[value]; + + if (name && index != null && index != undefined) { + this.receiverData.at(index)!.name = name + } + + // !!! do not allow email duplication !!! + var similarMails = this.receiver_mails.filter(m => m.toLocaleLowerCase() === value.toLocaleLowerCase() && m !== value) + if (similarMails.length > 0 && index != undefined) { + this.receiverInputs[index].text = similarMails[0]; + } + // if added into last row if (value.length > 0 && (this.receiverInputs.at(-1)?.lenght ?? 0) > 0) { this.receiverData.at(-1)!.accessCode = generateAccessCode(); this.receiverData.push({ email: "", name: "", accessCode: "" }); this.update(); } - else if (value.length == 0) { - for (var i = 0; i < this.receiverInputs.length - 1; i++) { - if (this.receiverInputs[i].lenght === 0) { - this.receiverData.splice(i, 1); - this.update(); - } + // delete the row with out mail + else if (value.length === 0 && this.receiverInputs.length - 1 !== index) { + if (this.receiverInputs.length > 1 && this.receiverInputs[index!]?.lenght === 0) { + this.receiverData.splice(index!, 1); + this.update(); } } @@ -59,6 +76,7 @@ export class ReceiverTableComponent implements OnInit { } receiver_mails: string[] = []; + last_used_name: { [key: string]: string | null } = {}; @ViewChildren(ReceiverInputComponent) receiverInputsQueryList!: QueryList; get receiverInputs(): ReceiverInputComponent[] { diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/pages/envelope-creation/envelope-creation.component.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/pages/envelope-creation/envelope-creation.component.ts index 9b617390..32b38270 100644 --- a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/pages/envelope-creation/envelope-creation.component.ts +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/pages/envelope-creation/envelope-creation.component.ts @@ -5,7 +5,7 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatStepperModule } from '@angular/material/stepper'; import { MatButtonModule } from '@angular/material/button'; import { MatSelectModule } from '@angular/material/select'; -import { ReceiverTableComponent } from "../../components/receiver-table/receiver-table.component"; +import { ReceiverTableComponent } from "../../components/tables/receiver-table/receiver-table.component"; import { MatIconModule } from '@angular/material/icon'; @Component({ diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/pages/envelope/envelope.component.html b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/pages/envelope/envelope.component.html index b131b165..34ed812e 100644 --- a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/pages/envelope/envelope.component.html +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/pages/envelope/envelope.component.html @@ -1,10 +1,10 @@
- + - +
\ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/pages/envelope/envelope.component.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/pages/envelope/envelope.component.ts index ee5f93e6..fd2ff694 100644 --- a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/pages/envelope/envelope.component.ts +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/pages/envelope/envelope.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import { EnvelopeTableComponent } from "../../components/envelope-table/envelope-table.component"; +import { EnvelopeTableComponent } from "../../components/tables/envelope-table/envelope-table.component"; import { MatTabsModule } from '@angular/material/tabs'; import { LocalizationService } from '../../services/localization.service'; import { Status } from '../../enums/envelope-const' diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/configuration.service.spec.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/configuration.service.spec.ts new file mode 100644 index 00000000..ec51dfa5 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/configuration.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { ConfigurationService } from './configuration.service'; + +describe('ConfigurationService', () => { + let service: ConfigurationService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(ConfigurationService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/configuration.service.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/configuration.service.ts new file mode 100644 index 00000000..2b56191e --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/configuration.service.ts @@ -0,0 +1,47 @@ +import { Injectable, OnInit, inject } from '@angular/core'; +import { HttpClient, HttpParams } from '@angular/common/http'; +import { Observable, firstValueFrom } from 'rxjs'; +import { API_URL } from '../tokens/index'; + +@Injectable({ + providedIn: 'root' +}) +export class ConfigurationService implements OnInit { + + protected url: string; + + private _envelopeTypes! : any[]; + + private _envelopeTypeTitles! : any[]; + + private _referenceType!: any; + + constructor(private http: HttpClient) { + const api_url = inject(API_URL); + this.url = `${api_url}`; + } + + async ngOnInit(): Promise { + const envelopeTypes$: Observable = this.http.get(`${this.url}/EnvelopeType`) + envelopeTypes$.subscribe({next: res => { + this._envelopeTypes = res; + this._envelopeTypeTitles = res.map(e => e.title); + }}); + + this.http.get(`${this.url}/History/reference-type`).subscribe({ + next: res => this._referenceType = res + }) + } + + public get envelopeTypes() { + return this._envelopeTypes; + } + + public get envelopeTypeTitles() { + return this._envelopeTypeTitles; + } + + public get referenceType() { + return this._referenceType; + } +} diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/envelope-receiver.service.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/envelope-receiver.service.ts index 3a1a3766..c919798d 100644 --- a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/envelope-receiver.service.ts +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/envelope-receiver.service.ts @@ -27,8 +27,18 @@ export class EnvelopeReceiverService { return this.http.get(this.url, { params }); } - getEnvelopeReceiverAsync(options?: { min_status?: number; max_status?: number; ignore_status?: number[] }): Promise { return firstValueFrom(this.getEnvelopeReceiver(options)); } + + getSecret(uuid: string): Observable { + let params = new HttpParams(); + params = params.set('uuid', uuid); + + return this.http.get(`${this.url}/secret`, { params }); + } + + getSecretAsync(uuid: string): Promise { + return firstValueFrom(this.getSecret(uuid)); + } } \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/envelope.service.spec.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/envelope.service.spec.ts new file mode 100644 index 00000000..25fa59b3 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/envelope.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { EnvelopeService } from './envelope.service'; + +describe('EnvelopeService', () => { + let service: EnvelopeService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(EnvelopeService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/envelope.service.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/envelope.service.ts new file mode 100644 index 00000000..228f2677 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/envelope.service.ts @@ -0,0 +1,33 @@ +import { Injectable, inject } from '@angular/core'; +import { HttpClient, HttpParams } from '@angular/common/http'; +import { Observable, firstValueFrom } from 'rxjs'; +import { API_URL } from '../tokens/index'; + +@Injectable({ + providedIn: 'root' +}) +export class EnvelopeService { + protected url: string; + + constructor(private http: HttpClient) { + const api_url = inject(API_URL); + this.url = `${api_url}/envelope`; + } + + public getEnvelope(options?: { min_status?: number; max_status?: number; ignore_status?: number[] }): Observable { + let params = new HttpParams(); + if (options) { + if (options.min_status) + params = params.set('min_status', options.min_status.toString()); + if (options.max_status) + params = params.set('max_status', options.max_status.toString()); + if (options.ignore_status) + params = params.set('ignore_status', options.ignore_status.join(',')); + } + return this.http.get(this.url, { params }); + } + + public async getEnvelopeAsync(options?: { min_status?: number; max_status?: number; ignore_status?: number[] }): Promise { + return await firstValueFrom(this.getEnvelope(options)); + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/history.service.spec.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/history.service.spec.ts new file mode 100644 index 00000000..65de5db7 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/history.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { HistoryService } from './history.service'; + +describe('HistoryService', () => { + let service: HistoryService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(HistoryService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/history.service.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/history.service.ts new file mode 100644 index 00000000..b458943f --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/history.service.ts @@ -0,0 +1,46 @@ +import { Injectable, inject } from '@angular/core'; +import { HttpClient, HttpParams } from '@angular/common/http'; +import { Observable, firstValueFrom } from 'rxjs'; +import { API_URL } from '../tokens/index'; + + +@Injectable({ + providedIn: 'root' +}) +export class HistoryService { + protected url: string; + + constructor(private http: HttpClient) { + const api_url = inject(API_URL); + this.url = `${api_url}/history`; + } + + public getHistory(options?: Options): Observable { + let params = new HttpParams(); + if (options) { + if (options.envelopeId) + params = params.set('envelopeId', options.envelopeId); + if (options.referenceType != null) + params = params.set('referenceType', options.referenceType); + if (options.userReference) + params = params.set('userReference', options.userReference); + if (options.withReceiver) + params = params.set('withReceiver', options.withReceiver); + if (options.withSender) + params = params.set('withSender', options.withSender); + } + return this.http.get(this.url, { params }); + } + + public async getHistoryAsync(options?: Options): Promise { + return firstValueFrom(this.getHistory(options)); + } +} + +class Options { + envelopeId?: number; + userReference?: string; + referenceType: number | null = null; + withSender?: boolean; + withReceiver?: boolean; +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/ControllerExtensions.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/ControllerExtensions.cs index a897824b..1121a9b8 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/ControllerExtensions.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/ControllerExtensions.cs @@ -5,20 +5,20 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers { public static class ControllerExtensions { - public static int? GetId(this ControllerBase controller) - => int.TryParse(controller.User.FindFirst(ClaimTypes.NameIdentifier)?.Value, out int result) + public static int? GetId(this ClaimsPrincipal user) + => int.TryParse(user.FindFirst(ClaimTypes.NameIdentifier)?.Value, out int result) ? result : null; - public static string? GetUsername(this ControllerBase controller) - => controller.User.FindFirst(ClaimTypes.Name)?.Value; + public static string? GetUsername(this ClaimsPrincipal user) + => user.FindFirst(ClaimTypes.Name)?.Value; - public static string? GetName(this ControllerBase controller) - => controller.User.FindFirst(ClaimTypes.Surname)?.Value; + public static string? GetName(this ClaimsPrincipal user) + => user.FindFirst(ClaimTypes.Surname)?.Value; - public static string? GetPrename(this ControllerBase controller) - => controller.User.FindFirst(ClaimTypes.GivenName)?.Value; + public static string? GetPrename(this ClaimsPrincipal user) + => user.FindFirst(ClaimTypes.GivenName)?.Value; - public static string? GetEmail(this ControllerBase controller) - => controller.User.FindFirst(ClaimTypes.Email)?.Value; + public static string? GetEmail(this ClaimsPrincipal user) + => user.FindFirst(ClaimTypes.Email)?.Value; } } \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs new file mode 100644 index 00000000..a7306a36 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs @@ -0,0 +1,52 @@ +using DigitalData.Core.DTO; +using EnvelopeGenerator.Application.Contracts; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace EnvelopeGenerator.GeneratorAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + [Authorize] + public class EnvelopeController : ControllerBase + { + private readonly ILogger _logger; + private readonly IEnvelopeService _envelopeService; + + public EnvelopeController(ILogger logger, IEnvelopeService envelopeService) + { + _logger = logger; + _envelopeService = envelopeService; + } + + [Authorize] + [HttpGet] + public async Task GetCurrentAsync( + [FromQuery] int? min_status = null, + [FromQuery] int? max_status = null, + [FromQuery] params int[] ignore_statuses) + { + try + { + if (User.GetId() is int intId) + return await _envelopeService.ReadByUserAsync(intId, min_status: min_status, max_status: max_status, ignore_statuses: ignore_statuses).ThenAsync( + Success: Ok, + Fail: IActionResult (msg, ntc) => + { + _logger.LogNotice(ntc); + return StatusCode(StatusCodes.Status500InternalServerError); + }); + else + { + _logger.LogError("Despite successful authorization, the 'api/envelope' route encountered an issue: the user ID is not recognized as an integer. This may be due to the removal of the ID during the creation of the claims list."); + return StatusCode(StatusCodes.Status500InternalServerError); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "{Message}", ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeReceiverController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeReceiverController.cs index bf8e2cb2..b5a9c989 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeReceiverController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeReceiverController.cs @@ -1,11 +1,13 @@ using DigitalData.Core.DTO; using EnvelopeGenerator.Application.Contracts; +using EnvelopeGenerator.Common.My.Resources; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace EnvelopeGenerator.GeneratorAPI.Controllers { [Route("api/[controller]")] + [Authorize] [ApiController] public class EnvelopeReceiverController : ControllerBase { @@ -17,19 +19,18 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers _logger = logger; _erService = envelopeReceiverService; } - - [Authorize] + [HttpGet] public async Task GetEnvelopeReceiver([FromQuery] int? min_status = null, [FromQuery] int? max_status = null, [FromQuery] int[]? ignore_status = null) { try { - var username = this.GetUsername(); + var username = User.GetUsername(); if (username is null) { _logger.LogError(@"Envelope Receiver dto cannot be sent because username claim is null. Potential authentication and authorization error. The value of other claims are [id: {id}], [username: {username}], [name: {name}], [prename: {prename}], [email: {email}].", - this.GetId(), this.GetUsername(), this.GetName(), this.GetPrename(), this.GetEmail()); + User.GetId(), User.GetUsername(), User.GetName(), User.GetPrename(), User.GetEmail()); return StatusCode(StatusCodes.Status500InternalServerError); } @@ -49,5 +50,49 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers return new StatusCodeResult(StatusCodes.Status500InternalServerError); } } + + [HttpGet("receiver-name/{mail}")] + public async Task GetReceiverName([FromRoute] string mail) + { + try + { + return await _erService.ReadLastUsedReceiverNameByMail(mail).ThenAsync( + Success: res => res is null ? Ok(string.Empty) : Ok(res), + Fail: IActionResult (msg, ntc) => + { + if (ntc.HasFlag(Flag.NotFound)) + return NotFound(); + + _logger.LogNotice(ntc); + return StatusCode(StatusCodes.Status500InternalServerError); + }); + } + catch(Exception ex) + { + _logger.LogError(ex, "{message}", ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } + } + + [HttpGet("secret")] + [Authorize] + public async Task GetSecretAsync([FromQuery] string uuid) + { + try + { + return await _erService.ReadSecretByUuidAsync(uuid: uuid).ThenAsync( + Success: Ok, + Fail: IActionResult (msg, ntc) => + { + _logger.LogNotice(ntc); + return StatusCode(StatusCodes.Status500InternalServerError); + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "{message}", ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } + } } } \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs new file mode 100644 index 00000000..daacd703 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs @@ -0,0 +1,43 @@ +using DigitalData.Core.DTO; +using EnvelopeGenerator.Application.Contracts; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Net.Mail; +using System.Security.Cryptography.Xml; + +namespace EnvelopeGenerator.GeneratorAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class EnvelopeTypeController : ControllerBase + { + private readonly ILogger _logger; + private readonly IEnvelopeTypeService _service; + + public EnvelopeTypeController(ILogger logger, IEnvelopeTypeService service) + { + _logger = logger; + _service = service; + } + + [HttpGet] + public async Task GetAllAsync() + { + try + { + return await _service.ReadAllAsync().ThenAsync( + Success: Ok, + Fail: IActionResult (msg, ntc) => + { + _logger.LogNotice(ntc); + return ntc.HasFlag(Flag.NotFound) ? NotFound() : StatusCode(StatusCodes.Status500InternalServerError); + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "{Message}", ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/HistoryController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/HistoryController.cs new file mode 100644 index 00000000..8b24cc9d --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/HistoryController.cs @@ -0,0 +1,73 @@ +using EnvelopeGenerator.Application.Contracts; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System; +using static EnvelopeGenerator.Common.Constants; + +namespace EnvelopeGenerator.GeneratorAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + [Authorize] + public class HistoryController : ControllerBase + { + private readonly ILogger _logger; + + private readonly IEnvelopeHistoryService _service; + + public HistoryController(ILogger logger, IEnvelopeHistoryService service) + { + _logger = logger; + _service = service; + } + + [HttpGet("reference-type")] + [Authorize] + public IActionResult GetReferenceTypes() + { + // Enum to Key-Value pair + var referenceTypes = Enum.GetValues(typeof(ReferenceType)) + .Cast() + .ToDictionary(rt => + { + var key = rt.ToString(); + var keyAsCamelCase = char.ToLower(key[0]) + key[1..]; + return keyAsCamelCase; + }, rt => (int)rt); + + return Ok(referenceTypes); + } + + [HttpGet] + [Authorize] + public async Task GetAllAsync([FromQuery] int? envelopeId = null, [FromQuery] string? userReference = null, [FromQuery] int? referenceType = null, [FromQuery] bool withSender = false, [FromQuery] bool withReceiver = false) + { + ReferenceType? refTypEnum = null; + + if (referenceType is int refTypInt) + if (Enum.IsDefined(typeof(ReferenceType), refTypInt)) + refTypEnum = (ReferenceType)refTypInt; + else + throw new ArgumentException($"The provided referenceType '{referenceType}' is not valid. It must correspond to a valid value in the {nameof(ReferenceType)} enum."); + + switch(referenceType) + { + case (int)ReferenceType.Receiver: + withReceiver = true; + break; + case (int)ReferenceType.Sender: + withSender = true; + break; + } + + var histories = await _service.ReadAsync( + envelopeId: envelopeId, + userReference: userReference, + referenceType: refTypEnum, + withSender: withSender, + withReceiver: withReceiver); + + return Ok(histories); + } + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/ReceiverController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/ReceiverController.cs index 9fbeea1c..4c057b92 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/ReceiverController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/ReceiverController.cs @@ -17,8 +17,6 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers { } - - [HttpGet] public async Task Get([FromQuery] string? emailAddress = null, [FromQuery] string? signature = null) { diff --git a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj index d42159a2..2684ed2c 100644 --- a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj +++ b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj @@ -1,4 +1,4 @@ - + net7.0 @@ -7,8 +7,8 @@ - - + + diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeReceiverRepository.cs index 219e64eb..e471ddf7 100644 --- a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeReceiverRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeReceiverRepository.cs @@ -3,7 +3,7 @@ using EnvelopeGenerator.Domain.Entities; namespace EnvelopeGenerator.Infrastructure.Contracts { - public interface IEnvelopeReceiverRepository : ICRUDRepository + public interface IEnvelopeReceiverRepository : ICRUDRepository { Task> ReadByUuidAsync(string uuid, bool withEnvelope = true, bool withReceiver = false); @@ -20,5 +20,7 @@ namespace EnvelopeGenerator.Infrastructure.Contracts Task ReadAccessCodeByIdAsync(int envelopeId, int receiverId); Task> ReadByUsernameAsync(string username, int? min_status = null, int? max_status = null, params int[] ignore_statuses); + + Task ReadLastByReceiver(string email); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeRepository.cs b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeRepository.cs index d2d1377f..5b78658e 100644 --- a/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Contracts/IEnvelopeRepository.cs @@ -8,5 +8,7 @@ namespace EnvelopeGenerator.Infrastructure.Contracts Task> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false); Task ReadByUuidAsync(string uuid, bool withDocuments = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withUser = false, bool withAll = false); + + Task> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[] ignore_statuses); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/EGDbContext.cs b/EnvelopeGenerator.Infrastructure/EGDbContext.cs index a367bf47..449bd55e 100644 --- a/EnvelopeGenerator.Infrastructure/EGDbContext.cs +++ b/EnvelopeGenerator.Infrastructure/EGDbContext.cs @@ -1,14 +1,77 @@ using DigitalData.EmailProfilerDispatcher.Abstraction.Entities; +using DigitalData.UserManager.Domain.Entities; using DigitalData.UserManager.Infrastructure; +using DigitalData.UserManager.Infrastructure.Contracts; using EnvelopeGenerator.Domain.Entities; using Microsoft.EntityFrameworkCore; +using Group = DigitalData.UserManager.Domain.Entities.Group; +using Module = DigitalData.UserManager.Domain.Entities.Module; +using DigitalData.EmailProfilerDispatcher; namespace EnvelopeGenerator.Infrastructure { - public class EGDbContext : DbContext + //TODO: Adding EmailOut instead of EmailOut.Abst is not correct for the arch. Re-design EmailPut consedering this. IMailDbContext shoud move to Abstraction layer (hint: in this case using DBSet in abst. will be problem because entity framework will have to be added. + public class EGDbContext : DbContext, IUserManagerDbContext, IMailDbContext { + public DbSet UserReceivers { get; set; } + + public DbSet Configs { get; set; } + + public DbSet EnvelopeReceivers { get; set; } + + public DbSet Envelopes { get; set; } + + public DbSet DocumentReceiverElements { get; set; } + + public DbSet DocumentStatus { get; set; } + + public DbSet EmailTemplate { get; set; } + + public DbSet EnvelopeCertificates { get; set; } + + public DbSet EnvelopeDocument { get; set; } + + public DbSet EnvelopeHistories { get; set; } + + public DbSet EnvelopeTypes { get; set; } + + public DbSet Receivers { get; set; } + + public DbSet GroupOfUsers { get; set; } + + public DbSet Groups { get; set; } + + public DbSet ModuleOfUsers { get; set; } + + public DbSet Modules { get; set; } + + public DbSet Users { get; set; } + + public DbSet UserReps { get; set; } + + public DbSet EMailOuts { get; set; } + public EGDbContext(DbContextOptions options) : base(options) { + UserReceivers = Set(); + Configs = Set(); + EnvelopeReceivers = Set(); + Envelopes = Set(); + DocumentReceiverElements = Set(); + DocumentStatus = Set(); + EnvelopeCertificates = Set(); + EnvelopeDocument = Set(); + EnvelopeHistories = Set(); + EnvelopeTypes = Set(); + Receivers = Set(); + + GroupOfUsers = Set(); + Groups = Set(); + ModuleOfUsers = Set(); + Modules = Set(); + Users = Set(); + UserReps = Set(); + EMailOuts = Set(); } protected override void OnModelCreating(ModelBuilder modelBuilder) diff --git a/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj b/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj index f81afd68..f295ff69 100644 --- a/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj +++ b/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj @@ -7,15 +7,16 @@ - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/EnvelopeGenerator.Infrastructure/Repositories/ConfigRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/ConfigRepository.cs index 6dc89ebb..bae012ae 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/ConfigRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/ConfigRepository.cs @@ -1,5 +1,4 @@ using DigitalData.Core.Infrastructure; -using DigitalData.UserManager.Infrastructure.Repositories; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; using Microsoft.EntityFrameworkCore; @@ -8,7 +7,7 @@ namespace EnvelopeGenerator.Infrastructure.Repositories { public class ConfigRepository : CRUDRepository, IConfigRepository { - public ConfigRepository(EGDbContext dbContext) : base(dbContext) + public ConfigRepository(EGDbContext dbContext) : base(dbContext, dbContext.Configs) { } diff --git a/EnvelopeGenerator.Infrastructure/Repositories/DocumentReceiverElementRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/DocumentReceiverElementRepository.cs index 0c7c5b55..a57bde74 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/DocumentReceiverElementRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/DocumentReceiverElementRepository.cs @@ -1,5 +1,4 @@ using DigitalData.Core.Infrastructure; -using DigitalData.UserManager.Infrastructure.Repositories; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; @@ -7,7 +6,7 @@ namespace EnvelopeGenerator.Infrastructure.Repositories { public class DocumentReceiverElementRepository : CRUDRepository, IDocumentReceiverElementRepository { - public DocumentReceiverElementRepository(EGDbContext dbContext) : base(dbContext) + public DocumentReceiverElementRepository(EGDbContext dbContext) : base(dbContext, dbContext.DocumentReceiverElements) { } } diff --git a/EnvelopeGenerator.Infrastructure/Repositories/DocumentStatusRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/DocumentStatusRepository.cs index 0bb95c99..e27e56a6 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/DocumentStatusRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/DocumentStatusRepository.cs @@ -7,7 +7,7 @@ namespace EnvelopeGenerator.Infrastructure.Repositories { public class DocumentStatusRepository : CRUDRepository, IDocumentStatusRepository { - public DocumentStatusRepository(EGDbContext dbContext) : base(dbContext) + public DocumentStatusRepository(EGDbContext dbContext) : base(dbContext, dbContext.DocumentStatus) { } } diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EmailTemplateRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EmailTemplateRepository.cs index dc80e97b..47772341 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EmailTemplateRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EmailTemplateRepository.cs @@ -1,5 +1,4 @@ using DigitalData.Core.Infrastructure; -using DigitalData.UserManager.Infrastructure.Repositories; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; using Microsoft.EntityFrameworkCore; @@ -12,7 +11,7 @@ namespace EnvelopeGenerator.Infrastructure.Repositories { private readonly IMemoryCache _cache; - public EmailTemplateRepository(EGDbContext dbContext, IMemoryCache cache) : base(dbContext) + public EmailTemplateRepository(EGDbContext dbContext, IMemoryCache cache) : base(dbContext, dbContext.EmailTemplate) { _cache = cache; } diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeCertificateRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeCertificateRepository.cs index 5cc4195e..6bc3c4a9 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeCertificateRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeCertificateRepository.cs @@ -1,5 +1,4 @@ using DigitalData.Core.Infrastructure; -using DigitalData.UserManager.Infrastructure.Repositories; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; @@ -7,7 +6,7 @@ namespace EnvelopeGenerator.Infrastructure.Repositories { public class EnvelopeCertificateRepository : CRUDRepository, IEnvelopeCertificateRepository { - public EnvelopeCertificateRepository(EGDbContext dbContext) : base(dbContext) + public EnvelopeCertificateRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeCertificates) { } } diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeDocumentRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeDocumentRepository.cs index 57fa4eee..25ff8949 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeDocumentRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeDocumentRepository.cs @@ -7,7 +7,7 @@ namespace EnvelopeGenerator.Infrastructure.Repositories { public class EnvelopeDocumentRepository : CRUDRepository, IEnvelopeDocumentRepository { - public EnvelopeDocumentRepository(EGDbContext dbContext) : base(dbContext) + public EnvelopeDocumentRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeDocument) { } } diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeHistoryRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeHistoryRepository.cs index 2c3c64c3..97dcfc37 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeHistoryRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeHistoryRepository.cs @@ -1,5 +1,4 @@ using DigitalData.Core.Infrastructure; -using DigitalData.UserManager.Infrastructure.Repositories; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; using Microsoft.EntityFrameworkCore; @@ -8,7 +7,7 @@ namespace EnvelopeGenerator.Infrastructure.Repositories { public class EnvelopeHistoryRepository : CRUDRepository, IEnvelopeHistoryRepository { - public EnvelopeHistoryRepository(EGDbContext dbContext) : base(dbContext) + public EnvelopeHistoryRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeHistories) { } diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeRepository.cs index 73ac63a0..40783bf2 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeRepository.cs @@ -1,5 +1,4 @@ using DigitalData.Core.Infrastructure; -using DigitalData.UserManager.Infrastructure.Repositories; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; using Microsoft.EntityFrameworkCore; @@ -8,13 +7,13 @@ namespace EnvelopeGenerator.Infrastructure.Repositories { public class EnvelopeRepository : CRUDRepository, IEnvelopeRepository { - public EnvelopeRepository(EGDbContext dbContext) : base(dbContext) + public EnvelopeRepository(EGDbContext dbContext) : base(dbContext, dbContext.Envelopes) { } public async Task> ReadAllWithAsync(bool documents = false, bool history = false, bool documentReceiverElement = false) { - var query = _dbSet.AsQueryable(); + var query = _dbSet.AsNoTracking(); if (documents) if (documentReceiverElement) @@ -30,7 +29,7 @@ namespace EnvelopeGenerator.Infrastructure.Repositories public async Task ReadByUuidAsync(string uuid, bool withDocuments = false, bool withHistory = false, bool withDocumentReceiverElement = false, bool withUser = false, bool withAll = false) { - var query = _dbSet.Where(e => e.Uuid == uuid); + var query = _dbSet.AsNoTracking().Where(e => e.Uuid == uuid); if (withAll || withDocuments) if (withAll || withDocumentReceiverElement) @@ -46,5 +45,21 @@ namespace EnvelopeGenerator.Infrastructure.Repositories return await query.FirstOrDefaultAsync(); } + + public async Task> ReadByUserAsync(int userId, int? min_status = null, int? max_status = null, params int[] ignore_statuses) + { + var query = _dbSet.AsNoTracking().Where(e => e.UserId == userId); + + if (min_status is not null) + query = query.Where(e => e.Status >= min_status); + + if (max_status is not null) + query = query.Where(e => e.Status <= max_status); + + foreach (var ignore_status in ignore_statuses) + query = query.Where(e => e.Status != ignore_status); + + return await query.ToListAsync(); + } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeTypeRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeTypeRepository.cs index 9b7533e3..5bc9f6c5 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeTypeRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvelopeTypeRepository.cs @@ -1,5 +1,4 @@ using DigitalData.Core.Infrastructure; -using DigitalData.UserManager.Infrastructure.Repositories; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; @@ -7,7 +6,7 @@ namespace EnvelopeGenerator.Infrastructure.Repositories { public class EnvelopeTypeRepository : CRUDRepository, IEnvelopeTypeRepository { - public EnvelopeTypeRepository(EGDbContext dbContext) : base(dbContext) + public EnvelopeTypeRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeTypes) { } } diff --git a/EnvelopeGenerator.Infrastructure/Repositories/EnvlopeReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/EnvlopeReceiverRepository.cs index 10b7012b..7b72f29e 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/EnvlopeReceiverRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/EnvlopeReceiverRepository.cs @@ -1,14 +1,13 @@ using DigitalData.Core.Infrastructure; -using DigitalData.UserManager.Infrastructure.Repositories; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; using Microsoft.EntityFrameworkCore; namespace EnvelopeGenerator.Infrastructure.Repositories { - public class EnvelopeReceiverRepository : CRUDRepository, IEnvelopeReceiverRepository + public class EnvelopeReceiverRepository : CRUDRepository, IEnvelopeReceiverRepository { - public EnvelopeReceiverRepository(EGDbContext dbContext) : base(dbContext) + public EnvelopeReceiverRepository(EGDbContext dbContext) : base(dbContext, dbContext.EnvelopeReceivers) { } @@ -76,5 +75,10 @@ namespace EnvelopeGenerator.Infrastructure.Repositories return await query.Include(er => er.Envelope).Include(er => er.Receiver).ToListAsync(); } + + public async Task ReadLastByReceiver(string email) + { + return await _dbSet.Where(er => er.Receiver!.EmailAddress == email).OrderBy(er => er.EnvelopeId).LastOrDefaultAsync(); + } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/ReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/ReceiverRepository.cs index 53ffb2ba..bccb6c1b 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/ReceiverRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/ReceiverRepository.cs @@ -7,11 +7,11 @@ namespace EnvelopeGenerator.Infrastructure.Repositories { public class ReceiverRepository : CRUDRepository, IReceiverRepository { - public ReceiverRepository(EGDbContext dbContext) : base(dbContext) + public ReceiverRepository(EGDbContext dbContext) : base(dbContext, dbContext.Receivers) { } - protected IQueryable ReadBy(string? emailAddress = null, string? signature = null) + protected IQueryable ReadBy(string? emailAddress = null, string? signature = null, bool withLastUsedName = true) { IQueryable query = _dbSet.AsNoTracking(); @@ -21,9 +21,17 @@ namespace EnvelopeGenerator.Infrastructure.Repositories if(signature is not null) query = query.Where(r => r.Signature == signature); + // envelope receivers are ignored (with '[JsonIgnore]' attribute). The reson to add them is to get the las used receiver name + if (withLastUsedName) + { + query = query.Include(r => r.EnvelopeReceivers!.OrderByDescending(er => er.EnvelopeId).Take(1)); + } + return query; } public async Task ReadByAsync(string? emailAddress = null, string? signature = null) => await ReadBy(emailAddress, signature).FirstOrDefaultAsync(); + + public async override Task> ReadAllAsync() => await ReadBy().ToListAsync(); } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Repositories/UserReceiverRepository.cs b/EnvelopeGenerator.Infrastructure/Repositories/UserReceiverRepository.cs index 2c5800ec..04bb30fa 100644 --- a/EnvelopeGenerator.Infrastructure/Repositories/UserReceiverRepository.cs +++ b/EnvelopeGenerator.Infrastructure/Repositories/UserReceiverRepository.cs @@ -1,5 +1,4 @@ using DigitalData.Core.Infrastructure; -using DigitalData.UserManager.Infrastructure.Repositories; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; @@ -7,7 +6,7 @@ namespace EnvelopeGenerator.Infrastructure.Repositories { public class UserReceiverRepository : CRUDRepository, IUserReceiverRepository { - public UserReceiverRepository(EGDbContext dbContext) : base(dbContext) + public UserReceiverRepository(EGDbContext dbContext) : base(dbContext, dbContext.UserReceivers) { } } diff --git a/EnvelopeGenerator.Web/Controllers/HomeController.cs b/EnvelopeGenerator.Web/Controllers/HomeController.cs index e8309e52..431901e7 100644 --- a/EnvelopeGenerator.Web/Controllers/HomeController.cs +++ b/EnvelopeGenerator.Web/Controllers/HomeController.cs @@ -10,11 +10,11 @@ using DigitalData.Core.API; using EnvelopeGenerator.Application; using Microsoft.Extensions.Localization; using DigitalData.Core.DTO; -using EnvelopeGenerator.Application.DTOs; using Microsoft.AspNetCore.Localization; using System.Text.Encodings.Web; using EnvelopeGenerator.Web.Models; using EnvelopeGenerator.Application.Resources; +using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; namespace EnvelopeGenerator.Web.Controllers { diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestConfigController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestConfigController.cs index ad7e0ec3..0117f542 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestConfigController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestConfigController.cs @@ -1,10 +1,11 @@ using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; +using DigitalData.Core.API; namespace EnvelopeGenerator.Web.Controllers.Test { - public class TestConfigController : TestControllerBase + public class TestConfigController : ReadControllerBase { public TestConfigController(ILogger logger, IConfigService service) : base(logger, service) { diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestControllerBase.cs b/EnvelopeGenerator.Web/Controllers/Test/TestControllerBase.cs index e39b0ed8..b92ae934 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestControllerBase.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestControllerBase.cs @@ -1,6 +1,7 @@ using DigitalData.Core.API; using DigitalData.Core.Abstractions.Application; using Microsoft.AspNetCore.Mvc; +using DigitalData.Core.Abstractions; namespace EnvelopeGenerator.Web.Controllers.Test { @@ -8,10 +9,10 @@ namespace EnvelopeGenerator.Web.Controllers.Test [Route("api/test/[controller]")] public class TestControllerBase : BasicCRUDControllerBase where TCRUDService : ICRUDService - where TDto : class where TEntity : class + where TDto : class, IUnique where TEntity : class, IUnique { public TestControllerBase(ILogger logger, TCRUDService service) : base(logger, service) { } } -} +} \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeMailController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeMailController.cs index 2840c53f..47f958b2 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeMailController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeMailController.cs @@ -1,12 +1,12 @@ using DigitalData.Core.DTO; using EnvelopeGenerator.Application.Contracts; -using EnvelopeGenerator.Application.DTOs; +using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using Microsoft.AspNetCore.Mvc; using System.Net; namespace EnvelopeGenerator.Web.Controllers.Test { - [ApiController] + [ApiController] [Route("api/test/[controller]")] public class TestEnvelopeMailController : ControllerBase { diff --git a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeReceiverController.cs b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeReceiverController.cs index c4a09eb7..592688de 100644 --- a/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeReceiverController.cs +++ b/EnvelopeGenerator.Web/Controllers/Test/TestEnvelopeReceiverController.cs @@ -1,14 +1,14 @@ using DigitalData.Core.API; using DigitalData.Core.DTO; using EnvelopeGenerator.Application.Contracts; -using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Application; using EnvelopeGenerator.Domain.Entities; using Microsoft.AspNetCore.Mvc; +using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; namespace EnvelopeGenerator.Web.Controllers.Test { - public class TestEnvelopeReceiverController : TestControllerBase + public class TestEnvelopeReceiverController : ReadControllerBase { public TestEnvelopeReceiverController(ILogger logger, IEnvelopeReceiverService service) : base(logger, service) { diff --git a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj index 8bed176f..53958473 100644 --- a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj +++ b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj @@ -38,9 +38,9 @@ - - - + + + @@ -64,7 +64,7 @@ - + diff --git a/EnvelopeGenerator.Web/Views/Home/EnvelopeRejected.cshtml b/EnvelopeGenerator.Web/Views/Home/EnvelopeRejected.cshtml index c007d932..7e7999ba 100644 --- a/EnvelopeGenerator.Web/Views/Home/EnvelopeRejected.cshtml +++ b/EnvelopeGenerator.Web/Views/Home/EnvelopeRejected.cshtml @@ -2,10 +2,10 @@ ViewData["Title"] = _localizer[WebKey.DocRejected]; } @{ - var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string; + var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string; } @using DigitalData.Core.DTO; -@using EnvelopeGenerator.Application.DTOs; +@using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver @using Newtonsoft.Json @using Newtonsoft.Json.Serialization @model EnvelopeReceiverDto; diff --git a/EnvelopeGenerator.Web/Views/Home/ShowEnvelope.cshtml b/EnvelopeGenerator.Web/Views/Home/ShowEnvelope.cshtml index 0eef600e..f7e3a972 100644 --- a/EnvelopeGenerator.Web/Views/Home/ShowEnvelope.cshtml +++ b/EnvelopeGenerator.Web/Views/Home/ShowEnvelope.cshtml @@ -2,11 +2,10 @@ var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string; var logo = _logoOpt.Value; } -@using DigitalData.Core.DTO; -@using EnvelopeGenerator.Application.DTOs; +@using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver @using Newtonsoft.Json @using Newtonsoft.Json.Serialization -@model EnvelopeReceiverDto; +@model EnvelopeReceiverDto @{ ViewData["Title"] = _localizer[WebKey.SignDoc]; } @@ -63,6 +62,12 @@ + + + + + +
@@ -99,16 +104,16 @@ } }); } -@if (ViewData["DocumentBytes"] is byte[] documentBytes) -{ - var settings = new JsonSerializerSettings + @if (ViewData["DocumentBytes"] is byte[] documentBytes) { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }; - var envelopeReceiverJson = JsonConvert.SerializeObject(Model, settings); - var documentBase64String = Convert.ToBase64String(documentBytes); - var envelopeKey = ViewData["EnvelopeKey"] as string; + var settings = new JsonSerializerSettings + { + @:document.addEventListener("DOMContentLoaded", async () => await new App("@envelopeKey.TrySanitize(_sanitizer)", @Html.Raw(envelopeReceiverJson.TrySanitize(_sanitizer)), B64ToBuff("@Html.Raw(documentBase64String.TrySanitize(_sanitizer))"), "@ViewData["PSPDFKitLicenseKey"]", "@userCulture?.Info?.TwoLetterISOLanguageName").init()) + } + 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.TrySanitize(_sanitizer)", @Html.Raw(envelopeReceiverJson.TrySanitize(_sanitizer)), B64ToBuff("@Html.Raw(documentBase64String.TrySanitize(_sanitizer))"), "@ViewData["PSPDFKitLicenseKey"]", "@userCulture?.Info?.TwoLetterISOLanguageName").init()) -} + @:document.addEventListener("DOMContentLoaded", async () => await new App("@envelopeKey.TrySanitize(_sanitizer)", @Html.Raw(envelopeReceiverJson.TrySanitize(_sanitizer)), B64ToBuff("@Html.Raw(documentBase64String.TrySanitize(_sanitizer))"), "@ViewData["PSPDFKitLicenseKey"]", "@userCulture?.Info?.TwoLetterISOLanguageName").init()) + } \ No newline at end of file