From 04437b0033d6378afb0b4702b7e69be39e03a0fd Mon Sep 17 00:00:00 2001 From: Alexandre Stanislawski Date: Wed, 15 Feb 2017 15:35:51 +0100 Subject: [PATCH] feat(connector): remove legacy implementation of toggle --- src/connectors/toggle/connectToggle.js | 235 ++++++++++++------ .../toggle/implementations/current.js | 132 ---------- .../toggle/implementations/legacy.js | 111 --------- .../currentToggle-test.js} | 118 +++++---- .../toggle/implementations/currentToggle.js | 128 ---------- .../toggle/implementations/legacyToggle.js | 102 -------- src/widgets/toggle/toggle.js | 1 + 7 files changed, 224 insertions(+), 603 deletions(-) delete mode 100644 src/connectors/toggle/implementations/current.js delete mode 100644 src/connectors/toggle/implementations/legacy.js rename src/widgets/toggle/{implementations/__tests__/currentToggle-test.skip.js => __tests__/currentToggle-test.js} (79%) delete mode 100644 src/widgets/toggle/implementations/currentToggle.js delete mode 100644 src/widgets/toggle/implementations/legacyToggle.js diff --git a/src/connectors/toggle/connectToggle.js b/src/connectors/toggle/connectToggle.js index cda9a0770a..67314b3746 100644 --- a/src/connectors/toggle/connectToggle.js +++ b/src/connectors/toggle/connectToggle.js @@ -1,20 +1,17 @@ +import find from 'lodash/find'; + import { + prepareTemplateProps, bemHelper, getContainerNode, + escapeRefinement, + unescapeRefinement, } from '../../lib/utils.js'; import defaultTemplates from './defaultTemplates.js'; import cx from 'classnames'; -import connectCurrent from './implementations/current.js'; -import connectLegacy from './implementations/legacy.js'; const bem = bemHelper('ais-toggle'); -// we cannot use helper. because the facet is not yet declared in the helper -const hasFacetsRefinementsFor = (attributeName, searchParameters) => - searchParameters && - searchParameters.facetsRefinements && - searchParameters.facetsRefinements[attributeName] !== undefined; - /** * Instantiate the toggling of a boolean facet filter on and off. * @function toggle @@ -64,74 +61,160 @@ toggle({ [ autoHideContainer=true ], [ collapsible=false ] })`; -function connectToggle(toggleRendering) { - const legacyToggle = connectLegacy(toggleRendering); - const currentToggle = connectCurrent(toggleRendering); - - return ({ - container, - attributeName, - label, - values: userValues = {on: true, off: undefined}, - templates = defaultTemplates, - collapsible = false, - cssClasses: userCssClasses = {}, - transformData, - autoHideContainer = true, - } = {}) => { - const containerNode = getContainerNode(container); - - if (!container || !attributeName || !label) { - throw new Error(usage); - } - - const hasAnOffValue = userValues.off !== undefined; - - const cssClasses = { - root: cx(bem(null), userCssClasses.root), - header: cx(bem('header'), userCssClasses.header), - body: cx(bem('body'), userCssClasses.body), - footer: cx(bem('footer'), userCssClasses.footer), - list: cx(bem('list'), userCssClasses.list), - item: cx(bem('item'), userCssClasses.item), - active: cx(bem('item', 'active'), userCssClasses.active), - label: cx(bem('label'), userCssClasses.label), - checkbox: cx(bem('checkbox'), userCssClasses.checkbox), - count: cx(bem('count'), userCssClasses.count), - }; - - // store the computed options for usage in the two toggle implementations - const implemOptions = { - attributeName, - label, - userValues, - templates, - collapsible, - transformData, - hasAnOffValue, - containerNode, - cssClasses, - autoHideContainer, - }; - - return { - getConfiguration(currentSearchParameters, searchParametersFromUrl) { - const useLegacyToggle = - hasFacetsRefinementsFor(attributeName, currentSearchParameters) || - hasFacetsRefinementsFor(attributeName, searchParametersFromUrl); - - const toggleImplementation = useLegacyToggle ? - legacyToggle(implemOptions) : - currentToggle(implemOptions); - - this.init = toggleImplementation.init.bind(toggleImplementation); - this.render = toggleImplementation.render.bind(toggleImplementation); - return toggleImplementation.getConfiguration(currentSearchParameters, searchParametersFromUrl); - }, - init() {}, - render() {}, - }; +const connectToggle = toggleRendering => ({ + container, + attributeName, + label, + values: userValues = {on: true, off: undefined}, + templates = defaultTemplates, + collapsible = false, + cssClasses: userCssClasses = {}, + transformData, + autoHideContainer = true, +} = {}) => { + const containerNode = getContainerNode(container); + + if (!container || !attributeName || !label) { + throw new Error(usage); + } + + const hasAnOffValue = userValues.off !== undefined; + const on = userValues ? escapeRefinement(userValues.on) : undefined; + const off = userValues ? escapeRefinement(userValues.off) : undefined; + + const cssClasses = { + root: cx(bem(null), userCssClasses.root), + header: cx(bem('header'), userCssClasses.header), + body: cx(bem('body'), userCssClasses.body), + footer: cx(bem('footer'), userCssClasses.footer), + list: cx(bem('list'), userCssClasses.list), + item: cx(bem('item'), userCssClasses.item), + active: cx(bem('item', 'active'), userCssClasses.active), + label: cx(bem('label'), userCssClasses.label), + checkbox: cx(bem('checkbox'), userCssClasses.checkbox), + count: cx(bem('count'), userCssClasses.count), + }; + + return { + getConfiguration() { + return { + disjunctiveFacets: [attributeName], + }; + }, + init({state, helper, templatesConfig, createURL}) { + this._templateProps = prepareTemplateProps({ + transformData, + defaultTemplates, + templatesConfig, + templates, + }); + + this.toggleRefinement = this.toggleRefinement.bind(this, helper); + + // Bind createURL to this specific attribute + this._createURL = (currentState, isCurrentlyRefined) => () => + createURL(currentState.removeDisjunctiveFacetRefinement(attributeName, isCurrentlyRefined ? on : off) + .addDisjunctiveFacetRefinement(attributeName, isCurrentlyRefined ? off : on)); + + const isRefined = state.isDisjunctiveFacetRefined(attributeName, on); + // no need to refine anything at init if no custom off values + if (hasAnOffValue) { + // Add filtering on the 'off' value if set + if (!isRefined) { + helper.addDisjunctiveFacetRefinement(attributeName, off); + } + } + + const onFacetValue = { + name: label, + isRefined, + count: 0, + }; + + const offFacetValue = { + name: label, + isRefined: hasAnOffValue && !isRefined, + count: 0, + }; + + const facetValue = { + name: label, + isRefined, + count: null, + onFacetValue, + offFacetValue, + }; + + toggleRendering({ + collapsible, + createURL: this._createURL(state, isRefined), + cssClasses, + facetValues: [facetValue], + shouldAutoHideContainer: autoHideContainer, + templateProps: this._templateProps, + toggleRefinement: this.toggleRefinement, + containerNode, + }, true); + }, + render({helper, results, state}) { + const isRefined = helper.state.isDisjunctiveFacetRefined(attributeName, on); + const offValue = off === undefined ? false : off; + const allFacetValues = results.getFacetValues(attributeName); + const onData = find(allFacetValues, {name: unescapeRefinement(on)}); + const onFacetValue = { + name: label, + isRefined: onData !== undefined ? onData.isRefined : false, + count: onData === undefined ? null : onData.count, + }; + const offData = hasAnOffValue ? find(allFacetValues, {name: unescapeRefinement(offValue)}) : undefined; + const offFacetValue = { + name: label, + isRefined: offData !== undefined ? offData.isRefined : false, + count: offData === undefined ? results.nbHits : offData.count, + }; + + // what will we show by default, + // if checkbox is not checked, show: [ ] free shipping (countWhenChecked) + // if checkbox is checked, show: [x] free shipping (countWhenNotChecked) + const nextRefinement = isRefined ? offFacetValue : onFacetValue; + + const facetValue = { + name: label, + isRefined, + count: nextRefinement === undefined ? null : nextRefinement.count, + onFacetValue, + offFacetValue, + }; + + toggleRendering({ + collapsible, + createURL: this._createURL(state, isRefined), + cssClasses, + facetValues: [facetValue], + shouldAutoHideContainer: autoHideContainer && (facetValue.count === 0 || facetValue.count === null), + templateProps: this._templateProps, + toggleRefinement: this.toggleRefinement, + containerNode, + }, false); + }, + toggleRefinement(helper, facetValue, isRefined) { + // Checking + if (!isRefined) { + if (hasAnOffValue) { + helper.removeDisjunctiveFacetRefinement(attributeName, off); + } + helper.addDisjunctiveFacetRefinement(attributeName, on); + } else { + // Unchecking + helper.removeDisjunctiveFacetRefinement(attributeName, on); + if (hasAnOffValue) { + helper.addDisjunctiveFacetRefinement(attributeName, off); + } + } + + helper.search(); + }, }; -} +}; export default connectToggle; diff --git a/src/connectors/toggle/implementations/current.js b/src/connectors/toggle/implementations/current.js deleted file mode 100644 index e6074b99a2..0000000000 --- a/src/connectors/toggle/implementations/current.js +++ /dev/null @@ -1,132 +0,0 @@ -import find from 'lodash/find'; -import defaultTemplates from '../defaultTemplates.js'; -import { - prepareTemplateProps, - escapeRefinement, - unescapeRefinement, -} from '../../../lib/utils.js'; - -const connectToggle = toggleRendering => ({ - attributeName, - label, - userValues, - templates, - collapsible, - transformData, - hasAnOffValue, - containerNode, - cssClasses, - autoHideContainer, -} = {}) => { - const on = userValues ? escapeRefinement(userValues.on) : undefined; - const off = userValues ? escapeRefinement(userValues.off) : undefined; - - return { - getConfiguration() { - return { - disjunctiveFacets: [attributeName], - }; - }, - toggleRefinement(helper, facetValue, isRefined) { - // Checking - if (!isRefined) { - if (hasAnOffValue) { - helper.removeDisjunctiveFacetRefinement(attributeName, off); - } - helper.addDisjunctiveFacetRefinement(attributeName, on); - } else { - // Unchecking - helper.removeDisjunctiveFacetRefinement(attributeName, on); - if (hasAnOffValue) { - helper.addDisjunctiveFacetRefinement(attributeName, off); - } - } - - helper.search(); - }, - init({state, helper, templatesConfig}) { - this._templateProps = prepareTemplateProps({ - transformData, - defaultTemplates, - templatesConfig, - templates, - }); - - this.toggleRefinement = this.toggleRefinement.bind(this, helper); - - // no need to refine anything at init if no custom off values - if (!hasAnOffValue) { - return; - } - - // Add filtering on the 'off' value if set - const isRefined = state.isDisjunctiveFacetRefined(attributeName, on); - if (!isRefined) { - helper.addDisjunctiveFacetRefinement(attributeName, off); - } - - toggleRendering({ - collapsible, - createURL: () => '', - cssClasses, - facetValues: [], - shouldAutoHideContainer: autoHideContainer, - templateProps: this._templateProps, - toggleRefinement: this.toggleRefinement, - containerNode, - }, false); - }, - render({helper, results, state, createURL}) { - const isRefined = helper.state.isDisjunctiveFacetRefined(attributeName, on); - const offValue = off === undefined ? false : off; - const allFacetValues = results.getFacetValues(attributeName); - const onData = find(allFacetValues, {name: unescapeRefinement(on)}); - const onFacetValue = { - name: label, - isRefined: onData !== undefined ? onData.isRefined : false, - count: onData === undefined ? null : onData.count, - }; - const offData = hasAnOffValue ? find(allFacetValues, {name: unescapeRefinement(offValue)}) : undefined; - const offFacetValue = { - name: label, - isRefined: offData !== undefined ? offData.isRefined : false, - count: offData === undefined ? results.nbHits : offData.count, - }; - - // what will we show by default, - // if checkbox is not checked, show: [ ] free shipping (countWhenChecked) - // if checkbox is checked, show: [x] free shipping (countWhenNotChecked) - const nextRefinement = isRefined ? offFacetValue : onFacetValue; - - const facetValue = { - name: label, - isRefined, - count: nextRefinement === undefined ? null : nextRefinement.count, - onFacetValue, - offFacetValue, - }; - - // Bind createURL to this specific attribute - function _createURL() { - return createURL( - state - .removeDisjunctiveFacetRefinement(attributeName, isRefined ? on : off) - .addDisjunctiveFacetRefinement(attributeName, isRefined ? off : on) - ); - } - - toggleRendering({ - collapsible, - createURL: _createURL, - cssClasses, - facetValues: [facetValue], - shouldAutoHideContainer: autoHideContainer && (facetValue.count === 0 || facetValue.count === null), - templateProps: this._templateProps, - toggleRefinement: this.toggleRefinement, - containerNode, - }, false); - }, - }; -}; - -export default connectToggle; diff --git a/src/connectors/toggle/implementations/legacy.js b/src/connectors/toggle/implementations/legacy.js deleted file mode 100644 index 230fd4d794..0000000000 --- a/src/connectors/toggle/implementations/legacy.js +++ /dev/null @@ -1,111 +0,0 @@ -import find from 'lodash/find'; -import defaultTemplates from '../defaultTemplates.js'; -import { - prepareTemplateProps, -} from '../../../lib/utils.js'; - -const connectToggle = toggleRendering => ({ - attributeName, - label, - userValues, - templates, - collapsible, - transformData, - hasAnOffValue, - autoHideContainer, - cssClasses, - containerNode, -} = {}) => { //eslint-disable-line - return { - getConfiguration() { - return { - facets: [attributeName], - }; - }, - toggleRefinement(helper, facetValue, isRefined) { - const on = userValues.on; - const off = userValues.off; - - // Checking - if (!isRefined) { - if (hasAnOffValue) { - helper.removeFacetRefinement(attributeName, off); - } - helper.addFacetRefinement(attributeName, on); - } else { - // Unchecking - helper.removeFacetRefinement(attributeName, on); - if (hasAnOffValue) { - helper.addFacetRefinement(attributeName, off); - } - } - - helper.search(); - }, - init({state, helper, templatesConfig}) { - this._templateProps = prepareTemplateProps({ - transformData, - defaultTemplates, - templatesConfig, - templates, - }); - this.toggleRefinement = this.toggleRefinement.bind(this, helper); - - // no need to refine anything at init if no custom off values - if (!hasAnOffValue) { - return; - } - // Add filtering on the 'off' value if set - const isRefined = state.isFacetRefined(attributeName, userValues.on); - if (!isRefined) { - helper.addFacetRefinement(attributeName, userValues.off); - } - - toggleRendering({ - collapsible, - createURL: () => '', - cssClasses, - facetValues: [], - shouldAutoHideContainer: autoHideContainer, - templateProps: this._templateProps, - toggleRefinement: this.toggleRefinement, - containerNode, - }, true); - }, - render({helper, results, state, createURL}) { - const isRefined = helper.state.isFacetRefined(attributeName, userValues.on); - const currentRefinement = isRefined ? userValues.on : userValues.off; - let count; - if (typeof currentRefinement === 'number') { - count = results.getFacetStats(attributeName).sum; - } else { - const facetData = find(results.getFacetValues(attributeName), {name: isRefined.toString()}); - count = facetData !== undefined ? facetData.count : null; - } - - const facetValue = { - name: label, - isRefined, - count, - }; - - // Bind createURL to this specific attribute - function _createURL() { - return createURL(state.toggleRefinement(attributeName, isRefined)); - } - - toggleRendering({ - collapsible, - createURL: _createURL, - cssClasses, - facetValues: [facetValue], - shouldAutoHideContainer: autoHideContainer && results.nbHits === 0, - templateProps: this._templateProps, - toggleRefinement: this.toggleRefinement, - containerNode, - }, false); - }, - }; -}; - -export default connectToggle; diff --git a/src/widgets/toggle/implementations/__tests__/currentToggle-test.skip.js b/src/widgets/toggle/__tests__/currentToggle-test.js similarity index 79% rename from src/widgets/toggle/implementations/__tests__/currentToggle-test.skip.js rename to src/widgets/toggle/__tests__/currentToggle-test.js index ae177619bc..0924446c93 100644 --- a/src/widgets/toggle/implementations/__tests__/currentToggle-test.skip.js +++ b/src/widgets/toggle/__tests__/currentToggle-test.js @@ -4,8 +4,10 @@ import React from 'react'; import expect from 'expect'; import sinon from 'sinon'; -import currentToggle from '../../toggle.js'; -import defaultTemplates from '../../../../connectors/toggle/defaultTemplates.js'; +import currentToggle from '../toggle.js'; +import defaultTemplates from '../../../connectors/toggle/defaultTemplates.js'; + +import RefinementList from '../../../components/RefinementList/RefinementList.js'; import expectJSX from 'expect-jsx'; expect.extend(expectJSX); @@ -18,7 +20,6 @@ describe('currentToggle()', () => { let attributeName; let label; let userValues; - let RefinementList; let collapsible; let cssClasses; @@ -30,11 +31,21 @@ describe('currentToggle()', () => { containerNode = document.createElement('div'); label = 'Hello, '; attributeName = 'world!'; - cssClasses = {}; + cssClasses = { + active: 'ais-toggle--item__active', + body: 'ais-toggle--body', + checkbox: 'ais-toggle--checkbox', + count: 'ais-toggle--count', + footer: 'ais-toggle--footer', + header: 'ais-toggle--header', + item: 'ais-toggle--item', + label: 'ais-toggle--label', + list: 'ais-toggle--list', + root: 'ais-toggle', + }; collapsible = false; userValues = {on: true, off: undefined}; - RefinementList = () =>
; - widget = currentToggle({containerNode, attributeName, label}); + widget = currentToggle({container: containerNode, attributeName, label}); }); it('configures disjunctiveFacets', () => { @@ -70,14 +81,14 @@ describe('currentToggle()', () => { isDisjunctiveFacetRefined: sinon.stub().returns(false), }; props = { - cssClasses: {}, + cssClasses, collapsible: false, templateProps, createURL() {}, toggleRefinement() {}, }; createURL = () => '#'; - widget.init({state}); + widget.init({state, helper, createURL}); }); it('calls twice ReactDOM.render', () => { @@ -86,10 +97,11 @@ describe('currentToggle()', () => { nbHits: 1, getFacetValues: sinon.stub().returns([{name: 'true', count: 2}, {name: 'false', count: 1}]), }; - widget = currentToggle({containerNode, attributeName, label, userValues}); + widget = currentToggle({container: containerNode, attributeName, label, userValues}); widget.getConfiguration(); - widget.render({results, helper, state, createURL}); - widget.render({results, helper, state, createURL}); + widget.init({helper, state, createURL}); + widget.render({results, helper, state}); + widget.render({results, helper, state}); expect(ReactDOM.render.calledTwice).toBe(true, 'ReactDOM.render called twice'); expect(ReactDOM.render.firstCall.args[1]).toEqual(containerNode); expect(ReactDOM.render.secondCall.args[1]).toEqual(containerNode); @@ -104,7 +116,7 @@ describe('currentToggle()', () => { {name: 'false', count: 1, isRefined: false}, ]), }; - props.cssClasses.root = 'test'; + props.cssClasses.root = 'ais-toggle test'; props = { facetValues: [{ count: 2, @@ -116,19 +128,19 @@ describe('currentToggle()', () => { shouldAutoHideContainer: false, ...props, }; - cssClasses = {root: 'test'}; + cssClasses = props.cssClasses; widget = currentToggle({ - containerNode, + container: containerNode, attributeName, label, - cssClasses, + cssClasses: {root: 'test'}, userValues, RefinementList, collapsible, }); widget.getConfiguration(); - widget.init({state, helper}); - widget.render({results, helper, state, createURL}); + widget.init({state, helper, createURL}); + widget.render({results, helper, state}); expect(ReactDOM.render.firstCall.args[0]).toEqualJSX(); }); @@ -142,18 +154,17 @@ describe('currentToggle()', () => { ]), }; widget = currentToggle({ - containerNode, + container: containerNode, attributeName, label, - cssClasses, userValues, RefinementList, collapsible, }); widget.getConfiguration(); - widget.init({state, helper}); - widget.render({results, helper, state, createURL}); - widget.render({results, helper, state, createURL}); + widget.init({state, helper, createURL}); + widget.render({results, helper, state}); + widget.render({results, helper, state}); props = { facetValues: [{ @@ -182,22 +193,19 @@ describe('currentToggle()', () => { ]), }; widget = currentToggle({ - containerNode, - hasAnOffValue: true, + container: containerNode, attributeName, label, - cssClasses, - userValues: { + values: { off: -2, on: 5, }, - RefinementList, collapsible, }); widget.getConfiguration(); - widget.init({state, helper}); - widget.render({results, helper, state, createURL}); - widget.render({results, helper, state, createURL}); + widget.init({state, helper, createURL}); + widget.render({results, helper, state}); + widget.render({results, helper, state}); props = { facetValues: [{ @@ -211,6 +219,7 @@ describe('currentToggle()', () => { ...props, }; + // The first call is not the one expected, because of the new init rendering.. expect(ReactDOM.render.firstCall.args[0]).toEqualJSX(); expect(ReactDOM.render.secondCall.args[0]).toEqualJSX(); @@ -226,18 +235,17 @@ describe('currentToggle()', () => { getFacetValues: sinon.stub().returns([]), }; widget = currentToggle({ - containerNode, + container: containerNode, attributeName, label, - cssClasses, userValues, RefinementList, collapsible, }); widget.getConfiguration(); - widget.init({state, helper}); - widget.render({results, helper, state, createURL}); - widget.render({results, helper, state, createURL}); + widget.init({state, helper, createURL}); + widget.render({results, helper, state}); + widget.render({results, helper, state}); props = { facetValues: [{ @@ -270,18 +278,17 @@ describe('currentToggle()', () => { ]), }; widget = currentToggle({ - containerNode, + container: containerNode, attributeName, label, - cssClasses, userValues, RefinementList, collapsible, }); widget.getConfiguration(); - widget.init({state, helper}); - widget.render({results, helper, state, createURL}); - widget.render({results, helper, state, createURL}); + widget.init({state, helper, createURL}); + widget.render({results, helper, state}); + widget.render({results, helper, state}); props = { facetValues: [{ @@ -306,7 +313,7 @@ describe('currentToggle()', () => { getFacetValues: sinon.stub().returns([{name: 'true', count: 2}, {name: 'false', count: 1}]), }; widget = currentToggle({ - containerNode, + container: containerNode, attributeName, label, cssClasses, @@ -315,8 +322,8 @@ describe('currentToggle()', () => { collapsible, }); widget.getConfiguration(); - widget.init({state, helper}); - widget.render({results, helper, state, createURL}); + widget.init({state, helper, createURL}); + widget.render({results, helper, state}); const toggleRefinement = ReactDOM.render.firstCall.args[0].props.toggleRefinement; expect(toggleRefinement).toBeA('function'); toggleRefinement(); @@ -347,7 +354,7 @@ describe('currentToggle()', () => { context('default values', () => { it('toggle on should add filter to true', () => { // Given - widget = currentToggle({containerNode, attributeName, label, userValues}); + widget = currentToggle({container: containerNode, attributeName, label, userValues}); widget.getConfiguration(); // When @@ -359,7 +366,7 @@ describe('currentToggle()', () => { }); it('toggle off should remove all filters', () => { // Given - widget = currentToggle({containerNode, attributeName, label, userValues}); + widget = currentToggle({container: containerNode, attributeName, label, userValues}); widget.getConfiguration(); // When @@ -374,7 +381,7 @@ describe('currentToggle()', () => { it('toggle on should change the refined value', () => { // Given userValues = {on: 'on', off: 'off'}; - widget = currentToggle({containerNode, attributeName, label, userValues, hasAnOffValue: true}); + widget = currentToggle({container: containerNode, attributeName, label, values: userValues}); widget.getConfiguration(); // When @@ -387,7 +394,7 @@ describe('currentToggle()', () => { it('toggle off should change the refined value', () => { // Given userValues = {on: 'on', off: 'off'}; - widget = currentToggle({containerNode, attributeName, label, userValues, hasAnOffValue: true}); + widget = currentToggle({container: containerNode, attributeName, label, values: userValues}); widget.getConfiguration(); // When @@ -401,10 +408,11 @@ describe('currentToggle()', () => { }); context('custom off value', () => { + const createURL = () => '#'; it('should add a refinement for custom off value on init', () => { // Given userValues = {on: 'on', off: 'off'}; - widget = currentToggle({containerNode, attributeName, label, hasAnOffValue: true, userValues}); + widget = currentToggle({container: containerNode, attributeName, label, values: userValues}); widget.getConfiguration(); const state = { isDisjunctiveFacetRefined: sinon.stub().returns(false), @@ -414,7 +422,7 @@ describe('currentToggle()', () => { }; // When - widget.init({state, helper}); + widget.init({state, helper, createURL}); // Then expect(helper.addDisjunctiveFacetRefinement.calledWith(attributeName, 'off')).toBe(true); @@ -422,7 +430,7 @@ describe('currentToggle()', () => { it('should not add a refinement for custom off value on init if already checked', () => { // Given userValues = {on: 'on', off: 'off'}; - widget = currentToggle({containerNode, attributeName, label, userValues, hasAnOffValue: true}); + widget = currentToggle({container: containerNode, attributeName, label, values: userValues}); widget.getConfiguration(); const state = { isDisjunctiveFacetRefined: sinon.stub().returns(true), @@ -432,22 +440,24 @@ describe('currentToggle()', () => { }; // When - widget.init({state, helper}); + widget.init({state, helper, createURL}); // Then expect(helper.addDisjunctiveFacetRefinement.called).toBe(false); }); it('should not add a refinement for no custom off value on init', () => { // Given - widget = currentToggle({containerNode, attributeName, label, hasAnOffValue: false, userValues}); + widget = currentToggle({container: containerNode, attributeName, label, values: userValues}); widget.getConfiguration(); - const state = {}; + const state = { + isDisjunctiveFacetRefined: () => false, + }; const helper = { addDisjunctiveFacetRefinement: sinon.spy(), }; // When - widget.init({state, helper}); + widget.init({state, helper, createURL}); // Then expect(helper.addDisjunctiveFacetRefinement.called).toBe(false); diff --git a/src/widgets/toggle/implementations/currentToggle.js b/src/widgets/toggle/implementations/currentToggle.js deleted file mode 100644 index 6a535f3c52..0000000000 --- a/src/widgets/toggle/implementations/currentToggle.js +++ /dev/null @@ -1,128 +0,0 @@ -import find from 'lodash/find'; -import React from 'react'; -import ReactDOM from 'react-dom'; -import defaultTemplates from '../../../connectors/toggle/defaultTemplates.js'; -import { - prepareTemplateProps, - escapeRefinement, - unescapeRefinement, -} from '../../../lib/utils.js'; - -// cannot use a function declaration because of -// https://github.com/speedskater/babel-plugin-rewire/issues/109#issuecomment-227917555 -const currentToggle = ({ - attributeName, - label, - userValues, - templates, - collapsible, - transformData, - hasAnOffValue, - containerNode, - RefinementList, - cssClasses, -} = {}) => { - const on = userValues ? escapeRefinement(userValues.on) : undefined; - const off = userValues ? escapeRefinement(userValues.off) : undefined; - - return { - getConfiguration() { - return { - disjunctiveFacets: [attributeName], - }; - }, - toggleRefinement(helper, facetValue, isRefined) { - // Checking - if (!isRefined) { - if (hasAnOffValue) { - helper.removeDisjunctiveFacetRefinement(attributeName, off); - } - helper.addDisjunctiveFacetRefinement(attributeName, on); - } else { - // Unchecking - helper.removeDisjunctiveFacetRefinement(attributeName, on); - if (hasAnOffValue) { - helper.addDisjunctiveFacetRefinement(attributeName, off); - } - } - - helper.search(); - }, - init({state, helper, templatesConfig}) { - this._templateProps = prepareTemplateProps({ - transformData, - defaultTemplates, - templatesConfig, - templates, - }); - - this.toggleRefinement = this.toggleRefinement.bind(this, helper); - - // no need to refine anything at init if no custom off values - if (!hasAnOffValue) { - return; - } - - // Add filtering on the 'off' value if set - const isRefined = state.isDisjunctiveFacetRefined(attributeName, on); - if (!isRefined) { - helper.addDisjunctiveFacetRefinement(attributeName, off); - } - }, - render({helper, results, state, createURL}) { - const isRefined = helper.state.isDisjunctiveFacetRefined(attributeName, on); - const onValue = on; - const offValue = off === undefined ? false : off; - const allFacetValues = results.getFacetValues(attributeName); - const onData = find(allFacetValues, {name: unescapeRefinement(onValue)}); - const onFacetValue = { - name: label, - isRefined: onData !== undefined ? onData.isRefined : false, - count: onData === undefined ? null : onData.count, - }; - const offData = hasAnOffValue ? find(allFacetValues, {name: unescapeRefinement(offValue)}) : undefined; - const offFacetValue = { - name: label, - isRefined: offData !== undefined ? offData.isRefined : false, - count: offData === undefined ? results.nbHits : offData.count, - }; - - // what will we show by default, - // if checkbox is not checked, show: [ ] free shipping (countWhenChecked) - // if checkbox is checked, show: [x] free shipping (countWhenNotChecked) - const nextRefinement = isRefined ? offFacetValue : onFacetValue; - - const facetValue = { - name: label, - isRefined, - count: nextRefinement === undefined ? null : nextRefinement.count, - onFacetValue, - offFacetValue, - }; - - // Bind createURL to this specific attribute - function _createURL() { - return createURL( - state - .removeDisjunctiveFacetRefinement(attributeName, isRefined ? onValue : off) - .addDisjunctiveFacetRefinement(attributeName, isRefined ? off : onValue) - ); - } - - ReactDOM.render( - , - containerNode - ); - }, - }; -}; - -export default currentToggle; diff --git a/src/widgets/toggle/implementations/legacyToggle.js b/src/widgets/toggle/implementations/legacyToggle.js deleted file mode 100644 index 492923a0b6..0000000000 --- a/src/widgets/toggle/implementations/legacyToggle.js +++ /dev/null @@ -1,102 +0,0 @@ -import find from 'lodash/find'; -import React from 'react'; -import ReactDOM from 'react-dom'; -import defaultTemplates from '../../../connectors/toggle/defaultTemplates.js'; -import { - prepareTemplateProps, -} from '../../../lib/utils.js'; - -export default function currentToggle({ - attributeName, - label, - userValues, - templates, - collapsible, - transformData, - hasAnOffValue, - containerNode, - RefinementList, - cssClasses, -} = {}) { - return { - getConfiguration() { - return { - facets: [attributeName], - }; - }, - toggleRefinement(helper, facetValue, isRefined) { - const on = userValues.on; - const off = userValues.off; - - // Checking - if (!isRefined) { - if (hasAnOffValue) { - helper.removeFacetRefinement(attributeName, off); - } - helper.addFacetRefinement(attributeName, on); - } else { - // Unchecking - helper.removeFacetRefinement(attributeName, on); - if (hasAnOffValue) { - helper.addFacetRefinement(attributeName, off); - } - } - - helper.search(); - }, - init({state, helper, templatesConfig}) { - this._templateProps = prepareTemplateProps({ - transformData, - defaultTemplates, - templatesConfig, - templates, - }); - this.toggleRefinement = this.toggleRefinement.bind(this, helper); - - // no need to refine anything at init if no custom off values - if (!hasAnOffValue) { - return; - } - // Add filtering on the 'off' value if set - const isRefined = state.isFacetRefined(attributeName, userValues.on); - if (!isRefined) { - helper.addFacetRefinement(attributeName, userValues.off); - } - }, - render({helper, results, state, createURL}) { - const isRefined = helper.state.isFacetRefined(attributeName, userValues.on); - const currentRefinement = isRefined ? userValues.on : userValues.off; - let count; - if (typeof currentRefinement === 'number') { - count = results.getFacetStats(attributeName).sum; - } else { - const facetData = find(results.getFacetValues(attributeName), {name: isRefined.toString()}); - count = facetData !== undefined ? facetData.count : null; - } - - const facetValue = { - name: label, - isRefined, - count, - }; - - // Bind createURL to this specific attribute - function _createURL() { - return createURL(state.toggleRefinement(attributeName, isRefined)); - } - - ReactDOM.render( - , - containerNode - ); - }, - }; -} diff --git a/src/widgets/toggle/toggle.js b/src/widgets/toggle/toggle.js index d672cbf922..3c04084b3c 100644 --- a/src/widgets/toggle/toggle.js +++ b/src/widgets/toggle/toggle.js @@ -54,6 +54,7 @@ function defaultRendering({ containerNode, }, isFirstRendering) { if (isFirstRendering) return; + ReactDOM.render(