@@ -9,28 +9,55 @@ import {
99 } from "./types/preview" ;
1010import { Select , SelectTrigger , SelectValue , SelectContent , SelectGroup , SelectItem } from "./components/Select/Select" ;
1111import { Input } from "./components/Input/Input" ;
12+
1213export function DynamicForm ( ) {
14+ const [ testdata , setTestdata ] = useState < string > ( "conditional" ) ;
15+ const [ directories , setDirectories ] = useState < string [ ] > ( [ ] ) ;
16+
1317 const serverAddress = "localhost:8100" ;
14- const directoryPath = "conditional" ;
18+
19+ // Fetch directories when component mounts
20+ useEffect ( ( ) => {
21+ fetch ( `http://${ serverAddress } /directories` )
22+ . then ( response => {
23+ if ( ! response . ok ) {
24+ throw new Error ( `Failed to fetch directories: ${ response . status } ${ response . statusText } ` ) ;
25+ }
26+ return response . json ( ) ;
27+ } )
28+ . then ( data => {
29+ setDirectories ( data ) ;
30+ // If testdata is not in the list of directories, set it to the first directory
31+ if ( data . length > 0 && ! data . includes ( testdata ) ) {
32+ setTestdata ( data [ 0 ] ) ;
33+ }
34+ } )
35+ . catch ( error => {
36+ console . error ( 'Error fetching directories:' , error ) ;
37+ // Fallback to some default directories if fetch fails
38+ setDirectories ( [ "conditional" ] ) ;
39+ } ) ;
40+ } , [ ] ) ;
41+
1542 const planPath = "" ;
16- const wsUrl = `ws://${ serverAddress } /ws/${ encodeURIComponent ( directoryPath ) } ${ planPath ? `?plan=${ encodeURIComponent ( planPath ) } ` : '' } ` ;
43+ const wsUrl = `ws://${ serverAddress } /ws/${ encodeURIComponent ( testdata ) } ${ planPath ? `?plan=${ encodeURIComponent ( planPath ) } ` : '' } ` ;
1744
1845 const { message : serverResponse , sendMessage, connectionStatus } = useWebSocket < Response > ( wsUrl ) ;
1946
2047 const [ response , setResponse ] = useState < Response | null > ( null ) ;
21-
48+ const [ currentId , setCurrentId ] = useState < number > ( 0 ) ;
49+
2250 // Initialize React Hook Form
2351 const methods = useForm < Record < string , string > > ( {
2452 defaultValues : { }
2553 } ) ;
2654 const { watch, reset } = methods ;
2755
28- // Whenever we get a new server response, update local state
2956 useEffect ( ( ) => {
30- if ( serverResponse ) {
57+ if ( serverResponse && serverResponse . id >= currentId ) {
3158 setResponse ( serverResponse ) ;
3259 }
33- } , [ serverResponse ] ) ;
60+ } , [ serverResponse , currentId ] ) ;
3461
3562 // Reset form state whenever "response" changes
3663 useEffect ( ( ) => {
@@ -44,31 +71,41 @@ export function DynamicForm() {
4471
4572 // Use RHF's `reset` to update the entire form
4673 reset ( defaultValues ) ;
74+
75+ // Also update prevValues to match the initial form state
76+ // This prevents the initial values from being detected as changes
77+ setPrevValues ( defaultValues ) ;
4778 }
4879 } , [ response , reset ] ) ;
4980
5081 // Watch all fields and send changes to the server
5182 const watchedValues = watch ( ) ;
52- console . log ( "serverResponse" , serverResponse ) ;
53-
83+
5484 // Track previous values to detect changes
5585 const [ prevValues , setPrevValues ] = useState < Record < string , string > > ( { } ) ;
5686
5787 useEffect ( ( ) => {
58- if ( response ) {
59- const hasChanged = Object . keys ( watchedValues ) . some (
60- key => watchedValues [ key ] !== prevValues [ key ]
61- ) ;
62-
63- if ( hasChanged ) {
88+ if ( ! response ) return ;
89+
90+ // Skip if this is the first render or if prevValues is empty
91+ if ( Object . keys ( prevValues ) . length === 0 ) return ;
92+
93+ const hasChanged = Object . keys ( watchedValues ) . some (
94+ key => watchedValues [ key ] !== prevValues [ key ]
95+ ) ;
96+ if ( hasChanged ) {
97+ setCurrentId ( prevId => {
98+ const newId = prevId + 1 ;
6499 const request : Request = {
65- id : 1 ,
100+ id : newId ,
66101 inputs : watchedValues
67102 } ;
68- sendMessage ( request ) ;
69103
70- setPrevValues ( { ...watchedValues } ) ;
71- }
104+ sendMessage ( request ) ;
105+ return newId ;
106+ } ) ;
107+
108+ setPrevValues ( { ...watchedValues } ) ;
72109 }
73110 } , [ watchedValues , response , sendMessage , prevValues ] ) ;
74111
@@ -170,7 +207,6 @@ export function DynamicForm() {
170207 ) ;
171208 } ;
172209
173- // 8) Optionally display diagnostics from the server
174210 const renderDiagnostics = ( diagnostics : Diagnostics ) => {
175211 return (
176212 < div >
@@ -199,13 +235,40 @@ export function DynamicForm() {
199235 const sortedParams = [ ...response . parameters ] . sort ( ( a , b ) => a . order - b . order ) ;
200236
201237 return (
202- < FormProvider { ...methods } >
203- < form className = "flex flex-col gap-4" >
204- { response . diagnostics && renderDiagnostics ( response . diagnostics ) }
238+ < >
239+ < div >
240+ < Select
241+ onValueChange = { ( value ) => {
242+ setTestdata ( value ) ;
243+ // Reset response when changing testdata to avoid showing stale data
244+ setResponse ( null ) ;
245+ } }
246+ value = { testdata }
247+ defaultValue = { testdata }
248+ >
249+ < SelectTrigger className = "w-fit" >
250+ < SelectValue />
251+ </ SelectTrigger >
252+ < SelectContent >
253+ < SelectGroup >
254+ { directories . map ( ( name , idx ) => {
255+ return (
256+ < SelectItem key = { idx } value = { name } > { name } </ SelectItem >
257+ ) ;
258+ } ) }
259+ </ SelectGroup >
260+ </ SelectContent >
261+ </ Select >
262+ </ div >
263+
264+ < FormProvider { ...methods } >
265+ < form className = "flex flex-col gap-4" >
266+ { response . diagnostics && renderDiagnostics ( response . diagnostics ) }
205267
206- { sortedParams && sortedParams . map ( ( param ) => renderParameter ( param ) ) }
207- </ form >
208- </ FormProvider >
268+ { sortedParams && sortedParams . map ( ( param ) => renderParameter ( param ) ) }
269+ </ form >
270+ </ FormProvider >
271+ </ >
209272 ) ;
210273}
211274
0 commit comments