fix collections paging (#171)
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
using ErsatzTV.Core.Domain;
|
||||
using MediatR;
|
||||
|
||||
namespace ErsatzTV.Application.Configuration.Commands
|
||||
{
|
||||
public record SaveConfigElementByKey(ConfigElementKey Key, string Value) : IRequest<LanguageExt.Unit>;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ErsatzTV.Core.Domain;
|
||||
using ErsatzTV.Core.Interfaces.Repositories;
|
||||
using LanguageExt;
|
||||
|
||||
namespace ErsatzTV.Application.Configuration.Commands
|
||||
{
|
||||
public class SaveConfigElementByKeyHandler : MediatR.IRequestHandler<SaveConfigElementByKey, Unit>
|
||||
{
|
||||
private readonly IConfigElementRepository _configElementRepository;
|
||||
|
||||
public SaveConfigElementByKeyHandler(IConfigElementRepository configElementRepository) =>
|
||||
_configElementRepository = configElementRepository;
|
||||
|
||||
public async Task<Unit> Handle(SaveConfigElementByKey request, CancellationToken cancellationToken)
|
||||
{
|
||||
Option<ConfigElement> maybeElement = await _configElementRepository.Get(request.Key);
|
||||
await maybeElement.Match(
|
||||
ce =>
|
||||
{
|
||||
ce.Value = request.Value;
|
||||
return _configElementRepository.Update(ce);
|
||||
},
|
||||
() =>
|
||||
{
|
||||
var ce = new ConfigElement { Key = request.Key.Key, Value = request.Value };
|
||||
return _configElementRepository.Add(ce);
|
||||
});
|
||||
|
||||
return Unit.Default;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
namespace ErsatzTV.Application.Configuration
|
||||
{
|
||||
public record ConfigElementViewModel(string Key, string Value);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace ErsatzTV.Application.Configuration
|
||||
{
|
||||
internal static class Mapper
|
||||
{
|
||||
internal static ConfigElementViewModel ProjectToViewModel(Core.Domain.ConfigElement element) =>
|
||||
new(element.Key, element.Value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using ErsatzTV.Core.Domain;
|
||||
using LanguageExt;
|
||||
using MediatR;
|
||||
|
||||
namespace ErsatzTV.Application.Configuration.Queries
|
||||
{
|
||||
public record GetConfigElementByKey(ConfigElementKey Key) : IRequest<Option<ConfigElementViewModel>>;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ErsatzTV.Core.Interfaces.Repositories;
|
||||
using LanguageExt;
|
||||
using MediatR;
|
||||
using static ErsatzTV.Application.Configuration.Mapper;
|
||||
|
||||
namespace ErsatzTV.Application.Configuration.Queries
|
||||
{
|
||||
public class GetConfigElementByKeyHandler : IRequestHandler<GetConfigElementByKey, Option<ConfigElementViewModel>>
|
||||
{
|
||||
private readonly IConfigElementRepository _configElementRepository;
|
||||
|
||||
public GetConfigElementByKeyHandler(IConfigElementRepository configElementRepository) =>
|
||||
_configElementRepository = configElementRepository;
|
||||
|
||||
public Task<Option<ConfigElementViewModel>> Handle(
|
||||
GetConfigElementByKey request,
|
||||
CancellationToken cancellationToken) =>
|
||||
_configElementRepository.Get(request.Key).MapT(ProjectToViewModel);
|
||||
}
|
||||
}
|
||||
@@ -86,8 +86,10 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
|
||||
return Unit.Default;
|
||||
}
|
||||
|
||||
private Task Upsert(ConfigElementKey key, string value) =>
|
||||
_configElementRepository.Get(key).Match(
|
||||
private async Task Upsert(ConfigElementKey key, string value)
|
||||
{
|
||||
Option<ConfigElement> maybeElement = await _configElementRepository.Get(key);
|
||||
await maybeElement.Match(
|
||||
ce =>
|
||||
{
|
||||
ce.Value = value;
|
||||
@@ -98,5 +100,6 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
|
||||
var ce = new ConfigElement { Key = key.Key, Value = value };
|
||||
return _configElementRepository.Add(ce);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,5 +14,6 @@
|
||||
public static ConfigElementKey FFmpegPreferredLanguageCode => new("ffmpeg.preferred_language_code");
|
||||
public static ConfigElementKey SearchIndexVersion => new("search_index.version");
|
||||
public static ConfigElementKey HDHRTunerCount => new("hdhr.tuner_count");
|
||||
public static ConfigElementKey CollectionsPageSize => new("pages.collections.page_size");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
||||
ORDER BY Name
|
||||
LIMIT {0} OFFSET {1}",
|
||||
pageSize,
|
||||
(pageNumber - 1) * pageSize)
|
||||
pageNumber * pageSize)
|
||||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
@page "/media/collections"
|
||||
@using Microsoft.Extensions.Caching.Memory
|
||||
@using Blazored.LocalStorage
|
||||
@using ErsatzTV.Application.Configuration.Commands
|
||||
@using ErsatzTV.Application.Configuration.Queries
|
||||
@using ErsatzTV.Application.MediaCollections
|
||||
@using ErsatzTV.Application.MediaCollections.Commands
|
||||
@using ErsatzTV.Application.MediaCollections.Queries
|
||||
@using ErsatzTV.Application.MediaCards
|
||||
@inject IDialogService Dialog
|
||||
@inject IMediator Mediator
|
||||
@inject IMemoryCache MemoryCache
|
||||
@inject ILocalStorageService LocalStorage
|
||||
|
||||
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
|
||||
<MudTable Hover="true"
|
||||
@bind-RowsPerPage="@_rowsPerPage"
|
||||
ServerData="@(new Func<TableState, Task<TableData<MediaCollectionViewModel>>>(ServerReload))"
|
||||
Dense="true"
|
||||
@ref=" _table">
|
||||
@ref="_table">
|
||||
<ToolBarContent>
|
||||
<MudText Typo="Typo.h6">Collections</MudText>
|
||||
</ToolBarContent>
|
||||
@@ -55,11 +54,12 @@
|
||||
@code {
|
||||
private MudTable<MediaCollectionViewModel> _table;
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
private int _rowsPerPage;
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
int rowsPerPage = await LocalStorage.GetItemAsync<int?>("pages.collections.rows_per_page") ?? 10;
|
||||
_table.RowsPerPage = rowsPerPage;
|
||||
await _table.ReloadServerData();
|
||||
_rowsPerPage = await Mediator.Send(new GetConfigElementByKey(ConfigElementKey.CollectionsPageSize))
|
||||
.Map(maybeRows => maybeRows.Match(ce => int.TryParse(ce.Value, out int rows) ? rows : 10, () => 10));
|
||||
}
|
||||
|
||||
private async Task DeleteMediaCollection(MediaCardViewModel vm)
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
private async Task<TableData<MediaCollectionViewModel>> ServerReload(TableState state)
|
||||
{
|
||||
await LocalStorage.SetItemAsync<int?>("pages.collections.rows_per_page", state.PageSize);
|
||||
await Mediator.Send(new SaveConfigElementByKey(ConfigElementKey.CollectionsPageSize, state.PageSize.ToString()));
|
||||
|
||||
PagedMediaCollectionsViewModel data = await Mediator.Send(new GetPagedCollections(state.Page, state.PageSize));
|
||||
return new TableData<MediaCollectionViewModel> { TotalItems = data.TotalCount, Items = data.Page };
|
||||
|
||||
Reference in New Issue
Block a user