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 <rekmarks@protonmail.com>
feature/default_network_editable
Patryk Łucka 4 years ago committed by GitHub
parent ee205b893f
commit 128efc5b52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 30
      ui/app/pages/send/send-content/add-recipient/add-recipient.component.js
  2. 10
      ui/app/pages/send/send-content/add-recipient/add-recipient.container.js
  3. 18
      ui/app/pages/send/send-content/add-recipient/ens-input.component.js
  4. 11
      ui/app/pages/send/send-content/add-recipient/tests/add-recipient-container.test.js
  5. 31
      ui/app/pages/send/send.component.js
  6. 6
      ui/app/pages/send/tests/send-component.test.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 (
<div className="send__select-recipient-wrapper__list">
<Button
type="link"
className="send__select-recipient-wrapper__list__link"
onClick={() => this.setState({ isShowingTransfer: false })}
onClick={() => {
setInternalSearch(false)
this.setState({ isShowingTransfer: false })
}}
>
<div className="send__select-recipient-wrapper__list__back-caret" />
{t('backToAll')}
@ -164,7 +178,12 @@ export default class AddRecipient extends Component {
renderMain() {
const { t } = this.context
const { query, ownedAccounts = [], addressBook } = this.props
const {
query,
ownedAccounts = [],
addressBook,
setInternalSearch,
} = this.props
return (
<div className="send__select-recipient-wrapper__list">
@ -178,7 +197,10 @@ export default class AddRecipient extends Component {
<Button
type="link"
className="send__select-recipient-wrapper__list__link"
onClick={() => this.setState({ isShowingTransfer: true })}
onClick={() => {
setInternalSearch(true)
this.setState({ isShowingTransfer: true })
}}
>
{t('transferBetweenAccounts')}
</Button>

@ -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,
}
}

@ -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() {

@ -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: [],
})

@ -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 (
<EnsInput
className="send__to-row"
@ -314,6 +325,7 @@ export default class SendTransactionScreen extends Component {
onReset={() => 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)
}
/>
)
}

@ -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',

Loading…
Cancel
Save