Files
openarchival/OpenArchival.Blazor.ArchiveSearch/ArtifactGroupingSearch.cs

133 lines
4.4 KiB
C#

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.Extensions.Logging;
using MudBlazor;
using Npgsql.EntityFrameworkCore.PostgreSQL;
using NpgsqlTypes;
using OpenArchival.DataAccess;
using OpenArchival.DataAccess;
using System;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.Linq;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace OpenArchival.Blazor.ArchiveSearch;
public enum ArchiveSearchFilterType
{
All,
Tags,
Defects,
ListedNames,
Title,
Description,
Filenames,
ArtifactTranscriptions
}
public class ArtifactGroupingSearch
{
public int TotalResults { get; set; }
public int TotalPages { get; set; }
public int PageSize { get; set; } = 20;
public int CurrentPage { get; set; }
public List<ArtifactGrouping> SearchResults { get; set; } = [];
private string _searchTerms { get; set; }
private IDbContextFactory<ApplicationDbContext> _contextFactory { get; set; }
private Expression<Func<ArtifactGrouping, bool>> _currentFilterPredicate;
private ArchiveSearchFilterType _selectedFilter = ArchiveSearchFilterType.All;
public ArtifactGroupingSearch(IDbContextFactory<ApplicationDbContext> contextFactory)
{
_contextFactory = contextFactory;
}
public async Task Search(string Terms, ArchiveSearchFilterType filter, int page = 1)
{
_searchTerms = Terms;
_selectedFilter = filter;
// Determine which filter expression to use based on the radio button selection
switch (_selectedFilter)
{
case ArchiveSearchFilterType.Tags:
_currentFilterPredicate = x => x.TagsSearchVector.Matches(_searchTerms);
break;
case ArchiveSearchFilterType.Title:
_currentFilterPredicate = x => x.TitleSearchVector.Matches(_searchTerms);
break;
case ArchiveSearchFilterType.Description:
_currentFilterPredicate = x => x.DescriptionSearchVector.Matches(_searchTerms);
break;
case ArchiveSearchFilterType.Defects:
_currentFilterPredicate = x => x.DefectsSearchVector.Matches(_searchTerms);
break;
case ArchiveSearchFilterType.Filenames:
_currentFilterPredicate = x => x.FilenamesSearchVector.Matches(_searchTerms);
break;
case ArchiveSearchFilterType.ArtifactTranscriptions:
_currentFilterPredicate = x => x.FileContentSearchVector.Matches(_searchTerms);
break;
case ArchiveSearchFilterType.ListedNames:
_currentFilterPredicate = x => x.ListedNamesSearchVector.Matches(_searchTerms);
break;
case ArchiveSearchFilterType.All:
default:
_currentFilterPredicate = x => x.AllSearchVector.Matches(_searchTerms);
break;
}
// Get the total count using the chosen filter
await using var context = await _contextFactory.CreateDbContextAsync();
TotalResults = await context.ArtifactGroupings.Where(_currentFilterPredicate).CountAsync();
TotalPages = (int)Math.Ceiling(TotalResults / (double)PageSize);
// Load the first page with the chosen filter
await LoadPageAsync(page);
}
public async Task LoadPageAsync(int page)
{
CurrentPage = page;
if (_currentFilterPredicate == null) // Don't run if no search has been performed
{
return;
}
await using var context = await _contextFactory.CreateDbContextAsync();
// The query uses the dynamically set filter predicate
SearchResults = await context.ArtifactGroupings
.Where(_currentFilterPredicate)
.Include(x => x.ChildArtifactEntries)
.ThenInclude(x => x.Files)
.Include(x=>x.Category)
.OrderBy(x => x.Id)
.Skip((CurrentPage - 1) * PageSize)
.Take(PageSize)
.ToListAsync();
}
public void ClearResults()
{
SearchResults.Clear();
TotalResults = 0;
TotalPages = 0;
}
}