diff --git a/packages/page-staking/src/Filtering.tsx b/packages/page-staking/src/Filtering.tsx index f6f87a9e1e..1c78d9fa1a 100644 --- a/packages/page-staking/src/Filtering.tsx +++ b/packages/page-staking/src/Filtering.tsx @@ -15,8 +15,8 @@ interface Props { className?: string; nameFilter: string; setNameFilter: (value: string, isQuery: boolean) => void; - setWithIdentity: (value: boolean) => void; - withIdentity: boolean; + setWithIdentity?: (value: boolean) => void; + withIdentity?: boolean; } function Filtering ({ children, className, nameFilter, setNameFilter, setWithIdentity, withIdentity }: Props): React.ReactElement | null { @@ -47,17 +47,19 @@ function Filtering ({ children, className, nameFilter, setNameFilter, setWithIde onChange={_setNameFilter} value={nameFilter} /> -
- {children} - {api.query.identity && ( - ('with an identity')} - onChange={setWithIdentity} - value={withIdentity} - /> - )} -
+ {(children || setWithIdentity) && ( +
+ {children} + {setWithIdentity && api.query.identity && ( + ('with an identity')} + onChange={setWithIdentity} + value={withIdentity} + /> + )} +
+ )} ); } diff --git a/packages/page-staking/src/Overview/Address/index.tsx b/packages/page-staking/src/Overview/Address/index.tsx index c5be070262..73cd2f9aac 100644 --- a/packages/page-staking/src/Overview/Address/index.tsx +++ b/packages/page-staking/src/Overview/Address/index.tsx @@ -38,7 +38,7 @@ interface Props { recentlyOnline?: DeriveHeartbeatAuthor; toggleFavorite: (accountId: string) => void; validatorInfo?: ValidatorInfo; - withIdentity: boolean; + withIdentity?: boolean; } interface StakingState { diff --git a/packages/page-staking/src/Overview/CurrentList.tsx b/packages/page-staking/src/Overview/CurrentList.tsx index e7fd350afb..3d7a4ef5fb 100644 --- a/packages/page-staking/src/Overview/CurrentList.tsx +++ b/packages/page-staking/src/Overview/CurrentList.tsx @@ -10,7 +10,7 @@ import type { NominatedByMap, SortedTargets, ValidatorInfo } from '../types'; import React, { useContext, useMemo, useRef, useState } from 'react'; import { Table } from '@polkadot/react-components'; -import { useApi, useCall, useLoadingDelay, useSavedFlags } from '@polkadot/react-hooks'; +import { useApi, useLoadingDelay } from '@polkadot/react-hooks'; import { BlockAuthorsContext } from '@polkadot/react-query'; import Filtering from '../Filtering'; @@ -29,6 +29,7 @@ interface Props { nominatedBy?: NominatedByMap; ownStashIds?: string[]; paraValidators?: Record; + recentlyOnline?: DeriveHeartbeats; setNominators?: (nominators: string[]) => void; stakingOverview?: DeriveStakingOverview; targets: SortedTargets; @@ -73,7 +74,11 @@ function accountsToString (accounts: AccountId[]): string[] { return accounts.map((a) => a.toString()); } -function getFiltered (isOwn: boolean, stakingOverview: DeriveStakingOverview, favorites: string[], next?: string[], ownStashIds?: string[]): Filtered { +function getFiltered (isOwn: boolean, stakingOverview: DeriveStakingOverview | undefined, favorites: string[], next?: string[], ownStashIds?: string[]): Filtered { + if (!stakingOverview) { + return {}; + } + const allElected = accountsToString(stakingOverview.nextElected); const validatorIds = accountsToString(stakingOverview.validators); @@ -87,24 +92,31 @@ function getFiltered (isOwn: boolean, stakingOverview: DeriveStakingOverview, fa const DEFAULT_PARAS = {}; -function CurrentList ({ className, favorites, hasQueries, isIntentions, isOwn, minCommission, nominatedBy, ownStashIds, paraValidators = DEFAULT_PARAS, stakingOverview, targets, toggleFavorite }: Props): React.ReactElement | null { +function CurrentList ({ className, favorites, hasQueries, isIntentions, isOwn, minCommission, nominatedBy, ownStashIds, paraValidators = DEFAULT_PARAS, recentlyOnline, stakingOverview, targets, toggleFavorite }: Props): React.ReactElement | null { const { t } = useTranslation(); const { api } = useApi(); const { byAuthor, eraPoints } = useContext(isIntentions ? EmptyAuthorsContext : BlockAuthorsContext); - const recentlyOnline = useCall(!isIntentions && api.derive.imOnline?.receivedHeartbeats); const [nameFilter, setNameFilter] = useState(''); - const [toggles, setToggle] = useSavedFlags('staking:overview', { withIdentity: false }); // we have a very large list, so we use a loading delay const isLoading = useLoadingDelay(); const { validators, waiting } = useMemo( - () => stakingOverview ? getFiltered(isOwn, stakingOverview, favorites, targets.waitingIds, ownStashIds) : {}, + () => getFiltered(isOwn, stakingOverview, favorites, targets.waitingIds, ownStashIds), [favorites, isOwn, ownStashIds, stakingOverview, targets] ); + const list = useMemo( + () => isLoading + ? undefined + : isIntentions + ? nominatedBy && waiting + : validators, + [isIntentions, isLoading, nominatedBy, validators, waiting] + ); + const infoMap = useMemo( - () => targets.validators?.reduce>((result, info) => { + () => targets.validators && targets.validators.reduce>((result, info) => { result[info.key] = info; return result; @@ -137,11 +149,9 @@ function CurrentList ({ className, favorites, hasQueries, isIntentions, isOwn, m ('No waiting validators found') - : recentlyOnline && validators && infoMap && t('No active validators found') - ) + isIntentions + ? list && t('No waiting validators found') + : list && recentlyOnline && infoMap && t('No active validators found') } emptySpinner={ <> @@ -151,14 +161,13 @@ function CurrentList ({ className, favorites, hasQueries, isIntentions, isOwn, m ? !nominatedBy &&
{t('Retrieving nominators')}
: !recentlyOnline &&
{t('Retrieving online status')}
} + {!list &&
{t('Preparing validator list')}
} } filter={ } header={headerRef.current} @@ -169,12 +178,7 @@ function CurrentList ({ className, favorites, hasQueries, isIntentions, isOwn, m /> } > - {!isLoading && ( - (isIntentions - ? nominatedBy && waiting - : validators - ) || [] - ).map(([address, isElected, isFavorite]): React.ReactNode => ( + {list && list.map(([address, isElected, isFavorite]): React.ReactNode => (
))}
diff --git a/packages/page-staking/src/Overview/index.tsx b/packages/page-staking/src/Overview/index.tsx index 26bc62965f..ed2abf34b1 100644 --- a/packages/page-staking/src/Overview/index.tsx +++ b/packages/page-staking/src/Overview/index.tsx @@ -1,7 +1,7 @@ // Copyright 2017-2022 @polkadot/app-staking authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { DeriveStakingOverview } from '@polkadot/api-derive/types'; +import type { DeriveHeartbeats, DeriveStakingOverview } from '@polkadot/api-derive/types'; import type { StakerState } from '@polkadot/react-hooks/types'; import type { BN } from '@polkadot/util'; import type { NominatedByMap, SortedTargets } from '../types'; @@ -9,6 +9,7 @@ import type { NominatedByMap, SortedTargets } from '../types'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Button, ToggleGroup } from '@polkadot/react-components'; +import { useApi, useCall } from '@polkadot/react-hooks'; import { useTranslation } from '../translate'; import CurrentList from './CurrentList'; @@ -30,8 +31,10 @@ interface Props { function Overview ({ className = '', favorites, hasQueries, minCommission, nominatedBy, ownStashes, paraValidators, stakingOverview, targets, toggleFavorite, toggleLedger, toggleNominatedBy }: Props): React.ReactElement { const { t } = useTranslation(); + const { api } = useApi(); const [intentIndex, _setIntentIndex] = useState(0); const [typeIndex, setTypeIndex] = useState(1); + const recentlyOnline = useCall(api.derive.imOnline?.receivedHeartbeats); const setIntentIndex = useCallback( (index: number): void => { @@ -77,32 +80,20 @@ function Overview ({ className = '', favorites, hasQueries, minCommission, nomin /> - {intentIndex === 1 && ( - - )} ); } diff --git a/packages/page-staking/src/Targets/index.tsx b/packages/page-staking/src/Targets/index.tsx index f565e4398b..56a43f2826 100644 --- a/packages/page-staking/src/Targets/index.tsx +++ b/packages/page-staking/src/Targets/index.tsx @@ -391,13 +391,14 @@ function Targets ({ className = '', isInElection, nominatedBy, ownStashes, targe <> {!(validators && allIdentity) &&
{t('Retrieving validators')}
} {!nominatedBy &&
{t('Retrieving nominators')}
} + {!displayList &&
{t('Preparing target display')}
} } filter={filter} header={header} legend={} > - {displayList?.map((info): React.ReactNode => + {displayList && displayList.map((info): React.ReactNode =>