Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
35b715cd
Commit
35b715cd
authored
Sep 19, 2024
by
isstuev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add blackfort validators
parent
99446524
Changes
32
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
648 additions
and
91 deletions
+648
-91
.env.blackfort_testnet
configs/envs/.env.blackfort_testnet
+44
-0
ENVS.md
docs/ENVS.md
+1
-1
resources.ts
lib/api/resources.ts
+28
-12
blackfort.ts
mocks/validators/blackfort.ts
+41
-0
stability.ts
mocks/validators/stability.ts
+10
-6
validators.tsx
pages/validators.tsx
+15
-1
validators.ts
stubs/validators.ts
+21
-3
index.ts
tools/preset-sync/index.ts
+1
-0
validators.ts
types/api/validators.ts
+39
-10
validators.ts
types/client/validators.ts
+1
-0
ValidatorsBlackfort.pw.tsx
ui/pages/ValidatorsBlackfort.pw.tsx
+21
-0
ValidatorsBlackfort.tsx
ui/pages/ValidatorsBlackfort.tsx
+106
-0
ValidatorsStability.pw.tsx
ui/pages/ValidatorsStability.pw.tsx
+4
-4
ValidatorsStability.tsx
ui/pages/ValidatorsStability.tsx
+29
-23
ValidatorsBlackfort.pw.tsx_default_base-view-mobile-1.png
...ValidatorsBlackfort.pw.tsx_default_base-view-mobile-1.png
+0
-0
ValidatorsBlackfort.pw.tsx_mobile_base-view-mobile-1.png
.../ValidatorsBlackfort.pw.tsx_mobile_base-view-mobile-1.png
+0
-0
ValidatorsStability.pw.tsx_default_base-view-mobile-1.png
...ValidatorsStability.pw.tsx_default_base-view-mobile-1.png
+0
-0
ValidatorsStability.pw.tsx_mobile_base-view-mobile-1.png
.../ValidatorsStability.pw.tsx_mobile_base-view-mobile-1.png
+0
-0
ValidatorStabilityStatus.tsx
ui/shared/statusTag/ValidatorStabilityStatus.tsx
+4
-4
ValidatorsCounters.tsx
ui/validatorsBlackfort/ValidatorsCounters.tsx
+33
-0
ValidatorsList.tsx
ui/validatorsBlackfort/ValidatorsList.tsx
+2
-2
ValidatorsListItem.tsx
ui/validatorsBlackfort/ValidatorsListItem.tsx
+62
-0
ValidatorsTable.tsx
ui/validatorsBlackfort/ValidatorsTable.tsx
+68
-0
ValidatorsTableItem.tsx
ui/validatorsBlackfort/ValidatorsTableItem.tsx
+50
-0
utils.ts
ui/validatorsBlackfort/utils.ts
+16
-0
ValidatorsCounters.tsx
ui/validatorsStability/ValidatorsCounters.tsx
+3
-6
ValidatorsFilter.tsx
ui/validatorsStability/ValidatorsFilter.tsx
+2
-2
ValidatorsList.tsx
ui/validatorsStability/ValidatorsList.tsx
+22
-0
ValidatorsListItem.tsx
ui/validatorsStability/ValidatorsListItem.tsx
+3
-3
ValidatorsTable.tsx
ui/validatorsStability/ValidatorsTable.tsx
+13
-8
ValidatorsTableItem.tsx
ui/validatorsStability/ValidatorsTableItem.tsx
+3
-3
utils.ts
ui/validatorsStability/utils.ts
+6
-3
No files found.
configs/envs/.env.blackfort_testnet
0 → 100644
View file @
35b715cd
# 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
docs/ENVS.md
View file @
35b715cd
...
@@ -679,7 +679,7 @@ The feature enables the Validators page which provides detailed information abou
...
@@ -679,7 +679,7 @@ The feature enables the Validators page which provides detailed information abou
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
| 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+ |
...
...
lib/api/resources.ts
View file @
35b715cd
...
@@ -118,7 +118,15 @@ import type { TxInterpretationResponse } from 'types/api/txInterpretation';
...
@@ -118,7 +118,15 @@ import type { TxInterpretationResponse } from 'types/api/txInterpretation';
import
type
{
TTxsFilters
,
TTxsWithBlobsFilters
}
from
'
types/api/txsFilters
'
;
import
type
{
TTxsFilters
,
TTxsWithBlobsFilters
}
from
'
types/api/txsFilters
'
;
import
type
{
TxStateChanges
}
from
'
types/api/txStateChanges
'
;
import
type
{
TxStateChanges
}
from
'
types/api/txStateChanges
'
;
import
type
{
UserOpsResponse
,
UserOp
,
UserOpsFilters
,
UserOpsAccount
}
from
'
types/api/userOps
'
;
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
{
VerifiedContractsSorting
}
from
'
types/api/verifiedContracts
'
;
import
type
{
WithdrawalsResponse
,
WithdrawalsCounters
}
from
'
types/api/withdrawals
'
;
import
type
{
WithdrawalsResponse
,
WithdrawalsCounters
}
from
'
types/api/withdrawals
'
;
import
type
{
import
type
{
...
@@ -897,14 +905,19 @@ export const RESOURCES = {
...
@@ -897,14 +905,19 @@ export const RESOURCES = {
},
},
// VALIDATORS
// VALIDATORS
validators
:
{
validators_stability
:
{
path
:
'
/api/v2/validators/:chainType
'
,
path
:
'
/api/v2/validators/stability
'
,
pathParams
:
[
'
chainType
'
as
const
],
filterFields
:
[
'
address_hash
'
as
const
,
'
state_filter
'
as
const
],
filterFields
:
[
'
address_hash
'
as
const
,
'
state_filter
'
as
const
],
},
},
validators_counters
:
{
validators_stability_counters
:
{
path
:
'
/api/v2/validators/:chainType/counters
'
,
path
:
'
/api/v2/validators/stability/counters
'
,
pathParams
:
[
'
chainType
'
as
const
],
},
validators_blackfort
:
{
path
:
'
/api/v2/validators/blackfort
'
,
filterFields
:
[],
},
validators_blackfort_counters
:
{
path
:
'
/api/v2/validators/blackfort/counters
'
,
},
},
// BLOBS
// BLOBS
...
@@ -1002,7 +1015,7 @@ export type PaginatedResources = 'blocks' | 'block_txs' | 'block_election_reward
...
@@ -1002,7 +1015,7 @@ export type PaginatedResources = 'blocks' | 'block_txs' | 'block_election_reward
'
zksync_l2_txn_batches
'
|
'
zksync_l2_txn_batch_txs
'
|
'
zksync_l2_txn_batches
'
|
'
zksync_l2_txn_batch_txs
'
|
'
withdrawals
'
|
'
address_withdrawals
'
|
'
block_withdrawals
'
|
'
withdrawals
'
|
'
address_withdrawals
'
|
'
block_withdrawals
'
|
'
watchlist
'
|
'
private_tags_address
'
|
'
private_tags_tx
'
|
'
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
<
Q
extends
PaginatedResources
>
=
ResourcePayload
<
Q
>
;
export
type
PaginatedResponse
<
Q
extends
PaginatedResources
>
=
ResourcePayload
<
Q
>
;
...
@@ -1123,8 +1136,10 @@ Q extends 'address_metadata_tag_types' ? PublicTagTypesResponse :
...
@@ -1123,8 +1136,10 @@ Q extends 'address_metadata_tag_types' ? PublicTagTypesResponse :
Q
extends
'
blob
'
?
Blob
:
Q
extends
'
blob
'
?
Blob
:
Q
extends
'
marketplace_dapps
'
?
Array
<
MarketplaceAppOverview
>
:
Q
extends
'
marketplace_dapps
'
?
Array
<
MarketplaceAppOverview
>
:
Q
extends
'
marketplace_dapp
'
?
MarketplaceAppOverview
:
Q
extends
'
marketplace_dapp
'
?
MarketplaceAppOverview
:
Q
extends
'
validators
'
?
ValidatorsResponse
:
Q
extends
'
validators_stability
'
?
ValidatorsStabilityResponse
:
Q
extends
'
validators_counters
'
?
ValidatorsCountersResponse
:
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_withdrawals
'
?
ShibariumWithdrawalsResponse
:
Q
extends
'
shibarium_deposits
'
?
ShibariumDepositsResponse
:
Q
extends
'
shibarium_deposits
'
?
ShibariumDepositsResponse
:
Q
extends
'
shibarium_withdrawals_count
'
?
number
:
Q
extends
'
shibarium_withdrawals_count
'
?
number
:
...
@@ -1200,7 +1215,7 @@ Q extends 'verified_contracts' ? VerifiedContractsFilters :
...
@@ -1200,7 +1215,7 @@ Q extends 'verified_contracts' ? VerifiedContractsFilters :
Q
extends
'
addresses_lookup
'
?
EnsAddressLookupFilters
:
Q
extends
'
addresses_lookup
'
?
EnsAddressLookupFilters
:
Q
extends
'
domains_lookup
'
?
EnsDomainLookupFilters
:
Q
extends
'
domains_lookup
'
?
EnsDomainLookupFilters
:
Q
extends
'
user_ops
'
?
UserOpsFilters
:
Q
extends
'
user_ops
'
?
UserOpsFilters
:
Q
extends
'
validators
'
?
Validators
Filters
:
Q
extends
'
validators
_stability
'
?
ValidatorsStability
Filters
:
Q
extends
'
address_mud_tables
'
?
AddressMudTablesFilter
:
Q
extends
'
address_mud_tables
'
?
AddressMudTablesFilter
:
Q
extends
'
address_mud_records
'
?
AddressMudRecordsFilter
:
Q
extends
'
address_mud_records
'
?
AddressMudRecordsFilter
:
never
;
never
;
...
@@ -1214,7 +1229,8 @@ Q extends 'verified_contracts' ? VerifiedContractsSorting :
...
@@ -1214,7 +1229,8 @@ Q extends 'verified_contracts' ? VerifiedContractsSorting :
Q
extends
'
address_txs
'
?
TransactionsSorting
:
Q
extends
'
address_txs
'
?
TransactionsSorting
:
Q
extends
'
addresses_lookup
'
?
EnsLookupSorting
:
Q
extends
'
addresses_lookup
'
?
EnsLookupSorting
:
Q
extends
'
domains_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
:
Q
extends
'
address_mud_records
'
?
AddressMudRecordsSorting
:
never
;
never
;
/* eslint-enable @typescript-eslint/indent */
/* eslint-enable @typescript-eslint/indent */
mocks/validators/blackfort.ts
0 → 100644
View file @
35b715cd
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
'
,
};
mocks/validators/
index
.ts
→
mocks/validators/
stability
.ts
View file @
35b715cd
import
type
{
Validator
,
ValidatorsCountersResponse
,
ValidatorsResponse
}
from
'
types/api/validators
'
;
import
type
{
ValidatorStability
,
ValidatorsStabilityCountersResponse
,
ValidatorsStabilityResponse
,
}
from
'
types/api/validators
'
;
import
*
as
addressMock
from
'
../address/address
'
;
import
*
as
addressMock
from
'
../address/address
'
;
export
const
validator1
:
Validator
=
{
export
const
validator1
:
Validator
Stability
=
{
address
:
addressMock
.
withName
,
address
:
addressMock
.
withName
,
blocks_validated_count
:
7334224
,
blocks_validated_count
:
7334224
,
state
:
'
active
'
,
state
:
'
active
'
,
};
};
export
const
validator2
:
Validator
=
{
export
const
validator2
:
Validator
Stability
=
{
address
:
addressMock
.
withEns
,
address
:
addressMock
.
withEns
,
blocks_validated_count
:
8937453
,
blocks_validated_count
:
8937453
,
state
:
'
probation
'
,
state
:
'
probation
'
,
};
};
export
const
validator3
:
Validator
=
{
export
const
validator3
:
Validator
Stability
=
{
address
:
addressMock
.
withoutName
,
address
:
addressMock
.
withoutName
,
blocks_validated_count
:
1234
,
blocks_validated_count
:
1234
,
state
:
'
inactive
'
,
state
:
'
inactive
'
,
};
};
export
const
validatorsResponse
:
ValidatorsResponse
=
{
export
const
validatorsResponse
:
Validators
Stability
Response
=
{
items
:
[
validator1
,
validator2
,
validator3
],
items
:
[
validator1
,
validator2
,
validator3
],
next_page_params
:
null
,
next_page_params
:
null
,
};
};
export
const
validatorsCountersResponse
:
ValidatorsCountersResponse
=
{
export
const
validatorsCountersResponse
:
Validators
Stability
CountersResponse
=
{
active_validators_counter
:
'
42
'
,
active_validators_counter
:
'
42
'
,
active_validators_percentage
:
7.14
,
active_validators_percentage
:
7.14
,
new_validators_counter_24h
:
'
11
'
,
new_validators_counter_24h
:
'
11
'
,
...
...
pages/validators.tsx
View file @
35b715cd
...
@@ -4,7 +4,21 @@ import React from 'react';
...
@@ -4,7 +4,21 @@ import React from 'react';
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
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
=
()
=>
{
const
Page
:
NextPage
=
()
=>
{
return
(
return
(
...
...
stubs/validators.ts
View file @
35b715cd
import
type
{
Validator
,
ValidatorsCountersResponse
}
from
'
types/api/validators
'
;
import
type
{
ValidatorStability
,
ValidatorsStabilityCountersResponse
,
ValidatorBlackfort
,
ValidatorsBlackfortCountersResponse
,
}
from
'
types/api/validators
'
;
import
{
ADDRESS_PARAMS
}
from
'
./addressParams
'
;
import
{
ADDRESS_PARAMS
}
from
'
./addressParams
'
;
export
const
VALIDATOR
:
Validator
=
{
export
const
VALIDATOR
_STABILITY
:
ValidatorStability
=
{
address
:
ADDRESS_PARAMS
,
address
:
ADDRESS_PARAMS
,
blocks_validated_count
:
25987
,
blocks_validated_count
:
25987
,
state
:
'
active
'
,
state
:
'
active
'
,
};
};
export
const
VALIDATORS_
COUNTERS
:
Validators
CountersResponse
=
{
export
const
VALIDATORS_
STABILITY_COUNTERS
:
ValidatorsStability
CountersResponse
=
{
active_validators_counter
:
'
42
'
,
active_validators_counter
:
'
42
'
,
active_validators_percentage
:
7.14
,
active_validators_percentage
:
7.14
,
new_validators_counter_24h
:
'
11
'
,
new_validators_counter_24h
:
'
11
'
,
validators_counter
:
'
140
'
,
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
'
,
};
tools/preset-sync/index.ts
View file @
35b715cd
...
@@ -5,6 +5,7 @@ import path from 'path';
...
@@ -5,6 +5,7 @@ import path from 'path';
const
PRESETS
=
{
const
PRESETS
=
{
arbitrum
:
'
https://arbitrum.blockscout.com
'
,
arbitrum
:
'
https://arbitrum.blockscout.com
'
,
base
:
'
https://base.blockscout.com
'
,
base
:
'
https://base.blockscout.com
'
,
blackfort_testnet
:
'
https://blackfort-testnet.blockscout.com
'
,
celo_alfajores
:
'
https://celo-alfajores.blockscout.com
'
,
celo_alfajores
:
'
https://celo-alfajores.blockscout.com
'
,
eth
:
'
https://eth.blockscout.com
'
,
eth
:
'
https://eth.blockscout.com
'
,
eth_goerli
:
'
https://eth-goerli.blockscout.com
'
,
eth_goerli
:
'
https://eth-goerli.blockscout.com
'
,
...
...
types/api/validators.ts
View file @
35b715cd
import
type
{
AddressParam
}
from
'
./addressParams
'
;
import
type
{
AddressParam
}
from
'
./addressParams
'
;
export
interface
Validator
{
export
interface
Validator
Stability
{
address
:
AddressParam
;
address
:
AddressParam
;
blocks_validated_count
:
number
;
blocks_validated_count
:
number
;
state
:
'
active
'
|
'
probation
'
|
'
inactive
'
;
state
:
'
active
'
|
'
probation
'
|
'
inactive
'
;
}
}
export
interface
ValidatorsResponse
{
export
interface
Validators
Stability
Response
{
items
:
Array
<
Validator
>
;
items
:
Array
<
Validator
Stability
>
;
next_page_params
:
{
next_page_params
:
{
'
address_hash
'
:
string
;
'
address_hash
'
:
string
;
'
blocks_validated
'
:
string
;
'
blocks_validated
'
:
string
;
'
items_count
'
:
string
;
'
items_count
'
:
string
;
'
state
'
:
Validator
[
'
state
'
];
'
state
'
:
Validator
Stability
[
'
state
'
];
}
|
null
;
}
|
null
;
}
}
export
interface
ValidatorsCountersResponse
{
export
interface
Validators
Stability
CountersResponse
{
active_validators_counter
:
string
;
active_validators_counter
:
string
;
active_validators_percentage
:
number
;
active_validators_percentage
:
number
;
new_validators_counter_24h
:
string
;
new_validators_counter_24h
:
string
;
validators_counter
:
string
;
validators_counter
:
string
;
}
}
export
interface
ValidatorsFilters
{
export
interface
Validators
Stability
Filters
{
// address_hash: string | undefined; // right now API doesn't support filtering by address_hash
// address_hash: string | undefined; // right now API doesn't support filtering by address_hash
state_filter
:
Validator
[
'
state
'
]
|
undefined
;
state_filter
:
Validator
Stability
[
'
state
'
]
|
undefined
;
}
}
export
interface
ValidatorsSorting
{
export
interface
ValidatorsS
tabilityS
orting
{
sort
:
'
state
'
|
'
blocks_validated
'
;
sort
:
'
state
'
|
'
blocks_validated
'
;
order
:
'
asc
'
|
'
desc
'
;
order
:
'
asc
'
|
'
desc
'
;
}
}
export
type
ValidatorsS
ortingField
=
Validators
Sorting
[
'
sort
'
];
export
type
ValidatorsS
tabilitySortingField
=
ValidatorsStability
Sorting
[
'
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
<
ValidatorBlackfort
>
;
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
'
]
}
`
;
types/client/validators.ts
View file @
35b715cd
...
@@ -2,6 +2,7 @@ import type { ArrayElement } from 'types/utils';
...
@@ -2,6 +2,7 @@ import type { ArrayElement } from 'types/utils';
export
const
VALIDATORS_CHAIN_TYPE
=
[
export
const
VALIDATORS_CHAIN_TYPE
=
[
'
stability
'
,
'
stability
'
,
'
blackfort
'
,
]
as
const
;
]
as
const
;
export
type
ValidatorsChainType
=
ArrayElement
<
typeof
VALIDATORS_CHAIN_TYPE
>
;
export
type
ValidatorsChainType
=
ArrayElement
<
typeof
VALIDATORS_CHAIN_TYPE
>
;
ui/pages/ValidatorsBlackfort.pw.tsx
0 → 100644
View file @
35b715cd
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
(<
Validators
/>);
await
expect
(
component
).
toHaveScreenshot
();
});
ui/pages/ValidatorsBlackfort.tsx
0 → 100644
View file @
35b715cd
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
<
ValidatorsBlackfortSortingValue
|
undefined
>
(
getSortValueFromQuery
<
ValidatorsBlackfortSortingValue
>
(
router
.
query
,
VALIDATORS_BLACKFORT_SORT_OPTIONS
),
);
const
{
isError
,
isPlaceholderData
,
data
,
pagination
,
onSortingChange
}
=
useQueryWithPages
({
resourceName
:
'
validators_blackfort
'
,
sorting
:
getSortParamsFromValue
<
ValidatorsBlackfortSortingValue
,
ValidatorsBlackfortSortingField
,
ValidatorsBlackfortSorting
[
'
order
'
]
>
(
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
=
(
<
Sort
name=
"validators_sorting"
defaultValue=
{
sort
}
options=
{
VALIDATORS_BLACKFORT_SORT_OPTIONS
}
onChange=
{
handleSortChange
}
/>
);
const
actionBar
=
(
<>
<
HStack
spacing=
{
3
}
mb=
{
6
}
display=
{
{
base
:
'
flex
'
,
lg
:
'
none
'
}
}
>
{
sortButton
}
</
HStack
>
{
pagination
.
isVisible
&&
(
<
ActionBar
mt=
{
-
6
}
>
<
Pagination
ml=
"auto"
{
...
pagination
}
/>
</
ActionBar
>
)
}
</>
);
const
content
=
data
?.
items
?
(
<>
<
Show
below=
"lg"
ssr=
{
false
}
>
<
ValidatorsList
data=
{
data
.
items
}
isLoading=
{
isPlaceholderData
}
/>
</
Show
>
<
Hide
below=
"lg"
ssr=
{
false
}
>
<
ValidatorsTable
data=
{
data
.
items
}
sort=
{
sort
}
setSorting=
{
handleSortChange
}
isLoading=
{
isPlaceholderData
}
top=
{
pagination
.
isVisible
?
ACTION_BAR_HEIGHT_DESKTOP
:
0
}
/>
</
Hide
>
</>
)
:
null
;
return
(
<
Box
>
<
PageTitle
title=
"Validators"
withTextAd
/>
<
ValidatorsCounters
/>
<
DataListDisplay
isError=
{
isError
}
items=
{
data
?.
items
}
emptyText=
"There are no validators."
content=
{
content
}
actionBar=
{
actionBar
}
/>
</
Box
>
);
};
export
default
ValidatorsBlackfort
;
ui/pages/Validators.pw.tsx
→
ui/pages/Validators
Stability
.pw.tsx
View file @
35b715cd
import
React
from
'
react
'
;
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
{
test
,
expect
}
from
'
playwright/lib
'
;
import
Validators
from
'
./Validators
'
;
import
Validators
from
'
./Validators
Stability
'
;
const
chainType
=
'
stability
'
;
const
chainType
=
'
stability
'
;
...
@@ -11,8 +11,8 @@ test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd
...
@@ -11,8 +11,8 @@ test('base view +@mobile', async({ render, mockApiResponse, mockEnvs, mockTextAd
await
mockEnvs
([
await
mockEnvs
([
[
'
NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE
'
,
chainType
],
[
'
NEXT_PUBLIC_VALIDATORS_CHAIN_TYPE
'
,
chainType
],
]);
]);
await
mockApiResponse
(
'
validators
'
,
validatorsMock
.
validatorsResponse
,
{
pathParams
:
{
chainType
}
}
);
await
mockApiResponse
(
'
validators
_stability
'
,
validatorsMock
.
validatorsResponse
);
await
mockApiResponse
(
'
validators_
counters
'
,
validatorsMock
.
validatorsCountersResponse
,
{
pathParams
:
{
chainType
}
}
);
await
mockApiResponse
(
'
validators_
stability_counters
'
,
validatorsMock
.
validatorsCountersResponse
);
await
mockTextAd
();
await
mockTextAd
();
const
component
=
await
render
(<
Validators
/>);
const
component
=
await
render
(<
Validators
/>);
...
...
ui/pages/Validators.tsx
→
ui/pages/Validators
Stability
.tsx
View file @
35b715cd
...
@@ -2,8 +2,12 @@ import { Box, Hide, HStack, Show } from '@chakra-ui/react';
...
@@ -2,8 +2,12 @@ import { Box, Hide, HStack, Show } from '@chakra-ui/react';
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
getFeaturePayload
}
from
'
configs/app/features/types
'
;
import
type
{
import
type
{
ValidatorsFilters
,
ValidatorsSorting
,
ValidatorsSortingField
,
ValidatorsSortingValue
}
from
'
types/api/validators
'
;
ValidatorsStabilityFilters
,
ValidatorsStabilitySorting
,
ValidatorsStabilitySortingField
,
ValidatorsStabilitySortingValue
,
}
from
'
types/api/validators
'
;
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
// import useDebounce from 'lib/hooks/useDebounce';
// import useDebounce from 'lib/hooks/useDebounce';
...
@@ -11,7 +15,7 @@ import useIsMobile from 'lib/hooks/useIsMobile';
...
@@ -11,7 +15,7 @@ import useIsMobile from 'lib/hooks/useIsMobile';
import
{
apos
}
from
'
lib/html-entities
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
VALIDATOR
}
from
'
stubs/validators
'
;
import
{
VALIDATOR
_STABILITY
}
from
'
stubs/validators
'
;
import
ActionBar
from
'
ui/shared/ActionBar
'
;
import
ActionBar
from
'
ui/shared/ActionBar
'
;
import
DataListDisplay
from
'
ui/shared/DataListDisplay
'
;
import
DataListDisplay
from
'
ui/shared/DataListDisplay
'
;
// import FilterInput from 'ui/shared/filters/FilterInput';
// import FilterInput from 'ui/shared/filters/FilterInput';
...
@@ -21,35 +25,36 @@ import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
...
@@ -21,35 +25,36 @@ import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
import
getSortParamsFromValue
from
'
ui/shared/sort/getSortParamsFromValue
'
;
import
getSortParamsFromValue
from
'
ui/shared/sort/getSortParamsFromValue
'
;
import
getSortValueFromQuery
from
'
ui/shared/sort/getSortValueFromQuery
'
;
import
getSortValueFromQuery
from
'
ui/shared/sort/getSortValueFromQuery
'
;
import
Sort
from
'
ui/shared/sort/Sort
'
;
import
Sort
from
'
ui/shared/sort/Sort
'
;
import
{
SORT_OPTIONS
}
from
'
ui/validators
/utils
'
;
import
{
VALIDATORS_STABILITY_SORT_OPTIONS
}
from
'
ui/validatorsStability
/utils
'
;
import
ValidatorsCounters
from
'
ui/validators/ValidatorsCounters
'
;
import
ValidatorsCounters
from
'
ui/validators
Stability
/ValidatorsCounters
'
;
import
ValidatorsFilter
from
'
ui/validators/ValidatorsFilter
'
;
import
ValidatorsFilter
from
'
ui/validators
Stability
/ValidatorsFilter
'
;
import
ValidatorsList
from
'
ui/validators/ValidatorsList
'
;
import
ValidatorsList
from
'
ui/validators
Stability
/ValidatorsList
'
;
import
ValidatorsTable
from
'
ui/validators/ValidatorsTable
'
;
import
ValidatorsTable
from
'
ui/validators
Stability
/ValidatorsTable
'
;
const
Validators
=
()
=>
{
const
Validators
Stability
=
()
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
// const [ searchTerm, setSearchTerm ] = React.useState(getQueryParamString(router.query.address_hash) || undefined);
// 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
[
statusFilter
,
setStatusFilter
]
=
const
[
sort
,
setSort
]
=
React
.
useState
(
getQueryParamString
(
router
.
query
.
state_filter
)
as
ValidatorsStabilityFilters
[
'
state_filter
'
]
||
undefined
);
React
.
useState
<
ValidatorsSortingValue
|
undefined
>
(
getSortValueFromQuery
<
ValidatorsSortingValue
>
(
router
.
query
,
SORT_OPTIONS
));
const
[
sort
,
setSort
]
=
React
.
useState
<
ValidatorsStabilitySortingValue
|
undefined
>
(
getSortValueFromQuery
<
ValidatorsStabilitySortingValue
>
(
router
.
query
,
VALIDATORS_STABILITY_SORT_OPTIONS
),
);
// const debouncedSearchTerm = useDebounce(searchTerm || '', 300);
// const debouncedSearchTerm = useDebounce(searchTerm || '', 300);
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
{
isError
,
isPlaceholderData
,
data
,
pagination
,
onFilterChange
,
onSortingChange
}
=
useQueryWithPages
({
const
{
isError
,
isPlaceholderData
,
data
,
pagination
,
onFilterChange
,
onSortingChange
}
=
useQueryWithPages
({
resourceName
:
'
validators
'
,
resourceName
:
'
validators_stability
'
,
pathParams
:
{
chainType
:
getFeaturePayload
(
config
.
features
.
validators
)?.
chainType
},
filters
:
{
filters
:
{
// address_hash: debouncedSearchTerm,
// address_hash: debouncedSearchTerm,
state_filter
:
statusFilter
,
state_filter
:
statusFilter
,
},
},
sorting
:
getSortParamsFromValue
<
ValidatorsS
ortingValue
,
ValidatorsSortingField
,
Validators
Sorting
[
'
order
'
]
>
(
sort
),
sorting
:
getSortParamsFromValue
<
ValidatorsS
tabilitySortingValue
,
ValidatorsStabilitySortingField
,
ValidatorsStability
Sorting
[
'
order
'
]
>
(
sort
),
options
:
{
options
:
{
enabled
:
config
.
features
.
validators
.
isEnabled
,
enabled
:
config
.
features
.
validators
.
isEnabled
,
placeholderData
:
generateListStub
<
'
validators
'
>
(
placeholderData
:
generateListStub
<
'
validators
_stability
'
>
(
VALIDATOR
,
VALIDATOR
_STABILITY
,
50
,
50
,
{
next_page_params
:
null
},
{
next_page_params
:
null
},
),
),
...
@@ -69,7 +74,7 @@ const Validators = () => {
...
@@ -69,7 +74,7 @@ const Validators = () => {
return
;
return
;
}
}
const
state
=
value
===
'
all
'
?
undefined
:
value
as
ValidatorsFilters
[
'
state_filter
'
];
const
state
=
value
===
'
all
'
?
undefined
:
value
as
Validators
Stability
Filters
[
'
state_filter
'
];
onFilterChange
({
onFilterChange
({
// address_hash: debouncedSearchTerm,
// address_hash: debouncedSearchTerm,
...
@@ -78,12 +83,13 @@ const Validators = () => {
...
@@ -78,12 +83,13 @@ const Validators = () => {
setStatusFilter
(
state
);
setStatusFilter
(
state
);
},
[
onFilterChange
]);
},
[
onFilterChange
]);
const
handleSortChange
=
React
.
useCallback
((
value
?:
ValidatorsSortingValue
)
=>
{
const
handleSortChange
=
React
.
useCallback
((
value
?:
ValidatorsS
tabilityS
ortingValue
)
=>
{
setSort
(
value
);
setSort
(
value
);
onSortingChange
(
getSortParamsFromValue
(
value
));
onSortingChange
(
getSortParamsFromValue
(
value
));
},
[
onSortingChange
]);
},
[
onSortingChange
]);
const
filterMenu
=
<
ValidatorsFilter
onChange=
{
handleStateFilterChange
}
defaultValue=
{
statusFilter
}
hasActiveFilter=
{
Boolean
(
statusFilter
)
}
/>;
const
filterMenu
=
<
ValidatorsFilter
onChange=
{
handleStateFilterChange
}
defaultValue=
{
statusFilter
}
hasActiveFilter=
{
Boolean
(
statusFilter
)
}
/>;
// const filterInput = (
// const filterInput = (
// <FilterInput
// <FilterInput
...
@@ -99,7 +105,7 @@ const Validators = () => {
...
@@ -99,7 +105,7 @@ const Validators = () => {
<
Sort
<
Sort
name=
"validators_sorting"
name=
"validators_sorting"
defaultValue=
{
sort
}
defaultValue=
{
sort
}
options=
{
SORT_OPTIONS
}
options=
{
VALIDATORS_STABILITY_
SORT_OPTIONS
}
onChange=
{
handleSortChange
}
onChange=
{
handleSortChange
}
/>
/>
);
);
...
@@ -141,7 +147,7 @@ const Validators = () => {
...
@@ -141,7 +147,7 @@ const Validators = () => {
<
DataListDisplay
<
DataListDisplay
isError=
{
isError
}
isError=
{
isError
}
items=
{
data
?.
items
}
items=
{
data
?.
items
}
emptyText=
"There are no v
erified contract
s."
emptyText=
"There are no v
alidator
s."
filterProps=
{
{
filterProps=
{
{
emptyFilteredText
:
`Couldn${ apos }t find any validator that matches your query.`
,
emptyFilteredText
:
`Couldn${ apos }t find any validator that matches your query.`
,
hasActiveFilters
:
Boolean
(
hasActiveFilters
:
Boolean
(
...
@@ -156,4 +162,4 @@ const Validators = () => {
...
@@ -156,4 +162,4 @@ const Validators = () => {
);
);
};
};
export
default
Validators
;
export
default
Validators
Stability
;
ui/pages/__screenshots__/ValidatorsBlackfort.pw.tsx_default_base-view-mobile-1.png
0 → 100644
View file @
35b715cd
33.9 KB
ui/pages/__screenshots__/ValidatorsBlackfort.pw.tsx_mobile_base-view-mobile-1.png
0 → 100644
View file @
35b715cd
45.4 KB
ui/pages/__screenshots__/Validators.pw.tsx_default_base-view-mobile-1.png
→
ui/pages/__screenshots__/Validators
Stability
.pw.tsx_default_base-view-mobile-1.png
View file @
35b715cd
File moved
ui/pages/__screenshots__/Validators.pw.tsx_mobile_base-view-mobile-1.png
→
ui/pages/__screenshots__/Validators
Stability
.pw.tsx_mobile_base-view-mobile-1.png
View file @
35b715cd
File moved
ui/shared/statusTag/ValidatorStatus.tsx
→
ui/shared/statusTag/ValidatorSta
bilitySta
tus.tsx
View file @
35b715cd
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
Validator
}
from
'
types/api/validators
'
;
import
type
{
Validator
Stability
}
from
'
types/api/validators
'
;
import
StatusTag
from
'
./StatusTag
'
;
import
StatusTag
from
'
./StatusTag
'
;
interface
Props
{
interface
Props
{
state
:
Validator
[
'
state
'
];
state
:
Validator
Stability
[
'
state
'
];
isLoading
?:
boolean
;
isLoading
?:
boolean
;
}
}
const
ValidatorStatus
=
({
state
,
isLoading
}:
Props
)
=>
{
const
ValidatorSta
bilitySta
tus
=
({
state
,
isLoading
}:
Props
)
=>
{
switch
(
state
)
{
switch
(
state
)
{
case
'
active
'
:
case
'
active
'
:
return
<
StatusTag
type=
"ok"
text=
"Active"
isLoading=
{
isLoading
}
/>;
return
<
StatusTag
type=
"ok"
text=
"Active"
isLoading=
{
isLoading
}
/>;
...
@@ -20,4 +20,4 @@ const ValidatorStatus = ({ state, isLoading }: Props) => {
...
@@ -20,4 +20,4 @@ const ValidatorStatus = ({ state, isLoading }: Props) => {
}
}
};
};
export
default
React
.
memo
(
ValidatorStatus
);
export
default
React
.
memo
(
ValidatorSta
bilitySta
tus
);
ui/validatorsBlackfort/ValidatorsCounters.tsx
0 → 100644
View file @
35b715cd
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
(
<
Box
columnGap=
{
3
}
rowGap=
{
3
}
mb=
{
6
}
display=
"grid"
gridTemplateColumns=
{
{
base
:
'
1fr
'
,
lg
:
'
repeat(2, 1fr)
'
}
}
>
<
StatsWidget
label=
"Total validators"
value=
{
Number
(
countersQuery
.
data
.
validators_counter
).
toLocaleString
()
}
diff=
{
Number
(
countersQuery
.
data
.
new_validators_counter_24h
).
toLocaleString
()
}
isLoading=
{
countersQuery
.
isPlaceholderData
}
/>
</
Box
>
);
};
export
default
React
.
memo
(
ValidatorsCounters
);
ui/validators/ValidatorsList.tsx
→
ui/validators
Blackfort
/ValidatorsList.tsx
View file @
35b715cd
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
Validator
}
from
'
types/api/validators
'
;
import
type
{
Validator
Blackfort
}
from
'
types/api/validators
'
;
import
ValidatorsListItem
from
'
./ValidatorsListItem
'
;
import
ValidatorsListItem
from
'
./ValidatorsListItem
'
;
const
ValidatorsList
=
({
data
,
isLoading
}:
{
data
:
Array
<
Validator
>
;
isLoading
:
boolean
})
=>
{
const
ValidatorsList
=
({
data
,
isLoading
}:
{
data
:
Array
<
Validator
Blackfort
>
;
isLoading
:
boolean
})
=>
{
return
(
return
(
<
Box
>
<
Box
>
{
data
.
map
((
item
,
index
)
=>
(
{
data
.
map
((
item
,
index
)
=>
(
...
...
ui/validatorsBlackfort/ValidatorsListItem.tsx
0 → 100644
View file @
35b715cd
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
(
<
ListItemMobileGrid
.
Container
gridTemplateColumns=
"130px auto"
>
<
ListItemMobileGrid
.
Label
isLoading=
{
isLoading
}
>
Address
</
ListItemMobileGrid
.
Label
>
<
ListItemMobileGrid
.
Value
>
<
AddressEntity
isLoading=
{
isLoading
}
address=
{
data
.
address
}
truncation=
"constant"
/>
</
ListItemMobileGrid
.
Value
>
<
ListItemMobileGrid
.
Label
isLoading=
{
isLoading
}
>
Name
</
ListItemMobileGrid
.
Label
>
<
ListItemMobileGrid
.
Value
>
<
Flex
><
TruncatedValue
value=
{
data
.
name
}
isLoading=
{
isLoading
}
/></
Flex
>
</
ListItemMobileGrid
.
Value
>
<
ListItemMobileGrid
.
Label
isLoading=
{
isLoading
}
>
Commission
</
ListItemMobileGrid
.
Label
>
<
ListItemMobileGrid
.
Value
>
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
>
{
`${ data.commission / 100 }%`
}
</
Skeleton
>
</
ListItemMobileGrid
.
Value
>
<
ListItemMobileGrid
.
Label
isLoading=
{
isLoading
}
>
Self bonded
</
ListItemMobileGrid
.
Label
>
<
ListItemMobileGrid
.
Value
>
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
>
{
`${ BigNumber(data.self_bonded_amount).div(BigNumber(10 ** config.chain.currency.decimals)).toFormat() } ${ currencyUnits.ether }`
}
</
Skeleton
>
</
ListItemMobileGrid
.
Value
>
<
ListItemMobileGrid
.
Label
isLoading=
{
isLoading
}
>
Delegated amount
</
ListItemMobileGrid
.
Label
>
<
ListItemMobileGrid
.
Value
>
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
>
{
`${ BigNumber(data.delegated_amount).div(BigNumber(10 ** config.chain.currency.decimals)).toFormat() } ${ currencyUnits.ether }`
}
</
Skeleton
>
</
ListItemMobileGrid
.
Value
>
</
ListItemMobileGrid
.
Container
>
);
};
export
default
React
.
memo
(
ValidatorsListItem
);
ui/validatorsBlackfort/ValidatorsTable.tsx
0 → 100644
View file @
35b715cd
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
<
ValidatorBlackfort
>
;
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
<
ValidatorsBlackfortSortingField
,
ValidatorsBlackfortSortingValue
>
(
VALIDATORS_BLACKFORT_SORT_SEQUENCE
,
field
)(
sort
);
setSorting
(
value
);
},
[
sort
,
setSorting
]);
return
(
<
Table
variant=
"simple"
size=
"sm"
>
<
Thead
top=
{
top
}
>
<
Tr
>
<
Th
>
<
Link
display=
"flex"
alignItems=
"center"
onClick=
{
isLoading
?
undefined
:
onSortToggle
(
'
address_hash
'
)
}
columnGap=
{
1
}
>
{
sort
?.
includes
(
'
address
'
)
&&
<
IconSvg
name=
"arrows/east"
boxSize=
{
4
}
transform=
{
sortIconTransform
}
/>
}
Validator’s address
</
Link
>
</
Th
>
<
Th
>
Name
</
Th
>
<
Th
isNumeric
>
Commission
</
Th
>
<
Th
isNumeric
>
{
`Self bonded ${ currencyUnits.ether }`
}
</
Th
>
<
Th
isNumeric
>
{
`Delegated amount ${ currencyUnits.ether }`
}
</
Th
>
</
Tr
>
</
Thead
>
<
Tbody
>
{
data
.
map
((
item
,
index
)
=>
(
<
ValidatorsTableItem
key=
{
item
.
address
.
hash
+
(
isLoading
?
index
:
''
)
}
data=
{
item
}
isLoading=
{
isLoading
}
/>
))
}
</
Tbody
>
</
Table
>
);
};
export
default
React
.
memo
(
ValidatorsTable
);
ui/validatorsBlackfort/ValidatorsTableItem.tsx
0 → 100644
View file @
35b715cd
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
(
<
Tr
>
<
Td
verticalAlign=
"middle"
>
<
AddressEntity
address=
{
data
.
address
}
isLoading=
{
isLoading
}
truncation=
"constant"
/>
</
Td
>
<
Td
verticalAlign=
"middle"
>
<
Flex
>
<
TruncatedValue
value=
{
data
.
name
}
isLoading=
{
isLoading
}
/>
</
Flex
>
</
Td
>
<
Td
verticalAlign=
"middle"
isNumeric
>
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
>
{
`${ data.commission / 100 }%`
}
</
Skeleton
>
</
Td
>
<
Td
verticalAlign=
"middle"
isNumeric
>
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
>
{
BigNumber
(
data
.
self_bonded_amount
).
div
(
BigNumber
(
10
**
config
.
chain
.
currency
.
decimals
)).
toFormat
()
}
</
Skeleton
>
</
Td
>
<
Td
verticalAlign=
"middle"
isNumeric
>
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
>
{
BigNumber
(
data
.
delegated_amount
).
div
(
BigNumber
(
10
**
config
.
chain
.
currency
.
decimals
)).
toFormat
()
}
</
Skeleton
>
</
Td
>
</
Tr
>
);
};
export
default
React
.
memo
(
ValidatorsTableItem
);
ui/validatorsBlackfort/utils.ts
0 → 100644
View file @
35b715cd
import
type
{
ValidatorsBlackfortSortingValue
,
ValidatorsBlackfortSortingField
,
}
from
'
types/api/validators
'
;
import
type
{
TOption
}
from
'
ui/shared/sort/Option
'
;
export
const
VALIDATORS_BLACKFORT_SORT_OPTIONS
:
Array
<
TOption
<
ValidatorsBlackfortSortingValue
>>
=
[
{
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
<
ValidatorsBlackfortSortingField
,
Array
<
ValidatorsBlackfortSortingValue
|
undefined
>>
=
{
address_hash
:
[
'
address_hash-desc
'
,
'
address_hash-asc
'
,
undefined
],
};
ui/validators/ValidatorsCounters.tsx
→
ui/validators
Stability
/ValidatorsCounters.tsx
View file @
35b715cd
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
getFeaturePayload
}
from
'
configs/app/features/types
'
;
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
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
'
;
import
StatsWidget
from
'
ui/shared/stats/StatsWidget
'
;
const
ValidatorsCounters
=
()
=>
{
const
ValidatorsCounters
=
()
=>
{
const
countersQuery
=
useApiQuery
(
'
validators_counters
'
,
{
const
countersQuery
=
useApiQuery
(
'
validators_stability_counters
'
,
{
pathParams
:
{
chainType
:
getFeaturePayload
(
config
.
features
.
validators
)?.
chainType
},
queryOptions
:
{
queryOptions
:
{
enabled
:
config
.
features
.
validators
.
isEnabled
,
enabled
:
config
.
features
.
validators
.
isEnabled
,
placeholderData
:
VALIDATORS_COUNTERS
,
placeholderData
:
VALIDATORS_
STABILITY_
COUNTERS
,
},
},
});
});
...
...
ui/validators/ValidatorsFilter.tsx
→
ui/validators
Stability
/ValidatorsFilter.tsx
View file @
35b715cd
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
ValidatorsFilters
}
from
'
types/api/validators
'
;
import
type
{
Validators
Stability
Filters
}
from
'
types/api/validators
'
;
import
PopoverFilterRadio
from
'
ui/shared/filters/PopoverFilterRadio
'
;
import
PopoverFilterRadio
from
'
ui/shared/filters/PopoverFilterRadio
'
;
...
@@ -13,7 +13,7 @@ const OPTIONS = [
...
@@ -13,7 +13,7 @@ const OPTIONS = [
interface
Props
{
interface
Props
{
hasActiveFilter
:
boolean
;
hasActiveFilter
:
boolean
;
defaultValue
:
ValidatorsFilters
[
'
state_filter
'
]
|
undefined
;
defaultValue
:
Validators
Stability
Filters
[
'
state_filter
'
]
|
undefined
;
onChange
:
(
nextValue
:
string
|
Array
<
string
>
)
=>
void
;
onChange
:
(
nextValue
:
string
|
Array
<
string
>
)
=>
void
;
}
}
...
...
ui/validatorsStability/ValidatorsList.tsx
0 → 100644
View file @
35b715cd
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
<
ValidatorStability
>
;
isLoading
:
boolean
})
=>
{
return
(
<
Box
>
{
data
.
map
((
item
,
index
)
=>
(
<
ValidatorsListItem
key=
{
item
.
address
.
hash
+
(
isLoading
?
index
:
''
)
}
data=
{
item
}
isLoading=
{
isLoading
}
/>
))
}
</
Box
>
);
};
export
default
React
.
memo
(
ValidatorsList
);
ui/validators/ValidatorsListItem.tsx
→
ui/validators
Stability
/ValidatorsListItem.tsx
View file @
35b715cd
import
{
Skeleton
}
from
'
@chakra-ui/react
'
;
import
{
Skeleton
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
Validator
}
from
'
types/api/validators
'
;
import
type
{
Validator
Stability
}
from
'
types/api/validators
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
ListItemMobileGrid
from
'
ui/shared/ListItemMobile/ListItemMobileGrid
'
;
import
ListItemMobileGrid
from
'
ui/shared/ListItemMobile/ListItemMobileGrid
'
;
import
ValidatorStatus
from
'
ui/shared/statusTag/ValidatorStatus
'
;
import
ValidatorStatus
from
'
ui/shared/statusTag/ValidatorSta
bilitySta
tus
'
;
interface
Props
{
interface
Props
{
data
:
Validator
;
data
:
Validator
Stability
;
isLoading
?:
boolean
;
isLoading
?:
boolean
;
}
}
...
...
ui/validators/ValidatorsTable.tsx
→
ui/validators
Stability
/ValidatorsTable.tsx
View file @
35b715cd
import
{
Table
,
Tbody
,
Tr
,
Th
,
Link
}
from
'
@chakra-ui/react
'
;
import
{
Table
,
Tbody
,
Tr
,
Th
,
Link
}
from
'
@chakra-ui/react
'
;
import
React
from
'
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
{
ACTION_BAR_HEIGHT_DESKTOP
}
from
'
ui/shared/ActionBar
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
getNextSortValue
from
'
ui/shared/sort/getNextSortValue
'
;
import
getNextSortValue
from
'
ui/shared/sort/getNextSortValue
'
;
import
{
default
as
Thead
}
from
'
ui/shared/TheadSticky
'
;
import
{
default
as
Thead
}
from
'
ui/shared/TheadSticky
'
;
import
{
SORT_SEQUENCE
}
from
'
./utils
'
;
import
{
VALIDATORS_STABILITY_
SORT_SEQUENCE
}
from
'
./utils
'
;
import
ValidatorsTableItem
from
'
./ValidatorsTableItem
'
;
import
ValidatorsTableItem
from
'
./ValidatorsTableItem
'
;
interface
Props
{
interface
Props
{
data
:
Array
<
Validator
>
;
data
:
Array
<
Validator
Stability
>
;
sort
:
ValidatorsSortingValue
|
undefined
;
sort
:
ValidatorsS
tabilityS
ortingValue
|
undefined
;
setSorting
:
(
val
:
ValidatorsSortingValue
|
undefined
)
=>
void
;
setSorting
:
(
val
:
ValidatorsS
tabilityS
ortingValue
|
undefined
)
=>
void
;
isLoading
?:
boolean
;
isLoading
?:
boolean
;
}
}
const
ValidatorsTable
=
({
data
,
sort
,
setSorting
,
isLoading
}:
Props
)
=>
{
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
ValidatorsS
tabilityS
orting
[
'
order
'
])
?
'
rotate(-90deg)
'
:
'
rotate(90deg)
'
;
const
onSortToggle
=
React
.
useCallback
((
field
:
ValidatorsSortingField
)
=>
()
=>
{
const
onSortToggle
=
React
.
useCallback
((
field
:
ValidatorsS
tabilityS
ortingField
)
=>
()
=>
{
const
value
=
getNextSortValue
<
ValidatorsS
ortingField
,
ValidatorsSortingValue
>
(
SORT_SEQUENCE
,
field
)(
sort
);
const
value
=
getNextSortValue
<
ValidatorsS
tabilitySortingField
,
ValidatorsStabilitySortingValue
>
(
VALIDATORS_STABILITY_
SORT_SEQUENCE
,
field
)(
sort
);
setSorting
(
value
);
setSorting
(
value
);
},
[
sort
,
setSorting
]);
},
[
sort
,
setSorting
]);
...
...
ui/validators/ValidatorsTableItem.tsx
→
ui/validators
Stability
/ValidatorsTableItem.tsx
View file @
35b715cd
import
{
Tr
,
Td
,
Skeleton
}
from
'
@chakra-ui/react
'
;
import
{
Tr
,
Td
,
Skeleton
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
Validator
}
from
'
types/api/validators
'
;
import
type
{
Validator
Stability
}
from
'
types/api/validators
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
ValidatorStatus
from
'
ui/shared/statusTag/ValidatorStatus
'
;
import
ValidatorStatus
from
'
ui/shared/statusTag/ValidatorSta
bilitySta
tus
'
;
interface
Props
{
interface
Props
{
data
:
Validator
;
data
:
Validator
Stability
;
isLoading
?:
boolean
;
isLoading
?:
boolean
;
}
}
...
...
ui/validators/utils.ts
→
ui/validators
Stability
/utils.ts
View file @
35b715cd
import
type
{
ValidatorsSortingValue
,
ValidatorsSortingField
}
from
'
types/api/validators
'
;
import
type
{
ValidatorsStabilitySortingValue
,
ValidatorsStabilitySortingField
,
}
from
'
types/api/validators
'
;
import
type
{
TOption
}
from
'
ui/shared/sort/Option
'
;
import
type
{
TOption
}
from
'
ui/shared/sort/Option
'
;
export
const
SORT_OPTIONS
:
Array
<
TOption
<
Validators
SortingValue
>>
=
[
export
const
VALIDATORS_STABILITY_SORT_OPTIONS
:
Array
<
TOption
<
ValidatorsStability
SortingValue
>>
=
[
{
title
:
'
Default
'
,
id
:
undefined
},
{
title
:
'
Default
'
,
id
:
undefined
},
{
title
:
'
Status descending
'
,
id
:
'
state-desc
'
},
{
title
:
'
Status descending
'
,
id
:
'
state-desc
'
},
{
title
:
'
Status ascending
'
,
id
:
'
state-asc
'
},
{
title
:
'
Status ascending
'
,
id
:
'
state-asc
'
},
...
@@ -10,7 +13,7 @@ export const SORT_OPTIONS: Array<TOption<ValidatorsSortingValue>> = [
...
@@ -10,7 +13,7 @@ export const SORT_OPTIONS: Array<TOption<ValidatorsSortingValue>> = [
{
title
:
'
Blocks validated ascending
'
,
id
:
'
blocks_validated-asc
'
},
{
title
:
'
Blocks validated ascending
'
,
id
:
'
blocks_validated-asc
'
},
];
];
export
const
SORT_SEQUENCE
:
Record
<
ValidatorsSortingField
,
Array
<
Validators
SortingValue
|
undefined
>>
=
{
export
const
VALIDATORS_STABILITY_SORT_SEQUENCE
:
Record
<
ValidatorsStabilitySortingField
,
Array
<
ValidatorsStability
SortingValue
|
undefined
>>
=
{
state
:
[
'
state-desc
'
,
'
state-asc
'
,
undefined
],
state
:
[
'
state-desc
'
,
'
state-asc
'
,
undefined
],
blocks_validated
:
[
'
blocks_validated-desc
'
,
'
blocks_validated-asc
'
,
undefined
],
blocks_validated
:
[
'
blocks_validated-desc
'
,
'
blocks_validated-asc
'
,
undefined
],
};
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment