From 38b73858b29d9040e524fe1df5efa1e64a978759 Mon Sep 17 00:00:00 2001 From: CREDO23 Date: Fri, 29 May 2026 23:17:49 +0200 Subject: [PATCH] fix(json-view): coerce numeric strings to numbers on edit --- surfsense_web/components/json-view.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/surfsense_web/components/json-view.tsx b/surfsense_web/components/json-view.tsx index c293828b3..28ade824f 100644 --- a/surfsense_web/components/json-view.tsx +++ b/surfsense_web/components/json-view.tsx @@ -35,6 +35,23 @@ export interface JsonViewProps { className?: string; } +/** Recursively coerce string values that are valid JSON numbers back to numbers. + * react-json-view's text input always yields strings; this restores the + * correct type so filters like ``{ "folder_id": 56 }`` survive editing. */ +function coerceNumbers(value: unknown): unknown { + if (typeof value === "string") { + const n = Number(value); + return !Number.isNaN(n) && value.trim() !== "" ? n : value; + } + if (Array.isArray(value)) return value.map(coerceNumbers); + if (value && typeof value === "object") { + return Object.fromEntries( + Object.entries(value as Record).map(([k, v]) => [k, coerceNumbers(v)]) + ); + } + return value; +} + const DARK_THEME = "monokai" as const; const LIGHT_THEME = "rjv-default" as const; @@ -67,7 +84,7 @@ export function JsonView({ const handleChange = useCallback( (interaction: InteractionProps) => { - onChange?.(interaction.updated_src); + onChange?.(coerceNumbers(interaction.updated_src)); return true; }, [onChange]