11import { observable , reaction , runInAction } from "mobx" ;
2- import { useCallback , useEffect , useMemo , useState } from "react" ;
2+ import { useCallback , useEffect , useMemo , useRef , useState } from "react" ;
33import { PlaygroundDataV2 } from "@mendix/shared-charts/main" ;
4+ import { isEquivalentJson , prettifyJson } from "./editorJson" ;
45import { ComposedEditorProps } from "../components/ComposedEditor" ;
56import { SelectOption } from "../components/Sidebar" ;
67
@@ -29,14 +30,6 @@ function getModelerCode(data: PlaygroundDataV2, key: ConfigKey): object {
2930 return Object . fromEntries ( entries ) ;
3031}
3132
32- function prettifyJson ( json : string ) : string {
33- try {
34- return JSON . stringify ( JSON . parse ( json ) , null , 2 ) ;
35- } catch {
36- return '{ "error": "invalid JSON" }' ;
37- }
38- }
39-
4033export function useV2EditorController ( context : PlaygroundDataV2 ) : ComposedEditorProps {
4134 const [ key , setKey ] = useState < ConfigKey > ( "layout" ) ;
4235 const keyBox = useState ( ( ) => observable . box < ConfigKey > ( key ) ) [ 0 ] ;
@@ -69,12 +62,14 @@ export function useV2EditorController(context: PlaygroundDataV2): ComposedEditor
6962
7063 const code = prettifyJson ( getEditorCode ( store , key ) ) ;
7164 const [ input , setInput ] = useState ( ( ) => code ) ;
65+ const lastOwnEditRef = useRef < string | null > ( null ) ;
7266 const onEditorChange = useCallback (
7367 ( value : string ) : void => {
7468 setInput ( value ) ;
7569 try {
7670 // Parse string before sending to store
7771 const obj = JSON . parse ( value ) ;
72+ lastOwnEditRef . current = value ;
7873 if ( key === "layout" ) {
7974 store . setLayout ( obj ) ;
8075 } else if ( key === "config" ) {
@@ -92,7 +87,17 @@ export function useV2EditorController(context: PlaygroundDataV2): ComposedEditor
9287 ( ) =>
9388 reaction (
9489 ( ) => getEditorCode ( store , keyBox . get ( ) ) ,
95- code => setInput ( prettifyJson ( code ) )
90+ rawCode => {
91+ // Skip resync when this is just the store echoing back the user's own last
92+ // edit — otherwise every keystroke replaces the controlled value and resets
93+ // the cursor to the end.
94+ if ( lastOwnEditRef . current !== null && isEquivalentJson ( rawCode , lastOwnEditRef . current ) ) {
95+ lastOwnEditRef . current = null ;
96+ return ;
97+ }
98+ lastOwnEditRef . current = null ;
99+ setInput ( prettifyJson ( rawCode ) ) ;
100+ }
96101 ) ,
97102 [ store , keyBox ]
98103 ) ;
0 commit comments