@using OpenArchival.Blazor.AdminPages.Shared; @using Microsoft.AspNetCore.Components.Web @using Microsoft.EntityFrameworkCore @using MudBlazor @using MudExtensions @using OpenArchival.Blazor.ArchiveSearch @using OpenArchival.DataAccess Delete Edit @inject IArtifactGroupingProvider GroupingProvider; @inject IDialogService DialogService; @inject IArtifactGroupingProvider GroupingProvider; @inject BlogPostSearch SearchProvider; @inject IDbContextFactory ContextFactory; @inject ISnackbar Snackbar; @inject NavigationManager NavigationManager; @code { public class BlogPostRowElementComparer : IEqualityComparer { 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 DataGrid { get; set; } = default!; private HashSet _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 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> ServerReload(GridState state) { await using var context = await ContextFactory.CreateDbContextAsync(); int totalItems = await context.BlogPosts.CountAsync(); SearchProvider.PageSize = state.PageSize; IEnumerable 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() { TotalItems = totalItems, Items = pagedItems }; } private async Task OnSearchTermsChanged(string args) { _searchString = args; await DataGrid.ReloadServerData(); } public async Task> SelectedItems() { List 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 postsToSelect) { var rowElementsToSelect = postsToSelect.Select(post => new BlogPostRowElement { Id = post.Id, Title = post.Title, CreationTime = post.CreationTime, ModifiedTime = post.ModifiedTime }); _selectedItems = new HashSet(rowElementsToSelect, _comparer); StateHasChanged(); return Task.CompletedTask; } public void ClearSelected() { _selectedItems = new HashSet(); } }