Skip to content

Commit eb7aeed

Browse files
committed
feat: 集成Profile和历史记录功能到核心页面
- 在PromptTemplate.tsx中集成Profile选择和保存功能 - 在MarkdownEditor.tsx中集成历史记录和文件过滤功能 - 支持Profile的切换和当前配置保存 - 支持历史记录的自动保存和手动管理 - 支持文件过滤条件设置和应用 - 添加工具栏和状态提示,提升用户体验
1 parent dd2f31b commit eb7aeed

File tree

2 files changed

+314
-13
lines changed

2 files changed

+314
-13
lines changed

src/pages/MarkdownEditor.tsx

Lines changed: 151 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,29 @@ import FileUpload from './FileUpload';
44
import CopyButton from './CopyButton';
55
import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter';
66
import {materialLight} from 'react-syntax-highlighter/dist/esm/styles/prism';
7-
import {Box, Dialog, DialogContent, DialogTitle, IconButton, TextField, Typography} from '@mui/material';
7+
import {Box, Dialog, DialogContent, DialogTitle, IconButton, TextField, Typography, Button, Tooltip} from '@mui/material';
88
import CloseIcon from '@mui/icons-material/Close';
99
import DeleteIcon from '@mui/icons-material/Delete';
1010
import DeleteForever from '@mui/icons-material/DeleteForever';
11+
import HistoryIcon from '@mui/icons-material/History';
12+
import FilterListIcon from '@mui/icons-material/FilterList';
13+
import SaveIcon from '@mui/icons-material/Save';
1114
import './styles.css';
12-
13-
interface FileInfo {
14-
name: string;
15-
path: string;
16-
size: number;
17-
extension: string;
18-
content: string;
19-
}
15+
import { FileInfo } from '../types/types';
16+
import { HistoryRecord, FileFilter, DEFAULT_FILE_FILTER } from '../types/history';
17+
import { historyDB } from '../utils/indexedDB';
18+
import { applyFileFilter, getFilterStats } from '../utils/fileFilter';
19+
import HistoryPanel from '../components/HistoryPanel';
20+
import FileFilterComponent from '../components/FileFilter';
2021

2122
interface MarkdownEditorProps {
2223
ruleContent: string;
2324
roleContent: string;
2425
outputContent: string;
26+
onLoadFromHistory?: (record: HistoryRecord) => void;
2527
}
2628

27-
const MarkdownEditor: React.FC<MarkdownEditorProps> = ({ruleContent, roleContent, outputContent}) => {
29+
const MarkdownEditor: React.FC<MarkdownEditorProps> = ({ruleContent, roleContent, outputContent, onLoadFromHistory}) => {
2830
const [markdownContent, setMarkdownContent] = useState(() => {
2931
const saved = localStorage.getItem('markdownContent');
3032
return saved || '';
@@ -37,6 +39,29 @@ const MarkdownEditor: React.FC<MarkdownEditorProps> = ({ruleContent, roleContent
3739
const [isDialogOpen, setIsDialogOpen] = useState(false);
3840
const previewContentRef = useRef<HTMLDivElement>(null);
3941

42+
// 新增状态
43+
const [historyPanelOpen, setHistoryPanelOpen] = useState(false);
44+
const [fileFilterOpen, setFileFilterOpen] = useState(false);
45+
const [fileFilter, setFileFilter] = useState<FileFilter>(() => {
46+
const saved = localStorage.getItem('fileFilter');
47+
return saved ? JSON.parse(saved) : DEFAULT_FILE_FILTER;
48+
});
49+
const [originalFiles, setOriginalFiles] = useState<FileInfo[]>([]);
50+
const [isDBInitialized, setIsDBInitialized] = useState(false);
51+
52+
// 初始化IndexedDB
53+
useEffect(() => {
54+
const initDB = async () => {
55+
try {
56+
await historyDB.init();
57+
setIsDBInitialized(true);
58+
} catch (error) {
59+
console.error('Failed to initialize IndexedDB:', error);
60+
}
61+
};
62+
initDB();
63+
}, []);
64+
4065
// 持久化markdown内容
4166
useEffect(() => {
4267
const timer = setTimeout(() => {
@@ -64,9 +89,20 @@ const MarkdownEditor: React.FC<MarkdownEditorProps> = ({ruleContent, roleContent
6489
}
6590
}, [previewFile]);
6691

92+
// 持久化文件过滤器设置
93+
useEffect(() => {
94+
localStorage.setItem('fileFilter', JSON.stringify(fileFilter));
95+
}, [fileFilter]);
96+
6797
const handleFilesUploaded = (newFiles: FileInfo[]) => {
98+
// 保存原始文件
99+
setOriginalFiles(newFiles);
100+
101+
// 应用过滤器
102+
const filteredFiles = applyFileFilter(newFiles, fileFilter);
103+
68104
setFiles(prev => {
69-
const updatedFiles = [...prev, ...newFiles];
105+
const updatedFiles = [...prev, ...filteredFiles];
70106
// 去重逻辑
71107
const uniqueFiles = updatedFiles.reduce((acc, current) => {
72108
if (!acc.some(file => file.path === current.path)) {
@@ -78,6 +114,52 @@ const MarkdownEditor: React.FC<MarkdownEditorProps> = ({ruleContent, roleContent
78114
});
79115
};
80116

117+
// 保存当前状态为历史记录
118+
const saveToHistory = async () => {
119+
if (!isDBInitialized) return;
120+
121+
try {
122+
const record: HistoryRecord = {
123+
id: `history_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
124+
timestamp: Date.now(),
125+
title: `构造记录 ${new Date().toLocaleString('zh-CN')}`,
126+
description: '',
127+
roleContent,
128+
ruleContent,
129+
taskContent: markdownContent,
130+
outputContent,
131+
files,
132+
tags: [],
133+
version: 1
134+
};
135+
136+
await historyDB.saveRecord(record);
137+
console.log('History record saved successfully');
138+
} catch (error) {
139+
console.error('Failed to save history record:', error);
140+
}
141+
};
142+
143+
// 从历史记录加载
144+
const loadFromHistory = (record: HistoryRecord) => {
145+
setMarkdownContent(record.taskContent);
146+
setFiles(record.files);
147+
// 通知父组件更新其他内容
148+
if (onLoadFromHistory) {
149+
onLoadFromHistory(record);
150+
}
151+
console.log('Loaded from history:', record.title);
152+
};
153+
154+
// 应用文件过滤器
155+
const applyFilter = (newFilter: FileFilter) => {
156+
setFileFilter(newFilter);
157+
if (originalFiles.length > 0) {
158+
const filteredFiles = applyFileFilter(originalFiles, newFilter);
159+
setFiles(filteredFiles);
160+
}
161+
};
162+
81163
const formatFileSize = (bytes: number) => {
82164
const units = ['B', 'KB', 'MB', 'GB'];
83165
let size = bytes;
@@ -121,6 +203,49 @@ const MarkdownEditor: React.FC<MarkdownEditorProps> = ({ruleContent, roleContent
121203
<div className="editor-container">
122204
<FileUpload onFilesUploaded={handleFilesUploaded}/>
123205

206+
{/* 工具栏 */}
207+
<Box display="flex" gap={1} mb={2} flexWrap="wrap">
208+
<Tooltip title="查看构造历史">
209+
<Button
210+
startIcon={<HistoryIcon />}
211+
onClick={() => setHistoryPanelOpen(true)}
212+
variant="outlined"
213+
size="small"
214+
>
215+
历史记录
216+
</Button>
217+
</Tooltip>
218+
219+
<Tooltip title="设置文件过滤条件">
220+
<Button
221+
startIcon={<FilterListIcon />}
222+
onClick={() => setFileFilterOpen(true)}
223+
variant="outlined"
224+
size="small"
225+
>
226+
文件过滤
227+
</Button>
228+
</Tooltip>
229+
230+
<Tooltip title="保存当前构造到历史记录">
231+
<Button
232+
startIcon={<SaveIcon />}
233+
onClick={saveToHistory}
234+
variant="outlined"
235+
size="small"
236+
disabled={!isDBInitialized}
237+
>
238+
保存历史
239+
</Button>
240+
</Tooltip>
241+
242+
{originalFiles.length > 0 && originalFiles.length !== files.length && (
243+
<Typography variant="caption" color="text.secondary" sx={{ alignSelf: 'center', ml: 1 }}>
244+
已过滤 {originalFiles.length - files.length} 个文件
245+
</Typography>
246+
)}
247+
</Box>
248+
124249
{files.length > 0 && (
125250
<div className="file-list">
126251
<Box display="flex" justifyContent="space-between" alignItems="center" mb={1}>
@@ -231,6 +356,21 @@ const MarkdownEditor: React.FC<MarkdownEditorProps> = ({ruleContent, roleContent
231356
files={files}
232357
/>
233358
</div>
359+
360+
{/* 历史记录面板 */}
361+
<HistoryPanel
362+
open={historyPanelOpen}
363+
onClose={() => setHistoryPanelOpen(false)}
364+
onLoadRecord={loadFromHistory}
365+
/>
366+
367+
{/* 文件过滤对话框 */}
368+
<FileFilterComponent
369+
open={fileFilterOpen}
370+
onClose={() => setFileFilterOpen(false)}
371+
filter={fileFilter}
372+
onFilterChange={applyFilter}
373+
/>
234374
</div>
235375
);
236376
};

0 commit comments

Comments
 (0)