From 56aef9398b2a6213a75d5a13ebd06386cbee735e Mon Sep 17 00:00:00 2001 From: kwingram25 Date: Mon, 8 Apr 2019 05:01:20 -0700 Subject: [PATCH] Add BondedRx component & display bonded value, refactor RecentlyOffline (#923) * recently offline on own accounts * wip bonded display * RxBonded component * travis-ci * import mistake * redo * RRemove balance (overview) & index (accounts) * Remove session.validators * Re-add displaying only the last offline block * Small setState cleanup (+ State in generic) --- packages/app-accounts/src/Creator.tsx | 1 + packages/app-addresses/src/Creator.tsx | 1 + packages/app-addresses/src/Editor.tsx | 1 + packages/app-staking/src/Account/index.tsx | 8 ++- packages/app-staking/src/Overview/Address.tsx | 39 +++--------- packages/app-staking/src/Overview/index.css | 41 ------------- packages/app-staking/src/RecentlyOffline.tsx | 60 +++++++++++++++++++ packages/app-staking/src/index.css | 45 ++++++++++++++ packages/ui-app/src/AddressMini.tsx | 21 ++++++- packages/ui-app/src/AddressRow.tsx | 2 +- packages/ui-app/src/AddressSummary.tsx | 25 +++++--- packages/ui-app/src/Bonded.tsx | 35 +++++++++++ packages/ui-app/src/styles/components.css | 14 ++++- packages/ui-reactive/src/Bonded.tsx | 51 ++++++++++++++++ 14 files changed, 257 insertions(+), 87 deletions(-) create mode 100644 packages/app-staking/src/RecentlyOffline.tsx create mode 100644 packages/ui-app/src/Bonded.tsx create mode 100644 packages/ui-reactive/src/Bonded.tsx diff --git a/packages/app-accounts/src/Creator.tsx b/packages/app-accounts/src/Creator.tsx index 2c30a24cfe..2f7bfc59ae 100644 --- a/packages/app-accounts/src/Creator.tsx +++ b/packages/app-accounts/src/Creator.tsx @@ -110,6 +110,7 @@ class Creator extends React.PureComponent { ? address : '' } + withBonded /> {this.renderInput()} diff --git a/packages/app-addresses/src/Creator.tsx b/packages/app-addresses/src/Creator.tsx index 766d84ad05..7ba70511f2 100644 --- a/packages/app-addresses/src/Creator.tsx +++ b/packages/app-addresses/src/Creator.tsx @@ -43,6 +43,7 @@ class Creator extends React.PureComponent { {this.renderInput()} diff --git a/packages/app-addresses/src/Editor.tsx b/packages/app-addresses/src/Editor.tsx index ded909b50c..38be2e2cdc 100644 --- a/packages/app-addresses/src/Editor.tsx +++ b/packages/app-addresses/src/Editor.tsx @@ -93,6 +93,7 @@ class Editor extends React.PureComponent {
diff --git a/packages/app-staking/src/Account/index.tsx b/packages/app-staking/src/Account/index.tsx index b9ed20c3c1..19f8553c4e 100644 --- a/packages/app-staking/src/Account/index.tsx +++ b/packages/app-staking/src/Account/index.tsx @@ -91,6 +91,9 @@ class Account extends React.PureComponent { name={name} value={accountId} identIconSize={96} + withBonded + withIndex={false} + withNonce={false} >
{this.renderButtons()} @@ -205,7 +208,8 @@ class Account extends React.PureComponent { )) } @@ -280,7 +284,7 @@ class Account extends React.PureComponent { return (
- +
); } diff --git a/packages/app-staking/src/Overview/Address.tsx b/packages/app-staking/src/Overview/Address.tsx index 4436f5dc97..5a22c02f54 100644 --- a/packages/app-staking/src/Overview/Address.tsx +++ b/packages/app-staking/src/Overview/Address.tsx @@ -6,13 +6,14 @@ import { DerivedBalancesMap } from '@polkadot/api-derive/types'; import { I18nProps } from '@polkadot/ui-app/types'; import { Nominators, RecentlyOfflineMap } from '../types'; -import BN from 'bn.js'; import React from 'react'; import { AccountId, Balance, Option, StakingLedger } from '@polkadot/types'; import { withCalls, withMulti } from '@polkadot/ui-api/with'; import { AddressMini, AddressRow } from '@polkadot/ui-app'; import keyring from '@polkadot/ui-keyring'; -import { formatBalance, formatNumber } from '@polkadot/util'; +import { formatBalance } from '@polkadot/util'; + +import RecentlyOffline from '../RecentlyOffline'; import translate from '../translate'; @@ -88,6 +89,8 @@ class Address extends React.PureComponent { extraInfo={stashActive ? `bonded ${stashActive}` : undefined} name={this.getDisplayName()} value={stashId} + withBalance={false} + withBonded withCopy={false} withNonce={false} > @@ -122,12 +125,6 @@ class Address extends React.PureComponent { : defaultName; } - private toggleBadge = (): void => { - const { badgeExpanded } = this.state; - - this.setState({ badgeExpanded: !badgeExpanded }); - } - private renderKeys () { const { t } = this.props; const { bondedId, sessionId } = this.state; @@ -180,7 +177,7 @@ class Address extends React.PureComponent { )} @@ -188,35 +185,17 @@ class Address extends React.PureComponent { } private renderOffline () { - const { recentlyOffline, t } = this.props; - const { badgeExpanded, stashId } = this.state; + const { recentlyOffline } = this.props; + const { stashId } = this.state; if (!stashId || !recentlyOffline[stashId]) { return null; } const offline = recentlyOffline[stashId]; - const count = offline.reduce((total, { count }) => total.add(count), new BN(0)); - - const blockNumbers = offline.map(({ blockNumber }) => `#${formatNumber(blockNumber)}`); return ( -
-
- {count.toString()} -
-
- {t('Reported offline {{count}} times, last at {{blockNumber}}', { - replace: { - count: count.toString(), - blockNumber: blockNumbers[blockNumbers.length - 1] - } - })} -
-
+ ); } } diff --git a/packages/app-staking/src/Overview/index.css b/packages/app-staking/src/Overview/index.css index 5049ba64d1..aef55af1c1 100644 --- a/packages/app-staking/src/Overview/index.css +++ b/packages/app-staking/src/Overview/index.css @@ -85,48 +85,7 @@ } .recentlyOffline { - position: absolute; - bottom: 0.75rem; - font-size: 12px; - cursor: help; - display: flex; - justify-content: center; - right: 0.75rem; - width: 22px; - height: 22px; - padding: 0; - background: red; - color: #eee; - border-radius: 16px; - box-shadow: 0 3px 3px rgba(0, 0, 0, 0.2); - transition: all ease .2s; - & > * { - line-height: 22px; - overflow: hidden; - transition: all ease 0.25; - } - - .badge { - font-weight: bold; - width: auto; - } - - .detail { - width: 0; - } - - &.expand { - width: 300px; - - .badge { - width: 0; - } - - .detail { - width: auto; - } - } } } } diff --git a/packages/app-staking/src/RecentlyOffline.tsx b/packages/app-staking/src/RecentlyOffline.tsx new file mode 100644 index 0000000000..11163c29b4 --- /dev/null +++ b/packages/app-staking/src/RecentlyOffline.tsx @@ -0,0 +1,60 @@ +// Copyright 2017-2019 @polkadot/app-staking authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. +import { OfflineStatus } from './types'; +import { I18nProps } from '@polkadot/ui-app/types'; + +import BN from 'bn.js'; +import React from 'react'; +import { formatNumber } from '@polkadot/util'; + +import translate from './translate'; + +type Props = I18nProps & { + offline: Array +}; + +type State = { + isOpen: boolean +}; + +class RecentlyOffline extends React.PureComponent { + state: State = { + isOpen: false + }; + + render () { + const { offline, t } = this.props; + const { isOpen } = this.state; + + const count = offline.reduce((total, { count }) => total.add(count), new BN(0)); + const blockNumbers = offline.map(({ blockNumber }) => `#${formatNumber(blockNumber)}`); + + return ( +
+
+ {count.toString()} +
+
+ {t('Reported offline {{count}} times, last at {{blockNumber}}', { + replace: { + count, + blockNumber: blockNumbers[blockNumbers.length - 1] + } + })} +
+
+ ); + } + + private toggleOpen = (): void => { + this.setState(({ isOpen }) => ({ + isOpen: !isOpen + })); + } +} + +export default translate(RecentlyOffline); diff --git a/packages/app-staking/src/index.css b/packages/app-staking/src/index.css index 1cec8a98c7..5334021f98 100644 --- a/packages/app-staking/src/index.css +++ b/packages/app-staking/src/index.css @@ -131,3 +131,48 @@ margin-bottom: -0.5rem; } } + +.staking--Account-recentlyOffline { + position: absolute; + bottom: 0.75rem; + font-size: 12px; + cursor: help; + display: flex; + justify-content: center; + right: 0.75rem; + width: 22px; + height: 22px; + padding: 0; + background: red; + color: #eee; + border-radius: 16px; + box-shadow: 0 3px 3px rgba(0, 0, 0, 0.2); + transition: all ease .2s; + + & > * { + line-height: 22px; + overflow: hidden; + transition: all ease 0.25; + } + + .badge { + font-weight: bold; + width: auto; + } + + .detail { + width: 0; + } + + &.expand { + width: 300px; + + .badge { + width: 0; + } + + .detail { + width: auto; + } + } +} diff --git a/packages/ui-app/src/AddressMini.tsx b/packages/ui-app/src/AddressMini.tsx index 3e2db6c576..0fcbb7f344 100644 --- a/packages/ui-app/src/AddressMini.tsx +++ b/packages/ui-app/src/AddressMini.tsx @@ -10,6 +10,7 @@ import { AccountId, AccountIndex, Address, Balance } from '@polkadot/types'; import { classes, toShortAddress } from './util'; import BalanceDisplay from './Balance'; +import BondedDisplay from './Bonded'; import IdentityIcon from './IdentityIcon'; type Props = BareProps & { @@ -19,7 +20,8 @@ type Props = BareProps & { isShort?: boolean, value?: AccountId | AccountIndex | Address | string, withAddress?: boolean, - withBalance?: boolean + withBalance?: boolean, + withBonded?: boolean }; export default class AddressMini extends React.PureComponent { @@ -46,6 +48,7 @@ export default class AddressMini extends React.PureComponent { {children}
{this.renderBalance()} + {this.renderBonded()}
); } @@ -77,4 +80,20 @@ export default class AddressMini extends React.PureComponent { /> ); } + + private renderBonded () { + const { value, withBonded = false } = this.props; + + if (!withBonded || !value) { + return null; + } + + return ( + + ); + } } diff --git a/packages/ui-app/src/AddressRow.tsx b/packages/ui-app/src/AddressRow.tsx index 1e203f3ab0..ec1d8de8e6 100644 --- a/packages/ui-app/src/AddressRow.tsx +++ b/packages/ui-app/src/AddressRow.tsx @@ -23,7 +23,7 @@ class AddressRow extends AddressSummary {
{this.renderAddress()} {this.renderBalance()} - {this.renderExtra()} + {this.renderBonded()} {this.renderNonce()}
diff --git a/packages/ui-app/src/AddressSummary.tsx b/packages/ui-app/src/AddressSummary.tsx index 5bb6afcc58..8d66956357 100644 --- a/packages/ui-app/src/AddressSummary.tsx +++ b/packages/ui-app/src/AddressSummary.tsx @@ -12,17 +12,20 @@ import BaseIdentityIcon from '@polkadot/ui-identicon'; import { classes, toShortAddress } from './util'; import BalanceDisplay from './Balance'; +import BondedDisplay from './Bonded'; import IdentityIcon from './IdentityIcon'; import translate from './translate'; export type Props = I18nProps & { accounts_idAndIndex?: [AccountId?, AccountIndex?], balance?: Balance | Array, + bonded?: Balance | Array, children?: React.ReactNode, extraInfo?: React.ReactNode, name?: string, value: AccountId | AccountIndex | Address | string | null, withBalance?: boolean, + withBonded?: boolean, withIndex?: boolean, identIconSize?: number, isShort?: boolean, @@ -50,7 +53,7 @@ class AddressSummary extends React.PureComponent { {this.renderAccountId()} {this.renderAccountIndex()} {this.renderBalance()} - {this.renderExtra()} + {this.renderBonded()} {this.renderNonce()} {this.renderChildren()} @@ -113,10 +116,10 @@ class AddressSummary extends React.PureComponent { } protected renderAccountIndex () { - const { accounts_idAndIndex = [] } = this.props; + const { accounts_idAndIndex = [], withIndex = true } = this.props; const [, accountIndex] = accounts_idAndIndex; - if (!accountIndex) { + if (!accountIndex || !withIndex) { return null; } @@ -151,17 +154,21 @@ class AddressSummary extends React.PureComponent { ); } - protected renderExtra () { - const { extraInfo } = this.props; + protected renderBonded () { + const { accounts_idAndIndex = [], t, value, withBonded } = this.props; + const [_accountId] = accounts_idAndIndex; + const accountId = _accountId || value; - if (!extraInfo) { + if (!withBonded || !accountId) { return null; } return ( -
- {extraInfo} -
+ ); } diff --git a/packages/ui-app/src/Bonded.tsx b/packages/ui-app/src/Bonded.tsx new file mode 100644 index 0000000000..1682ace296 --- /dev/null +++ b/packages/ui-app/src/Bonded.tsx @@ -0,0 +1,35 @@ +// Copyright 2017-2019 @polkadot/ui-app authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { BareProps } from './types'; + +import React from 'react'; +import { AccountId, AccountIndex, Address } from '@polkadot/types'; +import RxBonded from '@polkadot/ui-reactive/Bonded'; + +import { classes } from './util'; + +export type Props = BareProps & { + label?: string, + value?: AccountId | AccountIndex | Address | string | Uint8Array | null, + withLabel?: boolean +}; + +export default class BondedDisplay extends React.PureComponent { + render () { + const { value, className, label, style } = this.props; + if (!value) { + return null; + } + + return ( + + ); + } +} diff --git a/packages/ui-app/src/styles/components.css b/packages/ui-app/src/styles/components.css index 3f2c6de3d1..575155e546 100644 --- a/packages/ui-app/src/styles/components.css +++ b/packages/ui-app/src/styles/components.css @@ -63,7 +63,8 @@ header .ui--Button-Group { margin-right: 0.5rem; } -.ui--AddressMini .ui--Balance { +.ui--AddressMini .ui--Balance, +.ui--AddressMini .ui--Bonded { font-size: 0.75rem; margin-top: -0.5rem; text-align: right; @@ -113,13 +114,20 @@ header .ui--Button-Group { .ui--Balance, .ui--AddressSummary-balance, -.ui--AddressSummary-extra, +.ui--AddressSummary-bonded, .ui--AddressSummary-nonce { font-weight: 100; opacity: 0.75; } -.ui--AddressSummary-balance { +.ui--Bonded { + opacity: 1; + color: green; +} + +.ui--AddressSummary-data+.ui--AddressSummary-balance, +.ui--AddressSummary-data+.ui--AddressSummary-bonded, +.ui--AddressSummary-data+.ui--AddressSummary-nonce { padding-top: 0.5em; } diff --git a/packages/ui-reactive/src/Bonded.tsx b/packages/ui-reactive/src/Bonded.tsx new file mode 100644 index 0000000000..32ece35e74 --- /dev/null +++ b/packages/ui-reactive/src/Bonded.tsx @@ -0,0 +1,51 @@ +// Copyright 2017-2019 @polkadot/ui-reactive authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { AccountId, AccountIndex, Address, Option, StakingLedger } from '@polkadot/types'; +import { BareProps, CallProps } from '@polkadot/ui-api/types'; + +import React from 'react'; + +import { withCalls } from '@polkadot/ui-api'; +import { formatBalance } from '@polkadot/util'; + +type Props = BareProps & CallProps & { + children?: React.ReactNode, + value?: AccountId | AccountIndex | Address | string | Uint8Array | null, + label?: string, + staking_ledger?: Option +}; + +class BondedDisplay extends React.PureComponent { + render () { + const { children, className, label = '', style, staking_ledger } = this.props; + + if (!staking_ledger || staking_ledger.isNone) { + return null; + } + + const { active: bonded } = staking_ledger.unwrap(); + + return ( +
+ {label}{ + bonded + ? formatBalance(bonded) + : '0' + }{children} +
+ ); + } +} + +export default withCalls( + ['query.staking.bonded', { + paramName: 'value', + transform: (value) => value.unwrapOr(null) + }], + ['query.staking.ledger', { paramName: 'staking_bonded' }] +)(BondedDisplay);