Improved component structure
This commit is contained in:
parent
8f22cbc0c9
commit
47e078a502
55
apps/explorer/src/app/components/blocks/block-data.tsx
Normal file
55
apps/explorer/src/app/components/blocks/block-data.tsx
Normal file
@ -0,0 +1,55 @@
|
||||
import React from 'react';
|
||||
import { BlockMeta } from '../../routes/blocks/tendermint-blockchain-response';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { SecondsAgo } from '../seconds-ago';
|
||||
import { Table, TableRow, TableCell } from '../table';
|
||||
|
||||
interface BlockProps {
|
||||
block: BlockMeta;
|
||||
}
|
||||
|
||||
export const BlockData = ({ block }: BlockProps) => {
|
||||
return (
|
||||
<Table aria-label={`Data for block ${block.header?.height}`}>
|
||||
<TableRow dataTestId="block-row" modifier="background">
|
||||
<TableCell
|
||||
dataTestId="block-height"
|
||||
className="pl-4 py-2"
|
||||
aria-label="Block height"
|
||||
>
|
||||
<Link
|
||||
to={`/blocks/${block.header?.height}`}
|
||||
className="text-vega-yellow"
|
||||
>
|
||||
{block.header?.height}
|
||||
</Link>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
dataTestId="num-txs"
|
||||
className="px-8 text-center"
|
||||
aria-label="Number of transactions"
|
||||
>
|
||||
{block.num_txs === '1'
|
||||
? '1 transaction'
|
||||
: `${block.num_txs} transactions`}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
dataTestId="validator-link"
|
||||
className="px-8 text-center"
|
||||
aria-label="Validator"
|
||||
>
|
||||
<Link to={`/validators/${block.header?.proposer_address}`}>
|
||||
{block.header.proposer_address}
|
||||
</Link>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
dataTestId="block-time"
|
||||
className="text-center pr-28 text-neutral-300"
|
||||
aria-label="Block genesis"
|
||||
>
|
||||
<SecondsAgo date={block.header?.time} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</Table>
|
||||
);
|
||||
};
|
29
apps/explorer/src/app/components/blocks/blocks-data.tsx
Normal file
29
apps/explorer/src/app/components/blocks/blocks-data.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import { TendermintBlockchainResponse } from '../../routes/blocks/tendermint-blockchain-response';
|
||||
import { BlockData } from './block-data';
|
||||
|
||||
interface BlocksProps {
|
||||
data: TendermintBlockchainResponse | undefined;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const BlocksData = ({ data, className }: BlocksProps) => {
|
||||
if (!data?.result) {
|
||||
return <div className={className}>Awaiting block data</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<ul
|
||||
aria-label={`Showing ${data.result?.block_metas.length} most recently loaded blocks`}
|
||||
className={className}
|
||||
>
|
||||
{data.result?.block_metas?.map((block, index) => {
|
||||
return (
|
||||
<li key={index} data-testid="block-row">
|
||||
<BlockData block={block} />
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
};
|
@ -1,62 +0,0 @@
|
||||
import React from 'react';
|
||||
import { TendermintBlockchainResponse } from '../../../routes/blocks/tendermint-blockchain-response';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { SecondsAgo } from '../../seconds-ago';
|
||||
import { TxsPerBlock } from '../../txs/txs-per-block';
|
||||
import { Table, TableRow, TableCell } from '../../table';
|
||||
|
||||
interface BlocksProps {
|
||||
data: TendermintBlockchainResponse | undefined;
|
||||
showTransactions?: boolean;
|
||||
}
|
||||
|
||||
export const BlocksTable = ({ data, showTransactions }: BlocksProps) => {
|
||||
if (!data?.result) {
|
||||
return <div className="mb-28">Awaiting block data</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Table>
|
||||
{data.result?.block_metas?.map((block, index) => {
|
||||
return (
|
||||
<React.Fragment key={index}>
|
||||
<TableRow dataTestId="block-row" modifier="background">
|
||||
<TableCell dataTestId="block-height" className="pl-4 py-2">
|
||||
<Link
|
||||
to={`/blocks/${block.header?.height}`}
|
||||
className="text-vega-yellow"
|
||||
>
|
||||
{block.header?.height}
|
||||
</Link>
|
||||
</TableCell>
|
||||
<TableCell dataTestId="num-txs" className="px-8 text-center">
|
||||
{block.num_txs === '1'
|
||||
? '1 transaction'
|
||||
: `${block.num_txs} transactions`}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
dataTestId="validator-link"
|
||||
className="px-8 text-center"
|
||||
>
|
||||
<Link to={`/validators/${block.header?.proposer_address}`}>
|
||||
{block.header.proposer_address}
|
||||
</Link>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
dataTestId="block-time"
|
||||
className="text-center pr-28 text-neutral-300"
|
||||
>
|
||||
<SecondsAgo date={block.header?.time} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{showTransactions && (
|
||||
<TableRow>
|
||||
<TxsPerBlock blockHeight={block.header?.height} />
|
||||
</TableRow>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</Table>
|
||||
);
|
||||
};
|
@ -1,2 +1,3 @@
|
||||
export { BlocksTable } from './home/blocks-table';
|
||||
export { BlocksRefetch } from './home/blocks-refetch';
|
||||
export { BlocksData } from './blocks-data';
|
||||
export { BlockData } from './block-data';
|
||||
export { BlocksRefetch } from './blocks-refetch';
|
||||
|
@ -1,59 +1,70 @@
|
||||
import React, { ThHTMLAttributes } from 'react';
|
||||
import classnames from 'classnames';
|
||||
|
||||
interface TableProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
interface TableHeaderProps extends ThHTMLAttributes<HTMLTableRowElement> {
|
||||
interface TableProps extends ThHTMLAttributes<HTMLTableElement> {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface TableChildProps {
|
||||
interface TableHeaderProps
|
||||
extends ThHTMLAttributes<HTMLTableHeaderCellElement> {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface TableRowProps extends ThHTMLAttributes<HTMLTableRowElement> {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
dataTestId?: string;
|
||||
modifier?: 'bordered' | 'background';
|
||||
}
|
||||
|
||||
export const Table = ({ children }: TableProps) => {
|
||||
interface TableCellProps extends ThHTMLAttributes<HTMLTableCellElement> {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
dataTestId?: string;
|
||||
modifier?: 'bordered' | 'background';
|
||||
}
|
||||
|
||||
export const Table = ({ children, className, ...props }: TableProps) => {
|
||||
const classes = classnames(className, 'overflow-x-auto whitespace-nowrap');
|
||||
return (
|
||||
<div className="overflow-x-auto whitespace-nowrap mb-28">
|
||||
<table className="w-full">
|
||||
<div className={classes}>
|
||||
<table className="w-full" {...props}>
|
||||
<tbody>{children}</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const TableRow = ({
|
||||
children,
|
||||
className,
|
||||
dataTestId,
|
||||
modifier,
|
||||
}: TableChildProps) => {
|
||||
const cellClasses = classnames(className, {
|
||||
'border-b border-white-40': modifier === 'bordered',
|
||||
'bg-white-25 border-b-4 border-b-black': modifier === 'background',
|
||||
});
|
||||
return (
|
||||
<tr className={cellClasses} data-testid={dataTestId || null}>
|
||||
{children}
|
||||
</tr>
|
||||
);
|
||||
};
|
||||
|
||||
export const TableHeader = ({
|
||||
children,
|
||||
className,
|
||||
...props
|
||||
}: TableHeaderProps) => {
|
||||
const cellClasses = classnames(className, {
|
||||
'text-left, font-normal': props?.scope === 'row',
|
||||
'text-left font-normal': props?.scope === 'row',
|
||||
});
|
||||
return (
|
||||
<tr className={cellClasses} {...props}>
|
||||
<th className={cellClasses} {...props}>
|
||||
{children}
|
||||
</th>
|
||||
);
|
||||
};
|
||||
|
||||
export const TableRow = ({
|
||||
children,
|
||||
className,
|
||||
dataTestId,
|
||||
modifier,
|
||||
...props
|
||||
}: TableRowProps) => {
|
||||
const cellClasses = classnames(className, {
|
||||
'border-b border-white-40': modifier === 'bordered',
|
||||
'bg-white-25 border-b-4 border-b-black': modifier === 'background',
|
||||
});
|
||||
return (
|
||||
<tr className={cellClasses} data-testid={dataTestId || null} {...props}>
|
||||
{children}
|
||||
</tr>
|
||||
);
|
||||
@ -64,12 +75,13 @@ export const TableCell = ({
|
||||
className,
|
||||
dataTestId,
|
||||
modifier,
|
||||
}: TableChildProps) => {
|
||||
...props
|
||||
}: TableCellProps) => {
|
||||
const cellClasses = classnames(className, {
|
||||
'py-4': modifier === 'bordered',
|
||||
});
|
||||
return (
|
||||
<td className={cellClasses} data-testid={dataTestId || null}>
|
||||
<td className={cellClasses} data-testid={dataTestId || null} {...props}>
|
||||
{children}
|
||||
</td>
|
||||
);
|
||||
|
31
apps/explorer/src/app/components/txs/home/txs-data.tsx
Normal file
31
apps/explorer/src/app/components/txs/home/txs-data.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
import { TendermintBlockchainResponse } from '../../../routes/blocks/tendermint-blockchain-response';
|
||||
import { BlockData } from '../../blocks';
|
||||
import { TxsPerBlock } from '../txs-per-block';
|
||||
|
||||
interface TxsProps {
|
||||
data: TendermintBlockchainResponse | undefined;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const TxsData = ({ data, className }: TxsProps) => {
|
||||
if (!data?.result) {
|
||||
return <div className={className}>Awaiting block data</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<ul
|
||||
aria-label={`Showing ${data.result?.block_metas.length} most recently loaded blocks and transactions`}
|
||||
className={className}
|
||||
>
|
||||
{data.result?.block_metas?.map((block, index) => {
|
||||
return (
|
||||
<li key={index} data-testid="block-row">
|
||||
<BlockData block={block} />
|
||||
<TxsPerBlock blockHeight={block.header.height} />
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
};
|
@ -1,3 +1,4 @@
|
||||
export { TxDetails } from './id/tx-details';
|
||||
export { TxContent } from './id/tx-content';
|
||||
export { TxList } from './home/tx-list';
|
||||
export { TxList } from './pending/tx-list';
|
||||
export { TxsData } from './home/txs-data';
|
||||
|
@ -2,7 +2,7 @@ import { DATA_SOURCES } from '../../../config';
|
||||
import useFetch from '../../../hooks/use-fetch';
|
||||
import { TendermintBlockchainResponse } from '../tendermint-blockchain-response';
|
||||
import { RouteTitle } from '../../../components/route-title';
|
||||
import { BlocksTable, BlocksRefetch } from '../../../components/blocks';
|
||||
import { BlocksData, BlocksRefetch } from '../../../components/blocks';
|
||||
import { JumpToBlock } from '../../../components/jump-to-block';
|
||||
|
||||
const Blocks = () => {
|
||||
@ -17,7 +17,7 @@ const Blocks = () => {
|
||||
<section>
|
||||
<RouteTitle>Blocks</RouteTitle>
|
||||
<BlocksRefetch refetch={refetch} />
|
||||
<BlocksTable data={data} />
|
||||
<BlocksData data={data} className="mb-28" />
|
||||
<JumpToBlock />
|
||||
</section>
|
||||
);
|
||||
|
@ -30,7 +30,7 @@ const Block = () => {
|
||||
return (
|
||||
<section>
|
||||
<RouteTitle>BLOCK {block}</RouteTitle>
|
||||
<Table>
|
||||
<Table className="mb-28">
|
||||
<TableRow modifier="bordered">
|
||||
<TableHeader scope="row">Mined by</TableHeader>
|
||||
<TableCell modifier="bordered">
|
||||
|
@ -2,7 +2,8 @@ import useFetch from '../../../hooks/use-fetch';
|
||||
import { TendermintBlockchainResponse } from '../../blocks/tendermint-blockchain-response';
|
||||
import { DATA_SOURCES } from '../../../config';
|
||||
import { RouteTitle } from '../../../components/route-title';
|
||||
import { BlocksTable, BlocksRefetch } from '../../../components/blocks';
|
||||
import { BlocksRefetch } from '../../../components/blocks';
|
||||
import { TxsData } from '../../../components/txs';
|
||||
import { JumpToBlock } from '../../../components/jump-to-block';
|
||||
|
||||
const Txs = () => {
|
||||
@ -17,7 +18,7 @@ const Txs = () => {
|
||||
<section>
|
||||
<RouteTitle>Transactions</RouteTitle>
|
||||
<BlocksRefetch refetch={refetch} />
|
||||
<BlocksTable data={data} showTransactions={true} />
|
||||
<TxsData data={data} />
|
||||
<JumpToBlock />
|
||||
</section>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user