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
6 changes: 6 additions & 0 deletions dashboard/src/components/EventExplorerCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { memo, useMemo } from 'react';
import type { BlockchainEvent } from '../types/event';
import type { ContractStatus } from '../services/eventsApi';
import { formatTimestamp, parseToDate } from '../utils/formatTime';
import { formatTimestamp } from '../utils/formatTime';
import { CopyButton } from './CopyButton';

Expand All @@ -18,6 +20,7 @@ interface EventExplorerCardProps {
onCopyContract: (contractAddress: string) => void;
isCopied: boolean;
onSelect?: (event: BlockchainEvent) => void;
contractStatuses: ContractStatus[];
contractStatuses?: ContractStatus[];
}

Expand All @@ -33,6 +36,7 @@ export function EventExplorerCard({
const label = event.eventName ?? event.type;
const badgeClass = getEventKindClass(event.type);
const kindLabel = getEventKindLabel(event.type);
const receivedAt = parseToDate(event.receivedAt);

return (
<article
Expand Down Expand Up @@ -78,6 +82,8 @@ export function EventExplorerCard({
</div>

<div className="event-explorer__cell" data-label="Received" role="cell">
<time dateTime={receivedAt?.toISOString()}>
{formatTimestamp(event.receivedAt)}
<time dateTime={new Date(event.receivedAt).toISOString()}>
{formattedTime}
</time>
Expand Down
9 changes: 8 additions & 1 deletion dashboard/src/components/EventExplorerTable.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
MIN_COLUMN_WIDTH,
EventExplorerTable,
} from './EventExplorerTable';
import { render, fireEvent } from '@testing-library/react';
import { render, fireEvent, screen } from '@testing-library/react';
import type { BlockchainEvent } from '../types/event';

const STORAGE_KEY = 'notify-chain-event-table-widths';
Expand Down Expand Up @@ -87,4 +87,11 @@ describe('EventExplorerTable resizing UI', () => {
expect(after.split(' ').length).toBe(DEFAULT_COLUMN_WIDTHS.length);
expect(localStorage.getItem(STORAGE_KEY)).toBeTruthy();
});

it('renders invalid event timestamps without throwing', () => {
render(<EventExplorerTable events={[{ ...sampleEvent, receivedAt: NaN }]} />);

expect(screen.getByText('Unknown time')).toBeInTheDocument();
expect(screen.getByText('Unknown time').closest('time')).not.toHaveAttribute('dateTime');
});
});
17 changes: 17 additions & 0 deletions dashboard/src/components/EventExplorerTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@ interface EventExplorerTableProps {
events: BlockchainEvent[];
}

export function loadColumnWidths(): number[] {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return [...DEFAULT_COLUMN_WIDTHS];
const parsed = JSON.parse(raw) as unknown;
if (!Array.isArray(parsed) || parsed.length !== DEFAULT_COLUMN_WIDTHS.length) {
return [...DEFAULT_COLUMN_WIDTHS];
}
return parsed.map((value, index) => {
const n = Number(value);
if (!Number.isFinite(n) || n < MIN_COLUMN_WIDTH) {
return DEFAULT_COLUMN_WIDTHS[index];
}
return n;
});
} catch {
return [...DEFAULT_COLUMN_WIDTHS];
async function syncCopyText(text: string) {
if (navigator.clipboard?.writeText) {
return navigator.clipboard.writeText(text);
Expand Down