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
3ecc9e5a
Unverified
Commit
3ecc9e5a
authored
Feb 12, 2024
by
tom goriunov
Committed by
GitHub
Feb 12, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Case: One button in a title (private/public tag) (#1593)
Fixes #1582
parent
6b43f9bd
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
307 additions
and
69 deletions
+307
-69
AccountActionsMenu.pw.tsx
ui/shared/AccountActionsMenu/AccountActionsMenu.pw.tsx
+113
-0
AccountActionsMenu.tsx
ui/shared/AccountActionsMenu/AccountActionsMenu.tsx
+49
-22
AccountActionsMenu.pw.tsx_default_with-multiple-items-base-view-1.png
...nsMenu.pw.tsx_default_with-multiple-items-base-view-1.png
+0
-0
AccountActionsMenu.pw.tsx_default_with-multiple-items-base-view-with-styles-1.png
...x_default_with-multiple-items-base-view-with-styles-1.png
+0
-0
AccountActionsMenu.pw.tsx_default_with-multiple-items-loading-1.png
...ionsMenu.pw.tsx_default_with-multiple-items-loading-1.png
+0
-0
AccountActionsMenu.pw.tsx_default_with-multiple-items-loading-with-styles-1.png
...tsx_default_with-multiple-items-loading-with-styles-1.png
+0
-0
AccountActionsMenu.pw.tsx_default_with-one-item-base-view-1.png
...tActionsMenu.pw.tsx_default_with-one-item-base-view-1.png
+0
-0
AccountActionsMenu.pw.tsx_default_with-one-item-base-view-with-styles-1.png
....pw.tsx_default_with-one-item-base-view-with-styles-1.png
+0
-0
AccountActionsMenu.pw.tsx_default_with-one-item-loading-1.png
...untActionsMenu.pw.tsx_default_with-one-item-loading-1.png
+0
-0
PrivateTagMenuItem.tsx
ui/shared/AccountActionsMenu/items/PrivateTagMenuItem.tsx
+28
-10
PublicTagMenuItem.tsx
ui/shared/AccountActionsMenu/items/PublicTagMenuItem.tsx
+25
-9
TokenInfoMenuItem.tsx
ui/shared/AccountActionsMenu/items/TokenInfoMenuItem.tsx
+37
-28
ButtonItem.tsx
ui/shared/AccountActionsMenu/parts/ButtonItem.tsx
+30
-0
MenuItem.tsx
ui/shared/AccountActionsMenu/parts/MenuItem.tsx
+18
-0
types.ts
ui/shared/AccountActionsMenu/types.ts
+7
-0
No files found.
ui/shared/AccountActionsMenu/AccountActionsMenu.pw.tsx
0 → 100644
View file @
3ecc9e5a
import
{
test
,
expect
}
from
'
@playwright/experimental-ct-react
'
;
import
React
from
'
react
'
;
import
TestApp
from
'
playwright/TestApp
'
;
import
AccountActionsMenu
from
'
./AccountActionsMenu
'
;
test
.
use
({
viewport
:
{
width
:
200
,
height
:
200
}
});
test
.
describe
(
'
with multiple items
'
,
async
()
=>
{
const
hooksConfig
=
{
router
:
{
query
:
{
hash
:
'
<hash>
'
},
pathname
:
'
/token/[hash]
'
,
isReady
:
true
,
},
};
test
(
'
base view
'
,
async
({
mount
,
page
})
=>
{
const
component
=
await
mount
(
<
TestApp
>
<
AccountActionsMenu
/>
</
TestApp
>,
{
hooksConfig
},
);
await
component
.
getByRole
(
'
button
'
).
click
();
await
expect
(
page
).
toHaveScreenshot
();
});
test
(
'
base view with styles
'
,
async
({
mount
,
page
})
=>
{
const
component
=
await
mount
(
<
TestApp
>
<
AccountActionsMenu
m=
{
2
}
outline=
"1px solid lightpink"
/>
</
TestApp
>,
{
hooksConfig
},
);
await
component
.
getByRole
(
'
button
'
).
click
();
await
expect
(
page
).
toHaveScreenshot
();
});
test
(
'
loading
'
,
async
({
mount
})
=>
{
const
component
=
await
mount
(
<
TestApp
>
<
AccountActionsMenu
isLoading
/>
</
TestApp
>,
{
hooksConfig
},
);
await
expect
(
component
).
toHaveScreenshot
();
});
test
(
'
loading with styles
'
,
async
({
mount
})
=>
{
const
component
=
await
mount
(
<
TestApp
>
<
AccountActionsMenu
isLoading
m=
{
2
}
outline=
"1px solid lightpink"
/>
</
TestApp
>,
{
hooksConfig
},
);
await
expect
(
component
).
toHaveScreenshot
();
});
});
test
.
describe
(
'
with one item
'
,
async
()
=>
{
const
hooksConfig
=
{
router
:
{
query
:
{
hash
:
'
<hash>
'
},
pathname
:
'
/tx/[hash]
'
,
isReady
:
true
,
},
};
test
(
'
base view
'
,
async
({
mount
,
page
})
=>
{
const
component
=
await
mount
(
<
TestApp
>
<
AccountActionsMenu
/>
</
TestApp
>,
{
hooksConfig
},
);
await
component
.
getByRole
(
'
button
'
).
hover
();
await
expect
(
page
).
toHaveScreenshot
();
});
test
(
'
base view with styles
'
,
async
({
mount
,
page
})
=>
{
const
component
=
await
mount
(
<
TestApp
>
<
AccountActionsMenu
m=
{
2
}
outline=
"1px solid lightpink"
/>
</
TestApp
>,
{
hooksConfig
},
);
await
component
.
getByRole
(
'
button
'
).
hover
();
await
expect
(
page
).
toHaveScreenshot
();
});
test
(
'
loading
'
,
async
({
mount
})
=>
{
const
component
=
await
mount
(
<
TestApp
>
<
AccountActionsMenu
isLoading
/>
</
TestApp
>,
{
hooksConfig
},
);
await
expect
(
component
).
toHaveScreenshot
();
});
});
ui/shared/AccountActionsMenu/AccountActionsMenu.tsx
View file @
3ecc9e5a
import
{
IconButton
,
Menu
,
MenuButton
,
MenuList
,
Skeleton
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
IconButton
,
Menu
,
MenuButton
,
MenuList
,
Skeleton
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
ItemProps
}
from
'
./types
'
;
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
import
useIsAccountActionAllowed
from
'
lib/hooks/useIsAccountActionAllowed
'
;
import
useIsAccountActionAllowed
from
'
lib/hooks/useIsAccountActionAllowed
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
...
@@ -33,30 +35,55 @@ const AccountActionsMenu = ({ isLoading, className }: Props) => {
...
@@ -33,30 +35,55 @@ const AccountActionsMenu = ({ isLoading, className }: Props) => {
return
null
;
return
null
;
}
}
const
items
=
[
{
render
:
(
props
:
ItemProps
)
=>
<
TokenInfoMenuItem
{
...
props
}
/>,
enabled
:
isTokenPage
&&
config
.
features
.
addressVerification
.
isEnabled
,
},
{
render
:
(
props
:
ItemProps
)
=>
<
PrivateTagMenuItem
{
...
props
}
entityType=
{
isTxPage
?
'
tx
'
:
'
address
'
}
/>,
enabled
:
true
,
},
{
render
:
(
props
:
ItemProps
)
=>
<
PublicTagMenuItem
{
...
props
}
/>,
enabled
:
!
isTxPage
,
},
].
filter
(({
enabled
})
=>
enabled
);
if
(
items
.
length
===
0
)
{
return
null
;
}
if
(
isLoading
)
{
return
<
Skeleton
w=
"36px"
h=
"32px"
borderRadius=
"base"
className=
{
className
}
/>;
}
if
(
items
.
length
===
1
)
{
return
(
<
Box
className=
{
className
}
>
{
items
[
0
].
render
({
type
:
'
button
'
,
hash
,
onBeforeClick
:
isAccountActionAllowed
})
}
</
Box
>
);
}
return
(
return
(
<
Menu
>
<
Menu
>
<
Skeleton
isLoaded=
{
!
isLoading
}
borderRadius=
"base"
className=
{
className
}
>
<
MenuButton
<
MenuButton
as=
{
IconButton
}
as=
{
IconButton
}
className=
{
className
}
size=
"sm"
size=
"sm"
variant=
"outline"
variant=
"outline"
colorScheme=
"gray"
colorScheme=
"gray"
px=
"7px"
px=
"7px"
onClick=
{
handleButtonClick
}
onClick=
{
handleButtonClick
}
icon=
{
<
IconSvg
name=
"dots"
boxSize=
"18px"
/>
}
icon=
{
<
IconSvg
name=
"dots"
boxSize=
"18px"
/>
}
/>
/>
</
Skeleton
>
<
MenuList
minWidth=
"180px"
zIndex=
"popover"
>
<
MenuList
minWidth=
"180px"
zIndex=
"popover"
>
{
isTokenPage
&&
config
.
features
.
addressVerification
.
isEnabled
&&
{
items
.
map
(({
render
},
index
)
=>
(
<
TokenInfoMenuItem
py=
{
2
}
px=
{
4
}
hash=
{
hash
}
onBeforeClick=
{
isAccountActionAllowed
}
/>
}
<
React
.
Fragment
key=
{
index
}
>
<
PrivateTagMenuItem
{
render
({
type
:
'
menu_item
'
,
hash
,
onBeforeClick
:
isAccountActionAllowed
})
}
py=
{
2
}
</
React
.
Fragment
>
px=
{
4
}
))
}
hash=
{
hash
}
onBeforeClick=
{
isAccountActionAllowed
}
type=
{
isTxPage
?
'
tx
'
:
'
address
'
}
/>
{
!
isTxPage
&&
<
PublicTagMenuItem
py=
{
2
}
px=
{
4
}
hash=
{
hash
}
onBeforeClick=
{
isAccountActionAllowed
}
/>
}
</
MenuList
>
</
MenuList
>
</
Menu
>
</
Menu
>
);
);
...
...
ui/shared/AccountActionsMenu/__screenshots__/AccountActionsMenu.pw.tsx_default_with-multiple-items-base-view-1.png
0 → 100644
View file @
3ecc9e5a
8.41 KB
ui/shared/AccountActionsMenu/__screenshots__/AccountActionsMenu.pw.tsx_default_with-multiple-items-base-view-with-styles-1.png
0 → 100644
View file @
3ecc9e5a
8.72 KB
ui/shared/AccountActionsMenu/__screenshots__/AccountActionsMenu.pw.tsx_default_with-multiple-items-loading-1.png
0 → 100644
View file @
3ecc9e5a
658 Bytes
ui/shared/AccountActionsMenu/__screenshots__/AccountActionsMenu.pw.tsx_default_with-multiple-items-loading-with-styles-1.png
0 → 100644
View file @
3ecc9e5a
907 Bytes
ui/shared/AccountActionsMenu/__screenshots__/AccountActionsMenu.pw.tsx_default_with-one-item-base-view-1.png
0 → 100644
View file @
3ecc9e5a
4 KB
ui/shared/AccountActionsMenu/__screenshots__/AccountActionsMenu.pw.tsx_default_with-one-item-base-view-with-styles-1.png
0 → 100644
View file @
3ecc9e5a
4.13 KB
ui/shared/AccountActionsMenu/__screenshots__/AccountActionsMenu.pw.tsx_default_with-one-item-loading-1.png
0 → 100644
View file @
3ecc9e5a
658 Bytes
ui/shared/AccountActionsMenu/items/PrivateTagMenuItem.tsx
View file @
3ecc9e5a
import
{
MenuItem
,
chakra
,
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
{
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
ItemType
}
from
'
../types
'
;
import
type
{
Address
}
from
'
types/api/address
'
;
import
type
{
Address
}
from
'
types/api/address
'
;
import
type
{
Transaction
}
from
'
types/api/transaction
'
;
import
type
{
Transaction
}
from
'
types/api/transaction
'
;
...
@@ -12,19 +13,23 @@ import AddressModal from 'ui/privateTags/AddressModal/AddressModal';
...
@@ -12,19 +13,23 @@ import AddressModal from 'ui/privateTags/AddressModal/AddressModal';
import
TransactionModal
from
'
ui/privateTags/TransactionModal/TransactionModal
'
;
import
TransactionModal
from
'
ui/privateTags/TransactionModal/TransactionModal
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
ButtonItem
from
'
../parts/ButtonItem
'
;
import
MenuItem
from
'
../parts/MenuItem
'
;
interface
Props
{
interface
Props
{
className
?:
string
;
className
?:
string
;
hash
:
string
;
hash
:
string
;
onBeforeClick
:
()
=>
boolean
;
onBeforeClick
:
()
=>
boolean
;
type
?:
'
address
'
|
'
tx
'
;
entityType
?:
'
address
'
|
'
tx
'
;
type
:
ItemType
;
}
}
const
PrivateTagMenuItem
=
({
className
,
hash
,
onBeforeClick
,
type
=
'
address
'
}:
Props
)
=>
{
const
PrivateTagMenuItem
=
({
className
,
hash
,
onBeforeClick
,
entityType
=
'
address
'
,
type
}:
Props
)
=>
{
const
modal
=
useDisclosure
();
const
modal
=
useDisclosure
();
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
queryKey
=
getResourceKey
(
t
ype
===
'
tx
'
?
'
tx
'
:
'
address
'
,
{
pathParams
:
{
hash
}
});
const
queryKey
=
getResourceKey
(
entityT
ype
===
'
tx
'
?
'
tx
'
:
'
address
'
,
{
pathParams
:
{
hash
}
});
const
queryData
=
queryClient
.
getQueryData
<
Address
|
Transaction
>
(
queryKey
);
const
queryData
=
queryClient
.
getQueryData
<
Address
|
Transaction
>
(
queryKey
);
const
handleClick
=
React
.
useCallback
(()
=>
{
const
handleClick
=
React
.
useCallback
(()
=>
{
...
@@ -58,13 +63,26 @@ const PrivateTagMenuItem = ({ className, hash, onBeforeClick, type = 'address' }
...
@@ -58,13 +63,26 @@ const PrivateTagMenuItem = ({ className, hash, onBeforeClick, type = 'address' }
pageType
,
pageType
,
};
};
const
element
=
(()
=>
{
switch
(
type
)
{
case
'
button
'
:
{
return
<
ButtonItem
label=
"Add private tag"
icon=
"privattags"
onClick=
{
handleClick
}
className=
{
className
}
/>;
}
case
'
menu_item
'
:
{
return
(
<
MenuItem
className=
{
className
}
onClick=
{
handleClick
}
>
<
IconSvg
name=
"privattags"
boxSize=
{
6
}
mr=
{
2
}
/>
<
span
>
Add private tag
</
span
>
</
MenuItem
>
);
}
}
})();
return
(
return
(
<>
<>
<
MenuItem
className=
{
className
}
onClick=
{
handleClick
}
>
{
element
}
<
IconSvg
name=
"privattags"
boxSize=
{
6
}
mr=
{
2
}
/>
{
entityType
===
'
tx
'
?
<
span
>
Add private tag
</
span
>
</
MenuItem
>
{
type
===
'
tx
'
?
<
TransactionModal
{
...
modalProps
}
data=
{
{
transaction_hash
:
hash
}
}
/>
:
<
TransactionModal
{
...
modalProps
}
data=
{
{
transaction_hash
:
hash
}
}
/>
:
<
AddressModal
{
...
modalProps
}
data=
{
{
address_hash
:
hash
}
}
/>
<
AddressModal
{
...
modalProps
}
data=
{
{
address_hash
:
hash
}
}
/>
}
}
...
@@ -72,4 +90,4 @@ const PrivateTagMenuItem = ({ className, hash, onBeforeClick, type = 'address' }
...
@@ -72,4 +90,4 @@ const PrivateTagMenuItem = ({ className, hash, onBeforeClick, type = 'address' }
);
);
};
};
export
default
React
.
memo
(
chakra
(
PrivateTagMenuItem
)
);
export
default
React
.
memo
(
PrivateTagMenuItem
);
ui/shared/AccountActionsMenu/items/PublicTagMenuItem.tsx
View file @
3ecc9e5a
import
{
MenuItem
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
ItemType
}
from
'
../types
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
ButtonItem
from
'
../parts/ButtonItem
'
;
import
MenuItem
from
'
../parts/MenuItem
'
;
interface
Props
{
interface
Props
{
className
?:
string
;
className
?:
string
;
hash
:
string
;
hash
:
string
;
onBeforeClick
:
()
=>
boolean
;
onBeforeClick
:
()
=>
boolean
;
type
:
ItemType
;
}
}
const
PublicTagMenuItem
=
({
className
,
hash
,
onBeforeClick
}:
Props
)
=>
{
const
PublicTagMenuItem
=
({
className
,
hash
,
onBeforeClick
,
type
}:
Props
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
handleClick
=
React
.
useCallback
(()
=>
{
const
handleClick
=
React
.
useCallback
(()
=>
{
...
@@ -21,12 +26,23 @@ const PublicTagMenuItem = ({ className, hash, onBeforeClick }: Props) => {
...
@@ -21,12 +26,23 @@ const PublicTagMenuItem = ({ className, hash, onBeforeClick }: Props) => {
router
.
push
({
pathname
:
'
/account/public-tags-request
'
,
query
:
{
address
:
hash
}
});
router
.
push
({
pathname
:
'
/account/public-tags-request
'
,
query
:
{
address
:
hash
}
});
},
[
hash
,
onBeforeClick
,
router
]);
},
[
hash
,
onBeforeClick
,
router
]);
return
(
const
element
=
(()
=>
{
<
MenuItem
className=
{
className
}
onClick=
{
handleClick
}
>
switch
(
type
)
{
<
IconSvg
name=
"publictags"
boxSize=
{
6
}
mr=
{
2
}
/>
case
'
button
'
:
{
<
span
>
Add public tag
</
span
>
return
<
ButtonItem
label=
"Add public tag"
icon=
"publictags"
onClick=
{
handleClick
}
className=
{
className
}
/>;
</
MenuItem
>
}
);
case
'
menu_item
'
:
{
return
(
<
MenuItem
className=
{
className
}
onClick=
{
handleClick
}
>
<
IconSvg
name=
"publictags"
boxSize=
{
6
}
mr=
{
2
}
/>
<
span
>
Add private tag
</
span
>
</
MenuItem
>
);
}
}
})();
return
element
;
};
};
export
default
React
.
memo
(
chakra
(
PublicTagMenuItem
)
);
export
default
React
.
memo
(
PublicTagMenuItem
);
ui/shared/AccountActionsMenu/items/TokenInfoMenuItem.tsx
View file @
3ecc9e5a
import
{
MenuItem
,
chakra
,
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
{
chakra
,
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
ItemType
}
from
'
../types
'
;
import
type
{
Route
}
from
'
nextjs-routes
'
;
import
type
{
Route
}
from
'
nextjs-routes
'
;
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
...
@@ -11,13 +13,17 @@ import { PAGE_TYPE_DICT } from 'lib/mixpanel/getPageType';
...
@@ -11,13 +13,17 @@ import { PAGE_TYPE_DICT } from 'lib/mixpanel/getPageType';
import
AddressVerificationModal
from
'
ui/addressVerification/AddressVerificationModal
'
;
import
AddressVerificationModal
from
'
ui/addressVerification/AddressVerificationModal
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
ButtonItem
from
'
../parts/ButtonItem
'
;
import
MenuItem
from
'
../parts/MenuItem
'
;
interface
Props
{
interface
Props
{
className
?:
string
;
className
?:
string
;
hash
:
string
;
hash
:
string
;
onBeforeClick
:
(
route
:
Route
)
=>
boolean
;
onBeforeClick
:
(
route
:
Route
)
=>
boolean
;
type
:
ItemType
;
}
}
const
TokenInfoMenuItem
=
({
className
,
hash
,
onBeforeClick
}:
Props
)
=>
{
const
TokenInfoMenuItem
=
({
className
,
hash
,
onBeforeClick
,
type
}:
Props
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
modal
=
useDisclosure
();
const
modal
=
useDisclosure
();
const
isAuth
=
useHasAccount
();
const
isAuth
=
useHasAccount
();
...
@@ -61,37 +67,40 @@ const TokenInfoMenuItem = ({ className, hash, onBeforeClick }: Props) => {
...
@@ -61,37 +67,40 @@ const TokenInfoMenuItem = ({ className, hash, onBeforeClick }: Props) => {
router
.
push
({
pathname
:
'
/account/verified-addresses
'
});
router
.
push
({
pathname
:
'
/account/verified-addresses
'
});
},
[
router
]);
},
[
router
]);
const
icon
=
<
IconSvg
name=
"edit"
boxSize=
{
6
}
mr=
{
2
}
p=
{
1
}
/>;
const
element
=
(()
=>
{
const
icon
=
<
IconSvg
name=
"edit"
boxSize=
{
6
}
p=
{
1
}
/>;
const
content
=
(()
=>
{
const
isVerifiedAddress
=
verifiedAddressesQuery
.
data
?.
verifiedAddresses
if
(
!
verifiedAddressesQuery
.
data
?.
verifiedAddresses
.
find
(({
contractAddress
})
=>
contractAddress
.
toLowerCase
()
===
hash
.
toLowerCase
()))
{
.
find
(({
contractAddress
})
=>
contractAddress
.
toLowerCase
()
===
hash
.
toLowerCase
());
return
(
<
MenuItem
className=
{
className
}
onClick=
{
handleAddAddressClick
}
>
{
icon
}
<
span
>
{
tokenInfoQuery
.
data
?.
tokenAddress
?
'
Update token info
'
:
'
Add token info
'
}
</
span
>
</
MenuItem
>
);
}
const
hasApplication
=
applicationsQuery
.
data
?.
submissions
.
some
(({
tokenAddress
})
=>
tokenAddress
.
toLowerCase
()
===
hash
.
toLowerCase
());
const
hasApplication
=
applicationsQuery
.
data
?.
submissions
.
some
(({
tokenAddress
})
=>
tokenAddress
.
toLowerCase
()
===
hash
.
toLowerCase
());
return
(
const
label
=
(()
=>
{
<
MenuItem
className=
{
className
}
onClick=
{
handleAddApplicationClick
}
>
if
(
!
isVerifiedAddress
)
{
{
icon
}
return
tokenInfoQuery
.
data
?.
tokenAddress
?
'
Update token info
'
:
'
Add token info
'
;
<
span
>
}
{
hasApplication
||
tokenInfoQuery
.
data
?.
tokenAddress
?
return
hasApplication
||
tokenInfoQuery
.
data
?.
tokenAddress
?
'
Update token info
'
:
'
Add token info
'
;
'
Update token info
'
:
})();
'
Add token info
'
}
const
onClick
=
isVerifiedAddress
?
handleAddApplicationClick
:
handleAddAddressClick
;
</
span
>
</
MenuItem
>
switch
(
type
)
{
);
case
'
button
'
:
{
return
<
ButtonItem
label=
{
label
}
icon=
{
icon
}
onClick=
{
onClick
}
className=
{
className
}
/>;
}
case
'
menu_item
'
:
{
return
(
<
MenuItem
className=
{
className
}
onClick=
{
onClick
}
>
{
icon
}
<
chakra
.
span
ml=
{
2
}
>
{
label
}
</
chakra
.
span
>
</
MenuItem
>
);
}
}
})();
})();
return
(
return
(
<>
<>
{
cont
ent
}
{
elem
ent
}
<
AddressVerificationModal
<
AddressVerificationModal
defaultAddress=
{
hash
}
defaultAddress=
{
hash
}
pageType=
{
PAGE_TYPE_DICT
[
'
/token/[hash]
'
]
}
pageType=
{
PAGE_TYPE_DICT
[
'
/token/[hash]
'
]
}
...
@@ -105,4 +114,4 @@ const TokenInfoMenuItem = ({ className, hash, onBeforeClick }: Props) => {
...
@@ -105,4 +114,4 @@ const TokenInfoMenuItem = ({ className, hash, onBeforeClick }: Props) => {
);
);
};
};
export
default
React
.
memo
(
chakra
(
TokenInfoMenuItem
)
);
export
default
React
.
memo
(
TokenInfoMenuItem
);
ui/shared/AccountActionsMenu/parts/ButtonItem.tsx
0 → 100644
View file @
3ecc9e5a
import
{
IconButton
,
Tooltip
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
IconName
}
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
interface
Props
{
className
?:
string
;
onClick
:
()
=>
void
;
label
:
string
;
icon
:
IconName
|
React
.
ReactElement
;
}
const
ButtonItem
=
({
className
,
label
,
onClick
,
icon
}:
Props
)
=>
{
return
(
<
Tooltip
label=
{
label
}
>
<
IconButton
aria
-
label=
{
label
}
className=
{
className
}
icon=
{
typeof
icon
===
'
string
'
?
<
IconSvg
name=
{
icon
}
boxSize=
{
6
}
/>
:
icon
}
onClick=
{
onClick
}
size=
"sm"
variant=
"outline"
px=
"4px"
/>
</
Tooltip
>
);
};
export
default
ButtonItem
;
ui/shared/AccountActionsMenu/parts/MenuItem.tsx
0 → 100644
View file @
3ecc9e5a
import
{
MenuItem
as
MenuItemChakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
interface
Props
{
className
?:
string
;
children
:
React
.
ReactNode
;
onClick
:
()
=>
void
;
}
const
MenuItem
=
({
className
,
children
,
onClick
}:
Props
)
=>
{
return
(
<
MenuItemChakra
className=
{
className
}
onClick=
{
onClick
}
py=
{
2
}
px=
{
4
}
>
{
children
}
</
MenuItemChakra
>
);
};
export
default
MenuItem
;
ui/shared/AccountActionsMenu/types.ts
0 → 100644
View file @
3ecc9e5a
export
type
ItemType
=
'
button
'
|
'
menu_item
'
;
export
interface
ItemProps
{
type
:
ItemType
;
hash
:
string
;
onBeforeClick
:
()
=>
boolean
;
}
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