Era points (#1811)
This commit is contained in:
parent
1ac7244e87
commit
3c5bee6dcf
@ -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}
|
||||
|
||||
@ -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}
|
||||
/>
|
||||
));
|
||||
};
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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' })
|
||||
);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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')} />
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -17,6 +17,11 @@ import InputTags from './InputTags';
|
||||
export const styles = `
|
||||
text-align: left;
|
||||
|
||||
&.disabled {
|
||||
filter: grayscale(100%);
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
&.inline {
|
||||
display: flex;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user