Fixed bug where deletes of artifact groupings would not cascade
This commit is contained in:
@@ -0,0 +1,270 @@
|
||||
@namespace OpenArchival.Blazor.AdminPages
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using MudBlazor
|
||||
@using MudExtensions
|
||||
@using OpenArchival.Blazor.ArchiveSearch
|
||||
@using OpenArchival.DataAccess
|
||||
@using OpenArchival.Blazor.AdminPages.Shared;
|
||||
@using OpenArchival.Blazor.AdminPages;
|
||||
@using OpenArchival.Blazor;
|
||||
|
||||
<ArchiveSearchBar @ref=_searchBar SearchTermsChanged="OnSearchTermsChanged"></ArchiveSearchBar>
|
||||
<MudDataGrid
|
||||
T="ArtifactGroupingRowElement"
|
||||
MultiSelection=true
|
||||
Filterable=false
|
||||
SelectOnRowClick=true
|
||||
ServerData="new Func<GridState<ArtifactGroupingRowElement>, Task<GridData<ArtifactGroupingRowElement>>>(ServerReload)"
|
||||
@ref=@DataGrid
|
||||
@bind-SelectedItems="_selectedGroupings"
|
||||
Comparer="_comparer">
|
||||
|
||||
<ToolBarContent>
|
||||
|
||||
<MudSpacer />
|
||||
|
||||
<MudButton Variant="Variant.Filled"
|
||||
StartIcon="@Icons.Material.Filled.Delete"
|
||||
Color="Color.Error"
|
||||
OnClick="OnDeleteClicked">Delete</MudButton>
|
||||
</ToolBarContent>
|
||||
|
||||
<Columns>
|
||||
<SelectColumn T="ArtifactGroupingRowElement"/>
|
||||
|
||||
<PropertyColumn
|
||||
Title="Id"
|
||||
Property="x=>x.ArtifactGroupingIdentifier"
|
||||
Filterable="false"/>
|
||||
|
||||
<PropertyColumn
|
||||
Title="Category"
|
||||
Property="x=>x.CategoryName"
|
||||
Filterable="false"/>
|
||||
|
||||
<PropertyColumn
|
||||
Title="Title"
|
||||
Property="x=>x.Title"
|
||||
Filterable="false"/>
|
||||
|
||||
<PropertyColumn
|
||||
Title="Publically Visible"
|
||||
Property="x=>x.IsPublicallyVisible"
|
||||
Filterable="false"/>
|
||||
|
||||
<TemplateColumn Title="Edit">
|
||||
<CellTemplate>
|
||||
<MudIconButton
|
||||
Color="Color.Primary"
|
||||
Icon="@Icons.Material.Filled.Edit"
|
||||
Variant="Variant.Filled"
|
||||
OnClick="() => OnRowEditClick(context.Item)">Edit</MudIconButton>
|
||||
</CellTemplate>
|
||||
</TemplateColumn>
|
||||
|
||||
</Columns>
|
||||
|
||||
<PagerContent>
|
||||
<MudDataGridPager T="ArtifactGroupingRowElement"/>
|
||||
</PagerContent>
|
||||
</MudDataGrid>
|
||||
|
||||
|
||||
@inject IArtifactGroupingProvider GroupingProvider;
|
||||
@inject IDialogService DialogService;
|
||||
@inject IArtifactGroupingProvider GroupingProvider;
|
||||
@inject ArtifactEntrySharedHelpers Helpers;
|
||||
@inject ArtifactGroupingSearch SearchProvider;
|
||||
@code
|
||||
{
|
||||
public class ArtifactGroupingRowElementComparer : IEqualityComparer<ArtifactGroupingRowElement>
|
||||
{
|
||||
public bool Equals(ArtifactGroupingRowElement? x, ArtifactGroupingRowElement? y)
|
||||
{
|
||||
if (ReferenceEquals(x, y)) return true;
|
||||
if (x is null || y is null) return false;
|
||||
return x.Id == y.Id;
|
||||
}
|
||||
|
||||
public int GetHashCode(ArtifactGroupingRowElement obj)
|
||||
{
|
||||
return obj.Id.GetHashCode();
|
||||
}
|
||||
}
|
||||
public List<ArtifactGroupingRowElement> ArtifactGroupingRows { get; set; } = new();
|
||||
|
||||
public MudDataGrid<ArtifactGroupingRowElement> DataGrid { get; set; } = default!;
|
||||
|
||||
private ArtifactGroupingRowElementComparer _comparer = new();
|
||||
|
||||
private string _searchString { get; set; } = "";
|
||||
|
||||
private ArchiveSearchBar _searchBar { get; set; } = default!;
|
||||
|
||||
private HashSet<ArtifactGroupingRowElement> _selectedGroupings { get; set; } = [];
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
// Load inital data
|
||||
List<ArtifactGrouping> groupings = await GroupingProvider.GetGroupingsPaged(1, 25);
|
||||
SetGroupingRows(groupings);
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void SetGroupingRows(IEnumerable<ArtifactGrouping> groupings)
|
||||
{
|
||||
ArtifactGroupingRows.Clear();
|
||||
|
||||
foreach (var grouping in groupings)
|
||||
{
|
||||
ArtifactGroupingRows.Add(new ArtifactGroupingRowElement()
|
||||
{
|
||||
ArtifactGroupingIdentifier=grouping.ArtifactGroupingIdentifier ?? throw new ArgumentNullException(nameof(grouping), "Got a null grouping identifier"),
|
||||
CategoryName=grouping.Category.Name,
|
||||
Title=grouping.Title,
|
||||
IsPublicallyVisible=grouping.IsPublicallyVisible,
|
||||
Id=grouping.Id
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnRowEditClick(ArtifactGroupingRowElement row)
|
||||
{
|
||||
var parameters = new DialogParameters();
|
||||
|
||||
var model = await GroupingProvider.GetGroupingAsync(row.Id);
|
||||
|
||||
parameters.Add("Model", ArtifactGroupingValidationModel.ToValidationModel(model));
|
||||
|
||||
var options = new DialogOptions()
|
||||
{
|
||||
MaxWidth = MaxWidth.ExtraExtraLarge,
|
||||
FullWidth = true
|
||||
};
|
||||
|
||||
var dialog = await DialogService.ShowAsync<AddGroupingDialog>("Edit Grouping", parameters, options);
|
||||
|
||||
var result = await dialog.Result;
|
||||
|
||||
if (result is not null && !result.Canceled)
|
||||
{
|
||||
var validationModel = (ArtifactGroupingValidationModel)result.Data!;
|
||||
|
||||
await Helpers.OnGroupingPublished(validationModel);
|
||||
|
||||
await DataGrid.ReloadServerData();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnDeleteClicked(MouseEventArgs args)
|
||||
{
|
||||
HashSet<ArtifactGroupingRowElement> selected = DataGrid.SelectedItems;
|
||||
|
||||
bool? confirmed = await DialogService.ShowMessageBox
|
||||
(
|
||||
new MessageBoxOptions(){
|
||||
Message=$"Are you sure you want to delete {selected.Count} groupings?",
|
||||
Title="Delete Groupings",
|
||||
CancelText="Cancel",
|
||||
YesText="Delete"
|
||||
});
|
||||
|
||||
if (confirmed is not null && (confirmed ?? throw new ArgumentNullException("confirmed was null")))
|
||||
{
|
||||
foreach (var grouping in selected)
|
||||
{
|
||||
await GroupingProvider.DeleteGroupingAsync(grouping.Id);
|
||||
}
|
||||
}
|
||||
|
||||
await DataGrid.ReloadServerData();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task<GridData<ArtifactGroupingRowElement>> ServerReload(GridState<ArtifactGroupingRowElement> state)
|
||||
{
|
||||
int totalItems = await GroupingProvider.GetTotalCount();
|
||||
|
||||
SearchProvider.PageSize = state.PageSize;
|
||||
IEnumerable<ArtifactGrouping> groupings;
|
||||
|
||||
if (string.IsNullOrEmpty(_searchString))
|
||||
{
|
||||
groupings = await GroupingProvider.GetGroupingsPaged(state.Page + 1, state.PageSize);
|
||||
totalItems = await GroupingProvider.GetTotalCount();
|
||||
|
||||
} else
|
||||
{
|
||||
await SearchProvider.Search(_searchString, _searchBar.SelectedFilter, state.Page + 1);
|
||||
groupings = SearchProvider.SearchResults;
|
||||
}
|
||||
|
||||
var pagedItems = groupings.Select(grouping => new ArtifactGroupingRowElement()
|
||||
{
|
||||
Id = grouping.Id,
|
||||
Title = grouping.Title,
|
||||
ArtifactGroupingIdentifier = grouping.ArtifactGroupingIdentifier ?? throw new ArgumentNullException(nameof(grouping), "Got a null ArtifactGroupingIdentifier"),
|
||||
CategoryName = grouping.Category.Name,
|
||||
IsPublicallyVisible = grouping.IsPublicallyVisible,
|
||||
});
|
||||
|
||||
StateHasChanged();
|
||||
|
||||
return new GridData<ArtifactGroupingRowElement>()
|
||||
{
|
||||
TotalItems = totalItems,
|
||||
Items = pagedItems
|
||||
};
|
||||
}
|
||||
|
||||
private async Task OnSearchTermsChanged(string args)
|
||||
{
|
||||
_searchString = args;
|
||||
await DataGrid.ReloadServerData();
|
||||
}
|
||||
|
||||
public async Task<List<ArtifactGrouping>> SelectedItems()
|
||||
{
|
||||
List<ArtifactGrouping> selectedGroupings = [];
|
||||
foreach (ArtifactGroupingRowElement row in DataGrid.SelectedItems)
|
||||
{
|
||||
selectedGroupings.Add(await GroupingProvider.GetGroupingAsync(row.Id));
|
||||
}
|
||||
|
||||
return selectedGroupings;
|
||||
}
|
||||
|
||||
public void ClearSelected()
|
||||
{
|
||||
// OLD: _selectedGroupings = new HashSet<ArtifactGroupingRowElement>();
|
||||
// NEW: Initialize with the comparer
|
||||
_selectedGroupings = new HashSet<ArtifactGroupingRowElement>(_comparer);
|
||||
}
|
||||
|
||||
// 6. ADD THIS NEW PUBLIC METHOD
|
||||
public Task SetSelectedItemsAsync(IEnumerable<ArtifactGrouping> groupingsToSelect)
|
||||
{
|
||||
// Convert from the full ArtifactGrouping entity to the RowElement.
|
||||
// We only *really* need the Id for the comparer, but populating
|
||||
// the other fields is good practice.
|
||||
var rowElementsToSelect = groupingsToSelect.Select(grouping => new ArtifactGroupingRowElement
|
||||
{
|
||||
Id = grouping.Id,
|
||||
Title = grouping.Title,
|
||||
ArtifactGroupingIdentifier = grouping.ArtifactGroupingIdentifier ?? string.Empty,
|
||||
CategoryName = grouping.Category?.Name ?? string.Empty,
|
||||
IsPublicallyVisible = grouping.IsPublicallyVisible
|
||||
});
|
||||
|
||||
// Create a new HashSet from the list, using the comparer.
|
||||
// Assigning this to the bound variable will update the grid's UI.
|
||||
_selectedGroupings = new HashSet<ArtifactGroupingRowElement>(rowElementsToSelect, _comparer);
|
||||
|
||||
StateHasChanged();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user