import classNames from 'classnames'; import { format } from 'date-fns'; import type { CSSProperties } from 'react'; import React, { useMemo, useState } from 'react'; import { useGrpcConnections } from '../hooks/useGrpcConnections'; import { useGrpcMessages } from '../hooks/useGrpcMessages'; import type { GrpcRequest } from '../lib/models'; import { Icon } from './core/Icon'; import { JsonAttributeTree } from './core/JsonAttributeTree'; import { Separator } from './core/Separator'; import { SplitLayout } from './core/SplitLayout'; import { HStack } from './core/Stacks'; import { RecentConnectionsDropdown } from './RecentConnectionsDropdown'; interface Props { style?: CSSProperties; className?: string; activeRequest: GrpcRequest; methodType: | 'unary' | 'client_streaming' | 'server_streaming' | 'streaming' | 'no-schema' | 'no-method'; } export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }: Props) { const [activeMessageId, setActiveMessageId] = useState(null); const connections = useGrpcConnections(activeRequest.id ?? null); const activeConnection = connections[0] ?? null; const messages = useGrpcMessages(activeConnection?.id ?? null); const activeMessage = useMemo( () => messages.find((m) => m.id === activeMessageId) ?? null, [activeMessageId, messages], ); return ( (
{messages.filter((m) => !m.isInfo).length} messages {activeConnection?.elapsed === 0 && ( )} {activeConnection && ( { // todo }} /> )}
{...messages.map((m) => ( { if (m.id === activeMessageId) setActiveMessageId(null); else setActiveMessageId(m.id); }} alignItems="center" className={classNames( 'px-2 py-1 font-mono cursor-default group', m === activeMessage && '!bg-highlight', )} >
{m.message}
{format(m.createdAt, 'HH:mm:ss')}
))}
)} secondSlot={ activeMessage && (() => (
{activeMessage.isInfo ? ( {activeMessage.message} ) : ( )}
)) } /> ); }