From d51303f3482ec27c75a26e70ced4fb098ed129ab Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Mon, 17 Feb 2020 09:51:36 -0300 Subject: [PATCH] Bug #523: Filtering contacts (#568) Works fine for me: - The address book selector displays - Typing the name/address will filter - Not case sensitive - Deleted won't show anymore. New added addresses will show and filter - Works for regular Tx and Custom Tx This is out of the scope of this issue, but worth mentioning: the issue reported in #482 is still here: the custom Tx still show addresses that are not valid (non contract addresses). --- .../screens/AddressBookInput/index.jsx | 85 ++++++++++++------- 1 file changed, 53 insertions(+), 32 deletions(-) diff --git a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.jsx b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.jsx index 91aa0696..31299e28 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.jsx +++ b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.jsx @@ -1,22 +1,20 @@ // @flow import React, { useEffect, useState } from 'react' -import { - withStyles, -} from '@material-ui/core/styles' +import { withStyles } from '@material-ui/core/styles' import { useSelector } from 'react-redux' import Autocomplete from '@material-ui/lab/Autocomplete' import TextField from '@material-ui/core/TextField' import makeStyles from '@material-ui/core/styles/makeStyles' import { List } from 'immutable' import { styles } from './style' +import { getAddressBookListSelector } from '~/logic/addressBook/store/selectors' import { - getAddressBookListSelector, -} from '~/logic/addressBook/store/selectors' -import { mustBeEthereumAddress, mustBeEthereumContractAddress } from '~/components/forms/validator' + mustBeEthereumAddress, + mustBeEthereumContractAddress, +} from '~/components/forms/validator' import Identicon from '~/components/Identicon' import { getAddressFromENS } from '~/logic/wallets/getWeb3' - type Props = { classes: Object, fieldMutator: Function, @@ -27,7 +25,6 @@ type Props = { pristine: boolean, } - const textFieldLabelStyle = makeStyles(() => ({ root: { overflow: 'hidden', @@ -44,10 +41,16 @@ const textFieldInputStyle = makeStyles(() => ({ }, })) -const isValidEnsName = (name) => /^([\w-]+\.)+(eth|test|xyz|luxe)$/.test(name) +const isValidEnsName = name => /^([\w-]+\.)+(eth|test|xyz|luxe)$/.test(name) const AddressBookInput = ({ - classes, fieldMutator, isCustomTx, recipientAddress, setSelectedEntry, pristine, setIsValidAddress, + classes, + fieldMutator, + isCustomTx, + recipientAddress, + setSelectedEntry, + pristine, + setIsValidAddress, }: Props) => { const addressBook = useSelector(getAddressBookListSelector) const [isValidForm, setIsValidForm] = useState(true) @@ -58,7 +61,7 @@ const AddressBookInput = ({ const [inputAddValue, setInputAddValue] = useState(recipientAddress) - const onAddressInputChanged = async (addressValue) => { + const onAddressInputChanged = async addressValue => { setInputAddValue(addressValue) let resolvedAddress = addressValue let isValidText @@ -77,6 +80,16 @@ const AddressBookInput = ({ if (isCustomTx && isValidText === undefined) { isValidText = await mustBeEthereumContractAddress(resolvedAddress) } + + // Filters the entries based on the input of the user + const filteredADBK = addressBook.filter(adbkEntry => { + const { name, address } = adbkEntry + return ( + name.toLowerCase().includes(addressValue.toLowerCase()) || + address.toLowerCase().includes(addressValue.toLowerCase()) + ) + }) + setADBKList(filteredADBK) } setIsValidForm(isValidText === undefined) setValidationText(isValidText) @@ -90,8 +103,15 @@ const AddressBookInput = ({ setADBKList(addressBook) return } - const abFlags = await Promise.all(addressBook.map(async ({ address }) => mustBeEthereumContractAddress(address) === undefined)) - const filteredADBK = addressBook.filter((adbkEntry, index) => abFlags[index]) + const abFlags = await Promise.all( + addressBook.map( + async ({ address }) => + mustBeEthereumContractAddress(address) === undefined + ) + ) + const filteredADBK = addressBook.filter( + (adbkEntry, index) => abFlags[index] + ) setADBKList(filteredADBK) } filterAdbkContractAddresses() @@ -112,14 +132,17 @@ const AddressBookInput = ({ options={adbkList.toArray()} style={{ display: 'flex', flexGrow: 1 }} closeIcon={null} - filterOptions={(optionsArray, { inputValue }) => optionsArray.filter((item) => { - const inputLowerCase = inputValue.toLowerCase() - const foundName = item.name.toLowerCase() - .includes(inputLowerCase) - const foundAddress = item.address.toLowerCase().includes(inputLowerCase) - return foundName || foundAddress - })} - getOptionLabel={(adbkEntry) => adbkEntry.address || ''} + filterOptions={(optionsArray, { inputValue }) => + optionsArray.filter(item => { + const inputLowerCase = inputValue.toLowerCase() + const foundName = item.name.toLowerCase().includes(inputLowerCase) + const foundAddress = item.address + .toLowerCase() + .includes(inputLowerCase) + return foundName || foundAddress + }) + } + getOptionLabel={adbkEntry => adbkEntry.address || ''} onOpen={() => { setSelectedEntry(null) setBlurred(false) @@ -136,7 +159,7 @@ const AddressBookInput = ({ setSelectedEntry({ address, name }) fieldMutator(address) }} - renderOption={(adbkEntry) => { + renderOption={adbkEntry => { const { name, address } = adbkEntry return (
@@ -150,7 +173,7 @@ const AddressBookInput = ({
) }} - renderInput={(params) => ( + renderInput={params => ( { + onChange={event => { setInputTouched(true) onAddressInputChanged(event.target.value) }} - InputProps={ - { - ...params.InputProps, - classes: { - ...txInputStyling, - }, - } - } + InputProps={{ + ...params.InputProps, + classes: { + ...txInputStyling, + }, + }} InputLabelProps={{ shrink: true, required: true,