1- import React , { useState , useEffect } from 'react' ;
1+ import React , { useState , useEffect , useRef } from 'react' ;
22import {
33 Box ,
44 Button ,
55 TextField ,
66 Alert ,
77 IconButton ,
8- Autocomplete
8+ Autocomplete ,
9+ Select ,
10+ MenuItem ,
11+ FormControl ,
12+ InputLabel
913} from '@mui/material' ;
1014import DeleteIcon from '@mui/icons-material/Delete' ;
1115import Save from '@mui/icons-material/Save' ;
@@ -19,6 +23,15 @@ type ModelParameter = {
1923 isStatic ?: boolean ;
2024} ;
2125
26+ const PARAMETER_TYPES = [
27+ 'string' ,
28+ 'integer' ,
29+ 'number' ,
30+ 'boolean' ,
31+ 'array' ,
32+ 'object'
33+ ] as const ;
34+
2235export type ModelParametersInputProps = {
2336 modelId ?: string | null ;
2437} ;
@@ -32,6 +45,7 @@ export function ModelParametersInput(
3245 const [ validationError , setValidationError ] = useState < string > ( '' ) ;
3346 const [ isLoading , setIsLoading ] = useState ( false ) ;
3447 const alert = useStackingAlert ( ) ;
48+ const argumentValueRefs = useRef < Record < number , HTMLInputElement | null > > ( { } ) ;
3549
3650 const inferParameterType = ( value : any ) : string => {
3751 if ( typeof value === 'boolean' ) {
@@ -117,23 +131,36 @@ export function ModelParametersInput(
117131 } ;
118132
119133 const handleParameterChange = (
120- name : string ,
134+ index : number ,
121135 field : keyof ModelParameter ,
122136 value : string
123137 ) => {
124138 setParameters ( prev =>
125- prev . map ( param =>
126- param . name === name
127- ? { ...param , [ field ] : value , isStatic : false }
139+ prev . map ( ( param , i ) =>
140+ i === index
141+ ? {
142+ ...param ,
143+ [ field ] : value ,
144+ // Only mark as non-static if it wasn't already static
145+ isStatic :
146+ param . isStatic && field !== 'value' ? param . isStatic : false
147+ }
128148 : param
129149 )
130150 ) ;
131151 setValidationError ( '' ) ;
152+
153+ // Auto-focus on the argument value input when type is selected
154+ if ( field === 'type' && value ) {
155+ setTimeout ( ( ) => {
156+ argumentValueRefs . current [ index ] ?. focus ( ) ;
157+ } , 0 ) ;
158+ }
132159 } ;
133160
134161 // Handle parameter name selection from dropdown
135162 const handleParameterNameSelect = (
136- currentName : string ,
163+ index : number ,
137164 paramName : string | null
138165 ) => {
139166 if ( ! paramName ) {
@@ -142,8 +169,8 @@ export function ModelParametersInput(
142169 const paramSchema = availableParameters ?. parameters ?. [ paramName ] ;
143170
144171 setParameters ( prev =>
145- prev . map ( param =>
146- param . name === currentName
172+ prev . map ( ( param , i ) =>
173+ i === index
147174 ? {
148175 ...param ,
149176 name : paramName ,
@@ -156,8 +183,8 @@ export function ModelParametersInput(
156183 setValidationError ( '' ) ;
157184 } ;
158185
159- const handleDeleteParameter = ( name : string ) => {
160- setParameters ( prev => prev . filter ( param => param . name !== name ) ) ;
186+ const handleDeleteParameter = ( index : number ) => {
187+ setParameters ( prev => prev . filter ( ( _ , i ) => i !== index ) ) ;
161188 setValidationError ( '' ) ;
162189 } ;
163190
@@ -290,7 +317,7 @@ export function ModelParametersInput(
290317 options = { getParameterOptions ( param . name ) }
291318 value = { param . name || null }
292319 onChange = { ( _ , newValue ) => {
293- handleParameterNameSelect ( param . name , newValue ) ;
320+ handleParameterNameSelect ( index , newValue ) ;
294321 } }
295322 freeSolo
296323 size = "small"
@@ -331,32 +358,38 @@ export function ModelParametersInput(
331358 } }
332359 />
333360 ) }
334- < TextField
335- label = "Parameter type"
336- placeholder = "e.g. float, string"
337- value = { param . type }
338- onChange = { e =>
339- handleParameterChange ( param . name , 'type' , e . target . value )
340- }
341- size = "small"
342- sx = { { flex : 1 } }
343- disabled = { param . isStatic }
344- InputProps = { {
345- readOnly : param . isStatic
346- } }
347- />
361+ < FormControl size = "small" sx = { { flex : 1 } } disabled = { param . isStatic } >
362+ < InputLabel > Parameter type</ InputLabel >
363+ < Select
364+ value = { param . type }
365+ label = "Parameter type"
366+ onChange = { e =>
367+ handleParameterChange ( index , 'type' , e . target . value )
368+ }
369+ disabled = { param . isStatic }
370+ >
371+ { PARAMETER_TYPES . map ( type => (
372+ < MenuItem key = { type } value = { type } >
373+ { type }
374+ </ MenuItem >
375+ ) ) }
376+ </ Select >
377+ </ FormControl >
348378 < TextField
349379 label = "Argument value"
350380 placeholder = "e.g. 0.7, https://localhost:8989"
351381 value = { param . value }
352382 onChange = { e =>
353- handleParameterChange ( param . name , 'value' , e . target . value )
383+ handleParameterChange ( index , 'value' , e . target . value )
354384 }
355385 size = "small"
356386 sx = { { flex : 1 } }
387+ inputRef = { el => {
388+ argumentValueRefs . current [ index ] = el ;
389+ } }
357390 />
358391 < IconButton
359- onClick = { ( ) => handleDeleteParameter ( param . name ) }
392+ onClick = { ( ) => handleDeleteParameter ( index ) }
360393 color = "error"
361394 size = "small"
362395 sx = { { ml : 1 } }
0 commit comments