demarches-normaliennes/app/javascript/components/ComboCommunesSearch.jsx

58 lines
1.8 KiB
React
Raw Normal View History

2020-10-07 17:42:41 +02:00
import React from 'react';
2021-02-16 13:54:16 +01:00
import { QueryClientProvider } from 'react-query';
import { matchSorter } from 'match-sorter';
2020-10-07 17:42:41 +02:00
import ComboSearch from './ComboSearch';
import { queryClient } from './shared/queryClient';
// Avoid hiding similar matches for precise queries (like "Sainte Marie")
function searchResultsLimit(term) {
return term.length > 5 ? 10 : 5;
}
2020-10-07 17:42:41 +02:00
function expandResultsWithMultiplePostalCodes(term, results) {
// A single result may have several associated postal codes.
// To make the search results more precise, we want to generate
// an actual result for each postal code.
const expandedResults = results.flatMap((result) =>
result.codesPostaux.map((codePostal) => ({
...result,
codesPostaux: [codePostal]
}))
);
// Some very large cities (like Paris) have A LOT of associated postal codes.
// As we generated one result per postal code, we now have a lot of results
// for the same city. If the number of results is above the threshold, we use
// local search to narrow the results.
const limit = searchResultsLimit(term);
if (expandedResults.length > limit) {
return matchSorter(expandedResults, term, {
keys: [(item) => `${item.nom} (${item.codesPostaux[0]})`, 'code'],
sorter: (rankedItems) => rankedItems
}).slice(0, limit + 1);
}
return expandedResults;
}
2020-10-07 17:42:41 +02:00
function ComboCommunesSearch(params) {
return (
2021-02-16 13:54:16 +01:00
<QueryClientProvider client={queryClient}>
2020-10-07 17:42:41 +02:00
<ComboSearch
required={params.mandatory}
hiddenFieldId={params.hiddenFieldId}
scope="communes"
minimumInputLength={2}
transformResult={({ code, nom, codesPostaux }) => [
code,
`${nom} (${codesPostaux[0]})`
]}
transformResults={expandResultsWithMultiplePostalCodes}
2020-10-07 17:42:41 +02:00
/>
2021-02-16 13:54:16 +01:00
</QueryClientProvider>
2020-10-07 17:42:41 +02:00
);
}
export default ComboCommunesSearch;