From f0091391713d22243fbf0e3381d32c9dc13cfc7f Mon Sep 17 00:00:00 2001 From: fernandomg Date: Mon, 9 Apr 2018 15:04:02 -0300 Subject: [PATCH] Validate min/max values for whitelist items in StepThree --- src/components/Common/TierBlock.js | 2 +- src/components/Common/WhitelistInputBlock.js | 115 ++++++++++++++++-- src/components/stepThree/StepThreeForm.js | 1 + .../__snapshots__/CrowdsaleBlock.spec.js.snap | 6 + 4 files changed, 116 insertions(+), 8 deletions(-) diff --git a/src/components/Common/TierBlock.js b/src/components/Common/TierBlock.js index 1af9690fb..08204652a 100644 --- a/src/components/Common/TierBlock.js +++ b/src/components/Common/TierBlock.js @@ -186,7 +186,7 @@ export const TierBlock = ({ fields, ...props }) => {

Whitelist

- + ) : null } diff --git a/src/components/Common/WhitelistInputBlock.js b/src/components/Common/WhitelistInputBlock.js index 21a175bd4..27141f5e7 100644 --- a/src/components/Common/WhitelistInputBlock.js +++ b/src/components/Common/WhitelistInputBlock.js @@ -5,11 +5,12 @@ import Dropzone from 'react-dropzone'; import Papa from 'papaparse' import '../../assets/stylesheets/application.css'; import { InputField } from './InputField' -import { TEXT_FIELDS, VALIDATION_TYPES } from '../../utils/constants' +import { TEXT_FIELDS, VALIDATION_MESSAGES, VALIDATION_TYPES } from '../../utils/constants' import { WhitelistItem } from './WhitelistItem' import { inject, observer } from 'mobx-react' import { clearingWhitelist, whitelistImported } from '../../utils/alerts' import processWhitelist from '../../utils/processWhitelist' +import { validateWhitelistMax, validateWhitelistMin } from '../../utils/validations' const { ADDRESS, MIN, MAX } = TEXT_FIELDS const {VALID, INVALID} = VALIDATION_TYPES; @@ -26,7 +27,17 @@ export class WhitelistInputBlock extends React.Component { address: { pristine: true, valid: INVALID - } + }, + min: { + pristine: true, + valid: INVALID, + errorMessage: VALIDATION_MESSAGES.REQUIRED + }, + max: { + pristine: true, + valid: INVALID, + errorMessage: VALIDATION_MESSAGES.REQUIRED + }, } } } @@ -40,11 +51,23 @@ export class WhitelistInputBlock extends React.Component { validation: { address: { pristine: { $set: false } - } + }, + min: { + pristine: { $set: false } + }, + max: { + pristine: { $set: false } + }, } })) - if (!addr || !min || !max || this.state.validation.address.valid === INVALID) { + const { + address: { valid: addrValid }, + min: { valid: minValid }, + max: { valid: maxValid }, + } = this.state.validation + + if (!addr || !min || !max || addrValid === INVALID || minValid === INVALID || maxValid === INVALID) { return } @@ -56,7 +79,17 @@ export class WhitelistInputBlock extends React.Component { address: { pristine: true, valid: INVALID - } + }, + min: { + pristine: true, + valid: INVALID, + errorMessage: VALIDATION_MESSAGES.REQUIRED + }, + max: { + pristine: true, + valid: INVALID, + errorMessage: VALIDATION_MESSAGES.REQUIRED + }, } }) @@ -81,6 +114,68 @@ export class WhitelistInputBlock extends React.Component { this.setState(newState) } + handleMinChange = ({ min }) => { + const errorMessage = validateWhitelistMin({ + min, + max: this.state.max, + decimals: this.props.decimals + }) + + return new Promise((resolve) => { + this.setState(update(this.state, { + min: { $set: min }, + validation: { + min: { + $set: { + pristine: false, + valid: errorMessage ? INVALID : VALID, + errorMessage + } + } + } + }), resolve) + }) + } + + handleMaxChange = ({ max }) => { + const errorMessage = validateWhitelistMax({ + min: this.state.min, + max, + decimals: this.props.decimals + }) + + return new Promise((resolve) => { + this.setState(update(this.state, { + max: { $set: max }, + validation: { + max: { + $set: { + pristine: false, + valid: errorMessage ? INVALID : VALID, + errorMessage + } + } + } + }), resolve) + }) + } + + handleMinMaxChange = ({ min, max }) => { + if (min !== undefined) { + this.handleMinChange({ min }) + .then(() => { + if (!this.state.validation.max.pristine) this.handleMaxChange({ max: this.state.max }) + }) + } + + if (max !== undefined) { + this.handleMaxChange({ max }) + .then(() => { + if (!this.state.validation.min.pristine) this.handleMinChange({ min: this.state.min }) + }) + } + } + onDrop = (acceptedFiles, rejectedFiles) => { acceptedFiles.forEach(file => { Papa.parse(file, { @@ -149,16 +244,22 @@ export class WhitelistInputBlock extends React.Component { type='number' title={MIN} value={this.state.min} - onChange={e => this.setState({ min: e.target.value })} + onChange={e => this.handleMinMaxChange({ min: e.target.value })} description={`Minimum amount tokens to buy. Not a minimal size of a transaction. If minCap is 1 and user bought 1 token in a previous transaction and buying 0.1 token it will allow him to buy.`} + pristine={this.state.validation.min.pristine} + valid={this.state.validation.min.valid} + errorMessage={this.state.validation.min.errorMessage} /> this.setState({ max: e.target.value })} + onChange={e => this.handleMinMaxChange({ max: e.target.value })} description={`Maximum is the hard limit.`} + pristine={this.state.validation.max.pristine} + valid={this.state.validation.max.valid} + errorMessage={this.state.validation.max.errorMessage} />
diff --git a/src/components/stepThree/StepThreeForm.js b/src/components/stepThree/StepThreeForm.js index b613c1f3d..a9927a1b3 100644 --- a/src/components/stepThree/StepThreeForm.js +++ b/src/components/stepThree/StepThreeForm.js @@ -154,6 +154,7 @@ export const StepThreeForm = ({ handleSubmit, values, invalid, pristine, mutator )} diff --git a/src/components/stepThree/__snapshots__/CrowdsaleBlock.spec.js.snap b/src/components/stepThree/__snapshots__/CrowdsaleBlock.spec.js.snap index 7130d98c1..ab482b38c 100644 --- a/src/components/stepThree/__snapshots__/CrowdsaleBlock.spec.js.snap +++ b/src/components/stepThree/__snapshots__/CrowdsaleBlock.spec.js.snap @@ -1567,10 +1567,13 @@ exports[`CrowdsaleBlock Should render the component for the second Tier with whi