From 35b715cdfc584622f2be1fc1e1cbe7c3ecd07d95 Mon Sep 17 00:00:00 2001 From: isstuev Date: Thu, 19 Sep 2024 10:28:58 +0200 Subject: [PATCH] add blackfort validators --- configs/envs/.env.blackfort_testnet | 44 ++++++++ docs/ENVS.md | 2 +- lib/api/resources.ts | 40 +++++-- mocks/validators/blackfort.ts | 41 +++++++ mocks/validators/{index.ts => stability.ts} | 16 ++- pages/validators.tsx | 16 ++- stubs/validators.ts | 24 +++- tools/preset-sync/index.ts | 1 + types/api/validators.ts | 49 ++++++-- types/client/validators.ts | 1 + ui/pages/ValidatorsBlackfort.pw.tsx | 21 ++++ ui/pages/ValidatorsBlackfort.tsx | 106 ++++++++++++++++++ ...tors.pw.tsx => ValidatorsStability.pw.tsx} | 8 +- ...Validators.tsx => ValidatorsStability.tsx} | 52 +++++---- ...fort.pw.tsx_default_base-view-mobile-1.png | Bin 0 -> 34716 bytes ...kfort.pw.tsx_mobile_base-view-mobile-1.png | Bin 0 -> 46504 bytes ...ity.pw.tsx_default_base-view-mobile-1.png} | Bin ...lity.pw.tsx_mobile_base-view-mobile-1.png} | Bin ...tatus.tsx => ValidatorStabilityStatus.tsx} | 8 +- ui/validatorsBlackfort/ValidatorsCounters.tsx | 33 ++++++ .../ValidatorsList.tsx | 4 +- ui/validatorsBlackfort/ValidatorsListItem.tsx | 62 ++++++++++ ui/validatorsBlackfort/ValidatorsTable.tsx | 68 +++++++++++ .../ValidatorsTableItem.tsx | 50 +++++++++ ui/validatorsBlackfort/utils.ts | 16 +++ .../ValidatorsCounters.tsx | 9 +- .../ValidatorsFilter.tsx | 4 +- ui/validatorsStability/ValidatorsList.tsx | 22 ++++ .../ValidatorsListItem.tsx | 6 +- .../ValidatorsTable.tsx | 21 ++-- .../ValidatorsTableItem.tsx | 6 +- .../utils.ts | 9 +- 32 files changed, 648 insertions(+), 91 deletions(-) create mode 100644 configs/envs/.env.blackfort_testnet create mode 100644 mocks/validators/blackfort.ts rename mocks/validators/{index.ts => stability.ts} (56%) create mode 100644 ui/pages/ValidatorsBlackfort.pw.tsx create mode 100644 ui/pages/ValidatorsBlackfort.tsx rename ui/pages/{Validators.pw.tsx => ValidatorsStability.pw.tsx} (55%) rename ui/pages/{Validators.tsx => ValidatorsStability.tsx} (71%) create mode 100644 ui/pages/__screenshots__/ValidatorsBlackfort.pw.tsx_default_base-view-mobile-1.png create mode 100644 ui/pages/__screenshots__/ValidatorsBlackfort.pw.tsx_mobile_base-view-mobile-1.png rename ui/pages/__screenshots__/{Validators.pw.tsx_default_base-view-mobile-1.png => ValidatorsStability.pw.tsx_default_base-view-mobile-1.png} (100%) rename ui/pages/__screenshots__/{Validators.pw.tsx_mobile_base-view-mobile-1.png => ValidatorsStability.pw.tsx_mobile_base-view-mobile-1.png} (100%) rename ui/shared/statusTag/{ValidatorStatus.tsx => ValidatorStabilityStatus.tsx} (66%) create mode 100644 ui/validatorsBlackfort/ValidatorsCounters.tsx rename ui/{validators => validatorsBlackfort}/ValidatorsList.tsx (81%) create mode 100644 ui/validatorsBlackfort/ValidatorsListItem.tsx create mode 100644 ui/validatorsBlackfort/ValidatorsTable.tsx create mode 100644 ui/validatorsBlackfort/ValidatorsTableItem.tsx create mode 100644 ui/validatorsBlackfort/utils.ts rename ui/{validators => validatorsStability}/ValidatorsCounters.tsx (77%) rename ui/{validators => validatorsStability}/ValidatorsFilter.tsx (83%) create mode 100644 ui/validatorsStability/ValidatorsList.tsx rename ui/{validators => validatorsStability}/ValidatorsListItem.tsx (88%) rename ui/{validators => validatorsStability}/ValidatorsTable.tsx (71%) rename ui/{validators => validatorsStability}/ValidatorsTableItem.tsx (83%) rename ui/{validators => validatorsStability}/utils.ts (57%) diff --git a/configs/envs/.env.blackfort_testnet b/configs/envs/.env.blackfort_testnet new file mode 100644 index 0000000000..eeaad00054 --- /dev/null +++ b/configs/envs/.env.blackfort_testnet @@ -0,0 +1,44 @@ +# Set of ENVs for BXN Testnet network explorer +# https://blackfort-testnet.blockscout.com +# This is an auto-generated file. To update all values, run "yarn dev:preset:sync --name=blackfort_testnet" + +# Local ENVs +NEXT_PUBLIC_APP_PROTOCOL=http +NEXT_PUBLIC_APP_HOST=localhost +NEXT_PUBLIC_APP_PORT=3000 +NEXT_PUBLIC_APP_ENV=development +NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws + +# Instance ENVs +NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com +NEXT_PUBLIC_API_BASE_PATH=/ +NEXT_PUBLIC_API_HOST=blackfort-testnet.blockscout.com +NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml +NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}] +NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com +NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/blackfort-testnet.json +NEXT_PUBLIC_FOOTER_LINKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/footer-links/blackfort.json +NEXT_PUBLIC_GRAPHIQL_TRANSACTION=0xcb4140e22cde3412eb5aecdedf2403032c7a251f5c96b11122aca5b1b88ed953 +NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs'] +NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND=linear-gradient(92deg, rgb(3, 150, 254) 0.24%, rgb(36, 209, 245) 98.31%) +NEXT_PUBLIC_IS_TESTNET=true +NEXT_PUBLIC_MARKETPLACE_ENABLED=false +NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com +NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18 +NEXT_PUBLIC_NETWORK_CURRENCY_NAME=TBXN +NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=TBXN +NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/blackfort.svg +NEXT_PUBLIC_NETWORK_ICON_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/blackfort-dark.svg +NEXT_PUBLIC_NETWORK_ID=4777 +NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/blackfort.svg +NEXT_PUBLIC_NETWORK_LOGO_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/blackfort-dark.svg +NEXT_PUBLIC_NETWORK_NAME=BXN Testnet +NEXT_PUBLIC_NETWORK_RPC_URL=https://testnet.blackfort.network/rpc +NEXT_PUBLIC_NETWORK_SHORT_NAME=BXN Testnet +NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true +NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/blackfort.png +NEXT_PUBLIC_STATS_API_HOST=https://stats-blackfort-testnet.k8s.blockscout.com +NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout +NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true +NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com +NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE=blackfort \ No newline at end of file diff --git a/docs/ENVS.md b/docs/ENVS.md index f9e34fa288..4b8d6c10fc 100644 --- a/docs/ENVS.md +++ b/docs/ENVS.md @@ -679,7 +679,7 @@ The feature enables the Validators page which provides detailed information abou | Variable | Type| Description | Compulsoriness | Default value | Example value | Version | | --- | --- | --- | --- | --- | --- | --- | -| NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE | `'stability'` | Chain type | Required | - | `'stability'` | v1.25.0+ | +| NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE | `'stability' \| 'blackfort'` | Chain type | Required | - | `'stability'` | v1.25.0+ |   diff --git a/lib/api/resources.ts b/lib/api/resources.ts index 826046f9ac..cee68978d0 100644 --- a/lib/api/resources.ts +++ b/lib/api/resources.ts @@ -118,7 +118,15 @@ import type { TxInterpretationResponse } from 'types/api/txInterpretation'; import type { TTxsFilters, TTxsWithBlobsFilters } from 'types/api/txsFilters'; import type { TxStateChanges } from 'types/api/txStateChanges'; import type { UserOpsResponse, UserOp, UserOpsFilters, UserOpsAccount } from 'types/api/userOps'; -import type { ValidatorsCountersResponse, ValidatorsFilters, ValidatorsResponse, ValidatorsSorting } from 'types/api/validators'; +import type { + ValidatorsStabilityCountersResponse, + ValidatorsStabilityFilters, + ValidatorsStabilityResponse, + ValidatorsStabilitySorting, + ValidatorsBlackfortCountersResponse, + ValidatorsBlackfortResponse, + ValidatorsBlackfortSorting, +} from 'types/api/validators'; import type { VerifiedContractsSorting } from 'types/api/verifiedContracts'; import type { WithdrawalsResponse, WithdrawalsCounters } from 'types/api/withdrawals'; import type { @@ -897,14 +905,19 @@ export const RESOURCES = { }, // VALIDATORS - validators: { - path: '/api/v2/validators/:chainType', - pathParams: [ 'chainType' as const ], + validators_stability: { + path: '/api/v2/validators/stability', filterFields: [ 'address_hash' as const, 'state_filter' as const ], }, - validators_counters: { - path: '/api/v2/validators/:chainType/counters', - pathParams: [ 'chainType' as const ], + validators_stability_counters: { + path: '/api/v2/validators/stability/counters', + }, + validators_blackfort: { + path: '/api/v2/validators/blackfort', + filterFields: [], + }, + validators_blackfort_counters: { + path: '/api/v2/validators/blackfort/counters', }, // BLOBS @@ -1002,7 +1015,7 @@ export type PaginatedResources = 'blocks' | 'block_txs' | 'block_election_reward 'zksync_l2_txn_batches' | 'zksync_l2_txn_batch_txs' | 'withdrawals' | 'address_withdrawals' | 'block_withdrawals' | 'watchlist' | 'private_tags_address' | 'private_tags_tx' | -'domains_lookup' | 'addresses_lookup' | 'user_ops' | 'validators' | 'noves_address_history'; +'domains_lookup' | 'addresses_lookup' | 'user_ops' | 'validators_stability' | 'validators_blackfort' | 'noves_address_history'; export type PaginatedResponse = ResourcePayload; @@ -1123,8 +1136,10 @@ Q extends 'address_metadata_tag_types' ? PublicTagTypesResponse : Q extends 'blob' ? Blob : Q extends 'marketplace_dapps' ? Array : Q extends 'marketplace_dapp' ? MarketplaceAppOverview : -Q extends 'validators' ? ValidatorsResponse : -Q extends 'validators_counters' ? ValidatorsCountersResponse : +Q extends 'validators_stability' ? ValidatorsStabilityResponse : +Q extends 'validators_stability_counters' ? ValidatorsStabilityCountersResponse : +Q extends 'validators_blackfort' ? ValidatorsBlackfortResponse : +Q extends 'validators_blackfort_counters' ? ValidatorsBlackfortCountersResponse : Q extends 'shibarium_withdrawals' ? ShibariumWithdrawalsResponse : Q extends 'shibarium_deposits' ? ShibariumDepositsResponse : Q extends 'shibarium_withdrawals_count' ? number : @@ -1200,7 +1215,7 @@ Q extends 'verified_contracts' ? VerifiedContractsFilters : Q extends 'addresses_lookup' ? EnsAddressLookupFilters : Q extends 'domains_lookup' ? EnsDomainLookupFilters : Q extends 'user_ops' ? UserOpsFilters : -Q extends 'validators' ? ValidatorsFilters : +Q extends 'validators_stability' ? ValidatorsStabilityFilters : Q extends 'address_mud_tables' ? AddressMudTablesFilter : Q extends 'address_mud_records' ? AddressMudRecordsFilter : never; @@ -1214,7 +1229,8 @@ Q extends 'verified_contracts' ? VerifiedContractsSorting : Q extends 'address_txs' ? TransactionsSorting : Q extends 'addresses_lookup' ? EnsLookupSorting : Q extends 'domains_lookup' ? EnsLookupSorting : -Q extends 'validators' ? ValidatorsSorting : +Q extends 'validators_stability' ? ValidatorsStabilitySorting : +Q extends 'validators_blackfort' ? ValidatorsBlackfortSorting : Q extends 'address_mud_records' ? AddressMudRecordsSorting : never; /* eslint-enable @typescript-eslint/indent */ diff --git a/mocks/validators/blackfort.ts b/mocks/validators/blackfort.ts new file mode 100644 index 0000000000..6a5232a321 --- /dev/null +++ b/mocks/validators/blackfort.ts @@ -0,0 +1,41 @@ +import type { + ValidatorBlackfort, + ValidatorsBlackfortCountersResponse, + ValidatorsBlackfortResponse, +} from 'types/api/validators'; + +import * as addressMock from '../address/address'; + +export const validator1: ValidatorBlackfort = { + address: addressMock.withName, + name: 'testnet-3', + commission: 10, + delegated_amount: '0', + self_bonded_amount: '10000', +}; + +export const validator2: ValidatorBlackfort = { + address: addressMock.withEns, + name: 'GooseGanG GooseGanG GooseGanG GooseGanG GooseGanG GooseGanG GooseGanG', + commission: 5000, + delegated_amount: '10000', + self_bonded_amount: '100', +}; + +export const validator3: ValidatorBlackfort = { + address: addressMock.withoutName, + name: 'testnet-1', + commission: 0, + delegated_amount: '0', + self_bonded_amount: '10000', +}; + +export const validatorsResponse: ValidatorsBlackfortResponse = { + items: [ validator1, validator2, validator3 ], + next_page_params: null, +}; + +export const validatorsCountersResponse: ValidatorsBlackfortCountersResponse = { + new_validators_counter_24h: '11', + validators_counter: '140', +}; diff --git a/mocks/validators/index.ts b/mocks/validators/stability.ts similarity index 56% rename from mocks/validators/index.ts rename to mocks/validators/stability.ts index 22081cae8c..a85f596674 100644 --- a/mocks/validators/index.ts +++ b/mocks/validators/stability.ts @@ -1,31 +1,35 @@ -import type { Validator, ValidatorsCountersResponse, ValidatorsResponse } from 'types/api/validators'; +import type { + ValidatorStability, + ValidatorsStabilityCountersResponse, + ValidatorsStabilityResponse, +} from 'types/api/validators'; import * as addressMock from '../address/address'; -export const validator1: Validator = { +export const validator1: ValidatorStability = { address: addressMock.withName, blocks_validated_count: 7334224, state: 'active', }; -export const validator2: Validator = { +export const validator2: ValidatorStability = { address: addressMock.withEns, blocks_validated_count: 8937453, state: 'probation', }; -export const validator3: Validator = { +export const validator3: ValidatorStability = { address: addressMock.withoutName, blocks_validated_count: 1234, state: 'inactive', }; -export const validatorsResponse: ValidatorsResponse = { +export const validatorsResponse: ValidatorsStabilityResponse = { items: [ validator1, validator2, validator3 ], next_page_params: null, }; -export const validatorsCountersResponse: ValidatorsCountersResponse = { +export const validatorsCountersResponse: ValidatorsStabilityCountersResponse = { active_validators_counter: '42', active_validators_percentage: 7.14, new_validators_counter_24h: '11', diff --git a/pages/validators.tsx b/pages/validators.tsx index 42409f3fd3..a234316a58 100644 --- a/pages/validators.tsx +++ b/pages/validators.tsx @@ -4,7 +4,21 @@ import React from 'react'; import PageNextJs from 'nextjs/PageNextJs'; -const Validators = dynamic(() => import('ui/pages/Validators'), { ssr: false }); +import config from 'configs/app'; + +const validatorsFeature = config.features.validators; + +const Validators = dynamic(() => { + if (validatorsFeature.isEnabled && validatorsFeature.chainType === 'stability') { + return import('ui/pages/ValidatorsStability'); + } + + if (validatorsFeature.isEnabled && validatorsFeature.chainType === 'blackfort') { + return import('ui/pages/ValidatorsBlackfort'); + } + + throw new Error('Validators feature is not enabled.'); +}, { ssr: false }); const Page: NextPage = () => { return ( diff --git a/stubs/validators.ts b/stubs/validators.ts index 1717a59ec0..885818e115 100644 --- a/stubs/validators.ts +++ b/stubs/validators.ts @@ -1,16 +1,34 @@ -import type { Validator, ValidatorsCountersResponse } from 'types/api/validators'; +import type { + ValidatorStability, + ValidatorsStabilityCountersResponse, + ValidatorBlackfort, + ValidatorsBlackfortCountersResponse, +} from 'types/api/validators'; import { ADDRESS_PARAMS } from './addressParams'; -export const VALIDATOR: Validator = { +export const VALIDATOR_STABILITY: ValidatorStability = { address: ADDRESS_PARAMS, blocks_validated_count: 25987, state: 'active', }; -export const VALIDATORS_COUNTERS: ValidatorsCountersResponse = { +export const VALIDATORS_STABILITY_COUNTERS: ValidatorsStabilityCountersResponse = { active_validators_counter: '42', active_validators_percentage: 7.14, new_validators_counter_24h: '11', validators_counter: '140', }; + +export const VALIDATOR_BLACKFORT: ValidatorBlackfort = { + address: ADDRESS_PARAMS, + name: 'testnet-1', + commission: 10, + delegated_amount: '0', + self_bonded_amount: '10000', +}; + +export const VALIDATORS_BLACKFORT_COUNTERS: ValidatorsBlackfortCountersResponse = { + new_validators_counter_24h: '11', + validators_counter: '140', +}; diff --git a/tools/preset-sync/index.ts b/tools/preset-sync/index.ts index 5f83d060e1..5991d1cb7b 100755 --- a/tools/preset-sync/index.ts +++ b/tools/preset-sync/index.ts @@ -5,6 +5,7 @@ import path from 'path'; const PRESETS = { arbitrum: 'https://arbitrum.blockscout.com', base: 'https://base.blockscout.com', + blackfort_testnet: 'https://blackfort-testnet.blockscout.com', celo_alfajores: 'https://celo-alfajores.blockscout.com', eth: 'https://eth.blockscout.com', eth_goerli: 'https://eth-goerli.blockscout.com', diff --git a/types/api/validators.ts b/types/api/validators.ts index ad6e33de96..18fe50962b 100644 --- a/types/api/validators.ts +++ b/types/api/validators.ts @@ -1,38 +1,67 @@ import type { AddressParam } from './addressParams'; -export interface Validator { +export interface ValidatorStability { address: AddressParam; blocks_validated_count: number; state: 'active' | 'probation' | 'inactive'; } -export interface ValidatorsResponse { - items: Array; +export interface ValidatorsStabilityResponse { + items: Array; next_page_params: { 'address_hash': string; 'blocks_validated': string; 'items_count': string; - 'state': Validator['state']; + 'state': ValidatorStability['state']; } | null; } -export interface ValidatorsCountersResponse { +export interface ValidatorsStabilityCountersResponse { active_validators_counter: string; active_validators_percentage: number; new_validators_counter_24h: string; validators_counter: string; } -export interface ValidatorsFilters { +export interface ValidatorsStabilityFilters { // address_hash: string | undefined; // right now API doesn't support filtering by address_hash - state_filter: Validator['state'] | undefined; + state_filter: ValidatorStability['state'] | undefined; } -export interface ValidatorsSorting { +export interface ValidatorsStabilitySorting { sort: 'state' | 'blocks_validated'; order: 'asc' | 'desc'; } -export type ValidatorsSortingField = ValidatorsSorting['sort']; +export type ValidatorsStabilitySortingField = ValidatorsStabilitySorting['sort']; -export type ValidatorsSortingValue = `${ ValidatorsSortingField }-${ ValidatorsSorting['order'] }`; +export type ValidatorsStabilitySortingValue = `${ ValidatorsStabilitySortingField }-${ ValidatorsStabilitySorting['order'] }`; + +export interface ValidatorBlackfort { + address: AddressParam; + name: string; + commission: number; + delegated_amount: string; + self_bonded_amount: string; +} + +export interface ValidatorsBlackfortResponse { + items: Array; + next_page_params: { + 'address_hash': string; + } | null; +} + +export interface ValidatorsBlackfortCountersResponse { + new_validators_counter_24h: string; + validators_counter: string; +} + +export interface ValidatorsBlackfortSorting { + sort: 'address_hash'; + order: 'asc' | 'desc'; +} + +export type ValidatorsBlackfortSortingField = ValidatorsBlackfortSorting['sort']; + +export type ValidatorsBlackfortSortingValue = `${ ValidatorsBlackfortSortingField }-${ ValidatorsBlackfortSorting['order'] }`; diff --git a/types/client/validators.ts b/types/client/validators.ts index 9fdc949d5d..3b806c4366 100644 --- a/types/client/validators.ts +++ b/types/client/validators.ts @@ -2,6 +2,7 @@ import type { ArrayElement } from 'types/utils'; export const VALIDATORS_CHAIN_TYPE = [ 'stability', + 'blackfort', ] as const; export type ValidatorsChainType = ArrayElement; diff --git a/ui/pages/ValidatorsBlackfort.pw.tsx b/ui/pages/ValidatorsBlackfort.pw.tsx new file mode 100644 index 0000000000..05df5a40a3 --- /dev/null +++ b/ui/pages/ValidatorsBlackfort.pw.tsx @@ -0,0 +1,21 @@ +import React from 'react'; + +import * as validatorsMock from 'mocks/validators/blackfort'; +import { test, expect } from 'playwright/lib'; + +import Validators from './ValidatorsBlackfort'; + +const chainType = 'blackfort'; + +test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd }) => { + await mockEnvs([ + [ 'NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE', chainType ], + ]); + await mockApiResponse('validators_blackfort', validatorsMock.validatorsResponse); + await mockApiResponse('validators_blackfort_counters', validatorsMock.validatorsCountersResponse); + await mockTextAd(); + + const component = await render(); + + await expect(component).toHaveScreenshot(); +}); diff --git a/ui/pages/ValidatorsBlackfort.tsx b/ui/pages/ValidatorsBlackfort.tsx new file mode 100644 index 0000000000..32b45aa872 --- /dev/null +++ b/ui/pages/ValidatorsBlackfort.tsx @@ -0,0 +1,106 @@ +import { Box, Hide, HStack, Show } from '@chakra-ui/react'; +import { useRouter } from 'next/router'; +import React from 'react'; + +import type { + ValidatorsBlackfortSorting, + ValidatorsBlackfortSortingField, + ValidatorsBlackfortSortingValue, +} from 'types/api/validators'; + +import config from 'configs/app'; +import { generateListStub } from 'stubs/utils'; +import { VALIDATOR_BLACKFORT } from 'stubs/validators'; +import ActionBar, { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar'; +import DataListDisplay from 'ui/shared/DataListDisplay'; +import PageTitle from 'ui/shared/Page/PageTitle'; +import Pagination from 'ui/shared/pagination/Pagination'; +import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages'; +import getSortParamsFromValue from 'ui/shared/sort/getSortParamsFromValue'; +import getSortValueFromQuery from 'ui/shared/sort/getSortValueFromQuery'; +import Sort from 'ui/shared/sort/Sort'; +import { VALIDATORS_BLACKFORT_SORT_OPTIONS } from 'ui/validatorsBlackfort/utils'; +import ValidatorsCounters from 'ui/validatorsBlackfort/ValidatorsCounters'; +import ValidatorsList from 'ui/validatorsBlackfort/ValidatorsList'; +import ValidatorsTable from 'ui/validatorsBlackfort/ValidatorsTable'; + +const ValidatorsBlackfort = () => { + const router = useRouter(); + const [ sort, setSort ] = + React.useState( + getSortValueFromQuery(router.query, VALIDATORS_BLACKFORT_SORT_OPTIONS), + ); + + const { isError, isPlaceholderData, data, pagination, onSortingChange } = useQueryWithPages({ + resourceName: 'validators_blackfort', + sorting: getSortParamsFromValue(sort), + options: { + enabled: config.features.validators.isEnabled, + placeholderData: generateListStub<'validators_blackfort'>( + VALIDATOR_BLACKFORT, + 50, + { next_page_params: null }, + ), + }, + }); + + const handleSortChange = React.useCallback((value?: ValidatorsBlackfortSortingValue) => { + setSort(value); + onSortingChange(getSortParamsFromValue(value)); + }, [ onSortingChange ]); + + const sortButton = ( + + ); + + const actionBar = ( + <> + + { sortButton } + + { pagination.isVisible && ( + + + + ) } + + ); + + const content = data?.items ? ( + <> + + + + + + + + ) : null; + + return ( + + + + + + ); +}; + +export default ValidatorsBlackfort; diff --git a/ui/pages/Validators.pw.tsx b/ui/pages/ValidatorsStability.pw.tsx similarity index 55% rename from ui/pages/Validators.pw.tsx rename to ui/pages/ValidatorsStability.pw.tsx index 605328b313..fcd3467754 100644 --- a/ui/pages/Validators.pw.tsx +++ b/ui/pages/ValidatorsStability.pw.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import * as validatorsMock from 'mocks/validators/index'; +import * as validatorsMock from 'mocks/validators/stability'; import { test, expect } from 'playwright/lib'; -import Validators from './Validators'; +import Validators from './ValidatorsStability'; const chainType = 'stability'; @@ -11,8 +11,8 @@ test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd await mockEnvs([ [ 'NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE', chainType ], ]); - await mockApiResponse('validators', validatorsMock.validatorsResponse, { pathParams: { chainType } }); - await mockApiResponse('validators_counters', validatorsMock.validatorsCountersResponse, { pathParams: { chainType } }); + await mockApiResponse('validators_stability', validatorsMock.validatorsResponse); + await mockApiResponse('validators_stability_counters', validatorsMock.validatorsCountersResponse); await mockTextAd(); const component = await render(); diff --git a/ui/pages/Validators.tsx b/ui/pages/ValidatorsStability.tsx similarity index 71% rename from ui/pages/Validators.tsx rename to ui/pages/ValidatorsStability.tsx index 8ef1b8b93f..8b518b4356 100644 --- a/ui/pages/Validators.tsx +++ b/ui/pages/ValidatorsStability.tsx @@ -2,8 +2,12 @@ import { Box, Hide, HStack, Show } from '@chakra-ui/react'; import { useRouter } from 'next/router'; import React from 'react'; -import { getFeaturePayload } from 'configs/app/features/types'; -import type { ValidatorsFilters, ValidatorsSorting, ValidatorsSortingField, ValidatorsSortingValue } from 'types/api/validators'; +import type { + ValidatorsStabilityFilters, + ValidatorsStabilitySorting, + ValidatorsStabilitySortingField, + ValidatorsStabilitySortingValue, +} from 'types/api/validators'; import config from 'configs/app'; // import useDebounce from 'lib/hooks/useDebounce'; @@ -11,7 +15,7 @@ import useIsMobile from 'lib/hooks/useIsMobile'; import { apos } from 'lib/html-entities'; import getQueryParamString from 'lib/router/getQueryParamString'; import { generateListStub } from 'stubs/utils'; -import { VALIDATOR } from 'stubs/validators'; +import { VALIDATOR_STABILITY } from 'stubs/validators'; import ActionBar from 'ui/shared/ActionBar'; import DataListDisplay from 'ui/shared/DataListDisplay'; // import FilterInput from 'ui/shared/filters/FilterInput'; @@ -21,35 +25,36 @@ import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages'; import getSortParamsFromValue from 'ui/shared/sort/getSortParamsFromValue'; import getSortValueFromQuery from 'ui/shared/sort/getSortValueFromQuery'; import Sort from 'ui/shared/sort/Sort'; -import { SORT_OPTIONS } from 'ui/validators/utils'; -import ValidatorsCounters from 'ui/validators/ValidatorsCounters'; -import ValidatorsFilter from 'ui/validators/ValidatorsFilter'; -import ValidatorsList from 'ui/validators/ValidatorsList'; -import ValidatorsTable from 'ui/validators/ValidatorsTable'; +import { VALIDATORS_STABILITY_SORT_OPTIONS } from 'ui/validatorsStability/utils'; +import ValidatorsCounters from 'ui/validatorsStability/ValidatorsCounters'; +import ValidatorsFilter from 'ui/validatorsStability/ValidatorsFilter'; +import ValidatorsList from 'ui/validatorsStability/ValidatorsList'; +import ValidatorsTable from 'ui/validatorsStability/ValidatorsTable'; -const Validators = () => { +const ValidatorsStability = () => { const router = useRouter(); // const [ searchTerm, setSearchTerm ] = React.useState(getQueryParamString(router.query.address_hash) || undefined); - const [ statusFilter, setStatusFilter ] = React.useState(getQueryParamString(router.query.state_filter) as ValidatorsFilters['state_filter'] || undefined); - const [ sort, setSort ] = - React.useState(getSortValueFromQuery(router.query, SORT_OPTIONS)); + const [ statusFilter, setStatusFilter ] = + React.useState(getQueryParamString(router.query.state_filter) as ValidatorsStabilityFilters['state_filter'] || undefined); + const [ sort, setSort ] = React.useState( + getSortValueFromQuery(router.query, VALIDATORS_STABILITY_SORT_OPTIONS), + ); // const debouncedSearchTerm = useDebounce(searchTerm || '', 300); const isMobile = useIsMobile(); const { isError, isPlaceholderData, data, pagination, onFilterChange, onSortingChange } = useQueryWithPages({ - resourceName: 'validators', - pathParams: { chainType: getFeaturePayload(config.features.validators)?.chainType }, + resourceName: 'validators_stability', filters: { // address_hash: debouncedSearchTerm, state_filter: statusFilter, }, - sorting: getSortParamsFromValue(sort), + sorting: getSortParamsFromValue(sort), options: { enabled: config.features.validators.isEnabled, - placeholderData: generateListStub<'validators'>( - VALIDATOR, + placeholderData: generateListStub<'validators_stability'>( + VALIDATOR_STABILITY, 50, { next_page_params: null }, ), @@ -69,7 +74,7 @@ const Validators = () => { return; } - const state = value === 'all' ? undefined : value as ValidatorsFilters['state_filter']; + const state = value === 'all' ? undefined : value as ValidatorsStabilityFilters['state_filter']; onFilterChange({ // address_hash: debouncedSearchTerm, @@ -78,12 +83,13 @@ const Validators = () => { setStatusFilter(state); }, [ onFilterChange ]); - const handleSortChange = React.useCallback((value?: ValidatorsSortingValue) => { + const handleSortChange = React.useCallback((value?: ValidatorsStabilitySortingValue) => { setSort(value); onSortingChange(getSortParamsFromValue(value)); }, [ onSortingChange ]); - const filterMenu = ; + const filterMenu = + ; // const filterInput = ( // { ); @@ -141,7 +147,7 @@ const Validators = () => { { ); }; -export default Validators; +export default ValidatorsStability; diff --git a/ui/pages/__screenshots__/ValidatorsBlackfort.pw.tsx_default_base-view-mobile-1.png b/ui/pages/__screenshots__/ValidatorsBlackfort.pw.tsx_default_base-view-mobile-1.png new file mode 100644 index 0000000000000000000000000000000000000000..381b041f8846ad640baf8210f550435236bfd837 GIT binary patch literal 34716 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 E3o%iBEdT%j literal 0 HcmV?d00001 diff --git a/ui/pages/__screenshots__/ValidatorsBlackfort.pw.tsx_mobile_base-view-mobile-1.png b/ui/pages/__screenshots__/ValidatorsBlackfort.pw.tsx_mobile_base-view-mobile-1.png new file mode 100644 index 0000000000000000000000000000000000000000..4ead093d77be1e8288c108d4fed9a72ca1a89908 GIT binary patch literal 46504 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 literal 0 HcmV?d00001 diff --git a/ui/pages/__screenshots__/Validators.pw.tsx_default_base-view-mobile-1.png b/ui/pages/__screenshots__/ValidatorsStability.pw.tsx_default_base-view-mobile-1.png similarity index 100% rename from ui/pages/__screenshots__/Validators.pw.tsx_default_base-view-mobile-1.png rename to ui/pages/__screenshots__/ValidatorsStability.pw.tsx_default_base-view-mobile-1.png diff --git a/ui/pages/__screenshots__/Validators.pw.tsx_mobile_base-view-mobile-1.png b/ui/pages/__screenshots__/ValidatorsStability.pw.tsx_mobile_base-view-mobile-1.png similarity index 100% rename from ui/pages/__screenshots__/Validators.pw.tsx_mobile_base-view-mobile-1.png rename to ui/pages/__screenshots__/ValidatorsStability.pw.tsx_mobile_base-view-mobile-1.png diff --git a/ui/shared/statusTag/ValidatorStatus.tsx b/ui/shared/statusTag/ValidatorStabilityStatus.tsx similarity index 66% rename from ui/shared/statusTag/ValidatorStatus.tsx rename to ui/shared/statusTag/ValidatorStabilityStatus.tsx index 4386b55af5..93b1bb771f 100644 --- a/ui/shared/statusTag/ValidatorStatus.tsx +++ b/ui/shared/statusTag/ValidatorStabilityStatus.tsx @@ -1,15 +1,15 @@ import React from 'react'; -import type { Validator } from 'types/api/validators'; +import type { ValidatorStability } from 'types/api/validators'; import StatusTag from './StatusTag'; interface Props { - state: Validator['state']; + state: ValidatorStability['state']; isLoading?: boolean; } -const ValidatorStatus = ({ state, isLoading }: Props) => { +const ValidatorStabilityStatus = ({ state, isLoading }: Props) => { switch (state) { case 'active': return ; @@ -20,4 +20,4 @@ const ValidatorStatus = ({ state, isLoading }: Props) => { } }; -export default React.memo(ValidatorStatus); +export default React.memo(ValidatorStabilityStatus); diff --git a/ui/validatorsBlackfort/ValidatorsCounters.tsx b/ui/validatorsBlackfort/ValidatorsCounters.tsx new file mode 100644 index 0000000000..0901e57688 --- /dev/null +++ b/ui/validatorsBlackfort/ValidatorsCounters.tsx @@ -0,0 +1,33 @@ +import { Box } from '@chakra-ui/react'; +import React from 'react'; + +import config from 'configs/app'; +import useApiQuery from 'lib/api/useApiQuery'; +import { VALIDATORS_BLACKFORT_COUNTERS } from 'stubs/validators'; +import StatsWidget from 'ui/shared/stats/StatsWidget'; + +const ValidatorsCounters = () => { + const countersQuery = useApiQuery('validators_blackfort_counters', { + queryOptions: { + enabled: config.features.validators.isEnabled, + placeholderData: VALIDATORS_BLACKFORT_COUNTERS, + }, + }); + + if (!countersQuery.data) { + return null; + } + + return ( + + + + ); +}; + +export default React.memo(ValidatorsCounters); diff --git a/ui/validators/ValidatorsList.tsx b/ui/validatorsBlackfort/ValidatorsList.tsx similarity index 81% rename from ui/validators/ValidatorsList.tsx rename to ui/validatorsBlackfort/ValidatorsList.tsx index abb7305ca0..90c24fea7e 100644 --- a/ui/validators/ValidatorsList.tsx +++ b/ui/validatorsBlackfort/ValidatorsList.tsx @@ -1,11 +1,11 @@ import { Box } from '@chakra-ui/react'; import React from 'react'; -import type { Validator } from 'types/api/validators'; +import type { ValidatorBlackfort } from 'types/api/validators'; import ValidatorsListItem from './ValidatorsListItem'; -const ValidatorsList = ({ data, isLoading }: { data: Array; isLoading: boolean }) => { +const ValidatorsList = ({ data, isLoading }: { data: Array; isLoading: boolean }) => { return ( { data.map((item, index) => ( diff --git a/ui/validatorsBlackfort/ValidatorsListItem.tsx b/ui/validatorsBlackfort/ValidatorsListItem.tsx new file mode 100644 index 0000000000..a01a144378 --- /dev/null +++ b/ui/validatorsBlackfort/ValidatorsListItem.tsx @@ -0,0 +1,62 @@ +import { Flex, Skeleton } from '@chakra-ui/react'; +import BigNumber from 'bignumber.js'; +import React from 'react'; + +import type { ValidatorBlackfort } from 'types/api/validators'; + +import config from 'configs/app'; +import { currencyUnits } from 'lib/units'; +import AddressEntity from 'ui/shared/entities/address/AddressEntity'; +import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; +import TruncatedValue from 'ui/shared/TruncatedValue'; + +interface Props { + data: ValidatorBlackfort; + isLoading?: boolean; +} + +const ValidatorsListItem = ({ data, isLoading }: Props) => { + + return ( + + + Address + + + + + Name + + + + + Commission + + + { `${ data.commission / 100 }%` } + + + + Self bonded + + + { `${ BigNumber(data.self_bonded_amount).div(BigNumber(10 ** config.chain.currency.decimals)).toFormat() } ${ currencyUnits.ether }` } + + + + Delegated amount + + + { `${ BigNumber(data.delegated_amount).div(BigNumber(10 ** config.chain.currency.decimals)).toFormat() } ${ currencyUnits.ether }` } + + + + + ); +}; + +export default React.memo(ValidatorsListItem); diff --git a/ui/validatorsBlackfort/ValidatorsTable.tsx b/ui/validatorsBlackfort/ValidatorsTable.tsx new file mode 100644 index 0000000000..cf7b839b7f --- /dev/null +++ b/ui/validatorsBlackfort/ValidatorsTable.tsx @@ -0,0 +1,68 @@ +import { Table, Tbody, Tr, Th, Link } from '@chakra-ui/react'; +import React from 'react'; + +import type { + ValidatorBlackfort, + ValidatorsBlackfortSorting, + ValidatorsBlackfortSortingField, + ValidatorsBlackfortSortingValue, +} from 'types/api/validators'; + +import { currencyUnits } from 'lib/units'; +import IconSvg from 'ui/shared/IconSvg'; +import getNextSortValue from 'ui/shared/sort/getNextSortValue'; +import { default as Thead } from 'ui/shared/TheadSticky'; + +import { VALIDATORS_BLACKFORT_SORT_SEQUENCE } from './utils'; +import ValidatorsTableItem from './ValidatorsTableItem'; + +interface Props { + data: Array; + sort: ValidatorsBlackfortSortingValue | undefined; + setSorting: (val: ValidatorsBlackfortSortingValue | undefined) => void; + isLoading?: boolean; + top: number; +} + +const ValidatorsTable = ({ data, sort, setSorting, isLoading, top }: Props) => { + const sortIconTransform = sort?.includes('asc' as ValidatorsBlackfortSorting['order']) ? 'rotate(-90deg)' : 'rotate(90deg)'; + + const onSortToggle = React.useCallback((field: ValidatorsBlackfortSortingField) => () => { + const value = getNextSortValue(VALIDATORS_BLACKFORT_SORT_SEQUENCE, field)(sort); + setSorting(value); + }, [ sort, setSorting ]); + + return ( + + + + + + + + + + + + { data.map((item, index) => ( + + )) } + +
+ + { sort?.includes('address') && } + Validator’s address + + NameCommission{ `Self bonded ${ currencyUnits.ether }` }{ `Delegated amount ${ currencyUnits.ether }` }
+ ); +}; + +export default React.memo(ValidatorsTable); diff --git a/ui/validatorsBlackfort/ValidatorsTableItem.tsx b/ui/validatorsBlackfort/ValidatorsTableItem.tsx new file mode 100644 index 0000000000..35e7cd0cbc --- /dev/null +++ b/ui/validatorsBlackfort/ValidatorsTableItem.tsx @@ -0,0 +1,50 @@ +import { Tr, Td, Skeleton, Flex } from '@chakra-ui/react'; +import BigNumber from 'bignumber.js'; +import React from 'react'; + +import type { ValidatorBlackfort } from 'types/api/validators'; + +import config from 'configs/app'; +import AddressEntity from 'ui/shared/entities/address/AddressEntity'; +import TruncatedValue from 'ui/shared/TruncatedValue'; + +interface Props { + data: ValidatorBlackfort; + isLoading?: boolean; +} + +const ValidatorsTableItem = ({ data, isLoading }: Props) => { + return ( + + + + + + + + + + + + { `${ data.commission / 100 }%` } + + + + + { BigNumber(data.self_bonded_amount).div(BigNumber(10 ** config.chain.currency.decimals)).toFormat() } + + + + + { BigNumber(data.delegated_amount).div(BigNumber(10 ** config.chain.currency.decimals)).toFormat() } + + + + ); +}; + +export default React.memo(ValidatorsTableItem); diff --git a/ui/validatorsBlackfort/utils.ts b/ui/validatorsBlackfort/utils.ts new file mode 100644 index 0000000000..a146199674 --- /dev/null +++ b/ui/validatorsBlackfort/utils.ts @@ -0,0 +1,16 @@ +import type { + ValidatorsBlackfortSortingValue, + ValidatorsBlackfortSortingField, +} from 'types/api/validators'; + +import type { TOption } from 'ui/shared/sort/Option'; + +export const VALIDATORS_BLACKFORT_SORT_OPTIONS: Array> = [ + { title: 'Default', id: undefined }, + { title: 'Address descending', id: 'address_hash-desc' }, + { title: 'Address ascending', id: 'address_hash-asc' }, +]; + +export const VALIDATORS_BLACKFORT_SORT_SEQUENCE: Record> = { + address_hash: [ 'address_hash-desc', 'address_hash-asc', undefined ], +}; diff --git a/ui/validators/ValidatorsCounters.tsx b/ui/validatorsStability/ValidatorsCounters.tsx similarity index 77% rename from ui/validators/ValidatorsCounters.tsx rename to ui/validatorsStability/ValidatorsCounters.tsx index 2e056ff1aa..3e76e81312 100644 --- a/ui/validators/ValidatorsCounters.tsx +++ b/ui/validatorsStability/ValidatorsCounters.tsx @@ -1,19 +1,16 @@ import { Box } from '@chakra-ui/react'; import React from 'react'; -import { getFeaturePayload } from 'configs/app/features/types'; - import config from 'configs/app'; import useApiQuery from 'lib/api/useApiQuery'; -import { VALIDATORS_COUNTERS } from 'stubs/validators'; +import { VALIDATORS_STABILITY_COUNTERS } from 'stubs/validators'; import StatsWidget from 'ui/shared/stats/StatsWidget'; const ValidatorsCounters = () => { - const countersQuery = useApiQuery('validators_counters', { - pathParams: { chainType: getFeaturePayload(config.features.validators)?.chainType }, + const countersQuery = useApiQuery('validators_stability_counters', { queryOptions: { enabled: config.features.validators.isEnabled, - placeholderData: VALIDATORS_COUNTERS, + placeholderData: VALIDATORS_STABILITY_COUNTERS, }, }); diff --git a/ui/validators/ValidatorsFilter.tsx b/ui/validatorsStability/ValidatorsFilter.tsx similarity index 83% rename from ui/validators/ValidatorsFilter.tsx rename to ui/validatorsStability/ValidatorsFilter.tsx index d0cf690c73..bcda1b5984 100644 --- a/ui/validators/ValidatorsFilter.tsx +++ b/ui/validatorsStability/ValidatorsFilter.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import type { ValidatorsFilters } from 'types/api/validators'; +import type { ValidatorsStabilityFilters } from 'types/api/validators'; import PopoverFilterRadio from 'ui/shared/filters/PopoverFilterRadio'; @@ -13,7 +13,7 @@ const OPTIONS = [ interface Props { hasActiveFilter: boolean; - defaultValue: ValidatorsFilters['state_filter'] | undefined; + defaultValue: ValidatorsStabilityFilters['state_filter'] | undefined; onChange: (nextValue: string | Array) => void; } diff --git a/ui/validatorsStability/ValidatorsList.tsx b/ui/validatorsStability/ValidatorsList.tsx new file mode 100644 index 0000000000..1193a908c3 --- /dev/null +++ b/ui/validatorsStability/ValidatorsList.tsx @@ -0,0 +1,22 @@ +import { Box } from '@chakra-ui/react'; +import React from 'react'; + +import type { ValidatorStability } from 'types/api/validators'; + +import ValidatorsListItem from './ValidatorsListItem'; + +const ValidatorsList = ({ data, isLoading }: { data: Array; isLoading: boolean }) => { + return ( + + { data.map((item, index) => ( + + )) } + + ); +}; + +export default React.memo(ValidatorsList); diff --git a/ui/validators/ValidatorsListItem.tsx b/ui/validatorsStability/ValidatorsListItem.tsx similarity index 88% rename from ui/validators/ValidatorsListItem.tsx rename to ui/validatorsStability/ValidatorsListItem.tsx index 35c97654d6..668bad3e86 100644 --- a/ui/validators/ValidatorsListItem.tsx +++ b/ui/validatorsStability/ValidatorsListItem.tsx @@ -1,14 +1,14 @@ import { Skeleton } from '@chakra-ui/react'; import React from 'react'; -import type { Validator } from 'types/api/validators'; +import type { ValidatorStability } from 'types/api/validators'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; -import ValidatorStatus from 'ui/shared/statusTag/ValidatorStatus'; +import ValidatorStatus from 'ui/shared/statusTag/ValidatorStabilityStatus'; interface Props { - data: Validator; + data: ValidatorStability; isLoading?: boolean; } diff --git a/ui/validators/ValidatorsTable.tsx b/ui/validatorsStability/ValidatorsTable.tsx similarity index 71% rename from ui/validators/ValidatorsTable.tsx rename to ui/validatorsStability/ValidatorsTable.tsx index 3955fa01a8..dd68f96109 100644 --- a/ui/validators/ValidatorsTable.tsx +++ b/ui/validatorsStability/ValidatorsTable.tsx @@ -1,28 +1,33 @@ import { Table, Tbody, Tr, Th, Link } from '@chakra-ui/react'; import React from 'react'; -import type { Validator, ValidatorsSorting, ValidatorsSortingField, ValidatorsSortingValue } from 'types/api/validators'; +import type { + ValidatorStability, + ValidatorsStabilitySorting, + ValidatorsStabilitySortingField, + ValidatorsStabilitySortingValue, +} from 'types/api/validators'; import { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar'; import IconSvg from 'ui/shared/IconSvg'; import getNextSortValue from 'ui/shared/sort/getNextSortValue'; import { default as Thead } from 'ui/shared/TheadSticky'; -import { SORT_SEQUENCE } from './utils'; +import { VALIDATORS_STABILITY_SORT_SEQUENCE } from './utils'; import ValidatorsTableItem from './ValidatorsTableItem'; interface Props { - data: Array; - sort: ValidatorsSortingValue | undefined; - setSorting: (val: ValidatorsSortingValue | undefined) => void; + data: Array; + sort: ValidatorsStabilitySortingValue | undefined; + setSorting: (val: ValidatorsStabilitySortingValue | undefined) => void; isLoading?: boolean; } const ValidatorsTable = ({ data, sort, setSorting, isLoading }: Props) => { - const sortIconTransform = sort?.includes('asc' as ValidatorsSorting['order']) ? 'rotate(-90deg)' : 'rotate(90deg)'; + const sortIconTransform = sort?.includes('asc' as ValidatorsStabilitySorting['order']) ? 'rotate(-90deg)' : 'rotate(90deg)'; - const onSortToggle = React.useCallback((field: ValidatorsSortingField) => () => { - const value = getNextSortValue(SORT_SEQUENCE, field)(sort); + const onSortToggle = React.useCallback((field: ValidatorsStabilitySortingField) => () => { + const value = getNextSortValue(VALIDATORS_STABILITY_SORT_SEQUENCE, field)(sort); setSorting(value); }, [ sort, setSorting ]); diff --git a/ui/validators/ValidatorsTableItem.tsx b/ui/validatorsStability/ValidatorsTableItem.tsx similarity index 83% rename from ui/validators/ValidatorsTableItem.tsx rename to ui/validatorsStability/ValidatorsTableItem.tsx index e4c600357c..7a1231b796 100644 --- a/ui/validators/ValidatorsTableItem.tsx +++ b/ui/validatorsStability/ValidatorsTableItem.tsx @@ -1,13 +1,13 @@ import { Tr, Td, Skeleton } from '@chakra-ui/react'; import React from 'react'; -import type { Validator } from 'types/api/validators'; +import type { ValidatorStability } from 'types/api/validators'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; -import ValidatorStatus from 'ui/shared/statusTag/ValidatorStatus'; +import ValidatorStatus from 'ui/shared/statusTag/ValidatorStabilityStatus'; interface Props { - data: Validator; + data: ValidatorStability; isLoading?: boolean; } diff --git a/ui/validators/utils.ts b/ui/validatorsStability/utils.ts similarity index 57% rename from ui/validators/utils.ts rename to ui/validatorsStability/utils.ts index 71558189c3..d3e37f8bf0 100644 --- a/ui/validators/utils.ts +++ b/ui/validatorsStability/utils.ts @@ -1,8 +1,11 @@ -import type { ValidatorsSortingValue, ValidatorsSortingField } from 'types/api/validators'; +import type { + ValidatorsStabilitySortingValue, + ValidatorsStabilitySortingField, +} from 'types/api/validators'; import type { TOption } from 'ui/shared/sort/Option'; -export const SORT_OPTIONS: Array> = [ +export const VALIDATORS_STABILITY_SORT_OPTIONS: Array> = [ { title: 'Default', id: undefined }, { title: 'Status descending', id: 'state-desc' }, { title: 'Status ascending', id: 'state-asc' }, @@ -10,7 +13,7 @@ export const SORT_OPTIONS: Array> = [ { title: 'Blocks validated ascending', id: 'blocks_validated-asc' }, ]; -export const SORT_SEQUENCE: Record> = { +export const VALIDATORS_STABILITY_SORT_SEQUENCE: Record> = { state: [ 'state-desc', 'state-asc', undefined ], blocks_validated: [ 'blocks_validated-desc', 'blocks_validated-asc', undefined ], };