Skip to content
This repository has been archived by the owner on Dec 30, 2022. It is now read-only.

Commit

Permalink
feat(facetOrdering): add a new option "facetOrdering" to Menu, Refine…
Browse files Browse the repository at this point in the history
…mentList & HierarchicalMenu

If `facetOrdering` is enabled (the default behaviour), before the default sortBy is used, the result from renderingContent.facetOrdering.values is first checked. If that's present, it will be used to sort the items.

You can still change that ordering afterwards with the existing transformItems, so if you are sorting in transformItems, you actually override the sorting done by facet ordering, and won't see the effect. To use facetOrdering, you thus need to remove any sorting done in transformItems.

If there is a facetOrdering present in the index, but you don't want to use it for a certain widget, you need to explicitly pass `facetOrdering: false` to the widget or connector

References:
- [RFC 45](https://github.com/algolia/instantsearch-rfcs/blob/master/accepted/flexible-facet-values.md)
- algolia/instantsearch#4784
- algolia/algoliasearch-helper-js#822
  • Loading branch information
Haroenv committed Jun 28, 2021
1 parent f39db18 commit 3edf8f4
Show file tree
Hide file tree
Showing 7 changed files with 399 additions and 10 deletions.
@@ -1,4 +1,4 @@
import { SearchParameters } from 'algoliasearch-helper';
import { SearchResults, SearchParameters } from 'algoliasearch-helper';
import connect from '../connectHierarchicalMenu';

jest.mock('../../core/createConnector', () => x => x);
Expand Down Expand Up @@ -174,6 +174,158 @@ describe('connectHierarchicalMenu', () => {
expect(props.items).toEqual(['items']);
});

it('facetValues results uses facetOrdering by default', () => {
const props = {
...connect.defaultProps,
attributes: ['lvl0', 'lvl1'],
contextValue,
};
const searchState = { hierarchicalMenu: { lvl0: 'wat' } };
const state = connect.getSearchParameters(
new SearchParameters(),
props,
searchState
);
const results = new SearchResults(state, [
{
hits: [],
renderingContent: {
facetOrdering: {
values: {
lvl0: {
order: ['wat'],
},
lvl1: {
order: ['wat > wut'],
},
},
},
},
facets: {
lvl0: {
wat: 20,
oy: 10,
},
lvl1: {
'wat > wot': 15,
'wat > wut': 5,
},
},
},
]);

const providedProps = connect.getProvidedProps(props, searchState, {
results,
});
expect(providedProps.items).toEqual([
{
label: 'wat',
value: undefined,
count: 20,
isRefined: true,
items: [
{
label: 'wut',
value: 'wat > wut',
count: 5,
isRefined: false,
items: null,
},
{
label: 'wot',
value: 'wat > wot',
count: 15,
isRefined: false,
items: null,
},
],
},
{
label: 'oy',
value: 'oy',
count: 10,
isRefined: false,
items: null,
},
]);
});

it('facetValues results does not use facetOrdering if disabled', () => {
const props = {
attributes: ['lvl0', 'lvl1'],
facetOrdering: false,
contextValue,
};
const searchState = { hierarchicalMenu: { lvl0: 'wat' } };
const state = connect.getSearchParameters(
new SearchParameters(),
props,
searchState
);
const results = new SearchResults(state, [
{
hits: [],
renderingContent: {
facetOrdering: {
values: {
lvl0: {
order: ['wat'],
},
lvl1: {
order: ['wat > wut'],
},
},
},
},
facets: {
lvl0: {
wat: 20,
oy: 10,
},
lvl1: {
'wat > wot': 15,
'wat > wut': 5,
},
},
},
]);

const providedProps = connect.getProvidedProps(props, searchState, {
results,
});
expect(providedProps.items).toEqual([
{
label: 'oy',
value: 'oy',
count: 10,
isRefined: false,
items: null,
},
{
label: 'wat',
value: undefined,
count: 20,
isRefined: true,
items: [
{
label: 'wot',
value: 'wat > wot',
count: 15,
isRefined: false,
items: null,
},
{
label: 'wut',
value: 'wat > wut',
count: 5,
isRefined: false,
items: null,
},
],
},
]);
});

it('shows the effect of showMoreLimit when there is no transformItems', () => {
const results = {
getFacetValues: jest.fn(),
Expand Down
@@ -1,4 +1,4 @@
import { SearchParameters } from 'algoliasearch-helper';
import { SearchParameters, SearchResults } from 'algoliasearch-helper';
import connect from '../connectMenu';

jest.mock('../../core/createConnector', () => x => x);
Expand Down Expand Up @@ -245,6 +245,116 @@ describe('connectMenu', () => {
]);
});

it('facetValues have facetOrdering by default', () => {
const userProps = {
...connect.defaultProps,
attribute: 'ok',
contextValue,
};
const searchState = {
menu: { ok: 'wat' },
};
const parameters = connect.getSearchParameters(
new SearchParameters(),
userProps,
searchState
);

const searchResults = new SearchResults(parameters, [
{
hits: [],
renderingContent: {
facetOrdering: {
values: {
ok: {
order: ['wat'],
},
},
},
},
facets: {
ok: {
wat: 20,
lol: 2000,
},
},
},
]);

const providedProps = connect.getProvidedProps(userProps, searchState, {
results: searchResults,
});

expect(providedProps.items).toEqual([
{
count: 20,
isRefined: true,
label: 'wat',
value: '',
},
{
count: 2000,
isRefined: false,
label: 'lol',
value: 'lol',
},
]);
expect(providedProps.isFromSearch).toBe(false);
});

it('facetValues results does not use facetOrdering if disabled', () => {
const userProps = { attribute: 'ok', facetOrdering: false, contextValue };
const searchState = {
menu: { ok: 'wat' },
};
const parameters = connect.getSearchParameters(
new SearchParameters(),
userProps,
searchState
);

const searchResults = new SearchResults(parameters, [
{
hits: [],
renderingContent: {
facetOrdering: {
values: {
ok: {
order: ['wat'],
},
},
},
},
facets: {
ok: {
wat: 20,
lol: 2000,
},
},
},
]);

const providedProps = connect.getProvidedProps(userProps, searchState, {
results: searchResults,
});

expect(providedProps.items).toEqual([
{
count: 2000,
isRefined: false,
label: 'lol',
value: 'lol',
},
{
count: 20,
isRefined: true,
label: 'wat',
value: '',
},
]);
expect(providedProps.isFromSearch).toBe(false);
});

it("calling refine updates the widget's search state", () => {
const nextState = connect.refine(
{ attribute: 'ok', contextValue },
Expand Down Expand Up @@ -435,13 +545,14 @@ describe('connectMenu', () => {
};

props = connect.getProvidedProps(
{ attribute: 'ok', contextValue },
{ ...connect.defaultProps, attribute: 'ok', contextValue },
{},
{ results }
);

expect(results.getFacetValues).toHaveBeenCalledWith('ok', {
sortBy: ['count:desc', 'name:asc'],
facetOrdering: true,
});

expect(props.items).toEqual([
Expand Down Expand Up @@ -479,13 +590,19 @@ describe('connectMenu', () => {
};

props = connect.getProvidedProps(
{ attribute: 'ok', searchable: true, contextValue },
{
...connect.defaultProps,
attribute: 'ok',
searchable: true,
contextValue,
},
{},
{ results }
);

expect(results.getFacetValues).toHaveBeenCalledWith('ok', {
sortBy: undefined,
facetOrdering: true,
});

expect(props.items).toEqual([
Expand Down

0 comments on commit 3edf8f4

Please sign in to comment.