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
This commit is contained in:
70
frontend-v2/src/shared/components/Chat/CodeBlockRenderer.tsx
Normal file
70
frontend-v2/src/shared/components/Chat/CodeBlockRenderer.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 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;
|
||||
Reference in New Issue
Block a user