diff --git a/packages/app/src/overlay/modals/ValidatorMetrics/ActiveGraph.tsx b/packages/app/src/overlay/canvas/ValidatorMetrics/ActiveGraph.tsx similarity index 50% rename from packages/app/src/overlay/modals/ValidatorMetrics/ActiveGraph.tsx rename to packages/app/src/overlay/canvas/ValidatorMetrics/ActiveGraph.tsx index bf7d2e348..350367704 100644 --- a/packages/app/src/overlay/modals/ValidatorMetrics/ActiveGraph.tsx +++ b/packages/app/src/overlay/canvas/ValidatorMetrics/ActiveGraph.tsx @@ -2,15 +2,24 @@ // SPDX-License-Identifier: GPL-3.0-only import type { NetworkId } from 'common-types' -import { EraPoints } from 'library/Graphs/EraPoints' +import { EraPointsLine } from 'library/Graphs/EraPointsLine' import { useValidatorEraPoints } from 'plugin-staking-api' +import type { PointsByEra } from 'types' interface Props { network: NetworkId validator: string fromEra: number + width: string | number + height: string | number } -export const ActiveGraph = ({ network, validator, fromEra }: Props) => { +export const ActiveGraph = ({ + network, + validator, + fromEra, + width, + height, +}: Props) => { const { data, loading, error } = useValidatorEraPoints({ chain: network, validator, @@ -22,7 +31,18 @@ export const ActiveGraph = ({ network, validator, fromEra }: Props) => { ? [] : data.validatorEraPoints - const sorted = [...list].sort((a, b) => a.era - b.era) + const sorted: PointsByEra = Object.fromEntries( + [...list] + .sort((a, b) => a.era - b.era) + .map((item) => [item.era, item.points]) + ) - return + return ( + + ) } diff --git a/packages/app/src/overlay/canvas/ValidatorMetrics/InactiveGraph.tsx b/packages/app/src/overlay/canvas/ValidatorMetrics/InactiveGraph.tsx new file mode 100644 index 000000000..98551cec2 --- /dev/null +++ b/packages/app/src/overlay/canvas/ValidatorMetrics/InactiveGraph.tsx @@ -0,0 +1,19 @@ +// Copyright 2024 @polkadot-cloud/polkadot-staking-dashboard authors & contributors +// SPDX-License-Identifier: GPL-3.0-only + +import { EraPointsLine } from 'library/Graphs/EraPointsLine' + +export const InactiveGraph = ({ + width, + height, +}: { + width: string | number + height: string | number +}) => ( + +) diff --git a/packages/app/src/overlay/canvas/ValidatorMetrics/index.tsx b/packages/app/src/overlay/canvas/ValidatorMetrics/index.tsx index aacc01e1a..03b02dd50 100644 --- a/packages/app/src/overlay/canvas/ValidatorMetrics/index.tsx +++ b/packages/app/src/overlay/canvas/ValidatorMetrics/index.tsx @@ -5,12 +5,14 @@ import { faTimes } from '@fortawesome/free-solid-svg-icons' import { useSize } from '@w3ux/hooks' import { Polkicon } from '@w3ux/react-polkicon' import BigNumber from 'bignumber.js' +import { useApi } from 'contexts/Api' import { useHelp } from 'contexts/Help' import { useNetwork } from 'contexts/Network' +import { usePlugins } from 'contexts/Plugins' import { useStaking } from 'contexts/Staking' import { useUi } from 'contexts/UI' -import { EraPointsLine } from 'library/Graphs/EraPointsLine' import { formatSize } from 'library/Graphs/Utils' +import { StatusLabel } from 'library/StatusLabel' import { useRef } from 'react' import { useTranslation } from 'react-i18next' import { ButtonHelp, ButtonPrimary } from 'ui-buttons' @@ -25,6 +27,8 @@ import { } from 'ui-core/canvas' import { useOverlay } from 'ui-overlay' import { planckToUnitBn } from 'utils' +import { ActiveGraph } from './ActiveGraph' +import { InactiveGraph } from './InactiveGraph' export const ValidatorMetrics = () => { const { t } = useTranslation() @@ -36,14 +40,18 @@ export const ValidatorMetrics = () => { config: { options }, } = useOverlay().canvas const { + network, networkData: { units, unit, brand: { token: Token }, }, } = useNetwork() + const { activeEra } = useApi() const { openHelp } = useHelp() const { containerRefs } = useUi() + const { pluginEnabled } = usePlugins() + const validator = options!.validator const identity = options!.identity @@ -70,7 +78,7 @@ export const ValidatorMetrics = () => { const size = useSize(graphInnerRef, { outerElement: containerRefs?.mainInterface, }) - const { width, height } = formatSize(size, 150) + const { width, height } = formatSize(size, 250) return (
@@ -127,12 +135,25 @@ export const ValidatorMetrics = () => { - + {pluginEnabled('staking_api') ? ( + + ) : ( + <> + + + + )} diff --git a/packages/app/src/overlay/modals/ValidatorMetrics/InactiveGraph.tsx b/packages/app/src/overlay/modals/ValidatorMetrics/InactiveGraph.tsx deleted file mode 100644 index 1454e8b52..000000000 --- a/packages/app/src/overlay/modals/ValidatorMetrics/InactiveGraph.tsx +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2024 @polkadot-cloud/polkadot-staking-dashboard authors & contributors -// SPDX-License-Identifier: GPL-3.0-only - -import { EraPoints } from 'library/Graphs/EraPoints' - -export const InactiveGraph = () => diff --git a/packages/app/src/overlay/modals/ValidatorMetrics/index.tsx b/packages/app/src/overlay/modals/ValidatorMetrics/index.tsx deleted file mode 100644 index 5433d214b..000000000 --- a/packages/app/src/overlay/modals/ValidatorMetrics/index.tsx +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2024 @polkadot-cloud/polkadot-staking-dashboard authors & contributors -// SPDX-License-Identifier: GPL-3.0-only - -import { useSize } from '@w3ux/hooks' -import { Polkicon } from '@w3ux/react-polkicon' -import { ellipsisFn } from '@w3ux/utils' -import BigNumber from 'bignumber.js' -import { useApi } from 'contexts/Api' -import { useHelp } from 'contexts/Help' -import { useNetwork } from 'contexts/Network' -import { usePlugins } from 'contexts/Plugins' -import { useStaking } from 'contexts/Staking' -import { useUi } from 'contexts/UI' -import { CardHeaderWrapper, CardWrapper } from 'library/Card/Wrappers' -import { formatSize } from 'library/Graphs/Utils' -import { GraphWrapper } from 'library/Graphs/Wrapper' -import { Title } from 'library/Modal/Title' -import { StatWrapper, StatsWrapper } from 'library/Modal/Wrappers' -import { StatusLabel } from 'library/StatusLabel' -import { useRef } from 'react' -import { useTranslation } from 'react-i18next' -import { ButtonHelp } from 'ui-buttons' -import { AddressHeader, Padding } from 'ui-core/modal' -import { useOverlay } from 'ui-overlay' -import { planckToUnitBn } from 'utils' -import { ActiveGraph } from './ActiveGraph' -import { InactiveGraph } from './InactiveGraph' - -export const ValidatorMetrics = () => { - const { t } = useTranslation() - const { - network, - networkData: { units, unit }, - } = useNetwork() - const { - eraStakers: { stakers }, - } = useStaking() - const { activeEra } = useApi() - const { openHelp } = useHelp() - const { containerRefs } = useUi() - const { pluginEnabled } = usePlugins() - const { options } = useOverlay().modal.config - const { address, identity } = options - - // is the validator in the active era - const validatorInEra = stakers.find((s) => s.address === address) || null - - let validatorOwnStake = new BigNumber(0) - let otherStake = new BigNumber(0) - if (validatorInEra) { - const { others, own } = validatorInEra - - others.forEach(({ value }) => { - otherStake = otherStake.plus(value) - }) - if (own) { - validatorOwnStake = new BigNumber(own) - } - } - - const ref = useRef(null) - const size = useSize(ref, { - outerElement: containerRefs?.mainInterface, - }) - const { width, height, minHeight } = formatSize(size, 300) - - const stats = [ - { - label: t('selfStake', { ns: 'modals' }), - value: `${planckToUnitBn(validatorOwnStake, units).toFormat()} ${unit}`, - help: 'Self Stake', - }, - { - label: t('nominatorStake', { ns: 'modals' }), - value: `${planckToUnitBn(otherStake, units).toFormat()} ${unit}`, - help: 'Nominator Stake', - }, - ] - return ( - <> - - <AddressHeader> - <Polkicon address={address} fontSize="2.75rem" /> - <h2> -    - {identity === null ? ellipsisFn(address) : identity} - </h2> - </AddressHeader> - - <Padding horizontalOnly> - <StatsWrapper> - {stats.map((s, i) => ( - <StatWrapper key={`metrics_stat_${i}`}> - <div className="inner"> - <h4> - {s.label}{' '} - <ButtonHelp marginLeft onClick={() => openHelp(s.help)} /> - </h4> - <h2>{s.value}</h2> - </div> - </StatWrapper> - ))} - </StatsWrapper> - </Padding> - <div - style={{ position: 'relative', marginTop: '0.5rem', padding: '1rem' }} - > - <CardWrapper - className="transparent" - style={{ - margin: '0 0 0 0.5rem', - height: 350, - }} - > - <CardHeaderWrapper $withMargin> - <h4> - {t('recentEraPoints', { ns: 'modals' })}{' '} - <ButtonHelp marginLeft onClick={() => openHelp('Era Points')} /> - </h4> - </CardHeaderWrapper> - <div ref={ref} style={{ minHeight }}> - <GraphWrapper - style={{ - height: `${height}px`, - width: `${width}px`, - }} - > - {pluginEnabled('staking_api') ? ( - <ActiveGraph - network={network} - validator={address} - fromEra={BigNumber.max( - activeEra.index.minus(1), - 0 - ).toNumber()} - /> - ) : ( - <> - <StatusLabel - status="active_service" - statusFor="staking_api" - title={t('common.stakingApiDisabled', { ns: 'pages' })} - topOffset="37%" - /> - <InactiveGraph /> - </> - )} - </GraphWrapper> - </div> - </CardWrapper> - </div> - </> - ) -}