From 80fb5b0c89501c79ceb22be3569bbe3b223859b1 Mon Sep 17 00:00:00 2001 From: parththakkar106 Date: Tue, 21 Jul 2026 16:01:42 +0530 Subject: [PATCH] Add explicit Save button to the schema JSON editor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The JSON view no longer parses/saves on every keystroke — you type freely and click "Save JSON" to apply. Invalid JSON (or a non-object) shows the parse error inline instead of auto-rejecting; valid JSON is pretty-printed, applied to the form/preview, and saved. The form editor still auto-saves. Co-Authored-By: Claude Opus 4.8 --- frontend/src/index.css | 7 ++++++ frontend/src/pages/ScenarioEditor.jsx | 34 ++++++++++++++++++--------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/frontend/src/index.css b/frontend/src/index.css index b5544f9..584bcd7 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -660,6 +660,13 @@ button:disabled { opacity: 0.45; cursor: default; transform: none; box-shadow: n color: var(--danger, #e5484d); font-size: 0.82rem; } +.schema-json-actions { + display: flex; + align-items: center; + gap: 12px; + margin-top: 8px; +} +.schema-json-actions .schema-error { margin-top: 0; } .schema-preview { margin-top: 14px; padding: 14px 16px; diff --git a/frontend/src/pages/ScenarioEditor.jsx b/frontend/src/pages/ScenarioEditor.jsx index 9476b5d..f00294f 100644 --- a/frontend/src/pages/ScenarioEditor.jsx +++ b/frontend/src/pages/ScenarioEditor.jsx @@ -43,32 +43,37 @@ export default function ScenarioEditor() { }) } - // RPG world-state schema: edited as raw JSON, only saved when it parses to an - // object (empty text clears the RPG layer). Invalid JSON shows an inline error - // and holds off saving. - const setSchema = (text) => { + // JSON view: typing only updates the text buffer; nothing is parsed or saved + // until the user clicks Save (so a half-typed edit doesn't spam errors). + const onJsonText = (text) => { setSchemaText(text) - const trimmed = text.trim() + if (schemaError) setSchemaError('') + } + + // Parse the JSON box on demand: apply + save if valid, else show the error. + const commitJson = () => { + const trimmed = schemaText.trim() if (!trimmed) { setSchemaError('') setParsedSchema(null) - debounceSave('stat_schema', () => saveSchema(null)) + saveSchema(null) return } let parsed try { parsed = JSON.parse(trimmed) } catch (err) { - setSchemaError(`Invalid JSON: ${err.message}`) // keep last-good preview + setSchemaError(`Invalid JSON: ${err.message}`) return } if (typeof parsed !== 'object' || Array.isArray(parsed)) { - setSchemaError('The schema must be a JSON object.') + setSchemaError('The schema must be a JSON object (e.g. { "player": { … } }).') return } setSchemaError('') setParsedSchema(parsed) - debounceSave('stat_schema', () => saveSchema(parsed)) + setSchemaText(JSON.stringify(parsed, null, 2)) // normalize / pretty-print + saveSchema(parsed) } const saveSchema = async (parsed) => { @@ -230,12 +235,19 @@ export default function ScenarioEditor() {