Adjust staking overview display (#312)
This commit is contained in:
parent
82be7d8905
commit
935b28c9b9
@ -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
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -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>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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')
|
||||||
|
);
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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(', ')})`;
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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(
|
||||||
[
|
[
|
||||||
|
|||||||
@ -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>,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user