Skip to content
Snippets Groups Projects
Unverified Commit 7fbb26f2 authored by Matiss Janis Aboltins's avatar Matiss Janis Aboltins Committed by GitHub
Browse files

:bug: (autocomplete) allow editing selected payee name (#856)

parent 143ddeaa
No related branches found
No related tags found
No related merge requests found
import React, { useState } from 'react'; import React, { useState } from 'react';
import Select, { import Select from 'react-select';
import type {
GroupBase,
Props as SelectProps, Props as SelectProps,
PropsValue, PropsValue,
SingleValue, SingleValue,
SelectInstance, SelectInstance,
} from 'react-select'; } from 'react-select';
import type { CreatableProps } from 'react-select/creatable';
import CreatableSelect from 'react-select/creatable'; import CreatableSelect from 'react-select/creatable';
import { NullComponent } from '../common'; import { NullComponent } from '../common';
import styles from './autocomplete-styles'; import styles from './autocomplete-styles';
type OptionValue = string; type OptionValue = {
__isNew__?: boolean;
interface AutocompleteProps extends SelectProps<OptionValue> { label: string;
focused: boolean; value: string;
embedded: boolean; };
onSelect: (value: PropsValue<OptionValue>) => void;
onCreateOption: (value: SingleValue<OptionValue>) => void; interface BaseAutocompleteProps {
isCreatable: boolean; focused?: boolean;
embedded?: boolean;
onSelect: (value: string | string[]) => void;
onCreateOption?: (value: string) => void;
isCreatable?: boolean;
} }
type SimpleAutocompleteProps = BaseAutocompleteProps & SelectProps<OptionValue>;
type CreatableAutocompleteProps = BaseAutocompleteProps &
CreatableProps<OptionValue, true, GroupBase<OptionValue>> & {
isCreatable: true;
};
type AutocompleteProps = SimpleAutocompleteProps | CreatableAutocompleteProps;
const isSingleValue = (
value: PropsValue<OptionValue>,
): value is SingleValue<OptionValue> => {
return !Array.isArray(value);
};
const Autocomplete = React.forwardRef<SelectInstance, AutocompleteProps>( const Autocomplete = React.forwardRef<SelectInstance, AutocompleteProps>(
( (
{ {
...@@ -38,16 +59,32 @@ const Autocomplete = React.forwardRef<SelectInstance, AutocompleteProps>( ...@@ -38,16 +59,32 @@ const Autocomplete = React.forwardRef<SelectInstance, AutocompleteProps>(
ref, ref,
) => { ) => {
const [initialValue] = useState(value); const [initialValue] = useState(value);
const [isOpen, setIsOpen] = useState(focused); const [isOpen, setIsOpen] = useState(focused || embedded);
const [inputValue, setInputValue] = useState<
AutocompleteProps['inputValue']
>(() => (isSingleValue(value) ? value?.label : undefined));
const [isInitialInputValue, setInitialInputValue] = useState(true);
const onInputChange: AutocompleteProps['onInputChange'] = value => {
setInputValue(value);
setInitialInputValue(false);
};
const filterOption: AutocompleteProps['filterOption'] = (option, input) => {
if (isInitialInputValue) {
return true;
}
const filterOption = (option, input) => {
return ( return (
option.data?.__isNew__ || option.data?.__isNew__ ||
option.label.toLowerCase().includes(input?.toLowerCase()) option.label.toLowerCase().includes(input?.toLowerCase())
); );
}; };
const onChange = async selected => { const onChange: AutocompleteProps['onChange'] = (
selected: PropsValue<OptionValue>,
) => {
// Clear button clicked // Clear button clicked
if (!selected) { if (!selected) {
onSelect(null); onSelect(null);
...@@ -55,18 +92,18 @@ const Autocomplete = React.forwardRef<SelectInstance, AutocompleteProps>( ...@@ -55,18 +92,18 @@ const Autocomplete = React.forwardRef<SelectInstance, AutocompleteProps>(
} }
// Create a new option // Create a new option
if (selected.__isNew__) { if (isSingleValue(selected) && selected.__isNew__) {
onCreateOption(selected.value); onCreateOption(selected.value);
return; return;
} }
// Close the menu when making a successful selection // Close the menu when making a successful selection
if (!Array.isArray(selected)) { if (isSingleValue(selected)) {
setIsOpen(false); setIsOpen(false);
} }
// Multi-select has multiple selections // Multi-select has multiple selections
if (Array.isArray(selected)) { if (!isSingleValue(selected)) {
onSelect(selected.map(option => option.value)); onSelect(selected.map(option => option.value));
return; return;
} }
...@@ -74,9 +111,13 @@ const Autocomplete = React.forwardRef<SelectInstance, AutocompleteProps>( ...@@ -74,9 +111,13 @@ const Autocomplete = React.forwardRef<SelectInstance, AutocompleteProps>(
onSelect(selected.value); onSelect(selected.value);
}; };
const onKeyDown = event => { const onKeyDown: AutocompleteProps['onKeyDown'] = event => {
if (event.code === 'Escape') { if (event.code === 'Escape') {
onSelect(initialValue); onSelect(
isSingleValue(initialValue)
? initialValue?.value
: initialValue.map(val => val.value),
);
setIsOpen(false); setIsOpen(false);
return; return;
} }
...@@ -92,7 +133,7 @@ const Autocomplete = React.forwardRef<SelectInstance, AutocompleteProps>( ...@@ -92,7 +133,7 @@ const Autocomplete = React.forwardRef<SelectInstance, AutocompleteProps>(
<Component <Component
ref={ref} ref={ref}
value={value} value={value}
menuIsOpen={isOpen || embedded} menuIsOpen={isOpen}
autoFocus={embedded} autoFocus={embedded}
options={options} options={options}
placeholder="(none)" placeholder="(none)"
...@@ -114,6 +155,8 @@ const Autocomplete = React.forwardRef<SelectInstance, AutocompleteProps>( ...@@ -114,6 +155,8 @@ const Autocomplete = React.forwardRef<SelectInstance, AutocompleteProps>(
data-embedded={embedded} data-embedded={embedded}
menuPlacement="auto" menuPlacement="auto"
menuPortalTarget={embedded ? undefined : document.body} menuPortalTarget={embedded ? undefined : document.body}
inputValue={inputValue}
onInputChange={onInputChange}
{...props} {...props}
/> />
); );
......
...@@ -77,8 +77,6 @@ export default function PayeeAutocomplete({ ...@@ -77,8 +77,6 @@ export default function PayeeAutocomplete({
const dispatch = useDispatch(); const dispatch = useDispatch();
const [inputValue, setInputValue] = useState();
return ( return (
<Autocomplete <Autocomplete
options={options} options={options}
...@@ -89,8 +87,6 @@ export default function PayeeAutocomplete({ ...@@ -89,8 +87,6 @@ export default function PayeeAutocomplete({
} }
isValidNewOption={input => input && !focusTransferPayees} isValidNewOption={input => input && !focusTransferPayees}
isMulti={multi} isMulti={multi}
inputValue={inputValue}
onInputChange={setInputValue}
onSelect={onSelect} onSelect={onSelect}
onCreateOption={async selectedValue => { onCreateOption={async selectedValue => {
const existingOption = allOptions.find(option => const existingOption = allOptions.find(option =>
...@@ -154,7 +150,6 @@ export default function PayeeAutocomplete({ ...@@ -154,7 +150,6 @@ export default function PayeeAutocomplete({
} }
} }
onClick={() => { onClick={() => {
setInputValue('');
setFocusTransferPayees(!focusTransferPayees); setFocusTransferPayees(!focusTransferPayees);
}} }}
/> />
......
...@@ -17,6 +17,7 @@ const colourStyles = { ...@@ -17,6 +17,7 @@ const colourStyles = {
...styles, ...styles,
padding: '0 2px', padding: '0 2px',
margin: 0, margin: 0,
overflow: 'hidden',
}), }),
menuPortal: styles => ({ menuPortal: styles => ({
...styles, ...styles,
......
---
category: Bugfix
authors: [MatissJanis]
---
Autocomplete: allow editing previously selected payees
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment