Browse Source

fix collections paging (#171)

pull/173/head
Jason Dove 5 years ago committed by GitHub
parent
commit
e368d4a075
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      ErsatzTV.Application/Configuration/Commands/SaveConfigElementByKey.cs
  2. 34
      ErsatzTV.Application/Configuration/Commands/SaveConfigElementByKeyHandler.cs
  3. 4
      ErsatzTV.Application/Configuration/ConfigElementViewModel.cs
  4. 8
      ErsatzTV.Application/Configuration/Mapper.cs
  5. 8
      ErsatzTV.Application/Configuration/Queries/GetConfigElementByKey.cs
  6. 22
      ErsatzTV.Application/Configuration/Queries/GetConfigElementByKeyHandler.cs
  7. 7
      ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegSettingsHandler.cs
  8. 1
      ErsatzTV.Core/Domain/ConfigElementKey.cs
  9. 2
      ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs
  10. 20
      ErsatzTV/Pages/Collections.razor

7
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<LanguageExt.Unit>;
}

34
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<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;
}
}
}

4
ErsatzTV.Application/Configuration/ConfigElementViewModel.cs

@ -0,0 +1,4 @@
namespace ErsatzTV.Application.Configuration
{
public record ConfigElementViewModel(string Key, string Value);
}

8
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);
}
}

8
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<Option<ConfigElementViewModel>>;
}

22
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<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);
}
}

7
ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegSettingsHandler.cs

@ -86,8 +86,10 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
return Unit.Default; return Unit.Default;
} }
private Task Upsert(ConfigElementKey key, string value) => private async Task Upsert(ConfigElementKey key, string value)
_configElementRepository.Get(key).Match( {
Option<ConfigElement> maybeElement = await _configElementRepository.Get(key);
await maybeElement.Match(
ce => ce =>
{ {
ce.Value = value; ce.Value = value;
@ -98,5 +100,6 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
var ce = new ConfigElement { Key = key.Key, Value = value }; var ce = new ConfigElement { Key = key.Key, Value = value };
return _configElementRepository.Add(ce); return _configElementRepository.Add(ce);
}); });
}
} }
} }

1
ErsatzTV.Core/Domain/ConfigElementKey.cs

@ -14,5 +14,6 @@
public static ConfigElementKey FFmpegPreferredLanguageCode => new("ffmpeg.preferred_language_code"); public static ConfigElementKey FFmpegPreferredLanguageCode => new("ffmpeg.preferred_language_code");
public static ConfigElementKey SearchIndexVersion => new("search_index.version"); public static ConfigElementKey SearchIndexVersion => new("search_index.version");
public static ConfigElementKey HDHRTunerCount => new("hdhr.tuner_count"); public static ConfigElementKey HDHRTunerCount => new("hdhr.tuner_count");
public static ConfigElementKey CollectionsPageSize => new("pages.collections.page_size");
} }
} }

2
ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs

@ -183,7 +183,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
ORDER BY Name ORDER BY Name
LIMIT {0} OFFSET {1}", LIMIT {0} OFFSET {1}",
pageSize, pageSize,
(pageNumber - 1) * pageSize) pageNumber * pageSize)
.AsNoTracking() .AsNoTracking()
.ToListAsync(); .ToListAsync();
} }

20
ErsatzTV/Pages/Collections.razor

@ -1,20 +1,19 @@
@page "/media/collections" @page "/media/collections"
@using Microsoft.Extensions.Caching.Memory @using ErsatzTV.Application.Configuration.Commands
@using Blazored.LocalStorage @using ErsatzTV.Application.Configuration.Queries
@using ErsatzTV.Application.MediaCollections @using ErsatzTV.Application.MediaCollections
@using ErsatzTV.Application.MediaCollections.Commands @using ErsatzTV.Application.MediaCollections.Commands
@using ErsatzTV.Application.MediaCollections.Queries @using ErsatzTV.Application.MediaCollections.Queries
@using ErsatzTV.Application.MediaCards @using ErsatzTV.Application.MediaCards
@inject IDialogService Dialog @inject IDialogService Dialog
@inject IMediator Mediator @inject IMediator Mediator
@inject IMemoryCache MemoryCache
@inject ILocalStorageService LocalStorage
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudTable Hover="true" <MudTable Hover="true"
@bind-RowsPerPage="@_rowsPerPage"
ServerData="@(new Func<TableState, Task<TableData<MediaCollectionViewModel>>>(ServerReload))" ServerData="@(new Func<TableState, Task<TableData<MediaCollectionViewModel>>>(ServerReload))"
Dense="true" Dense="true"
@ref=" _table"> @ref="_table">
<ToolBarContent> <ToolBarContent>
<MudText Typo="Typo.h6">Collections</MudText> <MudText Typo="Typo.h6">Collections</MudText>
</ToolBarContent> </ToolBarContent>
@ -55,11 +54,12 @@
@code { @code {
private MudTable<MediaCollectionViewModel> _table; 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; _rowsPerPage = await Mediator.Send(new GetConfigElementByKey(ConfigElementKey.CollectionsPageSize))
_table.RowsPerPage = rowsPerPage; .Map(maybeRows => maybeRows.Match(ce => int.TryParse(ce.Value, out int rows) ? rows : 10, () => 10));
await _table.ReloadServerData();
} }
private async Task DeleteMediaCollection(MediaCardViewModel vm) private async Task DeleteMediaCollection(MediaCardViewModel vm)
@ -82,7 +82,7 @@
private async Task<TableData<MediaCollectionViewModel>> ServerReload(TableState state) 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)); PagedMediaCollectionsViewModel data = await Mediator.Send(new GetPagedCollections(state.Page, state.PageSize));
return new TableData<MediaCollectionViewModel> { TotalItems = data.TotalCount, Items = data.Page }; return new TableData<MediaCollectionViewModel> { TotalItems = data.TotalCount, Items = data.Page };

Loading…
Cancel
Save