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

Enable pagination in Events lists #1489

Merged
merged 2 commits into from
Jul 23, 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/1489.trivial.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enable pagination in Events lists
117 changes: 60 additions & 57 deletions playwright/tests/accounts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,68 +46,71 @@ async function setup(page: Page) {
} satisfies Partial<RuntimeAccount>),
})
})
await page.route('**/v1/sapphire/events?rel=oasis1qq2v39p9fqk997vk6742axrzqyu9v2ncyuqt8uek', route => {
route.fulfill({
body: JSON.stringify({
is_total_count_clipped: false,
total_count: 3,
events: [
{
body: {
amount: {
Amount: '100000000000000000000',
Denomination: '',
await page.route(
'**/v1/sapphire/events?limit=10&offset=0&rel=oasis1qq2v39p9fqk997vk6742axrzqyu9v2ncyuqt8uek',
route => {
route.fulfill({
body: JSON.stringify({
is_total_count_clipped: false,
total_count: 3,
events: [
{
body: {
amount: {
Amount: '100000000000000000000',
Denomination: '',
},
from: 'oasis1qq235lqj77855qcemcr5w2qm372s4amqcc4v3ztc',
nonce: 29,
to: 'oasis1qrwncs459lauc77zw23efdn9dmfcp23cxv095l5z',
},
from: 'oasis1qq235lqj77855qcemcr5w2qm372s4amqcc4v3ztc',
nonce: 29,
to: 'oasis1qrwncs459lauc77zw23efdn9dmfcp23cxv095l5z',
evm_log_name: '',
round: 3038913,
timestamp: '2023-10-16T13:13:47Z',
tx_hash: null,
type: 'consensus_accounts.delegate',
layer: 'sapphire',
network: 'testnet',
},
evm_log_name: '',
round: 3038913,
timestamp: '2023-10-16T13:13:47Z',
tx_hash: null,
type: 'consensus_accounts.delegate',
layer: 'sapphire',
network: 'testnet',
},
{
body: {
debond_end_time: 30013,
from: 'oasis1qrwncs459lauc77zw23efdn9dmfcp23cxv095l5z',
nonce: 30,
shares: '100',
to: 'oasis1qq235lqj77855qcemcr5w2qm372s4amqcc4v3ztc',
{
body: {
debond_end_time: 30013,
from: 'oasis1qrwncs459lauc77zw23efdn9dmfcp23cxv095l5z',
nonce: 30,
shares: '100',
to: 'oasis1qq235lqj77855qcemcr5w2qm372s4amqcc4v3ztc',
},
evm_log_name: '',
round: 3038944,
timestamp: '2023-10-16T13:18:23Z',
tx_hash: null,
type: 'consensus_accounts.undelegate_start',
layer: 'sapphire',
network: 'testnet',
},
evm_log_name: '',
round: 3038944,
timestamp: '2023-10-16T13:18:23Z',
tx_hash: null,
type: 'consensus_accounts.undelegate_start',
layer: 'sapphire',
network: 'testnet',
},
{
body: {
amount: {
Amount: '100000281888000000000',
Denomination: '',
{
body: {
amount: {
Amount: '100000281888000000000',
Denomination: '',
},
from: 'oasis1qrwncs459lauc77zw23efdn9dmfcp23cxv095l5z',
shares: '100000281888',
to: 'oasis1qq235lqj77855qcemcr5w2qm372s4amqcc4v3ztc',
},
from: 'oasis1qrwncs459lauc77zw23efdn9dmfcp23cxv095l5z',
shares: '100000281888',
to: 'oasis1qq235lqj77855qcemcr5w2qm372s4amqcc4v3ztc',
evm_log_name: '',
round: 3216917,
timestamp: '2023-10-29T09:06:05Z',
tx_hash: null,
type: 'consensus_accounts.undelegate_done',
layer: 'sapphire',
network: 'testnet',
},
evm_log_name: '',
round: 3216917,
timestamp: '2023-10-29T09:06:05Z',
tx_hash: null,
type: 'consensus_accounts.undelegate_done',
layer: 'sapphire',
network: 'testnet',
},
],
} satisfies Partial<RuntimeEventList>),
})
})
],
} satisfies Partial<RuntimeEventList>),
})
},
)

await page.goto(
'http://localhost:1234/mainnet/sapphire/address/0x0000000000000000000000000000000000000000/events',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { FC } from 'react'
import { SearchScope } from '../../../types/searchScope'
import { RuntimeEvent } from '../../../oasis-nexus/api'
import { TablePagination, TablePaginationProps } from '../Table/TablePagination'
import { AddressSwitchOption } from '../AddressSwitch'
import { useTranslation } from 'react-i18next'
import { CardEmptyState } from '../CardEmptyState'
import { TextSkeleton } from '../Skeleton'
import { RuntimeEventDetails } from './RuntimeEventDetails'
import Box from '@mui/material/Box'
import Divider from '@mui/material/Divider'

const RuntimeEventDetailsWithSeparator: FC<{
Expand All @@ -28,7 +30,8 @@ export const RuntimeEventsDetailedList: FC<{
isLoading: boolean
isError: boolean
addressSwitchOption: AddressSwitchOption
}> = ({ scope, events, isLoading, isError, addressSwitchOption }) => {
pagination: false | TablePaginationProps
}> = ({ scope, events, isLoading, isError, addressSwitchOption, pagination }) => {
const { t } = useTranslation()
return (
<>
Expand All @@ -44,6 +47,11 @@ export const RuntimeEventsDetailedList: FC<{
addressSwitchOption={addressSwitchOption}
/>
))}
{pagination && (
<Box sx={{ display: 'flex', justifyContent: 'center' }}>
<TablePagination {...pagination} />
</Box>
)}
</>
)
}
23 changes: 20 additions & 3 deletions src/app/components/Transactions/TransactionEvents.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { FC } from 'react'
import { Layer, RuntimeTransaction, useGetRuntimeEvents } from '../../../oasis-nexus/api'
import { NUMBER_OF_ITEMS_ON_SEPARATE_PAGE as limit } from '../../config'
import { useSearchParamsPagination } from '../../components/Table/useSearchParamsPagination'
import { AppErrors } from '../../../types/errors'
import { AddressSwitchOption } from '../AddressSwitch'
import { RuntimeEventsDetailedList } from '../RuntimeEvents/RuntimeEventsDetailedList'
Expand All @@ -9,21 +11,36 @@ export const TransactionEvents: FC<{
addressSwitchOption: AddressSwitchOption
}> = ({ transaction, addressSwitchOption }) => {
const { network, layer } = transaction
const pagination = useSearchParamsPagination('page')
const offset = (pagination.selectedPage - 1) * limit
if (layer === Layer.consensus) {
throw AppErrors.UnsupportedLayer
}
const eventsQuery = useGetRuntimeEvents(network, layer, {
tx_hash: transaction.hash,
limit: 100, // We want to avoid pagination here, if possible
Copy link
Contributor Author

@buberdds buberdds Jul 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we want to avoid pagination and why we set 100 cap?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related: #226

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤷 I can't find an explanation. 1000 limit was allowed when #224 was made

limit,
offset,
})
const { isLoading, data, isError } = eventsQuery
const { isFetched, isLoading, data, isError } = eventsQuery
const events = data?.data.events
if (isFetched && pagination.selectedPage > 1 && !events?.length) {
throw AppErrors.PageDoesNotExist
}

return (
<RuntimeEventsDetailedList
scope={transaction}
events={data?.data?.events}
events={events}
isLoading={isLoading}
isError={isError}
addressSwitchOption={addressSwitchOption}
pagination={{
selectedPage: pagination.selectedPage,
linkToPage: pagination.linkToPage,
totalCount: data?.data.total_count,
isTotalCountClipped: data?.data.is_total_count_clipped,
rowsPerPage: limit,
}}
/>
)
}
13 changes: 12 additions & 1 deletion src/app/pages/RuntimeAccountDetailsPage/AccountEventsCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Card from '@mui/material/Card'
import CardHeader from '@mui/material/CardHeader'
import CardContent from '@mui/material/CardContent'
import { useTranslation } from 'react-i18next'
import { NUMBER_OF_ITEMS_ON_SEPARATE_PAGE as limit } from '../../config'
import { RuntimeEventsDetailedList } from '../../components/RuntimeEvents/RuntimeEventsDetailedList'
import { AddressSwitchOption } from '../../components/AddressSwitch'
import { ErrorBoundary } from '../../components/ErrorBoundary'
Expand All @@ -14,7 +15,10 @@ export const eventsContainerId = 'events'

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

return (
<Card>
Expand All @@ -29,6 +33,13 @@ export const AccountEventsCard: FC<RuntimeAccountDetailsContext> = ({ scope, add
isLoading={isLoading}
isError={isError}
addressSwitchOption={AddressSwitchOption.ETH} // TODO
pagination={{
selectedPage: pagination.selectedPage,
linkToPage: pagination.linkToPage,
totalCount,
isTotalCountClipped,
rowsPerPage: limit,
}}
/>
</ErrorBoundary>
</CardContent>
Expand Down
20 changes: 16 additions & 4 deletions src/app/pages/RuntimeAccountDetailsPage/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from '../../../oasis-nexus/api'
import { AppErrors } from '../../../types/errors'
import { useSearchParamsPagination } from '../../components/Table/useSearchParamsPagination'
import { NUMBER_OF_ITEMS_ON_SEPARATE_PAGE } from '../../config'
import { NUMBER_OF_ITEMS_ON_SEPARATE_PAGE as limit } from '../../config'
import { SearchScope } from '../../../types/searchScope'
import { getOasisAddressOrNull } from '../../utils/helpers'

Expand All @@ -27,7 +27,7 @@ export const useAccount = (scope: SearchScope, address: string) => {
export const useAccountTransactions = (scope: SearchScope, address: string) => {
const { network, layer } = scope
const pagination = useSearchParamsPagination('page')
const offset = (pagination.selectedPage - 1) * NUMBER_OF_ITEMS_ON_SEPARATE_PAGE
const offset = (pagination.selectedPage - 1) * limit
if (layer === Layer.consensus) {
throw AppErrors.UnsupportedLayer
// Loading transactions on the consensus layer is not supported yet.
Expand All @@ -39,7 +39,7 @@ export const useAccountTransactions = (scope: SearchScope, address: string) => {
network,
layer, // This is OK since consensus has been handled separately
{
limit: NUMBER_OF_ITEMS_ON_SEPARATE_PAGE,
limit,
offset: offset,
rel: oasisAddress!,
},
Expand Down Expand Up @@ -71,6 +71,8 @@ export const useAccountTransactions = (scope: SearchScope, address: string) => {

export const useAccountEvents = (scope: SearchScope, address: string) => {
const { network, layer } = scope
const pagination = useSearchParamsPagination('page')
const offset = (pagination.selectedPage - 1) * limit
if (layer === Layer.consensus) {
throw AppErrors.UnsupportedLayer
// Loading events on the consensus layer is not supported yet.
Expand All @@ -82,6 +84,8 @@ export const useAccountEvents = (scope: SearchScope, address: string) => {
network,
layer,
{
limit,
offset: offset,
rel: oasisAddress!,
// TODO: implement filtering for non-transactional events
},
Expand All @@ -93,5 +97,13 @@ export const useAccountEvents = (scope: SearchScope, address: string) => {
)
const { isFetched, isLoading, isError, data } = query
const events = data?.data.events
return { isFetched, isLoading, isError, events }

if (isFetched && pagination.selectedPage > 1 && !events?.length) {
throw AppErrors.PageDoesNotExist
buberdds marked this conversation as resolved.
Show resolved Hide resolved
}

const totalCount = data?.data.total_count
const isTotalCountClipped = data?.data.is_total_count_clipped

return { isFetched, isLoading, isError, events, pagination, totalCount, isTotalCountClipped }
}
14 changes: 13 additions & 1 deletion src/app/pages/RuntimeBlockDetailPage/BlockEventsCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ 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 { NUMBER_OF_ITEMS_ON_SEPARATE_PAGE as limit } from '../../config'
import { useSearchParamsPagination } from '../../components/Table/useSearchParamsPagination'
import { ErrorBoundary } from '../../components/ErrorBoundary'
import { AppErrors } from '../../../types/errors'
import { RuntimeEventsDetailedList } from '../../components/RuntimeEvents/RuntimeEventsDetailedList'
Expand All @@ -16,6 +18,8 @@ export const eventsContainerId = 'events'

const EventsList: FC<RuntimeBlockDetailsContext> = ({ scope, blockHeight }) => {
const { t } = useTranslation()
const pagination = useSearchParamsPagination('page')
const offset = (pagination.selectedPage - 1) * limit
if (scope.layer === Layer.consensus) {
// Loading events for consensus blocks is not yet supported.
// Should use useGetConsensusEvents()
Expand All @@ -24,7 +28,8 @@ const EventsList: FC<RuntimeBlockDetailsContext> = ({ scope, blockHeight }) => {
const eventsQuery = useGetRuntimeEvents(scope.network, scope.layer, {
block: blockHeight,
// TODO: search for tx_hash = null
limit: 100, // We want to avoid pagination here, if possible
limit,
offset,
})

const { isLoading, isError, data } = eventsQuery
Expand All @@ -48,6 +53,13 @@ const EventsList: FC<RuntimeBlockDetailsContext> = ({ scope, blockHeight }) => {
isLoading={isLoading}
isError={isError}
addressSwitchOption={AddressSwitchOption.ETH}
pagination={{
selectedPage: pagination.selectedPage,
linkToPage: pagination.linkToPage,
totalCount: data?.data.total_count,
isTotalCountClipped: data?.data.is_total_count_clipped,
rowsPerPage: limit,
}}
/>
)
}
Expand Down
Loading