1- import { useCallback , useMemo , useState } from "react" ;
1+ import { observable , reaction , runInAction } from "mobx" ;
2+ import { useCallback , useEffect , useMemo , useState } from "react" ;
23import { PlaygroundDataV2 } from "@mendix/shared-charts/main" ;
34import { ComposedEditorProps } from "../components/ComposedEditor" ;
45import { SelectOption } from "../components/Sidebar" ;
@@ -7,7 +8,7 @@ type ConfigKey = "layout" | "config" | number;
78
89const irrelevantSeriesKeys = [ "x" , "y" , "z" , "customSeriesOptions" , "dataSourceItems" ] ;
910
10- function getEditorCode ( { store } : PlaygroundDataV2 , key : ConfigKey ) : string {
11+ function getEditorCode ( store : PlaygroundDataV2 [ "store" ] , key : ConfigKey ) : string {
1112 if ( key === "layout" ) {
1213 return store . layoutJson ?? '{ "error": "value is unavailable" }' ;
1314 }
@@ -28,38 +29,56 @@ function getModelerCode(data: PlaygroundDataV2, key: ConfigKey): object {
2829 return Object . fromEntries ( entries ) ;
2930}
3031
31- export function useV2EditorController ( data : PlaygroundDataV2 ) : ComposedEditorProps {
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+
40+ export function useV2EditorController ( context : PlaygroundDataV2 ) : ComposedEditorProps {
3241 const [ key , setKey ] = useState < ConfigKey > ( "layout" ) ;
42+ const keyBox = useState ( ( ) => observable . box < ConfigKey > ( key ) ) [ 0 ] ;
3343
3444 const onViewSelectChange = ( value : string ) : void => {
45+ let newKey : ConfigKey ;
3546 if ( value === "layout" || value === "config" ) {
36- setKey ( value ) ;
47+ newKey = value ;
3748 } else {
3849 const n = parseInt ( value , 10 ) ;
39- setKey ( isNaN ( n ) ? "layout" : n ) ;
50+ newKey = isNaN ( n ) ? "layout" : n ;
4051 }
52+ setKey ( newKey ) ;
53+ runInAction ( ( ) => keyBox . set ( newKey ) ) ;
4154 } ;
4255
56+ const store = context . store ;
57+
4358 const options : SelectOption [ ] = useMemo ( ( ) => {
4459 return [
4560 { name : "Layout" , value : "layout" , isDefaultSelected : true } ,
46- ...data . plotData . map ( ( trace , index ) => ( {
47- name : trace . name || `trace ${ index } ` ,
61+ ...store . data . map ( ( trace , index ) => ( {
62+ name : ( trace . name as string ) || `trace ${ index } ` ,
4863 value : index ,
4964 isDefaultSelected : false
5065 } ) ) ,
5166 { name : "Configuration" , value : "config" , isDefaultSelected : false }
5267 ] ;
53- } , [ data . plotData ] ) ;
68+ } , [ store . data ] ) ;
5469
55- const store = data . store ;
70+ const code = prettifyJson ( getEditorCode ( store , key ) ) ;
71+ const [ input , setInput ] = useState ( ( ) => code ) ;
5672 const onEditorChange = useCallback (
5773 ( value : string ) : void => {
74+ setInput ( value ) ;
5875 try {
76+ // Parse string before sending to store
77+ const obj = JSON . parse ( value ) ;
5978 if ( key === "layout" ) {
60- store . setLayout ( JSON . parse ( value ) ) ;
79+ store . setLayout ( obj ) ;
6180 } else if ( key === "config" ) {
62- store . setConfig ( JSON . parse ( value ) ) ;
81+ store . setConfig ( obj ) ;
6382 } else {
6483 store . setDataAt ( key , value ) ;
6584 }
@@ -69,12 +88,21 @@ export function useV2EditorController(data: PlaygroundDataV2): ComposedEditorPro
6988 [ store , key ]
7089 ) ;
7190
91+ useEffect (
92+ ( ) =>
93+ reaction (
94+ ( ) => getEditorCode ( store , keyBox . get ( ) ) ,
95+ code => setInput ( prettifyJson ( code ) )
96+ ) ,
97+ [ store , keyBox ]
98+ ) ;
99+
72100 return {
73101 viewSelectValue : key . toString ( ) ,
74102 viewSelectOptions : options ,
75103 onViewSelectChange,
76- value : getEditorCode ( data , key ) ,
77- modelerCode : useMemo ( ( ) => JSON . stringify ( getModelerCode ( data , key ) , null , 2 ) , [ data , key ] ) ,
104+ value : input ,
105+ modelerCode : useMemo ( ( ) => JSON . stringify ( getModelerCode ( context , key ) , null , 2 ) , [ context , key ] ) ,
78106 onEditorChange
79107 } ;
80108}
0 commit comments