refactor(agent-editor): save only on explicit action

main
sp mac bookpro 2605 2026-05-29 19:27:41 +08:00
parent f0271c9027
commit e2855e0e46
1 changed files with 31 additions and 11 deletions

View File

@ -107,7 +107,7 @@ export default function AgentEditor() {
const [saving, setSaving] = useState(false);
const [teams, setTeams] = useState<Team[]>([]);
const [models, setModels] = useState<AiModel[]>([]);
const [autoSaveStatus, setAutoSaveStatus] = useState<'saved' | 'saving' | 'error'>('saved');
const [autoSaveStatus, setAutoSaveStatus] = useState<'saved' | 'dirty' | 'saving' | 'error'>('saved');
const [initModalOpen, setInitModalOpen] = useState(isNew);
const [selectedAvatar, setSelectedAvatar] = useState(DEFAULT_AVATAR);
const [avatarSelectorOpen, setAvatarSelectorOpen] = useState(false);
@ -121,14 +121,22 @@ export default function AgentEditor() {
const [editingSkillId, setEditingSkillId] = useState<string | null>(null);
const pollTimer = useRef<number | null>(null);
const hydratingRef = useRef(false);
const refresh = async () => {
const refresh = async (force = false) => {
if (!id) return;
const data = await AgentAPI.detail(id);
setAgent(data);
form.setFieldsValue(data);
setAgentName(data.name);
setSelectedAvatar(data.avatar || DEFAULT_AVATAR);
if (force || autoSaveStatus !== 'dirty') {
hydratingRef.current = true;
form.setFieldsValue(data);
window.setTimeout(() => {
hydratingRef.current = false;
}, 0);
setAutoSaveStatus('saved');
setAgentName(data.name);
setSelectedAvatar(data.avatar || DEFAULT_AVATAR);
}
// 若有索引中文件 → 启动轮询
const indexing = data.knowledge?.some((k) => k.status === 'pending' || k.status === 'indexing');
@ -162,7 +170,7 @@ export default function AgentEditor() {
});
} else {
setInitModalOpen(false);
refresh();
refresh(true);
}
return () => {
if (pollTimer.current) {
@ -202,7 +210,7 @@ export default function AgentEditor() {
try {
await AgentAPI.update(id!, values);
if (!silent) message.success('已保存');
refresh();
await refresh(true);
setAutoSaveStatus('saved');
} catch (e) {
setAutoSaveStatus('error');
@ -266,7 +274,7 @@ export default function AgentEditor() {
return Upload.LIST_IGNORE;
};
const liveAgent = agent || (form.getFieldsValue() as Agent);
const liveAgent = { ...(agent ?? {}), ...(form.getFieldsValue() as Agent) } as Agent;
const currentName = liveAgent?.name || agentName || '未命名智能体';
return (
@ -303,7 +311,13 @@ export default function AgentEditor() {
className="text-xs text-gray-400"
style={{ color: 'var(--color-text-tertiary)' }}
>
{autoSaveStatus === 'saving' ? '正在保存...' : '更改已自动保存'}
{autoSaveStatus === 'saving'
? '正在保存...'
: autoSaveStatus === 'dirty'
? '有未保存更改'
: autoSaveStatus === 'error'
? '保存失败'
: '已保存'}
</span>
<Button
icon={<FileTextOutlined />}
@ -350,7 +364,10 @@ export default function AgentEditor() {
<Form
form={form}
layout="vertical"
onValuesChange={() => handleSave(true)}
onValuesChange={() => {
if (hydratingRef.current) return;
setAutoSaveStatus('dirty');
}}
>
<div className="agent-editor-surface agent-editor-prompt-wrap">
<div style={{ fontSize: 12.5, color: 'var(--color-text-secondary)', marginBottom: 10, paddingInline: 4 }}></div>
@ -395,7 +412,10 @@ export default function AgentEditor() {
<Form
form={form}
layout="vertical"
onValuesChange={() => handleSave(true)}
onValuesChange={() => {
if (hydratingRef.current) return;
setAutoSaveStatus('dirty');
}}
>
<div
className="agent-editor-intro"