From 5ccf1da86bf40b10a60f36e15401ac30175b9017 Mon Sep 17 00:00:00 2001 From: Supra4E8C Date: Sat, 28 Feb 2026 13:33:20 +0800 Subject: [PATCH] fix(config-editor): preserve source YAML edits and empty keys --- src/hooks/useVisualConfig.ts | 6 +++++- src/pages/ConfigPage.tsx | 16 ++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/hooks/useVisualConfig.ts b/src/hooks/useVisualConfig.ts index 5cc6b5f..f66ef16 100644 --- a/src/hooks/useVisualConfig.ts +++ b/src/hooks/useVisualConfig.ts @@ -78,7 +78,11 @@ function setStringInDoc(doc: YamlDocument, path: YamlPath, value: unknown): void doc.setIn(path, safe); return; } - if (docHas(doc, path)) doc.deleteIn(path); + // Preserve existing empty-string keys to avoid dropping template blocks/comments. + // Only keep the key when it already exists in the YAML. + if (docHas(doc, path)) { + doc.setIn(path, ''); + } } function setIntFromStringInDoc(doc: YamlDocument, path: YamlPath, value: unknown): void { diff --git a/src/pages/ConfigPage.tsx b/src/pages/ConfigPage.tsx index 671edb9..26e1ef5 100644 --- a/src/pages/ConfigPage.tsx +++ b/src/pages/ConfigPage.tsx @@ -123,7 +123,8 @@ export function ConfigPage() { const handleSave = async () => { setSaving(true); try { - const nextMergedYaml = applyVisualChangesToYaml(content); + // In source mode, save exactly what the user edited. In visual mode, materialize visual changes into YAML. + const nextMergedYaml = activeTab === 'source' ? content : applyVisualChangesToYaml(content); const latestServerYaml = await configFileApi.fetchConfigYaml(); if (latestServerYaml === nextMergedYaml) { @@ -156,10 +157,13 @@ export function ConfigPage() { if (tab === activeTab) return; if (tab === 'source') { - const nextContent = applyVisualChangesToYaml(content); - if (nextContent !== content) { - setContent(nextContent); - setDirty(true); + // Only rewrite YAML when there are pending visual changes; otherwise preserve raw YAML + comments. + if (visualDirty) { + const nextContent = applyVisualChangesToYaml(content); + if (nextContent !== content) { + setContent(nextContent); + setDirty(true); + } } } else { loadVisualValuesFromYaml(content); @@ -167,7 +171,7 @@ export function ConfigPage() { setActiveTab(tab); localStorage.setItem('config-management:tab', tab); - }, [activeTab, applyVisualChangesToYaml, content, loadVisualValuesFromYaml]); + }, [activeTab, applyVisualChangesToYaml, content, loadVisualValuesFromYaml, visualDirty]); // Search functionality const performSearch = useCallback((query: string, direction: 'next' | 'prev' = 'next') => {