From 7d19159756526cdf87026a0bf3f4ca3aa0bd6228 Mon Sep 17 00:00:00 2001 From: pzyyll Date: Sat, 2 May 2026 14:53:00 +0800 Subject: [PATCH] fix(json-editor): show existing JSON data in visual mode on initial mount Previously, the JsonEditor rows state was initialized as an empty array, while the value and jsonValue states were initialized to the prop value. The useEffect guard `value !== jsonValue` would always be false on mount, preventing parseJsonToRows from ever running. This caused visual mode to display empty state even when the value prop contained valid JSON. Now, rows is initialized synchronously via a lazy useState initializer using a shared parseJsonRows helper, which also replaces the inline parse logic. Invalid JSON values still gracefully fall through to empty rows (null return preserved on parse failure). --- web/default/src/components/json-editor.tsx | 38 ++++++++++++---------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/web/default/src/components/json-editor.tsx b/web/default/src/components/json-editor.tsx index e38f4469f04..9024a511bc6 100644 --- a/web/default/src/components/json-editor.tsx +++ b/web/default/src/components/json-editor.tsx @@ -25,6 +25,23 @@ type EditorRow = { value: string } +function parseJsonRows(json: string): EditorRow[] | null { + try { + if (!json.trim()) { + return [] + } + + const parsed = JSON.parse(json) + return Object.entries(parsed).map(([key, val], index) => ({ + id: `${Date.now()}-${index}`, + key, + value: typeof val === 'object' ? JSON.stringify(val) : String(val), + })) + } catch (_error) { + return null + } +} + export function JsonEditor({ value, onChange, @@ -45,26 +62,13 @@ export function JsonEditor({ const resolvedKeyLabel = keyLabel ?? t('Key') const resolvedValueLabel = valueLabel ?? t('Value') const [mode, setMode] = useState<'visual' | 'json'>('visual') - const [rows, setRows] = useState([]) + const [rows, setRows] = useState(() => parseJsonRows(value) ?? []) const [jsonValue, setJsonValue] = useState(value) const parseJsonToRows = (json: string) => { - try { - if (!json.trim()) { - setRows([]) - return - } - const parsed = JSON.parse(json) - const newRows: EditorRow[] = Object.entries(parsed).map( - ([key, val], index) => ({ - id: `${Date.now()}-${index}`, - key, - value: typeof val === 'object' ? JSON.stringify(val) : String(val), - }) - ) - setRows(newRows) - } catch (_error) { - // Invalid JSON, keep current rows + const parsedRows = parseJsonRows(json) + if (parsedRows) { + setRows(parsedRows) } }