diff --git a/src/Application/Features/AuditTrails/Queries/PaginationQuery/AuditTrailsWithPaginationQuery.cs b/src/Application/Features/AuditTrails/Queries/PaginationQuery/AuditTrailsWithPaginationQuery.cs index 70306915f..512257f2c 100644 --- a/src/Application/Features/AuditTrails/Queries/PaginationQuery/AuditTrailsWithPaginationQuery.cs +++ b/src/Application/Features/AuditTrails/Queries/PaginationQuery/AuditTrailsWithPaginationQuery.cs @@ -1,8 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Globalization; +using System.Linq.Expressions; +using System.Reflection; using CleanArchitecture.Blazor.Application.Features.AuditTrails.Caching; using CleanArchitecture.Blazor.Application.Features.AuditTrails.DTOs; +using CleanArchitecture.Blazor.Application.Features.Products.Queries; namespace CleanArchitecture.Blazor.Application.Features.AuditTrails.Queries.PaginationQuery; @@ -13,9 +17,11 @@ public class AuditTrailsWithPaginationQuery : PaginationFilterBase, ICacheableRe public string? Keyword { get; set; } [OperatorComparison(OperatorType.Equal)] public AuditType? AuditType { get; set; } + [CompareTo(typeof(SearchAuditTrailsWithListView),"Id")] + public AuditTrailListView ListView { get; set; }= AuditTrailListView.All; public override string ToString() { - return $"Search:{Keyword},Sort:{Sort},SortBy:{SortBy},{Page},{PerPage}"; + return $"Listview:{ListView},AuditType:{AuditType},Search:{Keyword},Sort:{Sort},SortBy:{SortBy},{Page},{PerPage}"; } public string CacheKey => AuditTrailsCacheKey.GetPaginationCacheKey($"{this}"); public MemoryCacheEntryOptions? Options => AuditTrailsCacheKey.MemoryCacheEntryOptions; @@ -45,6 +51,42 @@ public async Task> Handle(AuditTrailsWithPagination return data; } + - } +public class SearchAuditTrailsWithListView : FilteringOptionsBaseAttribute +{ + public override Expression BuildExpression(Expression expressionBody, PropertyInfo targetProperty, PropertyInfo filterProperty, object value) + { + var today = DateTime.Now.Date; + var start = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", CultureInfo.CurrentCulture); + var end = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 23:59:59", CultureInfo.CurrentCulture); + var last30days= Convert.ToDateTime(today.AddDays(-30).ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", CultureInfo.CurrentCulture); + //var currentUser = filterProperty.CurrentUser; + var listview = (AuditTrailListView)value; + return listview switch + { + AuditTrailListView.All => expressionBody, + AuditTrailListView.Last30days => Expression.GreaterThanOrEqual(Expression.Property(expressionBody, "DateTime"), + Expression.Constant(last30days, typeof(DateTime))) + .Combine(Expression.LessThanOrEqual(Expression.Property(expressionBody, "DateTime"), + Expression.Constant(end, typeof(DateTime))), + CombineType.And), + AuditTrailListView.CreatedToday => Expression.GreaterThanOrEqual(Expression.Property(expressionBody, "DateTime"), + Expression.Constant(start, typeof(DateTime))) + .Combine(Expression.LessThanOrEqual(Expression.Property(expressionBody, "DateTime"), + Expression.Constant(end, typeof(DateTime))), + CombineType.And), + _ => expressionBody + }; + } +} +public enum AuditTrailListView +{ + [Description("All")] + All, + [Description("Created Toady")] + CreatedToday, + [Description("View of the last 30 days")] + Last30days, +} \ No newline at end of file diff --git a/src/Application/Features/KeyValues/Queries/PaginationQuery/KeyValuesWithPaginationQuery.cs b/src/Application/Features/KeyValues/Queries/PaginationQuery/KeyValuesWithPaginationQuery.cs index d3ab26ca8..67a05448b 100644 --- a/src/Application/Features/KeyValues/Queries/PaginationQuery/KeyValuesWithPaginationQuery.cs +++ b/src/Application/Features/KeyValues/Queries/PaginationQuery/KeyValuesWithPaginationQuery.cs @@ -13,7 +13,13 @@ public class KeyValuesWithPaginationQuery : PaginationFilterBase, ICacheableRequ [StringFilterOptions(StringFilterOption.Contains)] public string? Keyword { get; set; } [OperatorComparison(OperatorType.Equal)] + [CompareTo("Name")] public Picklist? Picklist { get; set; } + + public override string ToString() + { + return $"Picklist:{Picklist},Search:{Keyword},Sort:{Sort},SortBy:{SortBy},{Page},{PerPage}"; + } public string CacheKey => $"{nameof(KeyValuesWithPaginationQuery)},{this}"; public MemoryCacheEntryOptions? Options => KeyValueCacheKey.MemoryCacheEntryOptions; diff --git a/src/Application/Features/Loggers/Queries/PaginationQuery/LogsWithPaginationQuery.cs b/src/Application/Features/Loggers/Queries/PaginationQuery/LogsWithPaginationQuery.cs index ff26241ac..5da4041bc 100644 --- a/src/Application/Features/Loggers/Queries/PaginationQuery/LogsWithPaginationQuery.cs +++ b/src/Application/Features/Loggers/Queries/PaginationQuery/LogsWithPaginationQuery.cs @@ -1,46 +1,97 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using CleanArchitecture.Blazor.Application.Features.AuditTrails.Caching; -using CleanArchitecture.Blazor.Application.Features.Documents.Caching; +using System.Globalization; +using System.Linq.Expressions; +using System.Reflection; using CleanArchitecture.Blazor.Application.Features.Loggers.Caching; using CleanArchitecture.Blazor.Application.Features.Loggers.DTOs; namespace CleanArchitecture.Blazor.Application.Logs.Queries.PaginationQuery; -public class LogsWithPaginationQuery : PaginationFilter, ICacheableRequest> +public class LogsWithPaginationQuery : PaginationFilterBase, ICacheableRequest> { + [CompareTo("Message", "Exception", "UserName", "ClientIP")] + [StringFilterOptions(StringFilterOption.Contains)] + public string? Keyword { get; set; } + + [CompareTo(typeof(SearchLogsWithListView), "Id")] + public LogListView ListView { get; set; } = LogListView.All; + public override string ToString() + { + return $"Listview:{ListView},Search:{Keyword},Sort:{Sort},SortBy:{SortBy},{Page},{PerPage}"; + } public string CacheKey => LogsCacheKey.GetPaginationCacheKey($"{this}"); public MemoryCacheEntryOptions? Options => LogsCacheKey.MemoryCacheEntryOptions; } public class LogsQueryHandler : IRequestHandler> { - private readonly ICurrentUserService _currentUserService; private readonly IApplicationDbContext _context; private readonly IMapper _mapper; public LogsQueryHandler( - ICurrentUserService currentUserService, IApplicationDbContext context, IMapper mapper ) { - _currentUserService = currentUserService; _context = context; _mapper = mapper; } public async Task> Handle(LogsWithPaginationQuery request, CancellationToken cancellationToken) { - - - var data = await _context.Loggers - .Where(x=>x.Message!.Contains(request.Keyword) || x.Exception!.Contains(request.Keyword)) - .OrderBy($"{request.OrderBy} {request.SortDirection}") - .ProjectTo(_mapper.ConfigurationProvider) - .PaginatedDataAsync(request.PageNumber, request.PageSize); + var data = await _context.Loggers.ApplyFilterWithoutPagination(request) + .ProjectTo(_mapper.ConfigurationProvider) + .PaginatedDataAsync(request.Page, request.PerPage); return data; } + - +} +public class SearchLogsWithListView : FilteringOptionsBaseAttribute +{ + public override Expression BuildExpression(Expression expressionBody, PropertyInfo targetProperty, PropertyInfo filterProperty, object value) + { + var today = DateTime.Now.Date; + var start = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", CultureInfo.CurrentCulture); + var end = Convert.ToDateTime(today.ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 23:59:59", CultureInfo.CurrentCulture); + var last30days = Convert.ToDateTime(today.AddDays(-30).ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", CultureInfo.CurrentCulture); + var listview = (LogListView)value; + return listview switch + { + LogListView.All => expressionBody, + LogListView.Information => Expression.Equal(Expression.Property(expressionBody, "Level"),Expression.Constant("Information")), + LogListView.Warning => Expression.Equal(Expression.Property(expressionBody, "Level"), Expression.Constant("Warning")), + LogListView.Fatal => Expression.Equal(Expression.Property(expressionBody, "Level"), Expression.Constant("Fatal")), + LogListView.Error => Expression.Equal(Expression.Property(expressionBody, "Level"), Expression.Constant("Error")), + LogListView.Last30days => Expression.GreaterThanOrEqual(Expression.Property(expressionBody, "TimeStamp"), + Expression.Constant(last30days, typeof(DateTime))) + .Combine(Expression.LessThanOrEqual(Expression.Property(expressionBody, "TimeStamp"), + Expression.Constant(end, typeof(DateTime))), + CombineType.And), + LogListView.CreatedToday => Expression.GreaterThanOrEqual(Expression.Property(expressionBody, "TimeStamp"), + Expression.Constant(start, typeof(DateTime))) + .Combine(Expression.LessThanOrEqual(Expression.Property(expressionBody, "TimeStamp"), + Expression.Constant(end, typeof(DateTime))), + CombineType.And), + _ => expressionBody + }; + } +} +public enum LogListView +{ + [Description("All")] + All, + [Description("Created Toady")] + CreatedToday, + [Description("View of the last 30 days")] + Last30days, + [Description("View of Information")] + Information, + [Description("View of Warning")] + Warning, + [Description("View of Error")] + Error, + [Description("View of Fatal")] + Fatal, } diff --git a/src/Blazor.Server.UI/Pages/SystemManagement/AuditTrails.razor b/src/Blazor.Server.UI/Pages/SystemManagement/AuditTrails.razor index bc0dad31b..d1f5ebd62 100644 --- a/src/Blazor.Server.UI/Pages/SystemManagement/AuditTrails.razor +++ b/src/Blazor.Server.UI/Pages/SystemManagement/AuditTrails.razor @@ -29,7 +29,8 @@
@L[Title] - + +
@@ -42,13 +43,13 @@ StartIcon="@Icons.Material.Filled.Refresh" IconColor="Color.Surface" Color="Color.Primary" Style="margin-right: 5px;">@ConstantString.REFRESH
- - - - + + - - + + @@ -110,7 +111,7 @@ @context.OldValues - + New Value @@ -140,29 +141,24 @@ @code { public string Title { get; private set; } = "Audit Trails"; - private string _searchString = string.Empty; - private AuditType? _searchAuditType = null; private MudTable _table = default!; private bool _loading; private int _defaultPageSize = 15; [Inject] private IMediator _mediator { get; set; } = default!; - + private AuditTrailsWithPaginationQuery _query = new(); private async Task> ServerReload(TableState state) { try { _loading = true; - var request = new AuditTrailsWithPaginationQuery() - { - Keyword = _searchString, - AuditType = _searchAuditType, - Sort = string.IsNullOrEmpty(state.SortLabel) ? "Id" : state.SortLabel, - SortBy = (state.SortDirection == SortDirection.Ascending ? AutoFilterer.Enums.Sorting.Ascending : AutoFilterer.Enums.Sorting.Descending), - Page = state.Page + 1, - PerPage = state.PageSize - }; - var result = await _mediator.Send(request).ConfigureAwait(false); + + _query.Sort = string.IsNullOrEmpty(state.SortLabel) ? "Id" : state.SortLabel; + _query.SortBy = (state.SortDirection == SortDirection.Ascending ? AutoFilterer.Enums.Sorting.Ascending : AutoFilterer.Enums.Sorting.Descending); + _query.Page = state.Page + 1; + _query.PerPage = state.PageSize; + + var result = await _mediator.Send(_query).ConfigureAwait(false); return new TableData() { TotalItems = result.TotalItems, Items = result.Items }; } finally @@ -170,20 +166,25 @@ _loading = false; } } + private async Task OnChangedListView(AuditTrailListView listview) + { + _query.ListView = listview; + await _table.ReloadServerData(); + } private async Task OnSearch(string text) { - _searchString = text; + _query.Keyword = text; await _table.ReloadServerData(); } private async Task OnSearch(AuditType? val) { - _searchAuditType = val; + _query.AuditType = val; await _table.ReloadServerData(); } private async Task OnRefresh() { AuditTrailsCacheKey.Refresh(); - _searchString = string.Empty; + _query.Keyword = string.Empty; await _table.ReloadServerData(); } private Task OnShowDetail(AuditTrailDto dto) diff --git a/src/Blazor.Server.UI/Pages/SystemManagement/Dictionaries.razor b/src/Blazor.Server.UI/Pages/SystemManagement/Dictionaries.razor index eb0f12d04..73c5e47f8 100644 --- a/src/Blazor.Server.UI/Pages/SystemManagement/Dictionaries.razor +++ b/src/Blazor.Server.UI/Pages/SystemManagement/Dictionaries.razor @@ -129,27 +129,26 @@ } - - @ConstantString.REFRESH - @if (_canCreate) - { - @ConstantString.CREATE - } - @if (_canDelete) - { - @ConstantString.DELETE - } - @if (_canImport) - { - + @if (_canCreate) + { + @ConstantString.CREATE + } + @if (_canDelete) + { + @ConstantString.DELETE + } @if (_canSearch) diff --git a/src/Blazor.Server.UI/Pages/SystemManagement/Logs.razor b/src/Blazor.Server.UI/Pages/SystemManagement/Logs.razor index ebc4eaf2a..eca2e3af8 100644 --- a/src/Blazor.Server.UI/Pages/SystemManagement/Logs.razor +++ b/src/Blazor.Server.UI/Pages/SystemManagement/Logs.razor @@ -31,7 +31,8 @@
@L["Logs"] - + +
@@ -66,7 +67,7 @@ }
- @@ -192,6 +193,7 @@ [Inject] private IMediator _mediator { get; set; } = default!; private bool _canPurge; + private LogsWithPaginationQuery _query = new(); protected override async void OnInitialized() { Title = L["Logs"]; @@ -214,15 +216,11 @@ try { _loading = true; - var request = new LogsWithPaginationQuery() - { - Keyword = _searchString, - OrderBy = string.IsNullOrEmpty(state.SortLabel) ? "Id" : state.SortLabel, - SortDirection = (state.SortDirection == SortDirection.None ? SortDirection.Descending.ToString() : state.SortDirection.ToString()), - PageNumber = state.Page + 1, - PageSize = state.PageSize - }; - var result = await _mediator.Send(request).ConfigureAwait(false); + _query.Sort = string.IsNullOrEmpty(state.SortLabel) ? "Id" : state.SortLabel; + _query.SortBy = (state.SortDirection == SortDirection.Ascending ? AutoFilterer.Enums.Sorting.Ascending : AutoFilterer.Enums.Sorting.Descending); + _query.Page = state.Page + 1; + _query.PerPage = state.PageSize; + var result = await _mediator.Send(_query).ConfigureAwait(false); return new TableData() { TotalItems = result.TotalItems, Items = result.Items }; } finally @@ -230,14 +228,19 @@ _loading = false; } } + private async Task OnChangedListView(LogListView listview) + { + _query.ListView = listview; + await _table.ReloadServerData(); + } private async Task OnSearch(string text) { - _searchString = text; + _query.Keyword = text; await _table.ReloadServerData(); } private async Task OnRefresh() { - _searchString = string.Empty; + _query.Keyword = string.Empty; await _table.ReloadServerData(); } private Task OnShowDetail(LogDto dto)