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
f8d90439
Commit
f8d90439
authored
Nov 25, 2022
by
tom
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'api-changes' into pw-tests
parents
9a595730
e0954498
Changes
46
Hide whitespace changes
Inline
Side-by-side
Showing
46 changed files
with
308 additions
and
182 deletions
+308
-182
config.ts
configs/app/config.ts
+1
-1
values.yaml
deploy/values/main/values.yaml
+28
-23
values.yaml
deploy/values/review/values.yaml
+17
-11
cross.svg
icons/cross.svg
+3
-0
useQueryWithPages.ts
lib/hooks/useQueryWithPages.ts
+2
-4
stats.ts
pages/api/index/stats.ts
+0
-7
index.ts
pages/api/stats/index.ts
+0
-1
internalTransaction.ts
types/api/internalTransaction.ts
+10
-3
pagination.ts
types/api/pagination.ts
+10
-2
stats.ts
types/api/stats.ts
+1
-0
tokenTransfer.ts
types/api/tokenTransfer.ts
+5
-1
transaction.ts
types/api/transaction.ts
+10
-4
ApiKeyForm.tsx
ui/apiKey/ApiKeyModal/ApiKeyForm.tsx
+3
-3
AppModal.tsx
ui/apps/AppModal.tsx
+5
-3
BlocksContent.tsx
ui/blocks/BlocksContent.tsx
+1
-1
CustomAbiForm.tsx
ui/customAbi/CustomAbiModal/CustomAbiForm.tsx
+3
-3
LatestBlocks.tsx
ui/home/LatestBlocks.tsx
+20
-10
LatestTxs.tsx
ui/home/LatestTxs.tsx
+1
-1
LatestTxsItem.tsx
ui/home/LatestTxsItem.tsx
+1
-2
LatestTxsNotice.tsx
ui/home/LatestTxsNotice.tsx
+1
-1
Stats.tsx
ui/home/Stats.tsx
+1
-1
indicators.tsx
ui/home/indicators/utils/indicators.tsx
+1
-1
AddressForm.tsx
ui/privateTags/AddressModal/AddressForm.tsx
+3
-3
TransactionForm.tsx
ui/privateTags/TransactionModal/TransactionForm.tsx
+3
-3
PublicTagsForm.tsx
ui/publicTags/PublicTagsForm/PublicTagsForm.tsx
+9
-3
FilterButton.tsx
ui/shared/FilterButton.tsx
+1
-1
FilterInput.tsx
ui/shared/FilterInput.tsx
+23
-1
FormModal.tsx
ui/shared/FormModal.tsx
+4
-1
TokenTransfer.tsx
ui/shared/TokenTransfer/TokenTransfer.tsx
+23
-16
TokenTransferFilter.tsx
ui/shared/TokenTransfer/TokenTransferFilter.tsx
+40
-0
TokenTransferSkeletonMobile.tsx
ui/shared/TokenTransfer/TokenTransferSkeletonMobile.tsx
+42
-45
helpers.ts
ui/shared/TokenTransfer/helpers.ts
+7
-0
AddressLink.tsx
ui/shared/address/AddressLink.tsx
+2
-2
ChartTooltip.tsx
ui/shared/chart/ChartTooltip.tsx
+13
-5
NavFooter.tsx
ui/snippets/navigation/NavFooter.tsx
+1
-1
TxDetails.tsx
ui/tx/TxDetails.tsx
+1
-1
TxRevertReason.tsx
ui/tx/details/TxRevertReason.tsx
+2
-1
TxInternalsListItem.tsx
ui/tx/internals/TxInternalsListItem.tsx
+1
-1
TxInternalsTableItem.tsx
ui/tx/internals/TxInternalsTableItem.tsx
+1
-1
TxsContent.tsx
ui/txs/TxsContent.tsx
+0
-3
TxsListItem.tsx
ui/txs/TxsListItem.tsx
+1
-2
TxsNewItemNotice.tsx
ui/txs/TxsNewItemNotice.tsx
+1
-1
TxsTab.tsx
ui/txs/TxsTab.tsx
+0
-1
TxsTableItem.tsx
ui/txs/TxsTableItem.tsx
+1
-2
AddressForm.tsx
ui/watchlist/AddressModal/AddressForm.tsx
+3
-3
WatchListAddressItem.tsx
ui/watchlist/WatchlistTable/WatchListAddressItem.tsx
+2
-2
No files found.
configs/app/config.ts
View file @
f8d90439
...
...
@@ -60,9 +60,9 @@ const config = Object.freeze({
name
:
getEnvValue
(
process
.
env
.
NEXT_PUBLIC_NETWORK_CURRENCY_NAME
),
symbol
:
getEnvValue
(
process
.
env
.
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL
),
decimals
:
Number
(
getEnvValue
(
process
.
env
.
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS
))
||
DEFAULT_CURRENCY_DECIMALS
,
address
:
getEnvValue
(
process
.
env
.
NEXT_PUBLIC_NETWORK_TOKEN_ADDRESS
),
},
assetsPathname
:
getEnvValue
(
process
.
env
.
NEXT_PUBLIC_NETWORK_ASSETS_PATHNAME
),
nativeTokenAddress
:
getEnvValue
(
process
.
env
.
NEXT_PUBLIC_NETWORK_TOKEN_ADDRESS
),
explorers
:
parseEnvJson
<
Array
<
NetworkExplorer
>>
(
getEnvValue
(
process
.
env
.
NEXT_PUBLIC_NETWORK_EXPLORERS
))
||
[],
verificationType
:
process
.
env
.
NEXT_PUBLIC_NETWORK_VERIFICATION_TYPE
||
'
mining
'
,
},
...
...
deploy/values/main/values.yaml
View file @
f8d90439
...
...
@@ -31,8 +31,9 @@ blockscout:
tls
:
enabled
:
true
path
:
# - "/poa/sokol(/|$)(.*)"
-
"
/"
prefix
:
# - "/poa/sokol(/|$)(.*)"
-
"
/"
# probes
livenessProbe
:
enabled
:
true
...
...
@@ -43,14 +44,14 @@ blockscout:
resources
:
limits
:
memory
:
_default
:
"
1
Gi"
_default
:
"
4
Gi"
cpu
:
_default
:
"
2
"
_default
:
"
4
"
requests
:
memory
:
_default
:
"
1
Gi"
_default
:
"
4
Gi"
cpu
:
_default
:
"
2
"
_default
:
"
4
"
# enable service to connect to RDS
rds
:
enabled
:
false
...
...
@@ -152,17 +153,19 @@ postgres:
command
:
'
["docker-entrypoint.sh",
"-c"]'
args
:
'
["max_connections=300"]'
strategy
:
Recreate
resources
:
limits
:
memory
:
_default
:
"
1
Gi"
_default
:
"
2
Gi"
cpu
:
_default
:
"
1
"
_default
:
"
2
"
requests
:
memory
:
_default
:
"
1
Gi"
_default
:
"
2
Gi"
cpu
:
_default
:
"
1
"
_default
:
"
2
"
environment
:
POSTGRES_USER
:
...
...
@@ -434,18 +437,20 @@ frontend:
tls
:
enabled
:
true
path
:
# - "/(apps|auth/profile|account)"
-
"
/"
-
"
/apps"
-
"
/_next"
-
"
/node-api"
-
"
/static"
-
"
/auth/profile"
-
"
/account"
-
"
/txs"
-
"
/tx"
-
"
/blocks"
-
"
/block"
exact
:
# - "/(apps|auth/profile|account)"
-
"
/"
prefix
:
-
"
/apps"
-
"
/_next"
-
"
/node-api"
-
"
/static"
-
"
/auth/profile"
-
"
/account"
-
"
/txs"
-
"
/tx"
-
"
/blocks"
-
"
/block"
resources
:
limits
:
memory
:
...
...
@@ -504,7 +509,7 @@ frontend:
NEXT_PUBLIC_FOOTER_TWITTER_LINK
:
_default
:
https://www.twitter.com/blockscoutcom
NEXT_PUBLIC_APP_ENV
:
_default
:
preview
_default
:
stable
NEXT_PUBLIC_APP_INSTANCE
:
_default
:
unknown
NEXT_PUBLIC_API_HOST
:
...
...
deploy/values/review/values.yaml
View file @
f8d90439
...
...
@@ -31,8 +31,9 @@ blockscout:
tls
:
enabled
:
true
path
:
prefix
:
# - "/poa/sokol(/|$)(.*)"
-
"
/"
-
"
/"
# probes
livenessProbe
:
enabled
:
true
...
...
@@ -123,6 +124,8 @@ postgres:
command
:
'
["docker-entrypoint.sh",
"-c"]'
args
:
'
["max_connections=300"]'
strategy
:
Recreate
resources
:
limits
:
memory
:
...
...
@@ -299,17 +302,20 @@ frontend:
tls
:
enabled
:
true
path
:
exact
:
# - "/(apps|auth/profile|account)"
-
"
/"
prefix
:
# - "/(apps|auth/profile|account)"
-
"
/"
-
"
/apps"
-
"
/_next"
-
"
/node-api"
-
"
/static"
-
"
/auth/profile"
-
"
/txs"
-
"
/tx"
-
"
/blocks"
-
"
/block"
-
"
/apps"
-
"
/_next"
-
"
/node-api"
-
"
/static"
-
"
/auth/profile"
-
"
/txs"
-
"
/tx"
-
"
/blocks"
-
"
/block"
resources
:
limits
:
memory
:
...
...
icons/cross.svg
0 → 100644
View file @
f8d90439
<svg
viewBox=
"0 0 12 12"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
>
<path
d=
"m6 5.293 2.475-2.475.707.707L6.707 6l2.475 2.475-.707.707L6 6.707 3.525 9.182l-.707-.707L5.293 6 2.818 3.525l.707-.707L6 5.293Z"
fill=
"currentColor"
/>
</svg>
lib/hooks/useQueryWithPages.ts
View file @
f8d90439
...
...
@@ -5,10 +5,8 @@ import { useRouter } from 'next/router';
import
React
,
{
useCallback
}
from
'
react
'
;
import
{
animateScroll
}
from
'
react-scroll
'
;
import
type
{
BlockFilters
}
from
'
types/api/block
'
;
import
{
PAGINATION_FIELDS
}
from
'
types/api/pagination
'
;
import
type
{
PaginationParams
,
PaginatedResponse
,
PaginatedQueryKeys
}
from
'
types/api/pagination
'
;
import
type
{
TTxsFilters
}
from
'
types/api/txsFilters
'
;
import
type
{
PaginationParams
,
PaginatedResponse
,
PaginatedQueryKeys
,
PaginationFilters
}
from
'
types/api/pagination
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
...
...
@@ -16,7 +14,7 @@ interface Params<QueryName extends PaginatedQueryKeys> {
apiPath
:
string
;
queryName
:
QueryName
;
queryIds
?:
Array
<
string
>
;
filters
?:
TTxsFilters
|
BlockFilters
;
filters
?:
PaginationFilters
<
QueryName
>
;
options
?:
Omit
<
UseQueryOptions
<
unknown
,
unknown
,
PaginatedResponse
<
QueryName
>>
,
'
queryKey
'
|
'
queryFn
'
>
;
}
...
...
pages/api/index/stats.ts
deleted
100644 → 0
View file @
9a595730
import
handler
from
'
lib/api/handler
'
;
const
getUrl
=
()
=>
'
/v2/stats
'
;
const
requestHandler
=
handler
(
getUrl
,
[
'
GET
'
]);
export
default
requestHandler
;
pages/api/stats/index.ts
View file @
f8d90439
// todo_tom leave only one api endpoint
import
handler
from
'
lib/api/handler
'
;
const
getUrl
=
()
=>
'
/v2/stats
'
;
...
...
types/api/internalTransaction.ts
View file @
f8d90439
...
...
@@ -2,14 +2,21 @@ import type { AddressParam } from './addressParams';
export
type
TxInternalsType
=
'
call
'
|
'
delegatecall
'
|
'
staticcall
'
|
'
create
'
|
'
create2
'
|
'
selfdestruct
'
|
'
reward
'
export
interface
InternalTransaction
{
export
type
InternalTransaction
=
(
{
to
:
AddressParam
;
created_contract
:
null
;
}
|
{
to
:
null
;
created_contract
:
AddressParam
;
}
)
&
{
error
:
string
|
null
;
success
:
boolean
;
type
:
TxInternalsType
;
transaction_hash
:
string
;
from
:
AddressParam
;
to
:
AddressParam
;
created_contract
:
AddressParam
;
value
:
string
;
index
:
number
;
block
:
number
;
...
...
types/api/pagination.ts
View file @
f8d90439
import
type
{
BlocksResponse
,
BlockTransactionsResponse
}
from
'
types/api/block
'
;
import
type
{
BlocksResponse
,
BlockTransactionsResponse
,
BlockFilters
}
from
'
types/api/block
'
;
import
type
{
InternalTransactionsResponse
}
from
'
types/api/internalTransaction
'
;
import
type
{
LogsResponse
}
from
'
types/api/log
'
;
import
type
{
TokenTransferResponse
}
from
'
types/api/tokenTransfer
'
;
import
type
{
TokenTransferResponse
,
TokenTransferFilters
}
from
'
types/api/tokenTransfer
'
;
import
type
{
TransactionsResponseValidated
,
TransactionsResponsePending
}
from
'
types/api/transaction
'
;
import
type
{
TTxsFilters
}
from
'
types/api/txsFilters
'
;
import
{
QueryKeys
}
from
'
types/client/queries
'
;
import
type
{
KeysOfObjectOrNull
}
from
'
types/utils/KeysOfObjectOrNull
'
;
...
...
@@ -25,6 +26,13 @@ export type PaginatedResponse<Q extends PaginatedQueryKeys> =
Q
extends
QueryKeys
.
txTokenTransfers
?
TokenTransferResponse
:
never
export
type
PaginationFilters
<
Q
extends
PaginatedQueryKeys
>
=
Q
extends
QueryKeys
.
blocks
?
BlockFilters
:
Q
extends
QueryKeys
.
txsValidate
?
TTxsFilters
:
Q
extends
QueryKeys
.
txsPending
?
TTxsFilters
:
Q
extends
QueryKeys
.
txTokenTransfers
?
TokenTransferFilters
:
never
export
type
PaginationParams
<
Q
extends
PaginatedQueryKeys
>
=
PaginatedResponse
<
Q
>
[
'
next_page_params
'
];
type
PaginationFields
=
{
...
...
types/api/stats.ts
View file @
f8d90439
...
...
@@ -10,4 +10,5 @@ export type Stats = {
gas_prices
:
{
average
:
number
;
fast
:
number
;
slow
:
number
};
static_gas_price
:
string
;
market_cap
:
string
;
network_utilization_percentage
:
number
;
}
types/api/tokenTransfer.ts
View file @
f8d90439
import
type
{
AddressParam
}
from
'
./addressParams
'
;
import
type
{
TokenInfoGeneric
}
from
'
./tokenInfo
'
;
import
type
{
TokenInfoGeneric
,
TokenType
}
from
'
./tokenInfo
'
;
export
type
Erc20TotalPayload
=
{
decimals
:
string
|
null
;
...
...
@@ -47,3 +47,7 @@ export interface TokenTransferResponse {
transaction_hash
:
string
;
}
|
null
;
}
export
interface
TokenTransferFilters
{
type
:
Array
<
TokenType
>
;
}
types/api/transaction.ts
View file @
f8d90439
...
...
@@ -5,10 +5,18 @@ import type { TokenTransfer } from './tokenTransfer';
export
type
TransactionRevertReason
=
{
raw
:
string
;
decoded
:
string
;
}
|
DecodedInput
;
export
interface
Transaction
{
export
type
Transaction
=
(
{
to
:
AddressParam
;
created_contract
:
null
;
}
|
{
to
:
null
;
created_contract
:
AddressParam
;
}
)
&
{
hash
:
string
;
result
:
string
;
confirmations
:
number
;
...
...
@@ -17,8 +25,6 @@ export interface Transaction {
timestamp
:
string
|
null
;
confirmation_duration
:
Array
<
number
>
;
from
:
AddressParam
;
to
:
AddressParam
|
null
;
created_contract
:
AddressParam
;
value
:
string
;
fee
:
Fee
;
gas_price
:
string
;
...
...
ui/apiKey/ApiKeyModal/ApiKeyForm.tsx
View file @
f8d90439
...
...
@@ -120,7 +120,7 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
},
[
errors
,
formBackgroundColor
]);
return
(
<>
<
form
noValidate
onSubmit=
{
handleSubmit
(
onSubmit
)
}
>
{
data
&&
(
<
Box
marginBottom=
{
5
}
>
<
Controller
...
...
@@ -144,14 +144,14 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
<
Box
marginTop=
{
8
}
>
<
Button
size=
"lg"
onClick=
{
handleSubmit
(
onSubmit
)
}
type=
"submit"
disabled=
{
!
isValid
}
isLoading=
{
mutation
.
isLoading
}
>
{
data
?
'
Save
'
:
'
Generate API key
'
}
</
Button
>
</
Box
>
</>
</
form
>
);
};
...
...
ui/apps/AppModal.tsx
View file @
f8d90439
import
{
Box
,
Button
,
Heading
,
Icon
,
IconButton
,
Image
,
Link
,
List
,
Modal
,
ModalBody
,
Box
,
Button
,
Flex
,
Heading
,
Icon
,
IconButton
,
Image
,
Link
,
List
,
Modal
,
ModalBody
,
ModalCloseButton
,
ModalContent
,
ModalFooter
,
ModalHeader
,
ModalOverlay
,
Tag
,
Text
,
}
from
'
@chakra-ui/react
'
;
import
NextLink
from
'
next/link
'
;
...
...
@@ -79,7 +79,9 @@ const AppModal = ({
gridTemplateColumns=
{
{
base
:
'
auto 1fr
'
}
}
paddingRight=
{
{
sm
:
12
}
}
>
<
Box
<
Flex
alignItems=
"center"
justifyContent=
"center"
w=
{
{
base
:
'
72px
'
,
sm
:
'
144px
'
}
}
h=
{
{
base
:
'
72px
'
,
sm
:
'
144px
'
}
}
marginRight=
{
{
base
:
6
,
sm
:
8
}
}
...
...
@@ -89,7 +91,7 @@ const AppModal = ({
src=
{
logo
}
alt=
{
`${ title } app icon`
}
/>
</
Bo
x
>
</
Fle
x
>
<
Heading
as=
"h2"
...
...
ui/blocks/BlocksContent.tsx
View file @
f8d90439
...
...
@@ -104,7 +104,7 @@ const BlocksContent = ({ type }: Props) => {
return
(
<>
{
data
?
{
!
isLoading
?
totalText
:
<
Skeleton
h=
"24px"
w=
"200px"
mb=
{
{
base
:
0
,
lg
:
6
}
}
/>
}
...
...
ui/customAbi/CustomAbiModal/CustomAbiForm.tsx
View file @
f8d90439
...
...
@@ -139,7 +139,7 @@ const CustomAbiForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
}
, [ errors, formBackgroundColor ]);
return (
<>
<
form
noValidate
onSubmit=
{
handleSubmit
(
onSubmit
)
}
>
<
Box
>
<
Controller
name=
"contract_address_hash"
...
...
@@ -170,14 +170,14 @@ const CustomAbiForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
<
Box
marginTop=
{
8
}
>
<
Button
size=
"lg"
onClick=
{
handleSubmit
(
onSubmit
)
}
type=
"submit"
disabled=
{
!
isValid
}
isLoading=
{
mutation
.
isLoading
}
>
{
data
?
'
Save
'
:
'
Create custom ABI
'
}
</
Button
>
</
Box
>
</>
</
form
>
);
};
...
...
ui/home/LatestBlocks.tsx
View file @
f8d90439
...
...
@@ -5,6 +5,7 @@ import React from 'react';
import
type
{
SocketMessage
}
from
'
lib/socket/types
'
;
import
type
{
Block
}
from
'
types/api/block
'
;
import
type
{
Stats
}
from
'
types/api/stats
'
;
import
{
QueryKeys
}
from
'
types/client/queries
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
...
...
@@ -26,10 +27,14 @@ const LatestBlocks = () => {
const
fetch
=
useFetch
();
const
{
data
,
isLoading
,
isError
}
=
useQuery
<
unknown
,
unknown
,
Array
<
Block
>>
(
[
QueryKeys
.
indexBlocks
],
async
()
=>
await
fetch
(
`/api/index/blocks`
),
async
()
=>
await
fetch
(
`/
node-
api/index/blocks`
),
);
const
queryClient
=
useQueryClient
();
const
statsQueryResult
=
useQuery
<
unknown
,
unknown
,
Stats
>
(
[
QueryKeys
.
stats
],
()
=>
fetch
(
'
/node-api/stats
'
),
);
const
handleNewBlockMessage
:
SocketMessage
.
NewBlock
[
'
handler
'
]
=
React
.
useCallback
((
payload
)
=>
{
queryClient
.
setQueryData
([
QueryKeys
.
indexBlocks
],
(
prevData
:
Array
<
Block
>
|
undefined
)
=>
{
...
...
@@ -78,15 +83,20 @@ const LatestBlocks = () => {
content
=
(
<>
<
Box
mb=
{
{
base
:
6
,
lg
:
9
}
}
>
<
Text
as=
"span"
fontSize=
"sm"
>
Network utilization:
{
nbsp
}
</
Text
>
{
/* Not implemented in API yet */
}
<
Text
as=
"span"
fontSize=
"sm"
color=
"blue.400"
fontWeight=
{
700
}
>
43.8%
</
Text
>
</
Box
>
{
statsQueryResult
.
isLoading
&&
(
<
Skeleton
h=
"24px"
w=
"170px"
mb=
{
{
base
:
6
,
lg
:
9
}
}
/>
)
}
{
statsQueryResult
.
data
?.
network_utilization_percentage
&&
(
<
Box
mb=
{
{
base
:
6
,
lg
:
9
}
}
>
<
Text
as=
"span"
fontSize=
"sm"
>
Network utilization:
{
nbsp
}
</
Text
>
{
/* Not implemented in API yet */
}
<
Text
as=
"span"
fontSize=
"sm"
color=
"blue.400"
fontWeight=
{
700
}
>
{
statsQueryResult
.
data
.
network_utilization_percentage
.
toFixed
(
2
)
}
%
</
Text
>
</
Box
>
)
}
<
VStack
spacing=
{
`${ BLOCK_MARGIN }px`
}
mb=
{
6
}
height=
{
`${ BLOCK_HEIGHT * blocksCount + BLOCK_MARGIN * (blocksCount - 1) }px`
}
overflow=
"hidden"
>
<
AnimatePresence
initial=
{
false
}
>
{
dataToShow
.
map
((
block
=>
<
LatestBlocksItem
key=
{
block
.
height
}
block=
{
block
}
h=
{
BLOCK_HEIGHT
}
/>))
}
...
...
ui/home/LatestTxs.tsx
View file @
f8d90439
...
...
@@ -19,7 +19,7 @@ const LatestTransactions = () => {
const
fetch
=
useFetch
();
const
{
data
,
isLoading
,
isError
}
=
useQuery
<
unknown
,
unknown
,
Array
<
Transaction
>>
(
[
QueryKeys
.
indexTxs
],
async
()
=>
await
fetch
(
`/api/index/txs`
),
async
()
=>
await
fetch
(
`/
node-
api/index/txs`
),
);
let
content
;
...
...
ui/home/LatestTxsItem.tsx
View file @
f8d90439
...
...
@@ -40,7 +40,7 @@ const LatestBlocksItem = ({ tx }: Props) => {
const
borderColor
=
useColorModeValue
(
'
gray.200
'
,
'
whiteAlpha.200
'
);
const
iconColor
=
useColorModeValue
(
'
blue.600
'
,
'
blue.300
'
);
const
dataTo
=
tx
.
to
&&
tx
.
to
.
hash
?
tx
.
to
:
tx
.
created_contract
;
const
dataTo
=
tx
.
to
?
tx
.
to
:
tx
.
created_contract
;
const
timeAgo
=
useTimeAgoIncrement
(
tx
.
timestamp
||
'
0
'
,
true
);
const
isMobile
=
useIsMobile
();
...
...
@@ -100,7 +100,6 @@ const LatestBlocksItem = ({ tx }: Props) => {
type=
"transaction"
fontWeight=
"700"
truncation=
"constant"
target=
"_self"
/>
</
Address
>
</
Flex
>
...
...
ui/home/LatestTxsNotice.tsx
View file @
f8d90439
...
...
@@ -29,7 +29,7 @@ const LatestTxsNotice = ({ className }: Props) => {
<>
<
Spinner
size=
"sm"
mr=
{
3
}
/>
<
Text
as=
"span"
whiteSpace=
"pre"
>
+
{
num
}
new transaction
{
num
>
1
?
'
s
'
:
''
}
.
</
Text
>
<
Link
href=
{
txsUrl
}
>
Show in list
</
Link
>
<
Link
href=
{
txsUrl
}
>
View all
</
Link
>
</>
);
}
...
...
ui/home/Stats.tsx
View file @
f8d90439
...
...
@@ -28,7 +28,7 @@ const Stats = () => {
const
{
data
,
isLoading
,
isError
}
=
useQuery
<
unknown
,
unknown
,
Stats
>
(
[
QueryKeys
.
stats
],
async
()
=>
await
fetch
(
`/
api/index
/stats`
),
async
()
=>
await
fetch
(
`/
node-api
/stats`
),
);
if
(
isError
)
{
...
...
ui/home/indicators/utils/indicators.tsx
View file @
f8d90439
...
...
@@ -34,7 +34,7 @@ const coinPriceIndicator: TChainIndicator<QueryKeys.chartsMarket> = {
id
:
'
coin_price
'
,
title
:
`
${
appConfig
.
network
.
currency
.
symbol
}
price`
,
value
:
(
stats
)
=>
'
$
'
+
Number
(
stats
.
coin_price
).
toLocaleString
(
undefined
,
{
minimumFractionDigits
:
2
,
maximumFractionDigits
:
6
}),
icon
:
<
TokenLogo
hash=
{
appConfig
.
network
.
nativeTokenA
ddress
||
''
}
name=
{
appConfig
.
network
.
currency
.
name
}
boxSize=
{
6
}
/>,
icon
:
<
TokenLogo
hash=
{
appConfig
.
network
.
currency
.
a
ddress
||
''
}
name=
{
appConfig
.
network
.
currency
.
name
}
boxSize=
{
6
}
/>,
hint
:
`
${
appConfig
.
network
.
currency
.
symbol
}
token daily price in USD.`
,
api
:
{
queryName
:
QueryKeys
.
chartsMarket
,
...
...
ui/privateTags/AddressModal/AddressForm.tsx
View file @
f8d90439
...
...
@@ -93,7 +93,7 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
}
, [ errors, formBackgroundColor ]);
return (
<>
<
form
noValidate
onSubmit=
{
handleSubmit
(
onSubmit
)
}
>
<
Box
marginBottom=
{
5
}
>
<
Controller
name=
"address"
...
...
@@ -119,14 +119,14 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
<
Box
marginTop=
{
8
}
>
<
Button
size=
"lg"
onClick=
{
handleSubmit
(
onSubmit
)
}
type=
"submit"
disabled=
{
!
isValid
}
isLoading=
{
pending
}
>
{
data
?
'
Save changes
'
:
'
Add tag
'
}
</
Button
>
</
Box
>
</>
</
form
>
);
};
...
...
ui/privateTags/TransactionModal/TransactionForm.tsx
View file @
f8d90439
...
...
@@ -92,7 +92,7 @@ const TransactionForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) =>
}, [ errors, formBackgroundColor ]);
return (
<>
<
form
noValidate
onSubmit=
{
handleSubmit
(
onSubmit
)
}
>
<
Box
marginBottom=
{
5
}
>
<
Controller
name=
"transaction"
...
...
@@ -118,14 +118,14 @@ const TransactionForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) =>
<
Box
marginTop=
{
8
}
>
<
Button
size=
"lg"
onClick=
{
handleSubmit
(
onSubmit
)
}
type=
"submit"
disabled=
{
!
isValid
}
isLoading=
{
pending
}
>
{
data
?
'
Save changes
'
:
'
Add tag
'
}
</
Button
>
</
Box
>
</>
</
form
>
);
};
...
...
ui/publicTags/PublicTagsForm/PublicTagsForm.tsx
View file @
f8d90439
...
...
@@ -5,6 +5,7 @@ import {
GridItem
,
Text
,
HStack
,
chakra
,
}
from
'
@chakra-ui/react
'
;
import
{
useMutation
,
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
React
,
{
useCallback
,
useState
}
from
'
react
'
;
...
...
@@ -151,7 +152,12 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
},
[
changeToDataScreen
]);
return
(
<
Box
width=
{
{
base
:
'
auto
'
,
lg
:
`calc(100% - ${ ADDRESS_INPUT_BUTTONS_WIDTH }px)`
}
}
maxWidth=
"844px"
>
<
chakra
.
form
noValidate
width=
{
{
base
:
'
auto
'
,
lg
:
`calc(100% - ${ ADDRESS_INPUT_BUTTONS_WIDTH }px)`
}
}
maxWidth=
"844px"
onSubmit=
{
handleSubmit
(
onSubmit
)
}
>
{
isAlertVisible
&&
<
Box
mb=
{
4
}
><
FormSubmitAlert
/></
Box
>
}
<
Text
size=
"sm"
variant=
"secondary"
paddingBottom=
{
5
}
>
Company info
</
Text
>
<
Grid
templateColumns=
{
{
base
:
'
1fr
'
,
lg
:
'
1fr 1fr
'
}
}
rowGap=
{
4
}
columnGap=
{
5
}
>
...
...
@@ -230,7 +236,7 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
<
HStack
spacing=
{
6
}
>
<
Button
size=
"lg"
onClick=
{
handleSubmit
(
onSubmit
)
}
type=
"submit"
disabled=
{
!
isValid
}
isLoading=
{
mutation
.
isLoading
}
>
...
...
@@ -245,7 +251,7 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
Cancel
</
Button
>
</
HStack
>
</
Box
>
</
chakra
.
form
>
);
};
...
...
ui/shared/FilterButton.tsx
View file @
f8d90439
...
...
@@ -6,7 +6,7 @@ import filterIcon from 'icons/filter.svg';
const
FilterIcon
=
<
Icon
as=
{
filterIcon
}
boxSize=
{
5
}
mr=
{
{
base
:
0
,
lg
:
2
}
}
/>;
interface
Props
{
isActive
:
boolean
;
isActive
?
:
boolean
;
appliedFiltersNum
?:
number
;
onClick
:
()
=>
void
;
}
...
...
ui/shared/FilterInput.tsx
View file @
f8d90439
import
{
Input
,
InputGroup
,
InputLeftElement
,
Icon
,
useColorModeValue
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
chakra
,
Icon
,
IconButton
,
Input
,
InputGroup
,
InputLeftElement
,
InputRightElement
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
type
{
ChangeEvent
}
from
'
react
'
;
import
React
,
{
useCallback
,
useState
}
from
'
react
'
;
import
crossIcon
from
'
icons/cross.svg
'
;
import
searchIcon
from
'
icons/search.svg
'
;
type
Props
=
{
...
...
@@ -13,6 +14,7 @@ type Props = {
const
FilterInput
=
({
onChange
,
className
,
size
=
'
sm
'
,
placeholder
}:
Props
)
=>
{
const
[
filterQuery
,
setFilterQuery
]
=
useState
(
''
);
const
inputRef
=
React
.
useRef
<
HTMLInputElement
>
(
null
);
const
handleFilterQueryChange
=
useCallback
((
event
:
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
{
value
}
=
event
.
target
;
...
...
@@ -21,6 +23,12 @@ const FilterInput = ({ onChange, className, size = 'sm', placeholder }: Props) =
onChange
(
value
);
},
[
onChange
]);
const
handleFilterQueryClear
=
useCallback
(()
=>
{
setFilterQuery
(
''
);
onChange
(
''
);
inputRef
?.
current
?.
focus
();
},
[
onChange
]);
return
(
<
InputGroup
size=
{
size
}
...
...
@@ -33,6 +41,7 @@ const FilterInput = ({ onChange, className, size = 'sm', placeholder }: Props) =
</
InputLeftElement
>
<
Input
ref=
{
inputRef
}
size=
{
size
}
value=
{
filterQuery
}
onChange=
{
handleFilterQueryChange
}
...
...
@@ -40,6 +49,19 @@ const FilterInput = ({ onChange, className, size = 'sm', placeholder }: Props) =
borderWidth=
"2px"
textOverflow=
"ellipsis"
/>
<
InputRightElement
>
<
IconButton
colorScheme=
"gray"
aria
-
label=
"Clear the filter input"
title=
"Clear the filter input"
w=
{
6
}
h=
{
6
}
icon=
{
<
Icon
as=
{
crossIcon
}
w=
{
4
}
h=
{
4
}
color=
{
useColorModeValue
(
'
blackAlpha.600
'
,
'
whiteAlpha.600
'
)
}
/>
}
size=
"sm"
onClick=
{
handleFilterQueryClear
}
/>
</
InputRightElement
>
</
InputGroup
>
);
};
...
...
ui/shared/FormModal.tsx
View file @
f8d90439
...
...
@@ -10,6 +10,7 @@ import {
}
from
'
@chakra-ui/react
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
FormSubmitAlert
from
'
ui/shared/FormSubmitAlert
'
;
interface
Props
<
TData
>
{
...
...
@@ -38,8 +39,10 @@ export default function FormModal<TData>({
onClose
();
},
[
onClose
,
setAlertVisible
]);
const
isMobile
=
useIsMobile
();
return
(
<
Modal
isOpen=
{
isOpen
}
onClose=
{
onModalClose
}
size=
{
{
base
:
'
full
'
,
lg
:
'
md
'
}
}
>
<
Modal
isOpen=
{
isOpen
}
onClose=
{
onModalClose
}
size=
{
isMobile
?
'
full
'
:
'
md
'
}
>
<
ModalOverlay
/>
<
ModalContent
>
<
ModalHeader
fontWeight=
"500"
textStyle=
"h3"
>
{
title
}
</
ModalHeader
>
...
...
ui/shared/TokenTransfer/TokenTransfer.tsx
View file @
f8d90439
import
{
Hide
,
Show
,
Text
,
Flex
,
Skeleton
}
from
'
@chakra-ui/react
'
;
import
{
Hide
,
Show
,
Text
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
TokenType
}
from
'
types/api/tokenInfo
'
;
import
type
{
QueryKeys
}
from
'
types/client/queries
'
;
import
useQueryWithPages
from
'
lib/hooks/useQueryWithPages
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
import
EmptySearchResult
from
'
ui/apps/EmptySearchResult
'
;
import
ActionBar
from
'
ui/shared/ActionBar
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
HashStringShorten
from
'
ui/shared/HashStringShorten
'
;
import
Pagination
from
'
ui/shared/Pagination
'
;
import
SkeletonTable
from
'
ui/shared/SkeletonTable
'
;
import
{
flattenTotal
}
from
'
ui/shared/TokenTransfer/helpers
'
;
import
TokenTransferFilter
from
'
ui/shared/TokenTransfer/TokenTransferFilter
'
;
import
TokenTransferList
from
'
ui/shared/TokenTransfer/TokenTransferList
'
;
import
TokenTransferSkeletonMobile
from
'
ui/shared/TokenTransfer/TokenTransferSkeletonMobile
'
;
import
TokenTransferTable
from
'
ui/shared/TokenTransfer/TokenTransferTable
'
;
...
...
@@ -25,29 +28,34 @@ interface Props {
txHash
?:
string
;
}
const
TokenTransfer
=
({
isLoading
:
isLoadingProp
,
isDisabled
,
queryName
,
queryIds
,
path
,
baseAddress
,
showTxInfo
=
true
,
txHash
}:
Props
)
=>
{
const
TokenTransfer
=
({
isLoading
:
isLoadingProp
,
isDisabled
,
queryName
,
queryIds
,
path
,
baseAddress
,
showTxInfo
=
true
}:
Props
)
=>
{
const
[
filters
,
setFilters
]
=
React
.
useState
<
Array
<
TokenType
>>
([]);
const
{
isError
,
isLoading
,
data
,
pagination
}
=
useQueryWithPages
({
apiPath
:
path
,
queryName
,
queryIds
,
options
:
{
enabled
:
!
isDisabled
},
filters
:
filters
.
length
?
{
type
:
filters
}
:
undefined
,
});
const
isPaginatorHidden
=
pagination
.
page
===
1
&&
!
pagination
.
hasNextPage
;
const
handleFilterChange
=
React
.
useCallback
((
nextValue
:
Array
<
TokenType
>
)
=>
{
setFilters
(
nextValue
);
},
[]);
const
isActionBarHidden
=
filters
.
length
===
0
&&
!
data
?.
items
.
length
;
const
content
=
(()
=>
{
if
(
isLoading
||
isLoadingProp
)
{
return
(
<>
<
Hide
below=
"lg"
>
{
txHash
!==
undefined
&&
<
Skeleton
mb=
{
6
}
h=
{
6
}
w=
"340px"
/>
}
<
SkeletonTable
columns=
{
showTxInfo
?
[
'
44px
'
,
'
185px
'
,
'
160px
'
,
'
25%
'
,
'
25%
'
,
'
25%
'
,
'
25%
'
]
:
[
'
185px
'
,
'
25%
'
,
'
25%
'
,
'
25%
'
,
'
25%
'
]
}
/>
</
Hide
>
<
Show
below=
"lg"
>
<
TokenTransferSkeletonMobile
showTxInfo=
{
showTxInfo
}
txHash=
{
txHash
}
/>
<
TokenTransferSkeletonMobile
showTxInfo=
{
showTxInfo
}
/>
</
Show
>
</>
);
...
...
@@ -57,15 +65,19 @@ const TokenTransfer = ({ isLoading: isLoadingProp, isDisabled, queryName, queryI
return
<
DataFetchAlert
/>;
}
if
(
!
data
.
items
?.
length
)
{
if
(
!
data
.
items
?.
length
&&
filters
.
length
===
0
)
{
return
<
Text
as=
"span"
>
There are no token transfers
</
Text
>;
}
if
(
!
data
.
items
?.
length
)
{
return
<
EmptySearchResult
text=
{
`Couldn${ apos }t find any token transfer that matches your query.`
}
/>;
}
const
items
=
data
.
items
.
reduce
(
flattenTotal
,
[]);
return
(
<>
<
Hide
below=
"lg"
>
<
TokenTransferTable
data=
{
items
}
baseAddress=
{
baseAddress
}
showTxInfo=
{
showTxInfo
}
top=
{
isPaginatorHidden
?
0
:
80
}
/>
<
TokenTransferTable
data=
{
items
}
baseAddress=
{
baseAddress
}
showTxInfo=
{
showTxInfo
}
top=
{
80
}
/>
</
Hide
>
<
Show
below=
"lg"
>
<
TokenTransferList
data=
{
items
}
baseAddress=
{
baseAddress
}
showTxInfo=
{
showTxInfo
}
/>
...
...
@@ -76,14 +88,9 @@ const TokenTransfer = ({ isLoading: isLoadingProp, isDisabled, queryName, queryI
return
(
<>
{
txHash
&&
(
data
?.
items
.
length
||
0
>
0
)
&&
(
<
Flex
mb=
{
isPaginatorHidden
?
6
:
0
}
w=
"100%"
>
<
Text
as=
"span"
fontWeight=
{
600
}
whiteSpace=
"pre"
>
Token transfers for by txn hash:
</
Text
>
<
HashStringShorten
hash=
{
txHash
}
/>
</
Flex
>
)
}
{
isPaginatorHidden
?
null
:
(
<
ActionBar
>
{
!
isActionBarHidden
&&
(
<
ActionBar
mt=
{
-
6
}
>
<
TokenTransferFilter
defaultFilters=
{
filters
}
onFilterChange=
{
handleFilterChange
}
appliedFiltersNum=
{
filters
.
length
}
/>
<
Pagination
ml=
"auto"
{
...
pagination
}
/>
</
ActionBar
>
)
}
...
...
ui/shared/TokenTransfer/TokenTransferFilter.tsx
0 → 100644
View file @
f8d90439
import
{
Popover
,
PopoverTrigger
,
PopoverContent
,
PopoverBody
,
CheckboxGroup
,
Checkbox
,
Text
,
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
TokenType
}
from
'
types/api/tokenInfo
'
;
import
FilterButton
from
'
ui/shared/FilterButton
'
;
import
{
TOKEN_TYPE
}
from
'
./helpers
'
;
interface
Props
{
appliedFiltersNum
?:
number
;
defaultFilters
:
Array
<
TokenType
>
;
onFilterChange
:
(
nextValue
:
Array
<
TokenType
>
)
=>
void
;
}
const
TokenTransfer
=
({
onFilterChange
,
defaultFilters
,
appliedFiltersNum
}:
Props
)
=>
{
const
{
isOpen
,
onToggle
,
onClose
}
=
useDisclosure
();
return
(
<
Popover
isOpen=
{
isOpen
}
onClose=
{
onClose
}
placement=
"bottom-start"
isLazy
>
<
PopoverTrigger
>
<
FilterButton
isActive=
{
isOpen
||
Number
(
appliedFiltersNum
)
>
0
}
onClick=
{
onToggle
}
appliedFiltersNum=
{
appliedFiltersNum
}
/>
</
PopoverTrigger
>
<
PopoverContent
w=
"200px"
>
<
PopoverBody
px=
{
4
}
py=
{
6
}
display=
"flex"
flexDir=
"column"
rowGap=
{
5
}
>
<
Text
variant=
"secondary"
fontWeight=
{
600
}
>
Type
</
Text
>
<
CheckboxGroup
size=
"lg"
onChange=
{
onFilterChange
}
defaultValue=
{
defaultFilters
}
>
{
TOKEN_TYPE
.
map
(({
title
,
id
})
=>
<
Checkbox
key=
{
id
}
value=
{
id
}
><
Text
fontSize=
"md"
>
{
title
}
</
Text
></
Checkbox
>)
}
</
CheckboxGroup
>
</
PopoverBody
>
</
PopoverContent
>
</
Popover
>
);
};
export
default
React
.
memo
(
TokenTransfer
);
ui/shared/TokenTransfer/TokenTransferSkeletonMobile.tsx
View file @
f8d90439
import
{
Skeleton
,
SkeletonCircle
,
Flex
,
Box
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
const
TokenTransferSkeletonMobile
=
({
showTxInfo
,
txHash
}:
{
showTxInfo
?:
boolean
;
txHash
?:
string
})
=>
{
const
TokenTransferSkeletonMobile
=
({
showTxInfo
}:
{
showTxInfo
?:
boolean
})
=>
{
const
borderColor
=
useColorModeValue
(
'
blackAlpha.200
'
,
'
whiteAlpha.200
'
);
return
(
<>
{
txHash
!==
undefined
&&
<
Skeleton
mb=
{
6
}
h=
{
6
}
w=
"100%"
/>
}
<
Box
>
{
Array
.
from
(
Array
(
2
)).
map
((
item
,
index
)
=>
(
<
Flex
key=
{
index
}
rowGap=
{
3
}
flexDirection=
"column"
paddingY=
{
6
}
borderTopWidth=
"1px"
borderColor=
{
borderColor
}
_last=
{
{
borderBottomWidth
:
'
1px
'
,
}
}
>
<
Flex
h=
{
6
}
>
<
SkeletonCircle
size=
"6"
mr=
{
2
}
flexShrink=
{
0
}
/>
<
Skeleton
w=
"100px"
mr=
{
2
}
/>
<
Skeleton
w=
"50px"
/>
{
showTxInfo
&&
<
Skeleton
w=
"24px"
ml=
"auto"
/>
}
</
Flex
>
<
Flex
h=
{
6
}
columnGap=
{
2
}
>
<
Skeleton
w=
"70px"
/>
<
Skeleton
w=
"24px"
/>
<
Skeleton
w=
"90px"
/>
</
Flex
>
{
showTxInfo
&&
(
<
Flex
h=
{
6
}
columnGap=
{
2
}
>
<
Skeleton
w=
"70px"
flexShrink=
{
0
}
/>
<
Skeleton
w=
"100%"
/>
</
Flex
>
)
}
<
Flex
h=
{
6
}
>
<
SkeletonCircle
size=
"6"
mr=
{
2
}
flexShrink=
{
0
}
/>
<
Skeleton
flexGrow=
{
1
}
mr=
{
3
}
/>
<
Skeleton
w=
"50px"
mr=
{
3
}
/>
<
SkeletonCircle
size=
"6"
mr=
{
2
}
flexShrink=
{
0
}
/>
<
Skeleton
flexGrow=
{
1
}
mr=
{
3
}
/>
</
Flex
>
<
Box
>
{
Array
.
from
(
Array
(
2
)).
map
((
item
,
index
)
=>
(
<
Flex
key=
{
index
}
rowGap=
{
3
}
flexDirection=
"column"
paddingY=
{
6
}
borderTopWidth=
"1px"
borderColor=
{
borderColor
}
_last=
{
{
borderBottomWidth
:
'
1px
'
,
}
}
>
<
Flex
h=
{
6
}
>
<
SkeletonCircle
size=
"6"
mr=
{
2
}
flexShrink=
{
0
}
/>
<
Skeleton
w=
"100px"
mr=
{
2
}
/>
<
Skeleton
w=
"50px"
/>
{
showTxInfo
&&
<
Skeleton
w=
"24px"
ml=
"auto"
/>
}
</
Flex
>
<
Flex
h=
{
6
}
columnGap=
{
2
}
>
<
Skeleton
w=
"70px"
/>
<
Skeleton
w=
"24px"
/>
<
Skeleton
w=
"90px"
/>
</
Flex
>
{
showTxInfo
&&
(
<
Flex
h=
{
6
}
columnGap=
{
2
}
>
<
Skeleton
w=
"
45px"
/>
<
Skeleton
w=
"
90px
"
/>
<
Skeleton
w=
"
70px"
flexShrink=
{
0
}
/>
<
Skeleton
w=
"
100%
"
/>
</
Flex
>
)
}
<
Flex
h=
{
6
}
>
<
SkeletonCircle
size=
"6"
mr=
{
2
}
flexShrink=
{
0
}
/>
<
Skeleton
flexGrow=
{
1
}
mr=
{
3
}
/>
<
Skeleton
w=
"50px"
mr=
{
3
}
/>
<
SkeletonCircle
size=
"6"
mr=
{
2
}
flexShrink=
{
0
}
/>
<
Skeleton
flexGrow=
{
1
}
mr=
{
3
}
/>
</
Flex
>
<
Flex
h=
{
6
}
columnGap=
{
2
}
>
<
Skeleton
w=
"45px"
/>
<
Skeleton
w=
"90px"
/>
</
Flex
>
))
}
</
Box
>
</>
</
Flex
>
))
}
</
Box
>
);
};
...
...
ui/shared/TokenTransfer/helpers.ts
View file @
f8d90439
import
type
{
TokenType
}
from
'
types/api/tokenInfo
'
;
import
type
{
TokenTransfer
}
from
'
types/api/tokenTransfer
'
;
export
const
flattenTotal
=
(
result
:
Array
<
TokenTransfer
>
,
item
:
TokenTransfer
):
Array
<
TokenTransfer
>
=>
{
...
...
@@ -24,3 +25,9 @@ export const getTokenTransferTypeText = (type: TokenTransfer['type']) => {
return
'
Token transfer
'
;
}
};
export
const
TOKEN_TYPE
:
Array
<
{
title
:
string
;
id
:
TokenType
}
>
=
[
{
title
:
'
ERC-20
'
,
id
:
'
ERC-20
'
},
{
title
:
'
ERC-721
'
,
id
:
'
ERC-721
'
},
{
title
:
'
ERC-1155
'
,
id
:
'
ERC-1155
'
},
];
ui/shared/address/AddressLink.tsx
View file @
f8d90439
...
...
@@ -17,7 +17,7 @@ interface Props {
target
?:
HTMLAttributeAnchorTarget
;
}
const
AddressLink
=
({
alias
,
type
,
className
,
truncation
=
'
dynamic
'
,
hash
,
id
,
fontWeight
,
target
}:
Props
)
=>
{
const
AddressLink
=
({
alias
,
type
,
className
,
truncation
=
'
dynamic
'
,
hash
,
id
,
fontWeight
,
target
=
'
_self
'
}:
Props
)
=>
{
let
url
;
if
(
type
===
'
transaction
'
)
{
url
=
link
(
'
tx
'
,
{
id
:
id
||
hash
});
...
...
@@ -53,7 +53,7 @@ const AddressLink = ({ alias, type, className, truncation = 'dynamic', hash, id,
<
Link
className=
{
className
}
href=
{
url
}
target=
{
target
||
'
_blank
'
}
target=
{
target
}
overflow=
"hidden"
whiteSpace=
"nowrap"
>
...
...
ui/shared/chart/ChartTooltip.tsx
View file @
f8d90439
...
...
@@ -86,11 +86,19 @@ const ChartTooltip = ({ xScale, yScale, width, height, data, anchorEl, ...props
.
selectAll
(
'
.ChartTooltip__point
'
)
.
attr
(
'
transform
'
,
(
cur
,
i
)
=>
{
const
index
=
bisectDate
(
data
[
i
].
items
,
xDate
,
1
);
const
d0
=
data
[
i
].
items
[
index
-
1
];
const
d1
=
data
[
i
].
items
[
index
];
const
d
=
xDate
.
getTime
()
-
d0
?.
date
.
getTime
()
>
d1
?.
date
.
getTime
()
-
xDate
.
getTime
()
?
d1
:
d0
;
if
(
d
.
date
===
undefined
&&
d
.
value
===
undefined
)
{
const
d0
=
data
[
i
].
items
[
index
-
1
]
as
TimeChartItem
|
undefined
;
const
d1
=
data
[
i
].
items
[
index
]
as
TimeChartItem
|
undefined
;
const
d
=
(()
=>
{
if
(
!
d0
)
{
return
d1
;
}
if
(
!
d1
)
{
return
d0
;
}
return
xDate
.
getTime
()
-
d0
.
date
.
getTime
()
>
d1
.
date
.
getTime
()
-
xDate
.
getTime
()
?
d1
:
d0
;
})();
if
(
d
?.
date
===
undefined
&&
d
?.
value
===
undefined
)
{
// move point out of container
return
'
translate(-100,-100)
'
;
}
...
...
ui/snippets/navigation/NavFooter.tsx
View file @
f8d90439
...
...
@@ -51,7 +51,7 @@ const NavFooter = ({ isCollapsed, hasAccount }: Props) => {
<
Stack
direction=
{
{
base
:
'
row
'
,
lg
:
isExpanded
?
'
row
'
:
'
column
'
,
xl
:
isCollapsed
?
'
column
'
:
'
row
'
}
}
>
{
SOCIAL_LINKS
.
map
(
sl
=>
{
return
(
<
Link
href=
{
sl
.
link
}
key=
{
sl
.
link
}
variant=
"secondary"
w=
{
5
}
h=
{
5
}
aria
-
label=
{
sl
.
label
}
>
<
Link
href=
{
sl
.
link
}
key=
{
sl
.
link
}
variant=
"secondary"
w=
{
5
}
h=
{
5
}
aria
-
label=
{
sl
.
label
}
target=
"_blank"
>
<
Icon
as=
{
sl
.
icon
}
boxSize=
{
5
}
/>
</
Link
>
);
...
...
ui/tx/TxDetails.tsx
View file @
f8d90439
...
...
@@ -58,7 +58,7 @@ const TxDetails = () => {
...
data
.
from
.
watchlist_names
||
[],
].
map
((
tag
)
=>
<
Tag
key=
{
tag
.
label
}
>
{
tag
.
display_name
}
</
Tag
>);
const
toAddress
=
data
.
to
&&
data
.
to
.
hash
?
data
.
to
:
data
.
created_contract
;
const
toAddress
=
data
.
to
?
data
.
to
:
data
.
created_contract
;
const
addressToTags
=
[
...
toAddress
.
private_tags
||
[],
...
toAddress
.
public_tags
||
[],
...
...
ui/tx/details/TxRevertReason.tsx
View file @
f8d90439
...
...
@@ -3,6 +3,7 @@ import React from 'react';
import
type
{
TransactionRevertReason
}
from
'
types/api/transaction
'
;
import
hexToUtf8
from
'
lib/hexToUtf8
'
;
import
TxDecodedInputData
from
'
ui/tx/TxDecodedInputData/TxDecodedInputData
'
;
type
Props
=
TransactionRevertReason
;
...
...
@@ -25,7 +26,7 @@ const TxRevertReason = (props: Props) => {
<
GridItem
fontWeight=
{
500
}
>
Raw:
</
GridItem
>
<
GridItem
>
{
props
.
raw
}
</
GridItem
>
<
GridItem
fontWeight=
{
500
}
>
Decoded:
</
GridItem
>
<
GridItem
>
{
props
.
decoded
}
</
GridItem
>
<
GridItem
>
{
hexToUtf8
(
props
.
raw
)
}
</
GridItem
>
</
Grid
>
);
}
...
...
ui/tx/internals/TxInternalsListItem.tsx
View file @
f8d90439
...
...
@@ -17,7 +17,7 @@ type Props = InternalTransaction;
const
TxInternalsListItem
=
({
type
,
from
,
to
,
value
,
success
,
error
,
gas_limit
:
gasLimit
,
created_contract
:
createdContract
}:
Props
)
=>
{
const
typeTitle
=
TX_INTERNALS_ITEMS
.
find
(({
id
})
=>
id
===
type
)?.
title
;
const
toData
=
to
&&
to
.
hash
?
to
:
createdContract
;
const
toData
=
to
?
to
:
createdContract
;
return
(
<
AccountListItemMobile
rowGap=
{
3
}
>
...
...
ui/tx/internals/TxInternalsTableItem.tsx
View file @
f8d90439
...
...
@@ -15,7 +15,7 @@ type Props = InternalTransaction
const
TxInternalTableItem
=
({
type
,
from
,
to
,
value
,
success
,
error
,
gas_limit
:
gasLimit
,
created_contract
:
createdContract
}:
Props
)
=>
{
const
typeTitle
=
TX_INTERNALS_ITEMS
.
find
(({
id
})
=>
id
===
type
)?.
title
;
const
toData
=
to
&&
to
.
hash
?
to
:
createdContract
;
const
toData
=
to
?
to
:
createdContract
;
return
(
<
Tr
alignItems=
"top"
>
...
...
ui/txs/TxsContent.tsx
View file @
f8d90439
...
...
@@ -17,7 +17,6 @@ import useTxsSort from './useTxsSort';
type
Props
=
{
queryName
:
QueryKeys
.
txsPending
|
QueryKeys
.
txsValidate
|
QueryKeys
.
blockTxs
;
showDescription
?:
boolean
;
stateFilter
?:
TTxsFilters
[
'
filter
'
];
apiPath
:
string
;
showBlockInfo
?:
boolean
;
...
...
@@ -25,7 +24,6 @@ type Props = {
const
TxsContent
=
({
queryName
,
showDescription
,
stateFilter
,
apiPath
,
showBlockInfo
=
true
,
...
...
@@ -81,7 +79,6 @@ const TxsContent = ({
return
(
<>
{
showDescription
&&
<
Box
mb=
{
{
base
:
6
,
lg
:
12
}
}
>
Only the first 10,000 elements are displayed
</
Box
>
}
<
TxsHeader
mt=
{
-
6
}
sorting=
{
sorting
}
setSorting=
{
setSortByValue
}
paginationProps=
{
pagination
}
showPagination=
{
!
isPaginatorHidden
}
/>
{
content
}
</>
...
...
ui/txs/TxsListItem.tsx
View file @
f8d90439
...
...
@@ -33,7 +33,7 @@ const TxsListItem = ({ tx, showBlockInfo }: {tx: Transaction; showBlockInfo: boo
const
iconColor
=
useColorModeValue
(
'
blue.600
'
,
'
blue.300
'
);
const
borderColor
=
useColorModeValue
(
'
blackAlpha.200
'
,
'
whiteAlpha.200
'
);
const
dataTo
=
tx
.
to
&&
tx
.
to
.
hash
?
tx
.
to
:
tx
.
created_contract
;
const
dataTo
=
tx
.
to
?
tx
.
to
:
tx
.
created_contract
;
return
(
<>
...
...
@@ -59,7 +59,6 @@ const TxsListItem = ({ tx, showBlockInfo }: {tx: Transaction; showBlockInfo: boo
type=
"transaction"
fontWeight=
"700"
truncation=
"constant"
target=
"_self"
/>
</
Address
>
</
Flex
>
...
...
ui/txs/TxsNewItemNotice.tsx
View file @
f8d90439
...
...
@@ -43,7 +43,7 @@ const TxsNewItemNotice = ({ children, className }: Props) => {
<
Alert
className=
{
className
}
status=
"warning"
p=
{
4
}
fontWeight=
{
400
}
>
<
Spinner
size=
"sm"
mr=
{
3
}
/>
<
Text
as=
"span"
whiteSpace=
"pre"
>
+
{
num
}
new transaction
{
num
>
1
?
'
s
'
:
''
}
.
</
Text
>
<
Link
onClick=
{
handleClick
}
>
Sho
w in list
</
Link
>
<
Link
onClick=
{
handleClick
}
>
Vie
w in list
</
Link
>
</
Alert
>
);
})();
...
...
ui/txs/TxsTab.tsx
View file @
f8d90439
...
...
@@ -13,7 +13,6 @@ const TxsTab = ({ tab }: Props) => {
return
(
<
TxsContent
queryName=
{
QueryKeys
.
txsValidate
}
showDescription
stateFilter=
"validated"
apiPath=
"/node-api/transactions"
/>
...
...
ui/txs/TxsTableItem.tsx
View file @
f8d90439
...
...
@@ -44,7 +44,7 @@ const TxsTableItem = ({ tx, showBlockInfo }: {tx: Transaction; showBlockInfo: bo
</
Address
>
);
const
dataTo
=
tx
.
to
&&
tx
.
to
.
hash
?
tx
.
to
:
tx
.
created_contract
;
const
dataTo
=
tx
.
to
?
tx
.
to
:
tx
.
created_contract
;
const
addressTo
=
(
<
Address
>
...
...
@@ -87,7 +87,6 @@ const TxsTableItem = ({ tx, showBlockInfo }: {tx: Transaction; showBlockInfo: bo
hash=
{
tx
.
hash
}
type=
"transaction"
fontWeight=
"700"
target=
"_self"
/>
</
Address
>
<
Text
color=
"gray.500"
fontWeight=
"400"
>
{
dayjs
(
tx
.
timestamp
).
fromNow
()
}
</
Text
>
...
...
ui/watchlist/AddressModal/AddressForm.tsx
View file @
f8d90439
...
...
@@ -151,7 +151,7 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
), []);
return (
<>
<
form
noValidate
onSubmit=
{
handleSubmit
(
onSubmit
)
}
>
<
Box
marginBottom=
{
5
}
>
<
Controller
name=
"address"
...
...
@@ -189,14 +189,14 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
<
Box
marginTop=
{
8
}
>
<
Button
size=
"lg"
onClick=
{
handleSubmit
(
onSubmit
)
}
type=
"submit"
isLoading=
{
pending
}
disabled=
{
!
isValid
}
>
{
data
?
'
Save changes
'
:
'
Add address
'
}
</
Button
>
</
Box
>
</>
</
form
>
);
};
...
...
ui/watchlist/WatchlistTable/WatchListAddressItem.tsx
View file @
f8d90439
...
...
@@ -20,9 +20,9 @@ const WatchListAddressItem = ({ item }: {item: TWatchlistItem}) => {
<
VStack
spacing=
{
2
}
align=
"stretch"
fontWeight=
{
500
}
color=
"gray.700"
>
<
AddressSnippet
address=
{
item
.
address_hash
}
/>
<
Flex
fontSize=
"sm"
h=
{
6
}
pl=
{
infoItemsPaddingLeft
}
flexWrap=
"wrap"
alignItems=
"center"
rowGap=
{
1
}
>
{
appConfig
.
network
.
nativeTokenA
ddress
&&
(
{
appConfig
.
network
.
currency
.
a
ddress
&&
(
<
TokenLogo
hash=
{
appConfig
.
network
.
nativeTokenA
ddress
}
hash=
{
appConfig
.
network
.
currency
.
a
ddress
}
name=
{
appConfig
.
network
.
name
}
boxSize=
{
4
}
borderRadius=
"sm"
...
...
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