diff --git a/.changeset/happy-books-brake.md b/.changeset/happy-books-brake.md new file mode 100644 index 000000000..2de4d316b --- /dev/null +++ b/.changeset/happy-books-brake.md @@ -0,0 +1,5 @@ +--- +"@blobscan/rollups": minor +--- + +Updated the chain rollups retrieval to return both the rollup name and address for each rollup. diff --git a/.changeset/nasty-paws-trade.md b/.changeset/nasty-paws-trade.md new file mode 100644 index 000000000..9fdccc4d4 --- /dev/null +++ b/.changeset/nasty-paws-trade.md @@ -0,0 +1,5 @@ +--- +"@blobscan/web": minor +--- + +Enhanced dropdowns with clearable option support diff --git a/.changeset/odd-pumpkins-wait.md b/.changeset/odd-pumpkins-wait.md new file mode 100644 index 000000000..067c324ae --- /dev/null +++ b/.changeset/odd-pumpkins-wait.md @@ -0,0 +1,5 @@ +--- +"@blobscan/rollups": minor +--- + +Added support for retrieving rollups by their addresses diff --git a/.changeset/quiet-experts-lie.md b/.changeset/quiet-experts-lie.md new file mode 100644 index 000000000..08a42c422 --- /dev/null +++ b/.changeset/quiet-experts-lie.md @@ -0,0 +1,5 @@ +--- +"@blobscan/rollups": minor +--- + +Added support for retrieving all chain's available rollups diff --git a/.changeset/shaggy-adults-guess.md b/.changeset/shaggy-adults-guess.md new file mode 100644 index 000000000..1f4885477 --- /dev/null +++ b/.changeset/shaggy-adults-guess.md @@ -0,0 +1,5 @@ +--- +"@blobscan/web": patch +--- + +Added support for clearing dropdown diff --git a/.changeset/sixty-parrots-kneel.md b/.changeset/sixty-parrots-kneel.md new file mode 100644 index 000000000..ff651ee03 --- /dev/null +++ b/.changeset/sixty-parrots-kneel.md @@ -0,0 +1,5 @@ +--- +"@blobscan/db": minor +--- + +Exposed Prisma enums from a separated file diff --git a/.changeset/smooth-trains-fly.md b/.changeset/smooth-trains-fly.md new file mode 100644 index 000000000..6436220ef --- /dev/null +++ b/.changeset/smooth-trains-fly.md @@ -0,0 +1,5 @@ +--- +"@blobscan/web": minor +--- + +Added rollup filter to blobs, blocks and transactions views diff --git a/.gitignore b/.gitignore index 8b5f1e50d..0e23f7cca 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,9 @@ coverage **/prisma/db.sqlite **/prisma/db.sqlite-journal +# Prisma generated files +packages/db/prisma/enums + # next.js .next/ out/ diff --git a/apps/docs/src/app/docs/codebase-overview/page.md b/apps/docs/src/app/docs/codebase-overview/page.md index 869a2bb6d..237fa0a30 100644 --- a/apps/docs/src/app/docs/codebase-overview/page.md +++ b/apps/docs/src/app/docs/codebase-overview/page.md @@ -60,6 +60,7 @@ Here you can find all the shared packages used by the apps: | [`@blobscan/test`](https://github.com/Blobscan/blobscan/tree/next/packages/test) |  Shared test utilities and fixtures. | |  [`@blobscan/zod`](https://github.com/Blobscan/blobscan/tree/next/packages/zod) |  Shared [Zod](https://zod.dev) schemas and utilities. | |  [`@blobscan/eth-format`](https://github.com/Blobscan/blobscan/tree/next/packages/eth-format) |  Provides utility functions for handling Ethereum value conversions and formatting. | +|  [`@blobscan/rollups`](https://github.com/Blobscan/blobscan/tree/next/packages/rollups) |  A utility that provides a comprehensive list of all rollups and their associated addresses supported by Blobscan, along with functions to retrieve them easily. | ### Tooling diff --git a/apps/web/package.json b/apps/web/package.json index 796865490..4ce17abeb 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -21,6 +21,7 @@ "@blobscan/env": "workspace:^0.0.1", "@blobscan/eth-units": "workspace:^0.0.1", "@blobscan/open-telemetry": "workspace:^0.0.8", + "@blobscan/rollups": "workspace:^0.0.1", "@fontsource/inter": "^4.5.15", "@fontsource/public-sans": "^4.5.12", "@headlessui/react": "^2.1.0", diff --git a/apps/web/src/components/Cards/SurfaceCards/BlobCard.tsx b/apps/web/src/components/Cards/SurfaceCards/BlobCard.tsx index a6972bbea..294976b03 100644 --- a/apps/web/src/components/Cards/SurfaceCards/BlobCard.tsx +++ b/apps/web/src/components/Cards/SurfaceCards/BlobCard.tsx @@ -45,9 +45,9 @@ const BlobCard: FC = ({ {transactions ?.filter((tx) => !!tx.rollup) - .map(({ rollup }) => ( - - ))} + .map(({ rollup }) => + rollup ? : null + )} ) : ( diff --git a/apps/web/src/components/Dropdown/Option.tsx b/apps/web/src/components/Dropdown/Option.tsx index 594ec28d4..91700e17e 100644 --- a/apps/web/src/components/Dropdown/Option.tsx +++ b/apps/web/src/components/Dropdown/Option.tsx @@ -3,6 +3,7 @@ import { ListboxOption } from "@headlessui/react"; import type { Option as OptionProps } from "."; export const Option: React.FC = function (props) { + const { prefix, label, value } = props; return ( @@ -15,11 +16,12 @@ export const Option: React.FC = function (props) { value={props} > {({ selected }) => ( -
+
+ {prefix && prefix} - {props.label ? props.label : props.value} + {label ? label : value}
)} diff --git a/apps/web/src/components/Dropdown/index.tsx b/apps/web/src/components/Dropdown/index.tsx index 651d69a99..29aeea894 100644 --- a/apps/web/src/components/Dropdown/index.tsx +++ b/apps/web/src/components/Dropdown/index.tsx @@ -5,20 +5,22 @@ import { ListboxOptions, Transition, } from "@headlessui/react"; -import { ChevronUpDownIcon } from "@heroicons/react/24/outline"; +import { ChevronUpDownIcon, XMarkIcon } from "@heroicons/react/24/solid"; import { Option } from "./Option"; export interface Option { value: string | number; label?: ReactNode; + prefix?: ReactNode; } - export interface DropdownProps { options: Option[]; - selected: Option; + selected: Option | null; width?: string; - onChange(newOption: Option): void; + placeholder?: string; + clearable?: boolean; + onChange(newOption: Option | null): void; } const DEFAULT_WIDTH = "w-32"; @@ -28,6 +30,8 @@ export const Dropdown: React.FC = function ({ selected, width, onChange, + clearable = false, + placeholder = "Select an item", }) { return ( @@ -35,17 +39,31 @@ export const Dropdown: React.FC = function ({ - - {selected.label ? selected.label : selected.value} - - +
+ {selected ? selected.label ?? selected.value : placeholder} +
+
+ {clearable && selected ? ( + <> + { + e.stopPropagation(); + onChange(null); + }} + /> + + ) : null} +
+ | +
& { + onChange(newRollup: Option | null): void; +}; + +const chainId = getChainIdByName(env.NEXT_PUBLIC_NETWORK_NAME); +const rollups = chainId ? getChainRollups(chainId) : []; + +export const ROLLUP_OPTIONS: Option[] = [ + { + value: "null", + label: "None", + }, + ...rollups.map(([rollupAddress, rollupName]) => ({ + value: rollupAddress, + label: ( +
+ + {capitalize(rollupName)} +
+ ), + })), +]; + +export const RollupFilter: FC = function ({ + onChange, + selected, +}) { + return ( + + ); +}; diff --git a/apps/web/src/components/Filters/index.tsx b/apps/web/src/components/Filters/index.tsx new file mode 100644 index 000000000..017194050 --- /dev/null +++ b/apps/web/src/components/Filters/index.tsx @@ -0,0 +1,67 @@ +import { useEffect, useState } from "react"; +import type { FC } from "react"; +import { useRouter } from "next/router"; +import type { UrlObject } from "url"; + +import { Button } from "~/components/Button"; +import { useQueryParams } from "~/hooks/useQueryParams"; +import type { Option } from "../Dropdown"; +import { ROLLUP_OPTIONS, RollupFilter } from "./RollupFilter"; + +export const Filters: FC = function () { + const router = useRouter(); + const queryParams = useQueryParams(); + const [selectedRollup, setSelectedRollup] = useState