Add items in search celect
This commit is contained in:
@@ -19,13 +19,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="input-game">
|
<div class="input-game">
|
||||||
<div class="label">@ResourcesKey.Developers :</div>
|
<div class="label">@ResourcesKey.Developers :</div>
|
||||||
<SelectSearch TItem="DeveloperDto" Theme="Theme" GetLabel="@(i => i.Name)"
|
<SelectSearch TItem="DeveloperDto" Theme="Theme" GetLabel="@(i => i.Name)" QuickAdd=true
|
||||||
Items="Categories?.Developers" @bind-Values=GameDto.Developers />
|
Items="Categories?.Developers" @bind-Values=GameDto.Developers
|
||||||
|
AddItem="@(str => new DeveloperDto() { Name = str })" />
|
||||||
</div>
|
</div>
|
||||||
<div class="input-game">
|
<div class="input-game">
|
||||||
<div class="label">@ResourcesKey.Publishers :</div>
|
<div class="label">@ResourcesKey.Publishers :</div>
|
||||||
<SelectSearch TItem="PublisherDto" Theme="Theme" GetLabel="@(i => i.Name)"
|
<SelectSearch TItem="PublisherDto" Theme="Theme" GetLabel="@(i => i.Name)" QuickAdd=true
|
||||||
Items="Categories?.Publishers" @bind-Values=GameDto.Publishers />
|
Items="Categories?.Publishers" @bind-Values=GameDto.Publishers
|
||||||
|
AddItem="@(str => new PublisherDto() { Name = str })" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@@ -37,19 +39,22 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="input-game">
|
<div class="input-game">
|
||||||
<div class="label">@ResourcesKey.Properties :</div>
|
<div class="label">@ResourcesKey.Properties :</div>
|
||||||
<SelectSearch TItem="PropertyDto" Theme="Theme" GetLabel="@(i => i.Label)"
|
<SelectSearch TItem="PropertyDto" Theme="Theme" GetLabel="@(i => i.Label)" QuickAdd=true
|
||||||
Items="Categories?.Properties" @bind-Values=GameDto.Properties />
|
Items="Categories?.Properties" @bind-Values=GameDto.Properties
|
||||||
|
AddItem="@(str => new PropertyDto() { Label = str })" />
|
||||||
</div>
|
</div>
|
||||||
<div class="input-game">
|
<div class="input-game">
|
||||||
<div class="label">@ResourcesKey.Tags :</div>
|
<div class="label">@ResourcesKey.Tags :</div>
|
||||||
<SelectSearch TItem="TagDto" Theme="Theme" GetLabel="@(i => i.Label)"
|
<SelectSearch TItem="TagDto" Theme="Theme" GetLabel="@(i => i.Label)" QuickAdd=true
|
||||||
Items="Categories?.Tags" @bind-Values=GameDto.Tags />
|
Items="Categories?.Tags" @bind-Values=GameDto.Tags
|
||||||
|
AddItem="@(str => new TagDto() { Label = str })" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="input-game">
|
<div class="input-game">
|
||||||
<div class="label">@ResourcesKey.Platforms :</div>
|
<div class="label">@ResourcesKey.Platforms :</div>
|
||||||
<SelectSearch TItem="PlatformDto" Theme="Theme" GetLabel="@(i => i.Label)"
|
<SelectSearch TItem="PlatformDto" Theme="Theme" GetLabel="@(i => i.Label)" QuickAdd=true
|
||||||
Items="Categories?.Platforms" @bind-Values=GameDto.Platforms />
|
Items="Categories?.Platforms" @bind-Values=GameDto.Platforms
|
||||||
|
AddItem="@(str => new PlatformDto() { Label = str })" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ public partial class GameFilter
|
|||||||
{
|
{
|
||||||
Headers = SortTypes,
|
Headers = SortTypes,
|
||||||
GetHeaderLabel = header => header.Label,
|
GetHeaderLabel = header => header.Label,
|
||||||
DefaultHeader = SortTypes.FirstOrDefault(h => h.SortType == SortType.Ascending),
|
DefaultHeaders = SortTypes.Where(h => h.SortType == SortType.Ascending).ToList(),
|
||||||
Items = GameProperties,
|
Items = GameProperties,
|
||||||
GetItemLabel = item => item.Label,
|
GetItemLabel = item => item.Label,
|
||||||
DefaultItem = GameProperties.FirstOrDefault(p => p.Label == "Titre")
|
DefaultItems = GameProperties.Where(p => p.Label == "Titre").ToList()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<Select @ref="SelectListAdd" TItem="KeyValuePair<AddType, string>" THeader="object"
|
<Select @ref="SelectListAdd" TItem="KeyValuePair<AddType, string>" THeader="object"
|
||||||
ValuesChanged=HandleAddTypeClicked Params=SelectParams
|
ValuesChanged=HandleAddTypeClicked Params=SelectParams Theme="SelectTheme.Navigation">
|
||||||
Theme="SelectTheme.Navigation">
|
|
||||||
<div class="second-button button">
|
<div class="second-button button">
|
||||||
<svg class="button-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg class="button-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
<path d="M1 3H23L12 22" />
|
<path d="M1 3H23L12 22" />
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public partial class GameHeader : ComponentBase
|
|||||||
{
|
{
|
||||||
Items = AddTypes.ToList(),
|
Items = AddTypes.ToList(),
|
||||||
GetItemLabel = item => item.Value,
|
GetItemLabel = item => item.Value,
|
||||||
|
DefaultItems = []
|
||||||
};
|
};
|
||||||
|
|
||||||
base.OnInitialized();
|
base.OnInitialized();
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
.backdrop-filter {
|
.backdrop-filter {
|
||||||
position: fixed;
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: var(--index-backdrop);
|
z-index: var(--index-backdrop);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
.popup-wrapper {
|
.popup-wrapper {
|
||||||
display: none;
|
display: none;
|
||||||
justify-content: center;
|
justify-self: anchor-center;
|
||||||
align-items: center;
|
align-self: anchor-center;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
z-index: var(--index-popup);
|
z-index: var(--index-popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-content {
|
.popup-content {
|
||||||
position: relative;
|
|
||||||
background-color: var(--dropdown-content);
|
background-color: var(--dropdown-content);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: var(--big-radius);
|
border-radius: var(--big-radius);
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
public class SelectParams<TItem, THeader>
|
public class SelectParams<TItem, THeader>
|
||||||
{
|
{
|
||||||
public List<TItem> Items { get; set; } = [];
|
public List<TItem> Items { get; set; } = [];
|
||||||
public TItem? DefaultItem { get; set; }
|
public List<TItem> DefaultItems { get; set; } = [];
|
||||||
public Func<TItem, string> GetItemLabel { get; set; } = _ => string.Empty;
|
public Func<TItem, string> GetItemLabel { get; set; } = _ => string.Empty;
|
||||||
public List<THeader> Headers { get; set; } = [];
|
public List<THeader> Headers { get; set; } = [];
|
||||||
public THeader? DefaultHeader { get; set; }
|
public List<THeader> DefaultHeaders { get; set; } = [];
|
||||||
public Func<THeader, string> GetHeaderLabel { get; set; } = _ => string.Empty;
|
public Func<THeader, string> GetHeaderLabel { get; set; } = _ => string.Empty;
|
||||||
|
public Func<string, TItem>? AddItem { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,20 @@
|
|||||||
@if (IsContentOpen)
|
@if (IsContentOpen)
|
||||||
{
|
{
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@if (QuickAdd)
|
||||||
|
{
|
||||||
|
<div class="add-item">
|
||||||
|
<EditForm EditContext="QuickAddEditContext" OnSubmit="HandleSubmitAdd">
|
||||||
|
<input type="text" placeholder="@ResourcesKey.PlaceholderAdd" @bind=AddLabel>
|
||||||
|
</EditForm>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span class="line"></span>
|
||||||
|
}
|
||||||
|
|
||||||
@if (Params.Headers != null)
|
@if (Params.Headers != null)
|
||||||
{
|
{
|
||||||
@foreach (var header in Params.Headers)
|
@foreach (var header in Params.Headers.Union(HeaderValues ?? []))
|
||||||
{
|
{
|
||||||
<SelectRow IsSelected=HeaderValues?.Contains(header)
|
<SelectRow IsSelected=HeaderValues?.Contains(header)
|
||||||
Label="@Params.GetHeaderLabel(header)" Theme=Theme
|
Label="@Params.GetHeaderLabel(header)" Theme=Theme
|
||||||
@@ -24,14 +35,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (Params.Headers?.Any() == true)
|
@if (Params.Headers?.Count != 0)
|
||||||
{
|
{
|
||||||
<span class="line"></span>
|
<span class="line"></span>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (Params.Items != null)
|
@if (Params.Items != null)
|
||||||
{
|
{
|
||||||
@foreach (var item in Params.Items)
|
@foreach (var item in Params.Items.Union(Values ?? []))
|
||||||
{
|
{
|
||||||
<SelectRow IsSelected=Values?.Contains(item)
|
<SelectRow IsSelected=Values?.Contains(item)
|
||||||
Label="@Params.GetItemLabel(item)" Theme=Theme
|
Label="@Params.GetItemLabel(item)" Theme=Theme
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
using GameIdeas.BlazorApp.Shared.Components.Select.Models;
|
||||||
|
using GameIdeas.Resources;
|
||||||
|
using GameIdeas.Shared.Constants;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.AspNetCore.Components.Forms;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace GameIdeas.BlazorApp.Shared.Components.Select;
|
namespace GameIdeas.BlazorApp.Shared.Components.Select;
|
||||||
|
|
||||||
@@ -14,8 +18,11 @@ public partial class Select<TItem, THeader>
|
|||||||
[Parameter] public SelectTheme Theme { get; set; }
|
[Parameter] public SelectTheme Theme { get; set; }
|
||||||
[Parameter] public SelectType Type { get; set; } = SelectType.Single;
|
[Parameter] public SelectType Type { get; set; } = SelectType.Single;
|
||||||
[Parameter] public bool DisableClicked { get; set; } = false;
|
[Parameter] public bool DisableClicked { get; set; } = false;
|
||||||
|
[Parameter] public bool QuickAdd { get; set; } = false;
|
||||||
|
|
||||||
private bool IsContentOpen = false;
|
private bool IsContentOpen = false;
|
||||||
|
private string AddLabel = string.Empty;
|
||||||
|
private EditContext? QuickAddEditContext;
|
||||||
|
|
||||||
public void Close() =>
|
public void Close() =>
|
||||||
IsContentOpen = false;
|
IsContentOpen = false;
|
||||||
@@ -23,6 +30,21 @@ public partial class Select<TItem, THeader>
|
|||||||
public void Open() =>
|
public void Open() =>
|
||||||
IsContentOpen = true;
|
IsContentOpen = true;
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
QuickAddEditContext = new EditContext(AddLabel);
|
||||||
|
|
||||||
|
if (Params.DefaultItems.Count != 0)
|
||||||
|
{
|
||||||
|
Values.AddRange(Params.DefaultItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Params.DefaultHeaders.Count != 0)
|
||||||
|
{
|
||||||
|
HeaderValues.AddRange(Params.DefaultHeaders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void HandleButtonClicked()
|
private void HandleButtonClicked()
|
||||||
{
|
{
|
||||||
if (!DisableClicked)
|
if (!DisableClicked)
|
||||||
@@ -32,19 +54,6 @@ public partial class Select<TItem, THeader>
|
|||||||
private void HandleContentClosed() =>
|
private void HandleContentClosed() =>
|
||||||
IsContentOpen = false;
|
IsContentOpen = false;
|
||||||
|
|
||||||
protected override void OnInitialized()
|
|
||||||
{
|
|
||||||
if (Params.DefaultItem != null)
|
|
||||||
{
|
|
||||||
Values.Add(Params.DefaultItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Params.DefaultHeader != null)
|
|
||||||
{
|
|
||||||
HeaderValues.Add(Params.DefaultHeader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task HandleValueClicked(TItem value)
|
private async Task HandleValueClicked(TItem value)
|
||||||
{
|
{
|
||||||
if (Type != SelectType.Multiple || Values == null)
|
if (Type != SelectType.Multiple || Values == null)
|
||||||
@@ -82,4 +91,17 @@ public partial class Select<TItem, THeader>
|
|||||||
|
|
||||||
await HeaderValuesChanged.InvokeAsync(HeaderValues);
|
await HeaderValuesChanged.InvokeAsync(HeaderValues);
|
||||||
}
|
}
|
||||||
|
private async Task HandleSubmitAdd()
|
||||||
|
{
|
||||||
|
if (Regex.IsMatch(AddLabel, GlobalConstants.RegexSelectRow) &&
|
||||||
|
Params.AddItem != null)
|
||||||
|
{
|
||||||
|
Values ??= [];
|
||||||
|
Values.Add(Params.AddItem(AddLabel));
|
||||||
|
|
||||||
|
AddLabel = string.Empty;
|
||||||
|
|
||||||
|
await ValuesChanged.InvokeAsync(Values);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -29,6 +29,20 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.add-item {
|
||||||
|
align-content: center;
|
||||||
|
height: 24px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-item input {
|
||||||
|
width: 100%;
|
||||||
|
color: var(--white);
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown::-webkit-scrollbar {
|
.dropdown::-webkit-scrollbar {
|
||||||
width: 10px;
|
width: 10px;
|
||||||
}
|
}
|
||||||
@@ -72,4 +86,16 @@
|
|||||||
border-bottom: 2px solid var(--input-selected);
|
border-bottom: 2px solid var(--input-selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***** Sort Theme *****/
|
||||||
|
.creation .content {
|
||||||
|
border-radius: var(--small-radius);
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: solid 1px var(--violet);
|
||||||
|
}
|
||||||
|
|
||||||
|
.creation .content .line {
|
||||||
|
display: block;
|
||||||
|
margin: 2px 6px;
|
||||||
|
border-bottom: 2px solid var(--input-selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
@typeparam TItem
|
@typeparam TItem
|
||||||
|
|
||||||
<Select @ref=Select TItem="TItem" THeader="string" Theme="Theme" Type="SelectType.Multiple" DisableClicked=true
|
<Select @ref=Select TItem="TItem" THeader="string" Theme="Theme" Type="SelectType.Multiple" DisableClicked=true
|
||||||
Params="SelectParams" Values=Values ValuesChanged="HandleValuesChanged">
|
Params="SelectParams" Values=Values ValuesChanged="HandleValuesChanged" QuickAdd=QuickAdd>
|
||||||
|
|
||||||
<div class="@SelectHelper.GetClassFromTheme(Theme)">
|
<div class="@SelectHelper.GetClassFromTheme(Theme)">
|
||||||
<SearchInput @ref=SearchInput Icon="SearchInputIcon.Dropdown" Placeholder="@Placeholder"
|
<SearchInput @ref=SearchInput Icon="SearchInputIcon.Dropdown" Placeholder="@Placeholder"
|
||||||
|
|||||||
@@ -13,16 +13,20 @@ public partial class SelectSearch<TItem>
|
|||||||
[Parameter] public List<TItem> Values { get; set; } = [];
|
[Parameter] public List<TItem> Values { get; set; } = [];
|
||||||
[Parameter] public EventCallback<List<TItem>> ValuesChanged { get; set; }
|
[Parameter] public EventCallback<List<TItem>> ValuesChanged { get; set; }
|
||||||
[Parameter] public string Placeholder { get; set; } = string.Empty;
|
[Parameter] public string Placeholder { get; set; } = string.Empty;
|
||||||
|
[Parameter] public bool QuickAdd { get; set; } = false;
|
||||||
|
[Parameter] public Func<string, TItem>? AddItem { get; set; }
|
||||||
|
|
||||||
private SelectParams<TItem, string> SelectParams = new();
|
private SelectParams<TItem, string> SelectParams = new();
|
||||||
private SearchInput? SearchInput;
|
private SearchInput? SearchInput;
|
||||||
private Select<TItem, string>? Select;
|
private Select<TItem, string>? Select;
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
SelectParams = new()
|
SelectParams = new()
|
||||||
{
|
{
|
||||||
Items = Items,
|
Items = Items,
|
||||||
GetItemLabel = GetLabel
|
GetItemLabel = GetLabel,
|
||||||
|
AddItem = AddItem
|
||||||
};
|
};
|
||||||
|
|
||||||
base.OnParametersSet();
|
base.OnParametersSet();
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public class Translations (TranslationService translationService)
|
|||||||
public string ErrorWhenFetchingData => translationService.Translate(nameof(ErrorWhenFetchingData));
|
public string ErrorWhenFetchingData => translationService.Translate(nameof(ErrorWhenFetchingData));
|
||||||
public string RequestFailedStatusFormat => translationService.Translate(nameof(RequestFailedStatusFormat));
|
public string RequestFailedStatusFormat => translationService.Translate(nameof(RequestFailedStatusFormat));
|
||||||
public string ErrorFetchCategories => translationService.Translate(nameof(ErrorFetchCategories));
|
public string ErrorFetchCategories => translationService.Translate(nameof(ErrorFetchCategories));
|
||||||
|
public string PlaceholderAdd => translationService.Translate(nameof(PlaceholderAdd));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ResourcesKey
|
public static class ResourcesKey
|
||||||
@@ -76,4 +77,5 @@ public static class ResourcesKey
|
|||||||
public static string ErrorWhenFetchingData => _instance?.ErrorWhenFetchingData ?? throw new InvalidOperationException("ResourcesKey.ErrorWhenFetchingData is not initialized.");
|
public static string ErrorWhenFetchingData => _instance?.ErrorWhenFetchingData ?? throw new InvalidOperationException("ResourcesKey.ErrorWhenFetchingData is not initialized.");
|
||||||
public static string RequestFailedStatusFormat => _instance?.RequestFailedStatusFormat ?? throw new InvalidOperationException("ResourcesKey.RequestFailedStatusFormat is not initialized.");
|
public static string RequestFailedStatusFormat => _instance?.RequestFailedStatusFormat ?? throw new InvalidOperationException("ResourcesKey.RequestFailedStatusFormat is not initialized.");
|
||||||
public static string ErrorFetchCategories => _instance?.ErrorFetchCategories ?? throw new InvalidOperationException("ResourcesKey.ErrorFetchCategories is not initialized.");
|
public static string ErrorFetchCategories => _instance?.ErrorFetchCategories ?? throw new InvalidOperationException("ResourcesKey.ErrorFetchCategories is not initialized.");
|
||||||
|
public static string PlaceholderAdd => _instance?.PlaceholderAdd ?? throw new InvalidOperationException("ResourcesKey.PlaceholderAdd is not initialized.");
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,5 @@
|
|||||||
|
|
||||||
public class GlobalConstants
|
public class GlobalConstants
|
||||||
{
|
{
|
||||||
public const string EnterKeyCode = "Enter";
|
public const string RegexSelectRow = @"[a-zA-Z_ \-]*";
|
||||||
public const string PadEnterKeyCode = "NumpadEnter";
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,5 +29,6 @@
|
|||||||
"ErrorWhenDeletingData": "Erreur lors de la requête DELETE",
|
"ErrorWhenDeletingData": "Erreur lors de la requête DELETE",
|
||||||
"ErrorWhenFetchingData": "Erreur lors de la requête GET",
|
"ErrorWhenFetchingData": "Erreur lors de la requête GET",
|
||||||
"RequestFailedStatusFormat": "Erreur lors de la réponse, code {0}",
|
"RequestFailedStatusFormat": "Erreur lors de la réponse, code {0}",
|
||||||
"ErrorFetchCategories": "Erreur lors de la récupération des catégories"
|
"ErrorFetchCategories": "Erreur lors de la récupération des catégories",
|
||||||
|
"PlaceholderAdd": "Ajouter un nouveau"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user