Files
AIclinicalresearch/frontend-v2/src/shared/components/Chat/CodeBlockRenderer.tsx
HaHafeng af325348b8 feat(dc): Complete Tool C Day 5 - AI Chat + Ant Design X Integration
Summary:
- Upgrade to Ant Design 6.0.1 + install Ant Design X (2.1.0) + X SDK (2.1.0)
- Develop frontend common capability layer: Chat component library (~968 lines)
  * ChatContainer.tsx - Core container component
  * MessageRenderer.tsx - Message renderer
  * CodeBlockRenderer.tsx - Code block renderer with syntax highlighting
  * Complete TypeScript types and documentation
- Integrate ChatContainer into Tool C
- Fix 7 critical UI issues:
  * AG Grid module registration error
  * UI refinement (borders, shadows, gradients)
  * Add AI welcome message
  * Auto-clear input field after sending
  * Remove page scrollbars
  * Manual code execution (not auto-run)
  * Support simple Q&A (new /ai/chat API)
- Complete end-to-end testing
- Update all documentation (4 status docs + 6 dev logs)

Technical Stack:
- Frontend: React 19 + Ant Design 6.0 + Ant Design X 2.1
- Components: Bubble, Sender from @ant-design/x
- Total code: ~5418 lines

Status: Tool C MVP completed, production ready
2025-12-07 22:02:14 +08:00

71 lines
1.8 KiB
TypeScript

/**
* CodeBlockRenderer - 代码块渲染器
*
* Tool C 专用:显示 AI 生成的代码,支持语法高亮和执行
*/
import React, { useEffect } from 'react';
import { Button } from 'antd';
import { PlayCircleOutlined, LoadingOutlined } from '@ant-design/icons';
import Prism from 'prismjs';
import 'prismjs/themes/prism-tomorrow.css';
import 'prismjs/components/prism-python';
import type { CodeBlockRendererProps } from './types';
export const CodeBlockRenderer: React.FC<CodeBlockRendererProps> = ({
code,
language = 'python',
onExecute,
isExecuting = false,
executionResult,
}) => {
// 语法高亮
useEffect(() => {
Prism.highlightAll();
}, [code]);
const handleExecute = () => {
if (onExecute && !isExecuting) {
onExecute(code);
}
};
return (
<div className="code-block-container">
<div className="code-block-header">
<span className="code-language">{language}</span>
{onExecute && (
<Button
type="primary"
size="small"
icon={isExecuting ? <LoadingOutlined /> : <PlayCircleOutlined />}
onClick={handleExecute}
disabled={isExecuting}
className="execute-button"
>
{isExecuting ? '执行中...' : '运行代码'}
</Button>
)}
</div>
<pre className="code-block">
<code className={`language-${language}`}>
{code}
</code>
</pre>
{executionResult && (
<div className={`execution-result ${executionResult.success ? 'success' : 'error'}`}>
{executionResult.success ? (
<span> </span>
) : (
<span> {executionResult.message || '执行失败'}</span>
)}
</div>
)}
</div>
);
};
export default CodeBlockRenderer;