Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add facets to product list #3

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<EnablePackageValidation>false</EnablePackageValidation>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Examine" Version="4.0.0-beta.1" />
<PackageReference Include="Umbraco.Cms" Version="12.1.1" />
<PackageReference Include="Umbraco.Commerce" Version="12.1.0-rc1" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
}

@await Html.PartialAsync("Intro")
@await Component.InvokeAsync("Facet", new { category = Model.UrlSegment })
@await Component.InvokeAsync("ProductListByCategory", new { category = Model.UrlSegment })
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
}

@await Html.PartialAsync("Intro")
@await Component.InvokeAsync("Facet", new { collectionId = Model.Id })
@await Component.InvokeAsync("ProductListByCollection", new { collectionId = Model.Id })
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@using Umbraco.Commerce.Common.Models;
@using Umbraco.Commerce.DemoStore.Models;
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<IEnumerable<FacetGroup>>

<aside>
@foreach (var group in Model)
{
<details>
<summary>@group.Name</summary>

@foreach (var facet in group.Facets)
{
<div>
<input type="checkbox" id="@facet.Name" name="@group.Name" value="@facet.Value" class="filter">
<label for="@facet.Name">@facet.Name (@facet.Count)</label>
</div>
}
</details>
}
</aside>

<script>
document.querySelectorAll('.filter').forEach(filter => {
filter.addEventListener('change', event => {
if (event.currentTarget.checked) {
//alert('checked');
} else {
//alert('not checked');
}
})
});
</script>
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
@using Umbraco.Commerce.Common.Models;
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<PagedResult<Umbraco.Commerce.DemoStore.Models.ProductPage>>
@await Html.PartialAsync("PagedProductList", Model)
@await Html.PartialAsync("PagedProductList", Model)
8 changes: 7 additions & 1 deletion src/Umbraco.Commerce.DemoStore/DemoStoreBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Extensions;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Commerce.DemoStore.Web.Index;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Umbraco.Commerce.DemoStore.Web.Services;

namespace Umbraco.Commerce.DemoStore
{
Expand Down Expand Up @@ -36,13 +40,15 @@ public static IUmbracoBuilder AddDemoStore(this IUmbracoBuilder umbracoBuilder)

v.WithNotificationEvent<OrderShippingCountryRegionChangingNotification>()
.RegisterHandler<OrderShippingCountryRegionChangingHandler>();

v.WithNotificationEvent<OrderShippingMethodChangingNotification>()
.RegisterHandler<OrderShippingMethodChangingHandler>();

});

umbracoBuilder.AddNotificationHandler<UmbracoApplicationStartingNotification, TransformExamineValues>();
umbracoBuilder.Services.AddSingleton<IFacetService, FacetService>();
umbracoBuilder.Services.ConfigureOptions<ConfigureIndexOptions>();

return umbracoBuilder;
}
Expand Down
25 changes: 22 additions & 3 deletions src/Umbraco.Commerce.DemoStore/Events/TransformExamineValues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,33 @@
using Umbraco.Extensions;
using Umbraco.Commerce.DemoStore.Models;
using System.Text;
using Newtonsoft.Json;
using System;
using Umbraco.Commerce.Core.Services;

namespace Umbraco.Commerce.DemoStore.Events
{
public class TransformExamineValues : INotificationHandler<UmbracoApplicationStartingNotification>
{
private readonly IExamineManager _examineManager;
private readonly IUmbracoContextFactory _umbracoContextFactory;
private readonly ICurrencyService _currencyService;

public TransformExamineValues(IExamineManager examineManager,
IUmbracoContextFactory umbracoContextFactory)
public TransformExamineValues(
IExamineManager examineManager,
IUmbracoContextFactory umbracoContextFactory,
ICurrencyService currencyService)
{
_examineManager = examineManager;
_umbracoContextFactory = umbracoContextFactory;
_currencyService = currencyService;
}


public void Handle(UmbracoApplicationStartingNotification notification)
{
// Listen for nodes being reindexed in the external index set
if (_examineManager.TryGetIndex("ExternalIndex", out var index))
if (_examineManager.TryGetIndex(Constants.UmbracoIndexes.ExternalIndexName, out var index))
{
((BaseIndexProvider)index).TransformingIndexValues += (object sender, IndexingItemEventArgs e) =>
{
Expand Down Expand Up @@ -72,6 +79,18 @@ public void Handle(UmbracoApplicationStartingNotification notification)
values.Add("categoryAliases", new[] { string.Join(" ", categoryAliases) });
}
}

if (e.ValueSet.Values.ContainsKey("price"))
{
var prices = JsonConvert.DeserializeObject<Dictionary<Guid, string>>(e.ValueSet.GetValue("price").ToString());
foreach (var price in prices)
{
var currency = _currencyService.GetCurrency(price.Key);
if (currency == null)
continue;
values.Add($"price_{currency.Code}", new[] { price.Value });
}
}
}

// ================================================================
Expand Down
20 changes: 20 additions & 0 deletions src/Umbraco.Commerce.DemoStore/Models/FacetGroup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Collections.Generic;

namespace Umbraco.Commerce.DemoStore.Models
{
public class FacetGroup
{
public string Name { get; set; }

public IEnumerable<Facet> Facets { get; set; }
}

public class Facet
{
public string Name { get; set; }

public string Value { get; set; }

public long Count { get; set; }
}
}
12 changes: 12 additions & 0 deletions src/Umbraco.Commerce.DemoStore/Models/ProductListViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Collections.Generic;
using Umbraco.Commerce.Common.Models;

namespace Umbraco.Commerce.DemoStore.Models
{
public class ProductListViewModel
{
public IEnumerable<FacetGroup> Facets { get; set; }

public PagedResult<ProductPage> Products { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Examine.Core" Version="4.0.0-beta.231" />
<PackageReference Include="Examine.Lucene" Version="4.0.0-beta.1" />
<PackageReference Include="Umbraco.Cms.Web.Website" Version="12.1.1" />
<PackageReference Include="Umbraco.Commerce.Cms.Startup" Version="12.1.0-rc1" />
<PackageReference Include="Umbraco.Commerce.Persistence.Sqlite" Version="12.1.0-rc1" />
Expand Down
56 changes: 56 additions & 0 deletions src/Umbraco.Commerce.DemoStore/Web/Index/ConfigureIndexOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Examine;
using Examine.Lucene;
using Lucene.Net.Facet;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using Umbraco.Cms.Core;
using Umbraco.Commerce.Core.Configuration.Models;

namespace Umbraco.Commerce.DemoStore.Web.Index
{
public sealed class ConfigureIndexOptions : IConfigureNamedOptions<LuceneDirectoryIndexOptions>
{
private readonly ILoggerFactory _loggerFactory;
private readonly UmbracoCommerceSettings _settings;

public ConfigureIndexOptions(ILoggerFactory loggerFactory, IOptions<UmbracoCommerceSettings> settings)
{
_loggerFactory = loggerFactory;
_settings = settings.Value;
}

public void Configure(string name, LuceneDirectoryIndexOptions options)
{
switch (name)
{
case Constants.UmbracoIndexes.ExternalIndexName:

var priceFields = new List<string>
{
"price_GBP"
};

// Create a config
var facetsConfig = new FacetsConfig();

options.FieldDefinitions.TryAdd(new FieldDefinition("isGiftCard", FieldDefinitionTypes.FacetInteger));
facetsConfig.SetIndexFieldName("isGiftCard", $"facet_isGiftCard");

foreach (var field in priceFields)
{
options.FieldDefinitions.TryAdd(new FieldDefinition(field, FieldDefinitionTypes.FacetDouble));
facetsConfig.SetIndexFieldName(field, $"facet_{field}");
}

options.FacetsConfig = facetsConfig;
//options.UseTaxonomyIndex = true;

break;
}
}

public void Configure(LuceneDirectoryIndexOptions options)
=> Configure(string.Empty, options);
}
}
88 changes: 88 additions & 0 deletions src/Umbraco.Commerce.DemoStore/Web/Services/FacetService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using Examine;
using Examine.Lucene;
using Examine.Lucene.Search;
using Examine.Search;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Cms.Core;
using Umbraco.Commerce.DemoStore.Models;
using Umbraco.Extensions;

namespace Umbraco.Commerce.DemoStore.Web.Services
{
public interface IFacetService
{
IEnumerable<FacetGroup> GetFacets(int? collectionId, string category);
}

public class FacetService : IFacetService
{
private readonly IExamineManager _examineManager;

public FacetService(IExamineManager examineManager)
{
_examineManager = examineManager;
}

public IEnumerable<FacetGroup> GetFacets(int? collectionId, string category)
{
if (_examineManager.TryGetIndex(Constants.UmbracoIndexes.ExternalIndexName, out var index))
{
var q = $"+(__NodeTypeAlias:{ProductPage.ModelTypeAlias} __NodeTypeAlias:{MultiVariantProductPage.ModelTypeAlias})";

if (collectionId.HasValue)
{
q += $" +searchPath:{collectionId.Value}";
}

if (!category.IsNullOrWhiteSpace())
{
q += $" +categoryAliases:\"{category}\"";
}

var searcher = index.Searcher;
var query = searcher.CreateQuery().NativeQuery(q);

var results = query.OrderBy(new SortableField("name", SortType.String))
.WithFacets(facets => facets
.FacetString("isGiftCard", null, new[] { "1" })
//.FacetLongRange("isGiftCard", new Int64Range[] {
// new Int64Range("no", 0, true, 1, false),
// new Int64Range("yes", 0, false, 1, true)
//})
.FacetDoubleRange("price_GBP", new DoubleRange[] {
new DoubleRange("0-10", 0, true, 10, true),
new DoubleRange("11-20", 11, true, 20, true),
new DoubleRange("20-30", 21, true, 30, true),
new DoubleRange("30-40", 31, true, 40, true),
new DoubleRange("40-50", 41, true, 50, true)
})) // Get facets of the price field
.Execute(QueryOptions.SkipTake(0, 1000));

var facets = results.GetFacets();

return MapFacets(facets.ToList());
}

return Enumerable.Empty<FacetGroup>();
}

private static IEnumerable<FacetGroup> MapFacets(IList<IFacetResult> facets)
{
var mappedFacets = facets
.Select((x, i) => new FacetGroup()
{
Name = i == 0 ? "Gift Card" : "Price", //GetFacetName(x),
Facets = x.Select(f => new Facet()
{
Name = f.Label,
//Value = f.Value,
Count = (long)f.Value
})
.OrderBy(f => f.Name)
});

return mappedFacets;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Microsoft.AspNetCore.Mvc;
using Umbraco.Commerce.DemoStore.Web.Services;

namespace Umbraco.Commerce.DemoStore.Web.ViewComponents
{
[ViewComponent]
public class FacetViewComponent : ViewComponent
{
private readonly IFacetService _facetService;

public FacetViewComponent(IFacetService facetService)
{
_facetService = facetService;
}

public IViewComponentResult Invoke(int? collectionId, string category)
{
var facets = _facetService.GetFacets(collectionId, category);

return View("Facets", facets);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using Examine;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Web;
using Umbraco.Commerce.DemoStore.Models;
using Umbraco.Commerce.DemoStore.Web.Extensions;
using Umbraco.Commerce.DemoStore.Web.Services;

namespace Umbraco.Commerce.DemoStore.Web.ViewComponents
{
Expand All @@ -10,14 +12,17 @@ public class ProductListByCategoryViewComponent : ProductViewComponentBase
{
public ProductListByCategoryViewComponent(IExamineManager examineManager, IUmbracoContextFactory umbracoContextFactory)
: base(examineManager, umbracoContextFactory)
{ }
{
}

public IViewComponentResult Invoke(string category)
{
var p = Request.Query.GetInt("p", 1);
var ps = Request.Query.GetInt("ps", 12);

return View("PagedProductList", GetPagedProducts(null, category, p, ps));
var products = GetPagedProducts(null, category, p, ps);

return View("PagedProductList", products);
}
}
}
Loading