UNPKG

@mcp-shark/mcp-shark

Version:

Aggregate multiple Model Context Protocol (MCP) servers into a single unified interface with a powerful monitoring UI. Prov deep visibility into every request and response.

243 lines (238 loc) 7.58 kB
import { colors, fonts, withOpacity } from './theme'; function LogTable({ logs, selected, onSelect }) { const getStatusColor = (status) => { if (status === 'error') return colors.error; if (status === 'success') return colors.success; if (status === 'pending') return colors.warning; return colors.textTertiary; }; const formatTime = (iso) => { return new Date(iso).toLocaleTimeString(); }; return ( <div style={{ flex: 1, overflow: 'auto', background: colors.bgPrimary }}> <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: '12px', fontFamily: fonts.body, }} > <thead style={{ position: 'sticky', top: 0, background: colors.bgCard, zIndex: 1, boxShadow: `0 2px 4px ${colors.shadowSm}`, }} > <tr> <th style={{ padding: '12px 16px', textAlign: 'left', borderBottom: `1px solid ${colors.borderLight}`, color: colors.textSecondary, fontWeight: '600', fontSize: '11px', textTransform: 'uppercase', letterSpacing: '0.05em', background: colors.bgCard, }} > Time </th> <th style={{ padding: '12px 16px', textAlign: 'left', borderBottom: `1px solid ${colors.borderLight}`, color: colors.textSecondary, fontWeight: '600', fontSize: '11px', textTransform: 'uppercase', letterSpacing: '0.05em', background: colors.bgCard, }} > Server </th> <th style={{ padding: '12px 16px', textAlign: 'left', borderBottom: `1px solid ${colors.borderLight}`, color: colors.textSecondary, fontWeight: '600', fontSize: '11px', textTransform: 'uppercase', letterSpacing: '0.05em', background: colors.bgCard, }} > Dir </th> <th style={{ padding: '12px 16px', textAlign: 'left', borderBottom: `1px solid ${colors.borderLight}`, color: colors.textSecondary, fontWeight: '600', fontSize: '11px', textTransform: 'uppercase', letterSpacing: '0.05em', background: colors.bgCard, }} > Method </th> <th style={{ padding: '12px 16px', textAlign: 'left', borderBottom: `1px solid ${colors.borderLight}`, color: colors.textSecondary, fontWeight: '600', fontSize: '11px', textTransform: 'uppercase', letterSpacing: '0.05em', background: colors.bgCard, }} > Status </th> <th style={{ padding: '12px 16px', textAlign: 'right', borderBottom: `1px solid ${colors.borderLight}`, color: colors.textSecondary, fontWeight: '600', fontSize: '11px', textTransform: 'uppercase', letterSpacing: '0.05em', background: colors.bgCard, }} > Duration </th> <th style={{ padding: '12px 16px', textAlign: 'right', borderBottom: `1px solid ${colors.borderLight}`, color: colors.textSecondary, fontWeight: '600', fontSize: '11px', textTransform: 'uppercase', letterSpacing: '0.05em', background: colors.bgCard, }} > Size </th> </tr> </thead> <tbody> {logs.map((log) => ( <tr key={log.id} onClick={() => onSelect(log)} style={{ cursor: 'pointer', background: selected?.id === log.id ? colors.bgSelected : colors.bgCard, borderBottom: `1px solid ${colors.borderLight}`, transition: 'background-color 0.15s ease', }} onMouseEnter={(e) => { if (selected?.id !== log.id) e.currentTarget.style.background = colors.bgHover; }} onMouseLeave={(e) => { if (selected?.id !== log.id) e.currentTarget.style.background = colors.bgCard; }} > <td style={{ padding: '16px', color: colors.textTertiary, fontFamily: fonts.mono, fontSize: '12px', }} > {formatTime(log.timestamp_iso)} </td> <td style={{ padding: '16px', color: colors.textPrimary, fontSize: '12px', fontFamily: fonts.body, }} > {log.server_name} </td> <td style={{ padding: '16px', color: log.direction === 'request' ? colors.accentBlue : colors.accentOrange, fontSize: '12px', fontWeight: '500', fontFamily: fonts.body, }} > {log.direction} </td> <td style={{ padding: '16px', color: colors.textPrimary, fontSize: '12px', fontFamily: fonts.body, }} > {log.method || '-'} </td> <td style={{ padding: '16px', color: getStatusColor(log.status), fontSize: '12px', fontWeight: '500', fontFamily: fonts.body, }} > {log.status || '-'} </td> <td style={{ padding: '16px', textAlign: 'right', color: colors.textSecondary, fontSize: '12px', fontFamily: fonts.mono, }} > {log.duration_ms ? `${log.duration_ms.toFixed(2)}ms` : '-'} </td> <td style={{ padding: '16px', textAlign: 'right', color: colors.textSecondary, fontSize: '12px', fontFamily: fonts.mono, }} > {log.payload_size ? `${(log.payload_size / 1024).toFixed(1)}KB` : '-'} </td> </tr> ))} </tbody> </table> </div> ); } export default LogTable;