Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

UI component updates #4010

Merged
merged 9 commits into from
Jan 5, 2017
Merged
2 changes: 1 addition & 1 deletion js/src/api/util/identity.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const TEST_ENV = process.env.NODE_ENV === 'test';

export function createIdentityImg (address, scale = 8) {
return TEST_ENV
? ''
? 'test-createIdentityImg'
: blockies({
seed: (address || '').toLowerCase(),
size: 8,
Expand Down
47 changes: 36 additions & 11 deletions js/src/ui/BlockStatus/blockStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

Expand All @@ -39,34 +40,58 @@ class BlockStatus extends Component {
if (!syncing) {
return (
<div className={ styles.blockNumber }>
{ blockNumber.toFormat() } best block
<FormattedMessage
id='ui.blockStatus.bestBlock'
defaultMessage='{blockNumber} best block'
values={ {
blockNumber: blockNumber.toFormat()
} } />
</div>
);
}

if (syncing.warpChunksAmount && syncing.warpChunksProcessed && !syncing.warpChunksAmount.eq(syncing.warpChunksProcessed)) {
return (
<div className={ styles.syncStatus }>
{ syncing.warpChunksProcessed.mul(100).div(syncing.warpChunksAmount).toFormat(2) }% warp restore
<FormattedMessage
id='ui.blockStatus.warpRestore'
defaultMessage='{percentage}% warp restore'
values={ {
percentage: syncing.warpChunksProcessed.mul(100).div(syncing.warpChunksAmount).toFormat(2)
} } />
</div>
);
}

let syncStatus = null;
let warpStatus = null;

if (syncing.blockGap) {
const [first, last] = syncing.blockGap;

warpStatus = (
<span>, { first.mul(100).div(last).toFormat(2) }% historic</span>
if (syncing.currentBlock && syncing.highestBlock) {
syncStatus = (
<span>
<FormattedMessage
id='ui.blockStatus.syncStatus'
defaultMessage='{currentBlock}/{highestBlock} syncing'
values={ {
currentBlock: syncing.currentBlock.toFormat(),
highestBlock: syncing.highestBlock.toFormat()
} } />
</span>
);
}

let syncStatus = null;
if (syncing.blockGap) {
const [first, last] = syncing.blockGap;

if (syncing && syncing.currentBlock && syncing.highestBlock) {
syncStatus = (
<span>{ syncing.currentBlock.toFormat() }/{ syncing.highestBlock.toFormat() } syncing</span>
warpStatus = (
<span>
<FormattedMessage
id='ui.blockStatus.warpStatus'
defaultMessage=', {percentage}% historic'
values={ {
percentage: first.mul(100).div(last).toFormat(2)
} } />
</span>
);
}

Expand Down
94 changes: 94 additions & 0 deletions js/src/ui/BlockStatus/blockStatus.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

import BigNumber from 'bignumber.js';
import { shallow } from 'enzyme';
import React from 'react';
import sinon from 'sinon';

import BlockStatus from './';

let component;

function createRedux (syncing = false, blockNumber = new BigNumber(123)) {
return {
dispatch: sinon.stub(),
subscribe: sinon.stub(),
getState: () => {
return {
nodeStatus: {
blockNumber,
syncing
}
};
}
};
}

function render (reduxStore = createRedux(), props) {
component = shallow(
<BlockStatus { ...props } />,
{ context: { store: reduxStore } }
).find('BlockStatus').shallow();

return component;
}

describe('ui/BlockStatus', () => {
it('renders defaults', () => {
expect(render()).to.be.ok;
});

it('renders null with no blockNumber', () => {
expect(render(createRedux(false, null)).find('div')).to.have.length(0);
});

it('renders only the best block when syncing === false', () => {
const messages = render().find('FormattedMessage');

expect(messages).to.have.length(1);
expect(messages).to.have.id('ui.blockStatus.bestBlock');
});

it('renders only the warp restore status when restoring', () => {
const messages = render(createRedux({
warpChunksAmount: new BigNumber(100),
warpChunksProcessed: new BigNumber(5)
})).find('FormattedMessage');

expect(messages).to.have.length(1);
expect(messages).to.have.id('ui.blockStatus.warpRestore');
});

it('renders the current/highest when syncing', () => {
const messages = render(createRedux({
currentBlock: new BigNumber(123),
highestBlock: new BigNumber(456)
})).find('FormattedMessage');

expect(messages).to.have.length(1);
expect(messages).to.have.id('ui.blockStatus.syncStatus');
});

it('renders warp blockGap when catching up', () => {
const messages = render(createRedux({
blockGap: [new BigNumber(123), new BigNumber(456)]
})).find('FormattedMessage');

expect(messages).to.have.length(1);
expect(messages).to.have.id('ui.blockStatus.warpStatus');
});
});
10 changes: 7 additions & 3 deletions js/src/ui/Button/button.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ import { shallow } from 'enzyme';

import Button from './button';

function renderShallow (props) {
function render (props = {}) {
if (props && props.label === undefined) {
props.label = 'test';
}

return shallow(
<Button { ...props } />
);
Expand All @@ -28,11 +32,11 @@ function renderShallow (props) {
describe('ui/Button', () => {
describe('rendering', () => {
it('renders defaults', () => {
expect(renderShallow()).to.be.ok;
expect(render()).to.be.ok;
});

it('renders with the specified className', () => {
expect(renderShallow({ className: 'testClass' })).to.have.className('testClass');
expect(render({ className: 'testClass' })).to.have.className('testClass');
});
});
});
29 changes: 20 additions & 9 deletions js/src/ui/ConfirmDialog/confirmDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,27 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

import React, { Component, PropTypes } from 'react';
import ActionDone from 'material-ui/svg-icons/action/done';
import ContentClear from 'material-ui/svg-icons/content/clear';
import { FormattedMessage } from 'react-intl';

import { nodeOrStringProptype } from '~/util/proptypes';

import Button from '../Button';
import Modal from '../Modal';
import { CancelIcon, CheckIcon } from '../Icons';

import styles from './confirmDialog.css';

const DEFAULT_NO = (
<FormattedMessage
id='ui.confirmDialog.no'
defaultMessage='no' />
);
const DEFAULT_YES = (
<FormattedMessage
id='ui.confirmDialog.yes'
defaultMessage='yes' />
);

export default class ConfirmDialog extends Component {
static propTypes = {
children: PropTypes.node.isRequired,
Expand All @@ -33,10 +44,10 @@ export default class ConfirmDialog extends Component {
iconDeny: PropTypes.node,
labelConfirm: PropTypes.string,
labelDeny: PropTypes.string,
title: nodeOrStringProptype().isRequired,
visible: PropTypes.bool.isRequired,
onConfirm: PropTypes.func.isRequired,
onDeny: PropTypes.func.isRequired
onDeny: PropTypes.func.isRequired,
title: nodeOrStringProptype().isRequired,
visible: PropTypes.bool.isRequired
}

render () {
Expand All @@ -60,12 +71,12 @@ export default class ConfirmDialog extends Component {

return [
<Button
label={ labelDeny || 'no' }
icon={ iconDeny || <ContentClear /> }
icon={ iconDeny || <CancelIcon /> }
label={ labelDeny || DEFAULT_NO }
onClick={ onDeny } />,
<Button
label={ labelConfirm || 'yes' }
icon={ iconConfirm || <ActionDone /> }
icon={ iconConfirm || <CheckIcon /> }
label={ labelConfirm || DEFAULT_YES }
onClick={ onConfirm } />
];
}
Expand Down
Loading