diff --git a/web/src/components/Settings/ConfigPage.tsx b/web/src/components/Settings/ConfigPage.tsx index a378e62..6f49576 100644 --- a/web/src/components/Settings/ConfigPage.tsx +++ b/web/src/components/Settings/ConfigPage.tsx @@ -49,7 +49,7 @@ export function ConfigPage({ onClose, onSaveConnection, initialTab }: ConfigPage const [error, setError] = useState(''); const [toast, setToastState] = useState(''); const [dirty, setDirty] = useState(false); - const [showRestartDialog, setShowRestartDialog] = useState(false); + const [restartDialogMode, setRestartDialogMode] = useState<'saved' | 'manual' | null>(null); const [restarting, setRestarting] = useState(false); // toast 自动清除:每次设置非空 toast 时启动 3s 计时器 @@ -77,9 +77,13 @@ export function ConfigPage({ onClose, onSaveConnection, initialTab }: ConfigPage }, []); const handleClose = useCallback(() => { + if (restarting) { + showToast('服务正在重启,请等待完成'); + return; + } if (dirty && !confirm('有未保存的更改,确定要关闭吗?')) return; onClose(); - }, [dirty, onClose]); + }, [dirty, restarting, showToast, onClose]); // Load config useEffect(() => { @@ -93,11 +97,18 @@ export function ConfigPage({ onClose, onSaveConnection, initialTab }: ConfigPage // ESC 关闭(子模态框的 ESC 在 capture 阶段已 stopPropagation,不会触发此处) useEffect(() => { const h = (e: KeyboardEvent) => { - if (e.key === 'Escape') handleClose(); + if (e.key === 'Escape') { + // 重启确认对话框打开时,ESC 仅关闭对话框,不关闭整个页面 + if (restartDialogMode !== null) { + setRestartDialogMode(null); + return; + } + handleClose(); + } }; document.addEventListener('keydown', h); return () => document.removeEventListener('keydown', h); - }, [handleClose]); + }, [handleClose, restartDialogMode]); const update = useCallback((key: K, value: AppConfig[K]) => { setConfig((prev) => (prev ? { ...prev, [key]: value } : prev)); @@ -115,13 +126,13 @@ export function ConfigPage({ onClose, onSaveConnection, initialTab }: ConfigPage // Config is now synced to both disk and in-memory state, // so the local state is already correct. No need to re-fetch. setDirty(false); - setShowRestartDialog(true); + setRestartDialogMode('saved'); } setSaving(false); }; const handleRestart = async () => { - setShowRestartDialog(false); + setRestartDialogMode(null); setRestarting(true); try { const { status, data } = await restartGateway(); @@ -289,12 +300,21 @@ export function ConfigPage({ onClose, onSaveConnection, initialTab }: ConfigPage + {/* Toast */} @@ -310,7 +330,7 @@ export function ConfigPage({ onClose, onSaveConnection, initialTab }: ConfigPage )} {/* Restart confirmation dialog */} - {showRestartDialog && ( + {restartDialogMode && (
@@ -318,16 +338,24 @@ export function ConfigPage({ onClose, onSaveConnection, initialTab }: ConfigPage
-

配置已保存

-

是否立即重启服务使配置生效?

+

+ {restartDialogMode === 'saved' ? '配置已保存' : '重启服务'} +

+

+ {restartDialogMode === 'saved' + ? '是否立即重启服务使配置生效?' + : dirty + ? '有未保存的更改,重启后将丢失。确定要重启吗?' + : '确定要重启服务吗?'} +