Implement components for debug message result

pull/4/head
J M Rossy 2 years ago
parent ab4a60c1d8
commit f976161642
  1. 8
      src/components/nav/Header.tsx
  2. 83
      src/features/debugger/TxDebugger.tsx
  3. 9
      src/features/debugger/debugMessage.ts
  4. 2
      src/features/search/MessageSearch.tsx

@ -32,7 +32,7 @@ export function Header({ pathName }: { pathName: string }) {
</div>
</a>
</Link>
<div className="hidden sm:flex sm:space-x-8 sm:items-center md:space-x-10">
<nav className="hidden sm:flex sm:space-x-8 sm:items-center md:space-x-10">
<Link href="/">
<a className={styles.navLink + (pathName === '/' ? ' underline' : '')}>Home</a>
</Link>
@ -45,7 +45,7 @@ export function Header({ pathName }: { pathName: string }) {
About
</a>
<NetworkSelector />
</div>
</nav>
<div className="relative flex item-center sm:hidden mr-2">
<button className="hover:opactiy-70 transition-all" {...buttonProps}>
<Image src={HamburgerIcon} width={22} height={22} />
@ -53,7 +53,7 @@ export function Header({ pathName }: { pathName: string }) {
</div>
</div>
{/* Dropdown menu, used on mobile */}
<div className={`${styles.dropdownContainer} ${!isOpen && 'hidden'} right-0`} role="menu">
<nav className={`${styles.dropdownContainer} ${!isOpen && 'hidden'} right-0`} role="menu">
<Link href="/">
<a {...itemProps[0]} className={styles.dropdownOption} onClick={closeDropdown}>
<DropdownItemContent icon={HouseIcon} text="Home" />
@ -84,7 +84,7 @@ export function Header({ pathName }: { pathName: string }) {
>
<DropdownItemContent icon={InfoIcon} text="About" />
</a>
</div>
</nav>
</header>
);
}

@ -1,7 +1,9 @@
import { useQuery } from '@tanstack/react-query';
import Image from 'next/future/image';
import { useState } from 'react';
import { Fade } from '../../components/animation/Fade';
import { CopyButton } from '../../components/buttons/CopyButton';
import { SearchBar } from '../../components/search/SearchBar';
import {
NoSearchError,
@ -10,12 +12,13 @@ import {
SearchUnknownError,
} from '../../components/search/SearchError';
import { envDisplayValue } from '../../consts/environments';
import ShrugIcon from '../../images/icons/shrug.svg';
import { useStore } from '../../store';
import useDebounce from '../../utils/debounce';
import { sanitizeString } from '../../utils/string';
import { isValidSearchQuery } from '../search/utils';
import { debugMessageForHash } from './debugMessage';
import { MessageDebugResult, TxDebugStatus, debugMessageForHash } from './debugMessage';
export function TxDebugger() {
const environment = useStore((s) => s.environment);
@ -49,11 +52,15 @@ export function TxDebugger() {
placeholder="Search transaction hash to debug message"
/>
<div className="w-full h-[38.05rem] mt-5 bg-white shadow-md border border-blue-50 rounded overflow-auto relative">
<div className="px-2 py-3 sm:px-4 md:px-5 md:py-3 flex items-center justify-between border-b border-gray-100">
<div className="px-2 py-3 sm:px-4 md:px-5 flex items-center justify-between border-b border-gray-100">
<h2 className="text-gray-600">{`Transaction Debugger (${envDisplayValue[environment]})`}</h2>
</div>
<Fade show={isValidInput && !hasError && !!data}>{JSON.stringify(data)}</Fade>
<Fade show={isValidInput && !hasError && !!data}>
<div className="px-2 sm:px-4 md:px-5">
<DebugResult result={data} />
</div>
</Fade>
<SearchEmptyError
show={isValidInput && !hasError && !fetching && !data}
hasInput={hasInput}
@ -66,3 +73,73 @@ export function TxDebugger() {
</>
);
}
function DebugResult({ result }: { result: MessageDebugResult | null | undefined }) {
if (!result) return null;
if (result.status === TxDebugStatus.NotFound) {
return (
<div className="py-8 flex flex-col items-center">
<Image src={ShrugIcon} width={110} className="opacity-80" />
<h2 className="mt-4 text-lg text-gray-600">No transaction found</h2>
<p className="mt-4 leading-relaxed">{result.details}</p>
</div>
);
}
if (result.status === TxDebugStatus.NoMessages) {
return (
<div className="py-8 flex flex-col items-center">
<Image src={ShrugIcon} width={110} className="opacity-80" />
<h2 className="mt-4 text-lg text-gray-600">No message found</h2>
<p className="mt-4 leading-relaxed">{result.details}</p>
<TxExplorerLink href={result.explorerLink} />
</div>
);
}
if (result.status === TxDebugStatus.MessagesFound) {
return (
<>
{result.messageDetails.map((m, i) => (
<div className="border-b border-gray-200 py-4" key={`message-${i}`}>
<h2 className="text-lg text-gray-600">{`Message ${i + 1} / ${
result.messageDetails.length
}`}</h2>
<p className="mt-2 leading-relaxed">{m.summary}</p>
<div className="mt-2 text-sm">
{Array.from(m.properties.entries()).map(([key, val]) => (
<div className="flex mt-1" key={`message-${i}-prop-${key}`}>
<label className="text-gray-600 w-32">{key}</label>
<div className="relative ml-2 truncate max-w-xs sm:max-w-sm md:max-w-lg">
{val}
</div>
{val.length > 20 && (
<CopyButton copyValue={val} width={12} height={12} classes="ml-2" />
)}
</div>
))}
</div>
</div>
))}
<TxExplorerLink href={result.explorerLink} />
</>
);
}
return null;
}
function TxExplorerLink({ href }: { href: string | undefined }) {
if (!href) return null;
return (
<a
className="block my-5 text-blue-600 hover:text-blue-500 underline underline-offset-4"
href={href}
target="_blank"
rel="noopener noreferrer"
>
View transaction in explorer
</a>
);
}

@ -55,7 +55,10 @@ export interface DebugMessagesFoundResult {
messageDetails: MessageDetails[];
}
type MessageDebugResult = DebugNotFoundResult | DebugNoMessagesResult | DebugMessagesFoundResult;
export type MessageDebugResult =
| DebugNotFoundResult
| DebugNoMessagesResult
| DebugMessagesFoundResult;
export async function debugMessageForHash(
txHash: string,
@ -89,9 +92,9 @@ export async function debugMessageForHash(
logger.debug(`Found ${dispatchedMessages.length} messages`);
const messageDetails: MessageDetails[] = [];
for (let i = 0; i < dispatchedMessages.length; i++) {
logger.debug(`Checking message ${i} of ${dispatchedMessages.length}`);
logger.debug(`Checking message ${i + 1} of ${dispatchedMessages.length}`);
messageDetails.push(await checkMessage(core, multiProvider, dispatchedMessages[i]));
logger.debug(`Done checking message ${i}`);
logger.debug(`Done checking message ${i + 1}`);
}
return {
status: TxDebugStatus.MessagesFound,

@ -91,7 +91,7 @@ export function MessageSearch() {
/>
<div className="w-full h-[38.05rem] mt-5 bg-white shadow-md border border-blue-50 rounded overflow-auto relative">
{/* Content header and filter bar */}
<div className="px-2 py-3 sm:px-4 md:px-5 md:py-3 flex items-center justify-between border-b border-gray-100">
<div className="px-2 py-3 sm:px-4 md:px-5 flex items-center justify-between border-b border-gray-100">
<h2 className="text-gray-600">{!hasInput ? 'Latest Messages' : 'Search Results'}</h2>
<div className="flex items-center space-x-1 sm:space-x-2 md:space-x-3">
<div className="w-px h-8 bg-gray-100"></div>

Loading…
Cancel
Save