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
71 lines
1.8 KiB
TypeScript
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;
|