Merge pull request #126 from mateuszskoczek/features/person_database_page

people database page created
This commit is contained in:
2024-10-21 21:45:50 +02:00
committed by GitHub
Unverified
6 changed files with 225 additions and 85 deletions

View File

@@ -47,6 +47,8 @@
@if (_loaded) @if (_loaded)
{ {
if (string.IsNullOrWhiteSpace(_error)) if (string.IsNullOrWhiteSpace(_error))
{
if (_items.Count > 0)
{ {
foreach (TItem item in _items) foreach (TItem item in _items)
{ {
@@ -76,6 +78,15 @@
} }
} }
else else
{
<div class="panel">
<div class="d-flex justify-content-center">
<span>No items found</span>
</div>
</div>
}
}
else
{ {
<ErrorPanelComponent ErrorMessage="@_error"/> <ErrorPanelComponent ErrorMessage="@_error"/>
} }

View File

@@ -0,0 +1,71 @@
@using WatchIt.Common.Model.Genders
@inherits FilterFormComponent<WatchIt.Common.Model.Persons.PersonResponse, WatchIt.Common.Model.Persons.PersonQueryParameters>
<EditForm Model="@(Query)">
<div class="container-grid">
<div class="row mb-1">
<div class="input-group input-group-sm">
<span class="col-3 input-group-text">Name</span>
<InputText class="col form-control" placeholder="Search with regex" @bind-Value="@(Query.Name)"></InputText>
</div>
</div>
<div class="row my-1">
<div class="input-group input-group-sm">
<span class="col-3 input-group-text">Full name</span>
<InputText class="col form-control" placeholder="Search with regex" @bind-Value="@(Query.FullName)"/>
</div>
</div>
<div class="row my-1">
<div class="input-group input-group-sm">
<span class="col-3 input-group-text">Description</span>
<InputText class="col form-control" placeholder="Search with regex" @bind-Value="@(Query.Description)"/>
</div>
</div>
<div class="row my-1">
<div class="input-group input-group-sm">
<span class="col-3 input-group-text">Birth date</span>
<InputDate TValue="DateOnly?" class="col form-control" @bind-Value="@(Query.BirthDateFrom)"/>
<span class="col-auto input-group-text">-</span>
<InputDate TValue="DateOnly?" class="col form-control" @bind-Value="@(Query.BirthDateTo)"/>
</div>
</div>
<div class="row my-1">
<div class="input-group input-group-sm">
<span class="col-3 input-group-text">Death date</span>
<InputDate TValue="DateOnly?" class="col form-control" @bind-Value="@(Query.DeathDateFrom)"/>
<span class="col-auto input-group-text">-</span>
<InputDate TValue="DateOnly?" class="col form-control" @bind-Value="@(Query.DeathDateTo)"/>
</div>
</div>
<div class="row my-1">
<div class="input-group input-group-sm">
<span class="col-3 input-group-text">Gender</span>
<InputSelect TValue="short?" class="col form-control" @bind-Value="@(Query.GenderId)">
<option @onclick="() => Query.GenderId = null">No choice</option>
@foreach (GenderResponse gender in _genders)
{
<option value="@(gender.Id)">@(gender.Name)</option>
}
</InputSelect>
</div>
</div>
<div class="row my-1">
<div class="input-group input-group-sm">
<span class="col-3 input-group-text">Rating (count)</span>
<NumericEdit TValue="long?" Class="col form-control" Min="0" @bind-Value="@(Query.RatingCountFrom)"/>
<span class="col-auto input-group-text">-</span>
<NumericEdit TValue="long?" Class="col form-control" Min="0" @bind-Value="@(Query.RatingCountTo)"/>
</div>
</div>
<div class="row mt-1">
<div class="input-group input-group-sm">
<span class="col-3 input-group-text">Rating (average)</span>
<NumericEdit TValue="decimal?" Class="col form-control" Min="0" Max="10" Step="@(0.01M)" @bind-Value="@(Query.RatingAverageFrom)"/>
<span class="col-auto input-group-text">-</span>
<NumericEdit TValue="decimal?" Class="col form-control" Min="0" Max="10" Step="@(0.01M)" @bind-Value="@(Query.RatingAverageTo)"/>
</div>
</div>
</div>
</EditForm>

View File

@@ -0,0 +1,48 @@
using Microsoft.AspNetCore.Components;
using WatchIt.Common.Model.Genders;
using WatchIt.Common.Model.Persons;
using WatchIt.Website.Services.WebAPI.Genders;
namespace WatchIt.Website.Components.Pages.DatabasePage.Subcomponents;
public partial class PersonsFilterFormComponent : FilterFormComponent<PersonResponse, PersonQueryParameters>
{
#region SERVICES
[Inject] private IGendersWebAPIService GendersWebAPIService { get; set; } = default!;
#endregion
#region FIELDS
private IEnumerable<GenderResponse> _genders = [];
#endregion
#region PRIVATE METHODS
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
List<Task> endTasks = new List<Task>();
// STEP 0
endTasks.AddRange(
[
GendersWebAPIService.GetAllGenders(successAction: data => _genders = data)
]);
// END
await Task.WhenAll(endTasks);
StateHasChanged();
}
}
#endregion
}

View File

@@ -37,6 +37,7 @@
<DropdownMenu> <DropdownMenu>
<DropdownItem Clicked="@(() => NavigationManager.NavigateTo("/database/movies"))">Movies</DropdownItem> <DropdownItem Clicked="@(() => NavigationManager.NavigateTo("/database/movies"))">Movies</DropdownItem>
<DropdownItem Clicked="@(() => NavigationManager.NavigateTo("/database/series"))">TV Series</DropdownItem> <DropdownItem Clicked="@(() => NavigationManager.NavigateTo("/database/series"))">TV Series</DropdownItem>
<DropdownItem Clicked="@(() => NavigationManager.NavigateTo("/database/people"))">People</DropdownItem>
</DropdownMenu> </DropdownMenu>
</Dropdown> </Dropdown>
<button type="button" class="btn btn-sm" @onclick="@(() => _searchbarVisible = true)">⌕</button> <button type="button" class="btn btn-sm" @onclick="@(() => _searchbarVisible = true)">⌕</button>

View File

@@ -1,4 +1,5 @@
@using WatchIt.Common.Model.Movies @using WatchIt.Common.Model.Movies
@using WatchIt.Common.Model.Persons
@using WatchIt.Common.Model.Series @using WatchIt.Common.Model.Series
@using WatchIt.Website.Components.Pages.DatabasePage @using WatchIt.Website.Components.Pages.DatabasePage
@using WatchIt.Website.Components.Pages.DatabasePage.Subcomponents @using WatchIt.Website.Components.Pages.DatabasePage.Subcomponents
@@ -17,15 +18,17 @@
case "series": case "series":
@("Series"); @("Series");
break; break;
case "people":
@("People");
break;
} }
@(" database") @(" database")
</PageTitle> </PageTitle>
@if (_loaded)
@switch (Type)
{ {
switch (Type)
{
case "movies": case "movies":
<DatabasePageComponent TItem="MovieResponse" <DatabasePageComponent TItem="MovieResponse"
TQuery="MovieQueryParameters" TQuery="MovieQueryParameters"
@@ -68,12 +71,25 @@
<SeriesFilterFormComponent/> <SeriesFilterFormComponent/>
</DatabasePageComponent> </DatabasePageComponent>
break; break;
} case "people":
<DatabasePageComponent TItem="PersonResponse"
} TQuery="PersonQueryParameters"
else Title="People database"
{ IdSource="@(item => item.Id)"
<div class="m-5"> NameSource="@(item => item.Name)"
<LoadingComponent/> RatingSource="@(item => item.Rating)"
</div> UrlIdTemplate="/person/{0}"
PictureDownloadingTask="@((id, action) => PersonsWebAPIService.GetPersonPhoto(id, action))"
ItemDownloadingTask="@(PersonsWebAPIService.GetAllPersons)"
SortingOptions="@(new Dictionary<string, string>
{
{ "rating.count", "Number of ratings" },
{ "rating.average", "Average rating" },
{ "name", "Name" },
{ "birth_date", "Birth date" },
{ "death_date", "Death date" },
})">
<PersonsFilterFormComponent/>
</DatabasePageComponent>
break;
} }

View File

@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using WatchIt.Website.Services.WebAPI.Media; using WatchIt.Website.Services.WebAPI.Media;
using WatchIt.Website.Services.WebAPI.Movies; using WatchIt.Website.Services.WebAPI.Movies;
using WatchIt.Website.Services.WebAPI.Persons;
using WatchIt.Website.Services.WebAPI.Series; using WatchIt.Website.Services.WebAPI.Series;
namespace WatchIt.Website.Pages; namespace WatchIt.Website.Pages;
@@ -13,6 +14,7 @@ public partial class DatabasePage : ComponentBase
[Inject] private IMediaWebAPIService MediaWebAPIService { get; set; } = default!; [Inject] private IMediaWebAPIService MediaWebAPIService { get; set; } = default!;
[Inject] private IMoviesWebAPIService MoviesWebAPIService { get; set; } = default!; [Inject] private IMoviesWebAPIService MoviesWebAPIService { get; set; } = default!;
[Inject] private ISeriesWebAPIService SeriesWebAPIService { get; set; } = default!; [Inject] private ISeriesWebAPIService SeriesWebAPIService { get; set; } = default!;
[Inject] private IPersonsWebAPIService PersonsWebAPIService { get; set; } = default!;
#endregion #endregion
@@ -28,9 +30,7 @@ public partial class DatabasePage : ComponentBase
#region FIELDS #region FIELDS
private static IEnumerable<string> _databaseTypes = ["movies", "series"]; private static IEnumerable<string> _databaseTypes = ["movies", "series", "people"];
private bool _loaded;
#endregion #endregion
@@ -38,19 +38,12 @@ public partial class DatabasePage : ComponentBase
#region PRIVATE METHODS #region PRIVATE METHODS
protected override async Task OnAfterRenderAsync(bool firstRender) protected override void OnParametersSet()
{ {
if (firstRender)
{
// INIT
if (!_databaseTypes.Contains(Type)) if (!_databaseTypes.Contains(Type))
{ {
NavigationManager.NavigateTo($"/database/{_databaseTypes.First()}"); NavigationManager.NavigateTo($"/database/{_databaseTypes.First()}");
} }
_loaded = true;
StateHasChanged();
}
} }
#endregion #endregion