Files
openarchival/OpenArchival.Blazor.Blog/BlogPostTable.razor

219 lines
6.7 KiB
Plaintext

@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>();
}
}