Files
lislgosms/src/apps/admin/channels/ChannelLogModal.tsx
T

82 lines
3.2 KiB
TypeScript

import { Button, Input, Modal, Tag } from '@/components/ui';
import { formatDateTime } from '@/utils/dateTime';
import { connectionStatusLabelMap, formatLogDetail } from './channelModel';
import type { ChannelLogState } from './channelTypes';
export function ChannelLogModal({
logState,
keyword,
onKeywordChange,
onClose,
}: {
logState: ChannelLogState;
keyword: string;
onKeywordChange: (keyword: string) => void;
onClose: () => void;
}) {
const normalizedKeyword = keyword.trim().toLowerCase();
const filteredLogs = (logState.data?.logs ?? []).filter((log) =>
!normalizedKeyword
|| `${log.event} ${log.resourceId ?? ''} ${formatLogDetail(log.detail)}`.toLowerCase().includes(normalizedKeyword),
);
return (
<Modal
footer={<Button onClick={onClose} variant="ghost">关闭</Button>}
onClose={onClose}
open
size="xl"
title={<div className="template-modal-title"><h2>连接日志</h2><p>{logState.channel.name}</p></div>}
>
<div className="channel-log-modal">
{logState.data ? (
<div className="channel-connection-summary">
{logState.data.connectionStates.map((connection) => (
<article key={connection.id}>
<div>
<span>连接 ID</span>
<strong>{connection.connectionId}</strong>
</div>
<Tag tone={connection.status === 'connected' ? 'success' : connection.lastError ? 'danger' : 'info'}>
{connectionStatusLabelMap[connection.status] ?? connection.status}
</Tag>
<div>
<span>当前 / 期望</span>
<strong>{connection.currentConnections} / {connection.desiredConnections}</strong>
</div>
<div>
<span>最近心跳</span>
<strong>{formatDateTime(connection.lastHeartbeatAt)}</strong>
</div>
<div>
<span>自动重连</span>
<strong>{connection.reconnectCount} / {formatDateTime(connection.nextReconnectAt)}</strong>
</div>
{connection.lastError ? <p>{connection.lastError}</p> : null}
</article>
))}
{logState.data.connectionStates.length === 0 ? <p className="muted">暂无连接状态回写</p> : null}
</div>
) : null}
<Input label="筛选日志" onChange={(event) => onKeywordChange(event.target.value)} placeholder="事件、资源或详情关键词" value={keyword} />
<div className="channel-log-list">
{filteredLogs.map((log) => (
<article className="channel-log-item" key={log.id}>
<div>
<strong>{log.event}</strong>
<span>{formatDateTime(log.time)}</span>
</div>
<div>
<span>{log.resourceId}</span>
<pre>{formatLogDetail(log.detail)}</pre>
</div>
</article>
))}
{logState.data && filteredLogs.length === 0 ? <p className="muted">未找到匹配的连接日志</p> : null}
{!logState.data ? <p className="muted">正在加载连接日志...</p> : null}
</div>
</div>
</Modal>
);
}