From 05ceba1bdb5e4c34196509c7d05fc5c311a53f02 Mon Sep 17 00:00:00 2001 From: Suren Date: Thu, 14 Nov 2024 11:44:47 +0530 Subject: [PATCH] Update autocomplete --- .../components/Autocomplete/Autocomplete.jsx | 6 ++- .../SelectInfiniteScroll.jsx | 49 ++++++++++++++----- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/geonode_mapstore_client/client/js/components/Autocomplete/Autocomplete.jsx b/geonode_mapstore_client/client/js/components/Autocomplete/Autocomplete.jsx index 09ac71b8ed..5b17b83f31 100644 --- a/geonode_mapstore_client/client/js/components/Autocomplete/Autocomplete.jsx +++ b/geonode_mapstore_client/client/js/components/Autocomplete/Autocomplete.jsx @@ -47,9 +47,11 @@ const Autocomplete = ({ {...props} id={id} value={getValue()} + valueKey={valueKey} + labelKey={labelKey} {...props.creatable && { - newOptionCreator: props.newOptionCreator ?? defaultNewOptionCreator} - } + newOptionCreator: props.newOptionCreator ?? defaultNewOptionCreator + }} /> ); diff --git a/geonode_mapstore_client/client/js/components/SelectInfiniteScroll/SelectInfiniteScroll.jsx b/geonode_mapstore_client/client/js/components/SelectInfiniteScroll/SelectInfiniteScroll.jsx index 8a4068669a..cd1c251755 100644 --- a/geonode_mapstore_client/client/js/components/SelectInfiniteScroll/SelectInfiniteScroll.jsx +++ b/geonode_mapstore_client/client/js/components/SelectInfiniteScroll/SelectInfiniteScroll.jsx @@ -9,16 +9,19 @@ import React, { useRef, useState, useEffect } from 'react'; import axios from '@mapstore/framework/libs/ajax'; import debounce from 'lodash/debounce'; -import Select from 'react-select'; +import isEmpty from 'lodash/isEmpty'; +import ReactSelect from 'react-select'; import localizedProps from '@mapstore/framework/components/misc/enhancers/localizedProps'; -const ReactSelect = localizedProps(['placeholder'])(Select); -const ReactSelectCreatable = localizedProps(['placeholder'])(Select.Creatable); +const SelectSync = localizedProps('placeholder')(ReactSelect); function SelectInfiniteScroll({ loadOptions, pageSize = 20, debounceTime = 500, + labelKey, + valueKey, + newOptionPromptText = "Create option", ...props }) { @@ -41,6 +44,23 @@ function SelectInfiniteScroll({ source.current = cancelToken.source(); }; + const updateNewOption = (newOptions, query) => { + if (props.creatable && !isEmpty(query)) { + const isValueExist = props.value?.some(v => v[labelKey] === query); + const isOptionExist = newOptions.some((o) => o[labelKey] === query); + + // Add new option if it doesn't exist and `creatable` is enabled + if (!isValueExist && !isOptionExist) { + return [{ + [labelKey]: `${newOptionPromptText} "${query}"`, value: query, + result: { [valueKey]: query, [labelKey]: query } + }].concat(newOptions); + } + return newOptions; + } + return newOptions; + }; + const handleUpdateOptions = useRef(); handleUpdateOptions.current = (args = {}) => { createToken(); @@ -57,8 +77,10 @@ function SelectInfiniteScroll({ } }) .then((response) => { - const newOptions = response.results.map(({ selectOption }) => selectOption); - setOptions(newPage === 1 ? newOptions : [...options, ...newOptions]); + let newOptions = response.results.map(({ selectOption }) => selectOption); + newOptions = newPage === 1 ? newOptions : [...options, ...newOptions]; + newOptions = updateNewOption(newOptions, query); + setOptions(newOptions); setIsNextPageAvailable(response.isNextPageAvailable); setLoading(false); source.current = undefined; @@ -90,7 +112,7 @@ function SelectInfiniteScroll({ handleUpdateOptions.current({ q: value, page: 1 }); } }, debounceTime); - }, []); + }, [text]); useEffect(() => { if (open) { @@ -107,24 +129,27 @@ function SelectInfiniteScroll({ } }, [page]); - const SelectComponent = props.creatable ? ReactSelectCreatable : ReactSelect; + const filterOptions = (currentOptions) => { + return currentOptions.map(option=> { + const match = /\"(.*?)\"/.exec(text); + return match ? match[1] : option; + }); + }; return ( - setOpen(true)} onClose={() => setOpen(false)} + filterOptions={filterOptions} + onInputChange={(q) => handleInputChange(q)} onMenuScrollToBottom={() => { if (!loading && isNextPageAvailable) { setPage(page + 1); } }} - {...!props.creatable && ({ - filterOptions: (currentOptions) => currentOptions, - onInputChange: handleInputChange - })} /> ); }