From c203b2cbdb3ce53d8403c6f76f44a1e39f8ded4f Mon Sep 17 00:00:00 2001 From: Brian Bicknell Date: Sat, 18 Apr 2026 21:39:58 -0400 Subject: [PATCH] Updated Blazor UI tag/creator views. Altered logic for sorting favorite/blacklisted fields for tags/creators. --- .../Creators/CreatorSearchProvider.cs | 4 +- .../Creator/CreatorSearchProviderTests.cs | 4 +- .../Search/Tag/TagSearchProviderTests.cs | 26 +++ .../Components/VoiceWorkFilters.razor | 14 +- JSMR.UI.Blazor/JSMR.UI.Blazor.csproj | 1 + JSMR.UI.Blazor/Layout/MainLayout.razor | 3 +- JSMR.UI.Blazor/Pages/Circles.razor | 6 +- JSMR.UI.Blazor/Pages/Creators.razor | 145 +++++++++--- JSMR.UI.Blazor/Pages/Tags.razor | 209 +++++++++++------- JSMR.UI.Blazor/Program.cs | 1 + JSMR.UI.Blazor/Services/ILookupDataService.cs | 1 + JSMR.UI.Blazor/Services/LookupDataService.cs | 13 ++ JSMR.UI.Blazor/wwwroot/index.html | 1 + 13 files changed, 308 insertions(+), 120 deletions(-) diff --git a/JSMR.Infrastructure/Data/Repositories/Creators/CreatorSearchProvider.cs b/JSMR.Infrastructure/Data/Repositories/Creators/CreatorSearchProvider.cs index 97e9a5d..df8cb44 100644 --- a/JSMR.Infrastructure/Data/Repositories/Creators/CreatorSearchProvider.cs +++ b/JSMR.Infrastructure/Data/Repositories/Creators/CreatorSearchProvider.cs @@ -44,8 +44,8 @@ public class CreatorSearchProvider(AppDbContext context) : SearchProvider> selector = field switch { CreatorSortField.VoiceWorkCount => x => x.VoiceWorkCount, - CreatorSortField.Favorite => x => !x.Favorite, - CreatorSortField.Blacklisted => x => !x.Blacklisted, + CreatorSortField.Favorite => x => x.Favorite, + CreatorSortField.Blacklisted => x => x.Blacklisted, _ => x => x.Name }; diff --git a/JSMR.Tests/Search/Creator/CreatorSearchProviderTests.cs b/JSMR.Tests/Search/Creator/CreatorSearchProviderTests.cs index 761462a..deced80 100644 --- a/JSMR.Tests/Search/Creator/CreatorSearchProviderTests.cs +++ b/JSMR.Tests/Search/Creator/CreatorSearchProviderTests.cs @@ -54,7 +54,7 @@ public class CreatorSearchProviderTests(CreatorSearchProviderFixture fixture) : { var options = new SearchOptions() { - SortOptions = [new(CreatorSortField.Favorite, SortDirection.Ascending)] + SortOptions = [new(CreatorSortField.Favorite, SortDirection.Descending)] }; var result = await SearchAsync(options); @@ -67,7 +67,7 @@ public class CreatorSearchProviderTests(CreatorSearchProviderFixture fixture) : { var options = new SearchOptions() { - SortOptions = [new(CreatorSortField.Blacklisted, SortDirection.Ascending)] + SortOptions = [new(CreatorSortField.Blacklisted, SortDirection.Descending)] }; var result = await SearchAsync(options); diff --git a/JSMR.Tests/Search/Tag/TagSearchProviderTests.cs b/JSMR.Tests/Search/Tag/TagSearchProviderTests.cs index 5babf1c..00df4d7 100644 --- a/JSMR.Tests/Search/Tag/TagSearchProviderTests.cs +++ b/JSMR.Tests/Search/Tag/TagSearchProviderTests.cs @@ -84,4 +84,30 @@ public class TagSearchProviderTests(TagSearchProviderFixture fixture) : IClassFi result.TotalItems.ShouldBe(1); result.Items.ShouldContain(tagView => tagView.EnglishName == "Heartwarming"); } + + [Fact] + public async Task Filter_None_Sort_Favorite_Descending() + { + var options = new SearchOptions() + { + SortOptions = [new(TagSortField.Favorite, SortDirection.Descending)] + }; + + var result = await SearchAsync(options); + + result.Items[0].EnglishName.ShouldBe("Heartwarming"); + } + + [Fact] + public async Task Filter_None_Sort_Blacklisted_Descending() + { + var options = new SearchOptions() + { + SortOptions = [new(TagSortField.Blacklisted, SortDirection.Descending)] + }; + + var result = await SearchAsync(options); + + result.Items[0].EnglishName.ShouldBe("Tsundere"); + } } \ No newline at end of file diff --git a/JSMR.UI.Blazor/Components/VoiceWorkFilters.razor b/JSMR.UI.Blazor/Components/VoiceWorkFilters.razor index 9721521..cb4fdfe 100644 --- a/JSMR.UI.Blazor/Components/VoiceWorkFilters.razor +++ b/JSMR.UI.Blazor/Components/VoiceWorkFilters.razor @@ -5,6 +5,7 @@ @using JSMR.UI.Blazor.Enums @using JSMR.UI.Blazor.Filters @using JSMR.UI.Blazor.Services +@using AntDesign
@@ -59,9 +60,18 @@ Value="@Value.SaleStatus" ValueChanged="@(value => Update(Value with { SaleStatus = value }))"> - + + @* *@
> locales = []; List> saleStatuses = []; + List> saleStatuses2 = []; List> circleStatuses = []; List> tagStatuses = []; List> creatorStatuses = []; @@ -242,6 +253,7 @@ { locales = Lookups.GetLocales(); saleStatuses = Lookups.GetSaleStatuses(); + saleStatuses2 = Lookups.GetSaleStatuses2(); circleStatuses = Lookups.GetCircleStatuses(); tagStatuses = Lookups.GetTagStatuses(); creatorStatuses = Lookups.GetCreatorStatuses(); diff --git a/JSMR.UI.Blazor/JSMR.UI.Blazor.csproj b/JSMR.UI.Blazor/JSMR.UI.Blazor.csproj index d1ff082..47fe8e3 100644 --- a/JSMR.UI.Blazor/JSMR.UI.Blazor.csproj +++ b/JSMR.UI.Blazor/JSMR.UI.Blazor.csproj @@ -10,6 +10,7 @@ + diff --git a/JSMR.UI.Blazor/Layout/MainLayout.razor b/JSMR.UI.Blazor/Layout/MainLayout.razor index 824da10..5d42a7b 100644 --- a/JSMR.UI.Blazor/Layout/MainLayout.razor +++ b/JSMR.UI.Blazor/Layout/MainLayout.razor @@ -8,7 +8,7 @@ - + JSMR @* *@ @@ -52,6 +52,7 @@ + @code{ private bool _open = false; diff --git a/JSMR.UI.Blazor/Pages/Circles.razor b/JSMR.UI.Blazor/Pages/Circles.razor index b229f77..13d49ab 100644 --- a/JSMR.UI.Blazor/Pages/Circles.razor +++ b/JSMR.UI.Blazor/Pages/Circles.razor @@ -39,15 +39,15 @@ else @if (item.Favorite) { - Favorite + Favorite } else if (item.Blacklisted) { - Blacklisted + Blacklisted } else if (item.Spam) { - Spam + Spam } else { diff --git a/JSMR.UI.Blazor/Pages/Creators.razor b/JSMR.UI.Blazor/Pages/Creators.razor index 927d201..4f420ab 100644 --- a/JSMR.UI.Blazor/Pages/Creators.razor +++ b/JSMR.UI.Blazor/Pages/Creators.razor @@ -13,37 +13,48 @@ -@if (searchResults is null) -{ -

Loading…

-} -else if (searchResults.Items.Length == 0) -{ -

No results.

-} -else -{ - - - Name - Voice Works - Favorite - Blacklisted - - - @context.Name - @context.VoiceWorkCount - - - - - - - - - -} + + + + + + @if (context.Favorite) + { + Favorite + } + + + @if (context.Blacklisted) + { + Blacklisted + } + + @* + + + + + Some Menu Item + + + + + + + + *@ + + + + @code { - private string? keywords; + public string? Keywords { get; set; } + public int PageNumber { get; set; } = 1; + public int PageSize { get; set; } = 100; + public int TotalItems => searchResults?.TotalItems ?? 0; - public string? Keywords - { - get { return keywords; } - set - { - keywords = value; - _ = UpdateDataAsync(true); - } - } - - private int pageNumber = 1; - - public int PageNumber - { - get { return pageNumber; } - set - { - pageNumber = value; - _ = UpdateDataAsync(false); - } - } - - int pageSize = 100; - - public int PageSize - { - get { return pageSize; } - set - { - pageSize = value; - _ = UpdateDataAsync(true); - } - } + public bool LoadingData { get; set; } SearchResult? searchResults; - protected override Task OnInitializedAsync() + protected override async Task OnInitializedAsync() { - _ = LoadTagsAsync(); + //await UpdateDataAsync(true); + } - return Task.CompletedTask; + public async Task OnKeywordsChanged(string? newKeywords) + { + Keywords = newKeywords; + await UpdateDataAsync(true); + } + + public async Task OnPageNumberChanged(int newPageNumber) + { + PageNumber = newPageNumber; + await UpdateDataAsync(false); + } + + public async Task OnPageSizeChanged(int newPageSize) + { + PageSize = newPageSize; + await UpdateDataAsync(true); } private async Task UpdateDataAsync(bool resetPageNumber) { if (resetPageNumber) - pageNumber = 1; + PageNumber = 1; await LoadTagsAsync(); } private async Task LoadTagsAsync() { + LoadingData = true; + SearchTagsRequest request = new( Options: new() { PageNumber = PageNumber, - PageSize = pageSize, + PageSize = PageSize, Criteria = new() { Name = Keywords }, - SortOptions = - [ - new(TagSortField.Name, Application.Common.Search.SortDirection.Ascending) - ] + SortOptions = [.. _sortOptions] } ); @@ -138,11 +134,72 @@ else searchResults = result?.Results ?? new(); - await InvokeAsync(StateHasChanged); + LoadingData = false; + + //await InvokeAsync(StateHasChanged); } - private void IncrementCount(TagSearchItem item) + private List> _sortOptions = + [ + new(TagSortField.Name, Application.Common.Search.SortDirection.Ascending) + ]; + + private async Task HandleTableChange(AntDesign.TableModels.QueryModel queryModel) { - //item.Favorite = !item.Favorite; + //PageNumber = queryModel.PageIndex; + //PageSize = queryModel.PageSize; + + _sortOptions = MapSortOptions(queryModel); + + await LoadTagsAsync(); + } + + private List> MapSortOptions(AntDesign.TableModels.QueryModel queryModel) + { + var requestedSorts = queryModel.SortModel + .Select(sort => new + { + Field = sort.FieldName switch + { + nameof(TagSearchItem.Favorite) => TagSortField.Favorite, + nameof(TagSearchItem.Blacklisted) => TagSortField.Blacklisted, + nameof(TagSearchItem.VoiceWorkCount) => TagSortField.VoiceWorkCount, + nameof(TagSearchItem.EnglishName) => TagSortField.EnglishName, + nameof(TagSearchItem.Name) => TagSortField.Name, + _ => (TagSortField?)null + }, + Direction = sort.SortDirection switch + { + AntDesign.SortDirection.Ascending => Application.Common.Search.SortDirection.Ascending, + AntDesign.SortDirection.Descending => Application.Common.Search.SortDirection.Descending, + _ => (Application.Common.Search.SortDirection?)null + } + }) + .Where(x => x.Field is not null && x.Direction is not null) + .ToDictionary(x => x.Field!.Value, x => x.Direction!.Value); + + var finalSorts = new List>(); + + // Force your preferred precedence + if (requestedSorts.TryGetValue(TagSortField.Favorite, out var favoriteDir)) + finalSorts.Add(new(TagSortField.Favorite, favoriteDir)); + + if (requestedSorts.TryGetValue(TagSortField.Blacklisted, out var blacklistedDir)) + finalSorts.Add(new(TagSortField.Blacklisted, blacklistedDir)); + + if (requestedSorts.TryGetValue(TagSortField.VoiceWorkCount, out var countDir)) + finalSorts.Add(new(TagSortField.VoiceWorkCount, countDir)); + + if (requestedSorts.TryGetValue(TagSortField.EnglishName, out var englishNameDir)) + finalSorts.Add(new(TagSortField.EnglishName, englishNameDir)); + + if (requestedSorts.TryGetValue(TagSortField.Name, out var nameDir)) + finalSorts.Add(new(TagSortField.Name, nameDir)); + + // Default fallback + if (finalSorts.Count == 0) + finalSorts.Add(new(TagSortField.Name, Application.Common.Search.SortDirection.Ascending)); + + return finalSorts; } } \ No newline at end of file diff --git a/JSMR.UI.Blazor/Program.cs b/JSMR.UI.Blazor/Program.cs index 2edcfde..5f8d2a5 100644 --- a/JSMR.UI.Blazor/Program.cs +++ b/JSMR.UI.Blazor/Program.cs @@ -47,6 +47,7 @@ builder.Services.AddScoped(); builder.Services.AddMudServices(); builder.Services.AddRadzenComponents(); builder.Services.AddBitBlazorUIServices(); +builder.Services.AddAntDesign(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/JSMR.UI.Blazor/Services/ILookupDataService.cs b/JSMR.UI.Blazor/Services/ILookupDataService.cs index 48b52dc..3bf2c16 100644 --- a/JSMR.UI.Blazor/Services/ILookupDataService.cs +++ b/JSMR.UI.Blazor/Services/ILookupDataService.cs @@ -10,6 +10,7 @@ public interface ILookupDataService { List> GetLocales(); List> GetSaleStatuses(); + List> GetSaleStatuses2(); List> GetCircleStatuses(); List> GetTagStatuses(); List> GetCreatorStatuses(); diff --git a/JSMR.UI.Blazor/Services/LookupDataService.cs b/JSMR.UI.Blazor/Services/LookupDataService.cs index 7c86049..63409bf 100644 --- a/JSMR.UI.Blazor/Services/LookupDataService.cs +++ b/JSMR.UI.Blazor/Services/LookupDataService.cs @@ -29,6 +29,13 @@ public sealed class LookupDataService(VoiceWorksClient client) : ILookupDataServ new() { Text = "All", Value = null } ]; + public List> GetSaleStatuses2() => + [ + new() { Label = "Available", Value = SaleStatus.Available }, + new() { Label = "Upcoming", Value = SaleStatus.Upcoming }, + new() { Label = "All", Value = null } + ]; + public List> GetCircleStatuses() => [ new() { Text = "Not Blacklisted", Value = CircleStatus.NotBlacklisted }, @@ -131,4 +138,10 @@ public sealed class LookupDataService(VoiceWorksClient client) : ILookupDataServ return _creators; } +} + +public class SelectOption +{ + public string? Label { get; set; } + public T? Value { get; set; } } \ No newline at end of file diff --git a/JSMR.UI.Blazor/wwwroot/index.html b/JSMR.UI.Blazor/wwwroot/index.html index dfdab8f..91fbdc1 100644 --- a/JSMR.UI.Blazor/wwwroot/index.html +++ b/JSMR.UI.Blazor/wwwroot/index.html @@ -23,6 +23,7 @@ +