Moved search bar into separate component and fixed results display.
This commit is contained in:
parent
2d1f599bbf
commit
3c63ebc613
@ -17,10 +17,5 @@ namespace MultiShop.Client.Listing
|
|||||||
public Search.Status Status { get; set; }
|
public Search.Status Status { get; set; }
|
||||||
|
|
||||||
private protected abstract string GetCategoryTag(ResultsProfile.Category category);
|
private protected abstract string GetCategoryTag(ResultsProfile.Category category);
|
||||||
|
|
||||||
public ListingView(Search.Status status)
|
|
||||||
{
|
|
||||||
this.Status = status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -75,10 +75,6 @@
|
|||||||
@code {
|
@code {
|
||||||
public override Views View => Views.Table;
|
public override Views View => Views.Table;
|
||||||
|
|
||||||
public TableView(Search.Status status) : base(status)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private protected override string GetCategoryTag(ResultsProfile.Category c)
|
private protected override string GetCategoryTag(ResultsProfile.Category c)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
@page "/search/{Query?}"
|
@page "/search/{Query?}"
|
||||||
|
|
||||||
@using MultiShop.Client.Extensions
|
@using MultiShop.Client.Extensions
|
||||||
|
@using MultiShop.Client.Listing
|
||||||
|
|
||||||
<div class="my-2">
|
<div class="my-2">
|
||||||
<div class="input-group my-2">
|
<div class="input-group my-2">
|
||||||
<input type="text" class="form-control" placeholder="What are you looking for?" aria-label="What are you looking for?" id="search-input" @bind="Query" @onkeyup="@(async (a) => {if (a.Code == "Enter" || a.Code == "NumpadEnter") await PerformSearch(Query);})" disabled="@status.Searching" >
|
<SearchBar SearchPlaceholder="What are you looking for?" OnSearchRequested="@PerformSearch" @ref="searchBar">
|
||||||
<div class="input-group-append">
|
<Append>
|
||||||
<ToggleableButton class="btn btn-outline-secondary" title="Configure" OnToggleCallback="@((t) => status.SearchConfiguring = t)"><span class="oi oi-cog align-text-top"></span></ToggleableButton>
|
<ToggleableButton class="btn btn-outline-secondary" title="Configure" OnToggleCallback="@((t) => {status.SearchConfiguring = t; StateHasChanged();})"><span class="oi oi-cog align-text-top"></span></ToggleableButton>
|
||||||
<button class="btn btn-outline-primary" type="button" @onclick="@(async () => await PerformSearch(Query))" disabled="@status.Searching">Search</button>
|
</Append>
|
||||||
</div>
|
</SearchBar>
|
||||||
</div>
|
</div>
|
||||||
@if (status.SearchConfiguring)
|
@if (status.SearchConfiguring)
|
||||||
{
|
{
|
||||||
@ -238,7 +239,12 @@
|
|||||||
<div>
|
<div>
|
||||||
@if (listings.Count > 0)
|
@if (listings.Count > 0)
|
||||||
{
|
{
|
||||||
@listingViews[CurrentView]
|
@switch (CurrentView)
|
||||||
|
{
|
||||||
|
case Views.Table:
|
||||||
|
<TableView Listings="@listings" Status="@status"></TableView>
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using MultiShop.Client.Shared;
|
||||||
using MultiShop.Client.Extensions;
|
using MultiShop.Client.Extensions;
|
||||||
using MultiShop.Client.Listing;
|
using MultiShop.Client.Listing;
|
||||||
using MultiShop.Shared.Models;
|
using MultiShop.Shared.Models;
|
||||||
@ -17,6 +18,10 @@ namespace MultiShop.Client.Pages
|
|||||||
{
|
{
|
||||||
[Inject]
|
[Inject]
|
||||||
private ILogger<Search> Logger { get; set; }
|
private ILogger<Search> Logger { get; set; }
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private HttpClient Http { get; set; }
|
||||||
|
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
Task<AuthenticationState> AuthenticationStateTask { get; set; }
|
Task<AuthenticationState> AuthenticationStateTask { get; set; }
|
||||||
|
|
||||||
@ -26,13 +31,10 @@ namespace MultiShop.Client.Pages
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string Query { get; set; }
|
public string Query { get; set; }
|
||||||
|
|
||||||
[Inject]
|
private SearchBar searchBar;
|
||||||
private HttpClient Http { get; set; }
|
|
||||||
|
|
||||||
private Status status = new Status();
|
private Status status = new Status();
|
||||||
|
|
||||||
private Dictionary<Views, ListingView> listingViews;
|
|
||||||
|
|
||||||
private Views CurrentView = Views.Table;
|
private Views CurrentView = Views.Table;
|
||||||
|
|
||||||
private SearchProfile activeSearchProfile;
|
private SearchProfile activeSearchProfile;
|
||||||
@ -46,11 +48,7 @@ namespace MultiShop.Client.Pages
|
|||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
|
|
||||||
AuthenticationState authState = await AuthenticationStateTask;
|
AuthenticationState authState = await AuthenticationStateTask;
|
||||||
|
|
||||||
listingViews = new Dictionary<Views, ListingView>() {
|
|
||||||
{Views.Table, new TableView(status)}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (authState.User.Identity.IsAuthenticated) {
|
if (authState.User.Identity.IsAuthenticated) {
|
||||||
Logger.LogDebug($"User \"{authState.User.Identity.Name}\" is authenticated. Checking for saved profiles.");
|
Logger.LogDebug($"User \"{authState.User.Identity.Name}\" is authenticated. Checking for saved profiles.");
|
||||||
HttpResponseMessage searchProfileResponse = await Http.GetAsync("Profile/Search");
|
HttpResponseMessage searchProfileResponse = await Http.GetAsync("Profile/Search");
|
||||||
@ -84,10 +82,21 @@ namespace MultiShop.Client.Pages
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender) {
|
||||||
|
await base.OnAfterRenderAsync(firstRender);
|
||||||
|
if (firstRender) {
|
||||||
|
searchBar.Query = Query;
|
||||||
|
searchBar.Searching = true;
|
||||||
|
await PerformSearch(Query);
|
||||||
|
searchBar.Searching = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task PerformSearch(string query)
|
private async Task PerformSearch(string query)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(query)) return;
|
if (string.IsNullOrWhiteSpace(query)) return;
|
||||||
if (status.Searching) return;
|
if (status.Searching) return;
|
||||||
|
SearchProfile searchProfile = activeSearchProfile.DeepCopy();
|
||||||
status.Searching = true;
|
status.Searching = true;
|
||||||
Logger.LogDebug($"Received search request for \"{query}\".");
|
Logger.LogDebug($"Received search request for \"{query}\".");
|
||||||
resultsChecked = 0;
|
resultsChecked = 0;
|
||||||
@ -96,10 +105,10 @@ namespace MultiShop.Client.Pages
|
|||||||
List<ProductListingInfo>>();
|
List<ProductListingInfo>>();
|
||||||
foreach (string shopName in Shops.Keys)
|
foreach (string shopName in Shops.Keys)
|
||||||
{
|
{
|
||||||
if (activeSearchProfile.ShopStates[shopName])
|
if (searchProfile.ShopStates[shopName])
|
||||||
{
|
{
|
||||||
Logger.LogDebug($"Querying \"{shopName}\" for products.");
|
Logger.LogDebug($"Querying \"{shopName}\" for products.");
|
||||||
Shops[shopName].SetupSession(query, activeSearchProfile.Currency);
|
Shops[shopName].SetupSession(query, searchProfile.Currency);
|
||||||
int shopViableResults = 0;
|
int shopViableResults = 0;
|
||||||
await foreach (ProductListing listing in Shops[shopName])
|
await foreach (ProductListing listing in Shops[shopName])
|
||||||
{
|
{
|
||||||
@ -111,12 +120,12 @@ namespace MultiShop.Client.Pages
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (listing.Shipping == null && !activeSearchProfile.KeepUnknownShipping || (activeSearchProfile.EnableMaxShippingFee && listing.Shipping > activeSearchProfile.MaxShippingFee)) continue;
|
if (listing.Shipping == null && !searchProfile.KeepUnknownShipping || (searchProfile.EnableMaxShippingFee && listing.Shipping > searchProfile.MaxShippingFee)) continue;
|
||||||
float shippingDifference = listing.Shipping != null ? listing.Shipping.Value : 0;
|
float shippingDifference = listing.Shipping != null ? listing.Shipping.Value : 0;
|
||||||
if (!(listing.LowerPrice + shippingDifference >= activeSearchProfile.LowerPrice && (!activeSearchProfile.EnableUpperPrice || listing.UpperPrice + shippingDifference <= activeSearchProfile.UpperPrice))) continue;
|
if (!(listing.LowerPrice + shippingDifference >= searchProfile.LowerPrice && (!searchProfile.EnableUpperPrice || listing.UpperPrice + shippingDifference <= searchProfile.UpperPrice))) continue;
|
||||||
if ((listing.Rating == null && !activeSearchProfile.KeepUnrated) && activeSearchProfile.MinRating > (listing.Rating == null ? 0 : listing.Rating)) continue;
|
if ((listing.Rating == null && !searchProfile.KeepUnrated) && searchProfile.MinRating > (listing.Rating == null ? 0 : listing.Rating)) continue;
|
||||||
if ((listing.PurchaseCount == null && !activeSearchProfile.KeepUnknownPurchaseCount) || activeSearchProfile.MinPurchases > (listing.PurchaseCount == null ? 0 : listing.PurchaseCount)) continue;
|
if ((listing.PurchaseCount == null && !searchProfile.KeepUnknownPurchaseCount) || searchProfile.MinPurchases > (listing.PurchaseCount == null ? 0 : listing.PurchaseCount)) continue;
|
||||||
if ((listing.ReviewCount == null && !activeSearchProfile.KeepUnknownRatingCount) || activeSearchProfile.MinReviews > (listing.ReviewCount == null ? 0 : listing.ReviewCount)) continue;
|
if ((listing.ReviewCount == null && !searchProfile.KeepUnknownRatingCount) || searchProfile.MinReviews > (listing.ReviewCount == null ? 0 : listing.ReviewCount)) continue;
|
||||||
|
|
||||||
ProductListingInfo info = new ProductListingInfo(listing, shopName);
|
ProductListingInfo info = new ProductListingInfo(listing, shopName);
|
||||||
listings.Add(info);
|
listings.Add(info);
|
||||||
@ -142,7 +151,7 @@ namespace MultiShop.Client.Pages
|
|||||||
}
|
}
|
||||||
|
|
||||||
shopViableResults += 1;
|
shopViableResults += 1;
|
||||||
if (shopViableResults >= activeSearchProfile.MaxResults) break;
|
if (shopViableResults >= searchProfile.MaxResults) break;
|
||||||
}
|
}
|
||||||
Logger.LogDebug($"\"{shopName}\" has completed. There are {listings.Count} results in total.");
|
Logger.LogDebug($"\"{shopName}\" has completed. There are {listings.Count} results in total.");
|
||||||
}
|
}
|
||||||
|
26
src/MultiShop/Client/Shared/SearchBar.razor
Normal file
26
src/MultiShop/Client/Shared/SearchBar.razor
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<input type="text" class="form-control" placeholder=@SearchPlaceholder aria-label=@SearchPlaceholder id="search-input" @bind="Query" @onkeyup="@(async (a) => {if (a.Code == "Enter" || a.Code == "NumpadEnter") await Search();})" disabled="@Searching">
|
||||||
|
<div class="input-group-append">
|
||||||
|
@Append
|
||||||
|
<button class="btn btn-outline-primary" type="button" @onclick="@(async () => await Search())" disabled="@Searching">Search</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public RenderFragment Append { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string SearchPlaceholder { get; set; }
|
||||||
|
|
||||||
|
public string Query { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<string> OnSearchRequested { get; set; }
|
||||||
|
|
||||||
|
public bool Searching { get; set; }
|
||||||
|
public async Task Search()
|
||||||
|
{
|
||||||
|
Searching = true;
|
||||||
|
await OnSearchRequested.InvokeAsync(Query);
|
||||||
|
Searching = false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user