Era points (#1811)

This commit is contained in:
Jaco Greeff 2019-10-29 21:34:26 +01:00 committed by GitHub
parent 1ac7244e87
commit 3c5bee6dcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 65 additions and 16 deletions

View File

@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Balance } from '@polkadot/types/interfaces';
import { AccountId, Balance, Points } from '@polkadot/types/interfaces';
import { DerivedStaking, DerivedStakingOnlineStatus, DerivedHeartbeats } from '@polkadot/api-derive/types';
import { I18nProps } from '@polkadot/react-components/types';
import { ValidatorFilter } from '../types';
@ -14,7 +14,7 @@ import { ApiContext, withCalls, withMulti } from '@polkadot/react-api';
import { AddressCard, AddressMini, OnlineStatus } from '@polkadot/react-components';
import { classes } from '@polkadot/react-components/util';
import keyring from '@polkadot/ui-keyring';
import { formatBalance } from '@polkadot/util';
import { formatBalance, formatNumber } from '@polkadot/util';
import { updateOnlineStatus } from '../util';
import translate from '../translate';
@ -26,6 +26,7 @@ interface Props extends I18nProps {
defaultName: string;
filter: ValidatorFilter;
lastAuthor?: string;
points?: [Points, Points];
recentlyOnline?: DerivedHeartbeats;
stakingInfo?: DerivedStaking;
withNominations?: boolean;
@ -49,7 +50,7 @@ interface OnlineState {
const WITH_VALIDATOR_PREFS = { validatorPayment: true };
function Address ({ authorsMap, className, defaultName, filter, lastAuthor, recentlyOnline, stakingInfo, t, withNominations }: Props): React.ReactElement<Props> | null {
function Address ({ authorsMap, className, defaultName, filter, lastAuthor, points, recentlyOnline, stakingInfo, t, withNominations }: Props): React.ReactElement<Props> | null {
const { isSubstrateV2 } = useContext(ApiContext);
const [isNominatorMe, seIsNominatorMe] = useState(false);
const [{ hasOfflineWarnings, onlineStatus }, setOnlineStatus] = useState<OnlineState>({
@ -123,6 +124,8 @@ function Address ({ authorsMap, className, defaultName, filter, lastAuthor, rece
const lastBlockNumber = authorsMap[stashId];
points && console.error(points);
return (
<AddressCard
buttons={
@ -146,6 +149,11 @@ function Address ({ authorsMap, className, defaultName, filter, lastAuthor, rece
}
className={className}
defaultName={defaultName}
extraInfo={
points
? [[t('era points'), formatNumber(points[0])]]
: undefined
}
iconInfo={controllerId && onlineStatus && (
<OnlineStatus
accountId={controllerId}
@ -153,6 +161,7 @@ function Address ({ authorsMap, className, defaultName, filter, lastAuthor, rece
tooltip
/>
)}
isDisabled={!!points && points[0].isEmpty}
key={stashId}
value={stashId}
withBalance={balanceOpts}

View File

@ -4,6 +4,7 @@
import { DerivedHeartbeats } from '@polkadot/api-derive/types';
import { I18nProps } from '@polkadot/react-components/types';
import { EraPoints } from '@polkadot/types/interfaces';
import { ValidatorFilter } from '../types';
import React, { useState } from 'react';
@ -15,25 +16,31 @@ import Address from './Address';
interface Props extends I18nProps {
authorsMap: Record<string, string>;
currentValidators: string[];
eraPoints?: EraPoints;
lastAuthor?: string;
next: string[];
recentlyOnline?: DerivedHeartbeats;
}
function CurrentList ({ authorsMap, currentValidators, lastAuthor, next, recentlyOnline, t }: Props): React.ReactElement<Props> {
function CurrentList ({ authorsMap, currentValidators, eraPoints, lastAuthor, next, recentlyOnline, t }: Props): React.ReactElement<Props> {
const [filter, setFilter] = useState<ValidatorFilter>('all');
const _renderColumn = (addresses: string[], defaultName: string, withNominations: boolean): React.ReactNode => {
return addresses.map((address): React.ReactNode => (
const _renderColumn = (addresses: string[], defaultName: string, withExpanded: boolean): React.ReactNode => {
return addresses.map((address, index): React.ReactNode => (
<Address
address={address}
authorsMap={authorsMap}
defaultName={defaultName}
key={address}
filter={filter}
lastAuthor={lastAuthor}
key={address}
points={
withExpanded && eraPoints
? [eraPoints.individual[index], eraPoints.total]
: undefined
}
recentlyOnline={recentlyOnline}
withNominations={withNominations}
withNominations={withExpanded}
/>
));
};

View File

@ -4,6 +4,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { BareProps } from '@polkadot/react-components/types';
import { EraPoints } from '@polkadot/types/interfaces';
import { ComponentProps } from '../types';
import React, { useContext, useEffect, useState } from 'react';
@ -14,13 +15,14 @@ import CurrentList from './CurrentList';
import Summary from './Summary';
interface Props extends BareProps, ComponentProps {
eraPoints?: EraPoints;
}
export default function Overview (props: Props): React.ReactElement<Props> {
const { isSubstrateV2 } = useContext(ApiContext);
const { byAuthor, lastBlockAuthor, lastBlockNumber } = useContext(BlockAuthorsContext);
const [nextSorted, setNextSorted] = useState<string[]>([]);
const { allControllers, allStashes, currentValidators, recentlyOnline } = props;
const { allControllers, allStashes, currentValidators, eraPoints, recentlyOnline } = props;
useEffect((): void => {
setNextSorted(
@ -44,6 +46,7 @@ export default function Overview (props: Props): React.ReactElement<Props> {
<CurrentList
authorsMap={byAuthor}
currentValidators={currentValidators}
eraPoints={eraPoints}
lastAuthor={lastBlockAuthor}
next={nextSorted}
recentlyOnline={recentlyOnline}

View File

@ -5,7 +5,7 @@
import { DerivedHeartbeats } from '@polkadot/api-derive/types';
import { AppProps, I18nProps } from '@polkadot/react-components/types';
import { ApiProps } from '@polkadot/react-api/types';
import { AccountId, BlockNumber } from '@polkadot/types/interfaces';
import { AccountId, BlockNumber, EraPoints } from '@polkadot/types/interfaces';
import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
import { ComponentProps } from './types';
@ -28,13 +28,14 @@ interface Props extends AppProps, ApiProps, I18nProps {
allStashesAndControllers?: [string[], string[]];
bestNumber?: BlockNumber;
currentValidators?: string[];
eraPoints?: EraPoints;
recentlyOnline?: DerivedHeartbeats;
}
const EMPY_ACCOUNTS: string[] = [];
const EMPTY_ALL: [string[], string[]] = [EMPY_ACCOUNTS, EMPY_ACCOUNTS];
function App ({ allAccounts, allStashesAndControllers: [allStashes, allControllers] = EMPTY_ALL, className, currentValidators = EMPY_ACCOUNTS, basePath, recentlyOnline, t }: Props): React.ReactElement<Props> {
function App ({ allAccounts, allStashesAndControllers: [allStashes, allControllers] = EMPTY_ALL, className, currentValidators = EMPY_ACCOUNTS, basePath, eraPoints, recentlyOnline, t }: Props): React.ReactElement<Props> {
const _renderComponent = (Component: React.ComponentType<ComponentProps>): () => React.ReactNode => {
// eslint-disable-next-line react/display-name
return (): React.ReactNode => {
@ -48,6 +49,7 @@ function App ({ allAccounts, allStashesAndControllers: [allStashes, allControlle
allControllers={allControllers}
allStashes={allStashes}
currentValidators={currentValidators}
eraPoints={eraPoints}
recentlyOnline={recentlyOnline}
/>
);
@ -108,7 +110,9 @@ export default withMulti(
propName: 'currentValidators',
transform: (validators: AccountId[]): string[] =>
validators.map((accountId): string => accountId.toString())
}]
}],
['query.staking.currentEra', { propName: 'currentEra' }],
['query.staking.currentEraPointsEarned', { paramName: 'currentEra', propName: 'eraPoints' }]
),
withObservable(accountObservable.subject, { propName: 'allAccounts' })
);

View File

@ -4,6 +4,7 @@
import { DerivedFees, DerivedBalances, DerivedHeartbeats } from '@polkadot/api-derive/types';
import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
import { EraPoints } from '@polkadot/types/interfaces';
import BN from 'bn.js';
@ -14,6 +15,7 @@ export interface ComponentProps {
allControllers: string[];
allStashes: string[];
currentValidators: string[];
eraPoints?: EraPoints;
recentlyOnline?: DerivedHeartbeats;
}

View File

@ -22,6 +22,7 @@ import translate from './translate';
export interface BalanceActiveType {
available?: boolean;
bonded?: boolean | BN[];
extraInfo?: [React.ReactNode, React.ReactNode][];
locked?: boolean;
redeemable?: boolean;
reserved?: boolean;
@ -43,6 +44,7 @@ interface Props extends BareProps, I18nProps {
address: string;
balances_all?: DerivedBalances;
children?: React.ReactNode;
extraInfo?: [string, string][];
staking_info?: DerivedStaking;
withBalance?: boolean | BalanceActiveType;
withExtended?: boolean | CryptoActiveType;
@ -265,7 +267,7 @@ function renderBalances (props: Props): React.ReactNode {
}
function AddressInfo (props: Props): React.ReactElement<Props> {
const { className, children, staking_info, t, withHexSessionId, withRewardDestination } = props;
const { className, children, extraInfo, staking_info, t, withHexSessionId, withRewardDestination } = props;
return (
<div className={className}>
@ -278,6 +280,19 @@ function AddressInfo (props: Props): React.ReactElement<Props> {
</>
)}
{renderValidatorPrefs(props)}
{extraInfo && (
<>
<div />
{extraInfo.map(([label, value], index): React.ReactNode => (
<React.Fragment key={`label:${index}`}>
<Label label={label} />
<div className='result'>
{value}
</div>
</React.Fragment>
))}
</>
)}
{withRewardDestination && staking_info && staking_info.rewardDestination && (
<>
<Label label={t('reward destination')} />

View File

@ -24,7 +24,9 @@ import translate from './translate';
export interface Props extends I18nProps, RowProps {
bonded?: BN | BN[];
extraInfo?: [React.ReactNode, React.ReactNode][];
isContract?: boolean;
isDisabled?: boolean;
isValid?: boolean;
label?: string;
accounts_info?: DeriveAccountInfo;
@ -81,13 +83,13 @@ class AddressRow extends Row<ApiProps & Props, State> {
}
public render (): React.ReactNode {
const { accounts_idAndIndex = [], className, isContract, isInline, style } = this.props;
const { accounts_idAndIndex = [], className, isContract, isDisabled, isInline, style } = this.props;
const [accountId, accountIndex] = accounts_idAndIndex;
const isValid = this.props.isValid || accountId || accountIndex;
return (
<div
className={classes('ui--Row', !isValid && 'invalid', isInline && 'inline', className)}
className={classes('ui--Row', isDisabled && 'disabled', !isValid && 'invalid', isInline && 'inline', className)}
style={style}
>
<div className='ui--Row-base'>
@ -176,7 +178,7 @@ class AddressRow extends Row<ApiProps & Props, State> {
}
private renderBalances (): React.ReactNode {
const { accounts_idAndIndex = [], withBalance, withValidatorPrefs } = this.props;
const { accounts_idAndIndex = [], extraInfo, withBalance, withValidatorPrefs } = this.props;
const [accountId] = accounts_idAndIndex;
if (!(withBalance || withValidatorPrefs) || !accountId) {
@ -187,6 +189,7 @@ class AddressRow extends Row<ApiProps & Props, State> {
<div className='ui--Row-balances'>
<AddressInfo
address={accountId}
extraInfo={extraInfo}
withBalance={withBalance}
withValidatorPrefs={withValidatorPrefs}
/>
@ -289,6 +292,7 @@ export {
export default withMulti(
styled(AddressRow as React.ComponentClass<Props & ApiProps, State>)`
${styles}
.ui--Row-placeholder {
opacity: 0.5;
}

View File

@ -17,6 +17,11 @@ import InputTags from './InputTags';
export const styles = `
text-align: left;
&.disabled {
filter: grayscale(100%);
opacity: 0.75;
}
&.inline {
display: flex;