@@ -10,12 +10,12 @@ import {
1010 Button ,
1111 Combobox ,
1212 type ComboboxOption ,
13+ DatePicker ,
1314 Download ,
1415 Library ,
1516 RefreshCw ,
1617 toast ,
1718} from '@/components/emcn'
18- import { DatePicker } from '@/components/emcn/components/date-picker/date-picker'
1919import { dollarsToCredits } from '@/lib/billing/credits/conversion'
2020import { cn } from '@/lib/core/utils/cn'
2121import {
@@ -305,23 +305,17 @@ export default function Logs() {
305305 const [ contextMenuPosition , setContextMenuPosition ] = useState ( { x : 0 , y : 0 } )
306306 const [ contextMenuLog , setContextMenuLog ] = useState < WorkflowLog | null > ( null )
307307
308- const [ isPreviewOpen , setIsPreviewOpen ] = useState ( false )
309308 const [ previewLogId , setPreviewLogId ] = useState < string | null > ( null )
310309
311- const activeLogId = isPreviewOpen ? previewLogId : selectedLogId
310+ const activeLogId = previewLogId ?? selectedLogId
312311 const queryClient = useQueryClient ( )
313312
314- const detailRefetchInterval = useCallback (
315- ( query : { state : { data ?: WorkflowLog } } ) => {
313+ const activeLogQuery = useLogDetail ( activeLogId ?? undefined , {
314+ refetchInterval : ( query : { state : { data ?: WorkflowLog } } ) => {
316315 if ( ! isLive ) return false
317316 const status = query . state . data ?. status
318317 return status === 'running' || status === 'pending' ? 3000 : false
319318 } ,
320- [ isLive ]
321- )
322-
323- const activeLogQuery = useLogDetail ( activeLogId ?? undefined , {
324- refetchInterval : detailRefetchInterval ,
325319 } )
326320
327321 const logFilters = useMemo (
@@ -399,18 +393,14 @@ export default function Logs() {
399393 } )
400394 } , [ logs , activeSort ] )
401395
402- const selectedLogIndex = useMemo (
403- ( ) => ( selectedLogId ? sortedLogs . findIndex ( ( l ) => l . id === selectedLogId ) : - 1 ) ,
404- [ sortedLogs , selectedLogId ]
405- )
396+ const selectedLogIndex = selectedLogId ? sortedLogs . findIndex ( ( l ) => l . id === selectedLogId ) : - 1
406397 const selectedLogFromList = selectedLogIndex >= 0 ? sortedLogs [ selectedLogIndex ] : null
407398
408399 const selectedLog = useMemo ( ( ) => {
409400 if ( ! selectedLogFromList ) return null
410- if ( ! activeLogQuery . data || isPreviewOpen || activeLogQuery . isPlaceholderData )
411- return selectedLogFromList
401+ if ( ! activeLogQuery . data || previewLogId !== null ) return selectedLogFromList
412402 return { ...selectedLogFromList , ...activeLogQuery . data }
413- } , [ selectedLogFromList , activeLogQuery . data , activeLogQuery . isPlaceholderData , isPreviewOpen ] )
403+ } , [ selectedLogFromList , activeLogQuery . data , previewLogId ] )
414404
415405 const handleLogHover = useCallback (
416406 ( rowId : string ) => {
@@ -535,7 +525,6 @@ export default function Logs() {
535525 const handleOpenPreview = useCallback ( ( ) => {
536526 if ( contextMenuLog ?. id ) {
537527 setPreviewLogId ( contextMenuLog . id )
538- setIsPreviewOpen ( true )
539528 }
540529 } , [ contextMenuLog ] )
541530
@@ -749,10 +738,9 @@ export default function Logs() {
749738
750739 const handleCloseContextMenu = useCallback ( ( ) => setContextMenuOpen ( false ) , [ ] )
751740 const handleOpenNotificationSettings = useCallback ( ( ) => setIsNotificationSettingsOpen ( true ) , [ ] )
752- const handleClosePreview = useCallback ( ( ) => {
753- setIsPreviewOpen ( false )
741+ function handleClosePreview ( ) {
754742 setPreviewLogId ( null )
755- } , [ ] )
743+ }
756744
757745 const isDashboardView = viewMode === 'dashboard'
758746
@@ -812,31 +800,18 @@ export default function Logs() {
812800 [ sortedLogs ]
813801 )
814802
815- const sidebarOverlay = useMemo (
816- ( ) => (
817- < LogDetails
818- log = { selectedLog }
819- isOpen = { effectiveSidebarOpen }
820- onClose = { handleCloseSidebar }
821- onNavigateNext = { handleNavigateNext }
822- onNavigatePrev = { handleNavigatePrev }
823- hasNext = { selectedLogIndex < sortedLogs . length - 1 }
824- hasPrev = { selectedLogIndex > 0 }
825- onRetryExecution = { handleRetrySidebarExecution }
826- isRetryPending = { retryExecution . isPending }
827- />
828- ) ,
829- [
830- selectedLog ,
831- effectiveSidebarOpen ,
832- handleCloseSidebar ,
833- handleNavigateNext ,
834- handleNavigatePrev ,
835- handleRetrySidebarExecution ,
836- retryExecution . isPending ,
837- selectedLogIndex ,
838- sortedLogs . length ,
839- ]
803+ const sidebarOverlay = (
804+ < LogDetails
805+ log = { selectedLog }
806+ isOpen = { effectiveSidebarOpen }
807+ onClose = { handleCloseSidebar }
808+ onNavigateNext = { handleNavigateNext }
809+ onNavigatePrev = { handleNavigatePrev }
810+ hasNext = { selectedLogIndex < sortedLogs . length - 1 }
811+ hasPrev = { selectedLogIndex > 0 }
812+ onRetryExecution = { handleRetrySidebarExecution }
813+ isRetryPending = { retryExecution . isPending }
814+ />
840815 )
841816
842817 const { data : allWorkflows = { } } = useWorkflowMap ( workspaceId )
@@ -969,23 +944,17 @@ export default function Logs() {
969944 getSuggestions,
970945 } )
971946
972- const lastExternalSearchValue = useRef ( searchQuery )
947+ const lastExternalSearchValue = useRef < string | undefined > ( undefined )
973948 useEffect ( ( ) => {
974- if ( searchQuery !== lastExternalSearchValue . current ) {
975- lastExternalSearchValue . current = searchQuery
976- const parsed = parseQuery ( searchQuery )
977- initializeFromQuery ( parsed . textSearch , parsed . filters )
978- }
949+ if ( searchQuery === lastExternalSearchValue . current ) return
950+ const isMount = lastExternalSearchValue . current === undefined
951+ lastExternalSearchValue . current = searchQuery
952+ // On mount with no initial query, skip the no-op parse
953+ if ( isMount && ! searchQuery ) return
954+ const parsed = parseQuery ( searchQuery )
955+ initializeFromQuery ( parsed . textSearch , parsed . filters )
979956 } , [ searchQuery , initializeFromQuery ] )
980957
981- useEffect ( ( ) => {
982- if ( searchQuery ) {
983- const parsed = parseQuery ( searchQuery )
984- initializeFromQuery ( parsed . textSearch , parsed . filters )
985- }
986- // eslint-disable-next-line react-hooks/exhaustive-deps
987- } , [ ] )
988-
989958 useEffect ( ( ) => {
990959 if ( ! isSuggestionsOpen || highlightedIndex < 0 ) return
991960 const container = searchDropdownRef . current
@@ -1247,12 +1216,12 @@ export default function Logs() {
12471216 hasActiveFilters = { filtersActive }
12481217 />
12491218
1250- { isPreviewOpen && ! activeLogQuery . isPlaceholderData && activeLogQuery . data ?. executionId && (
1219+ { previewLogId !== null && activeLogQuery . data ?. executionId && (
12511220 < ExecutionSnapshot
12521221 executionId = { activeLogQuery . data . executionId }
12531222 traceSpans = { activeLogQuery . data . executionData ?. traceSpans }
12541223 isModal
1255- isOpen = { isPreviewOpen }
1224+ isOpen = { previewLogId !== null }
12561225 onClose = { handleClosePreview }
12571226 />
12581227 ) }
@@ -1306,7 +1275,7 @@ function LogsFilterPanel({ searchQuery, onSearchQueryChange }: LogsFilterPanelPr
13061275 )
13071276
13081277 const [ datePickerOpen , setDatePickerOpen ] = useState ( false )
1309- const [ previousTimeRange , setPreviousTimeRange ] = useState ( timeRange )
1278+ const previousTimeRangeRef = useRef ( timeRange )
13101279 const dateRangeAppliedRef = useRef ( false )
13111280 const { data : folders = { } } = useFolderMap ( workspaceId )
13121281 const { data : allWorkflowList = [ ] } = useWorkflows ( workspaceId )
@@ -1397,7 +1366,7 @@ function LogsFilterPanel({ searchQuery, onSearchQueryChange }: LogsFilterPanelPr
13971366
13981367 const handleTimeRangeChange = ( val : string ) => {
13991368 if ( val === 'Custom range' ) {
1400- setPreviousTimeRange ( timeRange )
1369+ previousTimeRangeRef . current = timeRange
14011370 setDatePickerOpen ( true )
14021371 } else {
14031372 clearDateRange ( )
@@ -1413,7 +1382,7 @@ function LogsFilterPanel({ searchQuery, onSearchQueryChange }: LogsFilterPanelPr
14131382
14141383 const handleDatePickerCancel = ( ) => {
14151384 if ( timeRange === 'Custom range' && ! startDate ) {
1416- setTimeRange ( previousTimeRange )
1385+ setTimeRange ( previousTimeRangeRef . current )
14171386 }
14181387 setDatePickerOpen ( false )
14191388 }
@@ -1596,10 +1565,12 @@ function SuggestionButton({
15961565 showCategory ?: boolean
15971566} ) {
15981567 return (
1599- < button
1568+ < Button
1569+ type = 'button'
1570+ variant = 'ghost'
16001571 data-index = { index }
16011572 className = { cn (
1602- 'w-full rounded-md px-3 py-2 text-left transition-colors hover-hover:bg-[var(--surface-5)]' ,
1573+ 'h-auto w-full justify-start rounded-md px-3 py-2 text-left transition-colors hover-hover:bg-[var(--surface-5)]' ,
16031574 highlighted && 'bg-[var(--surface-5)]'
16041575 ) }
16051576 onMouseEnter = { ( ) => onHover ( index ) }
@@ -1608,7 +1579,7 @@ function SuggestionButton({
16081579 onSelect ( suggestion )
16091580 } }
16101581 >
1611- < div className = 'flex items-center justify-between gap-3' >
1582+ < div className = 'flex w-full items-center justify-between gap-3' >
16121583 < div className = 'min-w-0 flex-1 truncate text-small' > { suggestion . label } </ div >
16131584 { showCategory && suggestion . value !== suggestion . label && (
16141585 < div className = 'shrink-0 font-mono text-[var(--text-muted)] text-xs' >
@@ -1621,6 +1592,6 @@ function SuggestionButton({
16211592 < div className = 'shrink-0 text-[var(--text-muted)] text-xs' > { suggestion . value } </ div >
16221593 ) }
16231594 </ div >
1624- </ button >
1595+ </ Button >
16251596 )
16261597}
0 commit comments