From 4ff13924596cb208fc09a66dcc6e824cf403064f Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 20 Aug 2018 10:49:52 +0200 Subject: [PATCH] DRY Card display (CardBar component, consistency) (#235) * DRY Card display (CardBar component, consistency) * Use SummaryCard on staking * Simplify summaries (no duplication from explorer) * Display lateness percentage value --- packages/app-democracy/src/Summary.tsx | 12 +-- packages/app-democracy/src/index.css | 22 ------ packages/app-explorer/src/Main.tsx | 2 - packages/app-explorer/src/Summary.tsx | 73 ++++-------------- packages/app-explorer/src/SummarySession.tsx | 74 ++++++++++++++++++ packages/app-explorer/src/index.css | 18 ----- packages/app-staking/src/Summary.tsx | 80 ++++++++++---------- packages/app-staking/src/index.css | 7 ++ packages/ui-app/src/Balance.tsx | 5 +- packages/ui-app/src/CardBar.tsx | 46 +++++++++++ packages/ui-app/src/CardSummary.tsx | 19 ++++- packages/ui-app/src/styles/components.css | 22 ++++++ 12 files changed, 227 insertions(+), 153 deletions(-) create mode 100644 packages/app-explorer/src/SummarySession.tsx create mode 100644 packages/ui-app/src/CardBar.tsx diff --git a/packages/app-democracy/src/Summary.tsx b/packages/app-democracy/src/Summary.tsx index 4a0eef2fe9..74995ca33a 100644 --- a/packages/app-democracy/src/Summary.tsx +++ b/packages/app-democracy/src/Summary.tsx @@ -6,7 +6,7 @@ import { I18nProps } from '@polkadot/ui-app/types'; import BN from 'bn.js'; import React from 'react'; -import classes from '@polkadot/ui-app/util/classes'; +import CardBar from '@polkadot/ui-app/CardBar'; import CardSummary from '@polkadot/ui-app/CardSummary'; import withObservable from '@polkadot/ui-react-rx/with/observable'; import withMulti from '@polkadot/ui-react-rx/with/multi'; @@ -27,11 +27,11 @@ class Summary extends React.PureComponent { const { className, democracyLaunchPeriod, democracyNextTally = new BN(0), democracyProposalCount, democracyReferendumCount = new BN(0), democracyVotingPeriod, style, t } = this.props; return ( -
-
+
@@ -51,7 +51,7 @@ class Summary extends React.PureComponent { }
-
+
@@ -63,7 +63,7 @@ class Summary extends React.PureComponent { {numberFormat(democracyLaunchPeriod)}
-
+ ); } } diff --git a/packages/app-democracy/src/index.css b/packages/app-democracy/src/index.css index 3f3f86f7cc..06f6a1ac0f 100644 --- a/packages/app-democracy/src/index.css +++ b/packages/app-democracy/src/index.css @@ -6,28 +6,6 @@ margin-bottom: 1em; } -/* FIXME These are just copied as-is from staking/Summary - once happy and proven to be - shareable, it needs to be moved into ui-app for consistency. -*/ -.democracy--Summary { - align-items: stretch; - display: flex; - justify-content: space-between; - flex-wrap: wrap; - margin-bottom: 2em; -} - -.democracy--Summary-column { - display: flex; - flex: 0 1 auto; - text-align: left; -} - -.democracy--Summary-card { - flex: 0 1 auto; - text-align: left; -} - .democracy--Proposals, .democracy--Referendums { margin-bottom: 2rem; diff --git a/packages/app-explorer/src/Main.tsx b/packages/app-explorer/src/Main.tsx index 130864b6e3..1ceea7f9c2 100644 --- a/packages/app-explorer/src/Main.tsx +++ b/packages/app-explorer/src/Main.tsx @@ -6,7 +6,6 @@ import { BareProps } from '@polkadot/ui-app/types'; import React from 'react'; -import Query from './Query'; import Summary from './Summary'; import BlockHeaders from './BlockHeaders'; @@ -18,7 +17,6 @@ export default class Main extends React.PureComponent { render () { return [ , - , ]; } diff --git a/packages/app-explorer/src/Summary.tsx b/packages/app-explorer/src/Summary.tsx index 0b20fa90ad..befcaaf922 100644 --- a/packages/app-explorer/src/Summary.tsx +++ b/packages/app-explorer/src/Summary.tsx @@ -4,37 +4,32 @@ import { I18nProps } from '@polkadot/ui-app/types'; -import BN from 'bn.js'; import React from 'react'; -import classes from '@polkadot/ui-app/util/classes'; +import CardBar from '@polkadot/ui-app/CardBar'; import CardSummary from '@polkadot/ui-app/CardSummary'; import BestNumber from '@polkadot/ui-react-rx/BestNumber'; import TimePeriod from '@polkadot/ui-react-rx/TimePeriod'; import TimeNow from '@polkadot/ui-react-rx/TimeNow'; -import withObservable from '@polkadot/ui-react-rx/with/observable'; -import withMulti from '@polkadot/ui-react-rx/with/multi'; +import Query from './Query'; +import SummarySession from './SummarySession'; import translate from './translate'; -type Props = I18nProps & { - eraBlockLength?: BN, - eraBlockProgress?: BN, - sessionBlockProgress?: BN, - sessionBrokenValue?: BN, - sessionBrokenPercentLate?: BN, - sessionLength?: BN -}; +type Props = I18nProps & {}; class Summary extends React.PureComponent { render () { - const { className, eraBlockLength, eraBlockProgress, sessionBlockProgress, sessionBrokenValue, sessionBrokenPercentLate, sessionLength, style, t } = this.props; + const { className, style, t } = this.props; return ( -
+ } style={style} > -
+
@@ -46,55 +41,19 @@ class Summary extends React.PureComponent {
-
- - - +
+
-
+
-
+ ); } } -export default withMulti( - Summary, - translate, - withObservable('eraBlockLength'), - withObservable('eraBlockProgress'), - withObservable('sessionBlockProgress'), - withObservable('sessionBrokenValue'), - withObservable('sessionLength'), - withObservable('sessionBrokenPercentLate') -); +export default translate(Summary); diff --git a/packages/app-explorer/src/SummarySession.tsx b/packages/app-explorer/src/SummarySession.tsx new file mode 100644 index 0000000000..6d6d1b7f91 --- /dev/null +++ b/packages/app-explorer/src/SummarySession.tsx @@ -0,0 +1,74 @@ +// Copyright 2017-2018 @polkadot/app-explorer authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { I18nProps } from '@polkadot/ui-app/types'; + +import BN from 'bn.js'; +import React from 'react'; +import CardSummary from '@polkadot/ui-app/CardSummary'; +import withObservable from '@polkadot/ui-react-rx/with/observable'; +import withMulti from '@polkadot/ui-react-rx/with/multi'; + +import translate from './translate'; + +type Props = I18nProps & { + eraBlockLength?: BN, + eraBlockProgress?: BN, + sessionBlockProgress?: BN, + sessionBrokenValue?: BN, + sessionBrokenPercentLate?: BN, + sessionLength?: BN +}; + +class SummarySession extends React.PureComponent { + render () { + const { eraBlockLength, eraBlockProgress, sessionBlockProgress, sessionBrokenValue, sessionBrokenPercentLate, sessionLength, t } = this.props; + + return [ + , + , + + ]; + } +} + +export default withMulti( + SummarySession, + translate, + withObservable('eraBlockLength'), + withObservable('eraBlockProgress'), + withObservable('sessionBlockProgress'), + withObservable('sessionBrokenValue'), + withObservable('sessionLength'), + withObservable('sessionBrokenPercentLate') +); diff --git a/packages/app-explorer/src/index.css b/packages/app-explorer/src/index.css index e96da1c646..a046eddd5c 100644 --- a/packages/app-explorer/src/index.css +++ b/packages/app-explorer/src/index.css @@ -79,24 +79,6 @@ right: 0rem; } -.explorer--Summary { - align-items: stretch; - display: flex; - justify-content: space-between; - flex-wrap: wrap; -} - -.explorer--Summary-column { - display: flex; - flex: 0 1 auto; - text-align: left; -} - -.explorer--Summary-card { - flex: 0 1 auto; - text-align: left; -} - .explorer--Query { margin-bottom: 2em; } diff --git a/packages/app-staking/src/Summary.tsx b/packages/app-staking/src/Summary.tsx index 4a3a9a0826..628119b44f 100644 --- a/packages/app-staking/src/Summary.tsx +++ b/packages/app-staking/src/Summary.tsx @@ -4,51 +4,63 @@ import { I18nProps } from '@polkadot/ui-app/types'; import { RxBalance, RxBalanceMap } from '@polkadot/ui-react-rx/ApiObservable/types'; -import { ApiProps } from '@polkadot/ui-react-rx/types'; import BN from 'bn.js'; import React from 'react'; -import classes from '@polkadot/ui-app/util/classes'; -import withObservable from '@polkadot/ui-react-rx/with/observable'; -import withMulti from '@polkadot/ui-react-rx/with/multi'; +import CardBar from '@polkadot/ui-app/CardBar'; +import CardSummary from '@polkadot/ui-app/CardSummary'; import numberFormat from '@polkadot/ui-react-rx/util/numberFormat'; import translate from './translate'; -type Props = ApiProps & I18nProps & { +type Props = I18nProps & { balances: RxBalanceMap, - bestNumber?: BN, intentions: Array, lastLengthChange?: BN, - sessionBlockProgress?: BN, - sessionLength?: BN, validators: Array }; -const DEFAULT_BLOCKNUMBER = new BN(0); -const DEFAULT_SESSION_PROGRESS = new BN(0); -const DEFAULT_SESSION_LENGTH = new BN(60); - class Summary extends React.PureComponent { render () { - const { bestNumber = DEFAULT_BLOCKNUMBER, className, intentions, style, sessionLength = DEFAULT_SESSION_LENGTH, sessionBlockProgress = DEFAULT_SESSION_PROGRESS, t, validators } = this.props; + const { className, intentions, style, t, validators } = this.props; + + return ( + +
+ + {validators.length} + + + {intentions.length} + +
+
+ + {this.renderBalances()} + +
+
+ ); + } + + private renderBalances () { + const { t } = this.props; const intentionHigh = this.calcIntentionsHigh(); const validatorLow = this.calcValidatorLow(); return ( -
-
{t('summary.headline', { - defaultValue: '{{validatorCount}} validators, {{intentionCount}} accounts with intentions', - replace: { - intentionCount: intentions.length, - validatorCount: validators.length - } - })}
+
{t('summary.balance.validator', { - defaultValue: 'lowest validator balance is {{validatorLow}}', + defaultValue: 'lowest validator {{validatorLow}}', replace: { validatorLow: validatorLow && validatorLow.stakingBalance ? `${numberFormat(validatorLow.stakingBalance)} (+${numberFormat(validatorLow.nominatedBalance)})` @@ -56,21 +68,13 @@ class Summary extends React.PureComponent { } })}
{t('summary.balance.stake', { - defaultValue: ' highest balance intending to stake is {{intentionHigh}}', + defaultValue: 'highest intention {{intentionHigh}}', replace: { intentionHigh: intentionHigh ? `${numberFormat(intentionHigh.stakingBalance)} (+${numberFormat(intentionHigh.nominatedBalance)})` : 'unknown' } })}
-
{t('summary.countdown', { - defaultValue: 'session block {{remainder}} / {{length}} at #{{blockNumber}}', - replace: { - blockNumber: numberFormat(bestNumber), - remainder: sessionBlockProgress.toString(), - length: sessionLength.toString() - } - })}
); } @@ -106,10 +110,4 @@ class Summary extends React.PureComponent { } } -export default withMulti( - Summary, - translate, - withObservable('bestNumber'), - withObservable('sessionBlockProgress'), - withObservable('sessionLength') -); +export default translate(Summary); diff --git a/packages/app-staking/src/index.css b/packages/app-staking/src/index.css index 2a369d7715..bc4ba1c017 100644 --- a/packages/app-staking/src/index.css +++ b/packages/app-staking/src/index.css @@ -85,3 +85,10 @@ opacity: 0.45; text-align: right; } + +.staking--Summary-text { + text-align: right; + font-size: 1rem; + font-weight: normal; + line-height: 1.2rem; +} diff --git a/packages/ui-app/src/Balance.tsx b/packages/ui-app/src/Balance.tsx index cb6df21824..45c2f77624 100644 --- a/packages/ui-app/src/Balance.tsx +++ b/packages/ui-app/src/Balance.tsx @@ -10,7 +10,6 @@ import RxBalance from '@polkadot/ui-react-rx/Balance'; import numberFormat from '@polkadot/ui-react-rx/util/numberFormat'; import classes from './util/classes'; -import translate from './translate'; export type Props = BareProps & { balance?: BN | Array, @@ -19,7 +18,7 @@ export type Props = BareProps & { withLabel?: boolean }; -class Balance extends React.PureComponent { +export default class Balance extends React.PureComponent { render () { const { balance, className, label, value, style } = this.props; @@ -62,5 +61,3 @@ class Balance extends React.PureComponent { ); } } - -export default translate(Balance); diff --git a/packages/ui-app/src/CardBar.tsx b/packages/ui-app/src/CardBar.tsx new file mode 100644 index 0000000000..bfe9c65209 --- /dev/null +++ b/packages/ui-app/src/CardBar.tsx @@ -0,0 +1,46 @@ +// Copyright 2017-2018 @polkadot/ui-app authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { BareProps } from '@polkadot/ui-app/types'; + +import React from 'react'; + +import classes from './util/classes'; + +export type Props = BareProps & { + children: React.ReactNode, + expanded?: React.ReactNode +}; + +export default class CardBar extends React.PureComponent { + render () { + const { children, className, style } = this.props; + + return ( +
+
+ {children} +
+ {this.renderExtra()} +
+ ); + } + + private renderExtra () { + const { expanded } = this.props; + + if (!expanded) { + return null; + } + + return ( +
+ {expanded} +
+ ); + } +} diff --git a/packages/ui-app/src/CardSummary.tsx b/packages/ui-app/src/CardSummary.tsx index a388f2e8b9..fac78ab582 100644 --- a/packages/ui-app/src/CardSummary.tsx +++ b/packages/ui-app/src/CardSummary.tsx @@ -15,6 +15,7 @@ import classes from './util/classes'; type ProgressProps = { color?: ProgressColors, + isPercent?: boolean, total?: BN, value?: BN }; @@ -31,8 +32,16 @@ export default class CardSummary extends React.PureComponent { const left = progress && !isUndefined(progress.value) && !isUndefined(progress.total) && progress.value.gten(0) && progress.total.gtn(0) ? ( progress.value.gt(progress.total) - ? `>${progress.total.toString()}` - : progress.value.toString() + ? `>${ + progress.isPercent + ? '100' + : progress.total.toString() + }` + : ( + progress.isPercent + ? progress.value.muln(100).div(progress.total).toString() + : progress.value.toString() + ) ) : undefined; @@ -47,7 +56,11 @@ export default class CardSummary extends React.PureComponent { progress && ( !left || isUndefined(progress.total) ? '-' - : `${left}/${progress.total.toString()}` + : `${left}${progress.isPercent ? '' : '/'}${ + progress.isPercent + ? '%' + : progress.total.toString() + }` ) }
diff --git a/packages/ui-app/src/styles/components.css b/packages/ui-app/src/styles/components.css index 116b767d1a..9dfc912d23 100644 --- a/packages/ui-app/src/styles/components.css +++ b/packages/ui-app/src/styles/components.css @@ -140,6 +140,28 @@ padding: 1.5rem; } +.ui--CardBar { + margin-bottom: 2em; +} + +.ui--CardBar-cards { + align-items: stretch; + display: flex; + justify-content: space-between; + flex-wrap: wrap; +} + +.ui--CardBar-cards .column { + display: flex; + flex: 0 1 auto; + text-align: left; +} + +.ui--CardBar-cards .ui--Card { + flex: 0 1 auto; + text-align: left; +} + .ui--CardSummary .ui.label { padding-left: 0; padding-right: 0;