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 [saving, setSaving] = useState(false);
|
||||||
const [teams, setTeams] = useState<Team[]>([]);
|
const [teams, setTeams] = useState<Team[]>([]);
|
||||||
const [models, setModels] = useState<AiModel[]>([]);
|
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 [initModalOpen, setInitModalOpen] = useState(isNew);
|
||||||
const [selectedAvatar, setSelectedAvatar] = useState(DEFAULT_AVATAR);
|
const [selectedAvatar, setSelectedAvatar] = useState(DEFAULT_AVATAR);
|
||||||
const [avatarSelectorOpen, setAvatarSelectorOpen] = useState(false);
|
const [avatarSelectorOpen, setAvatarSelectorOpen] = useState(false);
|
||||||
|
|
@ -121,14 +121,22 @@ export default function AgentEditor() {
|
||||||
const [editingSkillId, setEditingSkillId] = useState<string | null>(null);
|
const [editingSkillId, setEditingSkillId] = useState<string | null>(null);
|
||||||
|
|
||||||
const pollTimer = useRef<number | null>(null);
|
const pollTimer = useRef<number | null>(null);
|
||||||
|
const hydratingRef = useRef(false);
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async (force = false) => {
|
||||||
if (!id) return;
|
if (!id) return;
|
||||||
const data = await AgentAPI.detail(id);
|
const data = await AgentAPI.detail(id);
|
||||||
setAgent(data);
|
setAgent(data);
|
||||||
form.setFieldsValue(data);
|
if (force || autoSaveStatus !== 'dirty') {
|
||||||
setAgentName(data.name);
|
hydratingRef.current = true;
|
||||||
setSelectedAvatar(data.avatar || DEFAULT_AVATAR);
|
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');
|
const indexing = data.knowledge?.some((k) => k.status === 'pending' || k.status === 'indexing');
|
||||||
|
|
@ -162,7 +170,7 @@ export default function AgentEditor() {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setInitModalOpen(false);
|
setInitModalOpen(false);
|
||||||
refresh();
|
refresh(true);
|
||||||
}
|
}
|
||||||
return () => {
|
return () => {
|
||||||
if (pollTimer.current) {
|
if (pollTimer.current) {
|
||||||
|
|
@ -202,7 +210,7 @@ export default function AgentEditor() {
|
||||||
try {
|
try {
|
||||||
await AgentAPI.update(id!, values);
|
await AgentAPI.update(id!, values);
|
||||||
if (!silent) message.success('已保存');
|
if (!silent) message.success('已保存');
|
||||||
refresh();
|
await refresh(true);
|
||||||
setAutoSaveStatus('saved');
|
setAutoSaveStatus('saved');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setAutoSaveStatus('error');
|
setAutoSaveStatus('error');
|
||||||
|
|
@ -266,7 +274,7 @@ export default function AgentEditor() {
|
||||||
return Upload.LIST_IGNORE;
|
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 || '未命名智能体';
|
const currentName = liveAgent?.name || agentName || '未命名智能体';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -303,7 +311,13 @@ export default function AgentEditor() {
|
||||||
className="text-xs text-gray-400"
|
className="text-xs text-gray-400"
|
||||||
style={{ color: 'var(--color-text-tertiary)' }}
|
style={{ color: 'var(--color-text-tertiary)' }}
|
||||||
>
|
>
|
||||||
{autoSaveStatus === 'saving' ? '正在保存...' : '更改已自动保存'}
|
{autoSaveStatus === 'saving'
|
||||||
|
? '正在保存...'
|
||||||
|
: autoSaveStatus === 'dirty'
|
||||||
|
? '有未保存更改'
|
||||||
|
: autoSaveStatus === 'error'
|
||||||
|
? '保存失败'
|
||||||
|
: '已保存'}
|
||||||
</span>
|
</span>
|
||||||
<Button
|
<Button
|
||||||
icon={<FileTextOutlined />}
|
icon={<FileTextOutlined />}
|
||||||
|
|
@ -350,7 +364,10 @@ export default function AgentEditor() {
|
||||||
<Form
|
<Form
|
||||||
form={form}
|
form={form}
|
||||||
layout="vertical"
|
layout="vertical"
|
||||||
onValuesChange={() => handleSave(true)}
|
onValuesChange={() => {
|
||||||
|
if (hydratingRef.current) return;
|
||||||
|
setAutoSaveStatus('dirty');
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="agent-editor-surface agent-editor-prompt-wrap">
|
<div className="agent-editor-surface agent-editor-prompt-wrap">
|
||||||
<div style={{ fontSize: 12.5, color: 'var(--color-text-secondary)', marginBottom: 10, paddingInline: 4 }}>建议写清楚角色设定、目标用户、语气和回答结构。</div>
|
<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={form}
|
form={form}
|
||||||
layout="vertical"
|
layout="vertical"
|
||||||
onValuesChange={() => handleSave(true)}
|
onValuesChange={() => {
|
||||||
|
if (hydratingRef.current) return;
|
||||||
|
setAutoSaveStatus('dirty');
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="agent-editor-intro"
|
className="agent-editor-intro"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue