Skip to content

Commit 75b2ca3

Browse files
authored
feat(routing): provide a mechanism to synchronize the search (#2829)
* chore(serve): fix serve cmd with webpack config * fix(refinementList): wrong error message with wrong parameters * refactor(url-sync): remove unused code * feat(url-sync-2): add an experimental history handler * feat: support for new history handler in ref. list and searchbox * chore: cleanup dead code * feat(modern-history): add configurable debounce * chore(modern-history): make title update * feat(hierarchicalMenu): makes the connector syncable * feat(modern-history): methods to make customization easier * feat(pagination): add support for URLSync2 * chore(refactoring): renaming based after review * chore(refactor): update methods to final API * chore: do not uglify in dev + better banner * chore: fix naming refactoring * feat: pagination starts at 1 * feat: support hitsPerPage * feat: support for menu * fix: ui state create for menu * chore: fix doc * feat: support for numericRefinementList * chore: do not encode by default * feat: support for numericSelector * feat(routing): add support for priceRanges * feat(routing): support for range-* * fix(routing): prevent override in refinementList * feat(routing): support for sort-by * refactoring: make inner methode use searchparameters And fix test accordingly. * feat(routing): support for starRating * feat(routing): refinementlist support of conjunctive facets * fix(routing): prevent from breaking other widget routing feat * fix(connectMenu): do not add entry in view state when not used * feat(routing): add support for toggle widget * feat(routing): tests for hierarchical menu and hitsperpage connectors * feat(routing): add test for connectMenu * feat(routing): add tests for connectNumericRefinementList * chore: prettierify * feat(routing): support for numericSelector * feat(routing): support for pagination * fix(routing): should enforce the default value * feat(routing): support for priceRanges * feat: tests for connnectRange and connectPriceRanges * chore: formating * chore(connectRefinementList): refactor test * feat(routing): add tests connectRefinementList (and fix behavior) * feat(routing): add tests for searchbox * feat(routing): add tests for sortBy * feat(routing): add tests for star rating * feat(routing): add tests for toggle * chore: prettier * fix: move router -> routers, stateMapping -> stateMappings And also the namespace when using InstantSearch without a package manager is routers not routing * chore: rename writeTimeout => writeDelay * chore: rename titleFromUIState into windowTitle * fix(routing): history routers should be robust by default * fix(connectSortBySelector): correct behavior of default index Previously the index name used as the default was the one at the init. However this one is the one from the URL if provided. We should rely on the one provided on the instance of InstantSearch. For this purpose, I had to provide also an instance of InstantSearch in the test. * fix(connectToggle): was reseting the page This widget uses the Helper in order to modify the current value of the facet at init. This resets the page to 0. Now it stores the currrent page before and reapply it after. * fix(routing): hierarchicalMenu.getWidgetState should keep other entries * chore: add some comments to the tests * chore: prettier * fix(rangeSlider): handles were blocked (#2849) This was because rheostat (our preact version) was using incompatible versions from ours (preact and preact-compat). This PR makes sure that we are using the same exact version as the min. for rhoestat in order to end up with the same dependencies when resolving the dependencies. * v2.6.3 <a name=2.6.3></a> ## [2.6.3](v2.6.2...v2.6.3) (2018-03-30) ### Bug Fixes * **rangeSlider:** handles were blocked ([#2849](#2849)) ([a2af4f0](a2af4f0)) * chore(doc): better error message for @type wrong def * chore(doc): Give more context for "undefined type" warning * chore(doc): fix doc * chore(test): use real helper when necessary All tests should be updated to follow this pattern eventually. * chore: add yarn-error.log to .gitignore * v2.7.0-beta.0 <a name=2.7.0-beta.0></a> # [2.7.0-beta.0](v2.6.3...v2.7.0-beta.0) (2018-04-01) ### Bug Fixes * **connectMenu:** do not add entry in view state when not used ([5f105b2](5f105b2)) * **connectSortBySelector:** correct behavior of default index ([a8fcec5](a8fcec5)) * **connectToggle:** was reseting the page ([89456e9](89456e9)) * **refinementList:** wrong error message with wrong parameters ([3b251ee](3b251ee)) * **routing:** hierarchicalMenu.getWidgetState should keep other entries ([7ef34e3](7ef34e3)) * **routing:** history routers should be robust by default ([8ad84b1](8ad84b1)) * **routing:** prevent from breaking other widget routing feat ([9a8e0f2](9a8e0f2)) * **routing:** prevent override in refinementList ([46ac948](46ac948)) * **routing:** should enforce the default value ([693401a](693401a)) * move router -> routers, stateMapping -> stateMappings ([e0aec47](e0aec47)) * ui state create for menu ([6236e59](6236e59)) ### Features * **hierarchicalMenu:** makes the connector syncable ([6dd3a33](6dd3a33)) * **modern-history:** add configurable debounce ([01aa150](01aa150)) * **modern-history:** methods to make customization easier ([3cb8b1f](3cb8b1f)) * **pagination:** add support for URLSync2 ([3f8f030](3f8f030)) * **routing:** add support for priceRanges ([70134eb](70134eb)) * **routing:** add support for toggle widget ([ca0ba8c](ca0ba8c)) * **routing:** add test for connectMenu ([046c85d](046c85d)) * **routing:** add tests connectRefinementList (and fix behavior) ([b6b6553](b6b6553)) * **routing:** add tests for connectNumericRefinementList ([e84e49b](e84e49b)) * **routing:** add tests for searchbox ([831d507](831d507)) * **routing:** add tests for sortBy ([2cbbe20](2cbbe20)) * **routing:** add tests for star rating ([a315c27](a315c27)) * **routing:** add tests for toggle ([2e43ac7](2e43ac7)) * **routing:** refinementlist support of conjunctive facets ([1a2a6fa](1a2a6fa)) * **routing:** support for numericSelector ([259eaab](259eaab)) * **routing:** support for pagination ([12ad719](12ad719)) * **routing:** support for priceRanges ([3d72729](3d72729)) * **routing:** support for range-* ([84961b4](84961b4)) * **routing:** support for sort-by ([15f7337](15f7337)) * **routing:** support for starRating ([bc7903e](bc7903e)) * **routing:** tests for hierarchical menu and hitsperpage connectors ([de54f9a](de54f9a)) * **url-sync-2:** add an experimental history handler ([28976c7](28976c7)) * pagination starts at 1 ([c068c75](c068c75)) * support for menu ([8270386](8270386)) * support for new history handler in ref. list and searchbox ([c7867ff](c7867ff)) * support for numericRefinementList ([6634997](6634997)) * support for numericSelector ([887f889](887f889)) * support hitsPerPage ([7b9e567](7b9e567)) * tests for connnectRange and connectPriceRanges ([03d0f3a](03d0f3a)) * fix: default routing options should be instanciated * fix: simple state mapping doesn't take parameters * v2.7.0-beta.1 <a name=2.7.0-beta.1></a> # [2.7.0-beta.1](v2.6.3...v2.7.0-beta.1) (2018-04-01) ### Bug Fixes * **connectMenu:** do not add entry in view state when not used ([5f105b2](5f105b2)) * **connectSortBySelector:** correct behavior of default index ([a8fcec5](a8fcec5)) * **connectToggle:** was reseting the page ([89456e9](89456e9)) * move router -> routers, stateMapping -> stateMappings ([e0aec47](e0aec47)) * **refinementList:** wrong error message with wrong parameters ([3b251ee](3b251ee)) * **routing:** hierarchicalMenu.getWidgetState should keep other entries ([7ef34e3](7ef34e3)) * default routing options should be instanciated ([34b089e](34b089e)) * simple state mapping doesn't take parameters ([6517f27](6517f27)) * ui state create for menu ([6236e59](6236e59)) * **routing:** history routers should be robust by default ([8ad84b1](8ad84b1)) * **routing:** prevent from breaking other widget routing feat ([9a8e0f2](9a8e0f2)) * **routing:** prevent override in refinementList ([46ac948](46ac948)) * **routing:** should enforce the default value ([693401a](693401a)) ### Features * **hierarchicalMenu:** makes the connector syncable ([6dd3a33](6dd3a33)) * **modern-history:** add configurable debounce ([01aa150](01aa150)) * **modern-history:** methods to make customization easier ([3cb8b1f](3cb8b1f)) * **pagination:** add support for URLSync2 ([3f8f030](3f8f030)) * **routing:** add support for priceRanges ([70134eb](70134eb)) * **routing:** add support for toggle widget ([ca0ba8c](ca0ba8c)) * **routing:** add test for connectMenu ([046c85d](046c85d)) * **routing:** add tests connectRefinementList (and fix behavior) ([b6b6553](b6b6553)) * **routing:** add tests for connectNumericRefinementList ([e84e49b](e84e49b)) * **routing:** add tests for searchbox ([831d507](831d507)) * **routing:** add tests for sortBy ([2cbbe20](2cbbe20)) * **routing:** add tests for star rating ([a315c27](a315c27)) * **routing:** add tests for toggle ([2e43ac7](2e43ac7)) * **routing:** refinementlist support of conjunctive facets ([1a2a6fa](1a2a6fa)) * **routing:** support for numericSelector ([259eaab](259eaab)) * **routing:** support for pagination ([12ad719](12ad719)) * **routing:** support for priceRanges ([3d72729](3d72729)) * **routing:** support for range-* ([84961b4](84961b4)) * **routing:** support for sort-by ([15f7337](15f7337)) * **routing:** support for starRating ([bc7903e](bc7903e)) * **routing:** tests for hierarchical menu and hitsperpage connectors ([de54f9a](de54f9a)) * **url-sync-2:** add an experimental history handler ([28976c7](28976c7)) * pagination starts at 1 ([c068c75](c068c75)) * support for menu ([8270386](8270386)) * support for new history handler in ref. list and searchbox ([c7867ff](c7867ff)) * support for numericRefinementList ([6634997](6634997)) * support for numericSelector ([887f889](887f889)) * support hitsPerPage ([7b9e567](7b9e567)) * tests for connnectRange and connectPriceRanges ([03d0f3a](03d0f3a)) * fix(test): also test for beta versions * fix: using urlsync and router should trigger an error * chore(docs): add jsdoc for the router on InstantSearch.js * chore: refactor API names + test of RoutingManager * chore: better import of helper in tests * chore: remove useless else branch * refactor(priceRanges): return early and intentional code * fix(priceRanges): widen test spectrum for other range of values * refactor(connectRange): make code more intentional Also add more test. * v2.7.0-beta.2 <a name=2.7.0-beta.2></a> # [2.7.0-beta.2](v2.6.3...v2.7.0-beta.2) (2018-04-07) ### Bug Fixes * **connectMenu:** do not add entry in view state when not used ([5f105b2](5f105b2)) * **connectSortBySelector:** correct behavior of default index ([a8fcec5](a8fcec5)) * **connectToggle:** was reseting the page ([89456e9](89456e9)) * **priceRanges:** widen test spectrum for other range of values ([caaca8c](caaca8c)) * **refinementList:** wrong error message with wrong parameters ([3b251ee](3b251ee)) * **routing:** hierarchicalMenu.getWidgetState should keep other entries ([7ef34e3](7ef34e3)) * **routing:** history routers should be robust by default ([8ad84b1](8ad84b1)) * **routing:** prevent from breaking other widget routing feat ([9a8e0f2](9a8e0f2)) * **routing:** prevent override in refinementList ([46ac948](46ac948)) * **routing:** should enforce the default value ([693401a](693401a)) * **test:** also test for beta versions ([33f2dfb](33f2dfb)) * default routing options should be instanciated ([34b089e](34b089e)) * move router -> routers, stateMapping -> stateMappings ([e0aec47](e0aec47)) * simple state mapping doesn't take parameters ([6517f27](6517f27)) * ui state create for menu ([6236e59](6236e59)) * using urlsync and router should trigger an error ([9e0bc57](9e0bc57)) ### Features * **hierarchicalMenu:** makes the connector syncable ([6dd3a33](6dd3a33)) * **modern-history:** add configurable debounce ([01aa150](01aa150)) * **modern-history:** methods to make customization easier ([3cb8b1f](3cb8b1f)) * **pagination:** add support for URLSync2 ([3f8f030](3f8f030)) * **routing:** add support for priceRanges ([70134eb](70134eb)) * **routing:** add support for toggle widget ([ca0ba8c](ca0ba8c)) * **routing:** add test for connectMenu ([046c85d](046c85d)) * **routing:** add tests connectRefinementList (and fix behavior) ([b6b6553](b6b6553)) * **routing:** add tests for connectNumericRefinementList ([e84e49b](e84e49b)) * **routing:** add tests for searchbox ([831d507](831d507)) * **routing:** add tests for sortBy ([2cbbe20](2cbbe20)) * **routing:** add tests for star rating ([a315c27](a315c27)) * **routing:** add tests for toggle ([2e43ac7](2e43ac7)) * **routing:** refinementlist support of conjunctive facets ([1a2a6fa](1a2a6fa)) * **routing:** support for numericSelector ([259eaab](259eaab)) * **routing:** support for pagination ([12ad719](12ad719)) * **routing:** support for priceRanges ([3d72729](3d72729)) * **routing:** support for range-* ([84961b4](84961b4)) * **routing:** support for sort-by ([15f7337](15f7337)) * **routing:** support for starRating ([bc7903e](bc7903e)) * **routing:** tests for hierarchical menu and hitsperpage connectors ([de54f9a](de54f9a)) * **url-sync-2:** add an experimental history handler ([28976c7](28976c7)) * pagination starts at 1 ([c068c75](c068c75)) * support for menu ([8270386](8270386)) * support for new history handler in ref. list and searchbox ([c7867ff](c7867ff)) * support for numericRefinementList ([6634997](6634997)) * support for numericSelector ([887f889](887f889)) * support hitsPerPage ([7b9e567](7b9e567)) * tests for connnectRange and connectPriceRanges ([03d0f3a](03d0f3a)) * fix(priceRanges): partial update from URL should not drop values * fix(range): partial update from URL should not drop values * chore(RoutingManager-test): use native done in tests * fix(connectRange): use lodash isFinite * refactor(connectNumericRefinementList): show intent and return sooner for getWidgetSearchParameters. * chore(connectNumericRefinementList): add tests for equality
1 parent 8fdf752 commit 75b2ca3

File tree

62 files changed

+5274
-184
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+5274
-184
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ functional-tests/screenshots/
1414

1515
# Ignore ES6 build files
1616
es/
17+
18+
yarn-error.log

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
<a name="2.6.3"></a>
2+
## [2.6.3](https://github.com/algolia/instantsearch.js/compare/v2.6.2...v2.6.3) (2018-03-30)
3+
4+
5+
### Bug Fixes
6+
7+
* **rangeSlider:** handles were blocked ([#2849](https://github.com/algolia/instantsearch.js/issues/2849)) ([a2af4f0](https://github.com/algolia/instantsearch.js/commit/a2af4f0))
8+
9+
10+
111
<a name="2.6.2"></a>
212
## [2.6.2](https://github.com/algolia/instantsearch.js/compare/v2.6.1...v2.6.2) (2018-03-29)
313

docgen/plugins/documentationjs-data.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,7 @@ export default function({rootJSFile}) {
5959
metalsmith.metadata().widgetSymbols = groupSymbolsByCategories(filterSymbolsByType('WidgetFactory', mdFormattedSymbols));
6060

6161
console.log('after documentationjs');
62-
done();
63-
}, (e) => done);
62+
}, e => {throw e}).catch(e => console.error(e)).finally(done);
6463
};
6564
}
6665

@@ -74,7 +73,13 @@ function findInstantSearchFactory(symbols) {
7473

7574
function filterSymbolsByType(type, symbols) {
7675
return filter(symbols, (s) => {
77-
const index = findIndex(s.tags, t => t.title === 'type' && t.type.name === type);
76+
const index = findIndex(s.tags, t => {
77+
const isTypeTag = t.title === 'type';
78+
if(isTypeTag && !(t.type && t.type.name)) {
79+
throw new Error('Wrong jsdoc definition for @type in symbol: \n' + JSON.stringify(s, null, 2));
80+
}
81+
return isTypeTag && t.type.name === type;
82+
});
7883
return index !== -1;
7984
});
8085
}
@@ -198,15 +203,15 @@ function findRelatedTypes(functionSymbol, symbols) {
198203
} else {
199204
if (isCustomType(p.name)) {
200205
const typeSymbol = find(symbols, {name: p.name});
201-
if(!typeSymbol) console.warn('Undefined type: ', p.name);
206+
if(!typeSymbol) console.warn('Undefined type: ', p.name, JSON.stringify(functionSymbol, null, 2));
202207
else {
203208
types = [...types, typeSymbol];
204209
// iterate over each property to get their types
205210
forEach(typeSymbol.properties, p => findParamsTypes({name: p.type.name, type: p.type}));
206211
}
207212
} else if(isCustomType(p.type.name)){
208213
const typeSymbol = find(symbols, {name: p.type.name});
209-
if(!typeSymbol) console.warn('Undefined type: ', p.type.name);
214+
if(!typeSymbol) console.warn('Undefined type: ', p.type.name, JSON.stringify(functionSymbol, null, 2));
210215
else {
211216
types = [...types, typeSymbol];
212217
// iterate over each property to get their types

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "instantsearch.js",
3-
"version": "2.6.2",
3+
"version": "2.7.0-beta.2",
44
"description": "instantsearch.js is a library of widgets to build high performance instant search experiences using Algolia",
55
"homepage": "https://community.algolia.com/instantsearch.js/",
66
"keywords": [
@@ -111,6 +111,7 @@
111111
"raw-loader": "0.5.1",
112112
"react-test-renderer": "15.6.1",
113113
"sass-lint": "1.12.1",
114+
"uglifyjs-webpack-plugin": "^1.1.4",
114115
"sass-loader": "6.0.7",
115116
"scriptjs": "2.5.8",
116117
"semver": "5.5.0",
@@ -134,10 +135,11 @@
134135
"events": "1.1.0",
135136
"hogan.js": "3.0.2",
136137
"lodash": "4.17.5",
137-
"preact": "8.1.0",
138-
"preact-compat": "3.17.0",
138+
"preact": "8.2.7",
139+
"preact-compat": "3.18.0",
139140
"preact-rheostat": "2.1.1",
140141
"prop-types": "15.5.10",
142+
"qs": "6.5.1",
141143
"to-factory": "1.0.0"
142144
},
143145
"jest": {

scripts/serve.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env bash
22
# Serves the current build version on a local server available (by default) on
3-
# http://127.0.0.1:8080/instantsearch.js
3+
# http://127.0.0.1:8080/instantsearch.min.js
44
#
55
# This is useful when you want to test the latest instantsearch.js version
66
# (including your own branches) on a specific local project. Just run `npm run
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`connectHierarchicalMenu routing getWidgetSearchParameters should add the refinements according to the UI state provided 1`] = `
4+
SearchParameters {
5+
"advancedSyntax": undefined,
6+
"allowTyposOnNumericTokens": undefined,
7+
"analytics": undefined,
8+
"analyticsTags": undefined,
9+
"aroundLatLng": undefined,
10+
"aroundLatLngViaIP": undefined,
11+
"aroundPrecision": undefined,
12+
"aroundRadius": undefined,
13+
"attributesToHighlight": undefined,
14+
"attributesToRetrieve": undefined,
15+
"attributesToSnippet": undefined,
16+
"disableExactOnAttributes": undefined,
17+
"disjunctiveFacets": Array [],
18+
"disjunctiveFacetsRefinements": Object {},
19+
"distinct": undefined,
20+
"enableExactOnSingleWordQuery": undefined,
21+
"facets": Array [],
22+
"facetsExcludes": Object {},
23+
"facetsRefinements": Object {},
24+
"getRankingInfo": undefined,
25+
"hierarchicalFacets": Array [
26+
Object {
27+
"attributes": Array [
28+
"category",
29+
"subCategory",
30+
],
31+
"name": "category",
32+
"rootPath": null,
33+
"separator": " > ",
34+
"showParentLevel": true,
35+
},
36+
],
37+
"hierarchicalFacetsRefinements": Object {
38+
"category": Array [
39+
"path",
40+
],
41+
},
42+
"highlightPostTag": undefined,
43+
"highlightPreTag": undefined,
44+
"hitsPerPage": undefined,
45+
"ignorePlurals": undefined,
46+
"index": "",
47+
"insideBoundingBox": undefined,
48+
"insidePolygon": undefined,
49+
"length": undefined,
50+
"maxValuesPerFacet": 10,
51+
"minProximity": undefined,
52+
"minWordSizefor1Typo": undefined,
53+
"minWordSizefor2Typos": undefined,
54+
"minimumAroundRadius": undefined,
55+
"numericFilters": undefined,
56+
"numericRefinements": Object {},
57+
"offset": undefined,
58+
"optionalFacetFilters": undefined,
59+
"optionalTagFilters": undefined,
60+
"optionalWords": undefined,
61+
"page": 0,
62+
"query": "",
63+
"queryType": undefined,
64+
"removeWordsIfNoResults": undefined,
65+
"replaceSynonymsInHighlight": undefined,
66+
"restrictSearchableAttributes": undefined,
67+
"snippetEllipsisText": undefined,
68+
"synonyms": undefined,
69+
"tagFilters": undefined,
70+
"tagRefinements": Array [],
71+
"typoTolerance": undefined,
72+
}
73+
`;
74+
75+
exports[`connectHierarchicalMenu routing getWidgetState should add an entry equal to the refinement 1`] = `
76+
Object {
77+
"hierarchicalMenu": Object {
78+
"category": Array [
79+
"path",
80+
],
81+
},
82+
}
83+
`;
84+
85+
exports[`connectHierarchicalMenu routing getWidgetState should not overide other entries in the same namespace 1`] = `
86+
Object {
87+
"hierarchicalMenu": Object {
88+
"category": Array [
89+
"path",
90+
],
91+
"otherCategory": Array [
92+
"path",
93+
],
94+
},
95+
}
96+
`;

src/connectors/hierarchical-menu/__tests__/connectHierarchicalMenu-test.js

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import sinon from 'sinon';
22

33
import jsHelper from 'algoliasearch-helper';
44
const SearchResults = jsHelper.SearchResults;
5+
const SearchParameters = jsHelper.SearchParameters;
56

67
import connectHierarchicalMenu from '../connectHierarchicalMenu.js';
78

@@ -255,4 +256,123 @@ describe('connectHierarchicalMenu', () => {
255256
},
256257
]);
257258
});
259+
260+
describe('routing', () => {
261+
const getInitializedWidget = () => {
262+
const rendering = jest.fn();
263+
const makeWidget = connectHierarchicalMenu(rendering);
264+
const widget = makeWidget({
265+
attributes: ['category', 'subCategory'],
266+
});
267+
268+
const helper = jsHelper(
269+
{ addAlgoliaAgent: () => {} },
270+
'',
271+
widget.getConfiguration({})
272+
);
273+
helper.search = sinon.stub();
274+
275+
widget.init({
276+
helper,
277+
state: helper.state,
278+
createURL: () => '#',
279+
onHistoryChange: () => {},
280+
});
281+
282+
const { refine } = rendering.mock.calls[0][0];
283+
284+
return [widget, helper, refine];
285+
};
286+
287+
describe('getWidgetState', () => {
288+
test('should give back the object unmodified if there are no refinements', () => {
289+
const [widget, helper] = getInitializedWidget();
290+
const uiStateBefore = {};
291+
const uiStateAfter = widget.getWidgetState(uiStateBefore, {
292+
searchParameters: helper.state,
293+
helper,
294+
});
295+
296+
expect(uiStateAfter).toBe(uiStateBefore);
297+
});
298+
299+
test('should add an entry equal to the refinement', () => {
300+
const [widget, helper] = getInitializedWidget();
301+
helper.toggleRefinement('category', 'path');
302+
const uiStateBefore = {};
303+
const uiStateAfter = widget.getWidgetState(uiStateBefore, {
304+
searchParameters: helper.state,
305+
helper,
306+
});
307+
308+
expect(uiStateAfter).toMatchSnapshot();
309+
});
310+
311+
test('should not overide other entries in the same namespace', () => {
312+
const [widget, helper] = getInitializedWidget();
313+
const uiStateBefore = {
314+
hierarchicalMenu: {
315+
otherCategory: ['path'],
316+
},
317+
};
318+
helper.toggleRefinement('category', 'path');
319+
const uiStateAfter = widget.getWidgetState(uiStateBefore, {
320+
searchParameters: helper.state,
321+
helper,
322+
});
323+
324+
expect(uiStateAfter).toMatchSnapshot();
325+
});
326+
327+
test('should give back the object unmodified if refinements are already set', () => {
328+
const [widget, helper] = getInitializedWidget();
329+
const uiStateBefore = {
330+
hierarchicalMenu: {
331+
category: ['path'],
332+
},
333+
};
334+
helper.toggleRefinement('category', 'path');
335+
const uiStateAfter = widget.getWidgetState(uiStateBefore, {
336+
searchParameters: helper.state,
337+
helper,
338+
});
339+
340+
expect(uiStateAfter).toBe(uiStateBefore);
341+
});
342+
});
343+
344+
describe('getWidgetSearchParameters', () => {
345+
test('should return the same SP if there are no refinements in the UI state', () => {
346+
const [widget, helper] = getInitializedWidget();
347+
// User presses back in the browser and the URL state contains no parameters
348+
const uiState = {};
349+
// The current state is empty
350+
const searchParametersBefore = SearchParameters.make(helper.state);
351+
const searchParametersAfter = widget.getWidgetSearchParameters(
352+
searchParametersBefore,
353+
{ uiState }
354+
);
355+
// Applying an empty UI state should not change the object
356+
expect(searchParametersAfter).toBe(searchParametersBefore);
357+
});
358+
359+
test('should add the refinements according to the UI state provided', () => {
360+
const [widget, helper] = getInitializedWidget();
361+
// User presses back in the browser, and the URL contains the following:
362+
const uiState = {
363+
hierarchicalMenu: {
364+
category: ['path'],
365+
},
366+
};
367+
// The current state is empty
368+
const searchParametersBefore = SearchParameters.make(helper.state);
369+
// The state after the UI is applied on it
370+
const searchParametersAfter = widget.getWidgetSearchParameters(
371+
searchParametersBefore,
372+
{ uiState }
373+
);
374+
expect(searchParametersAfter).toMatchSnapshot();
375+
});
376+
});
377+
});
258378
});

src/connectors/hierarchical-menu/connectHierarchicalMenu.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,43 @@ export default function connectHierarchicalMenu(renderFn, unmountFn) {
213213

214214
return nextState;
215215
},
216+
217+
getWidgetState(uiState, { searchParameters }) {
218+
const path = searchParameters.getHierarchicalFacetBreadcrumb(
219+
hierarchicalFacetName
220+
);
221+
if (!path || path.length === 0) return uiState;
222+
if (
223+
uiState.hierarchicalMenu &&
224+
isEqual(path, uiState.hierarchicalMenu[hierarchicalFacetName])
225+
) {
226+
return uiState;
227+
}
228+
229+
return {
230+
...uiState,
231+
hierarchicalMenu: {
232+
...uiState.hierarchicalMenu,
233+
[hierarchicalFacetName]: path,
234+
},
235+
};
236+
},
237+
238+
getWidgetSearchParameters(searchParameters, { uiState }) {
239+
if (
240+
uiState.hierarchicalMenu &&
241+
uiState.hierarchicalMenu[hierarchicalFacetName]
242+
) {
243+
return searchParameters
244+
.clearRefinements(hierarchicalFacetName)
245+
.toggleRefinement(
246+
hierarchicalFacetName,
247+
uiState.hierarchicalMenu[hierarchicalFacetName].join(separator)
248+
);
249+
} else {
250+
return searchParameters;
251+
}
252+
},
216253
};
217254
};
218255
}

0 commit comments

Comments
 (0)