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
4c8f5ae9
Commit
4c8f5ae9
authored
Feb 21, 2025
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
api keys, custom abi, vizualize and csv export pages
parent
add0e9bb
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
180 additions
and
216 deletions
+180
-216
api-key.tsx
pages/account/api-key.tsx
+2
-2
custom-abi.tsx
pages/account/custom-abi.tsx
+2
-2
csv-export.tsx
pages/csv-export.tsx
+2
-2
sol2uml.tsx
pages/visualize/sol2uml.tsx
+2
-2
theme.ts
toolkit/theme/theme.ts
+0
-5
ContractExternalLibraries.tsx
ui/address/contract/ContractExternalLibraries.tsx
+26
-34
TokenSelect.tsx
ui/address/tokenSelect/TokenSelect.tsx
+16
-21
ApiKeyForm.tsx
ui/apiKey/ApiKeyModal/ApiKeyForm.tsx
+9
-12
ApiKeyModal.tsx
ui/apiKey/ApiKeyModal/ApiKeyModal.tsx
+7
-7
ApiKeyTable.tsx
ui/apiKey/ApiKeyTable/ApiKeyTable.tsx
+12
-17
ApiKeyTableItem.tsx
ui/apiKey/ApiKeyTable/ApiKeyTableItem.tsx
+7
-10
DeleteApiKeyModal.tsx
ui/apiKey/DeleteApiKeyModal.tsx
+5
-5
CsvExportForm.tsx
ui/csvExport/CsvExportForm.tsx
+8
-11
CsvExportFormField.tsx
ui/csvExport/CsvExportFormField.tsx
+3
-4
CustomAbiListItem.tsx
ui/customAbi/CustomAbiTable/CustomAbiListItem.tsx
+2
-2
CustomAbiTable.tsx
ui/customAbi/CustomAbiTable/CustomAbiTable.tsx
+12
-17
CustomAbiTableItem.tsx
ui/customAbi/CustomAbiTable/CustomAbiTableItem.tsx
+10
-13
DeleteCustomAbiModal.tsx
ui/customAbi/DeleteCustomAbiModal.tsx
+5
-5
ApiKeys.tsx
ui/pages/ApiKeys.tsx
+16
-13
CustomAbi.tsx
ui/pages/CustomAbi.tsx
+13
-11
ApiKeySnippet.tsx
ui/shared/ApiKeySnippet.tsx
+6
-6
CoinzillaTextAd.tsx
ui/shared/ad/CoinzillaTextAd.tsx
+11
-11
Sol2UmlDiagram.tsx
ui/sol2uml/Sol2UmlDiagram.tsx
+4
-4
No files found.
pages/account/api-key.tsx
View file @
4c8f5ae9
...
...
@@ -4,12 +4,12 @@ import React from 'react';
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
const ApiKeys = dynamic(() => import('ui/pages/ApiKeys'), { ssr: false });
const
ApiKeys
=
dynamic
(()
=>
import
(
'
ui/pages/ApiKeys
'
),
{
ssr
:
false
});
const
Page
:
NextPage
=
()
=>
{
return
(
<
PageNextJs
pathname=
"/account/api-key"
>
{
/* <ApiKeys/> */
}
<
ApiKeys
/>
</
PageNextJs
>
);
};
...
...
pages/account/custom-abi.tsx
View file @
4c8f5ae9
...
...
@@ -4,12 +4,12 @@ import React from 'react';
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
const CustomAbi = dynamic(() => import('ui/pages/CustomAbi'), { ssr: false });
const
CustomAbi
=
dynamic
(()
=>
import
(
'
ui/pages/CustomAbi
'
),
{
ssr
:
false
});
const
Page
:
NextPage
=
()
=>
{
return
(
<
PageNextJs
pathname=
"/account/custom-abi"
>
{
/* <CustomAbi/> */
}
<
CustomAbi
/>
</
PageNextJs
>
);
};
...
...
pages/csv-export.tsx
View file @
4c8f5ae9
...
...
@@ -3,12 +3,12 @@ import React from 'react';
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
import CsvExport from 'ui/pages/CsvExport';
import
CsvExport
from
'
ui/pages/CsvExport
'
;
const
Page
:
NextPage
=
()
=>
{
return
(
<
PageNextJs
pathname=
"/csv-export"
>
{
/* <CsvExport/> */
}
<
CsvExport
/>
</
PageNextJs
>
);
};
...
...
pages/visualize/sol2uml.tsx
View file @
4c8f5ae9
...
...
@@ -3,12 +3,12 @@ import React from 'react';
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
import Sol2Uml from 'ui/pages/Sol2Uml';
import
Sol2Uml
from
'
ui/pages/Sol2Uml
'
;
const
Page
:
NextPage
=
()
=>
{
return
(
<
PageNextJs
pathname=
"/visualize/sol2uml"
>
{
/* <Sol2Uml/> */
}
<
Sol2Uml
/>
</
PageNextJs
>
);
};
...
...
toolkit/theme/theme.ts
View file @
4c8f5ae9
import
{
createSystem
,
defaultConfig
,
defineConfig
}
from
'
@chakra-ui/react
'
;
// TODO @tom2drum migrate this to the new recipe system
// import components from './components/index';
// import config from './config';
import
{
keyframes
}
from
'
./foundations/animations
'
;
import
*
as
borders
from
'
./foundations/borders
'
;
import
breakpoints
from
'
./foundations/breakpoints
'
;
...
...
@@ -39,8 +36,6 @@ const customConfig = defineConfig({
},
},
},
// components,
// config,
});
export
default
createSystem
(
defaultConfig
,
customConfig
);
ui/address/contract/ContractExternalLibraries.tsx
View file @
4c8f5ae9
import
{
Alert
,
Box
,
Button
,
Flex
,
Heading
,
Modal
,
ModalCloseButton
,
ModalContent
,
PopoverBody
,
PopoverContent
,
PopoverTrigger
,
StackDivider
,
useDisclosure
,
VStack
,
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Flex
,
Separator
,
VStack
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
SmartContractExternalLibrary
}
from
'
types/api/contract
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
import
Popover
from
'
ui/shared/chakra/Popover
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
{
Alert
}
from
'
toolkit/chakra/alert
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
DialogBody
,
DialogContent
,
DialogHeader
,
DialogRoot
}
from
'
toolkit/chakra/dialog
'
;
import
{
Heading
}
from
'
toolkit/chakra/heading
'
;
import
{
PopoverRoot
,
PopoverBody
,
PopoverContent
,
PopoverTrigger
}
from
'
toolkit/chakra/popover
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
useDisclosure
}
from
'
toolkit/hooks/useDisclosure
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
...
...
@@ -47,11 +37,11 @@ const Item = (data: SmartContractExternalLibrary) => {
};
const
ContractExternalLibraries
=
({
className
,
data
,
isLoading
}:
Props
)
=>
{
const
{
isOpen
,
onToggle
,
onClos
e
}
=
useDisclosure
();
const
{
open
,
onToggle
,
onOpenChang
e
}
=
useDisclosure
();
const
isMobile
=
useIsMobile
();
if
(
isLoading
)
{
return
<
Skeleton
h=
{
8
}
w=
"150px"
borderRadius=
"base"
/>;
return
<
Skeleton
loading
h=
{
8
}
w=
"150px"
borderRadius=
"base"
/>;
}
if
(
data
.
length
===
0
)
{
...
...
@@ -62,17 +52,17 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => {
<
Button
className=
{
className
}
size=
"sm"
variant=
"outline"
colorScheme=
"gray"
variant=
"dropdown"
onClick=
{
onToggle
}
isActive=
{
isO
pen
}
expanded=
{
o
pen
}
fontWeight=
{
600
}
px=
{
2
}
gap=
{
0
}
aria
-
label=
"View external libraries"
>
<
span
>
{
data
.
length
}
{
data
.
length
>
1
?
'
Libraries
'
:
'
Library
'
}
</
span
>
<
IconSvg
name=
"status/warning"
boxSize=
{
5
}
color=
"orange.400"
ml=
"2px"
/>
<
IconSvg
name=
"arrows/east-mini"
transform=
{
isO
pen
?
'
rotate(90deg)
'
:
'
rotate(-90deg)
'
}
transitionDuration=
"faster"
boxSize=
{
5
}
ml=
{
2
}
/>
<
IconSvg
name=
"arrows/east-mini"
transform=
{
o
pen
?
'
rotate(90deg)
'
:
'
rotate(-90deg)
'
}
transitionDuration=
"faster"
boxSize=
{
5
}
ml=
{
2
}
/>
</
Button
>
);
...
...
@@ -84,8 +74,8 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => {
Check the source code at the library address (if any) if you want to be sure in case if there is any library linked
</
Alert
>
<
VStack
divider=
{
<
StackDivider
borderColor=
"border.divider"
/>
}
spacing
=
{
2
}
separator=
{
<
Separator
/>
}
gap
=
{
2
}
mt=
{
4
}
maxH=
{
{
lg
:
'
50vh
'
}
}
overflowY=
"scroll"
...
...
@@ -99,18 +89,20 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => {
return
(
<>
{
button
}
<
Modal
isOpen=
{
isOpen
}
onClose=
{
onClose
}
size=
"full"
>
<
ModalContent
paddingTop=
{
4
}
>
<
ModalCloseButton
/>
{
content
}
</
ModalContent
>
</
Modal
>
<
DialogRoot
open=
{
open
}
onOpenChange=
{
onOpenChange
}
size=
"full"
>
<
DialogContent
paddingTop=
{
4
}
>
<
DialogHeader
/>
<
DialogBody
>
{
content
}
</
DialogBody
>
</
DialogContent
>
</
DialogRoot
>
</>
);
}
return
(
<
Popover
isOpen=
{
isOpen
}
onClose=
{
onClose
}
placement=
"bottom-start"
isLazy
>
<
Popover
Root
open=
{
open
}
onOpenChange=
{
onOpenChange
}
>
<
PopoverTrigger
>
{
button
}
</
PopoverTrigger
>
...
...
@@ -119,7 +111,7 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => {
{
content
}
</
PopoverBody
>
</
PopoverContent
>
</
Popover
>
</
Popover
Root
>
);
};
...
...
ui/address/tokenSelect/TokenSelect.tsx
View file @
4c8f5ae9
...
...
@@ -6,15 +6,17 @@ import React from 'react';
import
type
{
Address
}
from
'
types/api/address
'
;
import
{
route
}
from
'
nextjs-routes
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
NextLink
from
'
ui/shared/NextLink
'
;
import
useFetchTokens
from
'
../utils/useFetchTokens
'
;
import
TokenSelectDesktop
from
'
./TokenSelectDesktop
'
;
...
...
@@ -64,27 +66,20 @@ const TokenSelect = ({ onClick }: Props) => {
<
TokenSelectDesktop
data=
{
data
}
isLoading=
{
tokensIsFetching
===
1
}
/>
}
<
Tooltip
content=
"Show all tokens"
>
<
Box
>
{
/* TODO @tom2drum: replace with Link */
}
<
NextLink
href=
{
{
pathname
:
'
/address/[hash]
'
,
query
:
{
hash
:
addressHash
,
tab
:
'
tokens
'
}
}
}
passHref
legacyBehavior
scroll=
{
false
}
<
Link
href=
{
route
({
pathname
:
'
/address/[hash]
'
,
query
:
{
hash
:
addressHash
,
tab
:
'
tokens
'
}
})
}
asChild
scroll=
{
false
}
>
<
IconButton
aria
-
label=
"Show all tokens"
variant=
"outline"
size=
"sm"
onClick=
{
handleIconButtonClick
}
>
<
IconButton
aria
-
label=
"Show all tokens"
variant=
"outline"
size=
"sm"
pl=
"6px"
pr=
"6px"
as=
"a"
onClick=
{
handleIconButtonClick
}
>
<
IconSvg
name=
"wallet"
boxSize=
{
5
}
/>
</
IconButton
>
</
NextLink
>
</
Box
>
<
IconSvg
name=
"wallet"
boxSize=
{
5
}
/>
</
IconButton
>
</
Link
>
</
Tooltip
>
</
Flex
>
);
...
...
ui/apiKey/ApiKeyModal/ApiKeyForm.tsx
View file @
4c8f5ae9
import
{
Box
,
Button
,
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
{
useMutation
,
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
type
{
SubmitHandler
}
from
'
react-hook-form
'
;
...
...
@@ -13,11 +10,12 @@ import type { ResourceErrorAccount } from 'lib/api/resources';
import
{
resourceKey
}
from
'
lib/api/resources
'
;
import
useApiFetch
from
'
lib/api/useApiFetch
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
FormFieldText
from
'
ui/shared/forms/fields/FormFieldText
'
;
type
Props
=
{
data
?:
ApiKey
;
on
Close
:
(
)
=>
void
;
on
OpenChange
:
({
open
}:
{
open
:
boolean
}
)
=>
void
;
setAlertVisible
:
(
isAlertVisible
:
boolean
)
=>
void
;
};
...
...
@@ -28,7 +26,7 @@ type Inputs = {
const
NAME_MAX_LENGTH
=
255
;
const
ApiKeyForm
:
React
.
FC
<
Props
>
=
({
data
,
on
Clos
e
,
setAlertVisible
})
=>
{
const
ApiKeyForm
:
React
.
FC
<
Props
>
=
({
data
,
on
OpenChang
e
,
setAlertVisible
})
=>
{
const
formApi
=
useForm
<
Inputs
>
({
mode
:
'
onTouched
'
,
defaultValues
:
{
...
...
@@ -73,7 +71,7 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
return
[
response
,
...(
prevData
||
[])
];
});
on
Close
(
);
on
OpenChange
({
open
:
false
}
);
},
onError
:
(
error
:
ResourceErrorAccount
<
ApiKeyErrors
>
)
=>
{
const
errorMap
=
error
.
payload
?.
errors
;
...
...
@@ -99,15 +97,14 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
<
FormFieldText
<
Inputs
>
name="token"
placeholder="Auto-generated API key token"
isReadOnly
bgColor="dialog.bg"
readOnly
mb=
{
5
}
/
>
)
}
<
FormFieldText
<
Inputs
>
name="name"
placeholder="Application name for API key (e.g Web3 project)"
isR
equired
r
equired
rules=
{
{
maxLength
:
NAME_MAX_LENGTH
,
}
}
...
...
@@ -118,8 +115,8 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
<
Button
size=
"lg"
type=
"submit"
isD
isabled=
{
!
formApi
.
formState
.
isDirty
}
isL
oading=
{
isPending
}
d
isabled=
{
!
formApi
.
formState
.
isDirty
}
l
oading=
{
isPending
}
>
{
data
?
'
Save
'
:
'
Generate API key
'
}
</
Button
>
...
...
ui/apiKey/ApiKeyModal/ApiKeyModal.tsx
View file @
4c8f5ae9
...
...
@@ -7,24 +7,24 @@ import FormModal from 'ui/shared/FormModal';
import
ApiKeyForm
from
'
./ApiKeyForm
'
;
type
Props
=
{
isO
pen
:
boolean
;
on
Close
:
(
)
=>
void
;
o
pen
:
boolean
;
on
OpenChange
:
({
open
}:
{
open
:
boolean
}
)
=>
void
;
data
?:
ApiKey
;
};
const
ApiKeyModal
:
React
.
FC
<
Props
>
=
({
isOpen
,
onClos
e
,
data
})
=>
{
const
ApiKeyModal
:
React
.
FC
<
Props
>
=
({
open
,
onOpenChang
e
,
data
})
=>
{
const
title
=
data
?
'
Edit API key
'
:
'
New API key
'
;
const
text
=
!
data
?
'
Add an application name to identify your API key. Click the button below to auto-generate the associated key.
'
:
''
;
const
[
isAlertVisible
,
setAlertVisible
]
=
useState
(
false
);
const
renderForm
=
useCallback
(()
=>
{
return
<
ApiKeyForm
data=
{
data
}
on
Close=
{
onClos
e
}
setAlertVisible=
{
setAlertVisible
}
/>;
},
[
data
,
on
Clos
e
]);
return
<
ApiKeyForm
data=
{
data
}
on
OpenChange=
{
onOpenChang
e
}
setAlertVisible=
{
setAlertVisible
}
/>;
},
[
data
,
on
OpenChang
e
]);
return
(
<
FormModal
<
ApiKey
>
isOpen=
{
isO
pen
}
on
Close=
{
onClos
e
}
open=
{
o
pen
}
on
OpenChange=
{
onOpenChang
e
}
title=
{
title
}
text=
{
text
}
renderForm=
{
renderForm
}
...
...
ui/apiKey/ApiKeyTable/ApiKeyTable.tsx
View file @
4c8f5ae9
import
{
Table
,
Thead
,
Tbody
,
Tr
,
Th
,
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
ApiKeys
,
ApiKey
}
from
'
types/api/account
'
;
import
{
TableBody
,
TableColumnHeader
,
TableHeader
,
TableRoot
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
ApiKeyTableItem
from
'
./ApiKeyTableItem
'
;
interface
Props
{
...
...
@@ -21,14 +16,14 @@ interface Props {
const
ApiKeyTable
=
({
data
,
isLoading
,
onDeleteClick
,
onEditClick
,
limit
}:
Props
)
=>
{
return
(
<
Table
minWidth=
"600px"
>
<
T
head
>
<
T
r
>
<
T
h
>
{
`API key token (limit ${ limit } keys)`
}
</
Th
>
<
T
h
width=
"108px"
></
Th
>
</
T
r
>
</
T
head
>
<
T
b
ody
>
<
Table
Root
minWidth=
"600px"
>
<
T
ableHeader
>
<
T
ableRow
>
<
T
ableColumnHeader
>
{
`API key token (limit ${ limit } keys)`
}
</
TableColumnHeader
>
<
T
ableColumnHeader
width=
"108px"
></
TableColumnHeader
>
</
T
ableRow
>
</
T
ableHeader
>
<
T
ableB
ody
>
{
data
?.
map
((
item
,
index
)
=>
(
<
ApiKeyTableItem
key=
{
item
.
api_key
+
(
isLoading
?
index
:
''
)
}
...
...
@@ -38,8 +33,8 @@ const ApiKeyTable = ({ data, isLoading, onDeleteClick, onEditClick, limit }: Pro
onEditClick=
{
onEditClick
}
/>
))
}
</
T
b
ody
>
</
Table
>
</
T
ableB
ody
>
</
Table
Root
>
);
};
...
...
ui/apiKey/ApiKeyTable/ApiKeyTableItem.tsx
View file @
4c8f5ae9
import
{
Tr
,
Td
,
}
from
'
@chakra-ui/react
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
type
{
ApiKey
}
from
'
types/api/account
'
;
import
{
TableCell
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
ApiKeySnippet
from
'
ui/shared/ApiKeySnippet
'
;
import
TableItemActionButtons
from
'
ui/shared/TableItemActionButtons
'
;
...
...
@@ -27,14 +24,14 @@ const ApiKeyTableItem = ({ item, isLoading, onEditClick, onDeleteClick }: Props)
},
[
item
,
onDeleteClick
]);
return
(
<
T
r
alignItems=
"top"
key=
{
item
.
api_key
}
>
<
T
d
>
<
T
ableRow
alignItems=
"top"
key=
{
item
.
api_key
}
>
<
T
ableCell
>
<
ApiKeySnippet
apiKey=
{
item
.
api_key
}
name=
{
item
.
name
}
isLoading=
{
isLoading
}
/>
</
T
d
>
<
T
d
>
</
T
ableCell
>
<
T
ableCell
>
<
TableItemActionButtons
onDeleteClick=
{
onItemDeleteClick
}
onEditClick=
{
onItemEditClick
}
isLoading=
{
isLoading
}
/>
</
T
d
>
</
T
r
>
</
T
ableCell
>
</
T
ableRow
>
);
};
...
...
ui/apiKey/DeleteApiKeyModal.tsx
View file @
4c8f5ae9
...
...
@@ -9,12 +9,12 @@ import useApiFetch from 'lib/api/useApiFetch';
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
type
Props
=
{
isO
pen
:
boolean
;
on
Close
:
(
)
=>
void
;
o
pen
:
boolean
;
on
OpenChange
:
({
open
}:
{
open
:
boolean
}
)
=>
void
;
data
:
ApiKey
;
};
const
DeleteApiKeyModal
:
React
.
FC
<
Props
>
=
({
isOpen
,
onClos
e
,
data
})
=>
{
const
DeleteApiKeyModal
:
React
.
FC
<
Props
>
=
({
open
,
onOpenChang
e
,
data
})
=>
{
const
queryClient
=
useQueryClient
();
const
apiFetch
=
useApiFetch
();
...
...
@@ -39,8 +39,8 @@ const DeleteApiKeyModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
return
(
<
DeleteModal
isOpen=
{
isO
pen
}
on
Close=
{
onClos
e
}
open=
{
o
pen
}
on
OpenChange=
{
onOpenChang
e
}
title=
"Remove API key"
renderContent=
{
renderText
}
mutationFn=
{
mutationFn
}
...
...
ui/csvExport/CsvExportForm.tsx
View file @
4c8f5ae9
import
{
Alert
,
Button
,
chakra
,
Flex
}
from
'
@chakra-ui/react
'
;
import
{
chakra
,
Flex
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
SubmitHandler
}
from
'
react-hook-form
'
;
import
{
useForm
,
FormProvider
}
from
'
react-hook-form
'
;
...
...
@@ -11,7 +11,9 @@ import buildUrl from 'lib/api/buildUrl';
import
type
{
ResourceName
}
from
'
lib/api/resources
'
;
import
dayjs
from
'
lib/date/dayjs
'
;
import
downloadBlob
from
'
lib/downloadBlob
'
;
import
useToast
from
'
lib/hooks/useToast
'
;
import
{
Alert
}
from
'
toolkit/chakra/alert
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
toaster
}
from
'
toolkit/chakra/toaster
'
;
import
ReCaptcha
from
'
ui/shared/reCaptcha/ReCaptcha
'
;
import
useReCaptcha
from
'
ui/shared/reCaptcha/useReCaptcha
'
;
...
...
@@ -35,7 +37,6 @@ const CsvExportForm = ({ hash, resource, filterType, filterValue, fileNameTempla
},
});
const
{
handleSubmit
,
formState
}
=
formApi
;
const
toast
=
useToast
();
const
recaptcha
=
useReCaptcha
();
const
onFormSubmit
:
SubmitHandler
<
FormFields
>
=
React
.
useCallback
(
async
(
data
)
=>
{
...
...
@@ -73,17 +74,13 @@ const CsvExportForm = ({ hash, resource, filterType, filterValue, fileNameTempla
downloadBlob
(
blob
,
fileName
);
}
catch
(
error
)
{
toast
({
position
:
'
top-right
'
,
toaster
.
error
({
title
:
'
Error
'
,
description
:
(
error
as
Error
)?.
message
||
'
Something went wrong. Try again later.
'
,
status
:
'
error
'
,
variant
:
'
subtle
'
,
isClosable
:
true
,
});
}
},
[
recaptcha
,
resource
,
hash
,
exportType
,
filterType
,
filterValue
,
fileNameTemplate
,
toast
]);
},
[
recaptcha
,
resource
,
hash
,
exportType
,
filterType
,
filterValue
,
fileNameTemplate
]);
if
(
!
config
.
services
.
reCaptchaV2
.
siteKey
)
{
return
(
...
...
@@ -110,9 +107,9 @@ const CsvExportForm = ({ hash, resource, filterType, filterValue, fileNameTempla
size=
"lg"
type=
"submit"
mt=
{
8
}
isL
oading=
{
formState
.
isSubmitting
}
l
oading=
{
formState
.
isSubmitting
}
loadingText=
"Download"
isD
isabled=
{
Boolean
(
formState
.
errors
.
from
||
formState
.
errors
.
to
)
}
d
isabled=
{
Boolean
(
formState
.
errors
.
from
||
formState
.
errors
.
to
)
}
>
Download
</
Button
>
...
...
ui/csvExport/CsvExportFormField.tsx
View file @
4c8f5ae9
...
...
@@ -38,12 +38,11 @@ const CsvExportFormField = ({ formApi, name }: Props) => {
return
(
<
FormFieldText
<
FormFields
,
typeof
name
>
name=
{
name
}
type="date"
max=
{
dayjs
().
format
(
'
YYYY-MM-DD
'
)
}
inputProps=
{
{
type
:
'
date
'
,
max
:
dayjs
().
format
(
'
YYYY-MM-DD
'
)
}
}
placeholder=
{
capitalize
(
name
)
}
isR
equired
r
equired
rules=
{
{
validate
}
}
size=
{
{
base
:
'
md
'
,
lg
:
'
lg
'
}
}
size=
"xl"
maxW=
{
{
base
:
'
auto
'
,
lg
:
'
220px
'
}
}
/
>
);
...
...
ui/customAbi/CustomAbiTable/CustomAbiListItem.tsx
View file @
4c8f5ae9
...
...
@@ -3,7 +3,7 @@ import React, { useCallback } from 'react';
import
type
{
CustomAbi
}
from
'
types/api/account
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
ListItemMobile
from
'
ui/shared/ListItemMobile/ListItemMobile
'
;
import
TableItemActionButtons
from
'
ui/shared/TableItemActionButtons
'
;
...
...
@@ -33,7 +33,7 @@ const CustomAbiListItem = ({ item, isLoading, onEditClick, onDeleteClick }: Prop
fontWeight=
"600"
isLoading=
{
isLoading
}
/>
<
Skeleton
fontSize=
"sm"
color=
"text_secondary"
mt=
{
0.5
}
ml=
{
8
}
display=
"inline-block"
isLoaded=
{
!
isLoading
}
>
<
Skeleton
textStyle=
"sm"
color=
"text.secondary"
mt=
{
0.5
}
ml=
{
8
}
display=
"inline-block"
loading=
{
isLoading
}
>
<
span
>
{
item
.
name
}
</
span
>
</
Skeleton
>
</
Box
>
...
...
ui/customAbi/CustomAbiTable/CustomAbiTable.tsx
View file @
4c8f5ae9
import
{
Table
,
Thead
,
Tbody
,
Tr
,
Th
,
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
CustomAbis
,
CustomAbi
}
from
'
types/api/account
'
;
import
{
TableBody
,
TableColumnHeader
,
TableHeader
,
TableRoot
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
CustomAbiTableItem
from
'
./CustomAbiTableItem
'
;
interface
Props
{
...
...
@@ -20,14 +15,14 @@ interface Props {
const
CustomAbiTable
=
({
data
,
isLoading
,
onDeleteClick
,
onEditClick
}:
Props
)
=>
{
return
(
<
Table
minWidth=
"600px"
>
<
T
head
>
<
T
r
>
<
T
h
>
ABI for Smart contract address (0x...)
</
Th
>
<
T
h
width=
"108px"
></
Th
>
</
T
r
>
</
T
head
>
<
T
b
ody
>
<
Table
Root
minWidth=
"600px"
>
<
T
ableHeader
>
<
T
ableRow
>
<
T
ableColumnHeader
>
ABI for Smart contract address (0x...)
</
TableColumnHeader
>
<
T
ableColumnHeader
width=
"108px"
></
TableColumnHeader
>
</
T
ableRow
>
</
T
ableHeader
>
<
T
ableB
ody
>
{
data
?.
map
((
item
,
index
)
=>
(
<
CustomAbiTableItem
key=
{
item
.
id
+
(
isLoading
?
String
(
index
)
:
''
)
}
...
...
@@ -37,8 +32,8 @@ const CustomAbiTable = ({ data, isLoading, onDeleteClick, onEditClick }: Props)
onEditClick=
{
onEditClick
}
/>
))
}
</
T
b
ody
>
</
Table
>
</
T
ableB
ody
>
</
Table
Root
>
);
};
...
...
ui/customAbi/CustomAbiTable/CustomAbiTableItem.tsx
View file @
4c8f5ae9
import
{
Tr
,
Td
,
Box
,
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
type
{
CustomAbi
}
from
'
types/api/account
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
TableCell
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
TableItemActionButtons
from
'
ui/shared/TableItemActionButtons
'
;
...
...
@@ -29,23 +26,23 @@ const CustomAbiTableItem = ({ item, isLoading, onEditClick, onDeleteClick }: Pro
},
[
item
,
onDeleteClick
]);
return
(
<
T
r
alignItems=
"top"
key=
{
item
.
id
}
>
<
T
d
>
<
T
ableRow
alignItems=
"top"
key=
{
item
.
id
}
>
<
T
ableCell
>
<
Box
maxW=
"100%"
>
<
AddressEntity
address=
{
item
.
contract_address
}
fontWeight=
"600"
isLoading=
{
isLoading
}
/>
<
Skeleton
fontSize=
"sm"
color=
"text_secondary"
mt=
{
0.5
}
ml=
{
8
}
display=
"inline-block"
isLoaded=
{
!
isLoading
}
>
<
Skeleton
textStyle=
"sm"
color=
"text.secondary"
mt=
{
0.5
}
ml=
{
8
}
display=
"inline-block"
loading=
{
isLoading
}
>
<
span
>
{
item
.
name
}
</
span
>
</
Skeleton
>
</
Box
>
</
T
d
>
<
T
d
>
</
T
ableCell
>
<
T
ableCell
>
<
TableItemActionButtons
onDeleteClick=
{
onItemDeleteClick
}
onEditClick=
{
onItemEditClick
}
isLoading=
{
isLoading
}
/>
</
T
d
>
</
T
r
>
</
T
ableCell
>
</
T
ableRow
>
);
};
...
...
ui/customAbi/DeleteCustomAbiModal.tsx
View file @
4c8f5ae9
...
...
@@ -9,12 +9,12 @@ import useApiFetch from 'lib/api/useApiFetch';
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
type
Props
=
{
isO
pen
:
boolean
;
on
Close
:
(
)
=>
void
;
o
pen
:
boolean
;
on
OpenChange
:
({
open
}:
{
open
:
boolean
}
)
=>
void
;
data
:
CustomAbi
;
};
const
DeleteCustomAbiModal
:
React
.
FC
<
Props
>
=
({
isOpen
,
onClos
e
,
data
})
=>
{
const
DeleteCustomAbiModal
:
React
.
FC
<
Props
>
=
({
open
,
onOpenChang
e
,
data
})
=>
{
const
queryClient
=
useQueryClient
();
const
apiFetch
=
useApiFetch
();
...
...
@@ -40,8 +40,8 @@ const DeleteCustomAbiModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
return
(
<
DeleteModal
isOpen=
{
isO
pen
}
on
Close=
{
onClos
e
}
open=
{
o
pen
}
on
OpenChange=
{
onOpenChang
e
}
title=
"Remove custom ABI"
renderContent=
{
renderText
}
mutationFn=
{
mutationFn
}
...
...
ui/pages/ApiKeys.tsx
View file @
4c8f5ae9
import
{
Box
,
Button
,
Link
,
Text
,
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Text
}
from
'
@chakra-ui/react
'
;
import
React
,
{
useCallback
,
useState
}
from
'
react
'
;
import
type
{
ApiKey
}
from
'
types/api/account
'
;
...
...
@@ -6,12 +6,15 @@ import type { ApiKey } from 'types/api/account';
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
{
space
}
from
'
lib/html-entities
'
;
import
{
API_KEY
}
from
'
stubs/account
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
useDisclosure
}
from
'
toolkit/hooks/useDisclosure
'
;
import
ApiKeyModal
from
'
ui/apiKey/ApiKeyModal/ApiKeyModal
'
;
import
ApiKeyListItem
from
'
ui/apiKey/ApiKeyTable/ApiKeyListItem
'
;
import
ApiKeyTable
from
'
ui/apiKey/ApiKeyTable/ApiKeyTable
'
;
import
DeleteApiKeyModal
from
'
ui/apiKey/DeleteApiKeyModal
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
useRedirectForInvalidAuthToken
from
'
ui/snippets/auth/useRedirectForInvalidAuthToken
'
;
...
...
@@ -37,9 +40,9 @@ const ApiKeysPage: React.FC = () => {
apiKeyModalProps
.
onOpen
();
},
[
apiKeyModalProps
]);
const
onApiKeyModal
Close
=
useCallback
((
)
=>
{
setApiKeyModalData
(
undefined
);
apiKeyModalProps
.
on
Close
(
);
const
onApiKeyModal
OpenChange
=
useCallback
(({
open
}:
{
open
:
boolean
}
)
=>
{
!
open
&&
setApiKeyModalData
(
undefined
);
apiKeyModalProps
.
on
OpenChange
({
open
}
);
},
[
apiKeyModalProps
]);
const
onDeleteClick
=
useCallback
((
data
:
ApiKey
)
=>
{
...
...
@@ -47,9 +50,9 @@ const ApiKeysPage: React.FC = () => {
deleteModalProps
.
onOpen
();
},
[
deleteModalProps
]);
const
onDeleteModal
Close
=
useCallback
((
)
=>
{
setDeleteModalData
(
undefined
);
deleteModalProps
.
on
Close
(
);
const
onDeleteModal
OpenChange
=
useCallback
(({
open
}:
{
open
:
boolean
}
)
=>
{
!
open
&&
setDeleteModalData
(
undefined
);
deleteModalProps
.
on
OpenChange
({
open
}
);
},
[
deleteModalProps
]);
const
description
=
(
...
...
@@ -99,7 +102,7 @@ const ApiKeysPage: React.FC = () => {
marginTop=
{
8
}
flexDir=
{
{
base
:
'
column
'
,
lg
:
'
row
'
}
}
alignItems=
{
{
base
:
'
start
'
,
lg
:
'
center
'
}
}
isLoaded=
{
!
isPlaceholderData
}
loading=
{
isPlaceholderData
}
display=
"inline-flex"
columnGap=
{
5
}
rowGap=
{
5
}
...
...
@@ -107,18 +110,18 @@ const ApiKeysPage: React.FC = () => {
<
Button
size=
"lg"
onClick=
{
apiKeyModalProps
.
onOpen
}
isD
isabled=
{
!
canAdd
}
d
isabled=
{
!
canAdd
}
>
Add API key
</
Button
>
{
!
canAdd
&&
(
<
Text
fontSize=
"sm"
variant=
"
secondary"
>
<
Text
fontSize=
"sm"
color=
"text.
secondary"
>
{
`You have added the maximum number of API keys (${ DATA_LIMIT }). Contact us to request additional keys.`
}
</
Text
>
)
}
</
Skeleton
>
<
ApiKeyModal
{
...
apiKeyModalProps
}
onClose=
{
onApiKeyModalClos
e
}
data=
{
apiKeyModalData
}
/>
{
deleteModalData
&&
<
DeleteApiKeyModal
{
...
deleteModalProps
}
onClose=
{
onDeleteModalClos
e
}
data=
{
deleteModalData
}
/>
}
<
ApiKeyModal
open=
{
apiKeyModalProps
.
open
}
onOpenChange=
{
onApiKeyModalOpenChang
e
}
data=
{
apiKeyModalData
}
/>
{
deleteModalData
&&
<
DeleteApiKeyModal
open=
{
deleteModalProps
.
open
}
onOpenChange=
{
onDeleteModalOpenChang
e
}
data=
{
deleteModalData
}
/>
}
</>
);
})();
...
...
ui/pages/CustomAbi.tsx
View file @
4c8f5ae9
import
{
Box
,
Button
,
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
React
,
{
useCallback
,
useState
}
from
'
react
'
;
import
type
{
CustomAbi
}
from
'
types/api/account
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
{
CUSTOM_ABI
}
from
'
stubs/account
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
useDisclosure
}
from
'
toolkit/hooks/useDisclosure
'
;
import
CustomAbiModal
from
'
ui/customAbi/CustomAbiModal/CustomAbiModal
'
;
import
CustomAbiListItem
from
'
ui/customAbi/CustomAbiTable/CustomAbiListItem
'
;
import
CustomAbiTable
from
'
ui/customAbi/CustomAbiTable/CustomAbiTable
'
;
import
DeleteCustomAbiModal
from
'
ui/customAbi/DeleteCustomAbiModal
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
useRedirectForInvalidAuthToken
from
'
ui/snippets/auth/useRedirectForInvalidAuthToken
'
;
...
...
@@ -34,9 +36,9 @@ const CustomAbiPage: React.FC = () => {
customAbiModalProps
.
onOpen
();
},
[
customAbiModalProps
]);
const
onCustomAbiModal
Close
=
useCallback
((
)
=>
{
setCustomAbiModalData
(
undefined
);
customAbiModalProps
.
on
Close
(
);
const
onCustomAbiModal
OpenChange
=
useCallback
(({
open
}:
{
open
:
boolean
}
)
=>
{
!
open
&&
setCustomAbiModalData
(
undefined
);
customAbiModalProps
.
on
OpenChange
({
open
}
);
},
[
customAbiModalProps
]);
const
onDeleteClick
=
useCallback
((
data
:
CustomAbi
)
=>
{
...
...
@@ -44,9 +46,9 @@ const CustomAbiPage: React.FC = () => {
deleteModalProps
.
onOpen
();
},
[
deleteModalProps
]);
const
onDeleteModal
Close
=
useCallback
((
)
=>
{
setDeleteModalData
(
undefined
);
deleteModalProps
.
on
Close
(
);
const
onDeleteModal
OpenChange
=
useCallback
(({
open
}:
{
open
:
boolean
}
)
=>
{
!
open
&&
setDeleteModalData
(
undefined
);
deleteModalProps
.
on
OpenChange
({
open
}
);
},
[
deleteModalProps
]);
const
description
=
(
...
...
@@ -88,7 +90,7 @@ const CustomAbiPage: React.FC = () => {
<>
{
description
}
{
Boolean
(
data
?.
length
)
&&
list
}
<
Skeleton
mt=
{
8
}
isLoaded=
{
!
isPlaceholderData
}
display=
"inline-block"
>
<
Skeleton
mt=
{
8
}
loading=
{
isPlaceholderData
}
display=
"inline-block"
>
<
Button
size=
"lg"
onClick=
{
customAbiModalProps
.
onOpen
}
...
...
@@ -96,8 +98,8 @@ const CustomAbiPage: React.FC = () => {
Add custom ABI
</
Button
>
</
Skeleton
>
<
CustomAbiModal
{
...
customAbiModalProps
}
onClose=
{
onCustomAbiModalClos
e
}
data=
{
customAbiModalData
}
/>
{
deleteModalData
&&
<
DeleteCustomAbiModal
{
...
deleteModalProps
}
onClose=
{
onDeleteModalClos
e
}
data=
{
deleteModalData
}
/>
}
<
CustomAbiModal
open=
{
customAbiModalProps
.
open
}
onOpenChange=
{
onCustomAbiModalOpenChang
e
}
data=
{
customAbiModalData
}
/>
{
deleteModalData
&&
<
DeleteCustomAbiModal
open=
{
deleteModalProps
.
open
}
onOpenChange=
{
onDeleteModalOpenChang
e
}
data=
{
deleteModalData
}
/>
}
</>
);
})();
...
...
ui/shared/ApiKeySnippet.tsx
View file @
4c8f5ae9
import
{
Box
,
HStack
,
Flex
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
HStack
,
Flex
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
CopyToClipboard
from
'
ui/shared/CopyToClipboard
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
...
...
@@ -13,17 +13,17 @@ interface Props {
const
ApiKeySnippet
=
({
apiKey
,
name
,
isLoading
}:
Props
)
=>
{
return
(
<
HStack
spacing
=
{
2
}
alignItems=
"start"
>
<
IconSvg
name=
"key"
boxSize=
{
6
}
color=
{
useColorModeValue
(
'
gray.500
'
,
'
gray.400
'
)
}
isLoading=
{
isLoading
}
/>
<
HStack
gap
=
{
2
}
alignItems=
"start"
>
<
IconSvg
name=
"key"
boxSize=
{
6
}
color=
{
{
_light
:
'
gray.500
'
,
_dark
:
'
gray.400
'
}
}
isLoading=
{
isLoading
}
/>
<
Box
>
<
Flex
alignItems=
{
{
base
:
'
flex-start
'
,
lg
:
'
center
'
}
}
>
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
fontWeight=
{
600
}
mr=
{
1
}
>
<
Skeleton
loading=
{
isLoading
}
display=
"inline-block"
fontWeight=
{
600
}
mr=
{
1
}
>
<
span
>
{
apiKey
}
</
span
>
</
Skeleton
>
<
CopyToClipboard
text=
{
apiKey
}
isLoading=
{
isLoading
}
/>
</
Flex
>
{
name
&&
(
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
fontSize=
"sm"
color=
"text_secondary"
mt=
{
1
}
>
<
Skeleton
loading=
{
isLoading
}
display=
"inline-block"
fontSize=
"sm"
color=
"text_secondary"
mt=
{
1
}
>
<
span
>
{
name
}
</
span
>
</
Skeleton
>
)
}
...
...
ui/shared/ad/CoinzillaTextAd.tsx
View file @
4c8f5ae9
...
...
@@ -18,15 +18,15 @@ type AdData = {
};
};
//
const MOCK: AdData = {
//
ad: {
//
url: 'https://unsplash.com/s/photos/cute-kitten',
// thumbnail: 'https://placekitten.com/40/40
',
//
name: 'All about kitties',
//
description_short: 'To see millions picture of cute kitties',
//
cta_button: 'click here',
//
},
//
};
const
MOCK
:
AdData
=
{
ad
:
{
url
:
'
https://unsplash.com/s/photos/cute-kitten
'
,
thumbnail
:
'
https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/gnosis.svg
'
,
name
:
'
All about kitties
'
,
description_short
:
'
To see millions picture of cute kitties
'
,
cta_button
:
'
click here
'
,
},
};
const
CoinzillaTextAd
=
({
className
}:
{
className
?:
string
})
=>
{
const
[
adData
,
setAdData
]
=
React
.
useState
<
AdData
|
null
>
(
null
);
...
...
@@ -44,7 +44,7 @@ const CoinzillaTextAd = ({ className }: { className?: string }) => {
}
})
.
finally
(()
=>
{
//
setAdData(MOCK);
setAdData
(
MOCK
);
setIsLoading
(
false
);
});
}
...
...
@@ -87,7 +87,7 @@ const CoinzillaTextAd = ({ className }: { className?: string }) => {
src=
{
adData
.
ad
.
thumbnail
}
width=
"20px"
height=
"20px"
mb=
"2px
"
verticalAlign=
"text-bottom
"
mr=
{
1
}
display=
"inline-block"
alt=
""
...
...
ui/sol2uml/Sol2UmlDiagram.tsx
View file @
4c8f5ae9
import
{
chakra
,
Tooltip
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
*
as
visualizer
from
'
@blockscout/visualizer-types
'
;
...
...
@@ -8,6 +8,7 @@ import type { ResourceError } from 'lib/api/resources';
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
throwOnAbsentParamError
from
'
lib/errors/throwOnAbsentParamError
'
;
import
throwOnResourceLoadError
from
'
lib/errors/throwOnResourceLoadError
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
ContentLoader
from
'
ui/shared/ContentLoader
'
;
interface
Props
{
...
...
@@ -53,7 +54,6 @@ const Sol2UmlDiagram = ({ addressHash }: Props) => {
});
const
imgUrl
=
`data:image/svg+xml;base64,
${
umlQuery
.
data
?.
svg
}
`;
const imgFilter = useColorModeValue('invert(0)', 'invert(1)');
const handleClick = React.useCallback(() => {
const image = new Image();
...
...
@@ -76,13 +76,13 @@ const Sol2UmlDiagram = ({ addressHash }: Props) => {
}
return (
<Tooltip
label="Click on image to zoom" placement="top"
>
<Tooltip
content="Click on image to zoom" positioning={{ placement: 'top' }}
>
<chakra.img
src={ imgUrl }
alt={ `
Contract
$
{
contractQuery
.
data
.
name
}
UML
diagram
` }
onClick={ handleClick }
cursor="pointer"
filter={
imgFilter
}
filter={
{ _light: 'invert(0)', _dark: 'invert(1)' }
}
/>
</Tooltip>
);
...
...
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