Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import { useCallback, useMemo } from 'react'
import { useCallback, useMemo, useState } from 'react'
import { ArrowUp, Bell, Library, MoreHorizontal, RefreshCw } from 'lucide-react'
import { useParams } from 'next/navigation'
import {
Expand All @@ -9,11 +9,13 @@ import {
type ComboboxOption,
Loader,
Popover,
PopoverAnchor,
PopoverContent,
PopoverItem,
PopoverScrollArea,
PopoverTrigger,
} from '@/components/emcn'
import { DatePicker } from '@/components/emcn/components/date-picker/date-picker'
import { cn } from '@/lib/core/utils/cn'
import { getTriggerOptions } from '@/lib/logs/get-trigger-options'
import { getBlock } from '@/blocks/registry'
Expand All @@ -35,8 +37,31 @@ const TIME_RANGE_OPTIONS: ComboboxOption[] = [
{ value: 'Past 7 days', label: 'Past 7 days' },
{ value: 'Past 14 days', label: 'Past 14 days' },
{ value: 'Past 30 days', label: 'Past 30 days' },
{ value: 'Custom range', label: 'Custom range' },
] as const

/**
* Formats a date string (YYYY-MM-DD) for display.
*/
function formatDateShort(dateStr: string): string {
const date = new Date(dateStr)
const months = [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec',
]
return `${months[date.getMonth()]} ${date.getDate()}`
}

type ViewMode = 'logs' | 'dashboard'

interface LogsToolbarProps {
Expand Down Expand Up @@ -153,7 +178,14 @@ export function LogsToolbar({
setTriggers,
timeRange,
setTimeRange,
startDate,
endDate,
setDateRange,
clearDateRange,
} = useFilterStore()

const [datePickerOpen, setDatePickerOpen] = useState(false)
const [previousTimeRange, setPreviousTimeRange] = useState(timeRange)
const folders = useFolderStore((state) => state.folders)

const allWorkflows = useWorkflowRegistry((state) => state.workflows)
Expand Down Expand Up @@ -269,8 +301,50 @@ export function LogsToolbar({

const timeDisplayLabel = useMemo(() => {
if (timeRange === 'All time') return 'Time'
if (timeRange === 'Custom range' && startDate && endDate) {
return `${formatDateShort(startDate)} - ${formatDateShort(endDate)}`
}
if (timeRange === 'Custom range') return 'Custom range'
return timeRange
}, [timeRange])
}, [timeRange, startDate, endDate])

/**
* Handles time range selection from combobox.
* Opens date picker when "Custom range" is selected.
*/
const handleTimeRangeChange = useCallback(
(val: string) => {
if (val === 'Custom range') {
setPreviousTimeRange(timeRange)
setDatePickerOpen(true)
} else {
clearDateRange()
setTimeRange(val as typeof timeRange)
}
},
[timeRange, setTimeRange, clearDateRange]
)

/**
* Handles date range selection from DatePicker.
*/
const handleDateRangeApply = useCallback(
(start: string, end: string) => {
setDateRange(start, end)
setDatePickerOpen(false)
},
[setDateRange]
)

/**
* Handles date picker cancel.
*/
const handleDatePickerCancel = useCallback(() => {
if (timeRange === 'Custom range' && !startDate) {
setTimeRange(previousTimeRange)
}
setDatePickerOpen(false)
}, [timeRange, startDate, previousTimeRange, setTimeRange])

const hasActiveFilters = useMemo(() => {
return (
Expand All @@ -287,8 +361,8 @@ export function LogsToolbar({
setWorkflowIds([])
setFolderIds([])
setTriggers([])
setTimeRange('All time')
}, [setLevel, setWorkflowIds, setFolderIds, setTriggers, setTimeRange])
clearDateRange()
}, [setLevel, setWorkflowIds, setFolderIds, setTriggers, clearDateRange])

return (
<div className='flex flex-col gap-[19px]'>
Expand Down Expand Up @@ -528,7 +602,7 @@ export function LogsToolbar({
<Combobox
options={TIME_RANGE_OPTIONS as unknown as ComboboxOption[]}
value={timeRange}
onChange={(val) => setTimeRange(val as typeof timeRange)}
onChange={handleTimeRangeChange}
placeholder='All time'
overlayContent={
<span className='truncate text-[var(--text-primary)]'>
Expand Down Expand Up @@ -636,18 +710,42 @@ export function LogsToolbar({
/>

{/* Timeline Filter */}
<Combobox
options={TIME_RANGE_OPTIONS as unknown as ComboboxOption[]}
value={timeRange}
onChange={(val) => setTimeRange(val as typeof timeRange)}
placeholder='Time'
overlayContent={
<span className='truncate text-[var(--text-primary)]'>{timeDisplayLabel}</span>
}
size='sm'
align='end'
className='h-[32px] w-[120px] rounded-[6px]'
/>
<Popover open={datePickerOpen} onOpenChange={setDatePickerOpen}>
<PopoverAnchor asChild>
<div>
<Combobox
options={TIME_RANGE_OPTIONS as unknown as ComboboxOption[]}
value={timeRange}
onChange={handleTimeRangeChange}
placeholder='Time'
overlayContent={
<span className='truncate text-[var(--text-primary)]'>
{timeDisplayLabel}
</span>
}
size='sm'
align='end'
className='h-[32px] w-[120px] rounded-[6px]'
/>
</div>
</PopoverAnchor>
<PopoverContent
side='bottom'
align='end'
sideOffset={4}
collisionPadding={16}
className='w-auto p-0'
>
<DatePicker
mode='range'
startDate={startDate}
endDate={endDate}
onRangeChange={handleDateRangeApply}
onCancel={handleDatePickerCancel}
inline
/>
</PopoverContent>
</Popover>
</div>
</div>
</div>
Expand Down
23 changes: 17 additions & 6 deletions apps/sim/app/workspace/[workspaceId]/logs/logs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Loader2 } from 'lucide-react'
import { useParams } from 'next/navigation'
import { cn } from '@/lib/core/utils/cn'
import { getStartDateFromTimeRange } from '@/lib/logs/filters'
import { getEndDateFromTimeRange, getStartDateFromTimeRange } from '@/lib/logs/filters'
import { parseQuery, queryToApiParams } from '@/lib/logs/query-parser'
import { useFolders } from '@/hooks/queries/folders'
import { useDashboardLogs, useLogDetail, useLogsList } from '@/hooks/queries/logs'
Expand All @@ -30,6 +30,8 @@ export default function Logs() {
setWorkspaceId,
initializeFromURL,
timeRange,
startDate,
endDate,
level,
workflowIds,
folderIds,
Expand Down Expand Up @@ -72,14 +74,16 @@ export default function Logs() {
const logFilters = useMemo(
() => ({
timeRange,
startDate,
endDate,
level,
workflowIds,
folderIds,
triggers,
searchQuery: debouncedSearchQuery,
limit: LOGS_PER_PAGE,
}),
[timeRange, level, workflowIds, folderIds, triggers, debouncedSearchQuery]
[timeRange, startDate, endDate, level, workflowIds, folderIds, triggers, debouncedSearchQuery]
)

const logsQuery = useLogsList(workspaceId, logFilters, {
Expand All @@ -90,13 +94,15 @@ export default function Logs() {
const dashboardFilters = useMemo(
() => ({
timeRange,
startDate,
endDate,
level,
workflowIds,
folderIds,
triggers,
searchQuery: debouncedSearchQuery,
}),
[timeRange, level, workflowIds, folderIds, triggers, debouncedSearchQuery]
[timeRange, startDate, endDate, level, workflowIds, folderIds, triggers, debouncedSearchQuery]
)

const dashboardLogsQuery = useDashboardLogs(workspaceId, dashboardFilters, {
Expand Down Expand Up @@ -261,9 +267,14 @@ export default function Logs() {
if (workflowIds.length > 0) params.set('workflowIds', workflowIds.join(','))
if (folderIds.length > 0) params.set('folderIds', folderIds.join(','))

const startDate = getStartDateFromTimeRange(timeRange)
if (startDate) {
params.set('startDate', startDate.toISOString())
const computedStartDate = getStartDateFromTimeRange(timeRange, startDate)
if (computedStartDate) {
params.set('startDate', computedStartDate.toISOString())
}

const computedEndDate = getEndDateFromTimeRange(timeRange, endDate)
if (computedEndDate) {
params.set('endDate', computedEndDate.toISOString())
}

const parsed = parseQuery(debouncedSearchQuery)
Expand Down
Loading