Adjust staking overview display (#312)

This commit is contained in:
Jaco Greeff 2018-09-14 15:20:15 +02:00 committed by GitHub
parent 82be7d8905
commit 935b28c9b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 144 additions and 64 deletions

View File

@ -18,34 +18,29 @@ type Props = I18nProps & {
sessionBlockProgress?: BN, sessionBlockProgress?: BN,
sessionBrokenValue?: BN, sessionBrokenValue?: BN,
sessionBrokenPercentLate?: BN, sessionBrokenPercentLate?: BN,
sessionLength?: BN sessionLength?: BN,
withBroken?: boolean,
withEra?: boolean,
withSession?: boolean
}; };
class SummarySession extends React.PureComponent<Props> { class SummarySession extends React.PureComponent<Props> {
render () { render () {
const { eraBlockLength, eraBlockProgress, sessionBlockProgress, sessionBrokenValue, sessionBrokenPercentLate, sessionLength, t } = this.props;
return [ return [
<CardSummary this.renderSession(),
key='sessionProgress' this.renderEra(),
label={t('summary.sessionProgress', { this.renderBroken()
defaultValue: 'session' ];
})} }
progress={{
total: sessionLength, private renderBroken () {
value: sessionBlockProgress const { sessionBrokenValue, sessionBrokenPercentLate, t, withBroken = true } = this.props;
}}
/>, if (!withBroken) {
<CardSummary return null;
key='eraProgress' }
label={t('summary.eraProgress', {
defaultValue: 'era' return (
})}
progress={{
total: eraBlockLength,
value: eraBlockProgress
}}
/>,
<CardSummary <CardSummary
key='brokenCount' key='brokenCount'
label={t('summary.brokenCount', { label={t('summary.brokenCount', {
@ -58,7 +53,49 @@ class SummarySession extends React.PureComponent<Props> {
value: sessionBrokenValue value: sessionBrokenValue
}} }}
/> />
]; );
}
private renderEra () {
const { eraBlockLength, eraBlockProgress, t, withEra = true } = this.props;
if (!withEra) {
return null;
}
return (
<CardSummary
key='eraProgress'
label={t('summary.eraProgress', {
defaultValue: 'era'
})}
progress={{
total: eraBlockLength,
value: eraBlockProgress
}}
/>
);
}
private renderSession () {
const { sessionBlockProgress, sessionLength, t, withSession = true } = this.props;
if (!withSession) {
return null;
}
return (
<CardSummary
key='sessionProgress'
label={t('summary.sessionProgress', {
defaultValue: 'session'
})}
progress={{
total: sessionLength,
value: sessionBlockProgress
}}
/>
);
} }
} }

View File

@ -11,7 +11,7 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.0.0", "@babel/runtime": "^7.0.0",
"@polkadot/app-extrinsics": "^0.20.8", "@polkadot/app-explorer": "^0.20.8",
"@polkadot/storage": "^0.28.35", "@polkadot/storage": "^0.28.35",
"@polkadot/ui-app": "^0.20.8", "@polkadot/ui-app": "^0.20.8",
"@polkadot/ui-keyring": "^0.20.8", "@polkadot/ui-keyring": "^0.20.8",

View File

@ -5,6 +5,7 @@
import { I18nProps } from '@polkadot/ui-app/types'; import { I18nProps } from '@polkadot/ui-app/types';
import { RxBalanceMap } from '@polkadot/ui-react-rx/ApiObservable/types'; import { RxBalanceMap } from '@polkadot/ui-react-rx/ApiObservable/types';
import BN from 'bn.js';
import React from 'react'; import React from 'react';
import AddressMini from '@polkadot/ui-app/AddressMini'; import AddressMini from '@polkadot/ui-app/AddressMini';
import AddressRow from '@polkadot/ui-app/AddressRow'; import AddressRow from '@polkadot/ui-app/AddressRow';
@ -34,12 +35,8 @@ class CurrentList extends React.PureComponent<Props> {
private renderCurrent () { private renderCurrent () {
const { current, t } = this.props; const { current, t } = this.props;
if (current.length === 0) {
return null;
}
return [ return [
<h1> <h1 key='header'>
{t('list.current', { {t('list.current', {
defaultValue: 'validators', defaultValue: 'validators',
replace: { replace: {
@ -47,51 +44,68 @@ class CurrentList extends React.PureComponent<Props> {
} }
})} })}
</h1>, </h1>,
...this.renderRow(current, t('name.validator', { defaultValue: 'validator' })) this.renderRow(current, t('name.validator', { defaultValue: 'validator' }))
]; ];
} }
private renderNext () { private renderNext () {
const { next, t } = this.props; const { next, t } = this.props;
if (next.length === 0) {
return null;
}
return [ return [
<h1> <h1 key='header'>
{t('list.next', { {t('list.next', {
defaultValue: 'next up' defaultValue: 'next up'
})} })}
</h1>, </h1>,
...this.renderRow(next, t('name.intention', { defaultValue: 'intention' })) this.renderRow(next, t('name.intention', { defaultValue: 'intention' }))
]; ];
} }
private renderRow (addresses: Array<string>, defaultName: string) { private renderRow (addresses: Array<string>, defaultName: string) {
const { balances, t } = this.props;
if (addresses.length === 0) {
return (
<div key='none'>{t('list.empty', {
defaultValue: 'no addresses found'
})}</div>
);
}
return (
<article key='list'>
{addresses.map((address) => {
const nominators = (balances[address] || {}).nominators || [];
return (
<AddressRow
balance={this.balanceArray(address)}
key={address}
name={name || defaultName}
value={address}
withCopy={false}
withNonce={false}
>
{nominators.map(({ address }) =>
<AddressMini
key={address}
value={address}
withBalance
/>
)}
</AddressRow>
);
})}
</article>
);
}
private balanceArray (address: string): Array<BN> | undefined {
const { balances } = this.props; const { balances } = this.props;
return addresses.map((address) => { return balances[address]
const nominators = (balances[address] || {}).nominators || []; ? [balances[address].stakingBalance, balances[address].nominatedBalance]
: undefined;
return (
<article key={address}>
<AddressRow
name={name || defaultName}
value={address}
withCopy={false}
withNonce={false}
>
{nominators.map(({ address }) =>
<AddressMini
key={address}
value={address}
/>
)}
</AddressRow>
</article>
);
});
} }
} }

View File

@ -9,6 +9,9 @@ import BN from 'bn.js';
import React from 'react'; import React from 'react';
import CardSummary from '@polkadot/ui-app/CardSummary'; import CardSummary from '@polkadot/ui-app/CardSummary';
import numberFormat from '@polkadot/ui-react-rx/util/numberFormat'; import numberFormat from '@polkadot/ui-react-rx/util/numberFormat';
import SummarySession from '@polkadot/app-explorer/SummarySession';
import withObservable from '@polkadot/ui-react-rx/with/observable';
import withMulti from '@polkadot/ui-react-rx/with/multi';
import translate from '../translate'; import translate from '../translate';
@ -16,12 +19,13 @@ type Props = I18nProps & {
balances: RxBalanceMap, balances: RxBalanceMap,
intentions: Array<string>, intentions: Array<string>,
lastLengthChange?: BN, lastLengthChange?: BN,
validatorCount?: BN,
validators: Array<string> validators: Array<string>
}; };
class Summary extends React.PureComponent<Props> { class Summary extends React.PureComponent<Props> {
render () { render () {
const { className, intentions, style, t, validators } = this.props; const { className, intentions, style, t, validatorCount, validators } = this.props;
return ( return (
<summary <summary
@ -32,7 +36,7 @@ class Summary extends React.PureComponent<Props> {
<CardSummary label={t('summary.validators', { <CardSummary label={t('summary.validators', {
defaultValue: 'validators' defaultValue: 'validators'
})}> })}>
{validators.length} {validators.length}/{validatorCount ? validatorCount.toString() : '-'}
</CardSummary> </CardSummary>
<CardSummary label={t('summary.intentions', { <CardSummary label={t('summary.intentions', {
defaultValue: 'intentions' defaultValue: 'intentions'
@ -40,6 +44,9 @@ class Summary extends React.PureComponent<Props> {
{intentions.length} {intentions.length}
</CardSummary> </CardSummary>
</section> </section>
<section>
<SummarySession withBroken={false} />
</section>
<section> <section>
<CardSummary label={t('summary.balances', { <CardSummary label={t('summary.balances', {
defaultValue: 'balances' defaultValue: 'balances'
@ -109,4 +116,7 @@ class Summary extends React.PureComponent<Props> {
} }
} }
export default translate(Summary); export default withMulti(
translate(Summary),
withObservable('validatorCount')
);

View File

@ -58,6 +58,10 @@
.validator--next { .validator--next {
margin: 1em; margin: 1em;
flex: 1; flex: 1;
.ui--AddressRow + .ui--AddressRow {
margin-top: 1em;
}
} }
.validator--Account-address.isMine { .validator--Account-address.isMine {

View File

@ -4,6 +4,10 @@
.staking--App { .staking--App {
padding: 1em 2rem; padding: 1em 2rem;
.rx--updated {
background: transparent !important;
}
} }
.staking--App-navigation.ui--Button-Group { .staking--App-navigation.ui--Button-Group {

View File

@ -45,7 +45,9 @@ export default class Balance extends React.PureComponent<Props> {
if (Array.isArray(balance)) { if (Array.isArray(balance)) {
const totals = balance const totals = balance
.filter((value, index) => index !== 0) .filter((value, index) =>
index !== 0
)
.map(numberFormat); .map(numberFormat);
value = `${value} (${totals.length === 1 ? '+' : ''}${totals.join(', ')})`; value = `${value} (${totals.length === 1 ? '+' : ''}${totals.join(', ')})`;

View File

@ -40,7 +40,7 @@ header .ui--Button-Group {
.ui--AddressMini.padded { .ui--AddressMini.padded {
display: inline-block; display: inline-block;
padding: 0.25rem; padding: 0.25rem 0 0 0;
} }
.ui--AddressMini-info div { .ui--AddressMini-info div {
@ -93,6 +93,10 @@ header .ui--Button-Group {
vertical-align: top; vertical-align: top;
} }
.ui--AddressSummary-children {
padding-top: 0.5rem;
}
.ui--AddressSummary .rx--updated { .ui--AddressSummary .rx--updated {
background: transparent !important; background: transparent !important;
} }
@ -123,7 +127,7 @@ header .ui--Button-Group {
} }
.ui--AddressSummary-data * { .ui--AddressSummary-data * {
margin: 0 0.25rem !important; /* margin: 0 0.25rem !important; */
vertical-align: middle; vertical-align: middle;
} }

View File

@ -509,6 +509,10 @@ export default class ObservableApi implements ObservableApiInterface {
return this.rawStorage(storage.system.public.accountIndexOf, address); return this.rawStorage(storage.system.public.accountIndexOf, address);
} }
validatorCount = (): Observable<OptBN> => {
return this.rawStorage(storage.staking.public.validatorCount);
}
validatingBalance = (address: string): Observable<RxBalance> => { validatingBalance = (address: string): Observable<RxBalance> => {
return this.combine( return this.combine(
[ [

View File

@ -94,6 +94,7 @@ export interface ObservableApiInterface {
systemAccountIndexOf: (address: string) => Observable<BN | undefined>, systemAccountIndexOf: (address: string) => Observable<BN | undefined>,
timestampBlockPeriod: () => Observable<BN | undefined>, timestampBlockPeriod: () => Observable<BN | undefined>,
timestampNow: () => Observable<Date | undefined>, timestampNow: () => Observable<Date | undefined>,
validatorCount: () => Observable<BN | undefined>,
validatingBalance: (address: string) => Observable<RxBalance>, validatingBalance: (address: string) => Observable<RxBalance>,
validatingBalances: (...addresses: Array<string>) => Observable<RxBalanceMap>, validatingBalances: (...addresses: Array<string>) => Observable<RxBalanceMap>,
votingBalance: (address: string) => Observable<RxBalance>, votingBalance: (address: string) => Observable<RxBalance>,