refactor(agent-editor): save only on explicit action
parent
f0271c9027
commit
e2855e0e46
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue