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
3e3f8741
Commit
3e3f8741
authored
Dec 13, 2022
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
desktop view
parent
faa3574e
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
218 additions
and
3 deletions
+218
-3
blocks-validated.ts
pages/api/addresses/[id]/blocks-validated.ts
+13
-0
address.ts
types/api/address.ts
+9
-0
pagination.ts
types/api/pagination.ts
+6
-3
queries.ts
types/client/queries.ts
+1
-0
AddressBlocksValidated.tsx
ui/address/AddressBlocksValidated.tsx
+137
-0
AddressBlocksValidatedTableItem.tsx
...dress/blocksValidated/AddressBlocksValidatedTableItem.tsx
+48
-0
Address.tsx
ui/pages/Address.tsx
+4
-0
No files found.
pages/api/addresses/[id]/blocks-validated.ts
0 → 100644
View file @
3e3f8741
import
type
{
NextApiRequest
}
from
'
next
'
;
import
getSearchParams
from
'
lib/api/getSearchParams
'
;
import
handler
from
'
lib/api/handler
'
;
const
getUrl
=
(
req
:
NextApiRequest
)
=>
{
const
searchParamsStr
=
getSearchParams
(
req
);
return
`/v2/addresses/
${
req
.
query
.
id
}
/blocks-validated
${
searchParamsStr
?
'
?
'
+
searchParamsStr
:
''
}
`
;
};
const
requestHandler
=
handler
(
getUrl
,
[
'
GET
'
]);
export
default
requestHandler
;
types/api/address.ts
View file @
3e3f8741
import
type
{
AddressTag
,
WatchlistName
}
from
'
./addressParams
'
;
import
type
{
Block
}
from
'
./block
'
;
import
type
{
TokenInfo
}
from
'
./tokenInfo
'
;
export
interface
Address
{
...
...
@@ -47,3 +48,11 @@ export interface AddressCoinBalanceHistoryResponse {
items_count
:
number
;
};
}
export
interface
AddressBlocksValidatedResponse
{
items
:
Array
<
Block
>
;
next_page_params
:
{
block_number
:
number
;
items_count
:
number
;
};
}
types/api/pagination.ts
View file @
3e3f8741
import
type
{
AddressCoinBalanceHistoryResponse
}
from
'
types/api/address
'
;
import
type
{
AddressCoinBalanceHistoryResponse
,
AddressBlocksValidatedResponse
}
from
'
types/api/address
'
;
import
type
{
BlocksResponse
,
BlockTransactionsResponse
,
BlockFilters
}
from
'
types/api/block
'
;
import
type
{
InternalTransactionsResponse
}
from
'
types/api/internalTransaction
'
;
import
type
{
LogsResponse
}
from
'
types/api/log
'
;
...
...
@@ -18,7 +18,8 @@ export type PaginatedQueryKeys =
QueryKeys
.
txInternals
|
QueryKeys
.
txLogs
|
QueryKeys
.
txTokenTransfers
|
QueryKeys
.
addressCoinBalanceHistory
;
QueryKeys
.
addressCoinBalanceHistory
|
QueryKeys
.
addressBlocksValidated
;
export
type
PaginatedResponse
<
Q
extends
PaginatedQueryKeys
>
=
Q
extends
(
QueryKeys
.
blocks
|
QueryKeys
.
blocksReorgs
|
QueryKeys
.
blocksUncles
)
?
BlocksResponse
:
...
...
@@ -29,7 +30,8 @@ export type PaginatedResponse<Q extends PaginatedQueryKeys> =
Q
extends
QueryKeys
.
txLogs
?
LogsResponse
:
Q
extends
QueryKeys
.
txTokenTransfers
?
TokenTransferResponse
:
Q
extends
QueryKeys
.
addressCoinBalanceHistory
?
AddressCoinBalanceHistoryResponse
:
never
Q
extends
QueryKeys
.
addressBlocksValidated
?
AddressBlocksValidatedResponse
:
never
export
type
PaginationFilters
<
Q
extends
PaginatedQueryKeys
>
=
Q
extends
QueryKeys
.
blocks
?
BlockFilters
:
...
...
@@ -55,4 +57,5 @@ export const PAGINATION_FIELDS: PaginationFields = {
[
QueryKeys
.
txTokenTransfers
]:
[
'
block_number
'
,
'
items_count
'
,
'
transaction_hash
'
,
'
index
'
],
[
QueryKeys
.
txLogs
]:
[
'
items_count
'
,
'
transaction_hash
'
,
'
index
'
],
[
QueryKeys
.
addressCoinBalanceHistory
]:
[
'
items_count
'
,
'
block_number
'
],
[
QueryKeys
.
addressBlocksValidated
]:
[
'
items_count
'
,
'
block_number
'
],
};
types/client/queries.ts
View file @
3e3f8741
...
...
@@ -26,4 +26,5 @@ export enum QueryKeys {
addressTokenBalances
=
'
address-token-balances
'
,
addressCoinBalanceHistory
=
'
address-coin-balance-history
'
,
addressCoinBalanceHistoryByDay
=
'
address-coin-balance-history-by-day
'
,
addressBlocksValidated
=
'
address-blocks-validated
'
,
}
ui/address/AddressBlocksValidated.tsx
0 → 100644
View file @
3e3f8741
import
{
Box
,
Hide
,
Show
,
Table
,
Tbody
,
Th
,
Tr
}
from
'
@chakra-ui/react
'
;
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
type
{
UseQueryResult
}
from
'
@tanstack/react-query
'
;
import
React
from
'
react
'
;
import
type
{
SocketMessage
}
from
'
lib/socket/types
'
;
import
type
{
Address
,
AddressBlocksValidatedResponse
}
from
'
types/api/address
'
;
import
{
QueryKeys
}
from
'
types/client/queries
'
;
import
appConfig
from
'
configs/app/config
'
;
import
useQueryWithPages
from
'
lib/hooks/useQueryWithPages
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
import
ActionBar
from
'
ui/shared/ActionBar
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
Pagination
from
'
ui/shared/Pagination
'
;
import
SkeletonTable
from
'
ui/shared/SkeletonTable
'
;
import
SocketAlert
from
'
ui/shared/SocketAlert
'
;
import
{
default
as
Thead
}
from
'
ui/shared/TheadSticky
'
;
import
AddressBlocksValidatedTableItem
from
'
./blocksValidated/AddressBlocksValidatedTableItem
'
;
interface
Props
{
addressQuery
:
UseQueryResult
<
Address
>
;
}
const
AddressBlocksValidated
=
({
addressQuery
}:
Props
)
=>
{
const
[
socketAlert
,
setSocketAlert
]
=
React
.
useState
(
false
);
const
queryClient
=
useQueryClient
();
const
query
=
useQueryWithPages
({
apiPath
:
`/node-api/addresses/
${
addressQuery
.
data
?.
hash
}
/blocks-validated`
,
queryName
:
QueryKeys
.
addressBlocksValidated
,
options
:
{
enabled
:
Boolean
(
addressQuery
.
data
),
}
,
});
const handleSocketError = React.useCallback(() => {
setSocketAlert(true);
}, []);
const handleNewSocketMessage: SocketMessage.NewBlock['handler'] = React.useCallback((payload) => {
setSocketAlert(false);
queryClient.setQueryData(
[ QueryKeys.addressBlocksValidated, { page: query.pagination.page } ],
(prevData: AddressBlocksValidatedResponse | undefined) => {
if (!prevData) {
return;
}
return {
...prevData,
items: [ payload.block, ...prevData.items ],
};
});
}, [ query.pagination.page, queryClient ]);
const channel = useSocketChannel({
topic: `
blocks
:
$
{
addressQuery
.
data
?.
hash
.
toLowerCase
()
}
`,
onSocketClose: handleSocketError,
onSocketError: handleSocketError,
isDisabled: addressQuery.isLoading || addressQuery.isError || !addressQuery.data.hash || query.pagination.page !== 1,
});
useSocketMessage({
channel,
event: 'new_block',
handler: handleNewSocketMessage,
});
const content = (() => {
if (query.isLoading) {
return (
<>
<Hide below="lg">
<SkeletonTable columns={ [ '12%', '12%', '12%', '14%', '25%', '25%' ] }/>
</Hide>
<Show below="lg">
loading
</Show>
</>
);
}
if (query.isError) {
return <DataFetchAlert/>;
}
if (query.data.items.length === 0) {
return 'There is no validated blocks for this address';
}
return (
<>
<Hide below="lg">
<Table variant="simple" size="sm">
<Thead top={ 80 }>
<Tr>
<Th width="12%">Block</Th>
<Th width="12%">Age</Th>
<Th width="12%">Txn</Th>
<Th width="14%">Difficulty</Th>
<Th width="25%">GasUsed</Th>
<Th width="25%" isNumeric>Reward { appConfig.network.currency.symbol }</Th>
</Tr>
</Thead>
<Tbody>
{ query.data.items.map((item) => (
<AddressBlocksValidatedTableItem key={ item.height } { ...item } page={ query.pagination.page }/>
)) }
</Tbody>
</Table>
</Hide>
<Show below="lg">
content
</Show>
</>
);
})();
const isPaginatorHidden = !query.isLoading && !query.isError && query.pagination.page === 1 && !query.pagination.hasNextPage;
return (
<Box>
{ !isPaginatorHidden && (
<ActionBar mt={ -6 }>
<Pagination ml="auto" { ...query.pagination }/>
</ActionBar>
) }
{ socketAlert && <SocketAlert mb={ 6 }/> }
{ content }
</Box>
);
};
export default React.memo(AddressBlocksValidated);
ui/address/blocksValidated/AddressBlocksValidatedTableItem.tsx
0 → 100644
View file @
3e3f8741
import
{
Link
,
Td
,
Tr
,
Text
,
Box
,
Flex
}
from
'
@chakra-ui/react
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
React
from
'
react
'
;
import
type
{
Block
}
from
'
types/api/block
'
;
import
getBlockTotalReward
from
'
lib/block/getBlockTotalReward
'
;
import
useTimeAgoIncrement
from
'
lib/hooks/useTimeAgoIncrement
'
;
import
link
from
'
lib/link/link
'
;
import
Utilization
from
'
ui/shared/Utilization/Utilization
'
;
type
Props
=
Block
&
{
page
:
number
;
};
const
AddressBlocksValidatedTableItem
=
(
props
:
Props
)
=>
{
const
blockUrl
=
link
(
'
block
'
,
{
id
:
String
(
props
.
height
)
});
const
timeAgo
=
useTimeAgoIncrement
(
props
.
timestamp
,
props
.
page
===
1
);
const
totalReward
=
getBlockTotalReward
(
props
);
return
(
<
Tr
>
<
Td
>
<
Link
href=
{
blockUrl
}
fontWeight=
"700"
>
{
props
.
height
}
</
Link
>
</
Td
>
<
Td
>
<
Text
variant=
"secondary"
>
{
timeAgo
}
</
Text
>
</
Td
>
<
Td
>
<
Text
fontWeight=
"500"
>
{
props
.
tx_count
}
</
Text
>
</
Td
>
<
Td
>
0.00 TH
</
Td
>
<
Td
>
<
Flex
alignItems=
"center"
columnGap=
{
2
}
>
<
Box
flexBasis=
"80px"
>
{
BigNumber
(
props
.
gas_used
||
0
).
toFormat
()
}
</
Box
>
<
Utilization
colorScheme=
"gray"
value=
{
BigNumber
(
props
.
gas_used
||
0
).
dividedBy
(
BigNumber
(
props
.
gas_limit
)).
toNumber
()
}
/>
</
Flex
>
</
Td
>
<
Td
isNumeric
display=
"flex"
justifyContent=
"end"
>
{
totalReward
}
</
Td
>
</
Tr
>
);
};
export
default
React
.
memo
(
AddressBlocksValidatedTableItem
);
ui/pages/Address.tsx
View file @
3e3f8741
...
...
@@ -8,6 +8,7 @@ import { QueryKeys } from 'types/client/queries';
import
type
{
RoutedTab
}
from
'
ui/shared/RoutedTabs/types
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
import
AddressBlocksValidated
from
'
ui/address/AddressBlocksValidated
'
;
import
AddressCoinBalance
from
'
ui/address/AddressCoinBalance
'
;
import
AddressDetails
from
'
ui/address/AddressDetails
'
;
import
Page
from
'
ui/shared/Page/Page
'
;
...
...
@@ -38,6 +39,9 @@ const AddressPageContent = () => {
{
id
:
'
tokens
'
,
title
:
'
Tokens
'
,
component
:
null
},
{
id
:
'
internal_txn
'
,
title
:
'
Internal txn
'
,
component
:
null
},
{
id
:
'
coin_balance_history
'
,
title
:
'
Coin balance history
'
,
component
:
<
AddressCoinBalance
addressQuery=
{
addressQuery
}
/>
},
// temporary show this tab in all address
// later api will return info about available tabs
{
id
:
'
blocks_validated
'
,
title
:
'
Blocks validated
'
,
component
:
<
AddressBlocksValidated
addressQuery=
{
addressQuery
}
/>
},
];
return
(
...
...
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