Download apps/web/src/components/console/IssueList.tsx from hunian003/message: direct link, hf CLI and curl.
- Browser
- Download file 2.65 kB
-
https://huggingface.co/spaces/hunian003/message/resolve/main/apps/web/src/components/console/IssueList.tsx
- Command line
-
hf download hf://spaces/hunian003/message/apps/web/src/components/console/IssueList.tsx
-
curl -L -o IssueList.tsx https://huggingface.co/spaces/hunian003/message/resolve/main/apps/web/src/components/console/IssueList.tsx
2.65 kB
| import React from 'react'; | |
| import { cn } from '@/lib/utils'; | |
| import { AlertTriangle, Info, XCircle } from 'lucide-react'; | |
| /** | |
| * 控制台问题列表组件 | |
| * 用于展示错误、警告、信息等诊断问题 | |
| */ | |
| export type IssueSeverity = 'error' | 'warning' | 'info'; | |
| export interface Issue { | |
| /** 问题唯一标识 */ | |
| id: string; | |
| /** 严重程度 */ | |
| severity: IssueSeverity; | |
| /** 问题消息 */ | |
| message: string; | |
| /** 可选的来源或位置 */ | |
| source?: string; | |
| } | |
| interface IssueListProps { | |
| /** 问题列表 */ | |
| issues: Issue[]; | |
| /** 空状态文案 */ | |
| emptyText?: string; | |
| /** 额外的 className */ | |
| className?: string; | |
| /** 问题点击回调 */ | |
| onIssueClick?: (issue: Issue) => void; | |
| } | |
| // 严重程度图标映射 | |
| const severityIcons: Record<IssueSeverity, React.ReactNode> = { | |
| error: <XCircle className="w-3.5 h-3.5 text-console-status-error" />, | |
| warning: <AlertTriangle className="w-3.5 h-3.5 text-console-status-warning" />, | |
| info: <Info className="w-3.5 h-3.5 text-console-status-info" />, | |
| }; | |
| // 严重程度背景色映射 | |
| const severityBg: Record<IssueSeverity, string> = { | |
| error: 'bg-console-status-error-bg', | |
| warning: 'bg-console-status-warning-bg', | |
| info: 'bg-console-status-info-bg', | |
| }; | |
| /** | |
| * 问题列表组件 | |
| * 用于控制台中展示诊断问题 | |
| */ | |
| export function IssueList({ | |
| issues, | |
| emptyText = '暂无问题', | |
| className, | |
| onIssueClick, | |
| }: IssueListProps) { | |
| if (issues.length === 0) { | |
| return ( | |
| <div className={cn('py-4 text-center text-xs text-console-text-muted', className)}> | |
| {emptyText} | |
| </div> | |
| ); | |
| } | |
| return ( | |
| <ul className={cn('space-y-1', className)} role="list"> | |
| {issues.map((issue) => ( | |
| <li | |
| key={issue.id} | |
| className={cn( | |
| 'flex items-start gap-2 px-2 py-1.5 rounded-console-sm text-xs', | |
| severityBg[issue.severity], | |
| onIssueClick && 'cursor-pointer hover:opacity-80' | |
| )} | |
| onClick={() => onIssueClick?.(issue)} | |
| role={onIssueClick ? 'button' : undefined} | |
| tabIndex={onIssueClick ? 0 : undefined} | |
| > | |
| {/* 图标 */} | |
| <span className="mt-0.5 shrink-0" aria-hidden="true"> | |
| {severityIcons[issue.severity]} | |
| </span> | |
| {/* 内容 */} | |
| <div className="flex-1 min-w-0"> | |
| <span className="text-console-text-primary">{issue.message}</span> | |
| {issue.source && ( | |
| <span className="ml-1 text-console-text-muted"> | |
| ({issue.source}) | |
| </span> | |
| )} | |
| </div> | |
| </li> | |
| ))} | |
| </ul> | |
| ); | |
| } | |