Skip to content

Commit

Permalink
feat(bridge-ui): add transaction list pagination (#13586)
Browse files Browse the repository at this point in the history
Co-authored-by: Francisco Ramos <jscriptcoder@gmail.com>
  • Loading branch information
shadab-taiko and jscriptcoder committed Apr 14, 2023
1 parent c86f2cd commit a3b7498
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 13 deletions.
22 changes: 17 additions & 5 deletions packages/bridge-ui/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,16 @@
import { CustomTokenService } from './storage/CustomTokenService';
import { userTokens, tokenService } from './store/userToken';
import { RelayerAPIService } from './relayer-api/RelayerAPIService';
import type { RelayerAPI } from './domain/relayerApi';
import { relayerApi, relayerBlockInfoMap } from './store/relayerApi';
import {
DEFAULT_PAGE,
MAX_PAGE_SIZE,
type RelayerAPI,
} from './domain/relayerApi';
import {
paginationInfo,
relayerApi,
relayerBlockInfoMap,
} from './store/relayerApi';
import { chains, mainnetWagmiChain, taikoWagmiChain } from './chain/chains';
import { providers } from './provider/providers';
import { RELAYER_URL } from './constants/envVars';
Expand Down Expand Up @@ -91,9 +99,13 @@
if (store) {
const userAddress = await store.getAddress();
const apiTxs = await $relayerApi.getAllBridgeTransactionByAddress(
userAddress,
);
const { txs: apiTxs, paginationInfo: info } =
await $relayerApi.getAllBridgeTransactionByAddress(userAddress, {
page: DEFAULT_PAGE,
size: MAX_PAGE_SIZE,
});
paginationInfo.set(info);
const blockInfoMap = await $relayerApi.getBlockInfo();
relayerBlockInfoMap.set(blockInfoMap);
Expand Down
93 changes: 93 additions & 0 deletions packages/bridge-ui/src/components/Pagination.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<script lang="ts">
export let totalPages: number;
export let page: number;
const DISABLED_BUTTON_LABEL = '...';
function getPageButtons(pages: number) {
if (pages <= 5) {
return new Array(pages).fill(0).map((_, index) => ({
label: index + 1,
onClick: () => (page = index + 1),
value: index + 1,
}));
} else {
return [
{
label: 1,
onClick: () => (page = 1),
value: 1,
},
{
label: 2,
onClick: () => (page = 2),
value: 2,
},
{
label: DISABLED_BUTTON_LABEL,
onClick: () => {
// do nothing
},
},
{
label: pages - 1,
onClick: () => (page = pages - 2),
value: pages - 1,
},
{
label: pages,
onClick: () => (page = pages - 1),
value: pages,
},
];
}
}
function makeButtons(pages) {
return [
{
label: '<<',
onClick: () => (page = 1),
},
{
label: '<',
onClick: () => {
if (page > 1) {
page -= 1;
}
},
},
...getPageButtons(pages),
{
label: '>',
onClick: () => {
if (page < totalPages) {
page += 1;
}
},
},
{
label: '>>',
onClick: () => (page = pages),
},
];
}
$: buttons = makeButtons(totalPages);
</script>

<div class="btn-group pagination justify-center mt-4">
{#each buttons as button}
<button
class={`btn btn-xs md:btn-md ${
button.value === page ? 'btn-active text-white' : ''
} ${button.label === DISABLED_BUTTON_LABEL ? 'btn-disabled' : ''}`}
on:click={button.onClick}>{button.label}</button>
{/each}
</div>

<style>
.pagination .btn-active {
color: white;
background-color: hsla(var(--af) / var(--tw-bg-opacity, 1));
}
</style>
41 changes: 39 additions & 2 deletions packages/bridge-ui/src/components/Transactions/Transactions.svelte
Original file line number Diff line number Diff line change
@@ -1,20 +1,56 @@
<script lang="ts">
import { transactions } from '../../store/transactions';
import { signer } from '../../store/signer';
import { relayerApi, paginationInfo } from '../../store/relayerApi';
import Transaction from './Transaction.svelte';
import TransactionDetail from './TransactionDetail.svelte';
import MessageStatusTooltip from './MessageStatusTooltip.svelte';
import InsufficientBalanceTooltip from './InsufficientBalanceTooltip.svelte';
import type { BridgeTransaction } from '../../domain/transactions';
import NoticeModal from '../modals/NoticeModal.svelte';
import Pagination from '../Pagination.svelte';
import { MAX_PAGE_SIZE } from '../../domain/relayerApi';
let selectedTransaction: BridgeTransaction;
let showMessageStatusTooltip: boolean;
let showInsufficientBalance: boolean;
let noticeModal: NoticeModal;
let page = 1;
let size = 10;
$: totalPagesInTransactionList = $paginationInfo
? Math.ceil($paginationInfo?.total / size)
: 0;
$: transactionsToShow = $transactions.slice(
(page - 1) * size,
(page - 1) * size + size,
);
async function loadMoreTransactionsFromAPI() {
if ($paginationInfo.page + 1 >= $paginationInfo.max_page) {
return;
}
const userAddress = await $signer.getAddress();
const { txs: apiTxs, paginationInfo: info } =
await $relayerApi.getAllBridgeTransactionByAddress(userAddress, {
page: $paginationInfo.page + 1,
size: MAX_PAGE_SIZE,
});
paginationInfo.set(info);
transactions.set([...$transactions, ...apiTxs]);
}
$: {
if ($transactions.length > 0 && (page + 1) * size > $transactions.length) {
loadMoreTransactionsFromAPI();
}
}
</script>

<div class="my-4 md:px-4">
{#if $transactions.length}
{#if transactionsToShow.length}
<table class="table-auto">
<thead>
<tr class="text-transaction-table">
Expand All @@ -26,7 +62,7 @@
</tr>
</thead>
<tbody class="text-sm md:text-base">
{#each $transactions as transaction (transaction.hash)}
{#each transactionsToShow as transaction (transaction.hash)}
<Transaction
on:claimNotice={({ detail }) => noticeModal.open(detail)}
on:tooltipStatus={() => (showMessageStatusTooltip = true)}
Expand All @@ -38,6 +74,7 @@
{/each}
</tbody>
</table>
<Pagination totalPages={totalPagesInTransactionList} bind:page />
{:else}
No transactions
{/if}
Expand Down
21 changes: 20 additions & 1 deletion packages/bridge-ui/src/domain/relayerApi.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
import type { Address, ChainID } from './chain';
import type { BridgeTransaction } from './transactions';

export const MAX_PAGE_SIZE = 100;
export const DEFAULT_PAGE = 0;

export type GetAllByAddressResponse = {
txs: BridgeTransaction[];
paginationInfo: PaginationInfo;
};

export type PaginationParams = {
size: typeof MAX_PAGE_SIZE;
page: number;
};

export interface RelayerAPI {
getAllBridgeTransactionByAddress(
address: string,
pagination: PaginationParams,
chainID?: number,
): Promise<BridgeTransaction[]>;
): Promise<GetAllByAddressResponse>;

getBlockInfo(): Promise<Map<number, RelayerBlockInfo>>;
}
Expand Down Expand Up @@ -71,3 +85,8 @@ export type APIResponse = {
first: boolean;
visible: number;
};

export type PaginationInfo = Pick<
APIResponse,
'page' | 'size' | 'max_page' | 'total_pages' | 'total' | 'last' | 'first'
>;
21 changes: 18 additions & 3 deletions packages/bridge-ui/src/relayer-api/RelayerAPIService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import type {
APIRequestParams,
APIResponse,
APIResponseTransaction,
GetAllByAddressResponse,
PaginationInfo,
PaginationParams,
RelayerAPI,
RelayerBlockInfo,
} from '../domain/relayerApi';
Expand Down Expand Up @@ -46,8 +49,9 @@ export class RelayerAPIService implements RelayerAPI {

async getAllBridgeTransactionByAddress(
address: string,
paginationParams: PaginationParams,
chainID?: number,
): Promise<BridgeTransaction[]> {
): Promise<GetAllByAddressResponse> {
if (!address) {
throw new Error('Address need to passed to fetch transactions');
}
Expand All @@ -56,12 +60,23 @@ export class RelayerAPIService implements RelayerAPI {
address,
chainID,
event: 'MessageSent',
...paginationParams,
};

const apiTxs: APIResponse = await this.getTransactionsFromAPI(params);

const paginationInfo: PaginationInfo = {
page: apiTxs.page,
size: apiTxs.size,
total: apiTxs.total,
total_pages: apiTxs.total_pages,
first: apiTxs.first,
last: apiTxs.last,
max_page: apiTxs.max_page,
};

if (apiTxs?.items?.length === 0) {
return [];
return { txs: [], paginationInfo };
}

apiTxs.items.map((t, i) => {
Expand Down Expand Up @@ -193,7 +208,7 @@ export class RelayerAPIService implements RelayerAPI {

bridgeTxs.reverse();
bridgeTxs.sort((tx) => (tx.status === MessageStatus.New ? -1 : 1));
return bridgeTxs;
return { txs: bridgeTxs, paginationInfo };
}

async getBlockInfo(): Promise<Map<number, RelayerBlockInfo>> {
Expand Down
9 changes: 7 additions & 2 deletions packages/bridge-ui/src/store/relayerApi.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import type { RelayerAPI, RelayerBlockInfo } from '../domain/relayerApi';
import type {
PaginationInfo,
RelayerAPI,
RelayerBlockInfo,
} from '../domain/relayerApi';
import { writable } from 'svelte/store';

const relayerApi = writable<RelayerAPI>();
const relayerBlockInfoMap = writable<Map<number, RelayerBlockInfo>>();
const paginationInfo = writable<PaginationInfo>();

export { relayerApi, relayerBlockInfoMap };
export { relayerApi, relayerBlockInfoMap, paginationInfo };

0 comments on commit a3b7498

Please sign in to comment.