11import CheckBoxIcon from "@mui/icons-material/CheckBox"
22import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank"
3- import ClearIcon from "@mui/icons-material/Clear"
43import FilterListIcon from "@mui/icons-material/FilterList"
54import StopCircleIcon from "@mui/icons-material/StopCircle"
65
76import {
87 Box ,
98 Button ,
10- CircularProgress ,
119 FormControl ,
1210 IconButton ,
13- InputAdornment ,
1411 InputLabel ,
1512 Menu ,
1613 MenuItem ,
1714 Select ,
18- TextField ,
1915 Typography ,
2016 useTheme ,
2117} from "@mui/material"
@@ -27,18 +23,18 @@ import ListItemButton from "@mui/material/ListItemButton"
2723import ListItemText from "@mui/material/ListItemText"
2824import ListSubheader from "@mui/material/ListSubheader"
2925import * as Optuna from "@optuna/types"
30- import React , { FC , ReactNode , useCallback , useMemo , useState } from "react"
26+ import React , { FC , ReactNode , useMemo , useState } from "react"
3127
3228import ListItemIcon from "@mui/material/ListItemIcon"
3329import { useVirtualizer } from "@tanstack/react-virtual"
3430import { useAtom } from "jotai"
3531import { useNavigate } from "react-router-dom"
36- import { FormWidgets , StudyDetail , Trial } from "ts/types/optuna"
3732import { actionCreator } from "../action"
3833import { useConstants } from "../constantsProvider"
3934import { useArtifactIsAvailable , useLLMIsAvailable } from "../hooks/useAPIMeta"
40- import { useTrialFilterQuery } from "../hooks/useTrialFilterQuery "
35+ import { useSmartFilteringForm } from "../hooks/useSmartFilteringForm "
4136import { trialListDurationTimeUnitState } from "../state"
37+ import { FormWidgets , StudyDetail , Trial } from "../types/optuna"
4238import { useQuery } from "../urlQuery"
4339import { ArtifactCards } from "./Artifact/ArtifactCards"
4440import { TrialNote } from "./Note"
@@ -416,21 +412,22 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({
416412 const [ llmFilteredTrials , setLlmFilteredTrials ] = useState <
417413 Trial [ ] | undefined
418414 > ( )
419- const [ trialFilterQuery , setTrialFilterQuery ] = useState < string > ( "" )
420- const handleClearFilter = useCallback ( ( ) => {
421- setTrialFilterQuery ( "" )
422- setLlmFilteredTrials ( undefined )
423- } , [ ] )
424- const [ trialFilter , renderIframe , isTrialFilterProcessing ] =
425- useTrialFilterQuery ( {
426- nRetry : 5 ,
427- onDenied : handleClearFilter ,
428- onFailed : ( errorMsg : string ) => {
429- console . error ( "Failed to filter trials:" , errorMsg )
430- handleClearFilter ( )
431- } ,
432- } )
433415 const llmEnabled = useLLMIsAvailable ( )
416+ const [ renderSmartFilteringForm ] = useSmartFilteringForm (
417+ ( trialFilterQuery , trialFilter ) => {
418+ if ( trialFilterQuery !== "" ) {
419+ trialFilter ( allTrials , trialFilterQuery )
420+ . then ( ( filtered ) => {
421+ setLlmFilteredTrials ( filtered )
422+ } )
423+ . catch ( ( ) => {
424+ setLlmFilteredTrials ( allTrials ) // Fallback to all trials on error
425+ } )
426+ } else {
427+ setLlmFilteredTrials ( allTrials )
428+ }
429+ }
430+ )
434431
435432 const allTrials = useMemo ( ( ) => {
436433 return studyDetail ?. trials ?? [ ]
@@ -484,64 +481,13 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({
484481 sx = { {
485482 height : theme . spacing ( 8 ) ,
486483 p : theme . spacing ( 1 ) ,
484+ gap : theme . spacing ( 1 ) ,
487485 display : "flex" ,
488486 flexDirection : "row" ,
489487 alignItems : "center" ,
490488 } }
491489 >
492- < TextField
493- id = "trial-filter-query"
494- variant = "outlined"
495- placeholder = "Enter filter query (e.g., trial number < 10)"
496- fullWidth
497- size = "small"
498- value = { trialFilterQuery }
499- onChange = { ( e ) => setTrialFilterQuery ( e . target . value ) }
500- slotProps = { {
501- input : {
502- endAdornment : trialFilterQuery && (
503- < InputAdornment position = "end" >
504- < IconButton
505- aria-label = "clear filter"
506- onClick = { handleClearFilter }
507- edge = "end"
508- size = "small"
509- disabled = { isTrialFilterProcessing }
510- >
511- < ClearIcon />
512- </ IconButton >
513- </ InputAdornment >
514- ) ,
515- } ,
516- } }
517- />
518- < Button
519- variant = "contained"
520- startIcon = {
521- isTrialFilterProcessing ? (
522- < CircularProgress size = { 16 } />
523- ) : (
524- < FilterListIcon />
525- )
526- }
527- disabled = { isTrialFilterProcessing }
528- onClick = { ( ) => {
529- if ( trialFilterQuery !== "" && ! isTrialFilterProcessing ) {
530- trialFilter ( allTrials , trialFilterQuery )
531- . then ( ( filtered ) => {
532- setLlmFilteredTrials ( filtered )
533- } )
534- . catch ( ( ) => {
535- setLlmFilteredTrials ( allTrials ) // Fallback to all trials on error
536- } )
537- } else {
538- setLlmFilteredTrials ( allTrials )
539- }
540- } }
541- sx = { { marginLeft : theme . spacing ( 2 ) , minWidth : "120px" } }
542- >
543- Filter
544- </ Button >
490+ { renderSmartFilteringForm ( ) }
545491 </ Box >
546492 < Divider />
547493 </ >
@@ -746,7 +692,6 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({
746692 </ Box >
747693 </ Box >
748694 </ Box >
749- { renderIframe ( ) }
750695 </ Box >
751696 )
752697}
0 commit comments