Skip to content

Commit

Permalink
Merge pull request #49 from omisego/paginate-transactions
Browse files Browse the repository at this point in the history
Paginate transactions
  • Loading branch information
nicholasmueller authored Apr 21, 2020
2 parents 1f3ef47 + eb43ffd commit 42a27ba
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 47 deletions.
47 changes: 47 additions & 0 deletions src/components/pager/Pager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
Copyright 2019-present OmiseGO Pte Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

import React from 'react';
import { NavigateNext, NavigateBefore } from '@material-ui/icons';

import * as styles from './Pager.module.scss';

function Pager ({ currentPage, isLastPage, onClickNext, onClickBack }) {
return (
<div className={styles.Pager}>
<span className={styles.number}>{`Page ${currentPage}`}</span>
<div
className={[
styles.box,
currentPage === 1 ? styles.disabled : ''
].join(' ')}
onClick={onClickBack}
>
<NavigateBefore className={styles.icon} />
</div>
<div
className={[
styles.box,
isLastPage ? styles.disabled : ''
].join(' ')}
onClick={onClickNext}
>
<NavigateNext className={styles.icon} />
</div>
</div>
);
}

export default Pager;
36 changes: 36 additions & 0 deletions src/components/pager/Pager.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@import 'index.scss';

.Pager {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
margin-bottom: 20px;

.number {
font-size: 12px;
margin-right: 10px;
}

.box {
display: flex;
align-items: center;
justify-content: center;
border-radius: 3px;
width: 50px;
height: 20px;
margin-left: 3px;
background-color: $darkgray;
transition: all 200ms ease-in-out;
cursor: pointer;
&:hover {
background-color: $midgray;
}
}

.disabled {
pointer-events: none;
cursor: initial;
opacity: 0.5;
}
}
26 changes: 23 additions & 3 deletions src/containers/transactions/Deposits.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,32 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

import React from 'react';
import React, { useState, useEffect } from 'react';
import { orderBy, isEqual } from 'lodash';
import { useSelector } from 'react-redux';
import truncate from 'truncate-middle';

import { selectEthDeposits, selectErc20Deposits } from 'selectors/transactionSelector';

import Transaction from 'components/transaction/Transaction';
import Pager from 'components/pager/Pager';

import config from 'util/config';
import { logAmount } from 'util/amountConvert';

import * as styles from './Transactions.module.scss';

const PER_PAGE = 10;

function Deposits ({ searchHistory }) {
const [ page, setPage ] = useState(1);
const ethDeposits = useSelector(selectEthDeposits, isEqual);
const erc20Deposits = useSelector(selectErc20Deposits, isEqual);

useEffect(() => {
setPage(1);
}, [ searchHistory ]);

const deposits = orderBy(
[...ethDeposits, ...erc20Deposits],
i => i.blockNumber, 'desc'
Expand All @@ -38,13 +47,24 @@ function Deposits ({ searchHistory }) {
return i.transactionHash.includes(searchHistory) || i.returnValues.token.includes(searchHistory);
});

const startingIndex = page === 1 ? 0 : ((page - 1) * PER_PAGE);
const endingIndex = page * PER_PAGE;
const paginatedDeposits = _deposits.slice(startingIndex, endingIndex);

return (
<div className={styles.transactionSection}>
<div className={styles.transactions}>
{!_deposits.length && (
<Pager
currentPage={page}
isLastPage={paginatedDeposits.length < PER_PAGE}
onClickNext={() => setPage(page + 1)}
onClickBack={() => setPage(page - 1)}
/>

{!paginatedDeposits.length && (
<div className={styles.disclaimer}>No deposit history.</div>
)}
{_deposits.map((i, index) => {
{paginatedDeposits.map((i, index) => {
return (
<Transaction
key={index}
Expand Down
100 changes: 60 additions & 40 deletions src/containers/transactions/Exits.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ import { selectPendingExits, selectExitedExits } from 'selectors/exitSelector';

import ProcessExitsModal from 'containers/modals/processexit/ProcessExitsModal';
import Transaction from 'components/transaction/Transaction';
import Pager from 'components/pager/Pager';

import * as styles from './Transactions.module.scss';

const PER_PAGE = 10;

function Exits ({ searchHistory }) {
const [ page, setPage ] = useState(1);
const [ processExitModal, setProcessExitModal ] = useState(false);

const queues = useSelector(selectAllQueues, isEqual);
Expand Down Expand Up @@ -66,10 +70,58 @@ function Exits ({ searchHistory }) {
const _pendingExits = enhanceExits(pendingExits).filter(i => {
return i.transactionHash.includes(searchHistory);
});

const _exitedExits = exitedExits.filter(i => {
return i.transactionHash.includes(searchHistory);
});

const renderPending = _pendingExits.map((i, index) => {
const exitableMoment = moment.unix(i.exitableAt);
const isExitable = moment().isAfter(exitableMoment);
return (
<Transaction
key={`pending-${index}`}
button={
isExitable
? {
onClick: () => setProcessExitModal(i),
text: 'Process Exit'
}
: undefined
}
link={`${config.etherscanUrl}/tx/${i.transactionHash}`}
status={
i.status === 'Confirmed' && i.pendingPercentage >= 100
? 'Challenge Period'
: i.status
}
subStatus={`Block ${i.blockNumber}`}
statusPercentage={i.pendingPercentage <= 100 ? i.pendingPercentage : ''}
title={truncate(i.transactionHash, 10, 4, '...')}
midTitle={i.exitableAt ? `Exitable ${exitableMoment.format('lll')}` : ''}
subTitle={i.currency ? truncate(i.currency, 10, 4, '...'): ''}
/>
);
});

const renderExited = _exitedExits.map((i, index) => {
return (
<Transaction
key={`exited-${index}`}
link={`${config.etherscanUrl}/tx/${i.transactionHash}`}
status='Exited'
subStatus={`Block ${i.blockNumber}`}
title={truncate(i.transactionHash, 10, 4, '...')}
/>
);
});

const allExits = [ ...renderPending, ...renderExited ];

const startingIndex = page === 1 ? 0 : ((page - 1) * PER_PAGE);
const endingIndex = page * PER_PAGE;
const paginatedExits = allExits.slice(startingIndex, endingIndex);

return (
<>
<ProcessExitsModal
Expand All @@ -81,48 +133,16 @@ function Exits ({ searchHistory }) {
<div className={styles.subTitle}>Exits</div>
<div className={styles.transactionSection}>
<div className={styles.transactions}>
{(!_pendingExits.length && !_exitedExits.length) && (
<Pager
currentPage={page}
isLastPage={paginatedExits.length < PER_PAGE}
onClickNext={() => setPage(page + 1)}
onClickBack={() => setPage(page - 1)}
/>
{!allExits.length && (
<div className={styles.disclaimer}>No exit history.</div>
)}
{_pendingExits.map((i, index) => {
const exitableMoment = moment.unix(i.exitableAt);
const isExitable = moment().isAfter(exitableMoment);
return (
<Transaction
key={index}
button={
isExitable
? {
onClick: () => setProcessExitModal(i),
text: 'Process Exit'
}
: undefined
}
link={`${config.etherscanUrl}/tx/${i.transactionHash}`}
status={
i.status === 'Confirmed' && i.pendingPercentage >= 100
? 'Challenge Period'
: i.status
}
subStatus={`Block ${i.blockNumber}`}
statusPercentage={i.pendingPercentage <= 100 ? i.pendingPercentage : ''}
title={truncate(i.transactionHash, 10, 4, '...')}
midTitle={i.exitableAt ? `Exitable ${exitableMoment.format('lll')}` : ''}
subTitle={i.currency ? truncate(i.currency, 10, 4, '...'): ''}
/>
);
})}
{_exitedExits.map((i, index) => {
return (
<Transaction
key={index}
link={`${config.etherscanUrl}/tx/${i.transactionHash}`}
status='Exited'
subStatus={`Block ${i.blockNumber}`}
title={truncate(i.transactionHash, 10, 4, '...')}
/>
);
})}
{React.Children.toArray(paginatedExits)}
</div>
</div>
</div>
Expand Down
29 changes: 25 additions & 4 deletions src/containers/transactions/Transactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,17 @@ import config from 'util/config';
import Tabs from 'components/tabs/Tabs';
import Input from 'components/input/Input';
import Transaction from 'components/transaction/Transaction';
import Pager from 'components/pager/Pager';

import Exits from './Exits';
import Deposits from './Deposits';

import * as styles from './Transactions.module.scss';

const PER_PAGE = 10;

function Transactions () {
const [ page, setPage ] = useState(1);
const [ searchHistory, setSearchHistory ] = useState('');
const [ activeTab, setActiveTab ] = useState('Transactions');

Expand All @@ -57,6 +61,10 @@ function Transactions () {
return i.txhash.includes(searchHistory) || i.metadata.toLowerCase().includes(searchHistory);
});

const startingIndex = page === 1 ? 0 : ((page - 1) * PER_PAGE);
const endingIndex = page * PER_PAGE;
const paginatedTransactions = _transactions.slice(startingIndex, endingIndex);

return (
<div className={styles.container}>
<div className={styles.header}>
Expand All @@ -65,25 +73,38 @@ function Transactions () {
icon
placeholder='Search history'
value={searchHistory}
onChange={i => setSearchHistory(i.target.value.toLowerCase())}
onChange={i => {
setPage(1);
setSearchHistory(i.target.value.toLowerCase());
}}
className={styles.searchBar}
/>
</div>

<div className={styles.data}>
<div className={styles.section}>
<Tabs
onClick={setActiveTab}
onClick={tab => {
setPage(1);
setActiveTab(tab);
}}
activeTab={activeTab}
tabs={[ 'Transactions', 'Deposits' ]}
/>

{activeTab === 'Transactions' && (
<div className={styles.transactions}>
{!_transactions.length && (
<Pager
currentPage={page}
isLastPage={paginatedTransactions.length < PER_PAGE}
onClickNext={() => setPage(page + 1)}
onClickBack={() => setPage(page - 1)}
/>

{!paginatedTransactions.length && (
<div className={styles.disclaimer}>No transaction history.</div>
)}
{_transactions.map((i, index) => {
{paginatedTransactions.map((i, index) => {
return (
<Transaction
key={index}
Expand Down

0 comments on commit 42a27ba

Please sign in to comment.