Recent payouts toggle (#4108)
* Recent payouts toggle * operator exposure * media--* * extra toggle padding * align
This commit is contained in:
parent
ae3f59568f
commit
837dd58c61
@ -121,7 +121,7 @@ function Validator ({ allSlashes, canSelect, filterName, info, isNominated, isSe
|
||||
)}
|
||||
</td>
|
||||
<td className='number media--1200'>{numNominators || ''}</td>
|
||||
<td className='number'>
|
||||
<td className='number media--1100'>
|
||||
{
|
||||
isCommission
|
||||
? `${commissionPer.toFixed(2)}%`
|
||||
@ -129,7 +129,7 @@ function Validator ({ allSlashes, canSelect, filterName, info, isNominated, isSe
|
||||
}
|
||||
</td>
|
||||
<td className='number together'>{!bondTotal.isZero() && <FormatBalance value={bondTotal} />}</td>
|
||||
<td className='number together'>{!bondOwn.isZero() && <FormatBalance value={bondOwn} />}</td>
|
||||
<td className='number together media--900'>{!bondOwn.isZero() && <FormatBalance value={bondOwn} />}</td>
|
||||
<td className='number together media--1600'>{!bondOther.isZero() && <FormatBalance value={bondOther} />}</td>
|
||||
<td className='number together'>{(stakedReturnCmp > 0) && <>{stakedReturnCmp.toFixed(2)}%</>}</td>
|
||||
<td>
|
||||
|
||||
@ -9,7 +9,7 @@ import BN from 'bn.js';
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Button, Icon, Table, Toggle } from '@polkadot/react-components';
|
||||
import { useApi, useAvailableSlashes, useCall } from '@polkadot/react-hooks';
|
||||
import { useApi, useAvailableSlashes, useBlocksPerDays, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
import ElectionBanner from '../ElectionBanner';
|
||||
import Filtering from '../Filtering';
|
||||
@ -31,10 +31,13 @@ interface Props {
|
||||
}
|
||||
|
||||
interface Flags {
|
||||
daysPayout: BN;
|
||||
isBabe: boolean;
|
||||
maxPaid: BN | undefined;
|
||||
withElected: boolean;
|
||||
withGroup: boolean;
|
||||
withIdentity: boolean;
|
||||
withPayout: boolean;
|
||||
withoutComm: boolean;
|
||||
withoutOver: boolean;
|
||||
}
|
||||
@ -46,15 +49,18 @@ interface SortState {
|
||||
|
||||
const CLASSES: Record<string, string> = {
|
||||
rankBondOther: 'media--1600',
|
||||
rankBondOwn: 'media--900',
|
||||
rankComm: 'media--1100',
|
||||
rankNumNominators: 'media--1200'
|
||||
};
|
||||
const MAX_COMM_FILTER = 20;
|
||||
const MAX_DAYS = 7;
|
||||
const SORT_KEYS = ['rankNumNominators', 'rankComm', 'rankBondTotal', 'rankBondOwn', 'rankBondOther', 'rankOverall'];
|
||||
|
||||
function filterValidators (validators: ValidatorInfo[], allIdentity: Record<string, DeriveHasIdentity>, { maxPaid, withElected, withGroup, withIdentity, withoutComm, withoutOver }: Flags): ValidatorInfo[] {
|
||||
function filterValidators (validators: ValidatorInfo[], allIdentity: Record<string, DeriveHasIdentity>, { daysPayout, isBabe, maxPaid, withElected, withGroup, withIdentity, withPayout, withoutComm, withoutOver }: Flags): ValidatorInfo[] {
|
||||
const parentIds: string[] = [];
|
||||
|
||||
return validators.filter(({ accountId, commissionPer, isElected, isFavorite, numNominators }): boolean => {
|
||||
return validators.filter(({ accountId, commissionPer, isElected, isFavorite, lastPayout, numNominators }): boolean => {
|
||||
if (isFavorite) {
|
||||
return true;
|
||||
}
|
||||
@ -63,8 +69,9 @@ function filterValidators (validators: ValidatorInfo[], allIdentity: Record<stri
|
||||
const thisIdentity = allIdentity[stashId];
|
||||
|
||||
if (
|
||||
(!withIdentity || !!thisIdentity?.hasIdentity) &&
|
||||
(!withElected || isElected) &&
|
||||
(!withIdentity || !!thisIdentity?.hasIdentity) &&
|
||||
(!withPayout || !isBabe || (!!lastPayout && daysPayout.gte(lastPayout))) &&
|
||||
(!withoutComm || (commissionPer < MAX_COMM_FILTER)) &&
|
||||
(!withoutOver || !maxPaid || maxPaid.gtn(numNominators))
|
||||
) {
|
||||
@ -135,12 +142,14 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const allSlashes = useAvailableSlashes();
|
||||
const daysPayout = useBlocksPerDays(MAX_DAYS);
|
||||
const ownNominators = useOwnNominators(ownStashes);
|
||||
const [selected, setSelected] = useState<string[]>([]);
|
||||
const [{ isQueryFiltered, nameFilter }, setNameFilter] = useState({ isQueryFiltered: false, nameFilter: '' });
|
||||
const [withElected, setWithElected] = useState(false);
|
||||
const [withGroup, setWithGroup] = useState(true);
|
||||
const [withIdentity, setWithIdentity] = useState(false);
|
||||
const [withPayout, setWithPayout] = useState(true);
|
||||
const [withoutComm, setWithoutComm] = useState(true);
|
||||
const [withoutOver, setWithoutOver] = useState(true);
|
||||
const [{ sortBy, sortFromMax }, setSortBy] = useState<SortState>({ sortBy: 'rankOverall', sortFromMax: true });
|
||||
@ -158,15 +167,18 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak
|
||||
|
||||
const flags = useMemo(
|
||||
() => ({
|
||||
daysPayout,
|
||||
isBabe: !!api.consts.babe,
|
||||
isQueryFiltered,
|
||||
maxPaid: api.consts.staking?.maxNominatorRewardedPerValidator,
|
||||
withElected,
|
||||
withGroup,
|
||||
withIdentity,
|
||||
withPayout,
|
||||
withoutComm,
|
||||
withoutOver
|
||||
}),
|
||||
[api, isQueryFiltered, withElected, withGroup, withIdentity, withoutComm, withoutOver]
|
||||
[api, daysPayout, isQueryFiltered, withElected, withGroup, withIdentity, withPayout, withoutComm, withoutOver]
|
||||
);
|
||||
|
||||
const filtered = useMemo(
|
||||
@ -242,7 +254,7 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak
|
||||
>
|
||||
<Toggle
|
||||
className='staking--buttonToggle'
|
||||
label={t<string>('limit single operator exposure')}
|
||||
label={t<string>('limit operator exposure')}
|
||||
onChange={setWithGroup}
|
||||
value={withGroup}
|
||||
/>
|
||||
@ -252,6 +264,15 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak
|
||||
onChange={setWithoutComm}
|
||||
value={withoutComm}
|
||||
/>
|
||||
{api.consts.babe && (
|
||||
// FIXME have some sane era defaults for Aura
|
||||
<Toggle
|
||||
className='staking--buttonToggle'
|
||||
label={t<string>('recent payouts')}
|
||||
onChange={setWithPayout}
|
||||
value={withPayout}
|
||||
/>
|
||||
)}
|
||||
<Toggle
|
||||
className='staking--buttonToggle'
|
||||
label={t<string>('no oversubscribed')}
|
||||
@ -266,7 +287,7 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak
|
||||
/>
|
||||
</Filtering>
|
||||
</div>
|
||||
), [nameFilter, _setNameFilter, t, withElected, withGroup, withIdentity, withoutComm, withoutOver]);
|
||||
), [api, nameFilter, _setNameFilter, t, withElected, withGroup, withIdentity, withPayout, withoutComm, withoutOver]);
|
||||
|
||||
const displayList = isQueryFiltered
|
||||
? validators
|
||||
|
||||
@ -194,7 +194,9 @@ export default React.memo(styled(StakingApp)(({ theme }: ThemeProps) => `
|
||||
}
|
||||
|
||||
.staking--optionsBar {
|
||||
text-align: right;
|
||||
margin: 0.5rem 0 1rem;
|
||||
text-align: center;
|
||||
white-space: normal;
|
||||
|
||||
.staking--buttonToggle {
|
||||
display: inline-block;
|
||||
|
||||
@ -8,6 +8,7 @@ export { useAddresses } from './useAddresses';
|
||||
export { useApi } from './useApi';
|
||||
export { useAvailableSlashes } from './useAvailableSlashes';
|
||||
export { useBlockTime } from './useBlockTime';
|
||||
export { useBlocksPerDays } from './useBlocksPerDays';
|
||||
export { useCacheKey } from './useCacheKey';
|
||||
export { useCall } from './useCall';
|
||||
export { useContracts } from './useContracts';
|
||||
|
||||
23
packages/react-hooks/src/useBlocksPerDays.ts
Normal file
23
packages/react-hooks/src/useBlocksPerDays.ts
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2017-2020 @polkadot/app-democracy authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { useMemo } from 'react';
|
||||
import { useApi } from '@polkadot/react-hooks';
|
||||
|
||||
const DEFAULT_TIME = new BN(6000);
|
||||
const A_DAY = new BN(24 * 60 * 60 * 1000);
|
||||
|
||||
export function useBlocksPerDays (days = 1): BN {
|
||||
const { api } = useApi();
|
||||
|
||||
return useMemo(
|
||||
() => A_DAY.muln(days).div(
|
||||
api.consts.babe?.expectedBlockTime ||
|
||||
api.consts.difficulty?.targetBlockTime ||
|
||||
api.consts.timestamp?.minimumPeriod.muln(2) ||
|
||||
DEFAULT_TIME
|
||||
),
|
||||
[api, days]
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user