-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
4326-Validators list - Page and widgets (#4375)
* Add Validators Module to the side menu and add tabs to validators page * Add widgets * fix widgets * display info modal on first open the page * get the staking informations using polkadot api * add validators list filter * fix widgets component and hook, add last reward * add validators' list- draft * add 'Total rewards', but not beyond history depth * remove filter and search box * fix validator page notification modal * lint:fix * Update packages/ui/src/validators/components/widgets/Era.tsx Co-authored-by: l1.media <31551045+traumschule@users.noreply.github.com> * Update packages/ui/src/validators/components/widgets/Era.tsx Co-authored-by: l1.media <31551045+traumschule@users.noreply.github.com> * Update packages/ui/src/validators/components/widgets/Rewards.tsx Co-authored-by: l1.media <31551045+traumschule@users.noreply.github.com> * Update packages/ui/src/validators/components/widgets/Rewards.tsx Co-authored-by: l1.media <31551045+traumschule@users.noreply.github.com> * rename 'widgets' to 'statistics','validators.tsx' to 'validatorlist.tsx' * add 'nominators' to the widget * add staking percentage to the widget * add blocks and points to the widget * fix validators page notification modal * fix the counter for active nominators * fix the format of staking value * yarn lint:fix * remove route, sidebar item, tab, dashboard, modal * add storybook for validator list page statistics * fix storybook, remove unused variables * Update packages/ui/src/app/pages/Validators/ValidatorList.stories.tsx Co-authored-by: Theophile Sandoz <theophile.sandoz@gmail.com> * Update packages/ui/src/app/pages/Validators/ValidatorList.stories.tsx Co-authored-by: Theophile Sandoz <theophile.sandoz@gmail.com> * Update packages/ui/src/app/pages/Validators/ValidatorList.stories.tsx Co-authored-by: Theophile Sandoz <theophile.sandoz@gmail.com> * Make story values more readable * Add a special case for `unwrap` methods * Assign an object to unwrap * Update packages/ui/src/common/components/charts/PercentageChart.tsx Co-authored-by: Theophile Sandoz <theophile.sandoz@gmail.com> * Update packages/ui/src/validators/constants/constant.ts Co-authored-by: Theophile Sandoz <theophile.sandoz@gmail.com> * Update packages/ui/src/validators/hooks/useStakingStatistics.tsx Co-authored-by: Theophile Sandoz <theophile.sandoz@gmail.com> * Update packages/ui/src/validators/hooks/useStakingStatistics.tsx Co-authored-by: Theophile Sandoz <theophile.sandoz@gmail.com> * Update packages/ui/src/validators/hooks/useStakingStatistics.tsx Co-authored-by: Theophile Sandoz <theophile.sandoz@gmail.com> * fix rewardPoints * remove InfoModal * fix asChainData helper * Simplify chain unwrapped mocks * move ERA_DRATION to common/constant/number * remove the default value for activeEra, assign undefined instead * pass the statistic values as props * fix some code to make it clear * fix some issue in Era widget --------- Co-authored-by: l1.media <31551045+traumschule@users.noreply.github.com> Co-authored-by: Theophile Sandoz <theophile.sandoz@gmail.com>
- Loading branch information
1 parent
a4f23b7
commit 9f9514b
Showing
13 changed files
with
447 additions
and
17 deletions.
There are no files selected for viewing
116 changes: 116 additions & 0 deletions
116
packages/ui/src/app/pages/Validators/ValidatorList.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import { Meta, StoryObj } from '@storybook/react' | ||
|
||
import { joy } from '@/mocks/helpers' | ||
import { MocksParameters } from '@/mocks/providers' | ||
|
||
import { ValidatorList } from './ValidatorList' | ||
|
||
type Args = object | ||
|
||
export default { | ||
title: 'Pages/Validators/ValidatorList', | ||
component: ValidatorList, | ||
|
||
parameters: { | ||
mocks: (): MocksParameters => { | ||
return { | ||
chain: { | ||
derive: { | ||
staking: { | ||
erasRewards: [ | ||
{ era: 688, eraReward: joy(0.123456) }, | ||
{ era: 689, eraReward: joy(0.123456) }, | ||
{ era: 690, eraReward: joy(0.123456) }, | ||
{ era: 691, eraReward: joy(0.123456) }, | ||
{ era: 692, eraReward: joy(0.123456) }, | ||
{ era: 693, eraReward: joy(0.123456) }, | ||
{ era: 694, eraReward: joy(0.123456) }, | ||
{ era: 695, eraReward: joy(0.123456) }, | ||
{ era: 696, eraReward: joy(0.123456) }, | ||
{ era: 697, eraReward: joy(0.123456) }, | ||
{ era: 698, eraReward: joy(0.123456) }, | ||
{ era: 699, eraReward: joy(0.123456) }, | ||
{ era: 700, eraReward: joy(0.123456) }, | ||
], | ||
}, | ||
}, | ||
query: { | ||
balances: { | ||
totalIssuance: joy(1000000), | ||
}, | ||
timestamp: { now: Date.now() }, | ||
session: { | ||
validators: [ | ||
'j4RLnWh3DWgc9u4CMprqxfBhq3kthXhvZDmnpjEtETFVm446D', | ||
'j4RbTjvPyaufVVoxVGk5vEKHma1k7j5ZAQCaAL9qMKQWKAswW', | ||
'j4Rc8VUXGYAx7FNbVZBFU72rQw3GaCuG2AkrUQWnWTh5SpemP', | ||
'j4Rh1cHtZFAQYGh7Y8RZwoXbkAPtZN46FmuYpKNiR3P2Dc2oz', | ||
'j4RjraznxDKae1aGL2L2xzXPSf8qCjFbjuw9sPWkoiy1UqWCa', | ||
'j4RuqkJ2Xqf3NTVRYBUqgbatKVZ31mbK59fWnq4ZzfZvhbhbN', | ||
'j4RxTMa1QVucodYPfQGA2JrHxZP944dfJ8qdDDYKU4QbJCWNP', | ||
'j4Rxkb1w9yB6WXroB2npKjRJJxwxbD8JjSQwMZFB31cf5aZAJ', | ||
'j4RyLBbSUBvipuQLkjLyUGeFWEzmrnfYdpteDa2gYNoM13qEg', | ||
'j4S998Thq5kQHyurofh8QfHrcFN2c1T19gTdMGUVVx5EHKgky', | ||
], | ||
}, | ||
staking: { | ||
activeEra: { | ||
index: 700, | ||
start: Date.now() - 5400000, | ||
}, | ||
counterForValidators: 12, | ||
counterForNominators: 20, | ||
erasRewardPoints: { | ||
total: 18000, | ||
individuals: { | ||
j4RLnWh3DWgc9u4CMprqxfBhq3kthXhvZDmnpjEtETFVm446D: 180, | ||
j4RbTjvPyaufVVoxVGk5vEKHma1k7j5ZAQCaAL9qMKQWKAswW: 200, | ||
j4Rc8VUXGYAx7FNbVZBFU72rQw3GaCuG2AkrUQWnWTh5SpemP: 280, | ||
j4Rh1cHtZFAQYGh7Y8RZwoXbkAPtZN46FmuYpKNiR3P2Dc2oz: 200, | ||
j4RjraznxDKae1aGL2L2xzXPSf8qCjFbjuw9sPWkoiy1UqWCa: 160, | ||
j4RuqkJ2Xqf3NTVRYBUqgbatKVZ31mbK59fWnq4ZzfZvhbhbN: 180, | ||
j4RxTMa1QVucodYPfQGA2JrHxZP944dfJ8qdDDYKU4QbJCWNP: 140, | ||
j4Rxkb1w9yB6WXroB2npKjRJJxwxbD8JjSQwMZFB31cf5aZAJ: 160, | ||
j4RyLBbSUBvipuQLkjLyUGeFWEzmrnfYdpteDa2gYNoM13qEg: 160, | ||
j4S998Thq5kQHyurofh8QfHrcFN2c1T19gTdMGUVVx5EHKgky: 220, | ||
}, | ||
}, | ||
erasValidatorReward: joy(0.123456), | ||
erasStakers: { | ||
total: joy(0.1), | ||
own: joy(0.0001), | ||
others: [ | ||
{ who: 'j4WGdFxqTkyAgzJiTbEBeRseP12dPEvJgf2Wy9qkPa68XSP55', value: joy(0.2) }, | ||
{ who: 'j4UQEfPFnKwGuHytxs9YEouLnhnSNkPDgNm9tKeB7an3dRaiy', value: joy(0.2) }, | ||
{ who: 'j4WwTZ3fnkoXJw3D1vGVyymjaiLxM78TGyAAX41JRH8Kx6T2u', value: joy(0.2) }, | ||
{ who: 'j4WqZwj6KjB4DbxknxyJB1ZkeVrPRGmg6DUGw2YkuAy7jUERg', value: joy(0.2) }, | ||
{ who: 'j4WwTZ3fnkoXJw3D1vGVyymjaiLxM78TGyAAX41JRH8Kx6T2u', value: joy(0.2) }, | ||
{ who: 'j4Wo9377XBAvhmB35J4TkpJUHnUKmyccXhGtHCVvi6pPr9so8', value: joy(0.2) }, | ||
{ who: 'j4WwTZ3fnkoXJw3D1vGVyymjaiLxM78TGyAAX41JRH8Kx6T2u', value: joy(0.2) }, | ||
{ who: 'j4WfB3TD4tFgrJpCmUi8P3wPp3EocyC5At9ZM2YUpmKGJ1FWM', value: joy(0.2) }, | ||
{ who: 'j4WwTZ3fnkoXJw3D1vGVyymjaiLxM78TGyAAX41JRH8Kx6T2u', value: joy(0.2) }, | ||
{ who: 'j4T3XgRMUaZZL6GsMk6RXfBcjuMWxfSLnoATYkBTHh7xyjmoH', value: joy(0.2) }, | ||
{ who: 'j4W2bw7ggG69e9TZ77RP9mjem1GrbPwpbKYK7WdZiym77yzMJ', value: joy(0.2) }, | ||
{ who: 'j4UzoJUhDGpnsCWrmx9ojofwaT8KHz3azp8C1S49MSN6rYjim', value: joy(0.2) }, | ||
{ who: 'j4ShWRXxTG4K5Q5H7KXmdWN8HnaaLwppqM7GdiSwAy3eTLsJt', value: joy(0.2) }, | ||
{ who: 'j4SgrgDrzzGyfrxPe4ZgaKfByKyLo5SdsUXNfHzZJPh5R6f8q', value: joy(0.2) }, | ||
{ who: 'j4RLnWh3DWgc9u4CMprqxfBhq3kthXhvZDmnpjEtETFVm446D', value: joy(0.2) }, | ||
{ who: 'j4SgrgDrzzGyfrxPe4ZgaKfByKyLo5SdsUXNfHzZJPh5R6f8q', value: joy(0.2) }, | ||
{ who: 'j4RxTMa1QVucodYPfQGA2JrHxZP944dfJ8qdDDYKU4QbJCWNP', value: joy(0.2) }, | ||
{ who: 'j4Rxkb1w9yB6WXroB2npKjRJJxwxbD8JjSQwMZFB31cf5aZAJ', value: joy(0.2) }, | ||
{ who: 'j4RyLBbSUBvipuQLkjLyUGeFWEzmrnfYdpteDa2gYNoM13qEg', value: joy(0.2) }, | ||
{ who: 'j4S998Thq5kQHyurofh8QfHrcFN2c1T19gTdMGUVVx5EHKgky', value: joy(0.2) }, | ||
], | ||
}, | ||
erasTotalStake: joy(130_000), | ||
}, | ||
}, | ||
}, | ||
} | ||
}, | ||
}, | ||
} satisfies Meta<Args> | ||
|
||
type Story = StoryObj<typeof ValidatorList> | ||
|
||
export const Statistics: Story = {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import React from 'react' | ||
|
||
import { PageLayout } from '@/app/components/PageLayout' | ||
import { RowGapBlock } from '@/common/components/page/PageContent' | ||
import { Statistics } from '@/common/components/statistics' | ||
import { Era } from '@/validators/components/statistics/Era' | ||
import { Rewards } from '@/validators/components/statistics/Rewards' | ||
import { Staking } from '@/validators/components/statistics/Staking' | ||
import { ValidatorsState } from '@/validators/components/statistics/ValidatorsState' | ||
import { useStakingStatistics } from '@/validators/hooks/useStakingStatistics' | ||
|
||
export const ValidatorList = () => { | ||
const { | ||
eraStartedOn, | ||
eraDuration, | ||
now, | ||
eraRewardPoints, | ||
totalRewards, | ||
lastRewards, | ||
idealStaking, | ||
currentStaking, | ||
stakingPercentage, | ||
activeValidatorsCount, | ||
allValidatorsCount, | ||
acitveNominatorsCount, | ||
allNominatorsCount, | ||
} = useStakingStatistics() | ||
|
||
return ( | ||
<PageLayout | ||
header={ | ||
<RowGapBlock gap={24}> | ||
<Statistics> | ||
<ValidatorsState | ||
activeValidatorsCount={activeValidatorsCount} | ||
allValidatorsCount={allValidatorsCount} | ||
acitveNominatorsCount={acitveNominatorsCount} | ||
allNominatorsCount={allNominatorsCount} | ||
/> | ||
<Staking | ||
idealStaking={idealStaking} | ||
currentStaking={currentStaking} | ||
stakingPercentage={stakingPercentage} | ||
/> | ||
<Era eraStartedOn={eraStartedOn} eraDuration={eraDuration} now={now} eraRewardPoints={eraRewardPoints} /> | ||
<Rewards totalRewards={totalRewards} lastRewards={lastRewards} /> | ||
</Statistics> | ||
</RowGapBlock> | ||
} | ||
main={<></>} | ||
/> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { Option, u64 } from '@polkadot/types' | ||
import { PalletStakingEraRewardPoints } from '@polkadot/types/lookup' | ||
import React, { useMemo } from 'react' | ||
|
||
import { PercentageChart } from '@/common/components/charts/PercentageChart' | ||
import { BlockIcon } from '@/common/components/icons' | ||
import { | ||
NumericValue, | ||
StatisticItem, | ||
StatisticItemSpacedContent, | ||
StatisticLabel, | ||
formatDurationDate, | ||
} from '@/common/components/statistics' | ||
import { DurationValue } from '@/common/components/typography/DurationValue' | ||
|
||
interface EraProps { | ||
eraStartedOn: Option<u64> | undefined | ||
eraDuration: number | ||
now: u64 | undefined | ||
eraRewardPoints: PalletStakingEraRewardPoints | undefined | ||
} | ||
|
||
export const Era = ({ eraStartedOn, eraDuration, now, eraRewardPoints }: EraProps) => { | ||
const { nextReward, percentage } = useMemo(() => { | ||
const nextReward = now && eraStartedOn && eraDuration - (Number(now) - Number(eraStartedOn)) | ||
const totalDuration = Number(eraDuration) | ||
const percentage = nextReward ? Math.ceil(100 - (nextReward / totalDuration) * 100) : 0 | ||
return { | ||
nextReward: formatDurationDate(nextReward ?? 0), | ||
totalDuration: formatDurationDate(totalDuration ?? 0), | ||
percentage, | ||
} | ||
}, [eraStartedOn, eraDuration, now]) | ||
return ( | ||
<StatisticItem | ||
title="era" | ||
tooltipText="One era consists of 6 epochs with 1 hour duration each." | ||
tooltipTitle="Era" | ||
tooltipLinkText="What is an era" | ||
tooltipLinkURL="TBD" | ||
actionElement={<PercentageChart percentage={percentage} small />} | ||
> | ||
<StatisticItemSpacedContent> | ||
<StatisticLabel>Next Reward</StatisticLabel> | ||
<div> | ||
<DurationValue value={nextReward} /> | ||
</div> | ||
</StatisticItemSpacedContent> | ||
<StatisticItemSpacedContent> | ||
<StatisticLabel>Blocks / Points</StatisticLabel> | ||
<div> | ||
{eraRewardPoints && ( | ||
<NumericValue> | ||
<BlockIcon /> | ||
{eraRewardPoints.total.toNumber() / 20} / {eraRewardPoints?.total.toNumber()} | ||
</NumericValue> | ||
)} | ||
</div> | ||
</StatisticItemSpacedContent> | ||
</StatisticItem> | ||
) | ||
} |
Oops, something went wrong.
9f9514b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
pioneer-2-storybook – ./
pioneer-2-storybook-joystream.vercel.app
pioneer-2-storybook-git-dev-joystream.vercel.app
pioneer-2-storybook.vercel.app
9f9514b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
pioneer-2 – ./
pioneer-2-joystream.vercel.app
pioneer-2.vercel.app
pioneer-2-git-dev-joystream.vercel.app