Skip to content

Commit e5b2ab8

Browse files
authored
feat: option remove pending txs from table (#356)
1 parent 0cb16a7 commit e5b2ab8

File tree

10 files changed

+249
-118
lines changed

10 files changed

+249
-118
lines changed

services/explorer-ui/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"@chicmoz-pkg/types": "workspace:^",
1414
"@radix-ui/react-accordion": "1.1.2",
1515
"@radix-ui/react-alert-dialog": "1.1.1",
16-
"@radix-ui/react-checkbox": "1.0.4",
16+
"@radix-ui/react-checkbox": "1.1.4",
1717
"@radix-ui/react-dialog": "1.1.1",
1818
"@radix-ui/react-dropdown-menu": "2.1.1",
1919
"@radix-ui/react-icons": "1.3.0",

services/explorer-ui/src/components/blocks/blocks-table.tsx

+10-8
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,19 @@ export const BlocksTable: FC<Props> = ({
1919
error,
2020
disableSizeSelector,
2121
}) => {
22-
if (error) return <p className="text-red-500">{error.message}</p>;
22+
if (error) { return <p className="text-red-500">{error.message}</p>; }
2323

2424
return (
2525
<section className="relative mx-0 w-full transition-all">
26-
<DataTable
27-
isLoading={isLoading}
28-
title={title}
29-
data={blocks ?? []}
30-
columns={BlockTableColumns}
31-
disableSizeSelector={disableSizeSelector}
32-
/>
26+
<div className="space-y-4 bg-white rounded-lg p-5">
27+
{title && <h3 className="ml-0.5">{title}</h3>}
28+
<DataTable
29+
isLoading={isLoading}
30+
data={blocks ?? []}
31+
columns={BlockTableColumns}
32+
disableSizeSelector={disableSizeSelector}
33+
/>
34+
</div>
3335
</section>
3436
);
3537
};

services/explorer-ui/src/components/contracts/classes/table.tsx

+10-8
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export const ContractClassesTable: FC<Props> = ({
1818
error,
1919
showContractVersions,
2020
}) => {
21-
if (!contracts) return <div>No data</div>;
22-
if (error) return <p className="text-red-500">{error.message}</p>;
21+
if (!contracts) { return <div>No data</div>; }
22+
if (error) { return <p className="text-red-500">{error.message}</p>; }
2323
let cols = contractsTableColumns;
2424
if (!showContractVersions) {
2525
cols = contractsTableColumns.filter((column) => {
@@ -29,12 +29,14 @@ export const ContractClassesTable: FC<Props> = ({
2929

3030
return (
3131
<section className="relative mx-auto w-full transition-all">
32-
<DataTable
33-
isLoading={isLoading}
34-
title={title}
35-
data={contracts}
36-
columns={cols}
37-
/>
32+
<div className="space-y-4 bg-white rounded-lg p-5">
33+
{title && <h3 className="ml-0.5">{title}</h3>}
34+
<DataTable
35+
isLoading={isLoading}
36+
data={contracts}
37+
columns={cols}
38+
/>
39+
</div>
3840
</section>
3941
);
4042
};

services/explorer-ui/src/components/contracts/instances/table.tsx

+10-8
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export const ContractInstancesTable: FC<Props> = ({
1818
error,
1919
showContractVersions,
2020
}) => {
21-
if (!contracts) return <div>No data</div>;
22-
if (error) return <p className="text-red-500">{error.message}</p>;
21+
if (!contracts) { return <div>No data</div>; }
22+
if (error) { return <p className="text-red-500">{error.message}</p>; }
2323
let cols = contractsTableColumns;
2424
if (!showContractVersions) {
2525
cols = contractsTableColumns.filter((column) => {
@@ -28,12 +28,14 @@ export const ContractInstancesTable: FC<Props> = ({
2828
}
2929
return (
3030
<section className="relative mx-auto w-full transition-all">
31-
<DataTable
32-
isLoading={isLoading}
33-
title={title}
34-
data={contracts}
35-
columns={cols}
36-
/>
31+
<div className="space-y-4 bg-white rounded-lg p-5">
32+
{title && <h3 className="ml-0.5">{title}</h3>}
33+
<DataTable
34+
isLoading={isLoading}
35+
data={contracts}
36+
columns={cols}
37+
/>
38+
</div>
3739
</section>
3840
);
3941
};

services/explorer-ui/src/components/data-table/data-table.tsx

+2-5
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,12 @@ import { Loader } from "../loader";
3131

3232
interface DataTableProps<TData, TValue> {
3333
isLoading?: boolean;
34-
title?: string;
3534
columns: ColumnDef<TData, TValue>[];
3635
data: TData[];
3736
disableSizeSelector?: boolean;
3837
}
3938
export function DataTable<TData, TValue>({
4039
isLoading,
41-
title,
4240
columns,
4341
data,
4442
disableSizeSelector,
@@ -82,8 +80,7 @@ export function DataTable<TData, TValue>({
8280
});
8381

8482
return (
85-
<div className="space-y-4 bg-white rounded-lg p-5">
86-
{title && <h3 className="ml-0.5">{title}</h3>}
83+
<>
8784
<div className="min-w-full">
8885
{isLoading && <Loader amount={10} />}
8986
{!isLoading && (
@@ -98,7 +95,7 @@ export function DataTable<TData, TValue>({
9895
table={table}
9996
disableSizeSelector={disableSizeSelector}
10097
/>
101-
</div>
98+
</>
10299
);
103100
}
104101

services/explorer-ui/src/components/tx-effects/tx-effects-table.tsx

+29-9
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import { type FC } from "react";
22
import { DataTable } from "~/components/data-table";
33
import { TxEffectsTableColumns } from "./tx-effects-columns";
44
import { type TxEffectTableSchema } from "./tx-effects-schema";
5+
import { Checkbox } from "../ui/checkbox";
56

67
interface Props {
78
title?: string;
89
txEffects?: TxEffectTableSchema[];
910
isLoading: boolean;
1011
error?: Error | null;
1112
disableSizeSelector?: boolean;
13+
handleDisablePendingTx?: (checked: boolean) => void;
1214
}
1315

1416
export const TxEffectsTable: FC<Props> = ({
@@ -17,18 +19,36 @@ export const TxEffectsTable: FC<Props> = ({
1719
isLoading,
1820
error,
1921
disableSizeSelector,
22+
handleDisablePendingTx
2023
}) => {
21-
if (!txEffects) return <div>No data</div>;
22-
if (error) return <p className="text-red-500">{error.message}</p>;
24+
if (!txEffects) { return <div>No data</div>; }
25+
if (error) { return <p className="text-red-500">{error.message}</p>; }
2326
return (
2427
<section className="relative mx-0 w-full transition-all">
25-
<DataTable
26-
isLoading={isLoading}
27-
title={title}
28-
data={txEffects}
29-
columns={TxEffectsTableColumns}
30-
disableSizeSelector={disableSizeSelector}
31-
/>
28+
<div className="space-y-4 bg-white rounded-lg p-5">
29+
{title &&
30+
<div className="flex flex-row justify-between">
31+
<h3 className="ml-0.5">{title}</h3>
32+
{handleDisablePendingTx &&
33+
<div className="flex items-center space-x-2">
34+
<Checkbox id="terms2" onCheckedChange={(checked) => handleDisablePendingTx(Boolean(checked))} defaultChecked={true} />
35+
<label
36+
htmlFor="terms2"
37+
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
38+
>
39+
Show pending
40+
</label>
41+
</div>}
42+
</div>
43+
}
44+
45+
<DataTable
46+
isLoading={isLoading}
47+
data={txEffects}
48+
columns={TxEffectsTableColumns}
49+
disableSizeSelector={disableSizeSelector}
50+
/>
51+
</div>
3252
</section>
3353
);
3454
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"use client"
2+
3+
import * as React from "react"
4+
import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
5+
import { cn } from "~/lib/utils"
6+
import { CheckIcon } from "@radix-ui/react-icons"
7+
8+
const Checkbox = React.forwardRef<
9+
React.ElementRef<typeof CheckboxPrimitive.Root>,
10+
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
11+
>(({ className, ...props }, ref) => (
12+
<CheckboxPrimitive.Root
13+
ref={ref}
14+
className={cn(
15+
"peer h-4 w-4 shrink-0 rounded-[2px] border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
16+
className
17+
)}
18+
{...props}
19+
>
20+
<CheckboxPrimitive.Indicator
21+
className={cn("flex items-center justify-center text-current")}
22+
>
23+
<CheckIcon className="h-4 w-4" />
24+
</CheckboxPrimitive.Indicator>
25+
</CheckboxPrimitive.Root>
26+
))
27+
Checkbox.displayName = CheckboxPrimitive.Root.displayName
28+
29+
export { Checkbox }

services/explorer-ui/src/pages/landing/index.tsx

+6-47
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,22 @@
1-
import { useMemo, type FC } from "react";
1+
import { type FC } from "react";
22
import { BlocksTable } from "~/components/blocks/blocks-table";
33
import { InfoBadge } from "~/components/info-badge";
4-
import { type TxEffectTableSchema } from "~/components/tx-effects/tx-effects-schema";
5-
import { TxEffectsTable } from "~/components/tx-effects/tx-effects-table";
64
import {
75
HealthStatus,
86
useAvarageBlockTime,
97
useAvarageFees,
10-
useGetLatestTxEffects,
118
useLatestBlocks,
12-
usePendingTxs,
139
useSubTitle,
1410
useSystemHealth,
1511
useTotalContracts,
1612
useTotalContractsLast24h,
1713
useTotalTxEffects,
1814
useTotalTxEffectsLast24h,
1915
} from "~/hooks";
20-
import { mapLatestBlocks, mapLatestTxEffects } from "~/lib/map-for-table";
16+
import { mapLatestBlocks } from "~/lib/map-for-table";
2117
import { formatDuration, formatFees } from "~/lib/utils";
2218
import { routes } from "~/routes/__root";
19+
import { TxEffectTableLanding } from "./tx-effect-table-landing";
2320

2421
export const Landing: FC = () => {
2522
const { systemHealth } = useSystemHealth();
@@ -57,38 +54,6 @@ export const Landing: FC = () => {
5754

5855
useSubTitle(latestBlocks?.[0]?.height.toString() ?? routes.home.title);
5956

60-
const {
61-
data: latestTxEffectsData,
62-
isLoading: isLoadingTxEffects,
63-
error: txEffectsError,
64-
} = useGetLatestTxEffects();
65-
66-
const { data: pendingTxs } = usePendingTxs();
67-
68-
const latestTxEffectsWithPending = useMemo(() => {
69-
if (!latestTxEffectsData) {
70-
return [];
71-
}
72-
if (!latestBlocks) {
73-
return [];
74-
}
75-
const disguisedPendingTxs =
76-
pendingTxs?.reduce((acc, tx) => {
77-
if (!latestTxEffectsData.some((effect) => effect.txHash === tx.hash)) {
78-
acc.push({
79-
txHash: tx.hash,
80-
transactionFee: -1,
81-
blockNumber: -1,
82-
timestamp: tx.birthTimestamp ?? 0,
83-
});
84-
}
85-
return acc;
86-
}, [] as TxEffectTableSchema[]) ?? [];
87-
return [
88-
...disguisedPendingTxs,
89-
...mapLatestTxEffects(latestTxEffectsData, latestBlocks),
90-
];
91-
}, [pendingTxs, latestTxEffectsData, latestBlocks]);
9257

9358
const averageBlockTimeFormatted = formatDuration(
9459
Number(avarageBlockTime) / 1000,
@@ -104,8 +69,8 @@ export const Landing: FC = () => {
10469
loadingAvarageFees ||
10570
loadingAmountContracts ||
10671
loadingAmountContracts24h ||
107-
loadingAvarageBlockTime ||
108-
isLoadingTxEffects;
72+
loadingAvarageBlockTime;
73+
10974
const isThereAnyComponentData =
11075
(latestBlocks?.length ?? 0) > 0 ||
11176
!!totalTxEffects ||
@@ -183,13 +148,7 @@ export const Landing: FC = () => {
183148
/>
184149
</div>
185150
<div className="bg-white rounded-lg shadow-lg w-full md:w-1/2">
186-
<TxEffectsTable
187-
title="Latest TX-Effects"
188-
txEffects={latestTxEffectsWithPending}
189-
isLoading={isLoadingTxEffects}
190-
error={txEffectsError}
191-
disableSizeSelector={true}
192-
/>
151+
<TxEffectTableLanding latestBlocks={latestBlocks} />
193152
</div>
194153
</div>
195154
</>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { type ChicmozL2BlockLight } from "@chicmoz-pkg/types"
2+
import { useMemo, useState, type FC } from "react"
3+
import { type TxEffectTableSchema } from "~/components/tx-effects/tx-effects-schema"
4+
import { TxEffectsTable } from "~/components/tx-effects/tx-effects-table"
5+
import { useGetLatestTxEffects, usePendingTxs } from "~/hooks"
6+
import { mapLatestTxEffects } from "~/lib/map-for-table"
7+
8+
interface TxEffectTableLandingProps {
9+
latestBlocks?: ChicmozL2BlockLight[];
10+
}
11+
12+
export const TxEffectTableLanding: FC<TxEffectTableLandingProps> = ({ latestBlocks }) => {
13+
const [showPendingTxs, setShowPendingTxs] = useState(true)
14+
const { data: pendingTxs } = usePendingTxs();
15+
const {
16+
data: latestTxEffectsData,
17+
isLoading: isLoadingTxEffects,
18+
error: txEffectsError,
19+
} = useGetLatestTxEffects();
20+
21+
const toggleShowPendingTx = (checked: boolean) => {
22+
setShowPendingTxs(checked);
23+
}
24+
25+
const latestTxEffectsWithPending = useMemo(() => {
26+
if (!latestTxEffectsData) {
27+
return [];
28+
}
29+
if (!latestBlocks) {
30+
return [];
31+
}
32+
const disguisedPendingTxs =
33+
pendingTxs?.reduce((acc, tx) => {
34+
if (!latestTxEffectsData.some((effect) => effect.txHash === tx.hash)) {
35+
acc.push({
36+
txHash: tx.hash,
37+
transactionFee: -1,
38+
blockNumber: -1,
39+
timestamp: tx.birthTimestamp ?? 0,
40+
});
41+
}
42+
return acc;
43+
}, [] as TxEffectTableSchema[]) ?? [];
44+
return [
45+
...disguisedPendingTxs,
46+
...mapLatestTxEffects(latestTxEffectsData, latestBlocks),
47+
];
48+
}, [pendingTxs, latestTxEffectsData, latestBlocks]);
49+
50+
const txEffectData = showPendingTxs ? latestTxEffectsWithPending : mapLatestTxEffects(latestTxEffectsData ?? [], latestBlocks ?? []);
51+
52+
return (
53+
<>
54+
<TxEffectsTable
55+
txEffects={txEffectData}
56+
isLoading={isLoadingTxEffects}
57+
title="Latest Tx Effects"
58+
error={txEffectsError}
59+
disableSizeSelector={true}
60+
handleDisablePendingTx={toggleShowPendingTx}
61+
/>
62+
</>)
63+
}

0 commit comments

Comments
 (0)