Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move events card to tabs #1488

Merged
merged 3 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changelog/1488.trivial.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Move events cards to tabs
4 changes: 3 additions & 1 deletion playwright/tests/accounts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ async function setup(page: Page) {
})
})

await page.goto('http://localhost:1234/mainnet/sapphire/address/0x0000000000000000000000000000000000000000')
await page.goto(
'http://localhost:1234/mainnet/sapphire/address/0x0000000000000000000000000000000000000000/events',
)
}

test.describe('Account details page', () => {
Expand Down
45 changes: 26 additions & 19 deletions src/app/pages/RuntimeAccountDetailsPage/AccountEventsCard.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
import { FC } from 'react'
import { RuntimeEvent } from '../../../oasis-nexus/api'
import { SubPageCard } from 'app/components/SubPageCard'
import Card from '@mui/material/Card'
import CardHeader from '@mui/material/CardHeader'
import CardContent from '@mui/material/CardContent'
import { useTranslation } from 'react-i18next'
import { RuntimeEventsDetailedList } from '../../components/RuntimeEvents/RuntimeEventsDetailedList'
import { SearchScope } from '../../../types/searchScope'
import { AddressSwitchOption } from '../../components/AddressSwitch'
import { ErrorBoundary } from '../../components/ErrorBoundary'
import { LinkableDiv } from '../../components/PageLayout/LinkableDiv'
import { useAccountEvents } from './hook'
import { RuntimeAccountDetailsContext } from '.'

type AccountEventProps = {
scope: SearchScope
isLoading: boolean
isError: boolean
events: RuntimeEvent[] | undefined
}
export const eventsContainerId = 'events'

export const AccountEventsCard: FC<AccountEventProps> = ({ scope, isLoading, isError, events }) => {
export const AccountEventsCard: FC<RuntimeAccountDetailsContext> = ({ scope, address }) => {
const { t } = useTranslation()
const { isLoading, isError, events } = useAccountEvents(scope, address)

return (
<SubPageCard title={t('common.events')}>
<RuntimeEventsDetailedList
scope={scope}
events={events}
isLoading={isLoading}
isError={isError}
addressSwitchOption={AddressSwitchOption.ETH} // TODO
/>
</SubPageCard>
<Card>
<LinkableDiv id={eventsContainerId}>
<CardHeader disableTypography component="h3" title={t('common.events')} />
</LinkableDiv>
<CardContent>
<ErrorBoundary light={true}>
<RuntimeEventsDetailedList
scope={scope}
events={events}
isLoading={isLoading}
isError={isError}
addressSwitchOption={AddressSwitchOption.ETH} // TODO
/>
</ErrorBoundary>
</CardContent>
</Card>
)
}
10 changes: 4 additions & 6 deletions src/app/pages/RuntimeAccountDetailsPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@ import { useHref, useLoaderData, useOutletContext } from 'react-router-dom'
import { PageLayout } from '../../components/PageLayout'
import { RouterTabs } from '../../components/RouterTabs'
import { useAllTokenPrices } from '../../../coin-gecko/api'

import { EvmTokenType, RuntimeAccount } from '../../../oasis-nexus/api'
import { accountTokenContainerId } from './AccountTokensCard'
import { useAccount, useAccountEvents } from './hook'
import { useAccount } from './hook'
import { useRequiredScopeParam } from '../../hooks/useScopeParam'
import { contractCodeContainerId } from './ContractCodeCard'
import { useTokenInfo } from '../TokenDashboardPage/hook'
import { accountTokenTransfersContainerId } from './AccountTokenTransfersCard'
import { getTokenTypePluralName } from '../../../types/tokens'
import { SearchScope } from '../../../types/searchScope'
import { RuntimeAccountDetailsCard } from './RuntimeAccountDetailsCard'
import { AccountEventsCard } from './AccountEventsCard'
import { eventsContainerId } from './AccountEventsCard'
import { DappBanner } from '../../components/DappBanner'
import { AddressLoaderData } from '../../utils/route-utils'
import { getFiatCurrencyForScope } from '../../../config'
Expand All @@ -39,8 +38,7 @@ export const RuntimeAccountDetailsPage: FC = () => {

const tokenPrices = useAllTokenPrices(getFiatCurrencyForScope(scope))

const { isLoading: areEventsLoading, isError: isEventsError, events } = useAccountEvents(scope, address)

const eventsLink = useHref(`events#${eventsContainerId}`)
const tokenTransfersLink = useHref(`token-transfers#${accountTokenTransfersContainerId}`)
const erc20Link = useHref(`tokens/erc-20#${accountTokenContainerId}`)
const erc721Link = useHref(`tokens/erc-721#${accountTokenContainerId}`)
Expand Down Expand Up @@ -68,6 +66,7 @@ export const RuntimeAccountDetailsPage: FC = () => {
<RouterTabs
tabs={[
{ label: t('common.transactions'), to: txLink },
{ label: t('common.events'), to: eventsLink },
{ label: t('common.transfers'), to: tokenTransfersLink },
{
label: getTokenTypePluralName(t, EvmTokenType.ERC20),
Expand All @@ -81,7 +80,6 @@ export const RuntimeAccountDetailsPage: FC = () => {
]}
context={context}
/>
<AccountEventsCard scope={scope} isLoading={areEventsLoading} isError={isEventsError} events={events} />
</PageLayout>
)
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { ScrollingCard } from '../../components/PageLayout/ScrollingCard'
import Card from '@mui/material/Card'
import CardHeader from '@mui/material/CardHeader'
import CardContent from '@mui/material/CardContent'

import { Layer, useGetRuntimeEvents } from '../../../oasis-nexus/api'
import { ErrorBoundary } from '../../components/ErrorBoundary'
import { AppErrors } from '../../../types/errors'
import { SearchScope } from '../../../types/searchScope'
import { RuntimeEventsDetailedList } from '../../components/RuntimeEvents/RuntimeEventsDetailedList'
import { AddressSwitchOption } from '../../components/AddressSwitch'
import { EmptyState } from '../../components/EmptyState'
import { LinkableDiv } from '../../components/PageLayout/LinkableDiv'
import { RuntimeBlockDetailsContext } from '.'

export const eventsContainerId = 'events'

const EventsList: FC<{ scope: SearchScope; blockHeight: number }> = ({ scope, blockHeight }) => {
const EventsList: FC<RuntimeBlockDetailsContext> = ({ scope, blockHeight }) => {
const { t } = useTranslation()
if (scope.layer === Layer.consensus) {
// Loading events for consensus blocks is not yet supported.
Expand Down Expand Up @@ -52,16 +52,23 @@ const EventsList: FC<{ scope: SearchScope; blockHeight: number }> = ({ scope, bl
)
}

export const EventsCard: FC<{ scope: SearchScope; blockHeight: number }> = ({ scope, blockHeight }) => {
export const BlockEventsCard: FC<RuntimeBlockDetailsContext> = ({ scope, blockHeight }) => {
const { t } = useTranslation()

if (!blockHeight) {
return null
}

return (
<ScrollingCard id={eventsContainerId}>
<CardHeader disableTypography component="h3" title={t('common.events')} />
<Card>
<LinkableDiv id={eventsContainerId}>
<CardHeader disableTypography component="h3" title={t('common.events')} />
</LinkableDiv>
<CardContent>
<ErrorBoundary light={true}>
<EventsList scope={scope} blockHeight={blockHeight} />
</ErrorBoundary>
</CardContent>
</ScrollingCard>
</Card>
)
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { ScrollingCard } from '../../components/PageLayout/ScrollingCard'
import Card from '@mui/material/Card'
import CardHeader from '@mui/material/CardHeader'
import CardContent from '@mui/material/CardContent'

import { useSearchParamsPagination } from '../../components/Table/useSearchParamsPagination'
import { NUMBER_OF_ITEMS_ON_SEPARATE_PAGE } from '../../config'
import { Layer, useGetRuntimeTransactions } from '../../../oasis-nexus/api'
import { RuntimeTransactions } from '../../components/Transactions'
import { ErrorBoundary } from '../../components/ErrorBoundary'
import { AppErrors } from '../../../types/errors'
import { SearchScope } from '../../../types/searchScope'
import { LinkableDiv } from '../../components/PageLayout/LinkableDiv'
import { RuntimeBlockDetailsContext } from '.'

export const transactionsContainerId = 'transactions'

const TransactionList: FC<{ scope: SearchScope; blockHeight: number }> = ({ scope, blockHeight }) => {
const TransactionList: FC<RuntimeBlockDetailsContext> = ({ scope, blockHeight }) => {
const txsPagination = useSearchParamsPagination('page')
const txsOffset = (txsPagination.selectedPage - 1) * NUMBER_OF_ITEMS_ON_SEPARATE_PAGE
if (scope.layer === Layer.consensus) {
Expand Down Expand Up @@ -52,16 +52,23 @@ const TransactionList: FC<{ scope: SearchScope; blockHeight: number }> = ({ scop
)
}

export const TransactionsCard: FC<{ scope: SearchScope; blockHeight: number }> = ({ scope, blockHeight }) => {
export const BlockTransactionsCard: FC<RuntimeBlockDetailsContext> = ({ scope, blockHeight }) => {
const { t } = useTranslation()

if (!blockHeight) {
return null
}

return (
<ScrollingCard id={transactionsContainerId}>
<CardHeader disableTypography component="h3" title={t('common.transactions')} />
<Card>
<LinkableDiv id={transactionsContainerId}>
<CardHeader disableTypography component="h3" title={t('common.transactions')} />
</LinkableDiv>
<CardContent>
<ErrorBoundary light={true}>
<TransactionList scope={scope} blockHeight={blockHeight} />
</ErrorBoundary>
</CardContent>
</ScrollingCard>
</Card>
)
}
28 changes: 22 additions & 6 deletions src/app/pages/RuntimeBlockDetailPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,39 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { useParams } from 'react-router-dom'
import { useHref, useOutletContext, useParams } from 'react-router-dom'
import { useScreenSize } from '../../hooks/useScreensize'
import Link from '@mui/material/Link'
import { Layer, RuntimeBlock, useGetRuntimeBlockByHeight } from '../../../oasis-nexus/api'
import { RouterTabs } from '../../components/RouterTabs'
import { StyledDescriptionList } from '../../components/StyledDescriptionList'
import { PageLayout } from '../../components/PageLayout'
import { SubPageCard } from '../../components/SubPageCard'
import { CopyToClipboard } from '../../components/CopyToClipboard'
import { TextSkeleton } from '../../components/Skeleton'
import { useFormattedTimestampStringWithDistance } from '../../hooks/useFormattedTimestamp'
import { TransactionsCard } from './TransactionsCard'
import { AppErrors } from '../../../types/errors'
import { paraTimesConfig } from '../../../config'
import { transactionsContainerId } from './TransactionsCard'
import { transactionsContainerId } from './BlockTransactionsCard'
import { BlockLink, BlockHashLink } from '../../components/Blocks/BlockLink'
import { RouteUtils } from '../../utils/route-utils'
import { useRequiredScopeParam } from '../../hooks/useScopeParam'
import { DashboardLink } from '../ParatimeDashboardPage/DashboardLink'
import { EventsCard } from './EventsCard'
import { eventsContainerId } from './BlockEventsCard'
import { RuntimeNextBlockButton, RuntimePrevBlockButton } from '../../components/BlockNavigationButtons'
import { SearchScope } from 'types/searchScope'

export type RuntimeBlockDetailsContext = {
scope: SearchScope
blockHeight?: number
}

export const useRuntimeBlockDetailsProps = () => useOutletContext<RuntimeBlockDetailsContext>()

export const RuntimeBlockDetailPage: FC = () => {
const { t } = useTranslation()
const scope = useRequiredScopeParam()
const txLink = useHref('')
const eventsLink = useHref(`events#${eventsContainerId}`)
if (scope.layer === Layer.consensus) {
throw AppErrors.UnsupportedLayer
// We should use useGetConsensusBlocksHeight()
Expand All @@ -38,14 +48,20 @@ export const RuntimeBlockDetailPage: FC = () => {
throw AppErrors.NotFoundBlockHeight
}
const block = data?.data
const context: RuntimeBlockDetailsContext = { scope, blockHeight }

return (
<PageLayout>
<SubPageCard featured title={t('common.block')} mainTitle>
<RuntimeBlockDetailView enableBlockNavigation={true} isLoading={isLoading} block={block} />
</SubPageCard>
{!!block?.num_transactions && <TransactionsCard scope={scope} blockHeight={blockHeight} />}
<EventsCard scope={scope} blockHeight={blockHeight} />
<RouterTabs
tabs={[
{ label: t('common.transactions'), to: txLink },
{ label: t('common.events'), to: eventsLink },
]}
context={context}
/>
</PageLayout>
)
}
Expand Down
19 changes: 18 additions & 1 deletion src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { RuntimeBlocksPage } from './app/pages/RuntimeBlocksPage'
import { RuntimeTransactionsPage } from './app/pages/RuntimeTransactionsPage'
import { RuntimeTransactionDetailPage } from './app/pages/RuntimeTransactionDetailPage'
import { ParatimeDashboardPage } from './app/pages/ParatimeDashboardPage'
import { RuntimeBlockDetailPage } from './app/pages/RuntimeBlockDetailPage'
import { RuntimeBlockDetailPage, useRuntimeBlockDetailsProps } from './app/pages/RuntimeBlockDetailPage'
import { BlockTransactionsCard } from './app/pages/RuntimeBlockDetailPage/BlockTransactionsCard'
import { BlockEventsCard } from './app/pages/RuntimeBlockDetailPage/BlockEventsCard'
import {
RuntimeAccountDetailsPage,
useRuntimeAccountDetailsProps,
Expand All @@ -28,6 +30,7 @@ import { RoutingErrorPage } from './app/pages/RoutingErrorPage'
import { ThemeByNetwork, withDefaultTheme } from './app/components/ThemeByNetwork'
import { useRequiredScopeParam } from './app/hooks/useScopeParam'
import { TokensPage } from './app/pages/TokensOverviewPage'
import { AccountEventsCard } from 'app/pages/RuntimeAccountDetailsPage/AccountEventsCard'
import { ContractCodeCard } from './app/pages/RuntimeAccountDetailsPage/ContractCodeCard'
import { TokenDashboardPage, useTokenDashboardProps } from './app/pages/TokenDashboardPage'
import { AccountTokenTransfersCard } from './app/pages/RuntimeAccountDetailsPage/AccountTokenTransfersCard'
Expand Down Expand Up @@ -216,6 +219,16 @@ export const routes: RouteObject[] = [
path: `block/:blockHeight`,
element: <RuntimeBlockDetailPage />,
loader: blockHeightParamLoader,
children: [
{
path: '',
Component: () => <BlockTransactionsCard {...useRuntimeBlockDetailsProps()} />,
},
{
path: 'events',
Component: () => <BlockEventsCard {...useRuntimeBlockDetailsProps()} />,
},
],
},
{
path: `address/:address`,
Expand All @@ -226,6 +239,10 @@ export const routes: RouteObject[] = [
path: '',
Component: () => <AccountTransactionsCard {...useRuntimeAccountDetailsProps()} />,
},
{
path: 'events',
Component: () => <AccountEventsCard {...useRuntimeAccountDetailsProps()} />,
},
{
path: 'token-transfers',
Component: () => <AccountTokenTransfersCard {...useRuntimeAccountDetailsProps()} />,
Expand Down
Loading