Skip to content

Commit 7e62f88

Browse files
bidoubiwagithub-actions[bot]meili-botmeili-bors[bot]
authored
Add compatibility with searchable in Refinemenlist widget (#1192)
* Prototype beta/prototype search for facet values (#1144) * Add prototype beta changeset * Add compatibility with searchable on facetRefinements * Add changeset for searchable parameter * Merge * Add a facet search context * Update changeset * Update pre mode * Update pre mode * Update pre mode * Version Packages (prototype-search-for-facet-values) (#1158) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Update README.md * Remove pre changeset mode --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: meili-bot <[email protected]> Co-authored-by: meili-bors[bot] <89034592+meili-bors[bot]@users.noreply.github.com> * Remove changelog * Rollback unexpected changes * Update meilisearch to latest rc * Fix cypress tests --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: meili-bot <[email protected]> Co-authored-by: meili-bors[bot] <89034592+meili-bors[bot]@users.noreply.github.com>
1 parent facd110 commit 7e62f88

File tree

11 files changed

+117
-24
lines changed

11 files changed

+117
-24
lines changed

.changeset/config.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
"@meilisearch/angular-playground",
1414
"@meilisearch/vue3-ts-playground",
1515
"@meilisearch/react-playground",
16-
"@meilisearch/local-react-playground"
16+
"@meilisearch/local-react-playground",
17+
"@meilisearch/node-playground",
18+
"@meilisearch/autocomplete-playground"
1719
]
1820
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@meilisearch/instant-meilisearch": patch
3+
---
4+
5+
Add compatibility with the `searchable` parameter of the [`RefinementList`](https://www.algolia.com/doc/api-reference/widgets/refinement-list/js/) widget

packages/instant-meilisearch/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -707,11 +707,11 @@ The `refinementList` widget is one of the most common widgets you can find in a
707707
- ✅ limit: How many facet values to retrieve.
708708
- ✅ showMore: Whether to display a button that expands the number of items.
709709
- ✅ showMoreLimit: The maximum number of displayed items. Does not work when showMoreLimit > limit.
710-
- searchable: Whether to add a search input to let the user search for more facet values. Not supported by Meilisearch. If you'd like to see it implemented [please vote](https://roadmap.meilisearch.com/c/64-search-for-facet-values?utm_medium=social&utm_source=portal_share).
711-
- searchablePlaceholder: The value of the search input’s placeholder. Not supported, see `searchable`.
712-
- searchableIsAlwaysActive: When false, disables the facet search input. Not supported, see `searchable`.
713-
- ❌ searchableEscapeFacetValues: When true, escapes the facet values. Not supported, see `searchable`.
714-
- ❌ sortBy: Not supported natively but can be implemented manually using `transformItems` options.
710+
- searchable: Whether to add a search input to let the user search for more facet values. Not supported by Meilisearch. If you'd like to see it implemented [please vote](https://roadmap.meilisearch.com/c/64-search-for-facet-values?utm_medium=social&utm_source=portal_share).
711+
- searchablePlaceholder: The value of the search input’s placeholder. Not supported, see `searchable`.
712+
- searchableIsAlwaysActive: When false, disables the facet search input. Not supported, see `searchable`.
713+
- ❌ searchableEscapeFacetValues: When true, escapes the facet values.
714+
- ❌ sortBy: Not supported but can be implemented manually using `transformItems` options.
715715
- ✅ transformItems: A function to transform the items passed to the templates.
716716
- ✅ templates: The templates to use for the widget.
717717
- ✅ cssClasses: The CSS classes to override.

packages/instant-meilisearch/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
"templates"
5151
],
5252
"dependencies": {
53-
"meilisearch": "^0.33.0"
53+
"meilisearch": "0.35.0-v1.3.0-pre-release.1"
5454
},
5555
"devDependencies": {
5656
"@babel/cli": "^7.21.0",

packages/instant-meilisearch/src/client/instant-meilisearch-client.ts

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
FacetDistribution,
99
PaginationState,
1010
MeilisearchConfig,
11+
AlgoliaSearchForFacetValuesRequests,
12+
AlgoliaSearchForFacetValuesResponse,
1113
} from '../types'
1214
import {
1315
getApiKey,
@@ -19,7 +21,7 @@ import {
1921
adaptSearchParams,
2022
SearchResolver,
2123
} from '../adapter'
22-
import { createSearchContext } from '../contexts'
24+
import { createSearchContext, createFacetSearchContext } from '../contexts'
2325
import {
2426
SearchCache,
2527
initFacetDistribution,
@@ -132,13 +134,48 @@ export function instantMeiliSearch(
132134
throw new Error(e)
133135
}
134136
},
135-
searchForFacetValues: async function (_: any) {
136-
return await new Promise((resolve, reject) => {
137-
reject(
138-
new Error('SearchForFacetValues is not compatible with Meilisearch')
137+
searchForFacetValues: async function (
138+
requests: AlgoliaSearchForFacetValuesRequests
139+
): Promise<AlgoliaSearchForFacetValuesResponse[]> {
140+
const results = []
141+
for (const request of requests) {
142+
const searchContext: SearchContext = createFacetSearchContext(
143+
request,
144+
instantMeiliSearchOptions
139145
)
140-
resolve([]) // added here to avoid compilation error
141-
})
146+
147+
const meilisearchSearchQuery = adaptSearchParams(searchContext)
148+
149+
const index = request.indexName
150+
151+
const meilisearchRequest: any = {
152+
...meilisearchSearchQuery,
153+
facetQuery: request.params.facetQuery,
154+
facetName: request.params.facetName,
155+
}
156+
157+
delete meilisearchRequest.indexUid
158+
159+
const meilisearchResponse = await meilisearchClient
160+
.index(index)
161+
.searchForFacetValues(meilisearchRequest)
162+
163+
const facetHits = meilisearchResponse.facetHits.map((facetHit) => ({
164+
...facetHit,
165+
// not currently supported
166+
highlighted: facetHit.value,
167+
}))
168+
169+
const result = {
170+
facetHits,
171+
exhaustiveFacetsCount: false,
172+
processingTimeMS: meilisearchResponse.processingTimeMs,
173+
}
174+
175+
results.push(result)
176+
}
177+
178+
return results
142179
},
143180
}
144181
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { createSearchContext } from './search-context'
1+
export { createSearchContext, createFacetSearchContext } from './search-context'

packages/instant-meilisearch/src/contexts/search-context.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
InstantMeiliSearchOptions,
33
AlgoliaMultipleQueriesQuery,
44
SearchContext,
5+
AlgoliaSearchForFacetValuesRequest,
56
} from '../types'
67
import { splitSortString } from './sort-context'
78
import { createPaginationState } from './pagination-context'
@@ -54,3 +55,36 @@ export function createSearchContext(
5455
}
5556
return searchContext
5657
}
58+
59+
/**
60+
* @param {AlgoliaMultipleQueriesQuery} searchRequest
61+
* @param {Context} options
62+
* @returns {SearchContext}
63+
*/
64+
export function createFacetSearchContext(
65+
searchRequest: AlgoliaSearchForFacetValuesRequest,
66+
options: InstantMeiliSearchOptions
67+
): SearchContext {
68+
// Split index name and possible sorting rules
69+
const [indexUid, ...sortByArray] = searchRequest.indexName.split(':')
70+
const { params: instantSearchParams } = searchRequest
71+
72+
const paginationState = createPaginationState(
73+
options.finitePagination,
74+
instantSearchParams?.hitsPerPage,
75+
instantSearchParams?.page
76+
)
77+
78+
const sortState = splitSortString(sortByArray.join(':'))
79+
80+
const searchContext: SearchContext = {
81+
...options,
82+
...instantSearchParams,
83+
sort: sortState,
84+
indexUid,
85+
pagination: paginationState,
86+
placeholderSearch: options.placeholderSearch !== false, // true by default
87+
keepZeroFacets: !!options.keepZeroFacets, // false by default
88+
}
89+
return searchContext
90+
}

packages/instant-meilisearch/src/types/types.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import type { SearchClient } from 'instantsearch.js'
2-
import type { MultipleQueriesQuery as AlgoliaMultipleQueriesQuery } from '@algolia/client-search'
2+
import type {
3+
MultipleQueriesQuery as AlgoliaMultipleQueriesQuery,
4+
multipleSearchForFacetValues,
5+
} from '@algolia/client-search'
36
import type {
47
MultiSearchQuery as MeiliSearchMultiSearchParams,
58
MultiSearchResult,
@@ -12,6 +15,13 @@ export type {
1215
SearchForFacetValuesResponse as AlgoliaSearchForFacetValuesResponse,
1316
} from '@algolia/client-search'
1417

18+
export type AlgoliaSearchForFacetValuesRequests = Parameters<
19+
ReturnType<typeof multipleSearchForFacetValues>
20+
>[0]
21+
22+
export type AlgoliaSearchForFacetValuesRequest =
23+
AlgoliaSearchForFacetValuesRequests[0]
24+
1525
export type {
1626
Filter,
1727
FacetDistribution,

playgrounds/local-react/cypress/integration/search-ui.spec.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ describe(`${playground} playground test`, () => {
3838

3939
it('Sort by recommendationCound ascending', () => {
4040
const select = `.ais-SortBy-select`
41-
cy.get(select).select('games:recommendationCount:asc')
41+
cy.get(select)
42+
.select('games:recommendationCount:asc')
43+
.should('have.value', 'games:recommendationCount:asc')
4244
cy.wait(1000)
4345
cy.get(HIT_ITEM_CLASS).eq(0).contains('Deathmatch Classic')
4446
})
@@ -61,7 +63,10 @@ describe(`${playground} playground test`, () => {
6163
})
6264

6365
it('Search', () => {
64-
cy.get('.ais-SearchBox-input').type('Half-Life')
66+
cy.get('.right-panel')
67+
.find('.ais-SearchBox-input')
68+
.type('Half-Life')
69+
.should('have.value', 'Half-Life')
6570
cy.wait(1000)
6671
cy.get(HIT_ITEM_CLASS).eq(0).contains('Half-Life')
6772
})

playgrounds/local-react/src/components/SingleIndex.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ const SingleIndex = () => (
5050
]}
5151
/>
5252
<h2>Genres</h2>
53-
<RefinementList attribute="genres" />
53+
<RefinementList attribute="genres" searchable={true} />
5454
<h2>Players</h2>
55-
<RefinementList attribute="players" />
55+
<RefinementList attribute="players" searchable={true} />
5656
<h2>Platforms</h2>
5757
<RefinementList attribute="platforms" />
5858
<h2>Misc</h2>

0 commit comments

Comments
 (0)