Rework select component (#14)

Reviewed-on: #14
This commit was merged in pull request #14.
This commit is contained in:
2025-04-14 09:01:50 +02:00
parent 225e8ba140
commit 3d713d5749
44 changed files with 577 additions and 604 deletions

View File

@@ -1,5 +1,4 @@
@using GameIdeas.BlazorApp.Shared.Components.Select
@using GameIdeas.BlazorApp.Shared.Components.Select.Models
@using GameIdeas.BlazorApp.Shared.Components.SelectSearch
@using GameIdeas.BlazorApp.Shared.Components.Slider
@using GameIdeas.Shared.Dto
@@ -20,13 +19,13 @@
</div>
<div class="input-game">
<div class="label">@ResourcesKey.Developers :</div>
<MultipleSelectList TItem="DeveloperDto" Theme="SelectListTheme" @bind-Values=GameDto.Developers
Items="CategoriesDto?.Developers?.Select(d => new SelectElement<DeveloperDto>(d, d.Name))" />
<SelectSearch TItem="DeveloperDto" Theme="Theme" GetLabel="@(i => i.Name)"
Items="Categories?.Developers" @bind-Values=GameDto.Developers />
</div>
<div class="input-game">
<div class="label">@ResourcesKey.Publishers :</div>
<MultipleSelectList TItem="PublisherDto" Theme="SelectListTheme" @bind-Values=GameDto.Publishers
Items="CategoriesDto?.Publishers?.Select(p => new SelectElement<PublisherDto>(p, p.Name))" />
<SelectSearch TItem="PublisherDto" Theme="Theme" GetLabel="@(i => i.Name)"
Items="Categories?.Publishers" @bind-Values=GameDto.Publishers />
</div>
</div>
<div class="container">
@@ -38,19 +37,19 @@
</div>
<div class="input-game">
<div class="label">@ResourcesKey.Properties :</div>
<MultipleSelectList TItem="PropertyDto" Theme="SelectListTheme" @bind-Values=GameDto.Properties
Items="CategoriesDto?.Properties?.Select(p => new SelectElement<PropertyDto>(p, p.Label))" />
<SelectSearch TItem="PropertyDto" Theme="Theme" GetLabel="@(i => i.Label)"
Items="Categories?.Properties" @bind-Values=GameDto.Properties />
</div>
<div class="input-game">
<div class="label">@ResourcesKey.Genres :</div>
<MultipleSelectList TItem="TagDto" Theme="SelectListTheme" @bind-Values=GameDto.Tags
Items="CategoriesDto?.Tags?.Select(t => new SelectElement<TagDto>(t, t.Label))" />
<div class="label">@ResourcesKey.Tags :</div>
<SelectSearch TItem="TagDto" Theme="Theme" GetLabel="@(i => i.Label)"
Items="Categories?.Tags" @bind-Values=GameDto.Tags />
</div>
<div class="input-game">
<div class="label">@ResourcesKey.Platforms :</div>
<MultipleSelectList TItem="PlatformDto" Theme="SelectListTheme" @bind-Values=GameDto.Platforms
Items="CategoriesDto?.Platforms?.Select(p => new SelectElement<PlatformDto>(p, p.Label))" />
<SelectSearch TItem="PlatformDto" Theme="Theme" GetLabel="@(i => i.Label)"
Items="Categories?.Platforms" @bind-Values=GameDto.Platforms />
</div>
</div>
</div>

View File

@@ -1,4 +1,3 @@
using GameIdeas.BlazorApp.Pages.Games.Gateways;
using GameIdeas.BlazorApp.Shared.Components.Popup;
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
using GameIdeas.BlazorApp.Shared.Components.Slider;
@@ -12,19 +11,17 @@ namespace GameIdeas.BlazorApp.Pages.Games.Components;
public partial class GameCreationForm
{
[Inject] private IJSRuntime Js { get; set; } = default!;
[Inject] private IGameGateway GameGateway { get; set; } = default!;
[CascadingParameter] private Popup? Popup { get; set; }
[Parameter] public CategoriesDto? Categories { get; set; }
private GameDto GameDto = new();
private CategoriesDto CategoriesDto = new();
private EditContext? EditContext;
private readonly SelectListTheme SelectListTheme = SelectListTheme.Creation;
private readonly SelectTheme Theme = SelectTheme.Creation;
private readonly SliderParams SliderParams = new() { Gap = 1, Min = 1, Max = 5 };
protected override async Task OnInitializedAsync()
{
EditContext = new(GameDto);
CategoriesDto = await GameGateway.FetchCategories();
if (Popup != null)
{

View File

@@ -1,45 +1,26 @@
@using GameIdeas.BlazorApp.Shared.Components.Select
@using GameIdeas.BlazorApp.Shared.Components.Select.Models
@using GameIdeas.BlazorApp.Shared.Components.Select.Models
@using GameIdeas.BlazorApp.Shared.Components.SelectSearch
@using GameIdeas.Shared.Dto
<div class="advanced-filter-container">
<span class="title">@ResourcesKey.Filters</span>
<div class="duplicate">
<MultipleSelectList TItem="string"
@bind-Values=GameFilterParams!.Platforms
Placeholder="@ResourcesKey.Platforms"
Theme="SelectListTheme.AdvancedFilter" />
<SelectSearch TItem="PlatformDto" Placeholder="@ResourcesKey.Platforms" GetLabel="@(p => p.Label)"
@bind-Values=GameFilter.Platforms @bind-Values:after=HandleValueChanged Theme="Theme" Items="Categories?.Platforms" />
<MultipleSelectList TItem="string"
Placeholder="@ResourcesKey.Genres"
@bind-Values=GameFilterParams!.Tags
Theme="SelectListTheme.AdvancedFilter" />
<SelectSearch TItem="TagDto" Placeholder="@ResourcesKey.Tags" GetLabel="@(p => p.Label)"
@bind-Values=GameFilter.Tags @bind-Values:after=HandleValueChanged Theme="Theme" Items="Categories?.Tags" />
</div>
<SelectSearch TItem="PropertyDto" Placeholder="@ResourcesKey.Properties" GetLabel="@(p => p.Label)"
@bind-Values=GameFilter.Properties @bind-Values:after=HandleValueChanged Theme="Theme" Items="Categories?.Properties" />
<MultipleSelectList TItem="string"
Placeholder="@ResourcesKey.Publishers"
@bind-Values=GameFilterParams!.Publishers
Theme="SelectListTheme.AdvancedFilter" />
<SelectSearch TItem="DeveloperDto" Placeholder="@ResourcesKey.Developers" GetLabel="@(p => p.Name)"
@bind-Values=GameFilter.Developers @bind-Values:after=HandleValueChanged Theme="Theme" Items="Categories?.Developers" />
<MultipleSelectList TItem="string"
Placeholder="@ResourcesKey.Developers"
@bind-Values=GameFilterParams!.Developers
Theme="SelectListTheme.AdvancedFilter" />
<MultipleSelectList TItem="string"
Placeholder="@ResourcesKey.StorageSize"
@bind-Values=GameFilterParams!.StorageSizes
Theme="SelectListTheme.AdvancedFilter" />
<MultipleSelectList TItem="string"
Placeholder="@ResourcesKey.LastModification"
@bind-Values=GameFilterParams!.LastModification
Theme="SelectListTheme.AdvancedFilter" />
<MultipleSelectList TItem="string"
Placeholder="@ResourcesKey.ReleaseDate"
@bind-Values=GameFilterParams!.ReleaseDates
Theme="SelectListTheme.AdvancedFilter" />
<SelectSearch TItem="PublisherDto" Placeholder="@ResourcesKey.Publishers" GetLabel="@(p => p.Name)"
@bind-Values=GameFilter.Publishers @bind-Values:after=HandleValueChanged Theme="Theme" Items="Categories?.Publishers" />
<span class="title">@ResourcesKey.LastAdd</span>
</div>
</div>

View File

@@ -1,10 +1,19 @@
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
using GameIdeas.Shared.Dto;
using Microsoft.AspNetCore.Components;
namespace GameIdeas.BlazorApp.Pages.Games.Filter;
public partial class AdvancedGameFilter
{
[Parameter] public GameFilterParams? GameFilterParams { get; set; }
[Parameter] public EventCallback<GameFilterParams> GameFilterParamsChanged { get; set; }
[Parameter] public GameFilterDto GameFilter { get; set; } = new();
[Parameter] public CategoriesDto? Categories { get; set; }
[Parameter] public EventCallback<GameFilterDto> GameFilterChanged { get; set; }
private readonly SelectTheme Theme = SelectTheme.AdvancedFilter;
private async Task HandleValueChanged()
{
await GameFilterChanged.InvokeAsync(GameFilter);
}
}

View File

@@ -8,7 +8,7 @@
box-sizing: border-box;
width: 240px;
border-left: 2px solid var(--line);
z-index: var(--index-component);
z-index: var(--index-content);
}
.duplicate {

View File

@@ -1,23 +1,21 @@
@using GameIdeas.BlazorApp.Shared.Components.Search
@using GameIdeas.BlazorApp.Shared.Components.Select
@using GameIdeas.BlazorApp.Shared.Components.Select.Models
@using GameIdeas.BlazorApp.Shared.Components.SelectSearch
@using GameIdeas.BlazorApp.Shared.Components.SliderRange
@using GameIdeas.BlazorApp.Shared.Models
@using GameIdeas.Shared.Dto
@using GameIdeas.Shared.Enum
<div class="form-filter">
<SelectList TItem="Func<GameDto, object>" Items="GameProperties"
@bind-Value=GameFilterParams.SortProperty
THeader="SortType" Headers="SortTypes"
@bind-Header=GameFilterParams.SortType
Theme="SelectListTheme.Sort">
<Select TItem="SortPropertyDto" ValuesChanged=HandleSortPropertyClicked
THeader="SortTypeDto" HeaderValuesChanged=HandleSortTypeClicked
Params=SelectParams Theme="SelectTheme.Sort" >
<div class="square-button">
<svg class="sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M10,13H22V11H10M10,19H22V17H10M10,7H22V5H10M6,7H8.5L5,3.5L1.5,7H4V17H1.5L5,20.5L8.5,17H6V7Z" />
</svg>
</div>
</SelectList>
</Select>
<div class="square-button" @onclick="@(() => HandleDisplayClicked(DisplayType.List))">
<svg class="list-icon @(DisplayType == DisplayType.List ? "selected-icon" : "")" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
@@ -32,29 +30,24 @@
</div>
<div class="search-container">
<SearchInput @bind-Text=GameFilterParams.SearchName
Placeholder="@ResourcesKey.Research" />
<SearchInput @bind-Text="@Value.Title"
Placeholder="@ResourcesKey.Research" />
</div>
<div class="select-container">
<MultipleSelectList TItem="string"
Placeholder="@ResourcesKey.Platforms"
@bind-Values=GameFilterParams.Platforms
Theme="SelectListTheme.Filter" />
<SelectSearch TItem="PlatformDto" Placeholder="@ResourcesKey.Platforms" GetLabel="@(p => p.Label)"
@bind-Values=Value.Platforms @bind-Values:after="HandleValueChanged" Theme="SelectTheme.Filter" Items="Categories?.Platforms" />
</div>
<div class="select-container">
<MultipleSelectList TItem="string"
Placeholder="@ResourcesKey.Genres"
@bind-Values=GameFilterParams.Tags
Theme="SelectListTheme.Filter" />
<SelectSearch TItem="TagDto" Placeholder="@ResourcesKey.Tags" GetLabel="@(p => p.Label)"
@bind-Values=Value.Tags @bind-Values:after="HandleValueChanged" Theme="SelectTheme.Filter" Items="Categories?.Tags" />
</div>
<div class="slider-container">
<SliderRange Params="SliderRangeParams"
@bind-Max=GameFilterParams.MaxRating
@bind-Min=GameFilterParams.MinRating />
@bind-Max="Value.MaxInterest" @bind-Max:after="HandleValueChanged"
@bind-Min="Value.MinInterest" @bind-Min:after="HandleValueChanged" />
</div>
</div>

View File

@@ -10,31 +10,36 @@ namespace GameIdeas.BlazorApp.Pages.Games.Filter;
public partial class GameFilter
{
[Parameter] public GameFilterParams GameFilterParams { get; set; } = new();
[Parameter] public EventCallback<GameFilterParams> GameFilterParamsChanged { get; set; }
[Parameter] public GameFilterDto Value { get; set; } = new();
[Parameter] public EventCallback<GameFilterDto> ValueChanged { get; set; }
[Parameter] public DisplayType DisplayType { get; set; }
[Parameter] public EventCallback<DisplayType> DisplayTypeChanged { get; set; }
[Parameter] public CategoriesDto? Categories { get; set; }
private readonly IEnumerable<SelectElement<SortType>> SortTypes = [
new(SortType.Ascending, "Ascendant") { IsSelected = true },
new(SortType.Descending, "Descendant")
];
private readonly IEnumerable<SelectElement<Func<GameDto?, object?>>> GameProperties = [
new(game => game?.Title, "Nom") { IsSelected = true },
new(game => game?.ReleaseDate, "Date de parution"),
private readonly List<SortTypeDto> SortTypes = [
new() { SortType = SortType.Ascending, Label = "Ascendant" },
new() { SortType = SortType.Descending, Label = "Descendant" }
];
private EditContext? EditContext;
private readonly SliderRangeParams SliderRangeParams =
new() { Min = 1, Max = 5 };
private readonly List<SortPropertyDto> GameProperties = [
new() { SortProperty = game => game.Title!, Label = "Titre" },
new() { SortProperty = game => game.ReleaseDate!, Label = "Date de parution" }
];
private SelectParams<SortPropertyDto, SortTypeDto> SelectParams = new();
private readonly SliderRangeParams SliderRangeParams = new() { Min = 1, Max = 5 };
protected override void OnInitialized()
{
EditContext = new EditContext(GameFilterParams);
EditContext.OnFieldChanged += async (s, e) =>
SelectParams = new()
{
await GameFilterParamsChanged.InvokeAsync(GameFilterParams);
Headers = SortTypes,
GetHeaderLabel = header => header.Label,
DefaultHeader = SortTypes.FirstOrDefault(h => h.SortType == SortType.Ascending),
Items = GameProperties,
GetItemLabel = item => item.Label,
DefaultItem = GameProperties.FirstOrDefault(p => p.Label == "Titre")
};
}
@@ -43,4 +48,21 @@ public partial class GameFilter
DisplayType = displayType;
await DisplayTypeChanged.InvokeAsync(displayType);
}
private async Task HandleSortTypeClicked(IEnumerable<SortTypeDto> sortTypes)
{
Value.SortType = sortTypes.FirstOrDefault();
await ValueChanged.InvokeAsync(Value);
}
private async Task HandleSortPropertyClicked(IEnumerable<SortPropertyDto> sortProperties)
{
Value.SortProperty = sortProperties.FirstOrDefault();
await ValueChanged.InvokeAsync(Value);
}
private async Task HandleValueChanged()
{
await ValueChanged.InvokeAsync(Value);
}
}

View File

@@ -3,7 +3,7 @@
flex-direction: row;
gap: 8px;
align-items: center;
z-index: var(--index-component);
z-index: var(--index-content);
}
.search-container {

View File

@@ -1,21 +0,0 @@
using GameIdeas.Shared.Enum;
using GameIdeas.Shared.Dto;
namespace GameIdeas.BlazorApp.Pages.Games.Filter;
public class GameFilterParams
{
public SortType SortType { get; set; } = SortType.Ascending;
public Func<GameDto?, object?>? SortProperty { get; set; }
public string? SearchName { get; set; }
public IEnumerable<string>? Platforms { get; set; }
public IEnumerable<string>? Properties { get; set; }
public IEnumerable<string>? Tags { get; set; }
public IEnumerable<string>? Publishers { get; set; }
public IEnumerable<string>? Developers { get; set; }
public IEnumerable<string>? StorageSizes { get; set; }
public IEnumerable<string>? LastModification { get; set; }
public IEnumerable<string>? ReleaseDates { get; set; }
public int MaxRating { get; set; } = 5;
public int MinRating { get; set; } = 1;
}

View File

@@ -12,17 +12,18 @@
<PageTitle>@ResourcesKey.GamesIdeas</PageTitle>
<GameHeader AddTypeChanged="HandleAddClicked">
<GameFilter @bind-DisplayType=DisplayType
@bind-GameFilterParams=GameFilterParams />
<GameFilter Categories="Categories"
@bind-DisplayType=DisplayType
@bind-Value=GameFilter/>
</GameHeader>
<div class="container">
<div class="content">
</div>
<AdvancedGameFilter @bind-GameFilterParams=GameFilterParams />
<AdvancedGameFilter @bind-GameFilter=GameFilter Categories="Categories" />
</div>
<Popup @ref=ManualAddPopup BackdropFilterClicked="HandleBackdropManualAddClicked">
<GameCreationForm />
<GameCreationForm Categories="Categories" />
</Popup>

View File

@@ -1,14 +1,25 @@
using GameIdeas.BlazorApp.Pages.Games.Filter;
using GameIdeas.BlazorApp.Pages.Games.Gateways;
using GameIdeas.BlazorApp.Shared.Components.Popup;
using GameIdeas.BlazorApp.Shared.Models;
using GameIdeas.Shared.Dto;
using Microsoft.AspNetCore.Components;
namespace GameIdeas.BlazorApp.Pages.Games;
public partial class GameBase ()
{
[Inject] private IGameGateway GameGateway { get; set; } = default!;
private DisplayType DisplayType = DisplayType.List;
private GameFilterParams GameFilterParams = new();
private GameFilterDto GameFilter = new();
private Popup? ManualAddPopup;
private CategoriesDto? Categories;
protected override async Task OnInitializedAsync()
{
Categories = await GameGateway.FetchCategories();
await base.OnInitializedAsync();
}
private void HandleAddClicked(AddType addType)
{
switch (addType)

View File

@@ -22,15 +22,15 @@
<path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" />
</svg>
</div>
<SelectList @ref="SelectListAdd" TItem="AddType" Items="SelectElements"
ValueChanged=HandleAddTypeClickedAsync THeader="object"
Theme="SelectListTheme.Navigation" AlignRight=true>
<Select @ref="SelectListAdd" TItem="KeyValuePair<AddType, string>" THeader="object"
ValuesChanged=HandleAddTypeClicked Params=SelectParams
Theme="SelectTheme.Navigation">
<div class="second-button button">
<svg class="button-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M1 3H23L12 22" />
</svg>
</div>
</SelectList>
</Select>
</div>
</div>
<div class="account-container">

View File

@@ -13,23 +13,35 @@ public partial class GameHeader : ComponentBase
[Parameter] public RenderFragment? ChildContent { get; set; }
private readonly IEnumerable<SelectElement<AddType>> SelectElements = [
new SelectElement<AddType>(AddType.Manual, ResourcesKey.ManualAdd),
new SelectElement<AddType> (AddType.Auto, ResourcesKey.AutoAdd)
];
private readonly Dictionary<AddType, string> AddTypes = new() {
{ AddType.Manual, ResourcesKey.ManualAdd },
{ AddType.Auto, ResourcesKey.AutoAdd }
};
private AccountSettings? AccountSettings;
private SelectList<AddType, object>? SelectListAdd;
private Select<KeyValuePair<AddType, string>, object>? SelectListAdd;
private SelectParams<KeyValuePair<AddType, string>, object> SelectParams = new();
protected override void OnInitialized()
{
SelectParams = new()
{
Items = AddTypes.ToList(),
GetItemLabel = item => item.Value,
};
base.OnInitialized();
}
private void HandleIconClicked()
{
throw new NotImplementedException();
}
private async Task HandleAddTypeClickedAsync(AddType value)
private async Task HandleAddTypeClicked(IEnumerable<KeyValuePair<AddType, string>> values)
{
SelectListAdd?.Close();
await AddTypeChanged.InvokeAsync(value);
await AddTypeChanged.InvokeAsync(values.FirstOrDefault().Key);
}
private void HandleAccountClicked()