Skip to content

Commit

Permalink
Update autocomplete
Browse files Browse the repository at this point in the history
  • Loading branch information
dsuren1 committed Nov 14, 2024
1 parent bd357e3 commit 20a9015
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
}}
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}) {

Expand All @@ -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();
Expand All @@ -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;
Expand Down Expand Up @@ -90,7 +112,7 @@ function SelectInfiniteScroll({
handleUpdateOptions.current({ q: value, page: 1 });
}
}, debounceTime);
}, []);
}, [text]);

useEffect(() => {
if (open) {
Expand All @@ -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 (
<SelectComponent
<SelectSync
{...props}
isLoading={loading}
options={options}
onOpen={() => 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
})}
/>
);
}
Expand Down

0 comments on commit 20a9015

Please sign in to comment.