Staking accounts filtering (#4099)

This commit is contained in:
Jaco Greeff 2020-11-29 13:47:32 +01:00 committed by GitHub
parent 98cf029a58
commit ca21879056
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,8 +5,8 @@ import type { StakerState } from '@polkadot/react-hooks/types';
import type { SortedTargets } from '../types';
import BN from 'bn.js';
import React, { useMemo, useRef } from 'react';
import { Button, Table } from '@polkadot/react-components';
import React, { useMemo, useRef, useState } from 'react';
import { Button, Table, ToggleGroup } from '@polkadot/react-components';
import { useAvailableSlashes } from '@polkadot/react-hooks';
import { FormatBalance } from '@polkadot/react-query';
import { BN_ZERO } from '@polkadot/util';
@ -28,7 +28,10 @@ interface Props {
}
interface State {
bondedNoms?: BN;
bondedNone?: BN;
bondedTotal?: BN;
bondedVals?: BN;
foundStashes?: StakerState[];
}
@ -49,19 +52,67 @@ function extractState (ownStashes?: StakerState[]): State {
return {};
}
const bondedNoms = new BN(0);
const bondedNone = new BN(0);
const bondedVals = new BN(0);
const bondedTotal = new BN(0);
ownStashes.forEach(({ isStashNominating, isStashValidating, stakingLedger }): void => {
const value = stakingLedger
? stakingLedger.total.unwrap()
: BN_ZERO;
bondedTotal.iadd(value);
if (isStashNominating) {
bondedNoms.iadd(value);
} else if (isStashValidating) {
bondedVals.iadd(value);
} else {
bondedNone.iadd(value);
}
});
return {
bondedTotal: ownStashes.reduce((total: BN, { stakingLedger }) =>
stakingLedger
? total.add(stakingLedger.total.unwrap())
: total,
BN_ZERO),
bondedNoms,
bondedNone,
bondedTotal,
bondedVals,
foundStashes: ownStashes.sort(sortStashes)
};
}
function filterStashes (typeIndex: number, stashes: StakerState[]): StakerState[] {
return stashes.filter(({ isStashNominating, isStashValidating }) => {
switch (typeIndex) {
case 1: return isStashNominating;
case 2: return isStashValidating;
case 3: return !isStashNominating && !isStashValidating;
default: return true;
}
});
}
function getValue (typeIndex: number, { bondedNoms, bondedNone, bondedTotal, bondedVals }: State): BN | undefined {
switch (typeIndex) {
case 0: return bondedTotal;
case 1: return bondedNoms;
case 2: return bondedVals;
case 3: return bondedNone;
default: return bondedTotal;
}
}
function formatTotal (typeIndex: number, state: State): React.ReactNode {
const value = getValue(typeIndex, state);
return value && <FormatBalance value={value} />;
}
function Actions ({ className = '', isInElection, ownStashes, targets }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const allSlashes = useAvailableSlashes();
const [typeIndex, setTypeIndex] = useState(0);
const headerRef = useRef([
[t('stashes'), 'start', 2],
@ -71,7 +122,14 @@ function Actions ({ className = '', isInElection, ownStashes, targets }: Props):
[undefined, undefined, 2]
]);
const { bondedTotal, foundStashes } = useMemo(
const typeRef = useRef([
{ text: t('All stashes'), value: 'all' },
{ text: t('Nominators'), value: 'noms' },
{ text: t('Validators'), value: 'vals' },
{ text: t('Inactive'), value: 'chill' }
]);
const state = useMemo(
() => extractState(ownStashes),
[ownStashes]
);
@ -79,16 +137,24 @@ function Actions ({ className = '', isInElection, ownStashes, targets }: Props):
const footer = useMemo(() => (
<tr>
<td colSpan={4} />
<td className='number'>
{bondedTotal && <FormatBalance value={bondedTotal} />}
</td>
<td className='number'>{formatTotal(typeIndex, state)}</td>
<td colSpan={2} />
</tr>
), [bondedTotal]);
), [state, typeIndex]);
const filtered = useMemo(
() => state.foundStashes && filterStashes(typeIndex, state.foundStashes),
[state, typeIndex]
);
return (
<div className={className}>
<Button.Group>
<ToggleGroup
onChange={setTypeIndex}
options={typeRef.current}
value={typeIndex}
/>
<NewNominator
isInElection={isInElection}
targets={targets}
@ -98,11 +164,11 @@ function Actions ({ className = '', isInElection, ownStashes, targets }: Props):
</Button.Group>
<ElectionBanner isInElection={isInElection} />
<Table
empty={foundStashes && t<string>('No funds staked yet. Bond funds to validate or nominate a validator')}
empty={filtered && t<string>('No funds staked yet. Bond funds to validate or nominate a validator')}
footer={footer}
header={headerRef.current}
>
{foundStashes?.map((info): React.ReactNode => (
{filtered?.map((info): React.ReactNode => (
<Account
allSlashes={allSlashes}
info={info}