Fixed bug where deletes of artifact groupings would not cascade
This commit is contained in:
219
OpenArchival.Blazor.Blog/BlogPostTable.razor
Normal file
219
OpenArchival.Blazor.Blog/BlogPostTable.razor
Normal file
@@ -0,0 +1,219 @@
|
||||
@using OpenArchival.Blazor.AdminPages.Shared;
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using MudBlazor
|
||||
@using MudExtensions
|
||||
@using OpenArchival.Blazor.ArchiveSearch
|
||||
@using OpenArchival.DataAccess
|
||||
|
||||
<BlogPostSearchBar @ref=_searchBar SearchTermsChanged="OnSearchTermsChanged"></BlogPostSearchBar>
|
||||
<MudDataGrid T="BlogPostRowElement"
|
||||
MultiSelection=true
|
||||
Filterable=false
|
||||
SelectOnRowClick=true
|
||||
ServerData="new Func<GridState<BlogPostRowElement>, Task<GridData<BlogPostRowElement>>>(ServerReload)"
|
||||
@ref=@DataGrid
|
||||
@bind-SelectedItems="_selectedItems"
|
||||
Comparer="_comparer">
|
||||
|
||||
<ToolBarContent>
|
||||
|
||||
<MudSpacer />
|
||||
|
||||
<MudButton Variant="Variant.Filled"
|
||||
StartIcon="@Icons.Material.Filled.Delete"
|
||||
Color="Color.Error"
|
||||
OnClick="OnDeleteClicked">Delete</MudButton>
|
||||
</ToolBarContent>
|
||||
|
||||
<Columns>
|
||||
<SelectColumn T="BlogPostRowElement"/>
|
||||
|
||||
<PropertyColumn
|
||||
Title="Id"
|
||||
Property="x=>x.Id"
|
||||
Filterable="false"/>
|
||||
|
||||
<PropertyColumn
|
||||
Title="Title"
|
||||
Property="x=>x.Title"
|
||||
Filterable="false"/>
|
||||
|
||||
<PropertyColumn
|
||||
Title="Created Time"
|
||||
Property="x=>x.CreationTime"
|
||||
Filterable="false"/>
|
||||
|
||||
<PropertyColumn
|
||||
Title="Modified Time"
|
||||
Property="x=>x.ModifiedTime"
|
||||
Filterable="false"/>
|
||||
|
||||
<TemplateColumn Title="Edit">
|
||||
<CellTemplate>
|
||||
<MudIconButton
|
||||
Color="Color.Primary"
|
||||
Icon="@Icons.Material.Filled.Edit"
|
||||
Variant="Variant.Filled"
|
||||
Href="@($"/admin/blogedit/{context.Item.Id}")"
|
||||
Target="_blank">Edit</MudIconButton>
|
||||
</CellTemplate>
|
||||
</TemplateColumn>
|
||||
|
||||
</Columns>
|
||||
|
||||
<PagerContent>
|
||||
<MudDataGridPager T="BlogPostRowElement"/>
|
||||
</PagerContent>
|
||||
</MudDataGrid>
|
||||
|
||||
|
||||
@inject IArtifactGroupingProvider GroupingProvider;
|
||||
@inject IDialogService DialogService;
|
||||
@inject IArtifactGroupingProvider GroupingProvider;
|
||||
@inject BlogPostSearch SearchProvider;
|
||||
@inject IDbContextFactory<ApplicationDbContext> ContextFactory;
|
||||
@inject ISnackbar Snackbar;
|
||||
@inject NavigationManager NavigationManager;
|
||||
@code
|
||||
{
|
||||
public class BlogPostRowElementComparer : IEqualityComparer<BlogPostRowElement>
|
||||
{
|
||||
public bool Equals(BlogPostRowElement? x, BlogPostRowElement? y)
|
||||
{
|
||||
if (ReferenceEquals(x, y)) return true;
|
||||
if (x is null || y is null) return false;
|
||||
return x.Id == y.Id;
|
||||
}
|
||||
|
||||
public int GetHashCode(BlogPostRowElement obj)
|
||||
{
|
||||
return obj.Id.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
private BlogPostRowElementComparer _comparer = new();
|
||||
|
||||
public MudDataGrid<BlogPostRowElement> DataGrid { get; set; } = default!;
|
||||
|
||||
private HashSet<BlogPostRowElement> _selectedItems = new();
|
||||
|
||||
private string _searchString { get; set; } = "";
|
||||
|
||||
private BlogPostSearchBar _searchBar { get; set; } = default!;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task OnDeleteClicked(MouseEventArgs args)
|
||||
{
|
||||
HashSet<BlogPostRowElement> selected = DataGrid.SelectedItems;
|
||||
|
||||
bool? confirmed = await DialogService.ShowMessageBox
|
||||
(
|
||||
new MessageBoxOptions(){
|
||||
Message=$"Are you sure you want to delete {selected.Count} posts?",
|
||||
Title="Delete Posts?",
|
||||
CancelText="Cancel",
|
||||
YesText="Delete"
|
||||
});
|
||||
|
||||
// It was REALLY whining about null here ;-;
|
||||
if (confirmed is not null && (confirmed ?? throw new ArgumentNullException("confirmed was null")))
|
||||
{
|
||||
await using var context = await ContextFactory.CreateDbContextAsync();
|
||||
foreach (BlogPostRowElement post in selected)
|
||||
{
|
||||
await context.BlogPosts.Where(p => p.Id == post.Id).ExecuteDeleteAsync();
|
||||
}
|
||||
}
|
||||
|
||||
await DataGrid.ReloadServerData();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task<GridData<BlogPostRowElement>> ServerReload(GridState<BlogPostRowElement> state)
|
||||
{
|
||||
await using var context = await ContextFactory.CreateDbContextAsync();
|
||||
int totalItems = await context.BlogPosts.CountAsync();
|
||||
|
||||
SearchProvider.PageSize = state.PageSize;
|
||||
IEnumerable<BlogPost> blogPosts;
|
||||
|
||||
if (string.IsNullOrEmpty(_searchString))
|
||||
{
|
||||
blogPosts = await context.BlogPosts
|
||||
.Skip(state.Page * state.PageSize)
|
||||
.Take(state.PageSize)
|
||||
.ToListAsync();
|
||||
|
||||
} else
|
||||
{
|
||||
await SearchProvider.Search(_searchString, _searchBar.SelectedFilter, state.Page + 1);
|
||||
blogPosts = SearchProvider.SearchResults;
|
||||
}
|
||||
|
||||
var pagedItems = blogPosts.Select(post => new BlogPostRowElement()
|
||||
{
|
||||
Id = post.Id,
|
||||
Title = post.Title,
|
||||
CreationTime = post.CreationTime,
|
||||
ModifiedTime = post.ModifiedTime
|
||||
});
|
||||
|
||||
return new GridData<BlogPostRowElement>()
|
||||
{
|
||||
TotalItems = totalItems,
|
||||
Items = pagedItems
|
||||
};
|
||||
}
|
||||
|
||||
private async Task OnSearchTermsChanged(string args)
|
||||
{
|
||||
_searchString = args;
|
||||
await DataGrid.ReloadServerData();
|
||||
}
|
||||
|
||||
public async Task<List<BlogPost>> SelectedItems()
|
||||
{
|
||||
List<BlogPost> selectedGroupings = [];
|
||||
foreach (BlogPostRowElement row in DataGrid.SelectedItems)
|
||||
{
|
||||
await using var context = await ContextFactory.CreateDbContextAsync();
|
||||
var post = await context.BlogPosts.Where(p => p.Id == row.Id).FirstOrDefaultAsync();
|
||||
if (post is null)
|
||||
{
|
||||
Snackbar.Add($"Post with id {row.Id} no longer exists in the database.", Severity.Error);
|
||||
continue;
|
||||
}
|
||||
selectedGroupings.Add(post);
|
||||
}
|
||||
|
||||
return selectedGroupings;
|
||||
}
|
||||
|
||||
public Task SetSelectedItemsAsync(IEnumerable<BlogPost> postsToSelect)
|
||||
{
|
||||
var rowElementsToSelect = postsToSelect.Select(post => new BlogPostRowElement
|
||||
{
|
||||
Id = post.Id,
|
||||
Title = post.Title,
|
||||
CreationTime = post.CreationTime,
|
||||
ModifiedTime = post.ModifiedTime
|
||||
});
|
||||
|
||||
_selectedItems = new HashSet<BlogPostRowElement>(rowElementsToSelect, _comparer);
|
||||
|
||||
StateHasChanged();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void ClearSelected()
|
||||
{
|
||||
_selectedItems = new HashSet<BlogPostRowElement>();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user