Commit bd2b2c48 authored by eddie's avatar eddie Committed by GitHub

fix: close MP drawer on nft nav (#6251)

* fix: close MP drawer on nft nav

* fix: make callbacks optional, rename props

* fix: improve card API

* fix: add e2e test
parent 2f004ed1
...@@ -53,4 +53,11 @@ describe('Testing nfts', () => { ...@@ -53,4 +53,11 @@ describe('Testing nfts', () => {
cy.get(getTestSelector('web3-status-connected')).click() cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('nft-view-self-nfts')).click() cy.get(getTestSelector('nft-view-self-nfts')).click()
}) })
it('should close the sidebar when navigating to NFT details', () => {
cy.get(getTestSelector('web3-status-connected')).click()
cy.get(getTestSelector('mini-portfolio-nav-nfts')).click()
cy.get(getTestSelector('mini-portfolio-nft')).first().click()
cy.contains('Buy crypto').should('not.be.visible')
})
}) })
...@@ -5,6 +5,7 @@ import Row from 'components/Row' ...@@ -5,6 +5,7 @@ import Row from 'components/Row'
import { useToggleWalletDrawer } from 'components/WalletDropdown' import { useToggleWalletDrawer } from 'components/WalletDropdown'
import { Box } from 'nft/components/Box' import { Box } from 'nft/components/Box'
import { NftCard } from 'nft/components/card' import { NftCard } from 'nft/components/card'
import { detailsHref } from 'nft/components/card/utils'
import { VerifiedIcon } from 'nft/components/icons' import { VerifiedIcon } from 'nft/components/icons'
import { WalletAsset } from 'nft/types' import { WalletAsset } from 'nft/types'
import { floorFormatter } from 'nft/utils' import { floorFormatter } from 'nft/utils'
...@@ -50,8 +51,8 @@ export function NFT({ ...@@ -50,8 +51,8 @@ export function NFT({
const trace = useTrace() const trace = useTrace()
const navigateToNFTDetails = () => { const navigateToNFTDetails = () => {
navigate(`/nfts/asset/${asset.asset_contract.address}/${asset.tokenId}`)
toggleWalletDrawer() toggleWalletDrawer()
navigate(detailsHref(asset))
} }
return ( return (
...@@ -62,10 +63,7 @@ export function NFT({ ...@@ -62,10 +63,7 @@ export function NFT({
display={{ disabledInfo: true }} display={{ disabledInfo: true }}
isSelected={false} isSelected={false}
isDisabled={false} isDisabled={false}
selectAsset={navigateToNFTDetails} onCardClick={navigateToNFTDetails}
unselectAsset={() => {
/* */
}}
sendAnalyticsEvent={() => sendAnalyticsEvent={() =>
sendAnalyticsEvent(SharedEventName.ELEMENT_CLICKED, { sendAnalyticsEvent(SharedEventName.ELEMENT_CLICKED, {
element: InterfaceElementName.MINI_PORTFOLIO_NFT_ITEM, element: InterfaceElementName.MINI_PORTFOLIO_NFT_ITEM,
...@@ -77,6 +75,7 @@ export function NFT({ ...@@ -77,6 +75,7 @@ export function NFT({
} }
mediaShouldBePlaying={mediaShouldBePlaying} mediaShouldBePlaying={mediaShouldBePlaying}
setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia} setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia}
testId="mini-portfolio-nft"
/> />
<NFTDetails asset={asset} /> <NFTDetails asset={asset} />
</NFTContainer> </NFTContainer>
......
...@@ -55,6 +55,7 @@ const PageWrapper = styled.div` ...@@ -55,6 +55,7 @@ const PageWrapper = styled.div`
interface Page { interface Page {
title: React.ReactNode title: React.ReactNode
key: string
component: ({ account }: { account: string }) => JSX.Element component: ({ account }: { account: string }) => JSX.Element
loggingElementName: string loggingElementName: string
} }
...@@ -62,13 +63,25 @@ interface Page { ...@@ -62,13 +63,25 @@ interface Page {
const Pages: Array<Page> = [ const Pages: Array<Page> = [
{ {
title: <Trans>Tokens</Trans>, title: <Trans>Tokens</Trans>,
key: 'tokens',
component: Tokens, component: Tokens,
loggingElementName: InterfaceElementName.MINI_PORTFOLIO_TOKENS_TAB, loggingElementName: InterfaceElementName.MINI_PORTFOLIO_TOKENS_TAB,
}, },
{ title: <Trans>NFTs</Trans>, component: NFTs, loggingElementName: InterfaceElementName.MINI_PORTFOLIO_NFT_TAB }, {
{ title: <Trans>Pools</Trans>, component: Pools, loggingElementName: InterfaceElementName.MINI_PORTFOLIO_POOLS_TAB }, title: <Trans>NFTs</Trans>,
key: 'nfts',
component: NFTs,
loggingElementName: InterfaceElementName.MINI_PORTFOLIO_NFT_TAB,
},
{
title: <Trans>Pools</Trans>,
key: 'pools',
component: Pools,
loggingElementName: InterfaceElementName.MINI_PORTFOLIO_POOLS_TAB,
},
{ {
title: <Trans>Activity</Trans>, title: <Trans>Activity</Trans>,
key: 'activity',
component: ActivityTab, component: ActivityTab,
loggingElementName: InterfaceElementName.MINI_PORTFOLIO_ACTIVITY_TAB, loggingElementName: InterfaceElementName.MINI_PORTFOLIO_ACTIVITY_TAB,
}, },
...@@ -83,7 +96,7 @@ function MiniPortfolio({ account }: { account: string }) { ...@@ -83,7 +96,7 @@ function MiniPortfolio({ account }: { account: string }) {
return ( return (
<Wrapper> <Wrapper>
<Nav> <Nav>
{Pages.map(({ title, loggingElementName }, index) => { {Pages.map(({ title, loggingElementName, key }, index) => {
if (shouldDisableNFTRoutes && loggingElementName.includes('nft')) return null if (shouldDisableNFTRoutes && loggingElementName.includes('nft')) return null
return ( return (
<TraceEvent <TraceEvent
...@@ -93,6 +106,7 @@ function MiniPortfolio({ account }: { account: string }) { ...@@ -93,6 +106,7 @@ function MiniPortfolio({ account }: { account: string }) {
key={index} key={index}
> >
<NavItem <NavItem
data-testid={`mini-portfolio-nav-${key}`}
onClick={() => setCurrentPage(index)} onClick={() => setCurrentPage(index)}
active={currentPage === index} active={currentPage === index}
key={`Mini Portfolio page ${index}`} key={`Mini Portfolio page ${index}`}
......
...@@ -186,22 +186,20 @@ const Container = ({ ...@@ -186,22 +186,20 @@ const Container = ({
isSelected, isSelected,
isDisabled, isDisabled,
detailsHref, detailsHref,
doNotLinkToDetails = false,
testId, testId,
onClick, onClick,
children, children,
}: { }: {
isSelected: boolean isSelected: boolean
isDisabled: boolean isDisabled: boolean
detailsHref: string detailsHref?: string
doNotLinkToDetails: boolean
testId?: string testId?: string
children: ReactNode children: ReactNode
onClick?: (e: React.MouseEvent) => void onClick?: (e: React.MouseEvent) => void
}) => { }) => {
return ( return (
<CardContainer isSelected={isSelected} isDisabled={isDisabled} testId={testId} onClick={onClick}> <CardContainer isSelected={isSelected} isDisabled={isDisabled} testId={testId} onClick={onClick}>
<StyledLink to={doNotLinkToDetails ? '' : detailsHref}>{children}</StyledLink> {detailsHref ? <StyledLink to={detailsHref}>{children}</StyledLink> : children}
</CardContainer> </CardContainer>
) )
} }
......
...@@ -13,11 +13,11 @@ interface NftCardProps { ...@@ -13,11 +13,11 @@ interface NftCardProps {
display: NftCardDisplayProps display: NftCardDisplayProps
isSelected: boolean isSelected: boolean
isDisabled: boolean isDisabled: boolean
selectAsset: () => void selectAsset?: () => void
unselectAsset: () => void unselectAsset?: () => void
onClick?: () => void onButtonClick?: () => void
onCardClick?: () => void
sendAnalyticsEvent?: () => void sendAnalyticsEvent?: () => void
doNotLinkToDetails?: boolean
mediaShouldBePlaying: boolean mediaShouldBePlaying: boolean
uniformAspectRatio?: UniformAspectRatio uniformAspectRatio?: UniformAspectRatio
setUniformAspectRatio?: (uniformAspectRatio: UniformAspectRatio) => void setUniformAspectRatio?: (uniformAspectRatio: UniformAspectRatio) => void
...@@ -38,6 +38,12 @@ export interface NftCardDisplayProps { ...@@ -38,6 +38,12 @@ export interface NftCardDisplayProps {
disabledInfo?: ReactNode disabledInfo?: ReactNode
} }
/**
* NftCard is a component that displays an NFT asset.
*
* By default, clicking on the card will navigate to the details page.
* If you wish to override this behavior, pass a value for the onCardClick prop.
*/
export const NftCard = ({ export const NftCard = ({
asset, asset,
display, display,
...@@ -45,9 +51,9 @@ export const NftCard = ({ ...@@ -45,9 +51,9 @@ export const NftCard = ({
selectAsset, selectAsset,
unselectAsset, unselectAsset,
isDisabled, isDisabled,
onClick, onButtonClick,
onCardClick,
sendAnalyticsEvent, sendAnalyticsEvent,
doNotLinkToDetails = false,
mediaShouldBePlaying, mediaShouldBePlaying,
uniformAspectRatio = UniformAspectRatios.square, uniformAspectRatio = UniformAspectRatios.square,
setUniformAspectRatio, setUniformAspectRatio,
...@@ -57,7 +63,13 @@ export const NftCard = ({ ...@@ -57,7 +63,13 @@ export const NftCard = ({
testId, testId,
hideDetails = false, hideDetails = false,
}: NftCardProps) => { }: NftCardProps) => {
const clickActionButton = useSelectAsset(selectAsset, unselectAsset, isSelected, isDisabled, onClick) const clickActionButton = useSelectAsset({
selectAsset,
unselectAsset,
isSelected,
isDisabled,
onClick: onButtonClick,
})
const { bagExpanded, setBagExpanded } = useBag( const { bagExpanded, setBagExpanded } = useBag(
(state) => ({ (state) => ({
bagExpanded: state.bagExpanded, bagExpanded: state.bagExpanded,
...@@ -77,11 +89,11 @@ export const NftCard = ({ ...@@ -77,11 +89,11 @@ export const NftCard = ({
<Card.Container <Card.Container
isSelected={isSelected} isSelected={isSelected}
isDisabled={isDisabled} isDisabled={isDisabled}
detailsHref={detailsHref(asset)} detailsHref={onCardClick ? undefined : detailsHref(asset)}
doNotLinkToDetails={doNotLinkToDetails}
testId={testId} testId={testId}
onClick={() => { onClick={() => {
if (bagExpanded) setBagExpanded({ bagExpanded: false }) if (bagExpanded) setBagExpanded({ bagExpanded: false })
onCardClick?.()
sendAnalyticsEvent?.() sendAnalyticsEvent?.()
}} }}
> >
......
...@@ -96,13 +96,19 @@ export function getNftDisplayComponent( ...@@ -96,13 +96,19 @@ export function getNftDisplayComponent(
} }
} }
export function useSelectAsset( export function useSelectAsset({
selectAsset: () => void, selectAsset,
unselectAsset: () => void, unselectAsset,
isSelected: boolean, isSelected,
isDisabled: boolean, isDisabled,
onClick,
}: {
selectAsset?: () => void
unselectAsset?: () => void
isSelected: boolean
isDisabled: boolean
onClick?: () => void onClick?: () => void
) { }) {
return useCallback( return useCallback(
(e: React.MouseEvent) => { (e: React.MouseEvent) => {
e.stopPropagation() e.stopPropagation()
...@@ -117,7 +123,7 @@ export function useSelectAsset( ...@@ -117,7 +123,7 @@ export function useSelectAsset(
return return
} }
return isSelected ? unselectAsset() : selectAsset() return isSelected ? unselectAsset?.() : selectAsset?.()
}, },
[selectAsset, isDisabled, onClick, unselectAsset, isSelected] [selectAsset, isDisabled, onClick, unselectAsset, isSelected]
) )
......
...@@ -3,10 +3,12 @@ import { useTrace } from '@uniswap/analytics' ...@@ -3,10 +3,12 @@ import { useTrace } from '@uniswap/analytics'
import { sendAnalyticsEvent } from '@uniswap/analytics' import { sendAnalyticsEvent } from '@uniswap/analytics'
import { NFTEventName } from '@uniswap/analytics-events' import { NFTEventName } from '@uniswap/analytics-events'
import { NftCard, NftCardDisplayProps } from 'nft/components/card' import { NftCard, NftCardDisplayProps } from 'nft/components/card'
import { detailsHref } from 'nft/components/card/utils'
import { VerifiedIcon } from 'nft/components/icons' import { VerifiedIcon } from 'nft/components/icons'
import { useBag, useIsMobile, useSellAsset } from 'nft/hooks' import { useBag, useIsMobile, useSellAsset } from 'nft/hooks'
import { WalletAsset } from 'nft/types' import { WalletAsset } from 'nft/types'
import { useMemo } from 'react' import { useMemo } from 'react'
import { useNavigate } from 'react-router-dom'
interface ViewMyNftsAssetProps { interface ViewMyNftsAssetProps {
asset: WalletAsset asset: WalletAsset
...@@ -27,6 +29,7 @@ export const ViewMyNftsAsset = ({ ...@@ -27,6 +29,7 @@ export const ViewMyNftsAsset = ({
const cartExpanded = useBag((state) => state.bagExpanded) const cartExpanded = useBag((state) => state.bagExpanded)
const toggleCart = useBag((state) => state.toggleBag) const toggleCart = useBag((state) => state.toggleBag)
const isMobile = useIsMobile() const isMobile = useIsMobile()
const navigate = useNavigate()
const isSelected = useMemo(() => { const isSelected = useMemo(() => {
return sellAssets.some( return sellAssets.some(
...@@ -35,7 +38,7 @@ export const ViewMyNftsAsset = ({ ...@@ -35,7 +38,7 @@ export const ViewMyNftsAsset = ({
}, [asset, sellAssets]) }, [asset, sellAssets])
const trace = useTrace() const trace = useTrace()
const onCardClick = () => handleSelect(isSelected) const toggleSelect = () => handleSelect(isSelected)
const handleSelect = (removeAsset: boolean) => { const handleSelect = (removeAsset: boolean) => {
if (removeAsset) { if (removeAsset) {
...@@ -79,11 +82,13 @@ export const ViewMyNftsAsset = ({ ...@@ -79,11 +82,13 @@ export const ViewMyNftsAsset = ({
isDisabled={Boolean(isDisabled)} isDisabled={Boolean(isDisabled)}
selectAsset={() => handleSelect(false)} selectAsset={() => handleSelect(false)}
unselectAsset={() => handleSelect(true)} unselectAsset={() => handleSelect(true)}
onClick={onCardClick} onButtonClick={toggleSelect}
onCardClick={() => {
if (!hideDetails) navigate(detailsHref(asset))
}}
mediaShouldBePlaying={mediaShouldBePlaying} mediaShouldBePlaying={mediaShouldBePlaying}
setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia} setCurrentTokenPlayingMedia={setCurrentTokenPlayingMedia}
testId="nft-profile-asset" testId="nft-profile-asset"
doNotLinkToDetails={hideDetails}
/> />
) )
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment