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
a51725d0
Commit
a51725d0
authored
Feb 12, 2025
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
validators and coin balance tabs
parent
8600aeba
Changes
22
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
325 additions
and
261 deletions
+325
-261
semanticTokens.ts
toolkit/theme/foundations/semanticTokens.ts
+6
-0
address-entity.ts
toolkit/theme/globals/address-entity.ts
+1
-0
index.ts
toolkit/theme/recipes/index.ts
+2
-0
menu.recipe.ts
toolkit/theme/recipes/menu.recipe.ts
+1
-1
stat.recipe.ts
toolkit/theme/recipes/stat.recipe.ts
+101
-0
AddressBlocksValidated.tsx
ui/address/AddressBlocksValidated.tsx
+23
-22
AddressTxs.tsx
ui/address/AddressTxs.tsx
+1
-1
AddressBlocksValidatedListItem.tsx
...ddress/blocksValidated/AddressBlocksValidatedListItem.tsx
+12
-12
AddressBlocksValidatedTableItem.tsx
...dress/blocksValidated/AddressBlocksValidatedTableItem.tsx
+21
-21
AddressCoinBalanceChart.tsx
ui/address/coinBalance/AddressCoinBalanceChart.tsx
+1
-1
AddressCoinBalanceHistory.tsx
ui/address/coinBalance/AddressCoinBalanceHistory.tsx
+23
-22
AddressCoinBalanceListItem.tsx
ui/address/coinBalance/AddressCoinBalanceListItem.tsx
+14
-16
AddressCoinBalanceTableItem.tsx
ui/address/coinBalance/AddressCoinBalanceTableItem.tsx
+24
-27
Address.tsx
ui/pages/Address.tsx
+15
-15
ChartAxis.tsx
ui/shared/chart/ChartAxis.tsx
+5
-4
ChartMenu.tsx
ui/shared/chart/ChartMenu.tsx
+30
-49
ChartWatermarkIcon.tsx
ui/shared/chart/ChartWatermarkIcon.tsx
+2
-3
ChartWidget.tsx
ui/shared/chart/ChartWidget.tsx
+14
-22
ChartWidgetContent.tsx
ui/shared/chart/ChartWidgetContent.tsx
+6
-5
ChartWidgetGraph.tsx
ui/shared/chart/ChartWidgetGraph.tsx
+1
-1
FullscreenChartModal.tsx
ui/shared/chart/FullscreenChartModal.tsx
+21
-38
TxsTableItem.tsx
ui/txs/TxsTableItem.tsx
+1
-1
No files found.
toolkit/theme/foundations/semanticTokens.ts
View file @
a51725d0
...
@@ -353,6 +353,12 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
...
@@ -353,6 +353,12 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
},
},
},
},
},
},
stat
:
{
indicator
:
{
up
:
{
value
:
{
_light
:
'
{colors.green.500}
'
,
_dark
:
'
{colors.green.400}
'
}
},
down
:
{
value
:
{
_light
:
'
{colors.red.600}
'
,
_dark
:
'
{colors.red.400}
'
}
},
},
},
heading
:
{
heading
:
{
DEFAULT
:
{
value
:
{
_light
:
'
{colors.blackAlpha.800}
'
,
_dark
:
'
{colors.whiteAlpha.800}
'
}
},
DEFAULT
:
{
value
:
{
_light
:
'
{colors.blackAlpha.800}
'
,
_dark
:
'
{colors.whiteAlpha.800}
'
}
},
},
},
...
...
toolkit/theme/globals/address-entity.ts
View file @
a51725d0
...
@@ -24,6 +24,7 @@ const styles = {
...
@@ -24,6 +24,7 @@ const styles = {
'
&.address-entity_highlighted
'
:
{
'
&.address-entity_highlighted
'
:
{
_before
:
{
_before
:
{
pr
:
2
,
pr
:
2
,
width
:
`calc(100% + 6px + 8px)`
,
},
},
},
},
},
},
...
...
toolkit/theme/recipes/index.ts
View file @
a51725d0
...
@@ -20,6 +20,7 @@ import { recipe as radiomark } from './radiomark.recipe';
...
@@ -20,6 +20,7 @@ import { recipe as radiomark } from './radiomark.recipe';
import
{
recipe
as
select
}
from
'
./select.recipe
'
;
import
{
recipe
as
select
}
from
'
./select.recipe
'
;
import
{
recipe
as
skeleton
}
from
'
./skeleton.recipe
'
;
import
{
recipe
as
skeleton
}
from
'
./skeleton.recipe
'
;
import
{
recipe
as
spinner
}
from
'
./spinner.recipe
'
;
import
{
recipe
as
spinner
}
from
'
./spinner.recipe
'
;
import
{
recipe
as
stat
}
from
'
./stat.recipe
'
;
import
{
recipe
as
switchRecipe
}
from
'
./switch.recipe
'
;
import
{
recipe
as
switchRecipe
}
from
'
./switch.recipe
'
;
import
{
recipe
as
table
}
from
'
./table.recipe
'
;
import
{
recipe
as
table
}
from
'
./table.recipe
'
;
import
{
recipe
as
tabs
}
from
'
./tabs.recipe
'
;
import
{
recipe
as
tabs
}
from
'
./tabs.recipe
'
;
...
@@ -55,6 +56,7 @@ export const slotRecipes = {
...
@@ -55,6 +56,7 @@ export const slotRecipes = {
progressCircle
,
progressCircle
,
radioGroup
,
radioGroup
,
select
,
select
,
stat
,
'
switch
'
:
switchRecipe
,
'
switch
'
:
switchRecipe
,
table
,
table
,
tabs
,
tabs
,
...
...
toolkit/theme/recipes/menu.recipe.ts
View file @
a51725d0
...
@@ -5,7 +5,7 @@ export const recipe = defineSlotRecipe({
...
@@ -5,7 +5,7 @@ export const recipe = defineSlotRecipe({
base
:
{
base
:
{
content
:
{
content
:
{
outline
:
0
,
outline
:
0
,
bg
:
'
popover
,
bg
'
,
bg
:
'
popover
.
bg
'
,
boxShadow
:
'
popover
'
,
boxShadow
:
'
popover
'
,
color
:
'
initial
'
,
color
:
'
initial
'
,
maxHeight
:
'
var(--available-height)
'
,
maxHeight
:
'
var(--available-height)
'
,
...
...
toolkit/theme/recipes/stat.recipe.ts
0 → 100644
View file @
a51725d0
import
{
defineSlotRecipe
}
from
'
@chakra-ui/react
'
;
export
const
recipe
=
defineSlotRecipe
({
slots
:
[
'
root
'
,
'
label
'
,
'
helpText
'
,
'
valueUnit
'
,
'
valueText
'
,
'
indicator
'
],
base
:
{
root
:
{
display
:
'
flex
'
,
flexDirection
:
'
column
'
,
gap
:
'
1
'
,
position
:
'
relative
'
,
flex
:
'
1
'
,
},
label
:
{
display
:
'
inline-flex
'
,
gap
:
'
1.5
'
,
alignItems
:
'
center
'
,
color
:
'
text
'
,
textStyle
:
'
sm
'
,
},
helpText
:
{
color
:
'
text
'
,
textStyle
:
'
xs
'
,
},
valueUnit
:
{
color
:
'
text
'
,
textStyle
:
'
xs
'
,
fontWeight
:
'
initial
'
,
letterSpacing
:
'
initial
'
,
},
valueText
:
{
verticalAlign
:
'
baseline
'
,
fontWeight
:
'
semibold
'
,
letterSpacing
:
'
normal
'
,
fontFeatureSettings
:
'
initial
'
,
fontVariantNumeric
:
'
initial
'
,
display
:
'
inline-flex
'
,
gap
:
'
1
'
,
},
indicator
:
{
display
:
'
inline-flex
'
,
alignItems
:
'
center
'
,
justifyContent
:
'
center
'
,
marginEnd
:
0
,
'
& :where(svg)
'
:
{
w
:
'
1em
'
,
h
:
'
1em
'
,
},
'
&[data-type=up]
'
:
{
color
:
'
stat.indicator.up
'
,
},
'
&[data-type=down]
'
:
{
color
:
'
stat.indicator.down
'
,
},
},
},
variants
:
{
orientation
:
{
horizontal
:
{
root
:
{
flexDirection
:
'
row
'
,
alignItems
:
'
center
'
,
},
},
},
positive
:
{
'
true
'
:
{
valueText
:
{
color
:
'
stat.indicator.up
'
,
},
},
'
false
'
:
{
valueText
:
{
color
:
'
stat.indicator.down
'
,
},
},
},
size
:
{
sm
:
{
valueText
:
{
textStyle
:
'
sm
'
,
},
},
md
:
{
valueText
:
{
textStyle
:
'
md
'
,
},
},
lg
:
{
valueText
:
{
textStyle
:
'
lg
'
,
},
},
},
},
defaultVariants
:
{
size
:
'
md
'
,
orientation
:
'
horizontal
'
,
},
});
ui/address/AddressBlocksValidated.tsx
View file @
a51725d0
import
{
Hide
,
Show
,
Table
,
Tbody
,
Th
,
Tr
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -14,12 +14,12 @@ import useSocketMessage from 'lib/socket/useSocketMessage';
...
@@ -14,12 +14,12 @@ import useSocketMessage from 'lib/socket/useSocketMessage';
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
BLOCK
}
from
'
stubs/block
'
;
import
{
BLOCK
}
from
'
stubs/block
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
TableBody
,
TableColumnHeader
,
TableHeaderSticky
,
TableRoot
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
ActionBar
,
{
ACTION_BAR_HEIGHT_DESKTOP
}
from
'
ui/shared/ActionBar
'
;
import
ActionBar
,
{
ACTION_BAR_HEIGHT_DESKTOP
}
from
'
ui/shared/ActionBar
'
;
import
DataListDisplay
from
'
ui/shared/DataListDisplay
'
;
import
DataListDisplay
from
'
ui/shared/DataListDisplay
'
;
import
Pagination
from
'
ui/shared/pagination/Pagination
'
;
import
Pagination
from
'
ui/shared/pagination/Pagination
'
;
import
useQueryWithPages
from
'
ui/shared/pagination/useQueryWithPages
'
;
import
useQueryWithPages
from
'
ui/shared/pagination/useQueryWithPages
'
;
import
*
as
SocketNewItemsNotice
from
'
ui/shared/SocketNewItemsNotice
'
;
import
*
as
SocketNewItemsNotice
from
'
ui/shared/SocketNewItemsNotice
'
;
import
{
default
as
Thead
}
from
'
ui/shared/TheadSticky
'
;
import
AddressBlocksValidatedListItem
from
'
./blocksValidated/AddressBlocksValidatedListItem
'
;
import
AddressBlocksValidatedListItem
from
'
./blocksValidated/AddressBlocksValidatedListItem
'
;
import
AddressBlocksValidatedTableItem
from
'
./blocksValidated/AddressBlocksValidatedTableItem
'
;
import
AddressBlocksValidatedTableItem
from
'
./blocksValidated/AddressBlocksValidatedTableItem
'
;
...
@@ -104,19 +104,19 @@ const AddressBlocksValidated = ({ scrollRef, shouldRender = true, isQueryEnabled
...
@@ -104,19 +104,19 @@ const AddressBlocksValidated = ({ scrollRef, shouldRender = true, isQueryEnabled
const
content
=
query
.
data
?.
items
?
(
const
content
=
query
.
data
?.
items
?
(
<>
<>
<
Hide
below=
"lg"
ssr=
{
false
}
>
<
Box
hideBelow=
"lg"
>
<
Table
style=
{
{
tableLayout
:
'
auto
'
}
}
>
<
Table
Root
style=
{
{
tableLayout
:
'
auto
'
}
}
>
<
T
head
top=
{
query
.
pagination
.
isVisible
?
ACTION_BAR_HEIGHT_DESKTOP
:
0
}
>
<
T
ableHeaderSticky
top=
{
query
.
pagination
.
isVisible
?
ACTION_BAR_HEIGHT_DESKTOP
:
0
}
>
<
T
r
>
<
T
ableRow
>
<
T
h
>
Block
</
Th
>
<
T
ableColumnHeader
>
Block
</
TableColumnHeader
>
<
T
h
>
Age
</
Th
>
<
T
ableColumnHeader
>
Age
</
TableColumnHeader
>
<
T
h
>
Txn
</
Th
>
<
T
ableColumnHeader
>
Txn
</
TableColumnHeader
>
<
T
h
>
Gas used
</
Th
>
<
T
ableColumnHeader
>
Gas used
</
TableColumnHeader
>
{
!
config
.
UI
.
views
.
block
.
hiddenFields
?.
total_reward
&&
!
config
.
features
.
rollup
.
isEnabled
&&
{
!
config
.
UI
.
views
.
block
.
hiddenFields
?.
total_reward
&&
!
config
.
features
.
rollup
.
isEnabled
&&
<
Th
isNumeric
>
Reward
{
currencyUnits
.
ether
}
</
Th
>
}
<
TableColumnHeader
isNumeric
>
Reward
{
currencyUnits
.
ether
}
</
TableColumnHeader
>
}
</
T
r
>
</
T
ableRow
>
</
T
head
>
</
T
ableHeaderSticky
>
<
T
b
ody
>
<
T
ableB
ody
>
<
SocketNewItemsNotice
.
Desktop
<
SocketNewItemsNotice
.
Desktop
url=
{
window
.
location
.
href
}
url=
{
window
.
location
.
href
}
num=
{
newItemsCount
}
num=
{
newItemsCount
}
...
@@ -132,10 +132,10 @@ const AddressBlocksValidated = ({ scrollRef, shouldRender = true, isQueryEnabled
...
@@ -132,10 +132,10 @@ const AddressBlocksValidated = ({ scrollRef, shouldRender = true, isQueryEnabled
isLoading=
{
query
.
isPlaceholderData
}
isLoading=
{
query
.
isPlaceholderData
}
/>
/>
))
}
))
}
</
T
b
ody
>
</
T
ableB
ody
>
</
Table
>
</
Table
Root
>
</
Hide
>
</
Box
>
<
Show
below=
"lg"
ssr=
{
false
}
>
<
Box
hideFrom=
"lg"
>
{
query
.
pagination
.
page
===
1
&&
(
{
query
.
pagination
.
page
===
1
&&
(
<
SocketNewItemsNotice
.
Mobile
<
SocketNewItemsNotice
.
Mobile
url=
{
window
.
location
.
href
}
url=
{
window
.
location
.
href
}
...
@@ -153,7 +153,7 @@ const AddressBlocksValidated = ({ scrollRef, shouldRender = true, isQueryEnabled
...
@@ -153,7 +153,7 @@ const AddressBlocksValidated = ({ scrollRef, shouldRender = true, isQueryEnabled
isLoading=
{
query
.
isPlaceholderData
}
isLoading=
{
query
.
isPlaceholderData
}
/>
/>
))
}
))
}
</
Show
>
</
Box
>
</>
</>
)
:
null
;
)
:
null
;
...
@@ -166,11 +166,12 @@ const AddressBlocksValidated = ({ scrollRef, shouldRender = true, isQueryEnabled
...
@@ -166,11 +166,12 @@ const AddressBlocksValidated = ({ scrollRef, shouldRender = true, isQueryEnabled
return
(
return
(
<
DataListDisplay
<
DataListDisplay
isError=
{
query
.
isError
}
isError=
{
query
.
isError
}
items
=
{
query
.
data
?.
items
}
items
Num=
{
query
.
data
?.
items
.
length
}
emptyText=
"There are no validated blocks for this address."
emptyText=
"There are no validated blocks for this address."
content=
{
content
}
actionBar=
{
actionBar
}
actionBar=
{
actionBar
}
/>
>
{
content
}
</
DataListDisplay
>
);
);
};
};
...
...
ui/address/AddressTxs.tsx
View file @
a51725d0
...
@@ -187,7 +187,7 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, shouldRender =
...
@@ -187,7 +187,7 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, shouldRender =
return (
return (
<>
<>
{ !isMobile && (
{ !isMobile && (
<ActionBar
mt={ -6 }
>
<ActionBar>
{ filter }
{ filter }
{ currentAddress && csvExportLink }
{ currentAddress && csvExportLink }
<Pagination { ...addressTxsQuery.pagination } ml={ 8 }/>
<Pagination { ...addressTxsQuery.pagination } ml={ 8 }/>
...
...
ui/address/blocksValidated/AddressBlocksValidatedListItem.tsx
View file @
a51725d0
...
@@ -7,8 +7,8 @@ import type { Block } from 'types/api/block';
...
@@ -7,8 +7,8 @@ import type { Block } from 'types/api/block';
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
import
getBlockTotalReward
from
'
lib/block/getBlockTotalReward
'
;
import
getBlockTotalReward
from
'
lib/block/getBlockTotalReward
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
BlockGasUsed
from
'
ui/shared/block/BlockGasUsed
'
;
import
BlockGasUsed
from
'
ui/shared/block/BlockGasUsed
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
BlockEntity
from
'
ui/shared/entities/block/BlockEntity
'
;
import
BlockEntity
from
'
ui/shared/entities/block/BlockEntity
'
;
import
ListItemMobile
from
'
ui/shared/ListItemMobile/ListItemMobile
'
;
import
ListItemMobile
from
'
ui/shared/ListItemMobile/ListItemMobile
'
;
import
TimeAgoWithTooltip
from
'
ui/shared/TimeAgoWithTooltip
'
;
import
TimeAgoWithTooltip
from
'
ui/shared/TimeAgoWithTooltip
'
;
...
@@ -22,7 +22,7 @@ const AddressBlocksValidatedListItem = (props: Props) => {
...
@@ -22,7 +22,7 @@ const AddressBlocksValidatedListItem = (props: Props) => {
const
totalReward
=
getBlockTotalReward
(
props
);
const
totalReward
=
getBlockTotalReward
(
props
);
return
(
return
(
<
ListItemMobile
rowGap=
{
2
}
isAnimated
>
<
ListItemMobile
rowGap=
{
2
}
>
<
Flex
justifyContent=
"space-between"
w=
"100%"
>
<
Flex
justifyContent=
"space-between"
w=
"100%"
>
<
BlockEntity
<
BlockEntity
isLoading=
{
props
.
isLoading
}
isLoading=
{
props
.
isLoading
}
...
@@ -34,32 +34,32 @@ const AddressBlocksValidatedListItem = (props: Props) => {
...
@@ -34,32 +34,32 @@ const AddressBlocksValidatedListItem = (props: Props) => {
timestamp=
{
props
.
timestamp
}
timestamp=
{
props
.
timestamp
}
enableIncrement=
{
props
.
page
===
1
}
enableIncrement=
{
props
.
page
===
1
}
isLoading=
{
props
.
isLoading
}
isLoading=
{
props
.
isLoading
}
color=
"text
_
secondary"
color=
"text
.
secondary"
display=
"inline-block"
display=
"inline-block"
/>
/>
</
Flex
>
</
Flex
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Txn
</
Skeleton
>
<
Skeleton
loading=
{
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Txn
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
display=
"inline-block"
color=
"Skeleton_secondary"
>
<
Skeleton
loading=
{
props
.
isLoading
}
display=
"inline-block"
color=
"Skeleton_secondary"
>
<
span
>
{
props
.
transaction_count
}
</
span
>
<
span
>
{
props
.
transaction_count
}
</
span
>
</
Skeleton
>
</
Skeleton
>
</
Flex
>
</
Flex
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Gas used
</
Skeleton
>
<
Skeleton
loading=
{
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Gas used
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
>
<
Skeleton
loading=
{
props
.
isLoading
}
>
<
Text
color=
"text
_
secondary"
>
{
BigNumber
(
props
.
gas_used
||
0
).
toFormat
()
}
</
Text
>
<
Text
color=
"text
.
secondary"
>
{
BigNumber
(
props
.
gas_used
||
0
).
toFormat
()
}
</
Text
>
</
Skeleton
>
</
Skeleton
>
<
BlockGasUsed
<
BlockGasUsed
gasUsed=
{
props
.
gas_used
}
gasUsed=
{
props
.
gas_used
||
undefined
}
gasLimit=
{
props
.
gas_limit
}
gasLimit=
{
props
.
gas_limit
}
isLoading=
{
props
.
isLoading
}
isLoading=
{
props
.
isLoading
}
/>
/>
</
Flex
>
</
Flex
>
{
!
config
.
UI
.
views
.
block
.
hiddenFields
?.
total_reward
&&
!
config
.
features
.
rollup
.
isEnabled
&&
(
{
!
config
.
UI
.
views
.
block
.
hiddenFields
?.
total_reward
&&
!
config
.
features
.
rollup
.
isEnabled
&&
(
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Reward
{
currencyUnits
.
ether
}
</
Skeleton
>
<
Skeleton
loading=
{
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Reward
{
currencyUnits
.
ether
}
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
>
<
Skeleton
loading=
{
props
.
isLoading
}
>
<
Text
color=
"text
_
secondary"
>
{
totalReward
.
toFixed
()
}
</
Text
>
<
Text
color=
"text
.
secondary"
>
{
totalReward
.
toFixed
()
}
</
Text
>
</
Skeleton
>
</
Skeleton
>
</
Flex
>
</
Flex
>
)
}
)
}
...
...
ui/address/blocksValidated/AddressBlocksValidatedTableItem.tsx
View file @
a51725d0
import
{
Td
,
Tr
,
Flex
}
from
'
@chakra-ui/react
'
;
import
{
Flex
}
from
'
@chakra-ui/react
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -6,8 +6,9 @@ import type { Block } from 'types/api/block';
...
@@ -6,8 +6,9 @@ import type { Block } from 'types/api/block';
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
import
getBlockTotalReward
from
'
lib/block/getBlockTotalReward
'
;
import
getBlockTotalReward
from
'
lib/block/getBlockTotalReward
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
TableCell
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
BlockGasUsed
from
'
ui/shared/block/BlockGasUsed
'
;
import
BlockGasUsed
from
'
ui/shared/block/BlockGasUsed
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
BlockEntity
from
'
ui/shared/entities/block/BlockEntity
'
;
import
BlockEntity
from
'
ui/shared/entities/block/BlockEntity
'
;
import
TimeAgoWithTooltip
from
'
ui/shared/TimeAgoWithTooltip
'
;
import
TimeAgoWithTooltip
from
'
ui/shared/TimeAgoWithTooltip
'
;
...
@@ -20,51 +21,50 @@ const AddressBlocksValidatedTableItem = (props: Props) => {
...
@@ -20,51 +21,50 @@ const AddressBlocksValidatedTableItem = (props: Props) => {
const
totalReward
=
getBlockTotalReward
(
props
);
const
totalReward
=
getBlockTotalReward
(
props
);
return
(
return
(
<
T
r
>
<
T
ableRow
>
<
T
d
>
<
T
ableCell
>
<
BlockEntity
<
BlockEntity
isLoading=
{
props
.
isLoading
}
isLoading=
{
props
.
isLoading
}
number=
{
props
.
height
}
number=
{
props
.
height
}
noIcon
noIcon
fontSize=
"sm"
textStyle=
"sm"
lineHeight=
{
5
}
fontWeight=
{
700
}
fontWeight=
{
700
}
/>
/>
</
T
d
>
</
T
ableCell
>
<
T
d
>
<
T
ableCell
>
<
TimeAgoWithTooltip
<
TimeAgoWithTooltip
timestamp=
{
props
.
timestamp
}
timestamp=
{
props
.
timestamp
}
enableIncrement=
{
props
.
page
===
1
}
enableIncrement=
{
props
.
page
===
1
}
isLoading=
{
props
.
isLoading
}
isLoading=
{
props
.
isLoading
}
color=
"text
_
secondary"
color=
"text
.
secondary"
display=
"inline-block"
display=
"inline-block"
/>
/>
</
T
d
>
</
T
ableCell
>
<
T
d
>
<
T
ableCell
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
display=
"inline-block"
fontWeight=
"500"
>
<
Skeleton
loading=
{
props
.
isLoading
}
display=
"inline-block"
fontWeight=
"500"
>
<
span
>
{
props
.
transaction_count
}
</
span
>
<
span
>
{
props
.
transaction_count
}
</
span
>
</
Skeleton
>
</
Skeleton
>
</
T
d
>
</
T
ableCell
>
<
T
d
>
<
T
ableCell
>
<
Flex
alignItems=
"center"
columnGap=
{
2
}
>
<
Flex
alignItems=
"center"
columnGap=
{
2
}
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
flexBasis=
"80px"
>
<
Skeleton
loading=
{
props
.
isLoading
}
flexBasis=
"80px"
>
{
BigNumber
(
props
.
gas_used
||
0
).
toFormat
()
}
{
BigNumber
(
props
.
gas_used
||
0
).
toFormat
()
}
</
Skeleton
>
</
Skeleton
>
<
BlockGasUsed
<
BlockGasUsed
gasUsed=
{
props
.
gas_used
}
gasUsed=
{
props
.
gas_used
||
undefined
}
gasLimit=
{
props
.
gas_limit
}
gasLimit=
{
props
.
gas_limit
}
isLoading=
{
props
.
isLoading
}
isLoading=
{
props
.
isLoading
}
/>
/>
</
Flex
>
</
Flex
>
</
T
d
>
</
T
ableCell
>
{
!
config
.
UI
.
views
.
block
.
hiddenFields
?.
total_reward
&&
!
config
.
features
.
rollup
.
isEnabled
&&
(
{
!
config
.
UI
.
views
.
block
.
hiddenFields
?.
total_reward
&&
!
config
.
features
.
rollup
.
isEnabled
&&
(
<
T
d
isNumeric
>
<
T
ableCell
isNumeric
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
display=
"inline-block"
>
<
Skeleton
loading=
{
props
.
isLoading
}
display=
"inline-block"
>
<
span
>
{
totalReward
.
toFixed
()
}
</
span
>
<
span
>
{
totalReward
.
toFixed
()
}
</
span
>
</
Skeleton
>
</
Skeleton
>
</
T
d
>
</
T
ableCell
>
)
}
)
}
</
T
r
>
</
T
ableRow
>
);
);
};
};
...
...
ui/address/coinBalance/AddressCoinBalanceChart.tsx
View file @
a51725d0
...
@@ -34,7 +34,7 @@ const AddressCoinBalanceChart = ({ addressHash }: Props) => {
...
@@ -34,7 +34,7 @@ const AddressCoinBalanceChart = ({ addressHash }: Props) => {
isLoading=
{
isPending
}
isLoading=
{
isPending
}
h=
"300px"
h=
"300px"
units=
{
currencyUnits
.
ether
}
units=
{
currencyUnits
.
ether
}
emptyText=
{
data
?.
days
&&
`Insufficient data for the past ${ data.days } days`
}
emptyText=
{
data
?.
days
?
`Insufficient data for the past ${ data.days } days`
:
undefined
}
/>
/>
);
);
};
};
...
...
ui/address/coinBalance/AddressCoinBalanceHistory.tsx
View file @
a51725d0
import
{
Hide
,
Show
,
Table
,
Tbody
,
Th
,
Tr
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
type
{
UseQueryResult
}
from
'
@tanstack/react-query
'
;
import
type
{
UseQueryResult
}
from
'
@tanstack/react-query
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -7,10 +7,10 @@ import type { PaginationParams } from 'ui/shared/pagination/types';
...
@@ -7,10 +7,10 @@ import type { PaginationParams } from 'ui/shared/pagination/types';
import
type
{
ResourceError
}
from
'
lib/api/resources
'
;
import
type
{
ResourceError
}
from
'
lib/api/resources
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
TableBody
,
TableColumnHeader
,
TableHeaderSticky
,
TableRoot
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
ActionBar
,
{
ACTION_BAR_HEIGHT_DESKTOP
}
from
'
ui/shared/ActionBar
'
;
import
ActionBar
,
{
ACTION_BAR_HEIGHT_DESKTOP
}
from
'
ui/shared/ActionBar
'
;
import
DataListDisplay
from
'
ui/shared/DataListDisplay
'
;
import
DataListDisplay
from
'
ui/shared/DataListDisplay
'
;
import
Pagination
from
'
ui/shared/pagination/Pagination
'
;
import
Pagination
from
'
ui/shared/pagination/Pagination
'
;
import
{
default
as
Thead
}
from
'
ui/shared/TheadSticky
'
;
import
AddressCoinBalanceListItem
from
'
./AddressCoinBalanceListItem
'
;
import
AddressCoinBalanceListItem
from
'
./AddressCoinBalanceListItem
'
;
import
AddressCoinBalanceTableItem
from
'
./AddressCoinBalanceTableItem
'
;
import
AddressCoinBalanceTableItem
from
'
./AddressCoinBalanceTableItem
'
;
...
@@ -25,18 +25,18 @@ const AddressCoinBalanceHistory = ({ query }: Props) => {
...
@@ -25,18 +25,18 @@ const AddressCoinBalanceHistory = ({ query }: Props) => {
const
content
=
query
.
data
?.
items
?
(
const
content
=
query
.
data
?.
items
?
(
<>
<>
<
Hide
below=
"lg"
ssr=
{
false
}
>
<
Box
hideBelow=
"lg"
>
<
Table
>
<
Table
Root
>
<
T
head
top=
{
query
.
pagination
.
isVisible
?
ACTION_BAR_HEIGHT_DESKTOP
:
0
}
>
<
T
ableHeaderSticky
top=
{
query
.
pagination
.
isVisible
?
ACTION_BAR_HEIGHT_DESKTOP
:
0
}
>
<
T
r
>
<
T
ableRow
>
<
T
h
width=
"20%"
>
Block
</
Th
>
<
T
ableColumnHeader
width=
"20%"
>
Block
</
TableColumnHeader
>
<
T
h
width=
"20%"
>
Txn
</
Th
>
<
T
ableColumnHeader
width=
"20%"
>
Txn
</
TableColumnHeader
>
<
T
h
width=
"20%"
>
Age
</
Th
>
<
T
ableColumnHeader
width=
"20%"
>
Age
</
TableColumnHeader
>
<
T
h
width=
"20%"
isNumeric
pr=
{
1
}
>
Balance
{
currencyUnits
.
ether
}
</
Th
>
<
T
ableColumnHeader
width=
"20%"
isNumeric
pr=
{
1
}
>
Balance
{
currencyUnits
.
ether
}
</
TableColumnHeader
>
<
T
h
width=
"20%"
isNumeric
>
Delta
</
Th
>
<
T
ableColumnHeader
width=
"20%"
isNumeric
>
Delta
</
TableColumnHeader
>
</
T
r
>
</
T
ableRow
>
</
T
head
>
</
T
ableHeaderSticky
>
<
T
b
ody
>
<
T
ableB
ody
>
{
query
.
data
.
items
.
map
((
item
,
index
)
=>
(
{
query
.
data
.
items
.
map
((
item
,
index
)
=>
(
<
AddressCoinBalanceTableItem
<
AddressCoinBalanceTableItem
key=
{
item
.
block_number
+
(
query
.
isPlaceholderData
?
String
(
index
)
:
''
)
}
key=
{
item
.
block_number
+
(
query
.
isPlaceholderData
?
String
(
index
)
:
''
)
}
...
@@ -45,10 +45,10 @@ const AddressCoinBalanceHistory = ({ query }: Props) => {
...
@@ -45,10 +45,10 @@ const AddressCoinBalanceHistory = ({ query }: Props) => {
isLoading=
{
query
.
isPlaceholderData
}
isLoading=
{
query
.
isPlaceholderData
}
/>
/>
))
}
))
}
</
T
b
ody
>
</
T
ableB
ody
>
</
Table
>
</
Table
Root
>
</
Hide
>
</
Box
>
<
Show
below=
"lg"
ssr=
{
false
}
>
<
Box
hideFrom=
"lg"
>
{
query
.
data
.
items
.
map
((
item
,
index
)
=>
(
{
query
.
data
.
items
.
map
((
item
,
index
)
=>
(
<
AddressCoinBalanceListItem
<
AddressCoinBalanceListItem
key=
{
item
.
block_number
+
(
query
.
isPlaceholderData
?
String
(
index
)
:
''
)
}
key=
{
item
.
block_number
+
(
query
.
isPlaceholderData
?
String
(
index
)
:
''
)
}
...
@@ -57,7 +57,7 @@ const AddressCoinBalanceHistory = ({ query }: Props) => {
...
@@ -57,7 +57,7 @@ const AddressCoinBalanceHistory = ({ query }: Props) => {
isLoading=
{
query
.
isPlaceholderData
}
isLoading=
{
query
.
isPlaceholderData
}
/>
/>
))
}
))
}
</
Show
>
</
Box
>
</>
</>
)
:
null
;
)
:
null
;
...
@@ -71,11 +71,12 @@ const AddressCoinBalanceHistory = ({ query }: Props) => {
...
@@ -71,11 +71,12 @@ const AddressCoinBalanceHistory = ({ query }: Props) => {
<
DataListDisplay
<
DataListDisplay
mt=
{
8
}
mt=
{
8
}
isError=
{
query
.
isError
}
isError=
{
query
.
isError
}
items
=
{
query
.
data
?.
items
}
items
Num=
{
query
.
data
?.
items
.
length
}
emptyText=
"There is no coin balance history for this address."
emptyText=
"There is no coin balance history for this address."
content=
{
content
}
actionBar=
{
actionBar
}
actionBar=
{
actionBar
}
/>
>
{
content
}
</
DataListDisplay
>
);
);
};
};
...
...
ui/address/coinBalance/AddressCoinBalanceListItem.tsx
View file @
a51725d0
import
{
Text
,
Stat
,
StatHelpText
,
StatArrow
,
Flex
}
from
'
@chakra-ui/react
'
;
import
{
Stat
,
Flex
}
from
'
@chakra-ui/react
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -6,7 +6,7 @@ import type { AddressCoinBalanceHistoryItem } from 'types/api/address';
...
@@ -6,7 +6,7 @@ import type { AddressCoinBalanceHistoryItem } from 'types/api/address';
import
{
WEI
,
ZERO
}
from
'
lib/consts
'
;
import
{
WEI
,
ZERO
}
from
'
lib/consts
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
BlockEntity
from
'
ui/shared/entities/block/BlockEntity
'
;
import
BlockEntity
from
'
ui/shared/entities/block/BlockEntity
'
;
import
TxEntity
from
'
ui/shared/entities/tx/TxEntity
'
;
import
TxEntity
from
'
ui/shared/entities/tx/TxEntity
'
;
import
ListItemMobile
from
'
ui/shared/ListItemMobile/ListItemMobile
'
;
import
ListItemMobile
from
'
ui/shared/ListItemMobile/ListItemMobile
'
;
...
@@ -22,24 +22,22 @@ const AddressCoinBalanceListItem = (props: Props) => {
...
@@ -22,24 +22,22 @@ const AddressCoinBalanceListItem = (props: Props) => {
const
isPositiveDelta
=
deltaBn
.
gte
(
ZERO
);
const
isPositiveDelta
=
deltaBn
.
gte
(
ZERO
);
return
(
return
(
<
ListItemMobile
rowGap=
{
2
}
isAnimated
>
<
ListItemMobile
rowGap=
{
2
}
>
<
Flex
justifyContent=
"space-between"
w=
"100%"
>
<
Flex
justifyContent=
"space-between"
w=
"100%"
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
fontWeight=
{
600
}
>
<
Skeleton
loading=
{
props
.
isLoading
}
fontWeight=
{
600
}
>
{
BigNumber
(
props
.
value
).
div
(
WEI
).
dp
(
8
).
toFormat
()
}
{
currencyUnits
.
ether
}
{
BigNumber
(
props
.
value
).
div
(
WEI
).
dp
(
8
).
toFormat
()
}
{
currencyUnits
.
ether
}
</
Skeleton
>
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
>
<
Skeleton
loading=
{
props
.
isLoading
}
>
<
Stat
flexGrow=
"0"
>
<
Stat
.
Root
flexGrow=
"0"
positive=
{
isPositiveDelta
}
size=
"sm"
>
<
StatHelpText
display=
"flex"
mb=
{
0
}
alignItems=
"center"
>
{
isPositiveDelta
?
<
Stat
.
UpIndicator
/>
:
<
Stat
.
DownIndicator
/>
}
<
StatArrow
type=
{
isPositiveDelta
?
'
increase
'
:
'
decrease
'
}
mr=
{
2
}
/>
<
Stat
.
ValueText
fontWeight=
{
600
}
>
<
Text
as=
"span"
color=
{
isPositiveDelta
?
'
green.500
'
:
'
red.500
'
}
fontWeight=
{
600
}
>
{
deltaBn
.
dp
(
8
).
toFormat
()
}
{
deltaBn
.
dp
(
8
).
toFormat
()
}
</
Text
>
</
Stat
.
ValueText
>
</
StatHelpText
>
</
Stat
.
Root
>
</
Stat
>
</
Skeleton
>
</
Skeleton
>
</
Flex
>
</
Flex
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Block
</
Skeleton
>
<
Skeleton
loading=
{
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Block
</
Skeleton
>
<
BlockEntity
<
BlockEntity
isLoading=
{
props
.
isLoading
}
isLoading=
{
props
.
isLoading
}
number=
{
props
.
block_number
}
number=
{
props
.
block_number
}
...
@@ -49,7 +47,7 @@ const AddressCoinBalanceListItem = (props: Props) => {
...
@@ -49,7 +47,7 @@ const AddressCoinBalanceListItem = (props: Props) => {
</
Flex
>
</
Flex
>
{
props
.
transaction_hash
&&
(
{
props
.
transaction_hash
&&
(
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Txs
</
Skeleton
>
<
Skeleton
loading=
{
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Txs
</
Skeleton
>
<
TxEntity
<
TxEntity
hash=
{
props
.
transaction_hash
}
hash=
{
props
.
transaction_hash
}
isLoading=
{
props
.
isLoading
}
isLoading=
{
props
.
isLoading
}
...
@@ -60,7 +58,7 @@ const AddressCoinBalanceListItem = (props: Props) => {
...
@@ -60,7 +58,7 @@ const AddressCoinBalanceListItem = (props: Props) => {
</
Flex
>
</
Flex
>
)
}
)
}
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Age
</
Skeleton
>
<
Skeleton
loading=
{
props
.
isLoading
}
fontWeight=
{
500
}
flexShrink=
{
0
}
>
Age
</
Skeleton
>
<
TimeAgoWithTooltip
<
TimeAgoWithTooltip
timestamp=
{
props
.
block_timestamp
}
timestamp=
{
props
.
block_timestamp
}
enableIncrement=
{
props
.
page
===
1
}
enableIncrement=
{
props
.
page
===
1
}
...
...
ui/address/coinBalance/AddressCoinBalanceTableItem.tsx
View file @
a51725d0
import
{
Td
,
Tr
,
Text
,
Stat
,
StatHelpText
,
StatArrow
}
from
'
@chakra-ui/react
'
;
import
{
Stat
}
from
'
@chakra-ui/react
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
AddressCoinBalanceHistoryItem
}
from
'
types/api/address
'
;
import
type
{
AddressCoinBalanceHistoryItem
}
from
'
types/api/address
'
;
import
{
WEI
,
ZERO
}
from
'
lib/consts
'
;
import
{
WEI
,
ZERO
}
from
'
lib/consts
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
TableCell
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
BlockEntity
from
'
ui/shared/entities/block/BlockEntity
'
;
import
BlockEntity
from
'
ui/shared/entities/block/BlockEntity
'
;
import
TxEntity
from
'
ui/shared/entities/tx/TxEntity
'
;
import
TxEntity
from
'
ui/shared/entities/tx/TxEntity
'
;
import
TimeAgoWithTooltip
from
'
ui/shared/TimeAgoWithTooltip
'
;
import
TimeAgoWithTooltip
from
'
ui/shared/TimeAgoWithTooltip
'
;
...
@@ -20,18 +21,16 @@ const AddressCoinBalanceTableItem = (props: Props) => {
...
@@ -20,18 +21,16 @@ const AddressCoinBalanceTableItem = (props: Props) => {
const
isPositiveDelta
=
deltaBn
.
gte
(
ZERO
);
const
isPositiveDelta
=
deltaBn
.
gte
(
ZERO
);
return
(
return
(
<
T
r
>
<
T
ableRow
>
<
T
d
>
<
T
ableCell
>
<
BlockEntity
<
BlockEntity
isLoading=
{
props
.
isLoading
}
isLoading=
{
props
.
isLoading
}
number=
{
props
.
block_number
}
number=
{
props
.
block_number
}
noIcon
noIcon
fontSize=
"sm"
lineHeight=
{
5
}
fontWeight=
{
700
}
fontWeight=
{
700
}
/>
/>
</
T
d
>
</
T
ableCell
>
<
T
d
>
<
T
ableCell
>
{
props
.
transaction_hash
&&
(
{
props
.
transaction_hash
&&
(
<
TxEntity
<
TxEntity
hash=
{
props
.
transaction_hash
}
hash=
{
props
.
transaction_hash
}
...
@@ -41,34 +40,32 @@ const AddressCoinBalanceTableItem = (props: Props) => {
...
@@ -41,34 +40,32 @@ const AddressCoinBalanceTableItem = (props: Props) => {
maxW=
"150px"
maxW=
"150px"
/>
/>
)
}
)
}
</
T
d
>
</
T
ableCell
>
<
T
d
>
<
T
ableCell
>
<
TimeAgoWithTooltip
<
TimeAgoWithTooltip
timestamp=
{
props
.
block_timestamp
}
timestamp=
{
props
.
block_timestamp
}
enableIncrement=
{
props
.
page
===
1
}
enableIncrement=
{
props
.
page
===
1
}
isLoading=
{
props
.
isLoading
}
isLoading=
{
props
.
isLoading
}
color=
"text
_
secondary"
color=
"text
.
secondary"
display=
"inline-block"
display=
"inline-block"
/>
/>
</
T
d
>
</
T
ableCell
>
<
T
d
isNumeric
pr=
{
1
}
>
<
T
ableCell
isNumeric
pr=
{
1
}
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
color=
"text_
secondary"
display=
"inline-block"
>
<
Skeleton
loading=
{
props
.
isLoading
}
color=
"text.
secondary"
display=
"inline-block"
>
<
span
>
{
BigNumber
(
props
.
value
).
div
(
WEI
).
dp
(
8
).
toFormat
()
}
</
span
>
<
span
>
{
BigNumber
(
props
.
value
).
div
(
WEI
).
dp
(
8
).
toFormat
()
}
</
span
>
</
Skeleton
>
</
Skeleton
>
</
Td
>
</
TableCell
>
<
Td
isNumeric
display=
"flex"
justifyContent=
"end"
>
<
TableCell
isNumeric
display=
"flex"
justifyContent=
"end"
>
<
Skeleton
isLoaded=
{
!
props
.
isLoading
}
>
<
Skeleton
loading=
{
props
.
isLoading
}
>
<
Stat
flexGrow=
"0"
lineHeight=
{
5
}
>
<
Stat
.
Root
flexGrow=
"0"
size=
"sm"
positive=
{
isPositiveDelta
}
>
<
StatHelpText
display=
"flex"
mb=
{
0
}
alignItems=
"center"
>
{
isPositiveDelta
?
<
Stat
.
UpIndicator
/>
:
<
Stat
.
DownIndicator
/>
}
<
StatArrow
type=
{
isPositiveDelta
?
'
increase
'
:
'
decrease
'
}
mr=
{
2
}
/>
<
Stat
.
ValueText
fontWeight=
{
600
}
>
<
Text
as=
"span"
color=
{
isPositiveDelta
?
'
green.500
'
:
'
red.500
'
}
fontWeight=
{
600
}
>
{
deltaBn
.
dp
(
8
).
toFormat
()
}
{
deltaBn
.
dp
(
8
).
toFormat
()
}
</
Text
>
</
Stat
.
ValueText
>
</
StatHelpText
>
</
Stat
.
Root
>
</
Stat
>
</
Skeleton
>
</
Skeleton
>
</
T
d
>
</
T
ableCell
>
</
T
r
>
</
T
ableRow
>
);
);
};
};
...
...
ui/pages/Address.tsx
View file @
a51725d0
...
@@ -2,8 +2,8 @@ import { Box, Flex, HStack } from '@chakra-ui/react';
...
@@ -2,8 +2,8 @@ import { Box, Flex, HStack } from '@chakra-ui/react';
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
TabItemRegular
}
from
'
toolkit/components/AdaptiveTabs/types
'
;
import
type
{
EntityTag
}
from
'
ui/shared/EntityTags/types
'
;
import
type
{
EntityTag
}
from
'
ui/shared/EntityTags/types
'
;
import
type
{
RoutedTab
}
from
'
ui/shared/Tabs/types
'
;
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
import
getCheckedSummedAddress
from
'
lib/address/getCheckedSummedAddress
'
;
import
getCheckedSummedAddress
from
'
lib/address/getCheckedSummedAddress
'
;
...
@@ -151,7 +151,7 @@ const AddressPageContent = () => {
...
@@ -151,7 +151,7 @@ const AddressPageContent = () => {
Boolean(config.features.mudFramework.isEnabled && mudTablesCountQuery.data && mudTablesCountQuery.data > 0),
Boolean(config.features.mudFramework.isEnabled && mudTablesCountQuery.data && mudTablesCountQuery.data > 0),
);
);
const tabs: Array<
RoutedTab
> = React.useMemo(() => {
const tabs: Array<
TabItemRegular
> = React.useMemo(() => {
return [
return [
// config.features.mudFramework.isEnabled && mudTablesCountQuery.data && mudTablesCountQuery.data > 0 && {
// config.features.mudFramework.isEnabled && mudTablesCountQuery.data && mudTablesCountQuery.data > 0 && {
// id: 'mud',
// id: 'mud',
...
@@ -213,19 +213,19 @@ const AddressPageContent = () => {
...
@@ -213,19 +213,19 @@ const AddressPageContent = () => {
// count: addressTabsCountersQuery.data?.celo_election_rewards_count,
// count: addressTabsCountersQuery.data?.celo_election_rewards_count,
// component: <AddressEpochRewards scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
// component: <AddressEpochRewards scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
// } : undefined,
// } : undefined,
//
{
{
//
id: 'coin_balance_history',
id: 'coin_balance_history',
//
title: 'Coin balance history',
title: 'Coin balance history',
//
component: <AddressCoinBalance shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
component: <AddressCoinBalance shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
//
},
},
//
addressTabsCountersQuery.data?.validations_count ?
addressTabsCountersQuery.data?.validations_count ?
//
{
{
//
id: 'blocks_validated',
id: 'blocks_validated',
//
title: `
Blocks
$
{
getNetworkValidationActionText
()
}
`,
title: `
Blocks
$
{
getNetworkValidationActionText
()
}
`,
//
count: addressTabsCountersQuery.data?.validations_count,
count: addressTabsCountersQuery.data?.validations_count,
//
component: <AddressBlocksValidated scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
component: <AddressBlocksValidated scrollRef={ tabsScrollRef } shouldRender={ !isTabsLoading } isQueryEnabled={ areQueriesEnabled }/>,
//
} :
} :
//
undefined,
undefined,
// addressTabsCountersQuery.data?.logs_count ?
// addressTabsCountersQuery.data?.logs_count ?
// {
// {
// id: 'logs',
// id: 'logs',
...
...
ui/shared/chart/ChartAxis.tsx
View file @
a51725d0
import
{
use
ColorModeValue
,
use
Token
}
from
'
@chakra-ui/react
'
;
import
{
useToken
}
from
'
@chakra-ui/react
'
;
import
*
as
d3
from
'
d3
'
;
import
*
as
d3
from
'
d3
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
useColorModeValue
}
from
'
toolkit/chakra/color-mode
'
;
interface
Props
extends
Omit
<
React
.
SVGProps
<
SVGGElement
>
,
'
scale
'
>
{
interface
Props
extends
Omit
<
React
.
SVGProps
<
SVGGElement
>
,
'
scale
'
>
{
type
:
'
left
'
|
'
bottom
'
;
type
:
'
left
'
|
'
bottom
'
;
scale
:
d3
.
ScaleTime
<
number
,
number
>
|
d3
.
ScaleLinear
<
number
,
number
>
;
scale
:
d3
.
ScaleTime
<
number
,
number
>
|
d3
.
ScaleLinear
<
number
,
number
>
;
...
@@ -14,8 +16,7 @@ interface Props extends Omit<React.SVGProps<SVGGElement>, 'scale'> {
...
@@ -14,8 +16,7 @@ interface Props extends Omit<React.SVGProps<SVGGElement>, 'scale'> {
const
ChartAxis
=
({
type
,
scale
,
ticks
,
tickFormatGenerator
,
noAnimation
,
anchorEl
,
...
props
}:
Props
)
=>
{
const
ChartAxis
=
({
type
,
scale
,
ticks
,
tickFormatGenerator
,
noAnimation
,
anchorEl
,
...
props
}:
Props
)
=>
{
const
ref
=
React
.
useRef
<
SVGGElement
>
(
null
);
const
ref
=
React
.
useRef
<
SVGGElement
>
(
null
);
const
textColorToken
=
useColorModeValue
(
'
blackAlpha.600
'
,
'
whiteAlpha.500
'
);
const
textColor
=
useToken
(
'
colors
'
,
useColorModeValue
(
'
blackAlpha.600
'
,
'
whiteAlpha.500
'
));
const
textColor
=
useToken
(
'
colors
'
,
textColorToken
);
React
.
useEffect
(()
=>
{
React
.
useEffect
(()
=>
{
if
(
!
ref
.
current
)
{
if
(
!
ref
.
current
)
{
...
@@ -41,7 +42,7 @@ const ChartAxis = ({ type, scale, ticks, tickFormatGenerator, noAnimation, ancho
...
@@ -41,7 +42,7 @@ const ChartAxis = ({ type, scale, ticks, tickFormatGenerator, noAnimation, ancho
axisGroup
.
selectAll
(
'
text
'
)
axisGroup
.
selectAll
(
'
text
'
)
.
attr
(
'
opacity
'
,
1
)
.
attr
(
'
opacity
'
,
1
)
.
attr
(
'
color
'
,
textColor
)
.
attr
(
'
color
'
,
textColor
)
.
attr
(
'
font-size
'
,
'
0.75rem
'
);
.
style
(
'
font-size
'
,
'
12px
'
);
},
[
scale
,
ticks
,
tickFormatGenerator
,
noAnimation
,
type
,
textColor
]);
},
[
scale
,
ticks
,
tickFormatGenerator
,
noAnimation
,
type
,
textColor
]);
React
.
useEffect
(()
=>
{
React
.
useEffect
(()
=>
{
...
...
ui/shared/chart/ChartMenu.tsx
View file @
a51725d0
import
{
import
{
useCopyToClipboard
}
from
'
@uidotdev/usehooks
'
;
IconButton
,
MenuButton
,
MenuItem
,
MenuList
,
useClipboard
,
useColorModeValue
,
VisuallyHidden
,
}
from
'
@chakra-ui/react
'
;
import
domToImage
from
'
dom-to-image
'
;
import
domToImage
from
'
dom-to-image
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -16,8 +8,10 @@ import type { Resolution } from '@blockscout/stats-types';
...
@@ -16,8 +8,10 @@ import type { Resolution } from '@blockscout/stats-types';
import
dayjs
from
'
lib/date/dayjs
'
;
import
dayjs
from
'
lib/date/dayjs
'
;
import
isBrowser
from
'
lib/isBrowser
'
;
import
isBrowser
from
'
lib/isBrowser
'
;
import
saveAsCSV
from
'
lib/saveAsCSV
'
;
import
saveAsCSV
from
'
lib/saveAsCSV
'
;
import
Menu
from
'
ui/shared/chakra/Menu
'
;
import
{
useColorModeValue
}
from
'
toolkit/chakra/color-mode
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
MenuContent
,
MenuItem
,
MenuRoot
,
MenuTrigger
}
from
'
toolkit/chakra/menu
'
;
import
{
useDisclosure
}
from
'
toolkit/hooks/useDisclosure
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
FullscreenChartModal
from
'
./FullscreenChartModal
'
;
import
FullscreenChartModal
from
'
./FullscreenChartModal
'
;
...
@@ -52,19 +46,15 @@ const ChartMenu = ({
...
@@ -52,19 +46,15 @@ const ChartMenu = ({
handleZoomReset
,
handleZoomReset
,
}:
Props
)
=>
{
}:
Props
)
=>
{
const
pngBackgroundColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
const
pngBackgroundColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
const
[
isFullscreen
,
setIsFullscreen
]
=
React
.
useState
(
false
);
const
fullscreenDialog
=
useDisclosure
(
);
const
{
onCopy
}
=
useClipboard
(
chartUrl
??
''
);
const
[
,
copyToClipboard
]
=
useCopyToClipboard
(
);
const
isInBrowser
=
isBrowser
();
const
isInBrowser
=
isBrowser
();
const
showChartFullscreen
=
React
.
useCallback
(()
=>
{
const
showChartFullscreen
=
React
.
useCallback
(()
=>
{
setIsFullscreen
(
true
);
fullscreenDialog
.
onOpenChange
({
open
:
true
});
},
[]);
},
[
fullscreenDialog
]);
const
clearFullscreenChart
=
React
.
useCallback
(()
=>
{
setIsFullscreen
(
false
);
},
[]);
const
handleFileSaveClick
=
React
.
useCallback
(()
=>
{
const
handleFileSaveClick
=
React
.
useCallback
(()
=>
{
// wait for context menu to close
// wait for context menu to close
...
@@ -111,6 +101,10 @@ const ChartMenu = ({
...
@@ -111,6 +101,10 @@ const ChartMenu = ({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const
hasShare
=
isInBrowser
&&
(
window
.
navigator
.
share
as
any
);
const
hasShare
=
isInBrowser
&&
(
window
.
navigator
.
share
as
any
);
const
handleCopy
=
React
.
useCallback
(()
=>
{
copyToClipboard
(
chartUrl
??
''
);
},
[
chartUrl
,
copyToClipboard
]);
const
handleShare
=
React
.
useCallback
(
async
()
=>
{
const
handleShare
=
React
.
useCallback
(
async
()
=>
{
try
{
try
{
await
window
.
navigator
.
share
({
await
window
.
navigator
.
share
({
...
@@ -123,27 +117,17 @@ const ChartMenu = ({
...
@@ -123,27 +117,17 @@ const ChartMenu = ({
return
(
return
(
<>
<>
<
Menu
>
<
MenuRoot
>
<
Skeleton
isLoaded=
{
!
isLoading
}
borderRadius=
"base"
>
<
MenuTrigger
asChild
>
<
MenuButton
<
IconButton
variant=
"dropdown"
size=
"sm"
aria
-
label=
"Open chart options menu"
loading=
{
isLoading
}
borderRadius=
"base"
borderWidth=
"0"
>
w=
"36px"
<
IconSvg
name=
"dots"
boxSize=
{
4
}
transform=
"rotate(-90deg)"
/>
h=
"32px"
</
IconButton
>
icon=
{
<
IconSvg
name=
"dots"
boxSize=
{
4
}
transform=
"rotate(-90deg)"
/>
}
</
MenuTrigger
>
colorScheme=
"gray"
<
MenuContent
>
variant=
"simple"
as=
{
IconButton
}
>
<
VisuallyHidden
>
Open chart options menu
</
VisuallyHidden
>
</
MenuButton
>
</
Skeleton
>
<
MenuList
>
{
chartUrl
&&
(
{
chartUrl
&&
(
<
MenuItem
<
MenuItem
display=
"flex"
value=
{
hasShare
?
'
share
'
:
'
copy
'
}
alignItems=
"center"
onClick=
{
hasShare
?
handleShare
:
handleCopy
}
onClick=
{
hasShare
?
handleShare
:
onCopy
}
closeOnSelect=
{
hasShare
?
false
:
true
}
closeOnSelect=
{
hasShare
?
false
:
true
}
>
>
<
IconSvg
name=
{
hasShare
?
'
share
'
:
'
copy
'
}
boxSize=
{
5
}
mr=
{
3
}
/>
<
IconSvg
name=
{
hasShare
?
'
share
'
:
'
copy
'
}
boxSize=
{
5
}
mr=
{
3
}
/>
...
@@ -151,38 +135,35 @@ const ChartMenu = ({
...
@@ -151,38 +135,35 @@ const ChartMenu = ({
</
MenuItem
>
</
MenuItem
>
)
}
)
}
<
MenuItem
<
MenuItem
display=
"flex"
value=
"fullscreen"
alignItems=
"center"
onClick=
{
showChartFullscreen
}
onClick=
{
showChartFullscreen
}
>
>
<
IconSvg
name=
"scope"
boxSize=
{
5
}
mr=
{
3
}
/>
<
IconSvg
name=
"scope"
boxSize=
{
5
}
mr=
{
3
}
/>
View fullscreen
View fullscreen
</
MenuItem
>
</
MenuItem
>
<
MenuItem
<
MenuItem
display=
"flex"
value=
"save-png"
alignItems=
"center"
onClick=
{
handleFileSaveClick
}
onClick=
{
handleFileSaveClick
}
>
>
<
IconSvg
name=
"files/image"
boxSize=
{
5
}
mr=
{
3
}
/>
<
IconSvg
name=
"files/image"
boxSize=
{
5
}
mr=
{
3
}
/>
Save as PNG
Save as PNG
</
MenuItem
>
</
MenuItem
>
<
MenuItem
<
MenuItem
display=
"flex"
value=
"save-csv"
alignItems=
"center"
onClick=
{
handleSVGSavingClick
}
onClick=
{
handleSVGSavingClick
}
>
>
<
IconSvg
name=
"files/csv"
boxSize=
{
5
}
mr=
{
3
}
/>
<
IconSvg
name=
"files/csv"
boxSize=
{
5
}
mr=
{
3
}
/>
Save as CSV
Save as CSV
</
MenuItem
>
</
MenuItem
>
</
Menu
Lis
t
>
</
Menu
Conten
t
>
</
Menu
>
</
Menu
Root
>
{
items
&&
isFullscreen
&&
(
{
items
&&
(
<
FullscreenChartModal
<
FullscreenChartModal
isOpen
open=
{
fullscreenDialog
.
open
}
onOpenChange=
{
fullscreenDialog
.
onOpenChange
}
items=
{
items
}
items=
{
items
}
title=
{
title
}
title=
{
title
}
description=
{
description
}
description=
{
description
}
onClose=
{
clearFullscreenChart
}
units=
{
units
}
units=
{
units
}
resolution=
{
resolution
}
resolution=
{
resolution
}
zoomRange=
{
zoomRange
}
zoomRange=
{
zoomRange
}
...
...
ui/shared/chart/ChartWatermarkIcon.tsx
View file @
a51725d0
import
type
{
IconProps
}
from
'
@chakra-ui/react
'
;
import
type
{
IconProps
}
from
'
@chakra-ui/react
'
;
import
{
Icon
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
Icon
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
// eslint-disable-next-line no-restricted-imports
// eslint-disable-next-line no-restricted-imports
import
logoIcon
from
'
icons/networks/logo-placeholder.svg
'
;
import
logoIcon
from
'
icons/networks/logo-placeholder.svg
'
;
const
ChartWatermarkIcon
=
(
props
:
IconProps
)
=>
{
const
ChartWatermarkIcon
=
(
props
:
IconProps
)
=>
{
const
watermarkColor
=
useColorModeValue
(
'
link
'
,
'
white
'
);
return
(
return
(
<
Icon
<
Icon
{
...
props
}
{
...
props
}
...
@@ -18,7 +17,7 @@ const ChartWatermarkIcon = (props: IconProps) => {
...
@@ -18,7 +17,7 @@ const ChartWatermarkIcon = (props: IconProps) => {
transform=
"translate(-50%, -50%)"
transform=
"translate(-50%, -50%)"
pointerEvents=
"none"
pointerEvents=
"none"
viewBox=
"0 0 114 20"
viewBox=
"0 0 114 20"
color=
{
watermarkColor
}
color=
{
{
_light
:
'
link
'
,
_dark
:
'
white
'
}
}
/>
/>
);
);
};
};
...
...
ui/shared/chart/ChartWidget.tsx
View file @
a51725d0
import
{
import
{
chakra
,
Flex
}
from
'
@chakra-ui/react
'
;
chakra
,
Flex
,
IconButton
,
Tooltip
,
useColorModeValue
,
}
from
'
@chakra-ui/react
'
;
import
NextLink
from
'
next/link
'
;
import
NextLink
from
'
next/link
'
;
import
React
,
{
useRef
}
from
'
react
'
;
import
React
,
{
useRef
}
from
'
react
'
;
...
@@ -13,7 +7,9 @@ import type { TimeChartItem } from './types';
...
@@ -13,7 +7,9 @@ import type { TimeChartItem } from './types';
import
{
route
,
type
Route
}
from
'
nextjs-routes
'
;
import
{
route
,
type
Route
}
from
'
nextjs-routes
'
;
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
ChartMenu
from
'
./ChartMenu
'
;
import
ChartMenu
from
'
./ChartMenu
'
;
...
@@ -48,8 +44,6 @@ const ChartWidget = ({
...
@@ -48,8 +44,6 @@ const ChartWidget = ({
const
ref
=
useRef
<
HTMLDivElement
>
(
null
);
const
ref
=
useRef
<
HTMLDivElement
>
(
null
);
const
{
zoomRange
,
handleZoom
,
handleZoomReset
}
=
useZoom
();
const
{
zoomRange
,
handleZoom
,
handleZoomReset
}
=
useZoom
();
const
borderColor
=
useColorModeValue
(
'
gray.200
'
,
'
gray.600
'
);
const
hasItems
=
items
&&
items
.
length
>
2
;
const
hasItems
=
items
&&
items
.
length
>
2
;
const
content
=
(
const
content
=
(
...
@@ -72,24 +66,22 @@ const ChartWidget = ({
...
@@ -72,24 +66,22 @@ const ChartWidget = ({
flexDir=
"column"
flexDir=
"column"
alignItems=
"flex-start"
alignItems=
"flex-start"
cursor=
{
href
?
'
pointer
'
:
'
default
'
}
cursor=
{
href
?
'
pointer
'
:
'
default
'
}
_hover=
{
href
?
{
color
:
'
link
_
hovered
'
}
:
{}
}
_hover=
{
href
?
{
color
:
'
link
.primary.
hovered
'
}
:
{}
}
>
>
<
Skeleton
<
Skeleton
isLoaded=
{
!
isLoading
}
loading=
{
isLoading
}
fontWeight=
{
600
}
fontWeight=
{
600
}
size=
{
{
base
:
'
xs
'
,
lg
:
'
sm
'
}
}
textStyle=
"md"
>
>
<
span
>
{
title
}
</
span
>
<
span
>
{
title
}
</
span
>
</
Skeleton
>
</
Skeleton
>
{
description
&&
(
{
description
&&
(
<
Skeleton
<
Skeleton
isLoaded=
{
!
isLoading
}
loading=
{
isLoading
}
color=
"text_secondary"
color=
"text_secondary"
fontSize=
"xs"
fontSize=
"xs"
mt=
{
1
}
mt=
{
1
}
>
>
<
span
>
{
description
}
</
span
>
<
span
>
{
description
}
</
span
>
</
Skeleton
>
</
Skeleton
>
...
@@ -104,8 +96,8 @@ const ChartWidget = ({
...
@@ -104,8 +96,8 @@ const ChartWidget = ({
flexDir=
"column"
flexDir=
"column"
padding=
{
{
base
:
3
,
lg
:
4
}
}
padding=
{
{
base
:
3
,
lg
:
4
}
}
borderRadius=
"lg"
borderRadius=
"lg"
border=
"1px"
border
Width
=
"1px"
borderColor=
{
borderColor
}
borderColor=
{
{
_light
:
'
gray.200
'
,
_dark
:
'
gray.600
'
}
}
className=
{
className
}
className=
{
className
}
>
>
<
Flex
columnGap=
{
6
}
mb=
{
2
}
alignItems=
"flex-start"
>
<
Flex
columnGap=
{
6
}
mb=
{
2
}
alignItems=
"flex-start"
>
...
@@ -115,18 +107,18 @@ const ChartWidget = ({
...
@@ -115,18 +107,18 @@ const ChartWidget = ({
</
NextLink
>
</
NextLink
>
)
:
chartHeader
}
)
:
chartHeader
}
<
Flex
ml=
"auto"
columnGap=
{
2
}
>
<
Flex
ml=
"auto"
columnGap=
{
2
}
>
<
Tooltip
label
=
"Reset zoom"
>
<
Tooltip
content
=
"Reset zoom"
>
<
IconButton
<
IconButton
hidden=
{
!
zoomRange
}
hidden=
{
!
zoomRange
}
aria
-
label=
"Reset zoom"
aria
-
label=
"Reset zoom"
colorScheme=
"blue"
w=
{
9
}
w=
{
9
}
h=
{
8
}
h=
{
8
}
size=
"sm"
size=
"sm"
variant=
"outline"
variant=
"outline"
onClick=
{
handleZoomReset
}
onClick=
{
handleZoomReset
}
icon=
{
<
IconSvg
name=
"repeat"
w=
{
4
}
h=
{
4
}
/>
}
>
/>
<
IconSvg
name=
"repeat"
boxSize=
{
4
}
/>
</
IconButton
>
</
Tooltip
>
</
Tooltip
>
{
hasItems
&&
(
{
hasItems
&&
(
...
...
ui/shared/chart/ChartWidgetContent.tsx
View file @
a51725d0
import
{
Box
,
Center
,
Flex
,
Link
,
Text
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Center
,
Flex
,
Text
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
TimeChartItem
}
from
'
./types
'
;
import
type
{
TimeChartItem
}
from
'
./types
'
;
import
type
{
Resolution
}
from
'
@blockscout/stats-types
'
;
import
type
{
Resolution
}
from
'
@blockscout/stats-types
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
ChartWatermarkIcon
from
'
./ChartWatermarkIcon
'
;
import
ChartWatermarkIcon
from
'
./ChartWatermarkIcon
'
;
import
ChartWidgetGraph
from
'
./ChartWidgetGraph
'
;
import
ChartWidgetGraph
from
'
./ChartWidgetGraph
'
;
...
@@ -48,7 +49,7 @@ const ChartWidgetContent = ({
...
@@ -48,7 +49,7 @@ const ChartWidgetContent = ({
py=
{
4
}
py=
{
4
}
>
>
<
Text
<
Text
variant=
"
secondary"
color=
"text.
secondary"
fontSize=
"sm"
fontSize=
"sm"
textAlign=
"center"
textAlign=
"center"
>
>
...
@@ -60,13 +61,13 @@ const ChartWidgetContent = ({
...
@@ -60,13 +61,13 @@ const ChartWidgetContent = ({
}
}
if
(
isLoading
)
{
if
(
isLoading
)
{
return
<
Skeleton
flexGrow=
{
1
}
w=
"100%"
/>;
return
<
Skeleton
loading
flexGrow=
{
1
}
w=
"100%"
/>;
}
}
if
(
!
hasItems
)
{
if
(
!
hasItems
)
{
return
(
return
(
<
Center
flexGrow=
{
1
}
>
<
Center
flexGrow=
{
1
}
>
<
Text
variant=
"
secondary"
fontSize=
"sm"
>
{
emptyText
||
'
No data
'
}
</
Text
>
<
Text
color=
"text.
secondary"
fontSize=
"sm"
>
{
emptyText
||
'
No data
'
}
</
Text
>
</
Center
>
</
Center
>
);
);
}
}
...
...
ui/shared/chart/ChartWidgetGraph.tsx
View file @
a51725d0
...
@@ -41,7 +41,7 @@ const ChartWidgetGraph = ({
...
@@ -41,7 +41,7 @@ const ChartWidgetGraph = ({
zoomRange
,
zoomRange
,
}:
Props
)
=>
{
}:
Props
)
=>
{
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
color
=
useToken
(
'
colors
'
,
'
blue.200
'
);
const
[
color
]
=
useToken
(
'
colors
'
,
'
blue.200
'
);
const
chartId
=
`chart-
${
title
.
split
(
'
'
).
join
(
''
)
}
-
${
isEnlarged
?
'
fullscreen
'
:
'
small
'
}
`
;
const
chartId
=
`chart-
${
title
.
split
(
'
'
).
join
(
''
)
}
-
${
isEnlarged
?
'
fullscreen
'
:
'
small
'
}
`
;
const
overlayRef
=
React
.
useRef
<
SVGRectElement
>
(
null
);
const
overlayRef
=
React
.
useRef
<
SVGRectElement
>
(
null
);
...
...
ui/shared/chart/FullscreenChartModal.tsx
View file @
a51725d0
import
{
Box
,
Button
,
Grid
,
Heading
,
Modal
,
ModalBody
,
ModalCloseButton
,
ModalContent
,
ModalOverlay
,
Text
}
from
'
@chakra-ui/react
'
;
import
{
Grid
,
Text
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
TimeChartItem
}
from
'
./types
'
;
import
type
{
TimeChartItem
}
from
'
./types
'
;
import
type
{
Resolution
}
from
'
@blockscout/stats-types
'
;
import
type
{
Resolution
}
from
'
@blockscout/stats-types
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
DialogBody
,
DialogContent
,
DialogHeader
,
DialogRoot
}
from
'
toolkit/chakra/dialog
'
;
import
{
Heading
}
from
'
toolkit/chakra/heading
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
ChartWidgetContent
from
'
./ChartWidgetContent
'
;
import
ChartWidgetContent
from
'
./ChartWidgetContent
'
;
type
Props
=
{
type
Props
=
{
isOpen
:
boolean
;
open
:
boolean
;
onOpenChange
:
({
open
}:
{
open
:
boolean
})
=>
void
;
title
:
string
;
title
:
string
;
description
?:
string
;
description
?:
string
;
items
:
Array
<
TimeChartItem
>
;
items
:
Array
<
TimeChartItem
>
;
onClose
:
()
=>
void
;
units
?:
string
;
units
?:
string
;
resolution
?:
Resolution
;
resolution
?:
Resolution
;
zoomRange
?:
[
Date
,
Date
];
zoomRange
?:
[
Date
,
Date
];
...
@@ -22,46 +25,35 @@ type Props = {
...
@@ -22,46 +25,35 @@ type Props = {
};
};
const
FullscreenChartModal
=
({
const
FullscreenChartModal
=
({
isOpen
,
open
,
onOpenChange
,
title
,
title
,
description
,
description
,
items
,
items
,
units
,
units
,
onClose
,
resolution
,
resolution
,
zoomRange
,
zoomRange
,
handleZoom
,
handleZoom
,
handleZoomReset
,
handleZoomReset
,
}:
Props
)
=>
{
}:
Props
)
=>
{
return
(
return
(
<
Modal
<
DialogRoot
isOpen=
{
isO
pen
}
open=
{
o
pen
}
on
Close=
{
onClos
e
}
on
OpenChange=
{
onOpenChang
e
}
size=
"full"
size=
"full"
isCentered
>
<
ModalOverlay
/>
<
ModalContent
>
<
Box
mb=
{
1
}
>
<
Grid
gridColumnGap=
{
2
}
>
<
Heading
mb=
{
1
}
size=
{
{
base
:
'
xs
'
,
sm
:
'
md
'
}
}
>
>
<
DialogContent
>
<
DialogHeader
/>
<
DialogBody
pt=
{
6
}
display=
"flex"
flexDir=
"column"
>
<
Grid
gridColumnGap=
{
2
}
>
<
Heading
mb=
{
1
}
level=
"2"
>
{
title
}
{
title
}
</
Heading
>
</
Heading
>
{
description
&&
(
{
description
&&
(
<
Text
<
Text
gridColumn=
{
1
}
gridColumn=
{
1
}
as=
"p"
color=
"text.secondary"
variant=
"secondary"
fontSize=
"xs"
fontSize=
"xs"
>
>
{
description
}
{
description
}
...
@@ -70,8 +62,6 @@ const FullscreenChartModal = ({
...
@@ -70,8 +62,6 @@ const FullscreenChartModal = ({
{
Boolean
(
zoomRange
)
&&
(
{
Boolean
(
zoomRange
)
&&
(
<
Button
<
Button
leftIcon=
{
<
IconSvg
name=
"repeat"
w=
{
4
}
h=
{
4
}
/>
}
colorScheme=
"blue"
gridColumn=
{
2
}
gridColumn=
{
2
}
justifySelf=
"end"
justifySelf=
"end"
alignSelf=
"top"
alignSelf=
"top"
...
@@ -80,18 +70,11 @@ const FullscreenChartModal = ({
...
@@ -80,18 +70,11 @@ const FullscreenChartModal = ({
variant=
"outline"
variant=
"outline"
onClick=
{
handleZoomReset
}
onClick=
{
handleZoomReset
}
>
>
<
IconSvg
name=
"repeat"
w=
{
4
}
h=
{
4
}
/>
Reset zoom
Reset zoom
</
Button
>
</
Button
>
)
}
)
}
</
Grid
>
</
Grid
>
</
Box
>
<
ModalCloseButton
/>
<
ModalBody
h=
"100%"
margin=
{
{
bottom
:
60
}
}
>
<
ChartWidgetContent
<
ChartWidgetContent
isEnlarged
isEnlarged
items=
{
items
}
items=
{
items
}
...
@@ -101,9 +84,9 @@ const FullscreenChartModal = ({
...
@@ -101,9 +84,9 @@ const FullscreenChartModal = ({
title=
{
title
}
title=
{
title
}
resolution=
{
resolution
}
resolution=
{
resolution
}
/>
/>
</
Modal
Body
>
</
Dialog
Body
>
</
Modal
Content
>
</
Dialog
Content
>
</
Modal
>
</
DialogRoot
>
);
);
};
};
...
...
ui/txs/TxsTableItem.tsx
View file @
a51725d0
...
@@ -71,7 +71,7 @@ const TxsTableItem = ({ tx, showBlockInfo, currentAddress, enableTimeIncrement,
...
@@ -71,7 +71,7 @@ const TxsTableItem = ({ tx, showBlockInfo, currentAddress, enableTimeIncrement,
</
TableCell
>
</
TableCell
>
<
TableCell
whiteSpace=
"nowrap"
>
<
TableCell
whiteSpace=
"nowrap"
>
{
tx
.
method
&&
(
{
tx
.
method
&&
(
<
Badge
color
Schem
e=
{
tx
.
method
===
'
Multicall
'
?
'
teal
'
:
'
gray
'
}
loading=
{
isLoading
}
truncated
>
<
Badge
color
Palett
e=
{
tx
.
method
===
'
Multicall
'
?
'
teal
'
:
'
gray
'
}
loading=
{
isLoading
}
truncated
>
<
span
>
{
tx
.
method
}
</
span
>
<
span
>
{
tx
.
method
}
</
span
>
</
Badge
>
</
Badge
>
)
}
)
}
...
...
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