diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Helpers/GameHelper.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Helpers/GameHelper.cs
index b737d80..9673b84 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Helpers/GameHelper.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Helpers/GameHelper.cs
@@ -22,4 +22,19 @@ public static class GameHelper
_ => "--yellow",
};
}
+
+ public static string GetFormatedStorageSpace(double? storageValue)
+ {
+ if (storageValue == null)
+ {
+ return string.Empty;
+ }
+
+ return storageValue switch
+ {
+ >= 1000000 => $"{storageValue / 1000000:f1} To",
+ >= 1000 => $"{storageValue / 1000:f1} Go",
+ _ => $"{storageValue:f1} Mo"
+ };
+ }
}
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameBase.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameBase.cs
index efc56cf..14e4339 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameBase.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameBase.cs
@@ -12,19 +12,4 @@ public class GameBase : ComponentBase
{
NavigationManager.NavigateTo($"/Games/Detail/{GameDto.Id}");
}
-
- protected string GetFormatedStorageSpace()
- {
- if (GameDto.StorageSpace == null)
- {
- return string.Empty;
- }
-
- return GameDto.StorageSpace switch
- {
- >= 1000000 => $"{GameDto.StorageSpace / 1000000:f1} To",
- >= 1000 => $"{GameDto.StorageSpace / 1000:f1} Go",
- _ => $"{GameDto.StorageSpace:f1} Mo"
- };
- }
}
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameRow.razor b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameRow.razor
index a2309f2..b31104c 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameRow.razor
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Components/GameRow.razor
@@ -28,7 +28,7 @@
}
- @GetFormatedStorageSpace()
+ @GameHelper.GetFormatedStorageSpace(GameDto.StorageSpace)
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Filter/AdvancedGameFilter.razor b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Filter/AdvancedGameFilter.razor
index 460ecf6..1657943 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Filter/AdvancedGameFilter.razor
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Filter/AdvancedGameFilter.razor
@@ -22,5 +22,11 @@
+
+
+
+
@ResourcesKey.LastAdd
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Filter/AdvancedGameFilter.razor.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Filter/AdvancedGameFilter.razor.cs
index be03b6b..ac79f65 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Filter/AdvancedGameFilter.razor.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Filter/AdvancedGameFilter.razor.cs
@@ -1,4 +1,7 @@
+using GameIdeas.BlazorApp.Helpers;
+using GameIdeas.BlazorApp.Pages.Games.Header;
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
+using GameIdeas.Resources;
using GameIdeas.Shared.Dto;
using Microsoft.AspNetCore.Components;
@@ -11,9 +14,43 @@ public partial class AdvancedGameFilter
[Parameter] public EventCallback GameFilterChanged { get; set; }
private readonly SelectTheme Theme = SelectTheme.AdvancedFilter;
+ private readonly List 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)
+ {
+ if (storageSpace.MinSize == null && storageSpace.MaxSize != null)
+ {
+ return string.Format(ResourcesKey.MinStorageSpaceFormat,
+ GameHelper.GetFormatedStorageSpace(storageSpace.MinSize));
+ }
+
+ if (storageSpace.MinSize != null && storageSpace.MaxSize == null)
+ {
+ return string.Format(ResourcesKey.MaxStorageSpaceFormat,
+ GameHelper.GetFormatedStorageSpace(storageSpace.MaxSize));
+ }
+
+ if (storageSpace.MinSize != null && storageSpace.MaxSize != null)
+ {
+ return string.Format(ResourcesKey.MinMaxStorageSpaceFormat,
+ GameHelper.GetFormatedStorageSpace(storageSpace.MinSize),
+ GameHelper.GetFormatedStorageSpace(storageSpace.MaxSize));
+ }
+
+ throw new ArgumentNullException(ResourcesKey.ErrorStorageSpaceLabel);
+ }
}
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Filter/GameFilterParams.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Filter/GameFilterParams.cs
index 1fc1f1b..87c02c1 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Filter/GameFilterParams.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Filter/GameFilterParams.cs
@@ -1,5 +1,6 @@
-
-namespace GameIdeas.Shared.Dto;
+using GameIdeas.Shared.Dto;
+
+namespace GameIdeas.BlazorApp.Pages.Games.Filter;
public class GameFilterParams
{
@@ -14,6 +15,5 @@ public class GameFilterParams
public int MinInterest { get; set; } = 1;
public int MaxInterest { get; set; } = 5;
public List? ReleaseYears { get; set; }
- public int? MinStorageSize { get; set; }
- public int? MaxStorageSize { get; set; }
+ public List? StorageSpaces { get; set; }
}
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Game.razor b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Game.razor
index 369b8bf..e49ff7f 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Game.razor
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Game.razor
@@ -40,5 +40,5 @@
-
+
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Game.razor.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Game.razor.cs
index 00c14b7..a8b0ae3 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Game.razor.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Game.razor.cs
@@ -1,3 +1,4 @@
+using GameIdeas.BlazorApp.Pages.Games.Filter;
using GameIdeas.BlazorApp.Pages.Games.Gateways;
using GameIdeas.BlazorApp.Shared.Components.Popup;
using GameIdeas.BlazorApp.Shared.Models;
@@ -28,7 +29,7 @@ public partial class Game
GameFilter.SortProperty= Filter.GameFilter.GameProperties
.First(gp => gp.PropertyName == nameof(GameIdeas.Shared.Model.Game.Title));
- await HandleFetchDatas(true);
+ await HandleFetchDatas();
await base.OnInitializedAsync();
}
@@ -49,11 +50,11 @@ public partial class Game
{
ManualAddPopup?.Close();
}
- private async Task HandleFetchDatas(bool loadCategories = false)
+ private async Task HandleFetchDatas(bool loadCategories = true, bool displayLoader = true)
{
try
{
- IsLoading = true;
+ IsLoading = displayLoader;
if (loadCategories)
Categories = await GameGateway.FetchCategories();
@@ -72,6 +73,6 @@ public partial class Game
private async Task HandleFilterChanged(GameFilterParams args)
{
GameFilter = args;
- await HandleFetchDatas(false);
+ await HandleFetchDatas(loadCategories: false, displayLoader: false);
}
}
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/GameGateway.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/GameGateway.cs
index 0cbf89b..e2823fb 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/GameGateway.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/GameGateway.cs
@@ -1,4 +1,5 @@
-using GameIdeas.BlazorApp.Services;
+using GameIdeas.BlazorApp.Pages.Games.Filter;
+using GameIdeas.BlazorApp.Services;
using GameIdeas.BlazorApp.Shared.Constants;
using GameIdeas.BlazorApp.Shared.Exceptions;
using GameIdeas.Resources;
@@ -44,16 +45,13 @@ public class GameGateway(IHttpClientService httpClientService) : IGameGateway
Title = filterParams.Title,
MaxInterest = filterParams.MaxInterest,
MinInterest = filterParams.MinInterest,
- MaxStorageSize = filterParams.MaxStorageSize,
- MinStorageSize = filterParams.MinStorageSize,
- ReleaseYears = filterParams.ReleaseYears,
+ StorageSpaces = filterParams.StorageSpaces,
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(),
PropertyIds = filterParams.Properties?.Select(d => d.Id ?? 0).ToList(),
+ ReleaseYears = filterParams.ReleaseYears,
TagIds = filterParams.Tags?.Select(d => d.Id ?? 0).ToList(),
- SortType = filterParams.SortType?.SortType,
- SortPropertyName = filterParams.SortProperty?.PropertyName
};
var result = await httpClientService.FetchDataAsync>(Endpoints.Game.Fetch(filter));
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/IGameGateway.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/IGameGateway.cs
index cbb8439..d78155f 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/IGameGateway.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Pages/Games/Gateways/IGameGateway.cs
@@ -1,4 +1,5 @@
-using GameIdeas.Shared.Dto;
+using GameIdeas.BlazorApp.Pages.Games.Filter;
+using GameIdeas.Shared.Dto;
namespace GameIdeas.BlazorApp.Pages.Games.Gateways;
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Search/SearchInput.razor.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Search/SearchInput.razor.cs
index d9e250a..f6521df 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Search/SearchInput.razor.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Search/SearchInput.razor.cs
@@ -21,7 +21,7 @@ public partial class SearchInput
Text = string.Empty;
Timer = new()
{
- Interval = 1000,
+ Interval = 500,
AutoReset = false,
};
diff --git a/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs b/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs
index c4a23c0..288e791 100644
--- a/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs
+++ b/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs
@@ -44,6 +44,10 @@ public class Translations (TranslationService translationService)
public string ErrorFetchGames => translationService.Translate(nameof(ErrorFetchGames));
public string Ascending => translationService.Translate(nameof(Ascending));
public string Descending => translationService.Translate(nameof(Descending));
+ public string ErrorStorageSpaceLabel => translationService.Translate(nameof(ErrorStorageSpaceLabel));
+ public string MinStorageSpaceFormat => translationService.Translate(nameof(MinStorageSpaceFormat));
+ public string MaxStorageSpaceFormat => translationService.Translate(nameof(MaxStorageSpaceFormat));
+ public string MinMaxStorageSpaceFormat => translationService.Translate(nameof(MinMaxStorageSpaceFormat));
}
public static class ResourcesKey
@@ -96,4 +100,8 @@ public static class ResourcesKey
public static string ErrorFetchGames => _instance?.ErrorFetchGames ?? throw new InvalidOperationException("ResourcesKey.ErrorFetchGames is not initialized.");
public static string Ascending => _instance?.Ascending ?? throw new InvalidOperationException("ResourcesKey.Ascending is not initialized.");
public static string Descending => _instance?.Descending ?? throw new InvalidOperationException("ResourcesKey.Descending is not initialized.");
+ public static string ErrorStorageSpaceLabel => _instance?.ErrorStorageSpaceLabel ?? throw new InvalidOperationException("ResourcesKey.ErrorStorageSpaceLabel is not initialized.");
+ public static string MinStorageSpaceFormat => _instance?.MinStorageSpaceFormat ?? throw new InvalidOperationException("ResourcesKey.MinStorageSpaceFormat is not initialized.");
+ public static string MaxStorageSpaceFormat => _instance?.MaxStorageSpaceFormat ?? throw new InvalidOperationException("ResourcesKey.MaxStorageSpaceFormat is not initialized.");
+ public static string MinMaxStorageSpaceFormat => _instance?.MinMaxStorageSpaceFormat ?? throw new InvalidOperationException("ResourcesKey.MinMaxStorageSpaceFormat is not initialized.");
}
\ No newline at end of file
diff --git a/src/GameIdeas/GameIdeas.Shared/Dto/CategoriesDto.cs b/src/GameIdeas/GameIdeas.Shared/Dto/CategoriesDto.cs
index 4d6583f..0136301 100644
--- a/src/GameIdeas/GameIdeas.Shared/Dto/CategoriesDto.cs
+++ b/src/GameIdeas/GameIdeas.Shared/Dto/CategoriesDto.cs
@@ -7,4 +7,5 @@ public class CategoriesDto
public List? Tags { get; set; }
public List? Developers { get; set; }
public List? Publishers { get; set; }
+ public List? ReleaseYears { get; set; }
}
diff --git a/src/GameIdeas/GameIdeas.Shared/Dto/GameFilterDto.cs b/src/GameIdeas/GameIdeas.Shared/Dto/GameFilterDto.cs
index 7c1fcb2..ef6f3fe 100644
--- a/src/GameIdeas/GameIdeas.Shared/Dto/GameFilterDto.cs
+++ b/src/GameIdeas/GameIdeas.Shared/Dto/GameFilterDto.cs
@@ -13,9 +13,8 @@ public class GameFilterDto
public List? TagIds { get; set; }
public List? PublisherIds { get; set; }
public List? DeveloperIds { get; set; }
- public int MinInterest { get; set; } = 1;
- public int MaxInterest { get; set; } = 5;
+ public int? MinInterest { get; set; }
+ public int? MaxInterest { get; set; }
public List? ReleaseYears { get; set; }
- public int? MinStorageSize { get; set; }
- public int? MaxStorageSize { get; set; }
+ public List? StorageSpaces { get; set; }
}
diff --git a/src/GameIdeas/GameIdeas.Shared/Dto/StorageSpaceDto.cs b/src/GameIdeas/GameIdeas.Shared/Dto/StorageSpaceDto.cs
new file mode 100644
index 0000000..1e0f96c
--- /dev/null
+++ b/src/GameIdeas/GameIdeas.Shared/Dto/StorageSpaceDto.cs
@@ -0,0 +1,7 @@
+namespace GameIdeas.Shared.Dto;
+
+public class StorageSpaceDto
+{
+ public int? MinSize { get; set; }
+ public int? MaxSize { get; set; }
+}
\ No newline at end of file
diff --git a/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json b/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json
index 9d63308..c0bffdf 100644
--- a/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json
+++ b/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json
@@ -39,5 +39,9 @@
"Unknown": "Inconnu",
"ErrorFetchGames": "Erreur lors de la récupération des jeux",
"Ascending": "Ascendant",
- "Descending": "Descendant"
+ "Descending": "Descendant",
+ "ErrorStorageSpaceLabel": "Erreur lors de la génération des label de l'espace de stockage",
+ "MinStorageSpaceFormat": "Jusqu'à {0}",
+ "MaxStorageSpaceFormat": "Plus de {0}",
+ "MinMaxStorageSpaceFormat": "{0} à {1}"
}
\ No newline at end of file
diff --git a/src/GameIdeas/Server/GameIdeas.WebAPI/Services/Categories/CategoryService.cs b/src/GameIdeas/Server/GameIdeas.WebAPI/Services/Categories/CategoryService.cs
index 4d7c05d..11562ac 100644
--- a/src/GameIdeas/Server/GameIdeas.WebAPI/Services/Categories/CategoryService.cs
+++ b/src/GameIdeas/Server/GameIdeas.WebAPI/Services/Categories/CategoryService.cs
@@ -15,6 +15,9 @@ public class CategoryService(GameIdeasContext context, IMapper mapper) : ICatego
var tags = await context.Tags.ToListAsync();
var developers = await context.Developers.ToListAsync();
var publishers = await context.Publishers.ToListAsync();
+ var releaseYears = await context.Games
+ .Where(game => game.ReleaseDate != null)
+ .Select(game => game.ReleaseDate!.Value.Year).Distinct().ToListAsync();
return new()
{
@@ -22,7 +25,8 @@ public class CategoryService(GameIdeasContext context, IMapper mapper) : ICatego
Properties = mapper.Map>(properties),
Tags = mapper.Map>(tags),
Developers = mapper.Map>(developers),
- Publishers = mapper.Map>(publishers)
+ Publishers = mapper.Map>(publishers),
+ ReleaseYears = mapper.Map>(releaseYears)
};
}
}
diff --git a/src/GameIdeas/Server/GameIdeas.WebAPI/Services/Games/GameReadService.cs b/src/GameIdeas/Server/GameIdeas.WebAPI/Services/Games/GameReadService.cs
index 16e80cd..def9582 100644
--- a/src/GameIdeas/Server/GameIdeas.WebAPI/Services/Games/GameReadService.cs
+++ b/src/GameIdeas/Server/GameIdeas.WebAPI/Services/Games/GameReadService.cs
@@ -5,6 +5,7 @@ using GameIdeas.Shared.Exceptions;
using GameIdeas.Shared.Model;
using GameIdeas.WebAPI.Context;
using Microsoft.EntityFrameworkCore;
+using System.Linq;
using System.Linq.Expressions;
namespace GameIdeas.WebAPI.Services.Games;
@@ -31,7 +32,7 @@ public class GameReadService(GameIdeasContext context, IMapper mapper) : IGameRe
if (!string.IsNullOrWhiteSpace(filter.Title))
{
- games = ApplySearchGameFilter(games, filter).ToList();
+ games = [.. ApplySearchGameFilter(games, filter)];
}
return mapper.Map>(games);
@@ -81,6 +82,52 @@ public class GameReadService(GameIdeasContext context, IMapper mapper) : IGameRe
query = query.Where(game => filter.PlatformIds.All(plat =>
game.GamePlatforms.Any(gp => gp.PlatformId == plat)));
}
+
+ if (filter.PropertyIds != null)
+ {
+ query = query.Where(game => filter.PropertyIds.All(prop =>
+ game.GameProperties.Any(gp => gp.PropertyId == prop)));
+ }
+
+ if (filter.TagIds != null)
+ {
+ query = query.Where(game => filter.TagIds.All(tag =>
+ game.GameTags.Any(gt => gt.TagId == tag)));
+ }
+
+ if (filter.PublisherIds != null)
+ {
+ query = query.Where(game => filter.PublisherIds.All(pub =>
+ game.GamePublishers.Any(gp => gp.PublisherId == pub)));
+ }
+
+ if (filter.DeveloperIds != null)
+ {
+ query = query.Where(game => filter.DeveloperIds.All(dev =>
+ game.GameDevelopers.Any(gd => gd.DeveloperId == dev)));
+ }
+
+ if (filter.MinInterest != null)
+ {
+ query = query.Where(game => game.Interest >= filter.MinInterest);
+ }
+
+ if (filter.MaxInterest != null)
+ {
+ 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 &&
+ filter.ReleaseYears.Contains(game.ReleaseDate.Value.Year));
+ }
}
private static IEnumerable ApplySearchGameFilter(IEnumerable query, GameFilterDto filter)