189 lines
6.7 KiB
Plaintext
189 lines
6.7 KiB
Plaintext
@page "/search"
|
|
@page "/search/{SearchTerms}"
|
|
|
|
@using Microsoft.EntityFrameworkCore
|
|
@using Microsoft.Extensions.Logging
|
|
@using MudBlazor
|
|
@using NpgsqlTypes
|
|
@using OpenArchival.DataAccess
|
|
@using Persic
|
|
@using Npgsql.EntityFrameworkCore.PostgreSQL
|
|
@using System.Linq
|
|
@using System.Linq.Expressions
|
|
|
|
@using OpenArchival.Blazor.ArtifactGroupingDisplay
|
|
@using OpenArchival.Blazor.ArchiveSearch
|
|
@* ^^^ Add this using statement to access your component and enum ^^^ *@
|
|
|
|
<ArchiveSearchBar @bind-SelectedFilter="_selectedFilter"
|
|
SearchTermsChanged="OnSearchSubmittedAsync" />
|
|
|
|
@if (_totalResults > 0)
|
|
{
|
|
<MudGrid Justify="Justify.FlexStart" Class="mt-1 ml-1 mb-2">
|
|
<MudText Typo="Typo.subtitle2" Class="my-2">@_totalResults results found</MudText>
|
|
<MudButton Class="ml-1" StartIcon="@Icons.Material.Filled.Clear" OnClick="OnClearResults" Variant="Variant.Filled" Color="Color.Primary" Size="Size.Small">Clear</MudButton>
|
|
</MudGrid>
|
|
}
|
|
|
|
@if (_artifactGroupings.Count > 0)
|
|
{
|
|
<MudGrid>
|
|
@foreach (var grouping in _artifactGroupings)
|
|
{
|
|
<MudItem xs="12" sm="6" md="4" lg="4">
|
|
<ArtifactGroupingSearchResult ArtifactGrouping="grouping"></ArtifactGroupingSearchResult>
|
|
</MudItem>
|
|
}
|
|
</MudGrid>
|
|
|
|
<MudPaper Class="d-flex justify-center py-2 mt-4" Elevation="0">
|
|
@* === HERE IS THE FIX === *@
|
|
<MudPagination Count="_totalPages" Selected="_currentPage" SelectedChanged="OnPageChangedAsync" />
|
|
</MudPaper>
|
|
}
|
|
else
|
|
{
|
|
@foreach (SearchPageSliderEntry entry in _sliderEntries)
|
|
{
|
|
<SearchPageSlider SliderEntry="entry"></SearchPageSlider>
|
|
}
|
|
}
|
|
|
|
@inject IDbContextFactory<ApplicationDbContext> ContextFactory;
|
|
@inject ILogger<SearchArchive> Logger;
|
|
@inject NavigationManager NavigationManager;
|
|
@code {
|
|
[Parameter]
|
|
public string SearchTerms { get; set; } = "";
|
|
|
|
// This enum is now defined in your ArchiveSearchBar component/namespace
|
|
private ArchiveSearchFilterType _selectedFilter = ArchiveSearchFilterType.All;
|
|
|
|
private List<ArtifactGrouping> _artifactGroupings { get; set; } = [];
|
|
private int _currentPage { get; set; } = 1;
|
|
private int _totalPages { get; set; } = 0;
|
|
private int _totalResults { get; set; } = 0;
|
|
private const int PageSize = 20;
|
|
|
|
private List<SearchPageSliderEntry> _sliderEntries { get; set; } = [];
|
|
|
|
// Field to store the current filter logic
|
|
private Expression<Func<ArtifactGrouping, bool>> _currentFilterPredicate;
|
|
|
|
protected override async Task OnParametersSetAsync()
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(SearchTerms))
|
|
{
|
|
await PerformSearchAsync();
|
|
}
|
|
|
|
await using var context = await ContextFactory.CreateDbContextAsync();
|
|
_sliderEntries = await context.SearchPageSliderEntries.Include(e => e.FilterTags).ToListAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by the ArchiveSearchBar component's 'SearchTermsChanged' event.
|
|
/// </summary>
|
|
private async Task OnSearchSubmittedAsync(string searchTerms)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(searchTerms))
|
|
{
|
|
OnClearResults(null);
|
|
return;
|
|
}
|
|
|
|
SearchTerms = searchTerms;
|
|
NavigationManager.NavigateTo($"/search/{Uri.EscapeDataString(SearchTerms)}", replace: true);
|
|
await PerformSearchAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the search predicate, calculates total results, and loads the first page.
|
|
/// </summary>
|
|
private async Task PerformSearchAsync()
|
|
{
|
|
// Determine which filter expression to use
|
|
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(1);
|
|
}
|
|
|
|
private async Task OnPageChangedAsync(int page)
|
|
{
|
|
await LoadPageAsync(page);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fetches a specific page of data from the database using the currently set filter.
|
|
/// </summary>
|
|
private 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
|
|
_artifactGroupings = await context.ArtifactGroupings
|
|
.Where(_currentFilterPredicate)
|
|
.Include(x => x.ChildArtifactEntries)
|
|
.ThenInclude(x => x.Files)
|
|
.OrderBy(x => x.Id)
|
|
.Skip((_currentPage - 1) * PageSize)
|
|
.Take(PageSize)
|
|
.ToListAsync();
|
|
|
|
StateHasChanged();
|
|
}
|
|
|
|
private void OnClearResults(Microsoft.AspNetCore.Components.Web.MouseEventArgs args)
|
|
{
|
|
_totalResults = 0;
|
|
_artifactGroupings.Clear();
|
|
_currentPage = 1;
|
|
_totalPages = 0;
|
|
SearchTerms = "";
|
|
|
|
NavigationManager.NavigateTo("/search", replace: true);
|
|
|
|
StateHasChanged();
|
|
}
|
|
} |