From 801581beadc19613029696edbe343a3d9c0aef7d Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 30 Sep 2020 10:28:10 +0200 Subject: [PATCH] fix(panel): react to changes on initial render (algolia/vue-instantsearch#871) you can see this when there's a query which is applied from the URL (sorry, not relevant in the storybook) which makes the `canRefine` (`ais-Panel--noRefinement`) different than the default (`true`) --- .../src/mixins/__tests__/panel.test.js | 29 ++++++++++++------- .../vue-instantsearch/src/mixins/panel.js | 23 ++++++++------- .../stories/Panel.stories.js | 8 +++++ 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/packages/vue-instantsearch/src/mixins/__tests__/panel.test.js b/packages/vue-instantsearch/src/mixins/__tests__/panel.test.js index 5042297d35..408e5dca48 100644 --- a/packages/vue-instantsearch/src/mixins/__tests__/panel.test.js +++ b/packages/vue-instantsearch/src/mixins/__tests__/panel.test.js @@ -108,16 +108,18 @@ describe('createPanelConsumerMixin', () => { attributeName: false, }; - expect(emitter.$emit).toHaveBeenCalledTimes(0); + expect(emitter.$emit).toHaveBeenCalledTimes(1); + expect(emitter.$emit).toHaveBeenLastCalledWith(PANEL_CHANGE_EVENT, false); wrapper.vm.state = { attributeName: true, }; - expect(emitter.$emit).toHaveBeenCalledTimes(1); + expect(emitter.$emit).toHaveBeenCalledTimes(2); + expect(emitter.$emit).toHaveBeenLastCalledWith(PANEL_CHANGE_EVENT, true); }); - it('emits at least once when both values are set', () => { + it('emits once when both values are set', () => { const localVue = createLocalVue(); const emitter = createFakeEmitter(); const Test = createFakeComponent(localVue); @@ -137,7 +139,8 @@ describe('createPanelConsumerMixin', () => { attributeName: false, }; - expect(emitter.$emit).toHaveBeenCalledTimes(0); + expect(emitter.$emit).toHaveBeenCalledTimes(1); + expect(emitter.$emit).toHaveBeenLastCalledWith(PANEL_CHANGE_EVENT, false); wrapper.vm.state = { attributeName: false, @@ -146,7 +149,7 @@ describe('createPanelConsumerMixin', () => { expect(emitter.$emit).toHaveBeenCalledTimes(1); }); - it('do not emit when the previous value is not set', () => { + it('emits once on init of the component', () => { const localVue = createLocalVue(); const emitter = createFakeEmitter(); const Test = createFakeComponent(localVue); @@ -166,7 +169,8 @@ describe('createPanelConsumerMixin', () => { attributeName: true, }; - expect(emitter.$emit).not.toHaveBeenCalled(); + expect(emitter.$emit).toHaveBeenCalledTimes(1); + expect(emitter.$emit).toHaveBeenLastCalledWith(PANEL_CHANGE_EVENT, true); }); it('do not emit when the next value is not set', () => { @@ -189,11 +193,12 @@ describe('createPanelConsumerMixin', () => { attributeName: true, }; - expect(emitter.$emit).not.toHaveBeenCalled(); + expect(emitter.$emit).toHaveBeenCalledTimes(1); + expect(emitter.$emit).toHaveBeenLastCalledWith(PANEL_CHANGE_EVENT, true); wrapper.vm.state = null; - expect(emitter.$emit).not.toHaveBeenCalled(); + expect(emitter.$emit).toHaveBeenCalledTimes(1); }); it('do not emit when the previous and next value are equal', () => { @@ -216,18 +221,20 @@ describe('createPanelConsumerMixin', () => { attributeName: true, }; - expect(emitter.$emit).not.toHaveBeenCalled(); + expect(emitter.$emit).toHaveBeenCalledTimes(1); + expect(emitter.$emit).toHaveBeenLastCalledWith(PANEL_CHANGE_EVENT, true); wrapper.vm.state = { attributeName: false, }; - expect(emitter.$emit).toHaveBeenCalledTimes(1); + expect(emitter.$emit).toHaveBeenCalledTimes(2); + expect(emitter.$emit).toHaveBeenLastCalledWith(PANEL_CHANGE_EVENT, false); wrapper.vm.state = { attributeName: false, }; - expect(emitter.$emit).toHaveBeenCalledTimes(1); + expect(emitter.$emit).toHaveBeenCalledTimes(2); }); }); diff --git a/packages/vue-instantsearch/src/mixins/panel.js b/packages/vue-instantsearch/src/mixins/panel.js index 40464ea370..7c90c864a3 100644 --- a/packages/vue-instantsearch/src/mixins/panel.js +++ b/packages/vue-instantsearch/src/mixins/panel.js @@ -58,19 +58,22 @@ export const createPanelConsumerMixin = ({ mapStateToCanRefine }) => ({ }; }, watch: { - state(nextState, previousState) { - if (!previousState || !nextState) { - return; - } + state: { + immediate: true, + handler(nextState, previousState) { + if (!nextState) { + return; + } - const previousCanRefine = mapStateToCanRefine(previousState); - const nextCanRefine = mapStateToCanRefine(nextState); + const previousCanRefine = mapStateToCanRefine(previousState || {}); + const nextCanRefine = mapStateToCanRefine(nextState); - if (!this.hasAlreadyEmitted || previousCanRefine !== nextCanRefine) { - this.emitter.$emit(PANEL_CHANGE_EVENT, nextCanRefine); + if (!this.hasAlreadyEmitted || previousCanRefine !== nextCanRefine) { + this.emitter.$emit(PANEL_CHANGE_EVENT, nextCanRefine); - this.hasAlreadyEmitted = true; - } + this.hasAlreadyEmitted = true; + } + }, }, }, }); diff --git a/packages/vue-instantsearch/stories/Panel.stories.js b/packages/vue-instantsearch/stories/Panel.stories.js index b04a25bc06..e341cfd90b 100644 --- a/packages/vue-instantsearch/stories/Panel.stories.js +++ b/packages/vue-instantsearch/stories/Panel.stories.js @@ -4,6 +4,14 @@ import { previewWrapper } from './utils'; storiesOf('ais-panel', module) .addDecorator(previewWrapper()) .add('default', () => ({ + template: ` + + + + + `, + })) + .add('text content', () => ({ template: ` This is the body of the Panel.