Browse Source

delete library path from ui

pull/31/head
Jason Dove 6 years ago
parent
commit
c09cc36ca3
  1. 7
      ErsatzTV.Application/Libraries/Commands/DeleteLocalLibraryPath.cs
  2. 34
      ErsatzTV.Application/Libraries/Commands/DeleteLocalLibraryPathHandler.cs
  3. 6
      ErsatzTV.Application/Libraries/Queries/CountMediaItemsByLibraryPath.cs
  4. 18
      ErsatzTV.Application/Libraries/Queries/CountMediaItemsByLibraryPathHandler.cs
  5. 3
      ErsatzTV.Core/Interfaces/Repositories/ILibraryRepository.cs
  6. 22
      ErsatzTV.Infrastructure/Data/Repositories/LibraryRepository.cs
  7. 1
      ErsatzTV.Infrastructure/Data/TvContext.cs
  8. 24
      ErsatzTV/Pages/LocalLibraryEditor.razor

7
ErsatzTV.Application/Libraries/Commands/DeleteLocalLibraryPath.cs

@ -0,0 +1,7 @@
using ErsatzTV.Core;
using LanguageExt;
namespace ErsatzTV.Application.Libraries.Commands
{
public record DeleteLocalLibraryPath(int LocalLibraryPathId) : MediatR.IRequest<Either<BaseError, Unit>>;
}

34
ErsatzTV.Application/Libraries/Commands/DeleteLocalLibraryPathHandler.cs

@ -0,0 +1,34 @@
using System.Threading;
using System.Threading.Tasks;
using ErsatzTV.Core;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Repositories;
using LanguageExt;
namespace ErsatzTV.Application.Libraries.Commands
{
public class
DeleteLocalLibraryPathHandler : MediatR.IRequestHandler<DeleteLocalLibraryPath, Either<BaseError, Unit>>
{
private readonly ILibraryRepository _libraryRepository;
public DeleteLocalLibraryPathHandler(ILibraryRepository libraryRepository) =>
_libraryRepository = libraryRepository;
public Task<Either<BaseError, Unit>> Handle(
DeleteLocalLibraryPath request,
CancellationToken cancellationToken) =>
MediaSourceMustExist(request)
.MapT(DoDeletion)
.Bind(t => t.ToEitherAsync());
private Task<Unit> DoDeletion(LibraryPath libraryPath) =>
_libraryRepository.DeleteLocalPath(libraryPath.Id).ToUnit();
private async Task<Validation<BaseError, LibraryPath>> MediaSourceMustExist(DeleteLocalLibraryPath request) =>
(await _libraryRepository.GetPath(request.LocalLibraryPathId))
.HeadOrNone()
.ToValidation<BaseError>(
$"Local library path {request.LocalLibraryPathId} does not exist.");
}
}

6
ErsatzTV.Application/Libraries/Queries/CountMediaItemsByLibraryPath.cs

@ -0,0 +1,6 @@
using MediatR;
namespace ErsatzTV.Application.Libraries.Queries
{
public record CountMediaItemsByLibraryPath(int LibraryPathId) : IRequest<int>;
}

18
ErsatzTV.Application/Libraries/Queries/CountMediaItemsByLibraryPathHandler.cs

@ -0,0 +1,18 @@
using System.Threading;
using System.Threading.Tasks;
using ErsatzTV.Core.Interfaces.Repositories;
using MediatR;
namespace ErsatzTV.Application.Libraries.Queries
{
public class CountMediaItemsByLibraryPathHandler : IRequestHandler<CountMediaItemsByLibraryPath, int>
{
private readonly ILibraryRepository _libraryRepository;
public CountMediaItemsByLibraryPathHandler(ILibraryRepository libraryRepository) =>
_libraryRepository = libraryRepository;
public Task<int> Handle(CountMediaItemsByLibraryPath request, CancellationToken cancellationToken) =>
_libraryRepository.CountMediaItemsByPath(request.LibraryPathId);
}
}

3
ErsatzTV.Core/Interfaces/Repositories/ILibraryRepository.cs

@ -11,5 +11,8 @@ namespace ErsatzTV.Core.Interfaces.Repositories
Task<List<LocalLibrary>> GetAllLocal(); Task<List<LocalLibrary>> GetAllLocal();
Task<Unit> UpdateLastScan(Library library); Task<Unit> UpdateLastScan(Library library);
Task<List<LibraryPath>> GetLocalPaths(int libraryId); Task<List<LibraryPath>> GetLocalPaths(int libraryId);
Task<Option<LibraryPath>> GetPath(int libraryPathId);
Task<int> CountMediaItemsByPath(int libraryPathId);
Task DeleteLocalPath(int libraryPathId);
} }
} }

22
ErsatzTV.Infrastructure/Data/Repositories/LibraryRepository.cs

@ -52,5 +52,27 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
.Map(Optional) .Map(Optional)
.Match(l => l.Paths, () => new List<LibraryPath>()); .Match(l => l.Paths, () => new List<LibraryPath>());
} }
public Task<Option<LibraryPath>> GetPath(int libraryPathId)
{
using TvContext context = _dbContextFactory.CreateDbContext();
return context.LibraryPaths
.OrderBy(lp => lp.Id)
.SingleOrDefaultAsync(lp => lp.Id == libraryPathId)
.Map(Optional);
}
public Task<int> CountMediaItemsByPath(int libraryPathId) =>
_dbConnection.QuerySingleAsync<int>(
@"SELECT COUNT(*) FROM MediaItem WHERE LibraryPathId = @LibraryPathId",
new { LibraryPathId = libraryPathId });
public async Task DeleteLocalPath(int libraryPathId)
{
await using TvContext context = _dbContextFactory.CreateDbContext();
LibraryPath libraryPath = await context.LibraryPaths.FindAsync(libraryPathId);
context.LibraryPaths.Remove(libraryPath);
await context.SaveChangesAsync();
}
} }
} }

1
ErsatzTV.Infrastructure/Data/TvContext.cs

@ -19,6 +19,7 @@ namespace ErsatzTV.Infrastructure.Data
public DbSet<PlexMediaSource> PlexMediaSources { get; set; } public DbSet<PlexMediaSource> PlexMediaSources { get; set; }
public DbSet<Library> Libraries { get; set; } public DbSet<Library> Libraries { get; set; }
public DbSet<LocalLibrary> LocalLibraries { get; set; } public DbSet<LocalLibrary> LocalLibraries { get; set; }
public DbSet<LibraryPath> LibraryPaths { get; set; }
public DbSet<PlexLibrary> PlexLibraries { get; set; } public DbSet<PlexLibrary> PlexLibraries { get; set; }
public DbSet<MediaItem> MediaItems { get; set; } public DbSet<MediaItem> MediaItems { get; set; }
public DbSet<Movie> Movies { get; set; } public DbSet<Movie> Movies { get; set; }

24
ErsatzTV/Pages/LocalLibraryEditor.razor

@ -1,6 +1,8 @@
@page "/media/libraries/local/{Id:int}" @page "/media/libraries/local/{Id:int}"
@using ErsatzTV.Application.Libraries @using ErsatzTV.Application.Libraries
@using ErsatzTV.Application.Libraries.Commands
@using ErsatzTV.Application.Libraries.Queries @using ErsatzTV.Application.Libraries.Queries
@inject IDialogService Dialog
@inject IMediator Mediator @inject IMediator Mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge"> <MudContainer MaxWidth="MaxWidth.ExtraLarge">
@ -43,6 +45,26 @@
private async Task LoadLibraryPaths() => private async Task LoadLibraryPaths() =>
_libraryPaths = await Mediator.Send(new GetLocalLibraryPaths(Id)); _libraryPaths = await Mediator.Send(new GetLocalLibraryPaths(Id));
private Task DeleteLibraryPath(LocalLibraryPathViewModel libraryPath) => Task.CompletedTask; private async Task DeleteLibraryPath(LocalLibraryPathViewModel libraryPath)
{
int count = await Mediator.Send(new CountMediaItemsByLibraryPath(libraryPath.Id));
var parameters = new DialogParameters
{
{ "EntityType", "library path" },
{ "EntityName", libraryPath.Path },
{ "DetailText", $"This library path contains {count} media items." },
{ "DetailHighlight", count.ToString() }
};
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<DeleteDialog>("Delete Library Path", parameters, options);
DialogResult result = await dialog.Result;
if (!result.Cancelled)
{
await Mediator.Send(new DeleteLocalLibraryPath(libraryPath.Id));
await LoadLibraryPaths();
}
}
} }
Loading…
Cancel
Save