Skip to content

Commit 42c329b

Browse files
committed
Fix placeholdersearch on filters and pagination
Add comments on pagination disable
1 parent bc73484 commit 42c329b

File tree

5 files changed

+145
-33
lines changed

5 files changed

+145
-33
lines changed

src/adapter/search-request-adapter/__tests__/search-params.tests.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const DEFAULT_CONTEXT = {
55
indexUid: 'test',
66
pagination: { page: 0, hitsPerPage: 6, finite: false },
77
defaultFacetDistribution: {},
8+
placeholderSearch: true,
9+
keepZeroFacets: false,
810
}
911

1012
describe('Parameters adapter', () => {
@@ -155,6 +157,31 @@ describe('Pagination adapter', () => {
155157
expect(searchParams.hitsPerPage).toBe(0)
156158
})
157159

160+
test('adapting a finite pagination with no placeholderSearch and a query', () => {
161+
const searchParams = adaptSearchParams({
162+
...DEFAULT_CONTEXT,
163+
query: 'a',
164+
pagination: { page: 4, hitsPerPage: 6, finite: true },
165+
placeholderSearch: false,
166+
})
167+
168+
expect(searchParams.page).toBe(5)
169+
expect(searchParams.hitsPerPage).toBeGreaterThan(0)
170+
})
171+
172+
test('adapting a finite pagination with no placeholderSearch and a facetFilter', () => {
173+
const searchParams = adaptSearchParams({
174+
...DEFAULT_CONTEXT,
175+
query: '',
176+
pagination: { page: 4, hitsPerPage: 6, finite: true },
177+
placeholderSearch: false,
178+
facetFilters: ['genres:Action'],
179+
})
180+
181+
expect(searchParams.page).toBe(5)
182+
expect(searchParams.hitsPerPage).toBeGreaterThan(0)
183+
})
184+
158185
test('adapting a scroll pagination with no placeholderSearch', () => {
159186
const searchParams = adaptSearchParams({
160187
...DEFAULT_CONTEXT,
@@ -166,4 +193,29 @@ describe('Pagination adapter', () => {
166193
expect(searchParams.limit).toBe(0)
167194
expect(searchParams.offset).toBe(0)
168195
})
196+
197+
test('adapting a scroll pagination with no placeholderSearch and a query', () => {
198+
const searchParams = adaptSearchParams({
199+
...DEFAULT_CONTEXT,
200+
query: 'a',
201+
pagination: { page: 4, hitsPerPage: 6, finite: false },
202+
placeholderSearch: false,
203+
})
204+
205+
expect(searchParams.limit).toBeGreaterThan(0)
206+
expect(searchParams.offset).toBeGreaterThan(0)
207+
})
208+
209+
test('adapting a scroll pagination with no placeholderSearch and a facetFilter', () => {
210+
const searchParams = adaptSearchParams({
211+
...DEFAULT_CONTEXT,
212+
query: 'a',
213+
pagination: { page: 4, hitsPerPage: 6, finite: false },
214+
placeholderSearch: false,
215+
facetFilters: ['genres:Action'],
216+
})
217+
218+
expect(searchParams.limit).toBeGreaterThan(0)
219+
expect(searchParams.offset).toBeGreaterThan(0)
220+
})
169221
})

src/adapter/search-request-adapter/search-params-adapter.ts

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,38 @@
1-
import type { MeiliSearchParams, SearchContext } from '../../types'
1+
import type {
2+
MeiliSearchParams,
3+
SearchContext,
4+
Filter,
5+
PaginationState,
6+
} from '../../types'
27

38
import {
49
adaptGeoPointsRules,
510
createGeoSearchContext,
611
} from './geo-rules-adapter'
712
import { adaptFilters } from './filter-adapter'
813

9-
function setScrollPagination(
10-
hitsPerPage: number,
11-
page: number,
14+
function isPaginationRequired(
15+
filter: Filter,
1216
query?: string,
1317
placeholderSearch?: boolean
18+
): boolean {
19+
// To disable pagination:
20+
// placeholderSearch must be disabled
21+
// The search query must be empty
22+
// There must be no filters
23+
if (!placeholderSearch && !query && (!filter || filter.length === 0)) {
24+
return false
25+
}
26+
return true
27+
}
28+
29+
function setScrollPagination(
30+
pagination: PaginationState,
31+
paginationRequired: boolean
1432
): { limit: number; offset: number } {
15-
if (!placeholderSearch && query === '') {
33+
const { page, hitsPerPage } = pagination
34+
35+
if (!paginationRequired) {
1636
return {
1737
limit: 0,
1838
offset: 0,
@@ -26,12 +46,12 @@ function setScrollPagination(
2646
}
2747

2848
function setFinitePagination(
29-
hitsPerPage: number,
30-
page: number,
31-
query?: string,
32-
placeholderSearch?: boolean
49+
pagination: PaginationState,
50+
paginationRequired: boolean
3351
): { hitsPerPage: number; page: number } {
34-
if (!placeholderSearch && query === '') {
52+
const { page, hitsPerPage } = pagination
53+
54+
if (!paginationRequired) {
3555
return {
3656
hitsPerPage: 0,
3757
page: page + 1,
@@ -58,9 +78,6 @@ export function MeiliParamsCreator(searchContext: SearchContext) {
5878
attributesToSnippet,
5979
snippetEllipsisText,
6080
attributesToRetrieve,
61-
filters,
62-
numericFilters,
63-
facetFilters,
6481
attributesToHighlight,
6582
highlightPreTag,
6683
highlightPostTag,
@@ -69,8 +86,13 @@ export function MeiliParamsCreator(searchContext: SearchContext) {
6986
sort,
7087
pagination,
7188
matchingStrategy,
89+
filters,
90+
numericFilters,
91+
facetFilters,
7292
} = searchContext
7393

94+
const meilisearchFilters = adaptFilters(filters, numericFilters, facetFilters)
95+
7496
return {
7597
getParams() {
7698
return meiliSearchParams
@@ -99,9 +121,8 @@ export function MeiliParamsCreator(searchContext: SearchContext) {
99121
}
100122
},
101123
addFilters() {
102-
const filter = adaptFilters(filters, numericFilters, facetFilters)
103-
if (filter.length) {
104-
meiliSearchParams.filter = filter
124+
if (meilisearchFilters.length) {
125+
meiliSearchParams.filter = meilisearchFilters
105126
}
106127
},
107128
addAttributesToHighlight() {
@@ -122,21 +143,22 @@ export function MeiliParamsCreator(searchContext: SearchContext) {
122143
}
123144
},
124145
addPagination() {
146+
const paginationRequired = isPaginationRequired(
147+
meilisearchFilters,
148+
query,
149+
placeholderSearch
150+
)
125151
if (pagination.finite) {
126152
const { hitsPerPage, page } = setFinitePagination(
127-
pagination.hitsPerPage,
128-
pagination.page,
129-
query,
130-
placeholderSearch
153+
pagination,
154+
paginationRequired
131155
)
132156
meiliSearchParams.hitsPerPage = hitsPerPage
133157
meiliSearchParams.page = page
134158
} else {
135159
const { limit, offset } = setScrollPagination(
136-
pagination.hitsPerPage,
137-
pagination.page,
138-
query,
139-
placeholderSearch
160+
pagination,
161+
paginationRequired
140162
)
141163
meiliSearchParams.limit = limit
142164
meiliSearchParams.offset = offset

src/adapter/search-request-adapter/search-resolver.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ export function SearchResolver(
2525
searchContext: SearchContext,
2626
searchParams: MeiliSearchParams
2727
): Promise<MeiliSearchResponse<Record<string, any>>> {
28-
const { placeholderSearch, query } = searchContext
29-
3028
// Create cache key containing a unique set of search parameters
3129
const key = cache.formatKey([
3230
searchParams,
@@ -54,13 +52,9 @@ export function SearchResolver(
5452
)
5553
}
5654

57-
// query can be: empty string, undefined or null
58-
// all of them are falsy's
59-
if (!placeholderSearch && !query) {
60-
searchResponse.hits = []
61-
}
6255
// Cache response
6356
cache.setEntry<MeiliSearchResponse>(key, searchResponse)
57+
6458
return searchResponse
6559
},
6660
}

src/types/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ export type SearchContext = Omit<InstantSearchParams, 'insideBoundingBox'> &
7878
defaultFacetDistribution: FacetDistribution
7979
pagination: PaginationState
8080
indexUid: string
81+
placeholderSearch: boolean
82+
keepZeroFacets: boolean
8183
insideBoundingBox?: InsideBoundingBox
82-
keepZeroFacets?: boolean
8384
cropMarker?: string
8485
sort?: string
85-
placeholderSearch?: boolean
8686
primaryKey?: string
8787
matchingStrategy?: MatchingStrategies
8888
}

tests/placeholder-search.tests.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,48 @@ describe('Pagination browser test', () => {
5151
const hits = response.results[0].hits
5252
expect(hits.length).toBe(0)
5353
})
54+
55+
test('placeholdersearch with query', async () => {
56+
const customClient = instantMeiliSearch(
57+
'http://localhost:7700',
58+
'masterKey',
59+
{
60+
placeholderSearch: false,
61+
}
62+
)
63+
64+
const response = await customClient.search<Movies>([
65+
{
66+
indexName: 'movies',
67+
params: {
68+
query: 'a',
69+
},
70+
},
71+
])
72+
73+
const hits = response.results[0].hits
74+
expect(hits.length).toBeGreaterThan(0)
75+
})
76+
77+
test('placeholdersearch set to false with filter', async () => {
78+
const customClient = instantMeiliSearch(
79+
'http://localhost:7700',
80+
'masterKey',
81+
{
82+
placeholderSearch: false,
83+
}
84+
)
85+
86+
const response = await customClient.search<Movies>([
87+
{
88+
indexName: 'movies',
89+
params: {
90+
facetFilters: ['genres:Action'],
91+
},
92+
},
93+
])
94+
95+
const hits = response.results[0].hits
96+
expect(hits.length).toBeGreaterThan(0)
97+
})
5498
})

0 commit comments

Comments
 (0)