import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import log from 'loglevel'; import classnames from 'classnames'; import BigNumber from 'bignumber.js'; import Modal from '../../modal'; import Identicon from '../../../ui/identicon'; import TextField from '../../../ui/text-field'; import { calcTokenAmount, toPrecisionWithoutTrailingZeros, } from '../../../../../shared/lib/transactions-controller-utils'; import { ButtonIcon, ButtonIconSize, IconName, } from '../../../component-library'; const MAX_UNSIGNED_256_INT = new BigNumber(2).pow(256).minus(1).toString(10); export default class EditApprovalPermission extends PureComponent { static propTypes = { decimals: PropTypes.number, hideModal: PropTypes.func.isRequired, selectedIdentity: PropTypes.object, tokenAmount: PropTypes.string, customTokenAmount: PropTypes.string, tokenSymbol: PropTypes.string, tokenBalance: PropTypes.string, setCustomAmount: PropTypes.func, origin: PropTypes.string.isRequired, requiredMinimum: PropTypes.instanceOf(BigNumber), }; static contextTypes = { t: PropTypes.func, }; state = { // This is used as a TextField value, which should be a string. customSpendLimit: this.props.customTokenAmount || '', selectedOptionIsUnlimited: !this.props.customTokenAmount, }; renderModalContent(error) { const { t } = this.context; const { hideModal, selectedIdentity, tokenAmount, tokenSymbol, tokenBalance, customTokenAmount, origin, } = this.props; const { name, address } = selectedIdentity || {}; const { selectedOptionIsUnlimited } = this.state; return (
{t('editPermission')}
{name}
{t('balance')}
{`${toPrecisionWithoutTrailingZeros( tokenBalance, 9, )} ${tokenSymbol}`}
{t('spendLimitPermission')}
{t('allowWithdrawAndSpend', [origin])}
this.setState({ selectedOptionIsUnlimited: true })} >
{selectedOptionIsUnlimited && (
)}
{new BigNumber(tokenAmount).equals( new BigNumber(MAX_UNSIGNED_256_INT), ) ? t('unlimited') : t('proposedApprovalLimit')}
{t('spendLimitRequestedBy', [origin])}
{`${Number(tokenAmount)} ${tokenSymbol}`}
this.setState({ selectedOptionIsUnlimited: false }) } >
{!selectedOptionIsUnlimited && (
)}
{t('customSpendLimit')}
{t('enterMaxSpendLimit')}
{ this.setState({ customSpendLimit: event.target.value }); if (selectedOptionIsUnlimited) { this.setState({ selectedOptionIsUnlimited: false }); } }} fullWidth margin="dense" value={this.state.customSpendLimit} error={error} />
); } validateSpendLimit() { const { t } = this.context; const { decimals, requiredMinimum } = this.props; const { selectedOptionIsUnlimited, customSpendLimit } = this.state; if (selectedOptionIsUnlimited || !customSpendLimit) { return undefined; } let customSpendLimitNumber; try { customSpendLimitNumber = new BigNumber(customSpendLimit); } catch (error) { log.debug(`Error converting '${customSpendLimit}' to BigNumber:`, error); return t('spendLimitInvalid'); } if (customSpendLimitNumber.isNegative()) { return t('spendLimitInvalid'); } const maxTokenAmount = calcTokenAmount(MAX_UNSIGNED_256_INT, decimals); if (customSpendLimitNumber.greaterThan(maxTokenAmount)) { return t('spendLimitTooLarge'); } if ( requiredMinimum !== undefined && customSpendLimitNumber.lessThan(requiredMinimum) ) { return t('spendLimitInsufficient'); } return undefined; } render() { const { t } = this.context; const { setCustomAmount, hideModal, customTokenAmount } = this.props; const { selectedOptionIsUnlimited, customSpendLimit } = this.state; const error = this.validateSpendLimit(); const disabled = Boolean( (customSpendLimit === customTokenAmount && !selectedOptionIsUnlimited) || error, ); return ( { setCustomAmount(selectedOptionIsUnlimited ? '' : customSpendLimit); hideModal(); }} submitText={t('save')} contentClass="edit-approval-permission-modal-content" containerClass="edit-approval-permission-modal-container" submitDisabled={disabled} > {this.renderModalContent(error)} ); } }