@ -5,7 +5,7 @@ import {
} from 'recharts' ;
} from 'recharts' ;
import {
import {
Zap , Play , Square , Plus , Trash2 , Pause , RotateCcw ,
Zap , Play , Square , Plus , Trash2 , Pause , RotateCcw ,
TrendingUp , TrendingDown , ChevronDown , PlayCircle ,
TrendingUp , TrendingDown , ChevronDown , PlayCircle , Eraser ,
} from 'lucide-react' ;
} from 'lucide-react' ;
import {
import {
orbTradingApi ,
orbTradingApi ,
@ -77,6 +77,11 @@ function SchedulerPanel({ selectedSessions }: { selectedSessions: string[] }) {
onError : ( e : Error ) = > alert ( ` 스케줄러 중지 실패: ${ e . message } ` ) ,
onError : ( e : Error ) = > alert ( ` 스케줄러 중지 실패: ${ e . message } ` ) ,
} ) ;
} ) ;
const clearLogMut = useMutation ( {
mutationFn : orbTradingApi.clearLog ,
onSuccess : ( ) = > qc . invalidateQueries ( { queryKey : [ 'orb-auto-status' ] } ) ,
} ) ;
const logLines = data ? . log_tail ? ? [ ] ;
const logLines = data ? . log_tail ? ? [ ] ;
// Auto-scroll to bottom when new log lines arrive (must be before early return)
// Auto-scroll to bottom when new log lines arrive (must be before early return)
@ -207,8 +212,9 @@ function SchedulerPanel({ selectedSessions }: { selectedSessions: string[] }) {
{ /* Log */ }
{ /* Log */ }
< div >
< div >
< div style = { { display : 'flex' , alignItems : 'center' , borderTop : '1px solid var(--border)' } } >
< button
< button
style = { { . . . btn ( 'ghost' ) , width: '100%' , justifyContent : 'space-between' , borderRadius : 0 , padding : '8px 20px' } }
style = { { . . . btn ( 'ghost' ) , flex: 1 , justifyContent : 'space-between' , borderRadius : 0 , border : 'none' , padding : '8px 20px' } }
onClick = { ( ) = > setShowLog ( v = > ! v ) }
onClick = { ( ) = > setShowLog ( v = > ! v ) }
>
>
< span style = { { fontSize : 12 } } >
< span style = { { fontSize : 12 } } >
@ -221,6 +227,15 @@ function SchedulerPanel({ selectedSessions }: { selectedSessions: string[] }) {
< / span >
< / span >
< ChevronDown size = { 13 } style = { { transform : showLog ? 'rotate(180deg)' : undefined , transition : 'transform 0.2s' } } / >
< ChevronDown size = { 13 } style = { { transform : showLog ? 'rotate(180deg)' : undefined , transition : 'transform 0.2s' } } / >
< / button >
< / button >
< button
style = { { . . . btn ( 'ghost' ) , borderRadius : 0 , border : 'none' , borderLeft : '1px solid var(--border)' , padding : '8px 14px' , color : 'var(--text3)' } }
onClick = { ( ) = > clearLogMut . mutate ( ) }
disabled = { clearLogMut . isPending || logLines . length === 0 }
title = "로그 초기화"
>
< Eraser size = { 13 } / >
< / button >
< / div >
{ showLog && (
{ showLog && (
< pre ref = { logRef } style = { {
< pre ref = { logRef } style = { {
margin : 0 , padding : '10px 20px' , maxHeight : 480 , overflowY : 'auto' ,
margin : 0 , padding : '10px 20px' , maxHeight : 480 , overflowY : 'auto' ,