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() {