From 128efc5b52dafd7f7094e1aa932675f95ed1456f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20=C5=81ucka?= Date: Sat, 7 Nov 2020 00:16:51 +0100 Subject: [PATCH] Add sort and search to AddRecipient accounts list (#9257) * sort and search accounts in AddRecipient component * Update AddRecipient unit test Co-authored-by: Erik Marks --- .../add-recipient/add-recipient.component.js | 30 +++++++++++++++--- .../add-recipient/add-recipient.container.js | 10 ++++-- .../add-recipient/ens-input.component.js | 18 ++++++++--- .../tests/add-recipient-container.test.js | 11 +++++-- ui/app/pages/send/send.component.js | 31 ++++++++++++++----- .../pages/send/tests/send-component.test.js | 6 ++++ 6 files changed, 83 insertions(+), 23 deletions(-) diff --git a/ui/app/pages/send/send-content/add-recipient/add-recipient.component.js b/ui/app/pages/send/send-content/add-recipient/add-recipient.component.js index bfef36524..1c43d8927 100644 --- a/ui/app/pages/send/send-content/add-recipient/add-recipient.component.js +++ b/ui/app/pages/send/send-content/add-recipient/add-recipient.component.js @@ -22,6 +22,7 @@ export default class AddRecipient extends Component { addressBookEntryName: PropTypes.string, contacts: PropTypes.array, nonContacts: PropTypes.array, + setInternalSearch: PropTypes.func, } constructor(props) { @@ -140,15 +141,28 @@ export default class AddRecipient extends Component { } renderTransfer() { - const { ownedAccounts } = this.props + let { ownedAccounts } = this.props + const { query, setInternalSearch } = this.props const { t } = this.context + const { isShowingTransfer } = this.state + + if (isShowingTransfer && query) { + ownedAccounts = ownedAccounts.filter( + (item) => + item.name.toLowerCase().indexOf(query.toLowerCase()) > -1 || + item.address.toLowerCase().indexOf(query.toLowerCase()) > -1, + ) + } return (
diff --git a/ui/app/pages/send/send-content/add-recipient/add-recipient.container.js b/ui/app/pages/send/send-content/add-recipient/add-recipient.container.js index b26dcb74b..c3f141183 100644 --- a/ui/app/pages/send/send-content/add-recipient/add-recipient.container.js +++ b/ui/app/pages/send/send-content/add-recipient/add-recipient.container.js @@ -23,14 +23,18 @@ function mapStateToProps(state) { const addressBook = getAddressBook(state) + const ownedAccounts = accountsWithSendEtherInfoSelector(state).sort((a, b) => + a.name.localeCompare(b.name), + ) + return { - ownedAccounts: accountsWithSendEtherInfoSelector(state), addressBook, - ensResolution, addressBookEntryName, - ensResolutionError: getSendEnsResolutionError(state), contacts: addressBook.filter(({ name }) => Boolean(name)), + ensResolution, + ensResolutionError: getSendEnsResolutionError(state), nonContacts: addressBook.filter(({ name }) => !name), + ownedAccounts, } } diff --git a/ui/app/pages/send/send-content/add-recipient/ens-input.component.js b/ui/app/pages/send/send-content/add-recipient/ens-input.component.js index f6e2100eb..5dce9869d 100644 --- a/ui/app/pages/send/send-content/add-recipient/ens-input.component.js +++ b/ui/app/pages/send/send-content/add-recipient/ens-input.component.js @@ -38,6 +38,7 @@ export default class EnsInput extends Component { onValidAddressTyped: PropTypes.func, contact: PropTypes.object, value: PropTypes.string, + internalSearch: PropTypes.bool, } state = { @@ -47,11 +48,11 @@ export default class EnsInput extends Component { } componentDidMount() { - const { network } = this.props + const { network, internalSearch } = this.props const networkHasEnsSupport = getNetworkEnsSupport(network) this.setState({ ensResolution: ZERO_ADDRESS }) - if (networkHasEnsSupport) { + if (networkHasEnsSupport && !internalSearch) { const provider = global.ethereumProvider this.ens = new ENS({ provider, network }) this.checkName = debounce(this.lookupEnsName, 200) @@ -60,7 +61,7 @@ export default class EnsInput extends Component { componentDidUpdate(prevProps) { const { input } = this.state - const { network, value } = this.props + const { network, value, internalSearch } = this.props let newValue @@ -81,6 +82,9 @@ export default class EnsInput extends Component { if (newValue !== undefined) { this.onChange({ target: { value: newValue } }) } + if (!internalSearch && prevProps.internalSearch) { + this.resetInput() + } } resetInput = () => { @@ -143,12 +147,15 @@ export default class EnsInput extends Component { updateEnsResolution, updateEnsResolutionError, onValidAddressTyped, + internalSearch, } = this.props const input = e.target.value const networkHasEnsSupport = getNetworkEnsSupport(network) this.setState({ input }, () => onChange(input)) - + if (internalSearch) { + return null + } // Empty ENS state if input is empty // maybe scan ENS @@ -161,7 +168,7 @@ export default class EnsInput extends Component { updateEnsResolutionError( networkHasEnsSupport ? '' : 'Network does not support ENS', ) - return + return null } if (isValidDomainName(input)) { @@ -172,6 +179,7 @@ export default class EnsInput extends Component { updateEnsResolution('') updateEnsResolutionError('') } + return null } render() { diff --git a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js index fdf3a0fff..b7502bf52 100644 --- a/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js +++ b/ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js @@ -22,8 +22,10 @@ proxyquire('../add-recipient.container.js', { getSendEnsResolutionError: (s) => `mockSendEnsResolutionError:${s}`, getAddressBook: (s) => [{ name: `mockAddressBook:${s}` }], getAddressBookEntry: (s) => `mockAddressBookEntry:${s}`, - accountsWithSendEtherInfoSelector: (s) => - `mockAccountsWithSendEtherInfoSelector:${s}`, + accountsWithSendEtherInfoSelector: (s) => [ + { name: `account2:${s}` }, + { name: `account1:${s}` }, + ], }, '../../../../store/actions': actionSpies, }) @@ -36,7 +38,10 @@ describe('add-recipient container', function () { contacts: [{ name: 'mockAddressBook:mockState' }], ensResolution: 'mockSendEnsResolution:mockState', ensResolutionError: 'mockSendEnsResolutionError:mockState', - ownedAccounts: 'mockAccountsWithSendEtherInfoSelector:mockState', + ownedAccounts: [ + { name: `account1:mockState` }, + { name: `account2:mockState` }, + ], addressBookEntryName: undefined, nonContacts: [], }) diff --git a/ui/app/pages/send/send.component.js b/ui/app/pages/send/send.component.js index e35d39561..996852e2e 100644 --- a/ui/app/pages/send/send.component.js +++ b/ui/app/pages/send/send.component.js @@ -63,6 +63,7 @@ export default class SendTransactionScreen extends Component { query: '', toError: null, toWarning: null, + internalSearch: false, } constructor(props) { @@ -204,21 +205,30 @@ export default class SendTransactionScreen extends Component { } onRecipientInputChange = (query) => { - if (query) { - this.dValidate(query) - } else { - this.validate(query) + const { internalSearch } = this.state + + if (!internalSearch) { + if (query) { + this.dValidate(query) + } else { + this.dValidate.cancel() + this.validate(query) + } } - this.setState({ - query, - }) + this.setState({ query }) + } + + setInternalSearch(internalSearch) { + this.setState({ query: '', internalSearch }) } validate(query) { const { hasHexData, tokens, sendToken, network } = this.props - if (!query) { + const { internalSearch } = this.state + + if (!query || internalSearch) { this.setState({ toError: '', toWarning: '' }) return } @@ -293,6 +303,7 @@ export default class SendTransactionScreen extends Component { } renderInput() { + const { internalSearch } = this.state return ( this.props.updateSendTo('', '')} updateEnsResolution={this.props.updateSendEnsResolution} updateEnsResolutionError={this.props.updateSendEnsResolutionError} + internalSearch={internalSearch} /> ) } @@ -327,6 +339,9 @@ export default class SendTransactionScreen extends Component { } query={this.state.query} toError={toError} + setInternalSearch={(internalSearch) => + this.setInternalSearch(internalSearch) + } /> ) } diff --git a/ui/app/pages/send/tests/send-component.test.js b/ui/app/pages/send/tests/send-component.test.js index 30aa334e8..42a3dc504 100644 --- a/ui/app/pages/send/tests/send-component.test.js +++ b/ui/app/pages/send/tests/send-component.test.js @@ -435,6 +435,7 @@ describe('Send Component', function () { ) assert.deepEqual(instance.state, { + internalSearch: false, query: '0x80F061544cC398520615B5d3e7A3BedD70cd4510', toError: null, toWarning: null, @@ -449,6 +450,7 @@ describe('Send Component', function () { clock.tick(1001) assert.deepEqual(instance.state, { + internalSearch: false, query: '0x80F061544cC398520615B5d3e7a3BedD70cd4510', toError: 'invalidAddressRecipient', toWarning: null, @@ -464,6 +466,7 @@ describe('Send Component', function () { clock.tick(1001) assert.deepEqual(instance.state, { + internalSearch: false, query: '0x80F061544cC398520615B5d3e7a3BedD70cd4510', toError: 'invalidAddressRecipientNotEthNetwork', toWarning: null, @@ -479,6 +482,7 @@ describe('Send Component', function () { clock.tick(1001) assert.deepEqual(instance.state, { + internalSearch: false, query: '0x80F061544cC398520615B5d3e7a3BedD70cd4510', toError: 'invalidAddressRecipientNotEthNetwork', toWarning: null, @@ -486,6 +490,7 @@ describe('Send Component', function () { instance.onRecipientInputChange('') assert.deepEqual(instance.state, { + internalSearch: false, query: '', toError: '', toWarning: '', @@ -501,6 +506,7 @@ describe('Send Component', function () { clock.tick(1001) assert.deepEqual(instance.state, { + internalSearch: false, query: '0x13cb85823f78Cff38f0B0E90D3e975b8CB3AAd64', toError: null, toWarning: 'knownAddressRecipient',