Add storage
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { Modal, List, Button, Toast, Typography, Spin, Popconfirm } from '@douyinfe/semi-ui';
|
||||
import { IconHistory, IconRotate } from '@douyinfe/semi-icons';
|
||||
import { useNoteStore } from '../../stores/useNoteStore';
|
||||
import noteService from '../../services/note.service';
|
||||
import type { IHistory } from '../../types';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export default function NoteHistoryModal({ visible, onClose }: Props) {
|
||||
const { currentNoteId, setCurrentNote } = useNoteStore();
|
||||
const [list, setList] = useState<IHistory[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!visible || !currentNoteId) return;
|
||||
setLoading(true);
|
||||
noteService
|
||||
.getHistory(currentNoteId)
|
||||
.then((res) => setList(res.data ?? []))
|
||||
.catch(() => Toast.error('加载历史版本失败'))
|
||||
.finally(() => setLoading(false));
|
||||
}, [visible, currentNoteId]);
|
||||
|
||||
const handleRestore = useCallback(
|
||||
async (item: IHistory) => {
|
||||
try {
|
||||
const res = await noteService.getHistoryContent(item.id);
|
||||
const h = res.data;
|
||||
// Restore: update note with history content
|
||||
await noteService.update(h.nid, h.title, h.context);
|
||||
// Reload the current note into the editor
|
||||
const noteRes = await noteService.get(h.nid);
|
||||
const note = noteRes.data;
|
||||
setCurrentNote(note.id, note.title, note.context);
|
||||
Toast.success(`已恢复到 ${h.createtime} 的版本`);
|
||||
onClose();
|
||||
} catch {
|
||||
Toast.error('恢复失败');
|
||||
}
|
||||
},
|
||||
[setCurrentNote, onClose],
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={
|
||||
<span>
|
||||
<IconHistory style={{ marginRight: 8 }} />
|
||||
历史版本
|
||||
</span>
|
||||
}
|
||||
visible={visible}
|
||||
onCancel={onClose}
|
||||
footer={null}
|
||||
width={520}
|
||||
>
|
||||
{loading ? (
|
||||
<div style={{ textAlign: 'center', padding: 32 }}>
|
||||
<Spin size="large" />
|
||||
</div>
|
||||
) : list.length === 0 ? (
|
||||
<div style={{ textAlign: 'center', padding: 32, color: 'var(--semi-color-text-2)' }}>
|
||||
暂无历史版本
|
||||
</div>
|
||||
) : (
|
||||
<List
|
||||
dataSource={list}
|
||||
renderItem={(item: IHistory) => (
|
||||
<List.Item
|
||||
main={
|
||||
<div>
|
||||
<Text strong style={{ display: 'block' }}>{item.title}</Text>
|
||||
<Text type="tertiary" size="small">{item.createtime}</Text>
|
||||
</div>
|
||||
}
|
||||
extra={
|
||||
<Popconfirm
|
||||
title="确认恢复"
|
||||
content="恢复后当前内容将被该版本覆盖,确定吗?"
|
||||
onConfirm={() => void handleRestore(item)}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
>
|
||||
<Button
|
||||
size="small"
|
||||
type="secondary"
|
||||
icon={<IconRotate />}
|
||||
>
|
||||
恢复
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user