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
1fae6db7
Commit
1fae6db7
authored
Apr 15, 2024
by
isstuev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
performance improvement on address page
parent
41a982c6
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
134 additions
and
63 deletions
+134
-63
AddressAccountHistory.tsx
ui/address/AddressAccountHistory.tsx
+8
-1
AddressBlocksValidated.tsx
ui/address/AddressBlocksValidated.tsx
+8
-1
AddressCoinBalance.tsx
ui/address/AddressCoinBalance.tsx
+12
-1
AddressDetails.tsx
ui/address/AddressDetails.tsx
+4
-1
AddressInternalTxs.tsx
ui/address/AddressInternalTxs.tsx
+12
-1
AddressLogs.tsx
ui/address/AddressLogs.tsx
+12
-1
AddressTokenTransfers.tsx
ui/address/AddressTokenTransfers.tsx
+16
-9
AddressTokens.tsx
ui/address/AddressTokens.tsx
+11
-1
AddressTxs.tsx
ui/address/AddressTxs.tsx
+3
-9
AddressUserOps.tsx
ui/address/AddressUserOps.tsx
+8
-1
AddressWithdrawals.tsx
ui/address/AddressWithdrawals.tsx
+12
-1
Address.tsx
ui/pages/Address.tsx
+19
-18
AdaptiveTabsList.tsx
ui/shared/Tabs/AdaptiveTabsList.tsx
+1
-1
RoutedTabs.tsx
ui/shared/Tabs/RoutedTabs.tsx
+3
-1
TabsWithScroll.tsx
ui/shared/Tabs/TabsWithScroll.tsx
+4
-15
types.ts
ui/shared/Tabs/types.ts
+1
-1
No files found.
ui/address/AddressAccountHistory.tsx
View file @
1fae6db7
...
@@ -7,6 +7,7 @@ import type { NovesHistoryFilterValue } from 'types/api/noves';
...
@@ -7,6 +7,7 @@ import type { NovesHistoryFilterValue } from 'types/api/noves';
import
{
NovesHistoryFilterValues
}
from
'
types/api/noves
'
;
import
{
NovesHistoryFilterValues
}
from
'
types/api/noves
'
;
import
getFilterValueFromQuery
from
'
lib/getFilterValueFromQuery
'
;
import
getFilterValueFromQuery
from
'
lib/getFilterValueFromQuery
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
NOVES_TRANSLATE
}
from
'
stubs/noves/NovesTranslate
'
;
import
{
NOVES_TRANSLATE
}
from
'
stubs/noves/NovesTranslate
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
...
@@ -25,10 +26,12 @@ const getFilterValue = (getFilterValueFromQuery<NovesHistoryFilterValue>).bind(n
...
@@ -25,10 +26,12 @@ const getFilterValue = (getFilterValueFromQuery<NovesHistoryFilterValue>).bind(n
type
Props
=
{
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
}
}
const
AddressAccountHistory
=
({
scrollRef
}:
Props
)
=>
{
const
AddressAccountHistory
=
({
scrollRef
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
currentAddress
=
getQueryParamString
(
router
.
query
.
hash
).
toLowerCase
();
const
currentAddress
=
getQueryParamString
(
router
.
query
.
hash
).
toLowerCase
();
...
@@ -49,6 +52,10 @@ const AddressAccountHistory = ({ scrollRef }: Props) => {
...
@@ -49,6 +52,10 @@ const AddressAccountHistory = ({ scrollRef }: Props) => {
setFilterValue
(
newVal
);
setFilterValue
(
newVal
);
},
[
]);
},
[
]);
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
actionBar
=
(
const
actionBar
=
(
<
ActionBar
mt=
{
-
6
}
pb=
{
{
base
:
6
,
md
:
5
}
}
>
<
ActionBar
mt=
{
-
6
}
pb=
{
{
base
:
6
,
md
:
5
}
}
>
<
AccountHistoryFilter
<
AccountHistoryFilter
...
...
ui/address/AddressBlocksValidated.tsx
View file @
1fae6db7
...
@@ -8,6 +8,7 @@ import type { AddressBlocksValidatedResponse } from 'types/api/address';
...
@@ -8,6 +8,7 @@ import type { AddressBlocksValidatedResponse } from 'types/api/address';
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
...
@@ -25,12 +26,14 @@ import AddressBlocksValidatedTableItem from './blocksValidated/AddressBlocksVali
...
@@ -25,12 +26,14 @@ import AddressBlocksValidatedTableItem from './blocksValidated/AddressBlocksVali
interface
Props
{
interface
Props
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
}
}
const
AddressBlocksValidated
=
({
scrollRef
}:
Props
)
=>
{
const
AddressBlocksValidated
=
({
scrollRef
,
isTabsLoading
}:
Props
)
=>
{
const
[
socketAlert
,
setSocketAlert
]
=
React
.
useState
(
false
);
const
[
socketAlert
,
setSocketAlert
]
=
React
.
useState
(
false
);
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
addressHash
=
String
(
router
.
query
.
hash
);
const
addressHash
=
String
(
router
.
query
.
hash
);
const
query
=
useQueryWithPages
({
const
query
=
useQueryWithPages
({
...
@@ -84,6 +87,10 @@ const AddressBlocksValidated = ({ scrollRef }: Props) => {
...
@@ -84,6 +87,10 @@ const AddressBlocksValidated = ({ scrollRef }: Props) => {
handler
:
handleNewSocketMessage
,
handler
:
handleNewSocketMessage
,
});
});
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
content
=
query
.
data
?.
items
?
(
const
content
=
query
.
data
?.
items
?
(
<>
<>
{
socketAlert
&&
<
SocketAlert
mb=
{
6
}
/>
}
{
socketAlert
&&
<
SocketAlert
mb=
{
6
}
/>
}
...
...
ui/address/AddressCoinBalance.tsx
View file @
1fae6db7
...
@@ -6,6 +6,7 @@ import type { SocketMessage } from 'lib/socket/types';
...
@@ -6,6 +6,7 @@ import type { SocketMessage } from 'lib/socket/types';
import
type
{
AddressCoinBalanceHistoryResponse
}
from
'
types/api/address
'
;
import
type
{
AddressCoinBalanceHistoryResponse
}
from
'
types/api/address
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
...
@@ -17,10 +18,16 @@ import SocketAlert from 'ui/shared/SocketAlert';
...
@@ -17,10 +18,16 @@ import SocketAlert from 'ui/shared/SocketAlert';
import
AddressCoinBalanceChart
from
'
./coinBalance/AddressCoinBalanceChart
'
;
import
AddressCoinBalanceChart
from
'
./coinBalance/AddressCoinBalanceChart
'
;
import
AddressCoinBalanceHistory
from
'
./coinBalance/AddressCoinBalanceHistory
'
;
import
AddressCoinBalanceHistory
from
'
./coinBalance/AddressCoinBalanceHistory
'
;
const
AddressCoinBalance
=
()
=>
{
type
Props
=
{
isTabsLoading
?:
boolean
;
}
const
AddressCoinBalance
=
({
isTabsLoading
}:
Props
)
=>
{
const
[
socketAlert
,
setSocketAlert
]
=
React
.
useState
(
false
);
const
[
socketAlert
,
setSocketAlert
]
=
React
.
useState
(
false
);
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
scrollRef
=
React
.
useRef
<
HTMLDivElement
>
(
null
);
const
scrollRef
=
React
.
useRef
<
HTMLDivElement
>
(
null
);
const
addressHash
=
getQueryParamString
(
router
.
query
.
hash
);
const
addressHash
=
getQueryParamString
(
router
.
query
.
hash
);
...
@@ -78,6 +85,10 @@ const AddressCoinBalance = () => {
...
@@ -78,6 +85,10 @@ const AddressCoinBalance = () => {
handler
:
handleNewSocketMessage
,
handler
:
handleNewSocketMessage
,
});
});
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
return
(
return
(
<>
<>
{
socketAlert
&&
<
SocketAlert
mb=
{
6
}
/>
}
{
socketAlert
&&
<
SocketAlert
mb=
{
6
}
/>
}
...
...
ui/address/AddressDetails.tsx
View file @
1fae6db7
...
@@ -3,6 +3,7 @@ import { useRouter } from 'next/router';
...
@@ -3,6 +3,7 @@ import { useRouter } from 'next/router';
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
throwOnResourceLoadError
from
'
lib/errors/throwOnResourceLoadError
'
;
import
throwOnResourceLoadError
from
'
lib/errors/throwOnResourceLoadError
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
AddressCounterItem
from
'
ui/address/details/AddressCounterItem
'
;
import
AddressCounterItem
from
'
ui/address/details/AddressCounterItem
'
;
import
ServiceDegradationWarning
from
'
ui/shared/alerts/ServiceDegradationWarning
'
;
import
ServiceDegradationWarning
from
'
ui/shared/alerts/ServiceDegradationWarning
'
;
...
@@ -60,6 +61,8 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
...
@@ -60,6 +61,8 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
has_validated_blocks
:
false
,
has_validated_blocks
:
false
,
}),
[
addressHash
]);
}),
[
addressHash
]);
const
isMounted
=
useIsMounted
();
// error handling (except 404 codes)
// error handling (except 404 codes)
if
(
addressQuery
.
isError
)
{
if
(
addressQuery
.
isError
)
{
if
(
isCustomAppError
(
addressQuery
.
error
))
{
if
(
isCustomAppError
(
addressQuery
.
error
))
{
...
@@ -74,7 +77,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
...
@@ -74,7 +77,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
const
data
=
addressQuery
.
isError
?
error404Data
:
addressQuery
.
data
;
const
data
=
addressQuery
.
isError
?
error404Data
:
addressQuery
.
data
;
if
(
!
data
)
{
if
(
!
data
||
!
isMounted
)
{
return
null
;
return
null
;
}
}
...
...
ui/address/AddressInternalTxs.tsx
View file @
1fae6db7
...
@@ -6,6 +6,7 @@ import type { AddressFromToFilter } from 'types/api/address';
...
@@ -6,6 +6,7 @@ import type { AddressFromToFilter } from 'types/api/address';
import
{
AddressFromToFilterValues
}
from
'
types/api/address
'
;
import
{
AddressFromToFilterValues
}
from
'
types/api/address
'
;
import
getFilterValueFromQuery
from
'
lib/getFilterValueFromQuery
'
;
import
getFilterValueFromQuery
from
'
lib/getFilterValueFromQuery
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
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
{
INTERNAL_TX
}
from
'
stubs/internalTx
'
;
import
{
INTERNAL_TX
}
from
'
stubs/internalTx
'
;
...
@@ -22,8 +23,14 @@ import AddressIntTxsList from './internals/AddressIntTxsList';
...
@@ -22,8 +23,14 @@ import AddressIntTxsList from './internals/AddressIntTxsList';
const
getFilterValue
=
(
getFilterValueFromQuery
<
AddressFromToFilter
>
).
bind
(
null
,
AddressFromToFilterValues
);
const
getFilterValue
=
(
getFilterValueFromQuery
<
AddressFromToFilter
>
).
bind
(
null
,
AddressFromToFilterValues
);
const
AddressInternalTxs
=
({
scrollRef
}:
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
})
=>
{
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
}
const
AddressInternalTxs
=
({
scrollRef
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
[
filterValue
,
setFilterValue
]
=
React
.
useState
<
AddressFromToFilter
>
(
getFilterValue
(
router
.
query
.
filter
));
const
[
filterValue
,
setFilterValue
]
=
React
.
useState
<
AddressFromToFilter
>
(
getFilterValue
(
router
.
query
.
filter
));
const
hash
=
getQueryParamString
(
router
.
query
.
hash
);
const
hash
=
getQueryParamString
(
router
.
query
.
hash
);
...
@@ -55,6 +62,10 @@ const AddressInternalTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE
...
@@ -55,6 +62,10 @@ const AddressInternalTxs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE
onFilterChange
({
filter
:
newVal
});
onFilterChange
({
filter
:
newVal
});
},
[
onFilterChange
]);
},
[
onFilterChange
]);
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
content
=
data
?.
items
?
(
const
content
=
data
?.
items
?
(
<>
<>
<
Show
below=
"lg"
ssr=
{
false
}
>
<
Show
below=
"lg"
ssr=
{
false
}
>
...
...
ui/address/AddressLogs.tsx
View file @
1fae6db7
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
LOG
}
from
'
stubs/log
'
;
import
{
LOG
}
from
'
stubs/log
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
...
@@ -12,8 +13,14 @@ import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
...
@@ -12,8 +13,14 @@ import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
import
AddressCsvExportLink
from
'
./AddressCsvExportLink
'
;
import
AddressCsvExportLink
from
'
./AddressCsvExportLink
'
;
const
AddressLogs
=
({
scrollRef
}:
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
})
=>
{
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
}
const
AddressLogs
=
({
scrollRef
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
hash
=
getQueryParamString
(
router
.
query
.
hash
);
const
hash
=
getQueryParamString
(
router
.
query
.
hash
);
const
{
data
,
isPlaceholderData
,
isError
,
pagination
}
=
useQueryWithPages
({
const
{
data
,
isPlaceholderData
,
isError
,
pagination
}
=
useQueryWithPages
({
...
@@ -41,6 +48,10 @@ const AddressLogs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivElement>
...
@@ -41,6 +48,10 @@ const AddressLogs = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivElement>
</
ActionBar
>
</
ActionBar
>
);
);
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
content
=
data
?.
items
?
data
.
items
.
map
((
item
,
index
)
=>
<
LogItem
key=
{
index
}
{
...
item
}
type=
"address"
isLoading=
{
isPlaceholderData
}
/>)
:
null
;
const
content
=
data
?.
items
?
data
.
items
.
map
((
item
,
index
)
=>
<
LogItem
key=
{
index
}
{
...
item
}
type=
"address"
isLoading=
{
isPlaceholderData
}
/>)
:
null
;
return
(
return
(
...
...
ui/address/AddressTokenTransfers.tsx
View file @
1fae6db7
...
@@ -13,6 +13,7 @@ import { getResourceKey } from 'lib/api/useApiQuery';
...
@@ -13,6 +13,7 @@ import { getResourceKey } from 'lib/api/useApiQuery';
import
getFilterValueFromQuery
from
'
lib/getFilterValueFromQuery
'
;
import
getFilterValueFromQuery
from
'
lib/getFilterValueFromQuery
'
;
import
getFilterValuesFromQuery
from
'
lib/getFilterValuesFromQuery
'
;
import
getFilterValuesFromQuery
from
'
lib/getFilterValuesFromQuery
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
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
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
...
@@ -63,14 +64,16 @@ const matchFilters = (filters: Filters, tokenTransfer: TokenTransfer, address?:
...
@@ -63,14 +64,16 @@ const matchFilters = (filters: Filters, tokenTransfer: TokenTransfer, address?:
type
Props
=
{
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
// for tests only
// for tests only
overloadCount
?:
number
;
overloadCount
?:
number
;
}
}
const
AddressTokenTransfers
=
({
scrollRef
,
overloadCount
=
OVERLOAD_COUNT
}:
Props
)
=>
{
const
AddressTokenTransfers
=
({
scrollRef
,
overloadCount
=
OVERLOAD_COUNT
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
isMounted
=
useIsMounted
();
const
currentAddress
=
getQueryParamString
(
router
.
query
.
hash
);
const
currentAddress
=
getQueryParamString
(
router
.
query
.
hash
);
...
@@ -179,6 +182,18 @@ const AddressTokenTransfers = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Pr
...
@@ -179,6 +182,18 @@ const AddressTokenTransfers = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Pr
handler
:
handleNewSocketMessage
,
handler
:
handleNewSocketMessage
,
});
});
const
tokenData
=
React
.
useMemo
(()
=>
({
address
:
tokenFilter
||
''
,
name
:
''
,
icon_url
:
''
,
symbol
:
''
,
type
:
'
ERC-20
'
as
const
,
}),
[
tokenFilter
]);
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
numActiveFilters
=
(
filters
.
type
?.
length
||
0
)
+
(
filters
.
filter
?
1
:
0
);
const
numActiveFilters
=
(
filters
.
type
?.
length
||
0
)
+
(
filters
.
filter
?
1
:
0
);
const
isActionBarHidden
=
!
tokenFilter
&&
!
numActiveFilters
&&
!
data
?.
items
.
length
&&
!
currentAddress
;
const
isActionBarHidden
=
!
tokenFilter
&&
!
numActiveFilters
&&
!
data
?.
items
.
length
&&
!
currentAddress
;
...
@@ -218,14 +233,6 @@ const AddressTokenTransfers = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Pr
...
@@ -218,14 +233,6 @@ const AddressTokenTransfers = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Pr
</>
</>
)
:
null
;
)
:
null
;
const
tokenData
=
React
.
useMemo
(()
=>
({
address
:
tokenFilter
||
''
,
name
:
''
,
icon_url
:
''
,
symbol
:
''
,
type
:
'
ERC-20
'
as
const
,
}),
[
tokenFilter
]);
const
tokenFilterComponent
=
tokenFilter
&&
(
const
tokenFilterComponent
=
tokenFilter
&&
(
<
Flex
alignItems=
"center"
flexWrap=
"wrap"
mb=
{
{
base
:
isActionBarHidden
?
3
:
6
,
lg
:
0
}
}
mr=
{
4
}
>
<
Flex
alignItems=
"center"
flexWrap=
"wrap"
mb=
{
{
base
:
isActionBarHidden
?
3
:
6
,
lg
:
0
}
}
mr=
{
4
}
>
<
Text
whiteSpace=
"nowrap"
mr=
{
2
}
py=
{
1
}
>
Filtered by token
</
Text
>
<
Text
whiteSpace=
"nowrap"
mr=
{
2
}
py=
{
1
}
>
Filtered by token
</
Text
>
...
...
ui/address/AddressTokens.tsx
View file @
1fae6db7
...
@@ -9,6 +9,7 @@ import { useAppContext } from 'lib/contexts/app';
...
@@ -9,6 +9,7 @@ import { useAppContext } from 'lib/contexts/app';
import
*
as
cookies
from
'
lib/cookies
'
;
import
*
as
cookies
from
'
lib/cookies
'
;
import
getFilterValuesFromQuery
from
'
lib/getFilterValuesFromQuery
'
;
import
getFilterValuesFromQuery
from
'
lib/getFilterValuesFromQuery
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
NFT_TOKEN_TYPE_IDS
}
from
'
lib/token/tokenTypes
'
;
import
{
NFT_TOKEN_TYPE_IDS
}
from
'
lib/token/tokenTypes
'
;
import
{
ADDRESS_TOKEN_BALANCE_ERC_20
,
ADDRESS_NFT_1155
,
ADDRESS_COLLECTION
}
from
'
stubs/address
'
;
import
{
ADDRESS_TOKEN_BALANCE_ERC_20
,
ADDRESS_NFT_1155
,
ADDRESS_COLLECTION
}
from
'
stubs/address
'
;
...
@@ -41,9 +42,14 @@ const TAB_LIST_PROPS_MOBILE = {
...
@@ -41,9 +42,14 @@ const TAB_LIST_PROPS_MOBILE = {
const
getTokenFilterValue
=
(
getFilterValuesFromQuery
<
NFTTokenType
>
).
bind
(
null
,
NFT_TOKEN_TYPE_IDS
);
const
getTokenFilterValue
=
(
getFilterValuesFromQuery
<
NFTTokenType
>
).
bind
(
null
,
NFT_TOKEN_TYPE_IDS
);
const
AddressTokens
=
()
=>
{
type
Props
=
{
isTabsLoading
?:
boolean
;
}
const
AddressTokens
=
({
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
isMounted
=
useIsMounted
();
const
scrollRef
=
React
.
useRef
<
HTMLDivElement
>
(
null
);
const
scrollRef
=
React
.
useRef
<
HTMLDivElement
>
(
null
);
...
@@ -99,6 +105,10 @@ const AddressTokens = () => {
...
@@ -99,6 +105,10 @@ const AddressTokens = () => {
setTokenTypes
(
value
);
setTokenTypes
(
value
);
},
[
nftsQuery
,
collectionsQuery
]);
},
[
nftsQuery
,
collectionsQuery
]);
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
nftTypeFilter
=
(
const
nftTypeFilter
=
(
<
PopoverFilter
isActive=
{
tokenTypes
&&
tokenTypes
.
length
>
0
}
contentProps=
{
{
w
:
'
200px
'
}
}
appliedFiltersNum=
{
tokenTypes
?.
length
}
>
<
PopoverFilter
isActive=
{
tokenTypes
&&
tokenTypes
.
length
>
0
}
contentProps=
{
{
w
:
'
200px
'
}
}
appliedFiltersNum=
{
tokenTypes
?.
length
}
>
<
TokenTypeFilter
<
NFTTokenType
>
nftOnly onChange=
{
handleTokenTypesChange
}
defaultValue=
{
tokenTypes
}
/
>
<
TokenTypeFilter
<
NFTTokenType
>
nftOnly onChange=
{
handleTokenTypesChange
}
defaultValue=
{
tokenTypes
}
/
>
...
...
ui/address/AddressTxs.tsx
View file @
1fae6db7
...
@@ -48,12 +48,12 @@ const matchFilter = (filterValue: AddressFromToFilter, transaction: Transaction,
...
@@ -48,12 +48,12 @@ const matchFilter = (filterValue: AddressFromToFilter, transaction: Transaction,
type
Props
=
{
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
// for tests only
// for tests only
overloadCount
?:
number
;
overloadCount
?:
number
;
onLoad
?:
()
=>
void
;
}
}
const
AddressTxs
=
({
scrollRef
,
overloadCount
=
OVERLOAD_COUNT
,
onLoad
}:
Props
)
=>
{
const
AddressTxs
=
({
scrollRef
,
overloadCount
=
OVERLOAD_COUNT
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
isMounted
=
useIsMounted
();
const
isMounted
=
useIsMounted
();
...
@@ -82,12 +82,6 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, onLoad }: Props
...
@@ -82,12 +82,6 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, onLoad }: Props
},
},
});
});
React
.
useEffect
(()
=>
{
if
(
!
addressTxsQuery
.
isPlaceholderData
)
{
onLoad
?.();
}
},
[
addressTxsQuery
.
isPlaceholderData
,
onLoad
]);
const
handleFilterChange
=
React
.
useCallback
((
val
:
string
|
Array
<
string
>
)
=>
{
const
handleFilterChange
=
React
.
useCallback
((
val
:
string
|
Array
<
string
>
)
=>
{
const
newVal
=
getFilterValue
(
val
);
const
newVal
=
getFilterValue
(
val
);
...
@@ -165,7 +159,7 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, onLoad }: Props
...
@@ -165,7 +159,7 @@ const AddressTxs = ({ scrollRef, overloadCount = OVERLOAD_COUNT, onLoad }: Props
handler: handleNewSocketMessage,
handler: handleNewSocketMessage,
});
});
if (!isMounted) {
if (!isMounted
|| isTabsLoading
) {
return null;
return null;
}
}
...
...
ui/address/AddressUserOps.tsx
View file @
1fae6db7
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
USER_OPS_ITEM
}
from
'
stubs/userOps
'
;
import
{
USER_OPS_ITEM
}
from
'
stubs/userOps
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
...
@@ -9,10 +10,12 @@ import UserOpsContent from 'ui/userOps/UserOpsContent';
...
@@ -9,10 +10,12 @@ import UserOpsContent from 'ui/userOps/UserOpsContent';
type
Props
=
{
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
}
}
const
AddressUserOps
=
({
scrollRef
}:
Props
)
=>
{
const
AddressUserOps
=
({
scrollRef
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
hash
=
getQueryParamString
(
router
.
query
.
hash
);
const
hash
=
getQueryParamString
(
router
.
query
.
hash
);
...
@@ -29,6 +32,10 @@ const AddressUserOps = ({ scrollRef }: Props) => {
...
@@ -29,6 +32,10 @@ const AddressUserOps = ({ scrollRef }: Props) => {
filters
:
{
sender
:
hash
},
filters
:
{
sender
:
hash
},
});
});
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
return
<
UserOpsContent
query=
{
userOpsQuery
}
showSender=
{
false
}
/>;
return
<
UserOpsContent
query=
{
userOpsQuery
}
showSender=
{
false
}
/>;
};
};
...
...
ui/address/AddressWithdrawals.tsx
View file @
1fae6db7
...
@@ -2,6 +2,7 @@ import { Show, Hide } from '@chakra-ui/react';
...
@@ -2,6 +2,7 @@ import { Show, Hide } from '@chakra-ui/react';
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
useIsMounted
from
'
lib/hooks/useIsMounted
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
WITHDRAWAL
}
from
'
stubs/withdrawals
'
;
import
{
WITHDRAWAL
}
from
'
stubs/withdrawals
'
;
...
@@ -12,8 +13,13 @@ import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
...
@@ -12,8 +13,13 @@ import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
import
BeaconChainWithdrawalsListItem
from
'
ui/withdrawals/beaconChain/BeaconChainWithdrawalsListItem
'
;
import
BeaconChainWithdrawalsListItem
from
'
ui/withdrawals/beaconChain/BeaconChainWithdrawalsListItem
'
;
import
BeaconChainWithdrawalsTable
from
'
ui/withdrawals/beaconChain/BeaconChainWithdrawalsTable
'
;
import
BeaconChainWithdrawalsTable
from
'
ui/withdrawals/beaconChain/BeaconChainWithdrawalsTable
'
;
const
AddressWithdrawals
=
({
scrollRef
}:
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
})
=>
{
type
Props
=
{
scrollRef
?:
React
.
RefObject
<
HTMLDivElement
>
;
isTabsLoading
?:
boolean
;
}
const
AddressWithdrawals
=
({
scrollRef
,
isTabsLoading
}:
Props
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
isMounted
=
useIsMounted
();
const
hash
=
getQueryParamString
(
router
.
query
.
hash
);
const
hash
=
getQueryParamString
(
router
.
query
.
hash
);
...
@@ -28,6 +34,11 @@ const AddressWithdrawals = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE
...
@@ -28,6 +34,11 @@ const AddressWithdrawals = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE
}
}),
}
}),
},
},
});
});
if
(
!
isMounted
||
isTabsLoading
)
{
return
null
;
}
const
content
=
data
?.
items
?
(
const
content
=
data
?.
items
?
(
<>
<>
<
Show
below=
"lg"
ssr=
{
false
}
>
<
Show
below=
"lg"
ssr=
{
false
}
>
...
...
ui/pages/Address.tsx
View file @
1fae6db7
import
{
Box
,
Flex
,
HStack
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Flex
,
HStack
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
dynamic
from
'
next/dynamic
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -17,7 +16,7 @@ import AddressAccountHistory from 'ui/address/AddressAccountHistory';
...
@@ -17,7 +16,7 @@ import AddressAccountHistory from 'ui/address/AddressAccountHistory';
import
AddressBlocksValidated
from
'
ui/address/AddressBlocksValidated
'
;
import
AddressBlocksValidated
from
'
ui/address/AddressBlocksValidated
'
;
import
AddressCoinBalance
from
'
ui/address/AddressCoinBalance
'
;
import
AddressCoinBalance
from
'
ui/address/AddressCoinBalance
'
;
import
AddressContract
from
'
ui/address/AddressContract
'
;
import
AddressContract
from
'
ui/address/AddressContract
'
;
//
import AddressDetails from 'ui/address/AddressDetails';
import
AddressDetails
from
'
ui/address/AddressDetails
'
;
import
AddressInternalTxs
from
'
ui/address/AddressInternalTxs
'
;
import
AddressInternalTxs
from
'
ui/address/AddressInternalTxs
'
;
import
AddressLogs
from
'
ui/address/AddressLogs
'
;
import
AddressLogs
from
'
ui/address/AddressLogs
'
;
import
AddressTokens
from
'
ui/address/AddressTokens
'
;
import
AddressTokens
from
'
ui/address/AddressTokens
'
;
...
@@ -41,8 +40,6 @@ import NetworkExplorers from 'ui/shared/NetworkExplorers';
...
@@ -41,8 +40,6 @@ import NetworkExplorers from 'ui/shared/NetworkExplorers';
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
RoutedTabs
from
'
ui/shared/Tabs/RoutedTabs
'
;
import
RoutedTabs
from
'
ui/shared/Tabs/RoutedTabs
'
;
const
AddressDetails
=
dynamic
(()
=>
import
(
'
ui/address/AddressDetails
'
),
{
ssr
:
false
});
const
TOKEN_TABS
=
[
'
tokens_erc20
'
,
'
tokens_nfts
'
,
'
tokens_nfts_collection
'
,
'
tokens_nfts_list
'
];
const
TOKEN_TABS
=
[
'
tokens_erc20
'
,
'
tokens_nfts
'
,
'
tokens_nfts_collection
'
,
'
tokens_nfts_list
'
];
const
txInterpretation
=
config
.
features
.
txInterpretation
;
const
txInterpretation
=
config
.
features
.
txInterpretation
;
...
@@ -77,19 +74,22 @@ const AddressPageContent = () => {
...
@@ -77,19 +74,22 @@ const AddressPageContent = () => {
const
contractTabs
=
useContractTabs
(
addressQuery
.
data
);
const
contractTabs
=
useContractTabs
(
addressQuery
.
data
);
const
isLoading
=
addressQuery
.
isPlaceholderData
||
(
config
.
features
.
userOps
.
isEnabled
&&
userOpsAccountQuery
.
isPlaceholderData
);
const
isTabsLoading
=
isLoading
||
addressTabsCountersQuery
.
isPlaceholderData
;
const
tabs
:
Array
<
RoutedTab
>
=
React
.
useMemo
(()
=>
{
const
tabs
:
Array
<
RoutedTab
>
=
React
.
useMemo
(()
=>
{
return
[
return
[
{
{
id
:
'
txs
'
,
id
:
'
txs
'
,
title
:
'
Transactions
'
,
title
:
'
Transactions
'
,
count
:
addressTabsCountersQuery
.
data
?.
transactions_count
,
count
:
addressTabsCountersQuery
.
data
?.
transactions_count
,
component
:
({
onLoad
}:
{
onLoad
:
()
=>
void
})
=>
<
AddressTxs
scrollRef=
{
tabsScrollRef
}
onLoad=
{
onLoad
}
/>,
component
:
<
AddressTxs
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
},
},
txInterpretation
.
isEnabled
&&
txInterpretation
.
provider
===
'
noves
'
?
txInterpretation
.
isEnabled
&&
txInterpretation
.
provider
===
'
noves
'
?
{
{
id
:
'
account_history
'
,
id
:
'
account_history
'
,
title
:
'
Account history
'
,
title
:
'
Account history
'
,
component
:
<
AddressAccountHistory
scrollRef=
{
tabsScrollRef
}
/>,
component
:
<
AddressAccountHistory
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
}
:
}
:
undefined
,
undefined
,
config
.
features
.
userOps
.
isEnabled
&&
Boolean
(
userOpsAccountQuery
.
data
?.
total_ops
)
?
config
.
features
.
userOps
.
isEnabled
&&
Boolean
(
userOpsAccountQuery
.
data
?.
total_ops
)
?
...
@@ -97,7 +97,7 @@ const AddressPageContent = () => {
...
@@ -97,7 +97,7 @@ const AddressPageContent = () => {
id
:
'
user_ops
'
,
id
:
'
user_ops
'
,
title
:
'
User operations
'
,
title
:
'
User operations
'
,
count
:
userOpsAccountQuery
.
data
?.
total_ops
,
count
:
userOpsAccountQuery
.
data
?.
total_ops
,
component
:
<
AddressUserOps
/>,
component
:
<
AddressUserOps
isTabsLoading=
{
isTabsLoading
}
/>,
}
:
}
:
undefined
,
undefined
,
config
.
features
.
beaconChain
.
isEnabled
&&
addressTabsCountersQuery
.
data
?.
withdrawals_count
?
config
.
features
.
beaconChain
.
isEnabled
&&
addressTabsCountersQuery
.
data
?.
withdrawals_count
?
...
@@ -105,39 +105,39 @@ const AddressPageContent = () => {
...
@@ -105,39 +105,39 @@ const AddressPageContent = () => {
id
:
'
withdrawals
'
,
id
:
'
withdrawals
'
,
title
:
'
Withdrawals
'
,
title
:
'
Withdrawals
'
,
count
:
addressTabsCountersQuery
.
data
?.
withdrawals_count
,
count
:
addressTabsCountersQuery
.
data
?.
withdrawals_count
,
component
:
<
AddressWithdrawals
scrollRef=
{
tabsScrollRef
}
/>,
component
:
<
AddressWithdrawals
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
}
:
}
:
undefined
,
undefined
,
{
{
id
:
'
token_transfers
'
,
id
:
'
token_transfers
'
,
title
:
'
Token transfers
'
,
title
:
'
Token transfers
'
,
count
:
addressTabsCountersQuery
.
data
?.
token_transfers_count
,
count
:
addressTabsCountersQuery
.
data
?.
token_transfers_count
,
component
:
<
AddressTokenTransfers
scrollRef=
{
tabsScrollRef
}
/>,
component
:
<
AddressTokenTransfers
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
},
},
{
{
id
:
'
tokens
'
,
id
:
'
tokens
'
,
title
:
'
Tokens
'
,
title
:
'
Tokens
'
,
count
:
addressTabsCountersQuery
.
data
?.
token_balances_count
,
count
:
addressTabsCountersQuery
.
data
?.
token_balances_count
,
component
:
<
AddressTokens
/>,
component
:
<
AddressTokens
isTabsLoading=
{
isTabsLoading
}
/>,
subTabs
:
TOKEN_TABS
,
subTabs
:
TOKEN_TABS
,
},
},
{
{
id
:
'
internal_txns
'
,
id
:
'
internal_txns
'
,
title
:
'
Internal txns
'
,
title
:
'
Internal txns
'
,
count
:
addressTabsCountersQuery
.
data
?.
internal_txs_count
,
count
:
addressTabsCountersQuery
.
data
?.
internal_txs_count
,
component
:
<
AddressInternalTxs
scrollRef=
{
tabsScrollRef
}
/>,
component
:
<
AddressInternalTxs
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
},
},
{
{
id
:
'
coin_balance_history
'
,
id
:
'
coin_balance_history
'
,
title
:
'
Coin balance history
'
,
title
:
'
Coin balance history
'
,
component
:
<
AddressCoinBalance
/>,
component
:
<
AddressCoinBalance
isTabsLoading=
{
isTabsLoading
}
/>,
},
},
config
.
chain
.
verificationType
===
'
validation
'
&&
addressTabsCountersQuery
.
data
?.
validations_count
?
config
.
chain
.
verificationType
===
'
validation
'
&&
addressTabsCountersQuery
.
data
?.
validations_count
?
{
{
id
:
'
blocks_validated
'
,
id
:
'
blocks_validated
'
,
title
:
'
Blocks validated
'
,
title
:
'
Blocks validated
'
,
count
:
addressTabsCountersQuery
.
data
?.
validations_count
,
count
:
addressTabsCountersQuery
.
data
?.
validations_count
,
component
:
<
AddressBlocksValidated
scrollRef=
{
tabsScrollRef
}
/>,
component
:
<
AddressBlocksValidated
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
}
:
}
:
undefined
,
undefined
,
addressTabsCountersQuery
.
data
?.
logs_count
?
addressTabsCountersQuery
.
data
?.
logs_count
?
...
@@ -145,9 +145,10 @@ const AddressPageContent = () => {
...
@@ -145,9 +145,10 @@ const AddressPageContent = () => {
id
:
'
logs
'
,
id
:
'
logs
'
,
title
:
'
Logs
'
,
title
:
'
Logs
'
,
count
:
addressTabsCountersQuery
.
data
?.
logs_count
,
count
:
addressTabsCountersQuery
.
data
?.
logs_count
,
component
:
<
AddressLogs
scrollRef=
{
tabsScrollRef
}
/>,
component
:
<
AddressLogs
scrollRef=
{
tabsScrollRef
}
isTabsLoading=
{
isTabsLoading
}
/>,
}
:
}
:
undefined
,
undefined
,
addressQuery
.
data
?.
is_contract
?
{
addressQuery
.
data
?.
is_contract
?
{
id
:
'
contract
'
,
id
:
'
contract
'
,
title
:
()
=>
{
title
:
()
=>
{
...
@@ -166,9 +167,7 @@ const AddressPageContent = () => {
...
@@ -166,9 +167,7 @@ const AddressPageContent = () => {
subTabs
:
contractTabs
.
map
(
tab
=>
tab
.
id
),
subTabs
:
contractTabs
.
map
(
tab
=>
tab
.
id
),
}
:
undefined
,
}
:
undefined
,
].
filter
(
Boolean
);
].
filter
(
Boolean
);
},
[
addressQuery
.
data
,
contractTabs
,
addressTabsCountersQuery
.
data
,
userOpsAccountQuery
.
data
]);
},
[
addressQuery
.
data
,
contractTabs
,
addressTabsCountersQuery
.
data
,
userOpsAccountQuery
.
data
,
isTabsLoading
]);
const
isLoading
=
addressQuery
.
isPlaceholderData
||
(
config
.
features
.
userOps
.
isEnabled
&&
userOpsAccountQuery
.
isPlaceholderData
);
const
tags
=
(
const
tags
=
(
<
EntityTags
<
EntityTags
...
@@ -185,7 +184,9 @@ const AddressPageContent = () => {
...
@@ -185,7 +184,9 @@ const AddressPageContent = () => {
/>
/>
);
);
const
content
=
(
addressQuery
.
isError
||
addressQuery
.
isDegradedData
)
?
null
:
<
RoutedTabs
tabs=
{
tabs
}
tabListProps=
{
{
mt
:
8
}
}
/>;
const
content
=
(
addressQuery
.
isError
||
addressQuery
.
isDegradedData
)
?
null
:
<
RoutedTabs
tabs=
{
tabs
}
tabListProps=
{
{
mt
:
8
}
}
isLoading=
{
isLoading
||
addressTabsCountersQuery
.
isPlaceholderData
}
/>;
const
backLink
=
React
.
useMemo
(()
=>
{
const
backLink
=
React
.
useMemo
(()
=>
{
const
hasGoBackLink
=
appProps
.
referrer
&&
appProps
.
referrer
.
includes
(
'
/accounts
'
);
const
hasGoBackLink
=
appProps
.
referrer
&&
appProps
.
referrer
.
includes
(
'
/accounts
'
);
...
...
ui/shared/Tabs/AdaptiveTabsList.tsx
View file @
1fae6db7
...
@@ -24,7 +24,7 @@ interface Props extends TabsProps {
...
@@ -24,7 +24,7 @@ interface Props extends TabsProps {
activeTabIndex
:
number
;
activeTabIndex
:
number
;
onItemClick
:
(
index
:
number
)
=>
void
;
onItemClick
:
(
index
:
number
)
=>
void
;
themeProps
:
ThemingProps
<
'
Tabs
'
>
;
themeProps
:
ThemingProps
<
'
Tabs
'
>
;
isLoading
:
boolean
;
isLoading
?
:
boolean
;
}
}
const
AdaptiveTabsList
=
(
props
:
Props
)
=>
{
const
AdaptiveTabsList
=
(
props
:
Props
)
=>
{
...
...
ui/shared/Tabs/RoutedTabs.tsx
View file @
1fae6db7
...
@@ -17,9 +17,10 @@ interface Props extends ThemingProps<'Tabs'> {
...
@@ -17,9 +17,10 @@ interface Props extends ThemingProps<'Tabs'> {
stickyEnabled
?:
boolean
;
stickyEnabled
?:
boolean
;
className
?:
string
;
className
?:
string
;
onTabChange
?:
(
index
:
number
)
=>
void
;
onTabChange
?:
(
index
:
number
)
=>
void
;
isLoading
?:
boolean
;
}
}
const
RoutedTabs
=
({
tabs
,
tabListProps
,
rightSlot
,
rightSlotProps
,
stickyEnabled
,
className
,
onTabChange
,
...
themeProps
}:
Props
)
=>
{
const
RoutedTabs
=
({
tabs
,
tabListProps
,
rightSlot
,
rightSlotProps
,
stickyEnabled
,
className
,
onTabChange
,
isLoading
,
...
themeProps
}:
Props
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
tabIndex
=
useTabIndexFromQuery
(
tabs
);
const
tabIndex
=
useTabIndexFromQuery
(
tabs
);
const
tabsRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
tabsRef
=
useRef
<
HTMLDivElement
>
(
null
);
...
@@ -63,6 +64,7 @@ const RoutedTabs = ({ tabs, tabListProps, rightSlot, rightSlotProps, stickyEnabl
...
@@ -63,6 +64,7 @@ const RoutedTabs = ({ tabs, tabListProps, rightSlot, rightSlotProps, stickyEnabl
stickyEnabled=
{
stickyEnabled
}
stickyEnabled=
{
stickyEnabled
}
onTabChange=
{
handleTabChange
}
onTabChange=
{
handleTabChange
}
defaultTabIndex=
{
tabIndex
}
defaultTabIndex=
{
tabIndex
}
isLoading=
{
isLoading
}
{
...
themeProps
}
{
...
themeProps
}
/>
/>
);
);
...
...
ui/shared/Tabs/TabsWithScroll.tsx
View file @
1fae6db7
...
@@ -25,6 +25,7 @@ export interface Props extends ThemingProps<'Tabs'> {
...
@@ -25,6 +25,7 @@ export interface Props extends ThemingProps<'Tabs'> {
stickyEnabled
?:
boolean
;
stickyEnabled
?:
boolean
;
onTabChange
?:
(
index
:
number
)
=>
void
;
onTabChange
?:
(
index
:
number
)
=>
void
;
defaultTabIndex
?:
number
;
defaultTabIndex
?:
number
;
isLoading
?:
boolean
;
className
?:
string
;
className
?:
string
;
}
}
...
@@ -37,12 +38,12 @@ const TabsWithScroll = ({
...
@@ -37,12 +38,12 @@ const TabsWithScroll = ({
stickyEnabled
,
stickyEnabled
,
onTabChange
,
onTabChange
,
defaultTabIndex
,
defaultTabIndex
,
isLoading
,
className
,
className
,
...
themeProps
...
themeProps
}:
Props
)
=>
{
}:
Props
)
=>
{
const
[
activeTabIndex
,
setActiveTabIndex
]
=
useState
<
number
>
(
defaultTabIndex
||
0
);
const
[
activeTabIndex
,
setActiveTabIndex
]
=
useState
<
number
>
(
defaultTabIndex
||
0
);
const
[
screenWidth
,
setScreenWidth
]
=
React
.
useState
(
isBrowser
()
?
window
.
innerWidth
:
0
);
const
[
screenWidth
,
setScreenWidth
]
=
React
.
useState
(
isBrowser
()
?
window
.
innerWidth
:
0
);
const
[
isLoading
,
setIsLoading
]
=
React
.
useState
(
true
);
const
tabsRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
tabsRef
=
useRef
<
HTMLDivElement
>
(
null
);
...
@@ -72,20 +73,8 @@ const TabsWithScroll = ({
...
@@ -72,20 +73,8 @@ const TabsWithScroll = ({
};
};
},
[]);
},
[]);
const
handleLoad
=
React
.
useCallback
(()
=>
{
setIsLoading
(
false
);
},
[]);
const
renderContent
=
React
.
useCallback
((
component
:
TabItem
[
'
component
'
])
=>
{
if
(
typeof
component
===
'
function
'
)
{
return
component
({
onLoad
:
handleLoad
});
}
return
component
;
},
[
handleLoad
]);
if
(
tabs
.
length
===
1
)
{
if
(
tabs
.
length
===
1
)
{
return
<
div
>
{
renderContent
(
tabs
[
0
].
component
)
}
</
div
>;
return
<
div
>
{
tabs
[
0
].
component
}
</
div
>;
}
}
return
(
return
(
...
@@ -117,7 +106,7 @@ const TabsWithScroll = ({
...
@@ -117,7 +106,7 @@ const TabsWithScroll = ({
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
/>
/>
<
TabPanels
>
<
TabPanels
>
{
tabsList
.
map
((
tab
)
=>
<
TabPanel
padding=
{
0
}
key=
{
tab
.
id
}
>
{
renderContent
(
tab
.
component
)
}
</
TabPanel
>)
}
{
tabsList
.
map
((
tab
)
=>
<
TabPanel
padding=
{
0
}
key=
{
tab
.
id
}
>
{
tab
.
component
}
</
TabPanel
>)
}
</
TabPanels
>
</
TabPanels
>
</
Tabs
>
</
Tabs
>
);
);
...
...
ui/shared/Tabs/types.ts
View file @
1fae6db7
...
@@ -4,7 +4,7 @@ export interface TabItem {
...
@@ -4,7 +4,7 @@ export interface TabItem {
id
:
string
;
id
:
string
;
title
:
string
|
(()
=>
React
.
ReactNode
);
title
:
string
|
(()
=>
React
.
ReactNode
);
count
?:
number
|
null
;
count
?:
number
|
null
;
component
:
React
.
ReactNode
|
(({
onLoad
}:
{
onLoad
:
()
=>
void
})
=>
React
.
ReactNode
)
;
component
:
React
.
ReactNode
;
}
}
export
type
RoutedTab
=
TabItem
&
{
subTabs
?:
Array
<
string
>
}
export
type
RoutedTab
=
TabItem
&
{
subTabs
?:
Array
<
string
>
}
...
...
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