Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/pages/ethereum/execution/payloads/IndexPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,20 @@ export function IndexPage(): JSX.Element {

// Calculate time range in seconds
// Use URL params if provided, otherwise default to last hour with no upper bound
// Skip time filtering when blockNumber is provided for deep-linking
const timeRange = useMemo(() => {
const nowSeconds = Math.floor(Date.now() / 1000);
const defaultRangeSeconds = DEFAULT_TIME_RANGE_HOURS * 60 * 60;

// When blockNumber is provided, skip time filtering to allow deep-linking
// to blocks that fall outside the default 6-hour window
if (search.blockNumber !== undefined) {
return {
start: undefined,
end: undefined,
};
}

if (search.timeStart !== undefined && search.timeEnd !== undefined) {
return {
start: search.timeStart,
Expand All @@ -58,7 +68,7 @@ export function IndexPage(): JSX.Element {
start: nowSeconds - defaultRangeSeconds,
end: undefined,
};
}, [search.timeStart, search.timeEnd]);
}, [search.timeStart, search.timeEnd, search.blockNumber]);

// Check if live mode is enabled from URL (only if feature is enabled)
const isLive = LIVE_MODE_ENABLED && (search.isLive ?? false);
Expand All @@ -85,7 +95,7 @@ export function IndexPage(): JSX.Element {
} = useQuery({
...intEngineNewPayloadServiceListOptions({
query: {
slot_start_date_time_gte: timeRange.start,
...(timeRange.start !== undefined && { slot_start_date_time_gte: timeRange.start }),
...(timeRange.end !== undefined && { slot_start_date_time_lte: timeRange.end }),
duration_ms_gte: durationMin,
page_size: search.pageSize ?? DEFAULT_PAGE_SIZE,
Expand Down Expand Up @@ -348,6 +358,9 @@ export function IndexPage(): JSX.Element {
);
}, [data, search.detailSlot, search.detailNodeName]);

// Get tracoor URL from network config for external links
const tracoorUrl = currentNetwork?.service_urls?.tracoor;

return (
<PayloadsView
data={data}
Expand All @@ -368,6 +381,7 @@ export function IndexPage(): JSX.Element {
selectedBlock={selectedBlock}
onBlockSelect={handleBlockSelect}
durationThreshold={durationMin}
tracoorUrl={tracoorUrl}
// Live mode props (disabled when LIVE_MODE_ENABLED is false)
isLive={isLive}
onLiveModeToggle={LIVE_MODE_ENABLED ? handleLiveModeToggle : undefined}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Container } from '@/components/Layout/Container';
import { Header } from '@/components/Layout/Header';
import { DataTable } from '@/components/DataTable';
import { ClientLogo } from '@/components/Ethereum/ClientLogo';
import { TracoorIcon } from '@/components/Ethereum/TracoorIcon';
import { Alert } from '@/components/Feedback/Alert';
import { Timestamp } from '@/components/DataDisplay/Timestamp';
import type { IntEngineNewPayload } from '@/api/types.gen';
Expand Down Expand Up @@ -157,6 +158,8 @@ export type PayloadsViewProps = {
onBlockSelect: (block: Payload | null) => void;
// Duration threshold for display
durationThreshold: number;
// External links
tracoorUrl?: string;
// Live mode props
isLive?: boolean;
onLiveModeToggle?: () => void;
Expand All @@ -177,6 +180,7 @@ export function PayloadsView({
onFiltersChange,
onClearFilters,
durationThreshold,
tracoorUrl,
isLive = false,
onLiveModeToggle,
newItemIdsRef,
Expand Down Expand Up @@ -289,8 +293,35 @@ export function PayloadsView({
},
sortingFn: 'basic',
}),
// Tracoor external link column (only shown if tracoorUrl is available)
...(tracoorUrl
? [
columnHelper.display({
id: 'tracoor',
header: '',
cell: info => {
const blockNumber = info.row.original.block_number;
if (blockNumber === undefined) return null;
const url = `${tracoorUrl}/execution_block_trace?executionBlockTraceBlockNumber=${blockNumber}`;
return (
<a
href={url}
target="_blank"
rel="noopener noreferrer"
onClick={e => e.stopPropagation()}
className="inline-flex items-center transition-opacity hover:opacity-70"
title="View in Tracoor"
>
<TracoorIcon className="size-4" />
</a>
);
},
enableSorting: false,
}),
]
: []),
],
[onFilterClick]
[onFilterClick, tracoorUrl]
);

// Get row ID for live mode highlighting
Expand Down
Loading