Staking accounts filtering (#4099)
This commit is contained in:
parent
98cf029a58
commit
ca21879056
@ -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}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user