chore(champ): remove unused react code
This commit is contained in:
parent
bb70e74659
commit
9d26a38997
3 changed files with 6 additions and 221 deletions
|
@ -1,124 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { QueryClientProvider } from 'react-query';
|
|
||||||
import { matchSorter } from 'match-sorter';
|
|
||||||
|
|
||||||
import ComboSearch, { ComboSearchProps } from './ComboSearch';
|
|
||||||
import { queryClient } from './shared/queryClient';
|
|
||||||
import { ComboDepartementsSearch } from './ComboDepartementsSearch';
|
|
||||||
import { useHiddenField, groupId } from './shared/hooks';
|
|
||||||
|
|
||||||
type CommuneResult = { code: string; nom: string; codesPostaux: string[] };
|
|
||||||
|
|
||||||
// Avoid hiding similar matches for precise queries (like "Sainte Marie")
|
|
||||||
function searchResultsLimit(term: string) {
|
|
||||||
return term.length > 5 ? 10 : 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
function expandResultsWithMultiplePostalCodes(term: string, result: unknown) {
|
|
||||||
const results = result as CommuneResult[];
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
const placeholderDepartements = [
|
|
||||||
['63 – Puy-de-Dôme', 'Clermont-Ferrand'],
|
|
||||||
['77 – Seine-et-Marne', 'Melun'],
|
|
||||||
['22 – Côtes d’Armor', 'Saint-Brieuc'],
|
|
||||||
['47 – Lot-et-Garonne', 'Agen']
|
|
||||||
] as const;
|
|
||||||
const [placeholderDepartement, placeholderCommune] =
|
|
||||||
placeholderDepartements[
|
|
||||||
Math.floor(Math.random() * (placeholderDepartements.length - 1))
|
|
||||||
];
|
|
||||||
|
|
||||||
export default function ComboCommunesSearch({
|
|
||||||
id,
|
|
||||||
classNameDepartement,
|
|
||||||
...props
|
|
||||||
}: ComboSearchProps<CommuneResult> & {
|
|
||||||
id: string;
|
|
||||||
classNameDepartement?: string;
|
|
||||||
}) {
|
|
||||||
const group = groupId(id);
|
|
||||||
const [departementValue, setDepartementValue] = useHiddenField(
|
|
||||||
group,
|
|
||||||
'departement'
|
|
||||||
);
|
|
||||||
const [codeDepartement, setCodeDepartement] = useHiddenField(
|
|
||||||
group,
|
|
||||||
'code_departement'
|
|
||||||
);
|
|
||||||
const departementDescribedBy = `${id}_departement_notice`;
|
|
||||||
const communeDescribedBy = `${id}_commune_notice`;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<QueryClientProvider client={queryClient}>
|
|
||||||
<div>
|
|
||||||
<div className="notice" id={departementDescribedBy}>
|
|
||||||
<p>
|
|
||||||
Choisissez le département dans lequel se situe la commune. Vous
|
|
||||||
pouvez entrer le nom ou le code.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<ComboDepartementsSearch
|
|
||||||
{...props}
|
|
||||||
id={!codeDepartement ? id : undefined}
|
|
||||||
describedby={departementDescribedBy}
|
|
||||||
placeholder={placeholderDepartement}
|
|
||||||
addForeignDepartement={false}
|
|
||||||
value={departementValue}
|
|
||||||
className={classNameDepartement}
|
|
||||||
onChange={(_, result) => {
|
|
||||||
setDepartementValue(result?.nom ?? '');
|
|
||||||
setCodeDepartement(result?.code ?? '');
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{codeDepartement ? (
|
|
||||||
<div>
|
|
||||||
<div className="notice" id={communeDescribedBy}>
|
|
||||||
<p>
|
|
||||||
Choisissez la commune. Vous pouvez entrer le nom ou le code
|
|
||||||
postal.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<ComboSearch
|
|
||||||
{...props}
|
|
||||||
id={id}
|
|
||||||
describedby={communeDescribedBy}
|
|
||||||
placeholder={placeholderCommune}
|
|
||||||
scope="communes"
|
|
||||||
scopeExtra={codeDepartement}
|
|
||||||
minimumInputLength={2}
|
|
||||||
transformResult={({ code, nom, codesPostaux }) => [
|
|
||||||
code,
|
|
||||||
`${nom} (${codesPostaux[0]})`
|
|
||||||
]}
|
|
||||||
transformResults={expandResultsWithMultiplePostalCodes}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</QueryClientProvider>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { matchSorter } from 'match-sorter';
|
|
||||||
|
|
||||||
import ComboSearch, { ComboSearchProps } from './ComboSearch';
|
|
||||||
|
|
||||||
type DepartementResult = { code: string; nom: string };
|
|
||||||
|
|
||||||
const extraTerms = [{ code: '99', nom: 'Etranger' }];
|
|
||||||
|
|
||||||
function expandResultsWithForeignDepartement(term: string, result: unknown) {
|
|
||||||
const results = result as DepartementResult[];
|
|
||||||
return [
|
|
||||||
...results,
|
|
||||||
...matchSorter(extraTerms, term, {
|
|
||||||
keys: ['nom', 'code']
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
type ComboDepartementsSearchProps = Omit<
|
|
||||||
ComboSearchProps<DepartementResult> & {
|
|
||||||
addForeignDepartement: boolean;
|
|
||||||
},
|
|
||||||
'transformResult' | 'transformResults'
|
|
||||||
>;
|
|
||||||
|
|
||||||
export function ComboDepartementsSearch({
|
|
||||||
addForeignDepartement = true,
|
|
||||||
...props
|
|
||||||
}: ComboDepartementsSearchProps) {
|
|
||||||
return (
|
|
||||||
<ComboSearch
|
|
||||||
{...props}
|
|
||||||
scope="departements"
|
|
||||||
minimumInputLength={1}
|
|
||||||
transformResult={({ code, nom }) => [code, `${code} - ${nom}`]}
|
|
||||||
transformResults={
|
|
||||||
addForeignDepartement ? expandResultsWithForeignDepartement : undefined
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,22 +1,11 @@
|
||||||
import { QueryClient, QueryFunction } from 'react-query';
|
import { QueryClient, QueryFunction } from 'react-query';
|
||||||
import { httpRequest, isNumeric, getConfig } from '@utils';
|
import { httpRequest, getConfig } from '@utils';
|
||||||
import { matchSorter } from 'match-sorter';
|
|
||||||
|
|
||||||
const API_EDUCATION_QUERY_LIMIT = 5;
|
const API_EDUCATION_QUERY_LIMIT = 5;
|
||||||
const API_GEO_QUERY_LIMIT = 5;
|
|
||||||
const API_ADRESSE_QUERY_LIMIT = 5;
|
const API_ADRESSE_QUERY_LIMIT = 5;
|
||||||
|
|
||||||
// When searching for short strings like "mer", le exact match shows up quite far in
|
|
||||||
// the ordering (~50).
|
|
||||||
//
|
|
||||||
// That's why we deliberately fetch a lot of results, and then let the local matching
|
|
||||||
// (match-sorter) do the work.
|
|
||||||
//
|
|
||||||
// NB: 60 is arbitrary, we may add more if needed.
|
|
||||||
const API_GEO_COMMUNES_QUERY_LIMIT = 60;
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
autocomplete: { api_geo_url, api_adresse_url, api_education_url }
|
autocomplete: { api_adresse_url, api_education_url }
|
||||||
} = getConfig();
|
} = getConfig();
|
||||||
|
|
||||||
type QueryKey = readonly [
|
type QueryKey = readonly [
|
||||||
|
@ -25,10 +14,10 @@ type QueryKey = readonly [
|
||||||
extra: string | undefined
|
extra: string | undefined
|
||||||
];
|
];
|
||||||
|
|
||||||
function buildURL(scope: string, term: string, extra?: string) {
|
function buildURL(scope: string, term: string) {
|
||||||
term = term.replace(/\(|\)/g, '');
|
term = term.replace(/\(|\)/g, '');
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
let path = `${api_geo_url}/${scope}`;
|
let path = '';
|
||||||
|
|
||||||
if (scope == 'adresse') {
|
if (scope == 'adresse') {
|
||||||
path = `${api_adresse_url}/search`;
|
path = `${api_adresse_url}/search`;
|
||||||
|
@ -39,40 +28,15 @@ function buildURL(scope: string, term: string, extra?: string) {
|
||||||
params.set('q', term);
|
params.set('q', term);
|
||||||
params.set('rows', `${API_EDUCATION_QUERY_LIMIT}`);
|
params.set('rows', `${API_EDUCATION_QUERY_LIMIT}`);
|
||||||
params.set('dataset', 'fr-en-annuaire-education');
|
params.set('dataset', 'fr-en-annuaire-education');
|
||||||
} else if (scope == 'communes') {
|
|
||||||
if (extra) {
|
|
||||||
params.set('codeDepartement', extra);
|
|
||||||
}
|
|
||||||
if (isNumeric(term)) {
|
|
||||||
params.set('codePostal', term);
|
|
||||||
} else {
|
|
||||||
params.set('nom', term);
|
|
||||||
params.set('boost', 'population');
|
|
||||||
}
|
|
||||||
params.set('limit', `${API_GEO_COMMUNES_QUERY_LIMIT}`);
|
|
||||||
} else {
|
|
||||||
if (isNumeric(term)) {
|
|
||||||
params.set('code', term.padStart(2, '0'));
|
|
||||||
} else {
|
|
||||||
params.set('nom', term);
|
|
||||||
}
|
|
||||||
if (scope == 'departements') {
|
|
||||||
params.set('zone', 'metro,drom,com');
|
|
||||||
}
|
|
||||||
params.set('limit', `${API_GEO_QUERY_LIMIT}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${path}?${params}`;
|
return `${path}?${params}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultQueryFn: QueryFunction<unknown, QueryKey> = async ({
|
const defaultQueryFn: QueryFunction<unknown, QueryKey> = async ({
|
||||||
queryKey: [scope, term, extra],
|
queryKey: [scope, term],
|
||||||
signal
|
signal
|
||||||
}) => {
|
}) => {
|
||||||
if (scope == 'pays') {
|
|
||||||
return matchSorter(await getPays(signal), term, { keys: ['label'] });
|
|
||||||
}
|
|
||||||
|
|
||||||
// BAN will error with queries less then 3 chars long
|
// BAN will error with queries less then 3 chars long
|
||||||
if (scope == 'adresse' && term.length < 3) {
|
if (scope == 'adresse' && term.length < 3) {
|
||||||
return {
|
return {
|
||||||
|
@ -83,23 +47,10 @@ const defaultQueryFn: QueryFunction<unknown, QueryKey> = async ({
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = buildURL(scope, term, extra);
|
const url = buildURL(scope, term);
|
||||||
return httpRequest(url, { csrf: false, signal }).json();
|
return httpRequest(url, { csrf: false, signal }).json();
|
||||||
};
|
};
|
||||||
|
|
||||||
let paysCache: { label: string }[];
|
|
||||||
async function getPays(signal?: AbortSignal): Promise<{ label: string }[]> {
|
|
||||||
if (!paysCache) {
|
|
||||||
const data = await httpRequest('/api/pays', { signal }).json<
|
|
||||||
typeof paysCache
|
|
||||||
>();
|
|
||||||
if (data) {
|
|
||||||
paysCache = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return paysCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const queryClient = new QueryClient({
|
export const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
queries: {
|
queries: {
|
||||||
|
|
Loading…
Reference in a new issue