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

Commit

Permalink
feat(ais-relevant-sort): add widget (#918)
Browse files Browse the repository at this point in the history
* feat(smartSort): add widget

* add story

* add isSmartSorted to text slot

* fix story

* fix(smartsort): don't render if not virtual replica

* test(smartsort): add tests

* chore(deps): update instantsearch

* chore(deps): update

* chore: update bundlesize

* update to relevantSort

* feat(stats): apply relevant sort

* chore: update instantsearch

Co-authored-by: Haroen Viaene <hello@haroen.me>
  • Loading branch information
Eunjae Lee and Haroenv authored Mar 3, 2021
1 parent 3c3f7e2 commit 4fe5745
Show file tree
Hide file tree
Showing 9 changed files with 212 additions and 25 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
},
"dependencies": {
"algoliasearch-helper": "^3.1.0",
"instantsearch.js": "^4.11.0"
"instantsearch.js": "^4.16.1"
},
"peerDependencies": {
"algoliasearch": ">= 3.32.0 < 5",
Expand Down Expand Up @@ -114,11 +114,11 @@
"bundlesize": [
{
"path": "./dist/vue-instantsearch.js",
"maxSize": "48.10 kB"
"maxSize": "52.50 kB"
},
{
"path": "./dist/vue-instantsearch.common.js",
"maxSize": "16 kB"
"maxSize": "16.25 kB"
}
],
"resolutions": {
Expand Down
51 changes: 51 additions & 0 deletions src/components/RelevantSort.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<template>
<div
v-if="state && state.isVirtualReplica"
:class="suit()"
>
<slot
:is-relevant-sorted="state.isRelevantSorted"
:refine="state.refine"
>
<div :class="suit('text')">
<slot
name="text"
:is-relevant-sorted="state.isRelevantSorted"
/>
</div>
<button
type="button"
:class="suit('button')"
@click="refine()"
>
<slot
name="button"
:is-relevant-sorted="state.isRelevantSorted"
>{{ state.isRelevantSorted ? 'See all results' : 'See relevant results' }}</slot>
</button>
</slot>
</div>
</template>

<script>
import { connectRelevantSort } from 'instantsearch.js/es/connectors';
import { createWidgetMixin } from '../mixins/widget';
import { createSuitMixin } from '../mixins/suit';
export default {
name: 'AisRelevantSort',
mixins: [
createSuitMixin({ name: 'RelevantSort' }),
createWidgetMixin({ connector: connectRelevantSort }),
],
methods: {
refine() {
if (this.state.isRelevantSorted) {
this.state.refine(0);
} else {
this.state.refine(undefined);
}
},
},
};
</script>
2 changes: 1 addition & 1 deletion src/components/Stats.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
v-bind="state"
:results="state.instantSearchInstance.helper.lastResults"
>
<span :class="suit('text')">{{ state.nbHits.toLocaleString() }} results found in {{ state.processingTimeMS.toLocaleString() }}ms</span>
<span :class="suit('text')"><template v-if="state.areHitsSorted">{{ state.nbSortedHits.toLocaleString() }} relevant results sorted out of {{ state.nbHits.toLocaleString() }}</template><template v-else>{{ state.nbHits.toLocaleString() }} results</template> found in {{ state.processingTimeMS.toLocaleString() }}ms</span>
</slot>
</div>
</template>
Expand Down
80 changes: 80 additions & 0 deletions src/components/__tests__/RelevantSort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { mount } from '@vue/test-utils';
import RelevantSort from '../RelevantSort.vue';
import { __setState } from '../../mixins/widget';
jest.mock('../../mixins/widget');

describe('renders correctly', () => {
test('no virtual replica', () => {
__setState({
isVirtualReplica: false,
isRelevantSorted: false,
});
const wrapper = mount(RelevantSort);
expect(wrapper.html()).toMatchInlineSnapshot(`undefined`);
});

test('not relevant sorted', () => {
__setState({
isVirtualReplica: true,
isRelevantSorted: false,
});
const wrapper = mount(RelevantSort);
expect(wrapper.html()).toMatchInlineSnapshot(`
<div class="ais-RelevantSort">
<div class="ais-RelevantSort-text">
</div>
<button type="button"
class="ais-RelevantSort-button"
>
See relevant results
</button>
</div>
`);
});

test('relevant sorted', () => {
__setState({
isVirtualReplica: true,
isRelevantSorted: true,
});
const wrapper = mount(RelevantSort);
expect(wrapper.html()).toMatchInlineSnapshot(`
<div class="ais-RelevantSort">
<div class="ais-RelevantSort-text">
</div>
<button type="button"
class="ais-RelevantSort-button"
>
See all results
</button>
</div>
`);
});
});

it("calls the connector's refine function with 0 and undefined", () => {
__setState({
isRelevantSorted: true,
isVirtualReplica: true,
refine: jest.fn(() => {
wrapper.vm.state.isRelevantSorted = !wrapper.vm.state.isRelevantSorted;
}),
});

const wrapper = mount(RelevantSort);

const button = wrapper.find('button');

button.trigger('click');
expect(wrapper.vm.state.refine).toHaveBeenLastCalledWith(0);

button.trigger('click');
expect(wrapper.vm.state.refine).toHaveBeenLastCalledWith(undefined);

button.trigger('click');
expect(wrapper.vm.state.refine).toHaveBeenLastCalledWith(0);
});
40 changes: 39 additions & 1 deletion src/components/__tests__/Stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Stats from '../Stats.vue';

import { __setState } from '../../mixins/widget';
jest.mock('../../mixins/widget');

it('renders correctly', () => {
__setState({
hitsPerPage: 50,
Expand All @@ -20,5 +21,42 @@ it('renders correctly', () => {
});

const wrapper = mount(Stats);
expect(wrapper.html()).toMatchSnapshot();
expect(wrapper.html()).toMatchInlineSnapshot(`
<div class="ais-Stats">
<span class="ais-Stats-text">
1,000 results found in 12ms
</span>
</div>
`);
});

it('renders correctly (relevant sort)', () => {
__setState({
areHitsSorted: true,
hitsPerPage: 50,
nbPages: 20,
nbHits: 1000,
nbSortedHits: 12,
page: 2,
processingTimeMS: 12,
query: 'ipho',
instantSearchInstance: {
helper: {
lastResults: [],
},
},
});

const wrapper = mount(Stats);
expect(wrapper.html()).toMatchInlineSnapshot(`
<div class="ais-Stats">
<span class="ais-Stats-text">
12 relevant results sorted out of 1,000 found in 12ms
</span>
</div>
`);
});
11 changes: 0 additions & 11 deletions src/components/__tests__/__snapshots__/Stats.js.snap

This file was deleted.

1 change: 1 addition & 0 deletions src/widgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ export {
default as AisToggleRefinement,
} from './components/ToggleRefinement.vue';
export { default as AisVoiceSearch } from './components/VoiceSearch.vue';
export { default as AisRelevantSort } from './components/RelevantSort.vue';
28 changes: 28 additions & 0 deletions stories/RelevantSort.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import algoliasearch from 'algoliasearch/lite';
import { storiesOf } from '@storybook/vue';
import { previewWrapper } from './utils';

storiesOf('ais-relevant-sort', module)
.addDecorator(
previewWrapper({
searchClient: algoliasearch(
'C7RIRJRYR9',
'77af6d5ffb27caa5ff4937099fcb92e8'
),
indexName: 'test_Bestbuy_vr_price_asc',
})
)
.add('default', () => ({
template: '<ais-relevant-sort></ais-relevant-sort>',
}))
.add('with custom text', () => ({
template: `
<ais-relevant-sort>
<template slot="text" slot-scope="{ isRelevantSorted }">
{{ isRelevantSorted
? 'We removed some search results to show you the most relevant ones'
: 'Currently showing all results' }}
</template>
</ais-relevant-sort>
`,
}));
18 changes: 9 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1156,10 +1156,10 @@ algoliasearch-helper@^3.1.0:
dependencies:
events "^1.1.1"

algoliasearch-helper@^3.3.4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.3.4.tgz#4a3c56d42a2a81589d5722b73653b2deaf3e7064"
integrity sha512-1Ts2XcgGdjGlDrp3v6zbY8VW+X9+jJ5rBmtPBmXOQLd4b5t/LpJlaBdxoAnlMfVFjywP7KSAdmyFUNNYVHDyRQ==
algoliasearch-helper@^3.4.4:
version "3.4.4"
resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.4.4.tgz#f2eb46bc4d2f6fed82c7201b8ac4ce0a1988ae67"
integrity sha512-OjyVLjykaYKCMxxRMZNiwLp8CS310E0qAeIY2NaublcmLAh8/SL19+zYHp7XCLtMem2ZXwl3ywMiA32O9jszuw==
dependencies:
events "^1.1.1"

Expand Down Expand Up @@ -7892,13 +7892,13 @@ instantsearch.css@7.3.1:
resolved "https://registry.yarnpkg.com/instantsearch.css/-/instantsearch.css-7.3.1.tgz#7ab74a8f355091ae040947a9cf5438f379026622"
integrity sha512-/kaMDna5D+Q9mImNBHEhb9HgHATDOFKYii7N1Iwvrj+lmD9gBJLqVhUw67gftq2O0QI330pFza+CRscIwB1wQQ==

instantsearch.js@^4.11.0:
version "4.11.0"
resolved "https://registry.yarnpkg.com/instantsearch.js/-/instantsearch.js-4.11.0.tgz#9e55426fbcf1929df9a772c53eeae282575e1a13"
integrity sha512-SVdS63S7skry5ebttPOq9D/BB2H61lYL2qdRiGdeuxsbrkwNssvpmtt/kAKxrnySUNxiSI2ZKTH2wa2WaMU98A==
instantsearch.js@^4.16.1:
version "4.16.1"
resolved "https://registry.yarnpkg.com/instantsearch.js/-/instantsearch.js-4.16.1.tgz#78e00d2256c89693a94f58ebfc5f0864953b7ec8"
integrity sha512-NfwNOb+Ftj7Y+h6lW7iCd5SXWKIHQZ981ldSddEHbgTexbdJEyxgWhaF8c3HajCySp8wZPD2gj9KpNQy/BsUgQ==
dependencies:
"@types/googlemaps" "^3.39.6"
algoliasearch-helper "^3.3.4"
algoliasearch-helper "^3.4.4"
classnames "^2.2.5"
events "^1.1.0"
hogan.js "^3.0.2"
Expand Down

0 comments on commit 4fe5745

Please sign in to comment.