Skip to content

Commit 41e1a66

Browse files
committed
improvement(logs): cleanup pass — remove anti-patterns, fix design tokens, simplify state
1 parent af42bfe commit 41e1a66

6 files changed

Lines changed: 78 additions & 95 deletions

File tree

apps/sim/app/workspace/[workspaceId]/logs/components/log-details/components/trace-view/trace-view.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -965,13 +965,16 @@ export const TraceView = memo(function TraceView({ traceSpans }: TraceViewProps)
965965
[normalizedSpans, selectedId]
966966
)
967967

968-
const runStatus = useMemo(() => {
969-
if (normalizedSpans.length === 0) return 'empty' as const
970-
const rootHasError = normalizedSpans.some((span) =>
971-
span.type?.toLowerCase() === 'workflow' ? hasUnhandledErrorInTree(span) : hasErrorInTree(span)
972-
)
973-
return rootHasError ? ('error' as const) : ('success' as const)
974-
}, [normalizedSpans])
968+
const runStatus =
969+
normalizedSpans.length === 0
970+
? ('empty' as const)
971+
: normalizedSpans.some((span) =>
972+
span.type?.toLowerCase() === 'workflow'
973+
? hasUnhandledErrorInTree(span)
974+
: hasErrorInTree(span)
975+
)
976+
? ('error' as const)
977+
: ('success' as const)
975978

976979
const handleSelect = useCallback((id: string) => setSelectedId(id), [])
977980

apps/sim/app/workspace/[workspaceId]/logs/components/log-details/log-details.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ export const LogDetails = memo(function LogDetails({
399399

400400
<div
401401
className={cn(
402-
'absolute top-0 right-0 bottom-0 z-50 overflow-hidden border-l bg-[var(--bg)] shadow-md transition-transform duration-200 ease-out',
402+
'absolute top-0 right-0 bottom-0 z-[var(--z-dropdown)] overflow-hidden border-l bg-[var(--bg)] shadow-md transition-transform duration-200 ease-out',
403403
isOpen ? 'translate-x-0' : 'translate-x-full'
404404
)}
405405
style={{ width: effectiveWidth }}

apps/sim/app/workspace/[workspaceId]/logs/components/log-row-context-menu/log-row-context-menu.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@
22

33
import { memo } from 'react'
44
import {
5+
Copy,
56
DropdownMenu,
67
DropdownMenuContent,
78
DropdownMenuItem,
89
DropdownMenuSeparator,
910
DropdownMenuTrigger,
11+
Eye,
12+
Link,
13+
ListFilter,
14+
Redo,
15+
SquareArrowUpRight,
16+
X,
1017
} from '@/components/emcn'
11-
import { Copy, Eye, Link, ListFilter, Redo, SquareArrowUpRight, X } from '@/components/emcn/icons'
1218
import type { WorkflowLog } from '@/stores/logs/filters/types'
1319

1420
interface LogRowContextMenuProps {

apps/sim/app/workspace/[workspaceId]/logs/logs.tsx

Lines changed: 40 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -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'
1919
import { dollarsToCredits } from '@/lib/billing/credits/conversion'
2020
import { cn } from '@/lib/core/utils/cn'
2121
import {
@@ -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

Comments
 (0)