Simplified and enhnaced voice work page.
This commit is contained in:
208
JSMR.UI.Blazor/Components/VoiceWorkFilters.razor
Normal file
208
JSMR.UI.Blazor/Components/VoiceWorkFilters.razor
Normal file
@@ -0,0 +1,208 @@
|
||||
@using JSMR.Application.Enums
|
||||
@using JSMR.Application.VoiceWorks.Queries.Search
|
||||
@using JSMR.Domain.Enums
|
||||
@using JSMR.Domain.ValueObjects
|
||||
@using JSMR.UI.Blazor.Enums
|
||||
@using JSMR.UI.Blazor.Filters
|
||||
@using JSMR.UI.Blazor.Services
|
||||
|
||||
<div class="search-filter-control-container">
|
||||
<div class="search-filter-control-span-2">
|
||||
<BitTextField Prefix="Keywords"
|
||||
Immediate="true" DebounceTime="500"
|
||||
Value="@Value.Keywords"
|
||||
ValueChanged="@(value => Update(Value with { Keywords = value }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-1">
|
||||
<BitDropdown Prefix="Languages"
|
||||
MultiSelect
|
||||
Items="languages"
|
||||
Placeholder="Select..."
|
||||
TItem="BitDropdownItem<Language>"
|
||||
TValue="Language"
|
||||
Values="@Value.SupportedLanguages"
|
||||
ValuesChanged="@(values => Update(Value with { SupportedLanguages = [.. values] }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-1">
|
||||
<BitDropdown Prefix="Locale"
|
||||
Items="locales"
|
||||
Placeholder="Select..."
|
||||
TItem="BitDropdownItem<Locale>"
|
||||
TValue="Locale"
|
||||
Value="@Value.Locale"
|
||||
ValueChanged="@(value => Update(Value with { Locale = value }))" />
|
||||
</div>
|
||||
<!-- Row 2 -->
|
||||
<div class="search-filter-control-span-1">
|
||||
<BitDropdown Prefix="Sale Status"
|
||||
Items="saleStatuses"
|
||||
Placeholder="Select..."
|
||||
TItem="BitDropdownItem<SaleStatus?>"
|
||||
TValue="SaleStatus ?"
|
||||
Value="@Value.SaleStatus"
|
||||
ValueChanged="@(value => Update(Value with { SaleStatus = value }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-1">
|
||||
<BitDropdown Prefix="Circles"
|
||||
Items="circleStatuses"
|
||||
Placeholder="Select..."
|
||||
TItem="BitDropdownItem<CircleStatus?>"
|
||||
TValue="CircleStatus ?"
|
||||
Value="@Value.CircleStatus"
|
||||
ValueChanged="@(value => Update(Value with { CircleStatus = value }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-1">
|
||||
<BitDropdown Prefix="Tags"
|
||||
Items="tagStatuses"
|
||||
Placeholder="Select..."
|
||||
TItem="BitDropdownItem<TagStatus?>"
|
||||
TValue="TagStatus ?"
|
||||
Value="@Value.TagStatus"
|
||||
ValueChanged="@(value => Update(Value with { TagStatus = value }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-1">
|
||||
<BitDropdown Prefix="Creators"
|
||||
Items="creatorStatuses"
|
||||
Placeholder="Select..."
|
||||
TItem="BitDropdownItem<CreatorStatus?>"
|
||||
TValue="CreatorStatus ?"
|
||||
Value="@Value.CreatorStatus"
|
||||
ValueChanged="@(value => Update(Value with { CreatorStatus = value }))" />
|
||||
</div>
|
||||
<!-- Row 3 -->
|
||||
<div class="search-filter-control-span-2">
|
||||
<BitDropdown Prefix="Tags"
|
||||
Items="tags"
|
||||
MultiSelect
|
||||
Virtualize
|
||||
ShowSearchBox
|
||||
AutoFocusSearchBox
|
||||
Chips
|
||||
Placeholder="Select..."
|
||||
TItem="BitDropdownItem<int>"
|
||||
TValue="int"
|
||||
Values="@Value.TagIds"
|
||||
ValuesChanged="@(values => Update(Value with { TagIds = [.. values] }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-1">
|
||||
<BitCheckbox Label="Include All Tags"
|
||||
Value="@Value.IncludeAllTags"
|
||||
ValueChanged="@(value => Update(Value with { IncludeAllTags = value }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-1"></div>
|
||||
<!-- Row 4 -->
|
||||
<div class="search-filter-control-span-2">
|
||||
<BitDropdown Prefix="Creators"
|
||||
Items="creators"
|
||||
MultiSelect
|
||||
Virtualize
|
||||
ShowSearchBox
|
||||
AutoFocusSearchBox
|
||||
Chips
|
||||
Placeholder="Select..."
|
||||
TItem="BitDropdownItem<int>"
|
||||
TValue="int"
|
||||
Values="@Value.CreatorIds"
|
||||
ValuesChanged="@(values => Update(Value with { CreatorIds = [.. values] }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-1">
|
||||
<BitCheckbox Label="Include All Creators"
|
||||
Value="@Value.IncludeAllCreators"
|
||||
ValueChanged="@(value => Update(Value with { IncludeAllCreators = value }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-1"></div>
|
||||
<!-- Row 5 -->
|
||||
<div class="search-filter-control-span-1">
|
||||
<BitCheckbox Label="Show Only Favorite Works"
|
||||
Value="@Value.ShowFavorite"
|
||||
ValueChanged="@(value => Update(Value with { ShowFavorite = value }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-1">
|
||||
<BitCheckbox Label="Show Only Invalid Works"
|
||||
Value="@Value.ShowInvalid"
|
||||
ValueChanged="@(value => Update(Value with { ShowInvalid = value }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-2"></div>
|
||||
<div class="search-filter-control-span-1">
|
||||
<BitDropdown Label="Age Ratings"
|
||||
MultiSelect
|
||||
Items="ageRatings"
|
||||
Placeholder="Select..."
|
||||
TItem="BitDropdownItem<AgeRating>"
|
||||
TValue="AgeRating"
|
||||
Values="@Value.AgeRatings"
|
||||
ValuesChanged="@(values => Update(Value with { AgeRatings = [.. values] }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-1">
|
||||
<BitDatePicker Label="Release Date Start"
|
||||
ShowClearButton="true"
|
||||
Value="@ToDto(Value.ReleaseDateStart)"
|
||||
ValueChanged="@(value => Update(Value with { ReleaseDateStart = FromDto(value) }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-1">
|
||||
<BitDatePicker Label="Release Date End"
|
||||
ShowClearButton="true"
|
||||
Value="@ToDto(Value.ReleaseDateEnd)"
|
||||
ValueChanged="@(value => Update(Value with { ReleaseDateEnd = FromDto(value) }))" />
|
||||
</div>
|
||||
<div class="search-filter-control-span-2">
|
||||
<BitDropdown Prefix="Sort"
|
||||
Items="sortOptions"
|
||||
Placeholder="Select..."
|
||||
TItem="BitDropdownItem<VoiceWorkSort>"
|
||||
TValue="VoiceWorkSort"
|
||||
Value="@Value.Sort"
|
||||
ValueChanged="@(value => Update(Value with { Sort = value }))" />
|
||||
</div>
|
||||
@* <div class="search-filter-control-span-1">
|
||||
<BitSlider Label="Downloads" Min="0" Max="100000" Value="MinDownloads" ValueChanged="OnMinDownloadsChanged" />
|
||||
</div> *@
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Inject]
|
||||
ILookupDataService Lookups { get; set; } = default!;
|
||||
|
||||
[Parameter]
|
||||
public VoiceWorkFilterState Value { get; set; } = new();
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<VoiceWorkFilterState> ValueChanged { get; set; }
|
||||
|
||||
List<BitDropdownItem<Locale>> locales = [];
|
||||
List<BitDropdownItem<SaleStatus?>> saleStatuses = [];
|
||||
List<BitDropdownItem<CircleStatus?>> circleStatuses = [];
|
||||
List<BitDropdownItem<TagStatus?>> tagStatuses = [];
|
||||
List<BitDropdownItem<CreatorStatus?>> creatorStatuses = [];
|
||||
List<BitDropdownItem<Language>> languages = [];
|
||||
List<BitDropdownItem<AgeRating>> ageRatings = [];
|
||||
List<BitDropdownItem<VoiceWorkSort>> sortOptions = [];
|
||||
List<BitDropdownItem<int>> tags = [];
|
||||
List<BitDropdownItem<int>> creators = [];
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
locales = Lookups.GetLocales();
|
||||
saleStatuses = Lookups.GetSaleStatuses();
|
||||
circleStatuses = Lookups.GetCircleStatuses();
|
||||
tagStatuses = Lookups.GetTagStatuses();
|
||||
creatorStatuses = Lookups.GetCreatorStatuses();
|
||||
languages = Lookups.GetLanguages();
|
||||
ageRatings = Lookups.GetAgeRatings();
|
||||
sortOptions = Lookups.GetSortOptions();
|
||||
|
||||
(tags, creators) = (await Lookups.GetTagsAsync(), await Lookups.GetCreatorsAsync());
|
||||
}
|
||||
|
||||
private Task Update(VoiceWorkFilterState next)
|
||||
=> ValueChanged.InvokeAsync(next with { PageNumber = 1 });
|
||||
|
||||
// Map DateOnly? -> DateTimeOffset? (UTC midnight to avoid TZ drift)
|
||||
private static DateTimeOffset? ToDto(DateOnly? d) =>
|
||||
d is null ? null
|
||||
: new DateTimeOffset(d.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified), TimeSpan.Zero);
|
||||
|
||||
// Map DateTimeOffset? -> DateOnly?
|
||||
private static DateOnly? FromDto(DateTimeOffset? dto) =>
|
||||
dto is null ? null : DateOnly.FromDateTime(dto.Value.Date);
|
||||
}
|
||||
Reference in New Issue
Block a user