feature/apply-filter #18
@@ -25,8 +25,8 @@
|
||||
<SelectSearch TItem="int" Placeholder="@ResourcesKey.ReleaseDate" GetLabel="@(p => p.ToString())"
|
||||
@bind-Values=GameFilter.ReleaseYears @bind-Values:after=HandleValueChanged Theme="Theme" Items="Categories?.ReleaseYears" />
|
||||
|
||||
<SelectSearch TItem="StorageSpaceDto" Placeholder="@ResourcesKey.StorageSize" GetLabel="@GetStorageSpaceLabel"
|
||||
@bind-Values=GameFilter.StorageSpaces @bind-Values:after=HandleValueChanged Theme="Theme" Items="StorageSpaces" />
|
||||
<SelectSearch TItem="int" Placeholder="@ResourcesKey.StorageSize" GetLabel="@GetStorageSpaceLabel"
|
||||
@bind-Values=GameFilter.StorageSpaceIds @bind-Values:after=HandleValueChanged Theme="Theme" Items="@(Categories?.StorageSpaces?.Select(stor => stor.Id).ToList())" />
|
||||
|
||||
<span class="title">@ResourcesKey.LastAdd</span>
|
||||
</div>
|
||||
|
||||
@@ -14,34 +14,27 @@ public partial class AdvancedGameFilter
|
||||
[Parameter] public EventCallback<GameFilterParams> GameFilterChanged { get; set; }
|
||||
|
||||
private readonly SelectTheme Theme = SelectTheme.AdvancedFilter;
|
||||
private readonly List<StorageSpaceDto> StorageSpaces = [
|
||||
new() { MaxSize = 100 },
|
||||
new() { MinSize = 100, MaxSize = 1000 },
|
||||
new() { MinSize = 1000, MaxSize = 5000 },
|
||||
new() { MinSize = 5000, MaxSize = 10000 },
|
||||
new() { MinSize = 10000, MaxSize = 20000 },
|
||||
new() { MinSize = 20000, MaxSize = 40000 },
|
||||
new() { MinSize = 40000, MaxSize = 100000 },
|
||||
new() { MinSize = 100000 },
|
||||
];
|
||||
|
||||
private async Task HandleValueChanged()
|
||||
{
|
||||
await GameFilterChanged.InvokeAsync(GameFilter);
|
||||
}
|
||||
|
||||
private static string GetStorageSpaceLabel(StorageSpaceDto storageSpace)
|
||||
private string GetStorageSpaceLabel(int storageSpaceId)
|
||||
{
|
||||
var storageSpace = Categories?.StorageSpaces?.FirstOrDefault(c => c.Id == storageSpaceId)
|
||||
?? throw new ArgumentNullException(ResourcesKey.ErrorStorageSpaceLabel);
|
||||
|
||||
if (storageSpace.MinSize == null && storageSpace.MaxSize != null)
|
||||
{
|
||||
return string.Format(ResourcesKey.MinStorageSpaceFormat,
|
||||
GameHelper.GetFormatedStorageSpace(storageSpace.MinSize));
|
||||
GameHelper.GetFormatedStorageSpace(storageSpace.MaxSize));
|
||||
}
|
||||
|
||||
if (storageSpace.MinSize != null && storageSpace.MaxSize == null)
|
||||
{
|
||||
return string.Format(ResourcesKey.MaxStorageSpaceFormat,
|
||||
GameHelper.GetFormatedStorageSpace(storageSpace.MaxSize));
|
||||
GameHelper.GetFormatedStorageSpace(storageSpace.MinSize));
|
||||
}
|
||||
|
||||
if (storageSpace.MinSize != null && storageSpace.MaxSize != null)
|
||||
|
||||
@@ -12,8 +12,8 @@ public class GameFilterParams
|
||||
public List<TagDto>? Tags { get; set; }
|
||||
public List<PublisherDto>? Publishers { get; set; }
|
||||
public List<DeveloperDto>? Developers { get; set; }
|
||||
public int? MinInterest { get; set; }
|
||||
public int? MaxInterest { get; set; }
|
||||
public int MinInterest { get; set; } = 1;
|
||||
public int MaxInterest { get; set; } = 5;
|
||||
public List<int>? ReleaseYears { get; set; }
|
||||
public List<StorageSpaceDto>? StorageSpaces { get; set; }
|
||||
public List<int>? StorageSpaceIds { get; set; }
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class GameGateway(IHttpClientService httpClientService) : IGameGateway
|
||||
Title = filterParams.Title,
|
||||
MaxInterest = filterParams.MaxInterest,
|
||||
MinInterest = filterParams.MinInterest,
|
||||
StorageSpaces = filterParams.StorageSpaces,
|
||||
StorageSpaces = filterParams.StorageSpaceIds,
|
||||
DeveloperIds = filterParams.Developers?.Select(d => d.Id ?? 0).ToList(),
|
||||
PublisherIds = filterParams.Publishers?.Select(d => d.Id ?? 0).ToList(),
|
||||
PlatformIds = filterParams.Platforms?.Select(d => d.Id ?? 0).ToList(),
|
||||
|
||||
@@ -6,10 +6,10 @@ namespace GameIdeas.BlazorApp.Shared.Components.SliderRange;
|
||||
public partial class SliderRange
|
||||
{
|
||||
[Parameter] public SliderRangeParams Params { get; set; } = new();
|
||||
[Parameter] public int? Max { get; set; }
|
||||
[Parameter] public EventCallback<int?> MaxChanged { get; set; }
|
||||
[Parameter] public int? Min { get; set; }
|
||||
[Parameter] public EventCallback<int?> MinChanged { get; set; }
|
||||
[Parameter] public int Max { get; set; }
|
||||
[Parameter] public EventCallback<int> MaxChanged { get; set; }
|
||||
[Parameter] public int Min { get; set; }
|
||||
[Parameter] public EventCallback<int> MinChanged { get; set; }
|
||||
|
||||
private async Task HandleSlideTwoInput()
|
||||
{
|
||||
@@ -33,12 +33,12 @@ public partial class SliderRange
|
||||
|
||||
private string FillColor()
|
||||
{
|
||||
var percent1 = (double)(Min! - Params.Min) / (Params.Max - Params.Min) * 100;
|
||||
var percent2 = (double)(Max! - Params.Min) / (Params.Max - Params.Min) * 100;
|
||||
var percent1 = (double)(Min - Params.Min) / (Params.Max - Params.Min) * 100;
|
||||
var percent2 = (double)(Max - Params.Min) / (Params.Max - Params.Min) * 100;
|
||||
return $"background: linear-gradient(to right, var(--line) {percent1}% , var(--violet) {percent1}% , var(--violet) {percent2}%, var(--line) {percent2}%)";
|
||||
}
|
||||
|
||||
private string StatusColor(int? value)
|
||||
private string StatusColor(int value)
|
||||
{
|
||||
string str = "--thumb-color: var({0});";
|
||||
|
||||
|
||||
@@ -8,4 +8,5 @@ public class CategoriesDto
|
||||
public List<DeveloperDto>? Developers { get; set; }
|
||||
public List<PublisherDto>? Publishers { get; set; }
|
||||
public List<int>? ReleaseYears { get; set; }
|
||||
public List<StorageSpaceDto>? StorageSpaces { get; set; }
|
||||
}
|
||||
|
||||
@@ -16,5 +16,5 @@ public class GameFilterDto
|
||||
public int? MinInterest { get; set; }
|
||||
public int? MaxInterest { get; set; }
|
||||
public List<int>? ReleaseYears { get; set; }
|
||||
public List<StorageSpaceDto>? StorageSpaces { get; set; }
|
||||
public List<int>? StorageSpaces { get; set; }
|
||||
}
|
||||
|
||||
@@ -4,4 +4,5 @@ public class StorageSpaceDto
|
||||
{
|
||||
public int? MinSize { get; set; }
|
||||
public int? MaxSize { get; set; }
|
||||
public int Id { get; set; }
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using GameIdeas.Shared.Dto;
|
||||
using GameIdeas.WebAPI.Services.Interfaces;
|
||||
using GameIdeas.WebAPI.Services.Categories;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace GameIdeas.WebAPI.Controllers;
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
using GameIdeas.Resources;
|
||||
using GameIdeas.WebAPI.Context;
|
||||
using GameIdeas.WebAPI.Profiles;
|
||||
using GameIdeas.WebAPI.Services.Categories;
|
||||
using GameIdeas.WebAPI.Services.Games;
|
||||
using GameIdeas.WebAPI.Services.Interfaces;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
var services = builder.Services;
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
using AutoMapper;
|
||||
using GameIdeas.Shared.Dto;
|
||||
using GameIdeas.WebAPI.Context;
|
||||
using GameIdeas.WebAPI.Services.Interfaces;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace GameIdeas.WebAPI.Services.Categories;
|
||||
|
||||
public class CategoryService(GameIdeasContext context, IMapper mapper) : ICategoryService
|
||||
{
|
||||
public List<StorageSpaceDto> GetStorageSpaces() => [
|
||||
new() { Id = 1, MaxSize = 100 },
|
||||
new() { Id = 2, MinSize = 100, MaxSize = 1000 },
|
||||
new() { Id = 3, MinSize = 1000, MaxSize = 5000 },
|
||||
new() { Id = 4, MinSize = 5000, MaxSize = 10000 },
|
||||
new() { Id = 5, MinSize = 10000, MaxSize = 20000 },
|
||||
new() { Id = 6, MinSize = 20000, MaxSize = 40000 },
|
||||
new() { Id = 7, MinSize = 40000, MaxSize = 100000 },
|
||||
new() { Id = 8, MinSize = 100000 },
|
||||
];
|
||||
|
||||
public async Task<CategoriesDto> GetCategories()
|
||||
{
|
||||
var platforms = await context.Platforms.ToListAsync();
|
||||
@@ -26,7 +36,8 @@ public class CategoryService(GameIdeasContext context, IMapper mapper) : ICatego
|
||||
Tags = mapper.Map<List<TagDto>>(tags),
|
||||
Developers = mapper.Map<List<DeveloperDto>>(developers),
|
||||
Publishers = mapper.Map<List<PublisherDto>>(publishers),
|
||||
ReleaseYears = mapper.Map<List<int>>(releaseYears)
|
||||
ReleaseYears = mapper.Map<List<int>>(releaseYears),
|
||||
StorageSpaces = GetStorageSpaces()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using GameIdeas.Shared.Dto;
|
||||
|
||||
namespace GameIdeas.WebAPI.Services.Interfaces;
|
||||
namespace GameIdeas.WebAPI.Services.Categories;
|
||||
|
||||
public interface ICategoryService
|
||||
{
|
||||
List<StorageSpaceDto> GetStorageSpaces();
|
||||
Task<CategoriesDto> GetCategories();
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@ using GameIdeas.Shared.Dto;
|
||||
using GameIdeas.Shared.Exceptions;
|
||||
using GameIdeas.Shared.Model;
|
||||
using GameIdeas.WebAPI.Context;
|
||||
using GameIdeas.WebAPI.Services.Categories;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace GameIdeas.WebAPI.Services.Games;
|
||||
|
||||
public class GameReadService(GameIdeasContext context, IMapper mapper) : IGameReadService
|
||||
public class GameReadService(GameIdeasContext context, IMapper mapper, ICategoryService categoryService) : IGameReadService
|
||||
{
|
||||
public async Task<IEnumerable<GameDto>> GetGames(GameFilterDto filter)
|
||||
{
|
||||
@@ -30,10 +30,7 @@ public class GameReadService(GameIdeasContext context, IMapper mapper) : IGameRe
|
||||
.Take(GlobalConstants.NUMBER_PER_PAGE)
|
||||
.ToListAsync();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(filter.Title))
|
||||
{
|
||||
games = [.. ApplySearchGameFilter(games, filter)];
|
||||
}
|
||||
ApplyStaticFilter(ref games, filter);
|
||||
|
||||
return mapper.Map<IEnumerable<GameDto>>(games);
|
||||
}
|
||||
@@ -75,7 +72,7 @@ public class GameReadService(GameIdeasContext context, IMapper mapper) : IGameRe
|
||||
}
|
||||
}
|
||||
|
||||
private static void ApplyFilter(ref IQueryable<Game> query, GameFilterDto filter)
|
||||
private void ApplyFilter(ref IQueryable<Game> query, GameFilterDto filter)
|
||||
{
|
||||
if (filter.PlatformIds != null)
|
||||
{
|
||||
@@ -117,12 +114,6 @@ public class GameReadService(GameIdeasContext context, IMapper mapper) : IGameRe
|
||||
query = query.Where(game => game.Interest <= filter.MaxInterest);
|
||||
}
|
||||
|
||||
if (filter.StorageSpaces != null)
|
||||
{
|
||||
query = query.Where(game => filter.StorageSpaces.Where(stor =>
|
||||
stor.MinSize <= game.StorageSpace && stor.MaxSize > game.StorageSpace).Count() != 0);
|
||||
}
|
||||
|
||||
if (filter.ReleaseYears != null)
|
||||
{
|
||||
query = query.Where(game => game.ReleaseDate != null &&
|
||||
@@ -130,22 +121,36 @@ public class GameReadService(GameIdeasContext context, IMapper mapper) : IGameRe
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<Game> ApplySearchGameFilter(IEnumerable<Game> query, GameFilterDto filter)
|
||||
private void ApplyStaticFilter(ref List<Game> games, GameFilterDto filter)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(filter.Title))
|
||||
{
|
||||
var keywords = filter.Title?
|
||||
.Split([' '], StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(k => k.Trim())
|
||||
.ToArray() ?? [];
|
||||
|
||||
query = query
|
||||
games = games
|
||||
.Where(game => keywords.All(
|
||||
kw => game.Title.Contains(kw, StringComparison.OrdinalIgnoreCase)
|
||||
))
|
||||
.OrderBy(game => keywords.Min(kw =>
|
||||
game.Title.IndexOf(kw, StringComparison.OrdinalIgnoreCase)
|
||||
))
|
||||
.ThenBy(game => game.Title.Length);
|
||||
.ThenBy(game => game.Title.Length)
|
||||
.ToList();
|
||||
|
||||
return query;
|
||||
return;
|
||||
}
|
||||
|
||||
if (filter.StorageSpaces != null)
|
||||
{
|
||||
var storageSpaces = categoryService.GetStorageSpaces().Where(stor => filter.StorageSpaces.Contains(stor.Id));
|
||||
|
||||
games = games
|
||||
.Where(game => storageSpaces.Any(stor =>
|
||||
(stor.MinSize ?? int.MinValue) <= game.StorageSpace && (stor.MaxSize ?? int.MaxValue) > game.StorageSpace))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user