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

feat: use pagination in transaction inputs/outputs list #188

Closed
wants to merge 12 commits into from
11 changes: 11 additions & 0 deletions src/components/Pagination/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.pageSize {
margin: 0 10px;
}

.pageSizeInput {
border-radius: 4px;
border: none;
width: 40px;
background: #f5f5f5;
padding: 4px 10px;
}
39 changes: 37 additions & 2 deletions src/components/Pagination/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,31 @@ import RightGrey from './pagination_grey_right.png'
import { useIsMobile } from '../../hooks'
import SimpleButton from '../SimpleButton'
import { HelpTip } from '../HelpTip'
import styles from './index.module.scss'

const Pagination = ({
currentPage,
totalPages,
gotoPage = currentPage === totalPages ? totalPages : currentPage + 1,
onChange,
onPageNumberChange: onChange,
onPageSizeChange,
pageSize = 10,
className,
annotation,
}: {
currentPage: number
pageSize?: number
totalPages: number
gotoPage?: number
onChange: (page: number) => void
onPageNumberChange: (pageNumber: number) => void
onPageSizeChange?: (pageSize: number) => void
className?: string
annotation?: string
}) => {
const isMobile = useIsMobile()
const { t } = useTranslation()
const [inputPage, setInputPage] = useState(gotoPage)
const [inputPageSize, setInputPageSize] = useState(pageSize)

const total = Math.max(totalPages, 1)
const current = Math.min(Math.max(currentPage, 1), totalPages)
Expand All @@ -45,6 +51,13 @@ const Pagination = ({
}
}

const changePageSize = (pageSize: number) => {
if (onPageSizeChange) {
onPageSizeChange(pageSize)
}
setInputPageSize(pageSize)
}

return (
<PaginationPanel className={className}>
<PaginationLeftItem isFirstPage={current === 1} isLastPage={current === total}>
Expand Down Expand Up @@ -74,6 +87,28 @@ const Pagination = ({
<SimpleButton className="paginationLastButton" onClick={() => changePage(total)}>
{t('pagination.last')}
</SimpleButton>
{!isMobile && (
<>
<span className={styles.pageSize}>{t('pagination.page_size')}</span>
<input
type="text"
pattern="[0-9]*"
className={styles.pageSizeInput}
value={inputPageSize}
onChange={event => {
const value = parseInt(event.target.value, 10)
if (!Number.isNaN(value)) {
setInputPageSize(value)
}
}}
onKeyUp={event => {
if (event.keyCode === 13) {
changePageSize(inputPageSize)
}
}}
/>
</>
)}
</PaginationLeftItem>
<PaginationRightItem>
<span className="paginationPageLabel">{t('pagination.page')}</span>
Expand Down
8 changes: 7 additions & 1 deletion src/components/PaginationWithRear/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ const PaginationWithRear = ({
totalPages,
onChange,
paginationClassName,
onPageSizeChange,
pageSize,
rear,
}: {
currentPage: number
totalPages: number
pageSize?: number
onChange: (page: number) => void
onPageSizeChange?: (pageSize: number) => void
paginationClassName?: string
rear: ReactNode
}) => {
Expand All @@ -22,7 +26,9 @@ const PaginationWithRear = ({
<Pagination
currentPage={currentPage}
totalPages={totalPages}
onChange={onChange}
pageSize={pageSize}
onPageSizeChange={onPageSizeChange}
onPageNumberChange={onChange}
className={classNames(styles.pagination, paginationClassName)}
/>
)}
Expand Down
3 changes: 2 additions & 1 deletion src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,8 @@
"end_page": "",
"current_page": "Page",
"of_page": "of",
"only_first_pages_visible": "Showing first {{pages}} pages"
"only_first_pages_visible": "Showing first {{pages}} pages",
"page_size": "Size"
},
"udt": {
"sudt": "sUDT",
Expand Down
3 changes: 2 additions & 1 deletion src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,8 @@
"end_page": "页",
"current_page": "第",
"of_page": "页,共",
"only_first_pages_visible": "显示最近 {{pages}} 页"
"only_first_pages_visible": "显示最近 {{pages}} 页",
"page_size": "每页"
},
"udt": {
"sudt": "sUDT",
Expand Down
2 changes: 1 addition & 1 deletion src/pages/BlockDetail/BlockComp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ export const BlockComp = ({
)}
{totalPages > 1 && (
<BlockTransactionsPagination>
<Pagination currentPage={currentPage} totalPages={totalPages} onChange={onPageChange} />
<Pagination currentPage={currentPage} totalPages={totalPages} onPageNumberChange={onPageChange} />
</BlockTransactionsPagination>
)}
</>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/NervosDao/DaoTransactions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export default ({
)}
{totalPages > 1 && (
<TransactionsPagination>
<Pagination currentPage={currentPage} totalPages={totalPages} onChange={onPageChange} />
<Pagination currentPage={currentPage} totalPages={totalPages} onPageNumberChange={onPageChange} />
</TransactionsPagination>
)}
</>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/NftCollectionInfo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,14 @@ const NftCollectionInfo = () => {
<Pagination
currentPage={+page}
totalPages={Math.ceil((holderList?.length ?? 0) / PAGE_SIZE) ?? 1}
onChange={handlePageChange}
onPageNumberChange={handlePageChange}
/>
</>
) : null}
{tab === tabs[2] ? (
<>
<NftCollectionInventory collection={id} list={inventoryList?.data ?? []} isLoading={isInventoryLoading} />
<Pagination {...pages} onChange={handlePageChange} />
<Pagination {...pages} onPageNumberChange={handlePageChange} />
</>
) : null}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/NftCollections/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const NftCollections = () => {
<Pagination
currentPage={data?.pagination.page ?? 1}
totalPages={data?.pagination.last ?? 1}
onChange={handlePageChange}
onPageNumberChange={handlePageChange}
/>
</div>
</Content>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/NftInfo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ const NftInfo = () => {
<Pagination
currentPage={transferListRes?.pagination.page ?? 1}
totalPages={transferListRes?.pagination.last ?? 1}
onChange={handlePageChange}
onPageNumberChange={handlePageChange}
/>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Script/ScriptsComp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const ScriptTransactions = ({ page, size }: { page: number; size: number
</div>
{totalPages > 1 && (
<div className={styles.scriptPagination}>
<Pagination currentPage={page} totalPages={totalPages} onChange={onChange} />
<Pagination currentPage={page} totalPages={totalPages} onPageNumberChange={onChange} />
</div>
)}
</>
Expand Down Expand Up @@ -217,7 +217,7 @@ export const ScriptCells = ({
</div>
{totalPages > 1 && (
<div className={styles.scriptPagination}>
<Pagination currentPage={page} totalPages={totalPages} onChange={onChange} />
<Pagination currentPage={page} totalPages={totalPages} onPageNumberChange={onChange} />
</div>
)}
</>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Tokens/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export default () => {
)}
</QueryResult>

<Pagination currentPage={currentPage} totalPages={totalPages} onChange={setPage} />
<Pagination currentPage={currentPage} totalPages={totalPages} onPageNumberChange={setPage} />
</TokensPanel>
</Content>
)
Expand Down
9 changes: 8 additions & 1 deletion src/pages/Transaction/TransactionCellList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ export default ({
outputs,
txHash,
showReward,
total,
indiceOffset,
}: {
inputs?: Cell[]
outputs?: Cell[]
txHash?: string
showReward?: boolean
total?: number
indiceOffset?: number
Copy link
Member

Choose a reason for hiding this comment

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

How about loading offset from the url, the page_number and page_size parameters, and get the offset by (page_number - 1) * page_size

Copy link
Author

Choose a reason for hiding this comment

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

There are input_cells_page_size/number and output_page_size/number params, if offset is removed, then need to add another field like cell_input_output_type to distinguish them

Copy link
Member

Choose a reason for hiding this comment

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

In what case will the sizes of input cells and output cells be different? I didn't find an entry to update the size on the page.

Copy link
Author

Choose a reason for hiding this comment

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

43894e5 has added page size change for pagination component, but there is no design yet, I may change the appearance according to design, please have a look @Sven-TBD
image

Choose a reason for hiding this comment

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

Ya, we could add a drop box with some default options for the user @Kirl70 , like 5,10,15.

Copy link

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

I found the page size component exists in input list and output list, so their sizes are independent, am I right? @Sven-TBD

}) => {
const { t } = useTranslation()
const [offset, setOffset] = useState(PAGE_CELL_COUNT)
Expand Down Expand Up @@ -54,6 +58,9 @@ export default ({
const toggleDeprecatedAddressesDisplayed = () => setIsDeprecatedAddressesDisplayed(value => !value)

const cellsCount = () => {
if (total) {
return total
}
if (inputs) {
return inputs.length
}
Expand Down Expand Up @@ -99,7 +106,7 @@ export default ({
key={cell.id}
cell={cell}
cellType={inputs ? CellType.Input : CellType.Output}
index={index}
index={index + (indiceOffset || 0)}
txHash={txHash}
showReward={showReward}
isAddrNew={!isDeprecatedAddressesDisplayed}
Expand Down
104 changes: 100 additions & 4 deletions src/pages/Transaction/TransactionComp/TransactionComp.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { useQuery } from '@tanstack/react-query'
import { useHistory, useLocation } from 'react-router-dom'
import TransactionCellList from '../TransactionCellList'
import { Cell } from '../../../models/Cell'
import { Transaction } from '../../../models/Transaction'
import { explorerService } from '../../../services/ExplorerService'
import Pagination from '../../../components/Pagination'
import Loading from '../../../components/Loading'
import { useSearchParams } from '../../../hooks'

const handleCellbaseInputs = (inputs: Cell[], outputs: Cell[]) => {
if (inputs[0] && inputs[0].fromCellbase && outputs[0] && outputs[0].baseReward) {
Expand All @@ -18,18 +24,108 @@ const handleCellbaseInputs = (inputs: Cell[], outputs: Cell[]) => {
}

export const TransactionComp = ({ transaction }: { transaction: Transaction }) => {

Choose a reason for hiding this comment

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

Based on the requirements here: #177 (comment)

This component should not be modified to use pagination mode, as it would result in multiple pages making a large number of requests, as seen in #177.

Copy link
Author

Choose a reason for hiding this comment

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

this file is meant to be changed, I reverted src/components/TransactionItem/index.tsx

const { transactionHash, displayInputs, displayOutputs, blockNumber, isCellbase } = transaction
const DEFAULT_PAGE_SIZE = 10
const txHash = transaction.transactionHash
const location = useLocation()
const queryParams = new URLSearchParams(location.search)
const history = useHistory()

const inputs = handleCellbaseInputs(displayInputs, displayOutputs)
const {
inputCellsPageNumber = 1,
inputCellsPageSize = DEFAULT_PAGE_SIZE,
outputCellsPageNumber = 1,
outputCellsPageSize = DEFAULT_PAGE_SIZE,
} = useSearchParams('inputCellsPageNumber', 'inputCellsPageSize', 'outputCellsPageNumber', 'outputCellsPageSize')

const handleInputCellsPageChange = (page: number) => {
queryParams.set('inputCellsPageNumber', page.toString())
history.replace(`${location.pathname}?${queryParams.toString()}`)
}
const handleInputCellsPageSizeChange = (pageSize: number) => {
queryParams.set('inputCellsPageSize', pageSize.toString())
history.replace(`${location.pathname}?${queryParams.toString()}`)
}

const txInputsQuery = useQuery(['transactionInputs', txHash, inputCellsPageNumber, inputCellsPageSize], async () => {
const result = await explorerService.api.fetchTransactionInputsByHash(
txHash,
Number(inputCellsPageNumber),
Number(inputCellsPageSize),
)
return result
})
const handleOutputCellsPageChange = (page: number) => {
queryParams.set('outputCellsPageNumber', page.toString())
history.replace(`${location.pathname}?${queryParams.toString()}`)
}
const handleOutputCellsPageSizeChange = (pageSize: number) => {
queryParams.set('outputCellsPageSize', pageSize.toString())
history.replace(`${location.pathname}?${queryParams.toString()}`)
}

const txOutputsQuery = useQuery(
['transactionOutputs', txHash, outputCellsPageNumber, outputCellsPageSize],
async () => {
const result = await explorerService.api.fetchTransactionOutputsByHash(
txHash,
Number(outputCellsPageNumber),
Number(outputCellsPageSize),
)
// TODO: When will displayOutputs be empty? Its type description indicates that it will not be empty.
if (result.data.length > 0) {
result.data[0].isGenesisOutput = transaction.blockNumber === 0
}
return result
},
)

const { transactionHash, blockNumber, isCellbase } = transaction

const inputs = handleCellbaseInputs(
txInputsQuery.isSuccess ? txInputsQuery.data.data : [],
txOutputsQuery.isSuccess ? txOutputsQuery.data.data : [],
)

const totalInputsCount = txInputsQuery.data?.meta?.total ?? 0
const totalOutputsCount = txOutputsQuery.data?.meta?.total ?? 0
/// [0, 11] block doesn't show block reward and only cellbase show block reward
return (
<>
<div className="transactionInputs">
{inputs && <TransactionCellList inputs={inputs} showReward={blockNumber > 0 && isCellbase} />}
{txInputsQuery.isFetching && <Loading show />}
{inputs && (
<TransactionCellList
total={totalInputsCount}
inputs={inputs}
showReward={Number(blockNumber) > 0 && isCellbase}
indiceOffset={(Number(inputCellsPageNumber) - 1) * Number(inputCellsPageSize)}
/>
)}
<Pagination
currentPage={Number(inputCellsPageNumber)}
pageSize={Number(inputCellsPageSize)}
totalPages={txInputsQuery.isSuccess ? Math.ceil(totalInputsCount / Number(inputCellsPageSize)) : 1}
onPageNumberChange={handleInputCellsPageChange}
onPageSizeChange={handleInputCellsPageSizeChange}
/>
</div>
<div className="transactionOutputs">
{displayOutputs && <TransactionCellList outputs={displayOutputs} txHash={transactionHash} />}
{txOutputsQuery.isFetching && <Loading show />}
{txOutputsQuery.isSuccess && (
<TransactionCellList
total={totalOutputsCount}
outputs={txOutputsQuery.data.data}
txHash={transactionHash}
indiceOffset={(Number(outputCellsPageNumber) - 1) * Number(outputCellsPageSize)}
/>
)}
<Pagination
currentPage={Number(outputCellsPageNumber)}
pageSize={Number(outputCellsPageSize)}
totalPages={txOutputsQuery.isSuccess ? Math.ceil(totalOutputsCount / Number(outputCellsPageSize)) : 1}
onPageNumberChange={handleOutputCellsPageChange}
onPageSizeChange={handleOutputCellsPageSizeChange}
/>
</div>
</>
)
Expand Down
9 changes: 1 addition & 8 deletions src/pages/Transaction/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,7 @@ export default () => {
const { Professional, Lite } = LayoutLiteProfessional
const { hash: txHash } = useParams<{ hash: string }>()

const query = useQuery(['transaction', txHash], async () => {
const transaction = await explorerService.api.fetchTransactionByHash(txHash)
// TODO: When will displayOutputs be empty? Its type description indicates that it will not be empty.
if (transaction.displayOutputs && transaction.displayOutputs.length > 0) {
transaction.displayOutputs[0].isGenesisOutput = transaction.blockNumber === 0
}
return transaction
})
const query = useQuery(['transaction', txHash], async () => explorerService.api.fetchTransactionByHash(txHash))

const transaction = query.data ?? defaultTransactionInfo
const searchParams = useSearchParams('layout')
Expand Down
Loading