From ca21879056f1aa6f5081e33b8b7231eb20ad2cbe Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Sun, 29 Nov 2020 13:47:32 +0100 Subject: [PATCH] Staking accounts filtering (#4099) --- packages/page-staking/src/Actions/index.tsx | 94 ++++++++++++++++++--- 1 file changed, 80 insertions(+), 14 deletions(-) diff --git a/packages/page-staking/src/Actions/index.tsx b/packages/page-staking/src/Actions/index.tsx index ad63137c15..f689b4cebf 100644 --- a/packages/page-staking/src/Actions/index.tsx +++ b/packages/page-staking/src/Actions/index.tsx @@ -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 && ; +} + function Actions ({ className = '', isInElection, ownStashes, targets }: Props): React.ReactElement { 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(() => ( - - {bondedTotal && } - + {formatTotal(typeIndex, state)} - ), [bondedTotal]); + ), [state, typeIndex]); + + const filtered = useMemo( + () => state.foundStashes && filterStashes(typeIndex, state.foundStashes), + [state, typeIndex] + ); return (
+ ('No funds staked yet. Bond funds to validate or nominate a validator')} + empty={filtered && t('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 => (