From 8a2f079acb0dc920f408f9b2efef154649ded911 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Wed, 7 Oct 2020 17:44:04 +0200 Subject: [PATCH] Implement ComboAdresseSearch --- app/assets/stylesheets/new_design/carte.scss | 4 + .../components/ComboAdresseSearch.js | 44 ++++++++++ .../components/MapEditor/SearchInput.js | 88 ------------------- app/javascript/components/MapEditor/index.js | 10 ++- app/javascript/loaders/ComboAdresseSearch.js | 3 + .../editable_champs/_address.html.haml | 7 +- 6 files changed, 60 insertions(+), 96 deletions(-) create mode 100644 app/javascript/components/ComboAdresseSearch.js delete mode 100644 app/javascript/components/MapEditor/SearchInput.js create mode 100644 app/javascript/loaders/ComboAdresseSearch.js diff --git a/app/assets/stylesheets/new_design/carte.scss b/app/assets/stylesheets/new_design/carte.scss index b23ec84e6..8728a4915 100644 --- a/app/assets/stylesheets/new_design/carte.scss +++ b/app/assets/stylesheets/new_design/carte.scss @@ -11,3 +11,7 @@ margin-top: 5px; } } + +.form [data-react-class='MapEditor'] [data-reach-combobox-input] { + margin-bottom: 0; +} diff --git a/app/javascript/components/ComboAdresseSearch.js b/app/javascript/components/ComboAdresseSearch.js new file mode 100644 index 000000000..a73ba8bf0 --- /dev/null +++ b/app/javascript/components/ComboAdresseSearch.js @@ -0,0 +1,44 @@ +import React, { useCallback } from 'react'; +import { ReactQueryCacheProvider } from 'react-query'; +import PropTypes from 'prop-types'; + +import ComboSearch from './ComboSearch'; +import { queryCache } from './shared/queryCache'; + +function ComboAdresseSearch({ + mandatory, + placeholder, + hiddenFieldId, + onChange, + transformResult = ({ properties: { label } }) => [label, label], + allowInputValues = true +}) { + const transformResults = useCallback((_, { features }) => features); + + return ( + + + + ); +} + +ComboAdresseSearch.propTypes = { + placeholder: PropTypes.string, + mandatory: PropTypes.bool, + hiddenFieldId: PropTypes.string, + transformResult: PropTypes.func, + allowInputValues: PropTypes.bool, + onChange: PropTypes.func +}; + +export default ComboAdresseSearch; diff --git a/app/javascript/components/MapEditor/SearchInput.js b/app/javascript/components/MapEditor/SearchInput.js deleted file mode 100644 index ae82126af..000000000 --- a/app/javascript/components/MapEditor/SearchInput.js +++ /dev/null @@ -1,88 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { getJSON } from '@utils'; -import { - Combobox, - ComboboxInput, - ComboboxPopover, - ComboboxList, - ComboboxOption -} from '@reach/combobox'; -import '@reach/combobox/styles.css'; -import PropTypes from 'prop-types'; - -let cache = {}; -const useAddressSearch = (searchTerm) => { - const [addresses, setAddresses] = useState([]); - useEffect(() => { - if (searchTerm.trim() !== '') { - let isFresh = true; - fetchAddresses(searchTerm).then((addresses) => { - if (isFresh) setAddresses(addresses); - }); - return () => (isFresh = false); - } - }, [searchTerm]); - return addresses; -}; - -const fetchAddresses = (value) => { - if (cache[value]) { - return Promise.resolve(cache[value]); - } - const url = `https://api-adresse.data.gouv.fr/search/`; - return getJSON(url, { q: value, limit: 5 }, 'get').then((result) => { - if (result) { - cache[value] = result; - } - return result; - }); -}; - -const SearchInput = ({ getCoords }) => { - const [searchTerm, setSearchTerm] = useState(''); - const addresses = useAddressSearch(searchTerm); - const handleSearchTermChange = (event) => { - setSearchTerm(event.target.value); - }; - return ( - - - {addresses.features && ( - - {addresses.features.length > 0 ? ( - - {addresses.features.map((feature) => { - const str = `${feature.properties.name}, ${feature.properties.city}`; - return ( - getCoords(feature.geometry.coordinates)} - key={str} - value={str} - /> - ); - })} - - ) : ( - Aucun résultat - )} - - )} - - ); -}; - -SearchInput.propTypes = { - getCoords: PropTypes.func -}; - -export default SearchInput; diff --git a/app/javascript/components/MapEditor/index.js b/app/javascript/components/MapEditor/index.js index d3ab35a1c..4c6246a2f 100644 --- a/app/javascript/components/MapEditor/index.js +++ b/app/javascript/components/MapEditor/index.js @@ -9,7 +9,7 @@ import { getJSON, ajax, fire } from '@utils'; import { getMapStyle, SwitchMapStyle } from '../MapStyles'; -import SearchInput from './SearchInput'; +import ComboAdresseSearch from '../ComboAdresseSearch'; import { polygonCadastresFill, polygonCadastresLine, @@ -279,9 +279,11 @@ function MapEditor({ featureCollection, url, preview, options }) { marginBottom: '50px' }} > - { - setCoords(searchTerm); + { + setCoords(coordinates); setZoom([17]); }} /> diff --git a/app/javascript/loaders/ComboAdresseSearch.js b/app/javascript/loaders/ComboAdresseSearch.js new file mode 100644 index 000000000..d37c73f31 --- /dev/null +++ b/app/javascript/loaders/ComboAdresseSearch.js @@ -0,0 +1,3 @@ +import Loadable from '../components/Loadable'; + +export default Loadable(() => import('../components/ComboAdresseSearch')); diff --git a/app/views/shared/dossiers/editable_champs/_address.html.haml b/app/views/shared/dossiers/editable_champs/_address.html.haml index 95025fc33..4cc7f62a1 100644 --- a/app/views/shared/dossiers/editable_champs/_address.html.haml +++ b/app/views/shared/dossiers/editable_champs/_address.html.haml @@ -1,4 +1,3 @@ -= form.select :value, [champ.value].compact, - { include_blank: true }, - required: champ.mandatory?, - class: 'select2 adresse' +- hidden_field_id = SecureRandom.uuid += form.hidden_field :value, { data: { uuid: hidden_field_id } } += react_component("ComboAdresseSearch", mandatory: champ.mandatory?, hiddenFieldId: hidden_field_id)