+
- @if (Value != null && Value.IsSelected)
+ @if (IsSelected == true)
{
}
-
- @Value?.Label
+
+ @Label
-
+
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Components/SelectRow.razor.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Components/SelectRow.razor.cs
new file mode 100644
index 0000000..6ce1077
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Components/SelectRow.razor.cs
@@ -0,0 +1,16 @@
+using GameIdeas.BlazorApp.Shared.Components.Select.Models;
+using Microsoft.AspNetCore.Components;
+
+namespace GameIdeas.BlazorApp.Shared.Components.Select.Components;
+
+public partial class SelectRow
+{
+ [Parameter] public bool? IsSelected { get; set; }
+ [Parameter] public string? Label { get; set; }
+ [Parameter] public SelectTheme Theme { get; set; }
+ [Parameter] public EventCallback OnClick { get; set; }
+ private async Task HandleElementClicked()
+ {
+ await OnClick.InvokeAsync();
+ }
+}
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Components/SelectRow.razor.css b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Components/SelectRow.razor.css
new file mode 100644
index 0000000..a12a8b5
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Components/SelectRow.razor.css
@@ -0,0 +1,45 @@
+.select-element {
+ display: flex;
+ flex-direction: row;
+ width: auto;
+ gap: 6px;
+ height: 20px;
+ align-items: center;
+ padding: 2px 6px;
+}
+
+ .select-element:hover {
+ cursor: pointer;
+ background: var(--input-selected);
+ }
+
+.selected {
+ width: 12px;
+ min-width: 12px;
+ height: 12px;
+ min-height: 12px;
+ border: 1px solid var(--line);
+}
+
+ .selected svg {
+ display: block;
+ fill: var(--white)
+ }
+
+.label {
+ text-wrap: nowrap;
+ margin-right: 6px;
+}
+
+/***** Navigation Theme *****/
+.navigation {
+ padding: 4px 8px;
+}
+
+ .navigation:hover {
+ background: var(--violet-selected);
+ }
+
+ .navigation .selected {
+ display: none;
+ }
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Helpers/SelectHelper.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Helpers/SelectHelper.cs
new file mode 100644
index 0000000..862ceda
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Helpers/SelectHelper.cs
@@ -0,0 +1,19 @@
+using GameIdeas.BlazorApp.Shared.Components.Select.Models;
+
+namespace GameIdeas.BlazorApp.Shared.Components.Select.Helpers;
+
+public static class SelectHelper
+{
+ public static string GetClassFromTheme(SelectTheme selectTheme)
+ {
+ return selectTheme switch
+ {
+ SelectTheme.Navigation => "navigation",
+ SelectTheme.Sort => "sort",
+ SelectTheme.Filter => "filter",
+ SelectTheme.AdvancedFilter => "advanced-filter",
+ SelectTheme.Creation => "creation",
+ _ => string.Empty
+ };
+ }
+}
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Models/SelectElement.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Models/SelectElement.cs
deleted file mode 100644
index 71a0232..0000000
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Models/SelectElement.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace GameIdeas.BlazorApp.Shared.Components.Select.Models;
-
-public class SelectElement
(TItem item, string? label)
-{
- public TItem Item { get; set; } = item;
- public string? Label { get; set; } = label;
- public bool IsSelected { get; set; } = false;
- public bool IsNew { get; set; } = false;
-}
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Models/SelectParams.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Models/SelectParams.cs
new file mode 100644
index 0000000..f904beb
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Models/SelectParams.cs
@@ -0,0 +1,12 @@
+namespace GameIdeas.BlazorApp.Shared.Components.Select.Models;
+
+public class SelectParams
+{
+ public List Items { get; set; } = [];
+ public TItem? DefaultItem { get; set; }
+ public Func GetItemLabel { get; set; } = _ => string.Empty;
+ public List Headers { get; set; } = [];
+ public THeader? DefaultHeader { get; set; }
+ public Func GetHeaderLabel { get; set; } = _ => string.Empty;
+
+}
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Models/SelectTheme.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Models/SelectTheme.cs
index df43019..63d38ba 100644
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Models/SelectTheme.cs
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Models/SelectTheme.cs
@@ -1,6 +1,6 @@
namespace GameIdeas.BlazorApp.Shared.Components.Select.Models;
-public enum SelectListTheme
+public enum SelectTheme
{
Navigation,
Sort,
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Models/SelectType.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Models/SelectType.cs
new file mode 100644
index 0000000..f3cb1e2
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Models/SelectType.cs
@@ -0,0 +1,7 @@
+namespace GameIdeas.BlazorApp.Shared.Components.Select.Models;
+
+public enum SelectType
+{
+ Single,
+ Multiple
+}
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/MultipleSelectList.razor b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/MultipleSelectList.razor
deleted file mode 100644
index 83c296a..0000000
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/MultipleSelectList.razor
+++ /dev/null
@@ -1,35 +0,0 @@
-@using GameIdeas.BlazorApp.Shared.Components.BackdropFilter
-@using GameIdeas.BlazorApp.Shared.Components.Search
-@using GameIdeas.BlazorApp.Shared.Components.Select.Components
-@typeparam TItem
-
-
-
-
-
-
-
- @if (IsContentOpen)
- {
-
- @foreach (var item in Items)
- {
-
- }
-
- }
-
-
-
-
-
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/MultipleSelectList.razor.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/MultipleSelectList.razor.cs
deleted file mode 100644
index def2a83..0000000
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/MultipleSelectList.razor.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using GameIdeas.BlazorApp.Shared.Components.Search;
-using GameIdeas.BlazorApp.Shared.Components.Select.Models;
-using Microsoft.AspNetCore.Components;
-using Microsoft.JSInterop;
-
-namespace GameIdeas.BlazorApp.Shared.Components.Select;
-
-public partial class MultipleSelectList
-{
- [Inject] IJSRuntime JS { get; set; } = default!;
- [Parameter] public IEnumerable? Values { get; set; }
- [Parameter] public EventCallback?> ValuesChanged { get; set; }
- [Parameter] public IEnumerable> Items { get; set; } = [];
- [Parameter] public SelectListTheme Theme { get; set; }
- [Parameter] public bool AlignRight { get; set; }
- [Parameter] public string? Placeholder { get; set; }
-
- private bool IsContentOpen = false;
- private SearchInput? SearchInput;
-
-
- protected override async Task OnAfterRenderAsync(bool firstRender)
- {
- await JS.InvokeVoidAsync("addResizeListener");
-
- await base.OnAfterRenderAsync(firstRender);
- }
-
- private async Task HandleItemClicked(SelectElement selectedValue)
- {
- selectedValue.IsSelected = !selectedValue.IsSelected;
-
- Values = Items.Where(x => x.IsSelected && x.Item != null).Select(x => x.Item!);
- SearchInput?.SetText(string.Join(", ", Values));
-
- await ValuesChanged.InvokeAsync(Values);
- StateHasChanged();
- }
-
- private async Task HandleTextChanged()
- {
- IsContentOpen = false;
-
- foreach (var item in Items)
- {
- item.IsSelected = false;
- }
-
- Values = Items.Where(x => x.IsSelected && x.Item != null).Select(x => x.Item!);
- await ValuesChanged.InvokeAsync(Values);
- }
-
- private void HandleSearchClicked()
- {
- IsContentOpen = !IsContentOpen;
- }
- private void HandleContentClosed()
- {
- IsContentOpen = false;
- }
- private void HandleTextFocusIn()
- {
- IsContentOpen = true;
- }
-}
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/MultipleSelectList.razor.css b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/MultipleSelectList.razor.css
deleted file mode 100644
index ab8485c..0000000
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/MultipleSelectList.razor.css
+++ /dev/null
@@ -1,72 +0,0 @@
-.select-list {
- position: relative;
-}
-
-.select-container {
- overflow: auto;
- right: 0;
- min-width: 100%;
- margin-top: 4px;
- position: absolute;
- z-index: var(--index-dropdown);
- border-radius: var(--small-radius);
-}
-
-.select-content {
- display: flex;
- flex-direction: column;
- animation-name: fade-in;
- animation-duration: 0.4s;
- background: var(--dropdown-content);
- box-shadow: var(--drop-shadow);
- padding: 4px 0;
-}
-
-.select-button {
- z-index: var(--index-component)
-}
-
-.line {
- margin: 2px 6px;
- border-bottom: 2px solid var(--input-selected);
-}
-/* Advanced filter */
-::deep .select-button.advancedfilter .search-container {
- height: 24px;
- background: var(--input-secondary);
-}
-
- ::deep .select-button.advancedfilter .search-container input::placeholder {
- color: #bbb;
- }
-
-/* Creation */
-::deep .select-button.creation .search-container {
- height: 24px;
- background: var(--input-secondary);
- border: solid 1px var(--input-selected);
- box-sizing: border-box;
-}
-
-/* width */
-.select-container::-webkit-scrollbar {
- width: 10px;
-}
-
-/* Track */
-.select-container::-webkit-scrollbar-track {
- background: var(--input-secondary);
- border-radius: 0 var(--small-radius) var(--small-radius) 0;
-}
-
-/* Handle */
-.select-container::-webkit-scrollbar-thumb {
- background: #555;
- border-radius: var(--small-radius);
-}
-
- /* Handle on hover */
- .select-container::-webkit-scrollbar-thumb:hover {
- background: #777;
- }
-
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/MultipleSelectList.razor.js b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/MultipleSelectList.razor.js
deleted file mode 100644
index 3506868..0000000
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/MultipleSelectList.razor.js
+++ /dev/null
@@ -1,19 +0,0 @@
-function offset(el) {
- var rect = el.getBoundingClientRect(),
- scrollLeft = window.scrollY || document.documentElement.scrollLeft,
- scrollTop = window.scrollX || document.documentElement.scrollTop;
- return { top: rect.top + scrollTop, left: rect.left + scrollLeft }
-}
-
-function resizeSelectContent() {
- const height = window.innerHeight;
- const selects = document.getElementsByClassName('select-container');
- for (var i = 0; i < selects.length; i++) {
- selects[i].style.maxHeight = height - offset(selects[i]).top - 10 + "px";
- }
-}
-
-window.addResizeListener = () => {
- resizeSelectContent();
- window.addEventListener('resize', resizeSelectContent);
-};
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Select.razor b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Select.razor
new file mode 100644
index 0000000..77b416d
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Select.razor
@@ -0,0 +1,47 @@
+@using GameIdeas.BlazorApp.Shared.Components.BackdropFilter
+@using GameIdeas.BlazorApp.Shared.Components.Select.Components
+@using GameIdeas.BlazorApp.Shared.Components.Select.Helpers
+
+@typeparam TItem
+@typeparam THeader
+
+
+
+ @ChildContent
+
+
+
+ @if (IsContentOpen)
+ {
+
+ @if (Params.Headers != null)
+ {
+ @foreach (var header in Params.Headers)
+ {
+
+ }
+ }
+
+ @if (Params.Headers?.Any() == true)
+ {
+
+ }
+
+ @if (Params.Items != null)
+ {
+ @foreach (var item in Params.Items)
+ {
+
+ }
+ }
+
+ }
+
+
+
+
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Select.razor.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Select.razor.cs
new file mode 100644
index 0000000..fe4bc56
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Select.razor.cs
@@ -0,0 +1,85 @@
+using GameIdeas.BlazorApp.Shared.Components.Select.Models;
+using Microsoft.AspNetCore.Components;
+
+namespace GameIdeas.BlazorApp.Shared.Components.Select;
+
+public partial class Select
+{
+ [Parameter] public RenderFragment? ChildContent { get; set; }
+ [Parameter] public List Values { get; set; } = [];
+ [Parameter] public EventCallback> ValuesChanged { get; set; }
+ [Parameter] public List HeaderValues { get; set; } = [];
+ [Parameter] public EventCallback> HeaderValuesChanged { get; set; }
+ [Parameter] public SelectParams Params { get; set; } = new();
+ [Parameter] public SelectTheme Theme { get; set; }
+ [Parameter] public SelectType Type { get; set; } = SelectType.Single;
+ [Parameter] public bool DisableClicked { get; set; } = false;
+
+ private bool IsContentOpen = false;
+
+ public void Close() =>
+ IsContentOpen = false;
+
+ public void Open() =>
+ IsContentOpen = true;
+
+ private void HandleButtonClicked()
+ {
+ if (!DisableClicked)
+ IsContentOpen = !IsContentOpen;
+ }
+
+ private void HandleContentClosed() =>
+ 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)
+ {
+ if (Type != SelectType.Multiple || Values == null)
+ {
+ Values = [];
+ }
+
+ if (Values?.Contains(value) == true)
+ {
+ Values.Remove(value);
+ }
+ else
+ {
+ Values!.Add(value);
+ }
+
+ await ValuesChanged.InvokeAsync(Values);
+ }
+
+ private async Task HandleHeaderClicked(THeader header)
+ {
+ if (Type != SelectType.Multiple || HeaderValues == null)
+ {
+ HeaderValues = [];
+ }
+
+ if (HeaderValues?.Contains(header) == true)
+ {
+ HeaderValues.Remove(header);
+ }
+ else
+ {
+ HeaderValues!.Add(header);
+ }
+
+ await HeaderValuesChanged.InvokeAsync(HeaderValues);
+ }
+}
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Select.razor.css b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Select.razor.css
new file mode 100644
index 0000000..7dce1f0
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/Select.razor.css
@@ -0,0 +1,75 @@
+.select-container {
+ position: relative;
+}
+
+.button {
+ z-index: var(--index-component)
+}
+
+.dropdown {
+ overflow: auto;
+ margin-top: 4px;
+ position: absolute;
+ z-index: var(--index-dropdown);
+ border-radius: var(--small-radius);
+ width: 100%;
+}
+
+.content {
+ background: var(--dropdown-content);
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ animation-name: fade-in;
+ animation-duration: 0.2s;
+ box-shadow: var(--drop-shadow);
+}
+
+.line {
+ display: none;
+}
+
+.dropdown::-webkit-scrollbar {
+ width: 10px;
+}
+
+.dropdown::-webkit-scrollbar-track {
+ background: var(--input-secondary);
+ border-radius: 0 var(--small-radius) var(--small-radius) 0;
+}
+
+.dropdown::-webkit-scrollbar-thumb {
+ background: #555;
+ border-radius: var(--small-radius);
+}
+
+ .dropdown::-webkit-scrollbar-thumb:hover {
+ background: #777;
+ }
+
+/***** Navigation Theme *****/
+.dropdown.navigation {
+ width: auto;
+ right: 0;
+}
+
+.navigation .content {
+ background: var(--violet);
+}
+
+/***** Sort Theme *****/
+.dropdown.sort {
+ width: auto;
+}
+
+.sort .content {
+ padding: 4px 0;
+}
+
+ .sort .content .line {
+ display: block;
+ margin: 2px 6px;
+ border-bottom: 2px solid var(--input-selected);
+ }
+
+
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/SelectList.razor b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/SelectList.razor
deleted file mode 100644
index 031592a..0000000
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/SelectList.razor
+++ /dev/null
@@ -1,40 +0,0 @@
-@using GameIdeas.BlazorApp.Shared.Components.BackdropFilter
-@using GameIdeas.BlazorApp.Shared.Components.Select.Components
-@typeparam TItem
-@typeparam THeader
-
-
-
- @ChildContent
-
-
-
- @if (IsContentOpen)
- {
-
- @foreach (var header in Headers)
- {
-
- }
- @if (Headers.Any())
- {
-
- }
- @foreach (var item in Items)
- {
-
- }
-
- }
-
-
-
-
-
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/SelectList.razor.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/SelectList.razor.cs
deleted file mode 100644
index 4aa9e5e..0000000
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/SelectList.razor.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-using GameIdeas.BlazorApp.Shared.Components.Select.Models;
-using Microsoft.AspNetCore.Components;
-
-namespace GameIdeas.BlazorApp.Shared.Components.Select;
-
-public partial class SelectList
-{
- [Parameter] public RenderFragment? ChildContent { get; set; }
- [Parameter] public TItem? Value { get; set; }
- [Parameter] public EventCallback ValueChanged { get; set; }
- [Parameter] public THeader? Header { get; set; }
- [Parameter] public EventCallback HeaderChanged { get; set; }
- [Parameter] public IEnumerable> Items { get; set; } = [];
- [Parameter] public IEnumerable> Headers { get; set; } = [];
- [Parameter] public SelectListTheme Theme { get; set; }
- [Parameter] public bool AlignRight { get; set; }
-
- private bool IsContentOpen = false;
-
- public void Close() =>
- IsContentOpen = false;
-
- private void HandleButtonClicked() =>
- IsContentOpen = !IsContentOpen;
-
- private void HandleContentClosed()
- {
- IsContentOpen = false;
- }
-
- private async Task HandleItemClicked(SelectElement selectedValue)
- {
- foreach (var item in Items)
- {
- item.IsSelected = false;
- }
-
- selectedValue.IsSelected = true;
-
- Value = selectedValue.Item;
- await ValueChanged.InvokeAsync(Value);
- }
-
- private async Task HandleHeaderClicked(SelectElement selectedValue)
- {
- foreach (var header in Headers)
- {
- header.IsSelected = false;
- }
-
- selectedValue.IsSelected = true;
-
- Header = selectedValue.Item;
- await HeaderChanged.InvokeAsync(Header);
- }
-}
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/SelectList.razor.css b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/SelectList.razor.css
deleted file mode 100644
index 56150db..0000000
--- a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/Select/SelectList.razor.css
+++ /dev/null
@@ -1,45 +0,0 @@
-.select-list {
- position: relative;
-}
-
-.select-container {
- margin-top: 4px;
- position: absolute;
- z-index: var(--index-dropdown)
-}
-
-.align-right {
- right: 0;
-}
-
-.select-content {
- overflow: hidden;
- display: flex;
- flex-direction: column;
- border-radius: var(--small-radius);
- animation-name: fade-in;
- animation-duration: 0.4s;
-}
-
-.select-button {
- z-index: var(--index-component)
-}
-
-.line {
- margin: 2px 6px;
- border-bottom: 2px solid var(--input-selected);
-}
-
-
-/***** Navigation Theme *****/
-.select-content.navigation {
- background: var(--violet);
- box-shadow: var(--drop-shadow);
-}
-
-/***** Sort Theme *****/
-.select-content.sort {
- background: var(--dropdown-content);
- box-shadow: var(--drop-shadow);
- padding: 4px 0;
-}
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/SelectSearch/SelectSearch.razor b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/SelectSearch/SelectSearch.razor
new file mode 100644
index 0000000..e169a80
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/SelectSearch/SelectSearch.razor
@@ -0,0 +1,17 @@
+@using GameIdeas.BlazorApp.Shared.Components.Search
+@using GameIdeas.BlazorApp.Shared.Components.Select
+@using GameIdeas.BlazorApp.Shared.Components.Select.Helpers
+@using GameIdeas.BlazorApp.Shared.Components.Select.Models
+
+@typeparam TItem
+
+
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/SelectSearch/SelectSearch.razor.cs b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/SelectSearch/SelectSearch.razor.cs
new file mode 100644
index 0000000..a9d03d7
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/SelectSearch/SelectSearch.razor.cs
@@ -0,0 +1,46 @@
+using GameIdeas.BlazorApp.Shared.Components.Search;
+using GameIdeas.BlazorApp.Shared.Components.Select.Models;
+using GameIdeas.BlazorApp.Shared.Components.Select;
+using Microsoft.AspNetCore.Components;
+
+namespace GameIdeas.BlazorApp.Shared.Components.SelectSearch;
+
+public partial class SelectSearch
+{
+ [Parameter] public SelectTheme Theme { get; set; }
+ [Parameter] public List Items { get; set; } = [];
+ [Parameter] public Func GetLabel { get; set; } = _ => string.Empty;
+ [Parameter] public List Values { get; set; } = [];
+ [Parameter] public EventCallback> ValuesChanged { get; set; }
+ [Parameter] public string Placeholder { get; set; } = string.Empty;
+
+ private SelectParams SelectParams = new();
+ private SearchInput? SearchInput;
+ private Select? Select;
+ protected override void OnParametersSet()
+ {
+ SelectParams = new()
+ {
+ Items = Items,
+ GetItemLabel = GetLabel
+ };
+
+ base.OnParametersSet();
+ }
+ private async Task HandleValuesChanged(IEnumerable values)
+ {
+ Values = values.ToList();
+ SearchInput?.SetText(string.Join(", ", Values.Select(GetLabel)));
+ await ValuesChanged.InvokeAsync(values.ToList());
+ }
+
+ private void HandleClearClicked()
+ {
+ Values = [];
+ }
+
+ private void HandleFocusIn()
+ {
+ Select?.Open();
+ }
+}
\ No newline at end of file
diff --git a/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/SelectSearch/SelectSearch.razor.css b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/SelectSearch/SelectSearch.razor.css
new file mode 100644
index 0000000..827e927
--- /dev/null
+++ b/src/GameIdeas/Client/GameIdeas.BlazorApp/Shared/Components/SelectSearch/SelectSearch.razor.css
@@ -0,0 +1,17 @@
+/* Advanced filter */
+.advanced-filter ::deep.search-container {
+ height: 24px;
+ background: var(--input-secondary);
+}
+
+.advanced-filter ::deep.search-container input::placeholder {
+ color: #bbb;
+}
+
+/* Creation */
+.creation ::deep.search-container {
+ height: 24px;
+ background: var(--input-secondary);
+ border: solid 1px var(--input-selected);
+ box-sizing: border-box;
+}
diff --git a/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs b/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs
index c904515..8f90fac 100644
--- a/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs
+++ b/src/GameIdeas/GameIdeas.Resources/CreateStaticResourceKey.cs
@@ -15,7 +15,7 @@ public class Translations (TranslationService translationService)
public string LastAdd => translationService.Translate(nameof(LastAdd));
public string Research => translationService.Translate(nameof(Research));
public string Platforms => translationService.Translate(nameof(Platforms));
- public string Genres => translationService.Translate(nameof(Genres));
+ public string Tags => translationService.Translate(nameof(Tags));
public string Publishers => translationService.Translate(nameof(Publishers));
public string Developers => translationService.Translate(nameof(Developers));
public string StorageSize => translationService.Translate(nameof(StorageSize));
@@ -57,7 +57,7 @@ public static class ResourcesKey
public static string LastAdd => _instance?.LastAdd ?? throw new InvalidOperationException("ResourcesKey.LastAdd is not initialized.");
public static string Research => _instance?.Research ?? throw new InvalidOperationException("ResourcesKey.Research is not initialized.");
public static string Platforms => _instance?.Platforms ?? throw new InvalidOperationException("ResourcesKey.Platforms is not initialized.");
- public static string Genres => _instance?.Genres ?? throw new InvalidOperationException("ResourcesKey.Genres is not initialized.");
+ public static string Tags => _instance?.Tags ?? throw new InvalidOperationException("ResourcesKey.Tags is not initialized.");
public static string Publishers => _instance?.Publishers ?? throw new InvalidOperationException("ResourcesKey.Publishers is not initialized.");
public static string Developers => _instance?.Developers ?? throw new InvalidOperationException("ResourcesKey.Developers is not initialized.");
public static string StorageSize => _instance?.StorageSize ?? throw new InvalidOperationException("ResourcesKey.StorageSize is not initialized.");
diff --git a/src/GameIdeas/GameIdeas.Shared/Dto/CategoriesDto.cs b/src/GameIdeas/GameIdeas.Shared/Dto/CategoriesDto.cs
index 233a090..4d6583f 100644
--- a/src/GameIdeas/GameIdeas.Shared/Dto/CategoriesDto.cs
+++ b/src/GameIdeas/GameIdeas.Shared/Dto/CategoriesDto.cs
@@ -2,9 +2,9 @@
public class CategoriesDto
{
- public IEnumerable? Platforms { get; set; }
- public IEnumerable? Properties { get; set; }
- public IEnumerable? Tags { get; set; }
- public IEnumerable? Developers { get; set; }
- public IEnumerable? Publishers { get; set; }
+ public List? Platforms { get; set; }
+ public List? Properties { get; set; }
+ public List? Tags { get; set; }
+ public List? Developers { get; set; }
+ public List? Publishers { get; set; }
}
diff --git a/src/GameIdeas/GameIdeas.Shared/Dto/GameDto.cs b/src/GameIdeas/GameIdeas.Shared/Dto/GameDto.cs
index 7917133..dd2afe0 100644
--- a/src/GameIdeas/GameIdeas.Shared/Dto/GameDto.cs
+++ b/src/GameIdeas/GameIdeas.Shared/Dto/GameDto.cs
@@ -14,9 +14,9 @@ public class GameDto
public double? StorageSpace { get; set; }
public string? Description { get; set; }
public int Interest { get; set; } = 3;
- public IEnumerable? Platforms { get; set; }
- public IEnumerable? Properties { get; set; }
- public IEnumerable? Tags { get; set; }
- public IEnumerable? Publishers { get; set; }
- public IEnumerable? Developers { get; set; }
+ public List? Platforms { get; set; }
+ public List? Properties { get; set; }
+ public List? Tags { get; set; }
+ public List? Publishers { get; set; }
+ public List? Developers { get; set; }
}
\ No newline at end of file
diff --git a/src/GameIdeas/GameIdeas.Shared/Dto/GameFilterDto.cs b/src/GameIdeas/GameIdeas.Shared/Dto/GameFilterDto.cs
index 25ba67c..d2922c2 100644
--- a/src/GameIdeas/GameIdeas.Shared/Dto/GameFilterDto.cs
+++ b/src/GameIdeas/GameIdeas.Shared/Dto/GameFilterDto.cs
@@ -1,16 +1,19 @@
-namespace GameIdeas.Shared.Dto;
+
+namespace GameIdeas.Shared.Dto;
public class GameFilterDto
{
- public IEnumerable? Platforms { get; set; }
- public string? Name { get; set; }
- public IEnumerable? Tags { get; set; }
- public IEnumerable? Properties { get; set; }
- public int? MinInterest { get; set; }
- public int? MaxInterest { get; set; }
- public IEnumerable? ReleaseYears { get; set; }
- public IEnumerable? PublisherIds { get; set; }
- public IEnumerable? DeveloperIds { get; set; }
- public IEnumerable? CreationUserIds { get; set; }
- public IEnumerable? ModificationUserIds { get; set; }
+ public SortTypeDto? SortType { get; set; }
+ public SortPropertyDto? SortProperty { get; set; }
+ public string? Title { get; set; }
+ public List? Platforms { get; set; }
+ public List? Properties { get; set; }
+ public List? Tags { get; set; }
+ public List? Publishers { get; set; }
+ public List? Developers { get; set; }
+ 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; }
}
diff --git a/src/GameIdeas/GameIdeas.Shared/Dto/SortPropertyDto.cs b/src/GameIdeas/GameIdeas.Shared/Dto/SortPropertyDto.cs
new file mode 100644
index 0000000..5f54704
--- /dev/null
+++ b/src/GameIdeas/GameIdeas.Shared/Dto/SortPropertyDto.cs
@@ -0,0 +1,7 @@
+namespace GameIdeas.Shared.Dto;
+
+public class SortPropertyDto
+{
+ public Func? SortProperty { get; set; }
+ public string Label { get; set; } = string.Empty;
+}
diff --git a/src/GameIdeas/GameIdeas.Shared/Dto/SortTypeDto.cs b/src/GameIdeas/GameIdeas.Shared/Dto/SortTypeDto.cs
new file mode 100644
index 0000000..6c7b927
--- /dev/null
+++ b/src/GameIdeas/GameIdeas.Shared/Dto/SortTypeDto.cs
@@ -0,0 +1,9 @@
+using GameIdeas.Shared.Enum;
+
+namespace GameIdeas.Shared.Dto;
+
+public class SortTypeDto
+{
+ public SortType SortType { get; set; } = SortType.Ascending;
+ public string Label { get; set; } = string.Empty;
+}
diff --git a/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json b/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json
index 5185f4f..a3ec135 100644
--- a/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json
+++ b/src/GameIdeas/Server/GameIdeas.WebAPI/Files/GameIdeas.fr.json
@@ -11,7 +11,7 @@
"LastAdd": "Les ajouts récents",
"Research": "Rechercher",
"Platforms": "Plateformes",
- "Genres": "Genres",
+ "Tags": "Genres",
"Publishers": "Editeurs",
"Developers": "Développeurs",
"StorageSize": "Taille d'espace",
diff --git a/src/GameIdeas/Server/GameIdeas.WebAPI/Services/CategoryService.cs b/src/GameIdeas/Server/GameIdeas.WebAPI/Services/CategoryService.cs
index 5a1aefc..f3650a1 100644
--- a/src/GameIdeas/Server/GameIdeas.WebAPI/Services/CategoryService.cs
+++ b/src/GameIdeas/Server/GameIdeas.WebAPI/Services/CategoryService.cs
@@ -18,11 +18,11 @@ public class CategoryService(GameIdeasContext context, IMapper mapper) : ICatego
return new()
{
- Platforms = mapper.Map>(platforms),
- Properties = mapper.Map>(properties),
- Tags = mapper.Map>(tags),
- Developers = mapper.Map>(developers),
- Publishers = mapper.Map>(publishers)
+ Platforms = mapper.Map>(platforms),
+ Properties = mapper.Map>(properties),
+ Tags = mapper.Map>(tags),
+ Developers = mapper.Map>(developers),
+ Publishers = mapper.Map>(publishers)
};
}
}