From 07f536938fd8db55f80f3004011166d56777e42d Mon Sep 17 00:00:00 2001 From: Anatolii Hrynchuk Date: Sun, 17 May 2026 11:43:25 +0300 Subject: [PATCH] feat: add filtering by `ServiceName` and `Key` in email templates query and UI --- .../Repositories/IEmailTemplateRepository.cs | 4 +-- .../Repositories/EmailTemplateRepository.cs | 16 ++++++++-- .../GetAll/GetAllEmailTemplatesHandler.cs | 2 +- .../GetAll/GetAllEmailTemplatesQuery.cs | 3 +- .../Admin/AdminTemplatesController.cs | 7 +++-- .../EmailTemplatesController.cs | 5 ++-- .../Views/AdminTemplates/Index.cshtml | 29 +++++++++++++++++++ 7 files changed, 56 insertions(+), 10 deletions(-) diff --git a/HrynCo.NotificationService.DAL.Abstract/Repositories/IEmailTemplateRepository.cs b/HrynCo.NotificationService.DAL.Abstract/Repositories/IEmailTemplateRepository.cs index b2cac8b..1bac856 100644 --- a/HrynCo.NotificationService.DAL.Abstract/Repositories/IEmailTemplateRepository.cs +++ b/HrynCo.NotificationService.DAL.Abstract/Repositories/IEmailTemplateRepository.cs @@ -4,10 +4,10 @@ namespace HrynCo.NotificationService.DAL.Abstract.Repositories; public interface IEmailTemplateRepository { - Task> GetAllAsync(CancellationToken ct = default); + Task> GetAllAsync(string? serviceName = null, string? key = null, CancellationToken ct = default); Task> GetByServiceAsync(string serviceName, CancellationToken ct = default); Task GetAsync(string serviceName, string key, string languageCode, CancellationToken ct = default); Task AddAsync(EmailTemplate template, CancellationToken ct = default); Task UpdateAsync(EmailTemplate template, CancellationToken ct = default); Task DeleteAsync(EmailTemplate template, CancellationToken ct = default); -} \ No newline at end of file +} diff --git a/HrynCo.NotificationService.DAL.EF/Repositories/EmailTemplateRepository.cs b/HrynCo.NotificationService.DAL.EF/Repositories/EmailTemplateRepository.cs index 148c3b1..b7fe3a9 100644 --- a/HrynCo.NotificationService.DAL.EF/Repositories/EmailTemplateRepository.cs +++ b/HrynCo.NotificationService.DAL.EF/Repositories/EmailTemplateRepository.cs @@ -13,9 +13,21 @@ internal sealed class EmailTemplateRepository { } - public async Task> GetAllAsync(CancellationToken ct = default) + public async Task> GetAllAsync(string? serviceName = null, string? key = null, CancellationToken ct = default) { - List entities = await EfRepository.Get() + IQueryable query = EfRepository.Get(); + + if (!string.IsNullOrWhiteSpace(serviceName)) + { + query = query.Where(x => x.ServiceName == serviceName); + } + + if (!string.IsNullOrWhiteSpace(key)) + { + query = query.Where(x => x.Key == key); + } + + List entities = await query .OrderBy(x => x.ServiceName).ThenBy(x => x.Key) .AsNoTracking() .ToListAsync(ct); diff --git a/HrynCo.NotificationService.Services/EmailTemplates/GetAll/GetAllEmailTemplatesHandler.cs b/HrynCo.NotificationService.Services/EmailTemplates/GetAll/GetAllEmailTemplatesHandler.cs index ac762f5..71954a2 100644 --- a/HrynCo.NotificationService.Services/EmailTemplates/GetAll/GetAllEmailTemplatesHandler.cs +++ b/HrynCo.NotificationService.Services/EmailTemplates/GetAll/GetAllEmailTemplatesHandler.cs @@ -22,7 +22,7 @@ internal sealed class GetAllEmailTemplatesHandler protected override async Task>> DoOnHandle( GetAllEmailTemplatesQuery request, CancellationToken cancellationToken) { - var templates = await _templates.GetAllAsync(cancellationToken); + var templates = await _templates.GetAllAsync(request.ServiceName, request.Key, cancellationToken); return Success(templates); } } diff --git a/HrynCo.NotificationService.Services/EmailTemplates/GetAll/GetAllEmailTemplatesQuery.cs b/HrynCo.NotificationService.Services/EmailTemplates/GetAll/GetAllEmailTemplatesQuery.cs index 7d9c13d..6718b43 100644 --- a/HrynCo.NotificationService.Services/EmailTemplates/GetAll/GetAllEmailTemplatesQuery.cs +++ b/HrynCo.NotificationService.Services/EmailTemplates/GetAll/GetAllEmailTemplatesQuery.cs @@ -4,4 +4,5 @@ using HrynCo.NotificationService.Services.Core; namespace HrynCo.NotificationService.Services.EmailTemplates.GetAll; -public sealed record GetAllEmailTemplatesQuery : IRequest>>; +public sealed record GetAllEmailTemplatesQuery(string? ServiceName = null, string? Key = null) + : IRequest>>; diff --git a/HrynCo.NotificationService.Web/Controllers/Admin/AdminTemplatesController.cs b/HrynCo.NotificationService.Web/Controllers/Admin/AdminTemplatesController.cs index f25b98a..c421397 100644 --- a/HrynCo.NotificationService.Web/Controllers/Admin/AdminTemplatesController.cs +++ b/HrynCo.NotificationService.Web/Controllers/Admin/AdminTemplatesController.cs @@ -23,9 +23,12 @@ public class AdminTemplatesController : Controller // GET /admin/templates [HttpGet("")] - public async Task Index(CancellationToken ct) + public async Task Index([FromQuery] string? serviceName, [FromQuery] string? key, CancellationToken ct) { - var result = await _mediator.Send(new GetAllEmailTemplatesQuery(), ct); + ViewData["ServiceNameFilter"] = serviceName; + ViewData["KeyFilter"] = key; + + var result = await _mediator.Send(new GetAllEmailTemplatesQuery(serviceName, key), ct); if (!result.IsSuccess) { ModelState.AddModelError("", result.Error?.Message ?? "Failed to load templates."); diff --git a/HrynCo.NotificationService.Web/Controllers/Api/EmailTemplates/EmailTemplatesController.cs b/HrynCo.NotificationService.Web/Controllers/Api/EmailTemplates/EmailTemplatesController.cs index 30bd332..e4b43f8 100644 --- a/HrynCo.NotificationService.Web/Controllers/Api/EmailTemplates/EmailTemplatesController.cs +++ b/HrynCo.NotificationService.Web/Controllers/Api/EmailTemplates/EmailTemplatesController.cs @@ -1,6 +1,7 @@ using HrynCo.NotificationService.Web.Infrastructure; using HrynCo.NotificationService.Services.EmailTemplates.Create; using HrynCo.NotificationService.Services.EmailTemplates.Delete; +using HrynCo.NotificationService.Services.EmailTemplates.GetAll; using HrynCo.NotificationService.Services.EmailTemplates.Get; using HrynCo.NotificationService.Services.EmailTemplates.GetByService; using HrynCo.NotificationService.Services.EmailTemplates.Update; @@ -15,9 +16,9 @@ public sealed class EmailTemplatesController : ApiControllerBase public EmailTemplatesController(IMediator mediator) : base(mediator) { } [HttpGet] - public async Task GetAll([FromQuery] string serviceName, CancellationToken cancellationToken) + public async Task GetAll([FromQuery] string? serviceName, [FromQuery] string? key, CancellationToken cancellationToken) { - var result = await Mediator.Send(new GetEmailTemplatesQuery(serviceName), cancellationToken); + var result = await Mediator.Send(new GetAllEmailTemplatesQuery(serviceName, key), cancellationToken); return FromServiceResult(result); } diff --git a/HrynCo.NotificationService.Web/Views/AdminTemplates/Index.cshtml b/HrynCo.NotificationService.Web/Views/AdminTemplates/Index.cshtml index ccc62f6..d16bf52 100644 --- a/HrynCo.NotificationService.Web/Views/AdminTemplates/Index.cshtml +++ b/HrynCo.NotificationService.Web/Views/AdminTemplates/Index.cshtml @@ -2,6 +2,8 @@ @model IReadOnlyList @{ ViewData["Title"] = "Email Templates"; + var serviceNameFilter = ViewData["ServiceNameFilter"] as string ?? string.Empty; + var keyFilter = ViewData["KeyFilter"] as string ?? string.Empty; } +
+
+
+
+ + +
+
+ + +
+
+ + Clear +
+
+
+
+ @if (!ViewData.ModelState.IsValid) {
-- 2.52.0