Merge pull request #267 from status-im/fix/small-bugs

Fix a couple of bugs
This commit is contained in:
Iuri Matias 2019-05-23 15:35:31 -04:00 committed by GitHub
commit 165b00a65e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 17 additions and 1040 deletions

View File

@ -1,68 +0,0 @@
import React from 'react';
import {Card, CardBody, CardHeader, CardTitle, Table} from 'reactstrap';
import PropTypes from 'prop-types';
import {withNamespaces} from "react-i18next";
import {ARBITRATION_UNSOLVED} from "../../features/arbitration/constants";
import ArbitrationResult from "./ArbitrationResult";
import Address from "../UserInformation/Address";
import TransactionResults from "./TransactionResults";
function getArbitrationState(escrow) {
if(escrow.arbitration.open && escrow.arbitration.result === ARBITRATION_UNSOLVED){
return <p className="text-danger">In arbitration</p>;
}
return <p className="text-success">Arbitration completed</p>;
}
const ArbitrationList = (props) => (
<Card className="mt-2">
<CardHeader>
<CardTitle>Disputed escrows</CardTitle>
</CardHeader>
<CardBody>
<TransactionResults txHash={props.txHash} loading={props.loading} error={props.error}
loadingText={props.t('arbitrationList.loading')} errorText={"Error: "}/>
{(props.escrows.length === 0) && !props.loading && <p>No Arbitration cases</p>}
{props.escrows.length > 0 && <Table>
<thead>
<tr>
<th>#</th>
<th>State</th>
<th>Seller</th>
<th>Buyer</th>
<th>Open By</th>
<th>Value</th>
<th>Expiration</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{props.escrows.map(escrow =>
<tr key={escrow.escrowId}>
<th scope="row">{escrow.escrowId}</th>
<td>{getArbitrationState(escrow)}</td>
<td><Address address={escrow.seller} compact={true} /></td>
<td><Address address={escrow.buyer} compact={true} /></td>
<td>{escrow.buyer === escrow.arbitration.openBy ? 'Buyer' : 'Seller'}</td>
<td>{escrow.amount}</td>
<td>{escrow.expirationTime.toString()}</td>
<td>
<ArbitrationResult decision={parseInt(escrow.arbitration.result, 10)} resolveDispute={props.resolveDispute}
escrowId={escrow.escrowId} disabled={props.loading}/>
</td>
</tr>)}
</tbody>
</Table>}
</CardBody>
</Card>);
ArbitrationList.propTypes = {
escrows: PropTypes.array,
resolveDispute: PropTypes.func,
t: PropTypes.func,
loading: PropTypes.bool,
error: PropTypes.string,
txHash: PropTypes.string
};
export default withNamespaces()(ArbitrationList);

View File

@ -1,48 +0,0 @@
import React, {Component} from 'react';
import {Button, FormGroup, Input} from "reactstrap";
import PropTypes from 'prop-types';
import {ARBITRATION_SOLVED_BUYER, ARBITRATION_SOLVED_SELLER, ARBITRATION_UNSOLVED} from "../../features/arbitration/constants";
class ArbitrationResult extends Component {
constructor(props) {
super(props);
this.state = {
decision: 0
};
}
onChange(e) {
this.setState({decision: e.target.value});
}
submit() {
this.props.resolveDispute(this.props.escrowId, this.state.decision);
}
render() {
const solved = this.props.decision.toString() !== ARBITRATION_UNSOLVED;
if(solved){
return <span>{this.props.decision.toString() === ARBITRATION_SOLVED_BUYER ? "Funds released to buyer" : "Seller refunded" }</span>;
}
return <FormGroup>
<Input type="select" name="select" id="exampleSelect" onChange={(e) => this.onChange(e)}
value={this.state.decision} disabled={this.props.disabled}>
<option value={ARBITRATION_UNSOLVED}>Select</option>
<option value={ARBITRATION_SOLVED_BUYER}>Release funds to buyer</option>
<option value={ARBITRATION_SOLVED_SELLER}>Refund seller</option>
</Input>
<Button color="secondary" onClick={() => this.submit()} disabled={this.props.disabled}>Solve</Button>
</FormGroup>;
}
}
ArbitrationResult.propTypes = {
escrowId: PropTypes.string,
decision: PropTypes.number,
resolveDispute: PropTypes.func,
disabled: PropTypes.bool
};
export default ArbitrationResult;

View File

@ -1,107 +0,0 @@
import React, {Component} from 'react';
import {Button, Card, CardBody, CardHeader, CardTitle, FormGroup, Label, FormFeedback} from 'reactstrap';
import PropTypes from 'prop-types';
import Datetime from 'react-datetime';
import moment from 'moment';
import classnames from 'classnames';
import {withNamespaces} from 'react-i18next';
import Form from 'react-validation/build/form';
import Input from 'react-validation/build/input';
import {isInteger, isAddress, required} from '../../validators';
import TransactionResults from './TransactionResults';
import '../../../../node_modules/react-datetime/css/react-datetime.css';
import '../../../css/Form.scss';
class CreateEscrowForm extends Component {
constructor(props) {
super(props);
this.state = {
amount: '',
expiration: moment(Date.now() + (15 * 60 * 1000)),
buyer: '',
expirationError: '',
error: ''
};
}
onBuyerChange(e) {
this.setState({buyer: e.target.value});
}
onAmountChange(e) {
this.setState({amount: e.target.value});
}
validateExpiration(expiration) {
let error = '';
if (!expiration.unix()) { // Somehow, the user managed to return NOT a moment date
error = 'Expiration is not a valid date object. Please use the Date Picker.';
}
if (expiration.unix() < moment().unix() + 600) {
error = 'Expiration date needs to be in at least 10 minutes';
}
this.setState({expirationError: error});
return error;
}
onExpirationChange(newDate) {
this.validateExpiration(newDate);
this.setState({expiration: newDate});
}
submit = () => {
this.form.validateAll();
const expirationError = this.validateExpiration(this.state.expiration);
if (this.form.getChildContext()._errors.length > 0 || expirationError) {
return this.setState({error: 'Please fix issues before submitting'});
}
this.setState({error: ''});
this.props.create(this.state.buyer, this.state.amount, this.state.expiration.unix());
};
render() {
const {expiration, buyer, amount, expirationError, error} = this.state;
const {t, isLoading, result, error: propsError, txHash} = this.props;
return <Card className="mt-2">
<CardHeader>
<CardTitle>{t('createEscrowFrom.title')}</CardTitle>
</CardHeader>
<CardBody>
<Form ref={c => { this.form = c; }}>
<TransactionResults txHash={txHash} loading={isLoading} error={propsError || error} result={result} errorText={t('createEscrowFrom.error')}
loadingText={t('createEscrowFrom.creating')} resultText={t('createEscrowFrom.receipt')}/>
<FormGroup>
<Label for="buyer">{t('createEscrowFrom.buyer')}</Label>
<Input type="text" name="buyer" id="buyer" placeholder="Address of the buyer" className="form-control"
onChange={(e) => this.onBuyerChange(e)} value={buyer} validations={[required, isAddress]} disabled={isLoading}/>
</FormGroup>
<FormGroup>
<Label for="amount">{t('createEscrowFrom.amount')}</Label>
<Input type="number" name="amount" id="amount" placeholder="Amount your are selling" className="form-control"
onChange={(e) => this.onAmountChange(e)} value={amount} validations={[required, isInteger]} disabled={isLoading}/>
</FormGroup>
<FormGroup>
<Label for="expiration">{t('createEscrowFrom.expiration')}</Label>
<Datetime inputProps={{className: classnames({'is-invalid': !!expirationError, 'form-control': true}), disabled:isLoading}}
value={expiration} onChange={(newDate) => this.onExpirationChange(newDate)}/>
<FormFeedback className={classnames({'d-block': !!expirationError})}>{expirationError}</FormFeedback>
</FormGroup>
<Button onClick={this.submit} disabled={isLoading}>{t('createEscrowFrom.submit')}</Button>
</Form>
</CardBody>
</Card>;
}
}
CreateEscrowForm.propTypes = {
t: PropTypes.func,
create: PropTypes.func,
error: PropTypes.string,
result: PropTypes.object,
isLoading: PropTypes.bool,
txHash: PropTypes.string
};
export default withNamespaces()(CreateEscrowForm);

View File

@ -1,126 +0,0 @@
/*global web3*/
import React, {Fragment} from 'react';
import {Card, CardBody, CardHeader, CardTitle, Table, Button} from 'reactstrap';
import PropTypes from 'prop-types';
import {withNamespaces} from 'react-i18next';
import {getTradeStatus, tradeStates} from "../../features/escrow/helpers";
import {SIGNATURE_PAYMENT, SIGNATURE_OPEN_CASE} from "../../features/escrow/constants";
import Rating from "./Rating";
import SignatureDialog from "./SignatureDialog";
import TransactionResults from "./TransactionResults";
function getTradeStatusText(escrow, t) {
switch (getTradeStatus(escrow)) {
case tradeStates.released:
return <p className="text-success">{t('escrowList.state.released')}</p>;
case tradeStates.paid:
return <p className="text-primary">{t('escrowList.state.paid')}</p>;
case tradeStates.canceled:
return <p className="text-warning">{t('escrowList.state.canceled')}</p>;
case tradeStates.expired:
return <p className="text-danger">{t('escrowList.state.expired')}</p>;
case tradeStates.arbitration_open:
return <p className="text-danger">{t('escrowList.state.inArbitration')}</p>;
case tradeStates.arbitration_closed:
return <p className="text-warning">{t('escrowList.state.arbitrationCompleted')}</p>;
case tradeStates.waiting:
default:
return <p className="text-primary">{t('escrowList.state.waiting')}</p>;
}
}
const EscrowList = (props) => (
<Fragment>
{props.signature && <SignatureDialog open={!!props.signature.message}
onClose={props.closeDialog}
message={{
escrowId: props.signature.escrowId,
message: props.signature.message,
type: props.signature.type
}}>
{props.signature.type === SIGNATURE_PAYMENT && props.t('escrowList.actions.markAsPaid')}
{props.signature.type === SIGNATURE_OPEN_CASE && props.t('escrowList.actions.openCase')}
</SignatureDialog>}
<Card className="mt-2">
<CardHeader>
<CardTitle>{props.t('escrowList.title')}</CardTitle>
</CardHeader>
<CardBody>
<TransactionResults txHash={props.txHash} loading={props.loading} error={props.error} resultText={"Receipt:"}
loadingText={props.t('escrowList.loading')} errorText={props.t('escrowList.error')}/>
{(!props.escrows || props.escrows.length === 0) && !props.loading && <p>{props.t('escrowList.empty')}</p>}
{props.escrows && props.escrows.length > 0 && <Table>
<thead>
<tr>
<th>#</th>
<th>{props.t('escrowList.head.state')}</th>
<th>{props.escrows[0].buyer === web3.eth.defaultAccount ? props.t('escrowList.head.seller') : props.t('escrowList.head.buyer')}</th>
<th>{props.t('escrowList.head.value')}</th>
<th>{props.t('escrowList.head.expiration')}</th>
<th>{props.t('escrowList.head.actions')}</th>
</tr>
</thead>
<tbody>
{props.escrows.map(escrow => {
escrow.state = getTradeStatus(escrow);
return escrow;
})
.map(escrow => <tr key={escrow.escrowId}>
<th scope="row">{escrow.escrowId}</th>
<td>{getTradeStatusText(escrow, props.t)}</td>
<td>{escrow.buyer === web3.eth.defaultAccount ? escrow.seller : escrow.buyer}</td>
<td>{escrow.amount}</td>
<td>{escrow.expirationTime.toString()}</td>
<td>
{escrow.state === tradeStates.waiting && escrow.seller === web3.eth.defaultAccount &&
<Button color="success" size="sm" className="mb-1" block
onClick={() => props.releaseEscrow(escrow.escrowId)}>
{props.t('escrowList.actions.release')}
</Button>}
{escrow.state === tradeStates.expired && escrow.seller === web3.eth.defaultAccount &&
<Button color="warning" size="sm" block
onClick={() => props.cancelEscrow(escrow.escrowId)}>{props.t('escrowList.actions.cancel')}</Button>}
{escrow.state === tradeStates.released && !escrow.arbitration && escrow.buyer === web3.eth.defaultAccount &&
<Rating rating={escrow.rating} rateTransaction={props.rateTransaction}
escrowId={escrow.escrowId}/>}
{escrow.state === tradeStates.waiting && escrow.buyer === web3.eth.defaultAccount && <Fragment>
<Button color="warning" size="sm" block
onClick={() => props.payEscrow(escrow.escrowId)}>{props.t('escrowList.actions.markAsPaid')}</Button>
<Button color="warning" size="sm" block
onClick={() => props.payEscrowSignature(escrow.escrowId)}>{props.t('escrowList.actions.signAsPaid')}</Button>
</Fragment>}
{escrow.state === tradeStates.paid && <Fragment>
<Button color="warning" size="sm" block
onClick={() => props.openCase(escrow.escrowId)}>{props.t('escrowList.actions.openCase')}</Button>
<Button color="warning" size="sm" block
onClick={() => props.openCaseSignature(escrow.escrowId)}>{props.t('escrowList.actions.openCaseSignature')}</Button>
</Fragment>
}
</td>
</tr>)}
</tbody>
</Table>}
</CardBody>
</Card>
</Fragment>);
EscrowList.propTypes = {
t: PropTypes.func,
escrows: PropTypes.array,
signature: PropTypes.object,
releaseEscrow: PropTypes.func,
payEscrow: PropTypes.func,
payEscrowSignature: PropTypes.func,
openCase: PropTypes.func,
openCaseSignature: PropTypes.func,
cancelEscrow: PropTypes.func,
closeDialog: PropTypes.func,
rateTransaction: PropTypes.func,
loading: PropTypes.bool,
error: PropTypes.string,
txHash: PropTypes.string
};
export default withNamespaces()(EscrowList);

View File

@ -1,49 +0,0 @@
import React from 'react';
import {Card, CardHeader, CardBody, CardTitle, Button} from 'reactstrap';
import PropTypes from 'prop-types';
import { withNamespaces } from 'react-i18next';
import TransactionResults from "./TransactionResults";
const BuyLicense = (props) => (
<Button onClick={props.buyLicense} disabled={props.disabled}>{props.t('license.buy')}</Button>
);
BuyLicense.propTypes = {
t: PropTypes.func,
buyLicense: PropTypes.func,
disabled: PropTypes.bool
};
const IsLicenseOwner = (props) => <p>{props.t('license.alreadyOwner')}</p>;
IsLicenseOwner.propTypes = {
t: PropTypes.func
};
const License = (props) => (
<Card className="mt-2">
<CardHeader>
<CardTitle>{props.t('license.title')}</CardTitle>
</CardHeader>
<CardBody>
<TransactionResults txHash={props.txHash} loading={props.loading} error={props.error}
loadingText={props.t('license.buying')} errorText={"Error: "}/>
{props.isLicenseOwner ? <IsLicenseOwner t={props.t}/> : <BuyLicense buyLicense={props.buyLicense} t={props.t} disabled={props.loading}/>}
{props.isLicenseOwner &&
<p>{props.t('license.rating')} {props.userRating ? props.userRating : props.t('license.noRating')}</p>
}
</CardBody>
</Card>
);
License.propTypes = {
t: PropTypes.func,
error: PropTypes.string,
txHash: PropTypes.string,
isLicenseOwner: PropTypes.bool,
loading: PropTypes.bool,
userRating: PropTypes.number,
buyLicense: PropTypes.func
};
export default withNamespaces()(License);

View File

@ -1,18 +0,0 @@
import React from "react";
import { shallow } from "enzyme";
import License from "./License";
describe('License', () => {
it('should render correctly', () => {
const component = shallow(<License />);
expect(component).toMatchSnapshot();
});
it('should render when being license owner', () => {
const component = shallow(<License isLicenseOwner />);
expect(component).toMatchSnapshot();
});
});

View File

@ -1,50 +0,0 @@
import React, {Component} from 'react';
import {Button, FormGroup, Input, Label} from "reactstrap";
import PropTypes from 'prop-types';
import { withNamespaces } from 'react-i18next';
const Options = () => {
const buttons = [];
for (let i = 5; i >= 1; i--) {
buttons.push(<option key={'rating-' + i}>{i}</option>);
}
return buttons;
};
class Rating extends Component {
constructor(props) {
super(props);
this.state = {
rating: 0
};
}
onChange(e) {
this.setState({rating: e.target.value});
}
submit() {
this.props.rateTransaction(this.props.escrowId, this.state.rating);
}
render() {
const disabled = this.props.rating !== 0;
return (<FormGroup>
<Label for="exampleSelect">{this.props.t('rating.label')} </Label>
<Input type="select" name="select" id="exampleSelect" disabled={disabled}
onChange={(e) => this.onChange(e)} value={this.props.rating || this.state.rating}>
<Options/>
</Input>
{!disabled && <Button color="secondary" onClick={() => this.submit()}>Rate</Button>}
</FormGroup>);
}
}
Rating.propTypes = {
t: PropTypes.func,
escrowId: PropTypes.string,
rating: PropTypes.number,
rateTransaction: PropTypes.func
};
export default withNamespaces()(Rating);

View File

@ -1,56 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`License should render correctly 1`] = `
<Card
className="mt-2"
tag="div"
>
<CardHeader
tag="div"
>
<CardTitle
tag="h5"
/>
</CardHeader>
<CardBody
tag="div"
>
<TransactionResults
errorText="Error: "
loadingText=""
/>
<BuyLicense
t={[Function]}
/>
</CardBody>
</Card>
`;
exports[`License should render when being license owner 1`] = `
<Card
className="mt-2"
tag="div"
>
<CardHeader
tag="div"
>
<CardTitle
tag="h5"
/>
</CardHeader>
<CardBody
tag="div"
>
<TransactionResults
errorText="Error: "
loadingText=""
/>
<IsLicenseOwner
t={[Function]}
/>
<p>
</p>
</CardBody>
</Card>
`;

View File

@ -1,6 +1,5 @@
import {PAYMENT_METHODS, MARKET_TYPES} from './constants'; import {PAYMENT_METHODS, MARKET_TYPES} from './constants';
import {addressCompare} from '../../utils/address'; import {addressCompare, toChecksumAddress} from '../../utils/address';
function enhanceOffer(state, offer) { function enhanceOffer(state, offer) {
return { return {
@ -12,7 +11,10 @@ function enhanceOffer(state, offer) {
} }
export const getProfile = (state, address) => { export const getProfile = (state, address) => {
const lAddress = address.toLowerCase(); if (!address) {
return null;
}
const lAddress = toChecksumAddress(address);
if (!state.metadata.users[lAddress]) { if (!state.metadata.users[lAddress]) {
return null; return null;

View File

@ -39,9 +39,7 @@ import SellCurrency from '../wizards/Sell/5_Currency';
import SellMargin from '../wizards/Sell/6_Margin'; import SellMargin from '../wizards/Sell/6_Margin';
// Tmp // Tmp
import EscrowsContainer from '../pages/tmp/EscrowsContainer';
import SignatureContainer from '../pages/tmp/SignatureContainer'; import SignatureContainer from '../pages/tmp/SignatureContainer';
import ArbitrationContainer from '../pages/tmp/ArbitrationContainer';
import prices from '../features/prices'; import prices from '../features/prices';
import network from '../features/network'; import network from '../features/network';
@ -132,9 +130,7 @@ class App extends Component {
]}/> ]}/>
} }
<Route path="/tmp/escrows" component={EscrowsContainer}/>
<Route path="/tmp/signature" component={SignatureContainer}/> <Route path="/tmp/signature" component={SignatureContainer}/>
<Route path="/tmp/arbitration" component={ArbitrationContainer}/>
<Route component={fourOFour}/> <Route component={fourOFour}/>
</Switch> </Switch>

View File

@ -1,42 +0,0 @@
import React, {Component} from 'react';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import ArbitrationList from "../../components/tmp/ArbitrationList";
import arbitration from '../../features/arbitration';
class ArbitrationContainer extends Component {
componentDidMount() {
this.props.getDisputedEscrows();
}
render() {
return <ArbitrationList escrows={this.props.escrows}
resolveDispute={this.props.resolveDispute}
error={this.props.errorGet}
loading={this.props.escrowsLoading} />;
}
}
ArbitrationContainer.propTypes = {
resolveDispute: PropTypes.func,
getDisputedEscrows: PropTypes.func,
escrows: PropTypes.array,
errorGet: PropTypes.string,
escrowsLoading: PropTypes.bool
};
const mapStateToProps = state => ({
errorGet: arbitration.selectors.errorGet(state),
escrowsLoading: arbitration.selectors.loading(state),
txHash: arbitration.selectors.txHash(state),
escrows: arbitration.selectors.escrows(state)
});
export default connect(
mapStateToProps,
{
getDisputedEscrows: arbitration.actions.getDisputedEscrows,
resolveDispute: arbitration.actions.resolveDispute
}
)(ArbitrationContainer);

View File

@ -1,115 +0,0 @@
import React, {Component, Fragment} from 'react';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import EscrowList from "../../components/tmp/EscrowList";
import CreateEscrowForm from '../../components/tmp/CreateEscrowForm';
import License from '../../components/tmp/License';
import license from '../../features/license';
import escrow from '../../features/escrow';
class EscrowsContainer extends Component {
componentDidMount() {
this.props.checkLicenseOwner();
this.props.checkUserRating();
this.props.getEscrows();
}
buyLicense = () => {
this.props.buyLicense();
};
createEscrow = (buyer, value, expiration) => {
this.props.createEscrow(buyer, value, expiration);
};
render() {
const {error, userRating, isLicenseOwner, isCreateLoading, escrowError, escrowReceipt, escrows, releaseEscrow,
openCase, payEscrow, signature, payEscrowSignature, openCaseSignature, closeDialog, cancelEscrow,
errorGet, loadingList, rateTransaction, createdTxHash, txHashList, licenseLoading, licenseTxHash} = this.props;
return <Fragment>
<License buyLicense={this.buyLicense} isLicenseOwner={isLicenseOwner} userRating={userRating} error={error}
loading={licenseLoading} txHash={licenseTxHash}/>
{isLicenseOwner &&
<CreateEscrowForm create={this.createEscrow} result={escrowReceipt} error={escrowError}
isLoading={isCreateLoading} txHash={createdTxHash}/>}
<EscrowList escrows={escrows} releaseEscrow={releaseEscrow}
openCase={openCase} payEscrow={payEscrow}
signature={signature}
payEscrowSignature={payEscrowSignature}
openCaseSignature={openCaseSignature}
closeDialog={closeDialog}
cancelEscrow={cancelEscrow} error={errorGet} loading={loadingList}
rateTransaction={rateTransaction} txHash={txHashList}/>
</Fragment>;
}
}
EscrowsContainer.propTypes = {
checkLicenseOwner: PropTypes.func,
licenseLoading: PropTypes.bool,
checkUserRating: PropTypes.func,
buyLicense: PropTypes.func,
licenseTxHash: PropTypes.string,
createEscrow: PropTypes.func,
releaseEscrow: PropTypes.func,
payEscrow: PropTypes.func,
payEscrowSignature: PropTypes.func,
openCase: PropTypes.func,
openCaseSignature: PropTypes.func,
closeDialog: PropTypes.func,
cancelEscrow: PropTypes.func,
rateTransaction: PropTypes.func,
getEscrows: PropTypes.func,
escrows: PropTypes.array,
isCreateLoading: PropTypes.bool,
createdTxHash: PropTypes.string,
txHashList: PropTypes.string,
signature: PropTypes.object,
loadingList: PropTypes.bool,
errorGet: PropTypes.string,
error: PropTypes.string,
userRating: PropTypes.number,
isLicenseOwner: PropTypes.bool,
escrowError: PropTypes.string,
escrowReceipt: PropTypes.object
};
const mapStateToProps = state => ({
isLicenseOwner: license.selectors.isLicenseOwner(state),
licenseLoading: license.selectors.isLoading(state),
userRating: license.selectors.userRating(state),
error: license.selectors.error(state),
licenseTxHash: license.selectors.txHash(state),
escrowError: escrow.selectors.error(state),
isCreateLoading: escrow.selectors.isLoading(state),
escrowReceipt: escrow.selectors.receipt(state),
errorGet: escrow.selectors.errorGet(state),
loadingList: escrow.selectors.loadingList(state),
createdTxHash: escrow.selectors.txHash(state),
txHashList: escrow.selectors.txHashList(state),
escrows: escrow.selectors.escrows(state),
signature: escrow.selectors.signature(state)
});
export default connect(
mapStateToProps,
{
buyLicense: license.actions.buyLicense,
createEscrow: escrow.actions.createEscrow,
getEscrows: escrow.actions.getEscrows,
payEscrow: escrow.actions.payEscrow,
payEscrowSignature: escrow.actions.payEscrowSignature,
openCase: escrow.actions.openCase,
openCaseSignature: escrow.actions.openCaseSignature,
releaseEscrow: escrow.actions.releaseEscrow,
cancelEscrow: escrow.actions.cancelEscrow,
rateTransaction: escrow.actions.rateTransaction,
checkLicenseOwner: license.actions.checkLicenseOwner,
checkUserRating: escrow.actions.checkUserRating,
closeDialog: escrow.actions.closeDialog
}
)(EscrowsContainer);

View File

@ -6,35 +6,31 @@ import {withNamespaces} from 'react-i18next';
import {compactAddress} from '../../../../utils/address'; import {compactAddress} from '../../../../utils/address';
class ArbitratorSelectorForm extends Component { class ArbitratorSelectorForm extends Component {
onInputChange = (text) => {
const arbitrator = this.props.arbitrators.find(x => x === text);
if (arbitrator) {
this.props.changeArbitrator(arbitrator);
}
};
onChange = (items) => { onChange = (items) => {
if(items.length){ if(items.length){
const item = items[0]; const item = items[0];
this.props.changeArbitrator(item); const index = item.substring(0, item.indexOf(' - '));
this.props.changeArbitrator(this.props.arbitrators[parseInt(index, 10)]);
} }
}; };
render() { render() {
const {t, value} = this.props; const {t, value} = this.props;
let defaultSelectedValue = []; let defaultSelectedValue = [];
if (value) {
const arbitrator = this.props.arbitrators.find(x => x === value);
defaultSelectedValue.push(arbitrator);
}
const arbitratorStrings = this.props.arbitrators.map(arbitratorAddr => { const arbitratorStrings = this.props.arbitrators.map((arbitratorAddr, index) => {
const user = this.props.users[arbitratorAddr]; const user = this.props.users[arbitratorAddr];
let text;
if (!user) { if (!user) {
return arbitratorAddr + ' - Loading...'; text = arbitratorAddr + ' - Loading...';
} else {
text = `${index} - ${user.username || compactAddress(arbitratorAddr, 3)}${user.location ? ' from ' + user.location : ''} - ${user.upCount || 0}${user.downCount || 0}`;
} }
return `${user.username || compactAddress(arbitratorAddr, 3)}${user.location ? ' from ' + user.location : ''} - ${user.upCount || 0}${user.downCount || 0}`; if (value && value === arbitratorAddr) {
defaultSelectedValue.push(text);
}
return text;
}); });
return ( return (
@ -46,7 +42,6 @@ class ArbitratorSelectorForm extends Component {
onChange={this.onChange} onChange={this.onChange}
options={arbitratorStrings} options={arbitratorStrings}
placeholder={t("arbitratorSelectorForm.placeholder")} placeholder={t("arbitratorSelectorForm.placeholder")}
onInputChange={this.onInputChange}
submitFormOnEnter={true} submitFormOnEnter={true}
emptyLabel={t("arbitratorSelectorForm.emptyLabel")} emptyLabel={t("arbitratorSelectorForm.emptyLabel")}
defaultSelected={defaultSelectedValue} defaultSelected={defaultSelectedValue}

View File

@ -1,92 +0,0 @@
import React from 'react';
import {storiesOf} from '@storybook/react';
import {withInfo} from "@storybook/addon-info";
import {action} from '@storybook/addon-actions';
import moment from 'moment';
import ArbitrationList from '../../src/js/components/tmp/ArbitrationList';
global.web3 = {
eth: {
defaultAccount: '0xBa31E1a4Ce37FE67DcAEa7950D379CB89A36867d'
}
};
const escrows = [
{
escrowId: 0,
buyer: '0xBa31E1a4Ce37FE67DcAEa7950D379CB89A36867d',
seller: '0xB8D851486d1C953e31A44374ACa11151D49B8bb3',
amount: 8,
arbitration: {open: true, result: "0", openBy: "0xBa31E1a4Ce37FE67DcAEa7950D379CB89A36867d" },
expirationTime: moment(Date.now() - 60000),
rating: 0,
paid: true,
released: false,
canceled: false
},
{
escrowId: 0,
buyer: '0xBa31E1a4Ce37FE67DcAEa7950D379CB89A36867d',
seller: '0xB8D851486d1C953e31A44374ACa11151D49B8bb3',
amount: 8,
arbitration: {open: true, result: "1"},
expirationTime: moment(Date.now() - 60000),
rating: 0,
paid: true,
released: false,
canceled: false
},
{
escrowId: 0,
buyer: '0xBa31E1a4Ce37FE67DcAEa7950D379CB89A36867d',
seller: '0xB8D851486d1C953e31A44374ACa11151D49B8bb3',
amount: 8,
arbitration: {open: true, result: "2"},
expirationTime: moment(Date.now() - 60000),
rating: 0,
paid: true,
released: false,
canceled: false
}
];
const info = {inline: true};
storiesOf('tmp/ArbitrationList', module)
.add(
"List with disputes",
withInfo(info)(() => (
<ArbitrationList escrows={escrows} resolveDispute={action("resolve-dispute")}
loading={false} error={false}/>
))
)
.add(
"Loading List",
withInfo(info)(() => (
<ArbitrationList escrows={escrows} resolveDispute={action("resolve-dispute")}
loading={true} error={false}/>
))
)
.add(
"Loading List + Hash",
withInfo(info)(() => (
<ArbitrationList escrows={escrows} resolveDispute={action("resolve-dispute")}
loading={true} error={false} txHash="0xd152ad280723b7b275ff4da1eb8afa09e99077beef253a387f7bc1c61e826230"/>
))
)
.add(
"Error doing something",
withInfo(info)(() => (
<ArbitrationList escrows={escrows} resolveDispute={action("resolve-dispute")}
loading={false} error="This is an error message"/>
))
)
.add(
"Empty list",
withInfo(info)(() => (
<ArbitrationList escrows={[]} resolveDispute={action("resolve-dispute")}
loading={false} error={false}/>
))
);

View File

@ -1,41 +0,0 @@
import React from 'react';
import {storiesOf} from '@storybook/react';
import {withInfo} from "@storybook/addon-info";
import {action} from '@storybook/addon-actions';
import CreateEscrowForm from '../../src/js/components/tmp/CreateEscrowForm';
const info = {inline: true, propTables: [CreateEscrowForm.WrappedComponent]};
storiesOf('tmp/CreateEscrowForm', module)
.add(
"Empty Form",
withInfo(info)(() => (
<CreateEscrowForm create={action("create-escrow")} result={null} error=""/>
))
)
.add(
"Loading Form",
withInfo(info)(() => (
<CreateEscrowForm create={action("create-escrow")} result={null} error="" isLoading={true}/>
))
)
.add(
"Loading Form + Tx Hash",
withInfo(info)(() => (
<CreateEscrowForm create={action("create-escrow")} result={null} error="" isLoading={true}
txHash="0xd152ad280723b7b275ff4da1eb8afa09e99077beef253a387f7bc1c61e826230"/>
))
)
.add(
"Form with error",
withInfo(info)(() => (
<CreateEscrowForm create={action("create-escrow")} result={null} error="Error while creating"/>
))
)
.add(
"Form with result",
withInfo(info)(() => (
<CreateEscrowForm create={action("create-escrow")} result={{id: 0, value: 'very good'}} error=""/>
))
);

View File

@ -1,157 +0,0 @@
import React from 'react';
import {storiesOf} from '@storybook/react';
import {withInfo} from "@storybook/addon-info";
import {action} from '@storybook/addon-actions';
import cloneDeep from 'clone-deep';
import moment from 'moment';
import EscrowList from '../../src/js/components/tmp/EscrowList';
global.web3 = {
eth: {
defaultAccount: '0xBa31E1a4Ce37FE67DcAEa7950D379CB89A36867d'
}
};
const escrows = [
{
escrowId: 0,
buyer: '0xBa31E1a4Ce37FE67DcAEa7950D379CB89A36867d',
seller: '0xB8D851486d1C953e31A44374ACa11151D49B8bb3',
amount: 5,
expirationTime: moment(Date.now() + 60000),
rating: 4,
released: true,
canceled: false,
paid: false
},
{
escrowId: 1,
buyer: '0xBa31E1a4Ce37FE67DcAEa7950D379CB89A36867d',
seller: '0xB8D851486d1C953e31A44374ACa11151D49B8bb3',
amount: 6,
expirationTime: moment(Date.now() + 60000),
rating: 0,
released: false,
canceled: false,
paid: false
},
{
escrowId: 2,
buyer: '0xBa31E1a4Ce37FE67DcAEa7950D379CB89A36867d',
seller: '0xB8D851486d1C953e31A44374ACa11151D49B8bb3',
amount: 2,
expirationTime: moment(Date.now() - 60000),
rating: 0,
released: false,
canceled: false,
paid: false
},
{
escrowId: 3,
buyer: '0xBa31E1a4Ce37FE67DcAEa7950D379CB89A36867d',
seller: '0xB8D851486d1C953e31A44374ACa11151D49B8bb3',
amount: 2,
expirationTime: moment(Date.now() - 60000),
rating: 0,
released: false,
canceled: false,
paid: true
},
{
escrowId: 4,
buyer: '0xBa31E1a4Ce37FE67DcAEa7950D379CB89A36867d',
seller: '0xB8D851486d1C953e31A44374ACa11151D49B8bb3',
amount: 8,
expirationTime: moment(Date.now() - 60000),
rating: 0,
released: false,
canceled: true,
paid: false
},
{
escrowId: 5,
buyer: '0xBa31E1a4Ce37FE67DcAEa7950D379CB89A36867d',
seller: '0xB8D851486d1C953e31A44374ACa11151D49B8bb3',
amount: 8,
arbitration: {open: true, result: "0"},
expirationTime: moment(Date.now() - 60000),
rating: 0,
paid: true,
released: false,
canceled: false
},
{
escrowId: 6,
buyer: '0xBa31E1a4Ce37FE67DcAEa7950D379CB89A36867d',
seller: '0xB8D851486d1C953e31A44374ACa11151D49B8bb3',
amount: 8,
arbitration: {open: true, result: "1"},
expirationTime: moment(Date.now() - 60000),
rating: 0,
paid: true,
released: false,
canceled: false
}
];
const sellerEscrows = cloneDeep(escrows);
sellerEscrows.forEach(escrow => {
const buyer = escrow.buyer;
escrow.buyer = escrow.seller;
escrow.seller = buyer;
});
const info = {inline: true, propTables: [EscrowList.WrappedComponent]};
storiesOf('tmp/EscrowList', module)
.add(
"Buyer List",
withInfo(info)(() => (
<EscrowList escrows={escrows} releaseEscrow={action("release-escrow")}
cancelEscrow={action("cancel-escrow")} rateTransaction={action("rate-escrow")}
loading={false} error={false}/>
))
)
.add(
"Seller List",
withInfo(info)(() => (
<EscrowList escrows={sellerEscrows} releaseEscrow={action("release-escrow")}
cancelEscrow={action("cancel-escrow")} rateTransaction={action("rate-escrow")}
loading={false} error={false}/>
))
)
.add(
"Loading List",
withInfo(info)(() => (
<EscrowList escrows={[]} releaseEscrow={action("release-escrow")}
cancelEscrow={action("cancel-escrow")} rateTransaction={action("rate-escrow")}
loading={true} error={false}/>
))
)
.add(
"Error doing something",
withInfo(info)(() => (
<EscrowList escrows={escrows} releaseEscrow={action("release-escrow")}
cancelEscrow={action("cancel-escrow")} rateTransaction={action("rate-escrow")}
loading={false} error="Error releasing or something"/>
))
)
.add(
"List with tx hash",
withInfo(info)(() => (
<EscrowList escrows={escrows} releaseEscrow={action("release-escrow")}
cancelEscrow={action("cancel-escrow")} rateTransaction={action("rate-escrow")}
loading={false} error="" txHash="0xd152ad280723b7b275ff4da1eb8afa09e99077beef253a387f7bc1c61e826230"/>
))
)
.add(
"Empty list",
withInfo(info)(() => (
<EscrowList escrows={[]} releaseEscrow={action("release-escrow")}
cancelEscrow={action("cancel-escrow")} rateTransaction={action("rate-escrow")}
loading={false} error={false}/>
))
);

View File

@ -1,47 +0,0 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { withKnobs, number } from '@storybook/addon-knobs';
import { withInfo } from "@storybook/addon-info";
import { action } from '@storybook/addon-actions';
import License from '../../src/js/components/tmp/License';
const info = {inline: true, propTables: [License.WrappedComponent]};
const stories = storiesOf('tmp/License', module);
stories.addDecorator(withKnobs);
stories
.add(
"Display License",
withInfo(info)(() => (
<License buyLicense={action("buy-license")}/>
))
)
.add(
"Display License when already own one (no rating)",
withInfo({ inline: true })(() => (
<License isLicenseOwner/>
))
)
.add(
"Display License when already own one",
withInfo({ inline: true })(() => (
<License isLicenseOwner userRating={number('rating', '3')} />
))
)
.add(
"Buying License",
withInfo({ inline: true })(() => (
<License loading={true}/>
))
)
.add(
"Buying License with Hash",
withInfo({ inline: true })(() => (
<License loading={true} txHash="0xd152ad280723b7b275ff4da1eb8afa09e99077beef253a387f7bc1c61e826230"/>
))
);