Skip to content

Commit

Permalink
Table pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
quietbits committed Jan 13, 2025
1 parent 7cd144f commit 5776c65
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,16 @@ export const ContractInfo = ({
infoData: ContractInfoApiResponse;
networkId: NetworkType;
}) => {
const [activeTab, setActiveTab] = useState("contract-version-history");
type ContractTabId =
| "contract-bindings"
| "contract-contract-info"
| "contract-source-code"
| "contract-contract-storage"
| "contract-version-history";

const [activeTab, setActiveTab] = useState<ContractTabId>(
"contract-version-history",
);

type ContractExplorerInfoField = {
id: string;
Expand Down Expand Up @@ -242,6 +251,7 @@ export const ContractInfo = ({
label: "Contract Storage",
content: (
<ContractStorage
isActive={activeTab === "contract-contract-storage"}
contractId={infoData.contract}
networkId={networkId}
totalEntriesCount={infoData.storage_entries}
Expand All @@ -253,14 +263,15 @@ export const ContractInfo = ({
label: "Version History",
content: (
<VersionHistory
isActive={activeTab === "contract-version-history"}
contractId={infoData.contract}
networkId={networkId}
/>
),
}}
activeTabId={activeTab}
onTabChange={(tabId) => {
setActiveTab(tabId);
setActiveTab(tabId as ContractTabId);
}}
/>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ import { capitalizeString } from "@/helpers/capitalizeString";
import { ContractStorageResponseItem, NetworkType } from "@/types/types";

export const ContractStorage = ({
isActive,
contractId,
networkId,
totalEntriesCount,
}: {
isActive: boolean;
contractId: string;
networkId: NetworkType;
totalEntriesCount: number | undefined;
Expand All @@ -28,6 +30,7 @@ export const ContractStorage = ({
isLoading: isStorageLoading,
isFetching: isStorageFetching,
} = useSEContractStorage({
isActive,
networkId,
contractId,
totalEntriesCount,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import { formatEpochToDate } from "@/helpers/formatEpochToDate";
import { ContractVersionHistoryResponseItem, NetworkType } from "@/types/types";

export const VersionHistory = ({
isActive,
contractId,
networkId,
}: {
isActive: boolean;
contractId: string;
networkId: NetworkType;
}) => {
Expand All @@ -22,6 +24,7 @@ export const VersionHistory = ({
isLoading: isVersionHistoryLoading,
isFetching: isVersionHistoryFetching,
} = useSEContractVersionHistory({
isActive,
networkId,
contractId,
});
Expand Down
83 changes: 80 additions & 3 deletions src/components/DataTable/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState } from "react";
import { Card, Icon } from "@stellar/design-system";
import { useEffect, useState } from "react";
import { Button, Card, Icon } from "@stellar/design-system";
import { Box } from "@/components/layout/Box";
import { DataTableCell, DataTableHeader, SortDirection } from "@/types/types";

Expand All @@ -18,9 +18,21 @@ export const DataTable = <T,>({
tableData: T[];
formatDataRow: (item: T) => DataTableCell[];
}) => {
const PAGE_SIZE = 10;
const tableDataSize = tableData.length;

// Sort by
const [sortById, setSortById] = useState("");
const [sortByDir, setSortByDir] = useState<SortDirection>("default");

// Pagination
const [currentPage, setCurrentPage] = useState(1);
const [totalPageCount, setTotalPageCount] = useState(1);

useEffect(() => {
setTotalPageCount(Math.ceil(tableDataSize / PAGE_SIZE));
}, [tableDataSize]);

const getSortByProps = (th: DataTableHeader) => {
if (th.isSortable) {
return {
Expand Down Expand Up @@ -52,11 +64,13 @@ export const DataTable = <T,>({

setSortById(headerId);
setSortByDir(sortDir);
setCurrentPage(1);
};

const tableRowsData = (): DataTableCell[][] => {
let sortedData = [...tableData];

// Sort
if (sortById) {
if (["asc", "desc"].includes(sortByDir)) {
// Asc
Expand All @@ -74,12 +88,26 @@ export const DataTable = <T,>({
return sortedData.map(formatDataRow);
};

const paginateData = (data: DataTableCell[][]): DataTableCell[][] => {
if (!data || data.length === 0) {
return [];
}

const startIndex = Math.max(currentPage - 1, 0) * PAGE_SIZE;
const endIndex = startIndex + PAGE_SIZE;

return data.slice(startIndex, endIndex);
};

const customStyle = {
"--DataTable-grid-template-columns": cssGridTemplateColumns,
} as React.CSSProperties;

const displayData = paginateData(tableRowsData());

return (
<Box gap="md">
{/* Table */}
<Card noPadding={true}>
<div className="DataTable__container">
<div className="DataTable__scroll">
Expand All @@ -104,7 +132,7 @@ export const DataTable = <T,>({
</tr>
</thead>
<tbody>
{tableRowsData().map((row, rowIdx) => {
{displayData.map((row, rowIdx) => {
const rowKey = `${tableId}-row-${rowIdx}`;

return (
Expand All @@ -131,6 +159,55 @@ export const DataTable = <T,>({
</div>
</div>
</Card>

<Box gap="lg" direction="row" align="center" justify="end">
{/* Pagination */}
<Box gap="xs" direction="row" align="center">
<Button
variant="tertiary"
size="sm"
onClick={() => {
setCurrentPage(1);
}}
disabled={currentPage === 1}
>
First
</Button>

<Button
variant="tertiary"
size="sm"
icon={<Icon.ArrowLeft />}
onClick={() => {
setCurrentPage(currentPage - 1);
}}
disabled={currentPage === 1}
></Button>

<div className="DataTable__pagination">{`Page ${currentPage} of ${totalPageCount}`}</div>

<Button
variant="tertiary"
size="sm"
icon={<Icon.ArrowRight />}
onClick={() => {
setCurrentPage(currentPage + 1);
}}
disabled={currentPage === totalPageCount}
></Button>

<Button
variant="tertiary"
size="sm"
onClick={() => {
setCurrentPage(totalPageCount);
}}
disabled={currentPage === totalPageCount}
>
Last
</Button>
</Box>
</Box>
</Box>
);
};
11 changes: 11 additions & 0 deletions src/components/DataTable/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,15 @@
}
}
}

&__pagination {
background-color: var(--sds-clr-gray-01);
border-radius: pxToRem(4px);
border: 1px solid var(--sds-clr-gray-06);
padding: pxToRem(3px) pxToRem(8px);
font-size: pxToRem(12px);
line-height: pxToRem(18px);
font-weight: var(--sds-fw-semi-bold);
color: var(--sds-clr-gray-12);
}
}
6 changes: 5 additions & 1 deletion src/query/external/useSEContracStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import { ContractStorageResponseItem, NetworkType } from "@/types/types";
* StellarExpert API to get smart contract’s storage data
*/
export const useSEContractStorage = ({
isActive,
networkId,
contractId,
totalEntriesCount,
}: {
isActive: boolean;
networkId: NetworkType;
contractId: string;
totalEntriesCount: number | undefined;
Expand Down Expand Up @@ -71,7 +73,9 @@ export const useSEContractStorage = ({
throw `Something went wrong. ${e}`;
}
},
enabled: Boolean(networkId && contractId),
enabled: Boolean(isActive && networkId && contractId),
// Keep data for 30 seconds
staleTime: 1000 * 30,
});

return query;
Expand Down
6 changes: 5 additions & 1 deletion src/query/external/useSEContractVersionHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import { ContractVersionHistoryResponseItem, NetworkType } from "@/types/types";
* StellarExpert API to get smart contract’s version history
*/
export const useSEContractVersionHistory = ({
isActive,
networkId,
contractId,
}: {
isActive: boolean;
networkId: NetworkType;
contractId: string;
}) => {
Expand Down Expand Up @@ -38,7 +40,9 @@ export const useSEContractVersionHistory = ({
throw `Something went wrong. ${e}`;
}
},
enabled: Boolean(networkId && contractId),
enabled: Boolean(isActive && networkId && contractId),
// Keep data for 30 seconds
staleTime: 1000 * 30,
});

return query;
Expand Down

0 comments on commit 5776c65

Please sign in to comment.