From e368d4a07520244083b24175deaa55f7de08d7ef Mon Sep 17 00:00:00 2001 From: Jason Dove Date: Fri, 16 Apr 2021 15:59:31 -0500 Subject: [PATCH] fix collections paging (#171) --- .../Commands/SaveConfigElementByKey.cs | 7 ++++ .../Commands/SaveConfigElementByKeyHandler.cs | 34 +++++++++++++++++++ .../Configuration/ConfigElementViewModel.cs | 4 +++ ErsatzTV.Application/Configuration/Mapper.cs | 8 +++++ .../Queries/GetConfigElementByKey.cs | 8 +++++ .../Queries/GetConfigElementByKeyHandler.cs | 22 ++++++++++++ .../Commands/UpdateFFmpegSettingsHandler.cs | 7 ++-- ErsatzTV.Core/Domain/ConfigElementKey.cs | 1 + .../Repositories/MediaCollectionRepository.cs | 2 +- ErsatzTV/Pages/Collections.razor | 20 +++++------ 10 files changed, 100 insertions(+), 13 deletions(-) create mode 100644 ErsatzTV.Application/Configuration/Commands/SaveConfigElementByKey.cs create mode 100644 ErsatzTV.Application/Configuration/Commands/SaveConfigElementByKeyHandler.cs create mode 100644 ErsatzTV.Application/Configuration/ConfigElementViewModel.cs create mode 100644 ErsatzTV.Application/Configuration/Mapper.cs create mode 100644 ErsatzTV.Application/Configuration/Queries/GetConfigElementByKey.cs create mode 100644 ErsatzTV.Application/Configuration/Queries/GetConfigElementByKeyHandler.cs diff --git a/ErsatzTV.Application/Configuration/Commands/SaveConfigElementByKey.cs b/ErsatzTV.Application/Configuration/Commands/SaveConfigElementByKey.cs new file mode 100644 index 000000000..26f2feef2 --- /dev/null +++ b/ErsatzTV.Application/Configuration/Commands/SaveConfigElementByKey.cs @@ -0,0 +1,7 @@ +using ErsatzTV.Core.Domain; +using MediatR; + +namespace ErsatzTV.Application.Configuration.Commands +{ + public record SaveConfigElementByKey(ConfigElementKey Key, string Value) : IRequest; +} diff --git a/ErsatzTV.Application/Configuration/Commands/SaveConfigElementByKeyHandler.cs b/ErsatzTV.Application/Configuration/Commands/SaveConfigElementByKeyHandler.cs new file mode 100644 index 000000000..504dd5cec --- /dev/null +++ b/ErsatzTV.Application/Configuration/Commands/SaveConfigElementByKeyHandler.cs @@ -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 + { + private readonly IConfigElementRepository _configElementRepository; + + public SaveConfigElementByKeyHandler(IConfigElementRepository configElementRepository) => + _configElementRepository = configElementRepository; + + public async Task Handle(SaveConfigElementByKey request, CancellationToken cancellationToken) + { + Option 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; + } + } +} diff --git a/ErsatzTV.Application/Configuration/ConfigElementViewModel.cs b/ErsatzTV.Application/Configuration/ConfigElementViewModel.cs new file mode 100644 index 000000000..e50b44cdf --- /dev/null +++ b/ErsatzTV.Application/Configuration/ConfigElementViewModel.cs @@ -0,0 +1,4 @@ +namespace ErsatzTV.Application.Configuration +{ + public record ConfigElementViewModel(string Key, string Value); +} diff --git a/ErsatzTV.Application/Configuration/Mapper.cs b/ErsatzTV.Application/Configuration/Mapper.cs new file mode 100644 index 000000000..9a1daf448 --- /dev/null +++ b/ErsatzTV.Application/Configuration/Mapper.cs @@ -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); + } +} diff --git a/ErsatzTV.Application/Configuration/Queries/GetConfigElementByKey.cs b/ErsatzTV.Application/Configuration/Queries/GetConfigElementByKey.cs new file mode 100644 index 000000000..96e6368c1 --- /dev/null +++ b/ErsatzTV.Application/Configuration/Queries/GetConfigElementByKey.cs @@ -0,0 +1,8 @@ +using ErsatzTV.Core.Domain; +using LanguageExt; +using MediatR; + +namespace ErsatzTV.Application.Configuration.Queries +{ + public record GetConfigElementByKey(ConfigElementKey Key) : IRequest>; +} diff --git a/ErsatzTV.Application/Configuration/Queries/GetConfigElementByKeyHandler.cs b/ErsatzTV.Application/Configuration/Queries/GetConfigElementByKeyHandler.cs new file mode 100644 index 000000000..76bac5641 --- /dev/null +++ b/ErsatzTV.Application/Configuration/Queries/GetConfigElementByKeyHandler.cs @@ -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> + { + private readonly IConfigElementRepository _configElementRepository; + + public GetConfigElementByKeyHandler(IConfigElementRepository configElementRepository) => + _configElementRepository = configElementRepository; + + public Task> Handle( + GetConfigElementByKey request, + CancellationToken cancellationToken) => + _configElementRepository.Get(request.Key).MapT(ProjectToViewModel); + } +} diff --git a/ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegSettingsHandler.cs b/ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegSettingsHandler.cs index 18a1c83ce..c4b53e699 100644 --- a/ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegSettingsHandler.cs +++ b/ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegSettingsHandler.cs @@ -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 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); }); + } } } diff --git a/ErsatzTV.Core/Domain/ConfigElementKey.cs b/ErsatzTV.Core/Domain/ConfigElementKey.cs index 329149a92..2b32937d7 100644 --- a/ErsatzTV.Core/Domain/ConfigElementKey.cs +++ b/ErsatzTV.Core/Domain/ConfigElementKey.cs @@ -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"); } } diff --git a/ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs index bc87c7c1d..5c3cb76d2 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs @@ -183,7 +183,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories ORDER BY Name LIMIT {0} OFFSET {1}", pageSize, - (pageNumber - 1) * pageSize) + pageNumber * pageSize) .AsNoTracking() .ToListAsync(); } diff --git a/ErsatzTV/Pages/Collections.razor b/ErsatzTV/Pages/Collections.razor index 86d63bf2a..f462e8138 100644 --- a/ErsatzTV/Pages/Collections.razor +++ b/ErsatzTV/Pages/Collections.razor @@ -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 + @ref="_table"> Collections @@ -55,11 +54,12 @@ @code { private MudTable _table; - protected override async Task OnAfterRenderAsync(bool firstRender) + private int _rowsPerPage; + + protected override async Task OnParametersSetAsync() { - int rowsPerPage = await LocalStorage.GetItemAsync("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> ServerReload(TableState state) { - await LocalStorage.SetItemAsync("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 { TotalItems = data.TotalCount, Items = data.Page };