@page "/admin/searchpage" @layout AdminControlPanelLayout @using Microsoft.AspNetCore.Components.Web @using Microsoft.EntityFrameworkCore @using OpenArchival.Blazor.AdminPages.Shared @using OpenArchival.Blazor.CustomComponents @using MudBlazor @using OpenArchival.DataAccess Search Page Featured Sliders Controls what artifacts are shown on the search page before a search happens. This is controlled via selecting tags. The first @ArtifactsPerSlider artifact with the listed tags will be shown in the slider. Only tags belonging to valid archive entries can be used. Entries must have all of the listed tags to be included in the slider. Add Slider @foreach (SearchPageSliderEntry entry in SliderEntries) { Delete Title: @entry.Title Description: @entry.Description Tags: } @inject ArtifactEntrySharedHelpers Helpers; @inject IDbContextFactory ContextFactory; @inject ISnackbar Snackbar; @code { [Parameter] public int ArtifactsPerSlider { get; set; } = 10; public List SliderEntries { get; set; } = []; private string _tagsInputValue { get; set; } = ""; private List _selectedTagStrings { get; set; } = []; private List _selectedTags { get; set; } = []; private string _titleInputValue { get; set; } = ""; private string _descriptionInputValue { get; set; } = ""; private ChipContainer _tagsChipContainer { get; set; } = default!; private async Task LoadSliders() { await using var context = await ContextFactory.CreateDbContextAsync(); SliderEntries = await context.SearchPageSliderEntries.Include(se=>se.FilterTags).ToListAsync(); } protected override async Task OnParametersSetAsync() { await LoadSliders(); } public async Task HandleChipContainerEnter(KeyboardEventArgs args, ChipContainer container, Type value, Action resetInputAction) { if (args.Key == "Enter") { await using var context = await ContextFactory.CreateDbContextAsync(); ArtifactEntryTag? tagToAdd = await context.ArtifactEntryTags.Where(tag => tag.Name == _tagsInputValue).FirstOrDefaultAsync(); if (tagToAdd is null) { tagToAdd = new ArtifactEntryTag() { Name=_tagsInputValue }; } _selectedTags.Add(tagToAdd); await container.AddItem(value); resetInputAction?.Invoke(); StateHasChanged(); } } private async Task OnAddSlider(MouseEventArgs args) { if (string.IsNullOrEmpty(_titleInputValue)) { Snackbar.Add("A slider title is required.", Severity.Error); return; } if (!_selectedTags.Any()) { Snackbar.Add("At least one tag is required", Severity.Error); return; } await using var context = await ContextFactory.CreateDbContextAsync(); // Attach all of the existing tags to the context foreach (var tag in _selectedTags.Where(t => t.Id != 0)) { context.ArtifactEntryTags.Attach(tag); } context.SearchPageSliderEntries.Add(new SearchPageSliderEntry(){ Title=_titleInputValue, Description=_descriptionInputValue, FilterTags=_selectedTags }); await context.SaveChangesAsync(); Snackbar.Add("Added slider", Severity.Success); _selectedTags.Clear(); _selectedTagStrings.Clear(); _titleInputValue = ""; _descriptionInputValue = ""; LoadSliders(); StateHasChanged(); } private void OnTagRemoved(string tagString) { int countRemoved = _selectedTags.RemoveAll(t => t.Name == tagString); if (countRemoved != 1) { throw new ArgumentException("Did not remove 1 element from the list of tags"); } } private async Task OnDeleteSliderClicked(SearchPageSliderEntry entry) { await using var context = await ContextFactory.CreateDbContextAsync(); SearchPageSliderEntry? entryToRemove = await context.SearchPageSliderEntries.Where(en => en.Id == entry.Id).FirstOrDefaultAsync(); if (entryToRemove is null) { throw new ArgumentException("The entry to remove was null and not in the database"); } SliderEntries.Remove(entry); context.SearchPageSliderEntries.Remove(entryToRemove); await context.SaveChangesAsync(); StateHasChanged(); } }