Skip to content

Commit

Permalink
feat(web): add filter panel with rollup filter in PaginatedTable
Browse files Browse the repository at this point in the history
  • Loading branch information
xFJA committed Aug 8, 2024
1 parent a299e04 commit a6e895a
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 6 deletions.
11 changes: 11 additions & 0 deletions apps/web/src/components/PaginatedTable/PaginatedTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import type { PaginationProps } from "~/components/Pagination";
import { Pagination } from "~/components/Pagination";
import type { TableProps } from "~/components/Table";
import { Table } from "~/components/Table";
import type { Rollup } from "~/types";
import { FilterPanel } from "./components/FilterPanel";

const DEFAULT_TABLE_EMPTY_STATE = "No items";
const PAGE_SIZES_OPTIONS: DropdownProps["options"] = [
Expand All @@ -21,6 +23,10 @@ const PAGE_SIZES_OPTIONS: DropdownProps["options"] = [
];
const DEFAULT_ROW_SKELETON_HEIGHT = 22;

export interface PaginatedTableQueryFilters {
rollup: Rollup;
}

type PaginationData = {
page: number;
pageSize: number;
Expand All @@ -33,6 +39,7 @@ export type PaginatedTableProps = {
isExpandable?: boolean;
paginationData: PaginationData;
rowSkeletonHeight?: string | number;
onFilter: (filters: PaginatedTableQueryFilters) => void;
} & Pick<TableProps, "headers" | "rows">;

const getRowsSkeleton = (
Expand All @@ -58,6 +65,7 @@ export const PaginatedTable: FC<PaginatedTableProps> = function ({
paginationData,
isExpandable = false,
rowSkeletonHeight = DEFAULT_ROW_SKELETON_HEIGHT,
onFilter,
}) {
const { page, pageSize } = paginationData;

Expand Down Expand Up @@ -120,6 +128,9 @@ export const PaginatedTable: FC<PaginatedTableProps> = function ({
emptyState={DEFAULT_TABLE_EMPTY_STATE}
>
<div className="flex flex-col gap-6">
<div className="w-1/2">
<FilterPanel onFilter={onFilter} />
</div>
<Table
fixedColumnsWidth={true}
expandableRowsMode={isExpandable}
Expand Down
45 changes: 45 additions & 0 deletions apps/web/src/components/PaginatedTable/components/FilterPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useState } from "react";
import type { FC } from "react";

import { Button } from "~/components/Button";
import type { Rollup } from "~/types";
import type { Option } from "../../Dropdown/Dropdown";
import type { PaginatedTableQueryFilters } from "../PaginatedTable";
import { RollupFilter } from "./RollupFilter";

interface FilterPanelState {
rollup: Option | null;
}

interface FilterPanelProps {
onFilter: (queryFilters: PaginatedTableQueryFilters) => void;
}

export const FilterPanel: FC<FilterPanelProps> = function ({ onFilter }) {
const [formData, setFormData] = useState<FilterPanelState>({
rollup: null,
});

const allowToFilter = !!formData.rollup;

const handleSubmit = () => {
!!formData.rollup && onFilter({ rollup: formData.rollup.value as Rollup });
};

const handleRollupFilterChange = (newRollup: Option) => {
setFormData((prevState) => ({ ...prevState, rollup: newRollup }));
};

return (
<form
className="flex justify-between rounded-lg bg-slate-50 p-2"
onSubmit={handleSubmit}
>
<RollupFilter
selected={formData.rollup}
onChange={handleRollupFilterChange}
/>
<Button label="Filter" onClick={handleSubmit} disabled={!allowToFilter} />
</form>
);
};
53 changes: 53 additions & 0 deletions apps/web/src/components/PaginatedTable/components/RollupFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { FC } from "react";

import { Dropdown } from "~/components/Dropdown/Dropdown";
import type { DropdownProps } from "~/components/Dropdown/Dropdown";
import { RollupIcon } from "~/components/RollupIcon";
import type { Rollup } from "~/types";

const rollups: Rollup[] = [
"base",
"mode",
"scroll",
"arbitrum",
"blast",
"boba",
"camp",
"kroma",
"linea",
"metal",
"optimism",
"optopia",
"paradex",
"pgn",
"starknet",
"taiko",
"zksync",
"zora",
];

const ROLLUP_OPTIONS: DropdownProps["options"] = rollups.map((rollup) => {
const icon = <RollupIcon rollup={rollup} />;
return {
value: rollup,
label: rollup.charAt(0).toUpperCase() + rollup.slice(1),
prefix: icon === null ? <div className="h-4 w-4"></div> : icon,
};
});

type RollupFilterProps = Pick<DropdownProps, "onChange" | "selected">;

export const RollupFilter: FC<RollupFilterProps> = function ({
onChange,
selected,
}) {
return (
<Dropdown
selected={selected}
options={ROLLUP_OPTIONS}
onChange={onChange}
placeholder="Rollup"
width="w-40"
/>
);
};
6 changes: 5 additions & 1 deletion apps/web/src/components/RollupIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,9 @@ export const RollupIcon: React.FC<RollupIconProps> = ({
break;
}

return <div title={rollupLabel}>{rollupIcon}</div>;
return (
<div title={rollupLabel}>
{rollupIcon === null ? <div className={commonStyles}></div> : rollupIcon}
</div>
);
};
15 changes: 13 additions & 2 deletions apps/web/src/pages/blobs.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useMemo } from "react";
import { useMemo, useState } from "react";
import type { NextPage } from "next";
import NextError from "next/error";
import { useRouter } from "next/router";

import { getPaginationParams } from "~/utils/pagination";
import { Link } from "~/components/Link";
import type { PaginatedTableQueryFilters } from "~/components/PaginatedTable/PaginatedTable";
import { PaginatedTable } from "~/components/PaginatedTable/PaginatedTable";
import { StorageIcon } from "~/components/StorageIcon";
import { api } from "~/api-client";
Expand Down Expand Up @@ -51,13 +52,18 @@ const BLOBS_TABLE_HEADERS = [
];

const Blobs: NextPage = function () {
const [filters, setFilters] = useState<PaginatedTableQueryFilters>();
const router = useRouter();
const { p, ps } = getPaginationParams(
router.query,
BLOBS_TABLE_DEFAULT_PAGE_SIZE
);

const { data, error, isLoading } = api.blob.getAll.useQuery({ p, ps });
const { data, error, isLoading } = api.blob.getAll.useQuery({
p,
ps,
...filters,
});
const { blobs, totalBlobs } = data || {};

const blobRows = useMemo(() => {
Expand Down Expand Up @@ -138,6 +144,10 @@ const Blobs: NextPage = function () {
);
}

const handleFilter = (filters: PaginatedTableQueryFilters) => {
setFilters(filters);
};

return (
<PaginatedTable
title={`Blobs ${totalBlobs ? `(${formatNumber(totalBlobs)})` : ""}`}
Expand All @@ -146,6 +156,7 @@ const Blobs: NextPage = function () {
rows={blobRows}
totalItems={totalBlobs}
paginationData={{ pageSize: ps, page: p }}
onFilter={handleFilter}
/>
);
};
Expand Down
16 changes: 14 additions & 2 deletions apps/web/src/pages/blocks.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { useMemo } from "react";
import { useMemo, useState } from "react";
import type { NextPage } from "next";
import { useRouter } from "next/router";

import { getPaginationParams } from "~/utils/pagination";
import { BlobGasUsageDisplay } from "~/components/Displays/BlobGasUsageDisplay";
import { EtherUnitDisplay } from "~/components/Displays/EtherUnitDisplay";
import { Link } from "~/components/Link";
import type { PaginatedTableQueryFilters } from "~/components/PaginatedTable/PaginatedTable";
import { PaginatedTable } from "~/components/PaginatedTable/PaginatedTable";
import { Table } from "~/components/Table";
import { api } from "~/api-client";
Expand Down Expand Up @@ -56,13 +57,19 @@ export const BLOCKS_TABLE_HEADERS = [
];

const Blocks: NextPage = function () {
const [filters, setFilters] = useState<PaginatedTableQueryFilters>();

const router = useRouter();
const { p, ps } = getPaginationParams(router.query);
const {
data: rawBlocksData,
isLoading,
error,
} = api.block.getAll.useQuery({ p, ps });
} = api.block.getAll.useQuery({
p,
ps,
...filters,
});
const blocksData = useMemo(() => {
if (!rawBlocksData) {
return {};
Expand Down Expand Up @@ -201,6 +208,10 @@ const Blocks: NextPage = function () {
);
}

const handleFilter = (filters: PaginatedTableQueryFilters) => {
setFilters(filters);
};

return (
<PaginatedTable
title={`Blocks ${totalBlocks ? `(${formatNumber(totalBlocks)})` : ""}`}
Expand All @@ -211,6 +222,7 @@ const Blocks: NextPage = function () {
paginationData={{ pageSize: ps, page: p }}
isExpandable
rowSkeletonHeight={44}
onFilter={handleFilter}
/>
);
};
Expand Down
10 changes: 9 additions & 1 deletion apps/web/src/pages/txs.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useMemo } from "react";
import { useMemo, useState } from "react";
import type { NextPage } from "next";
import { useRouter } from "next/router";

import { getPaginationParams } from "~/utils/pagination";
import { EtherUnitDisplay } from "~/components/Displays/EtherUnitDisplay";
import { Link } from "~/components/Link";
import type { PaginatedTableQueryFilters } from "~/components/PaginatedTable/PaginatedTable";
import { PaginatedTable } from "~/components/PaginatedTable/PaginatedTable";
import { RollupIcon } from "~/components/RollupIcon";
import { Table } from "~/components/Table";
Expand Down Expand Up @@ -84,6 +85,7 @@ type Transaction = Pick<
> & { blobsLength?: number };

const Txs: NextPage = function () {
const [filters, setFilters] = useState<PaginatedTableQueryFilters>();
const router = useRouter();
const { p, ps } = getPaginationParams(
router.query,
Expand All @@ -101,6 +103,7 @@ const Txs: NextPage = function () {
p,
ps,
expand: "block,blob",
...filters,
});
const txsData = useMemo(() => {
if (!rawTxsData) {
Expand Down Expand Up @@ -267,6 +270,10 @@ const Txs: NextPage = function () {
);
}

const handleFilter = (filters: PaginatedTableQueryFilters) => {
setFilters(filters);
};

return (
<PaginatedTable
title={`Blob Transactions ${
Expand All @@ -278,6 +285,7 @@ const Txs: NextPage = function () {
totalItems={totalTransactions}
paginationData={{ pageSize: ps, page: p }}
isExpandable
onFilter={handleFilter}
/>
);
};
Expand Down

0 comments on commit a6e895a

Please sign in to comment.