Skip to content

Commit 0dc2c1f

Browse files
authored
improvement(logs): improved logs ui bugs, added subflow disable UI (#2910)
* improvement(logs): improved logs ui bugs, added subflow disable UI * added duplicate to action bar for subflows
1 parent fb90c4e commit 0dc2c1f

File tree

12 files changed

+72
-35
lines changed

12 files changed

+72
-35
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ function ProgressBar({
234234
{segments.map((segment, index) => (
235235
<div
236236
key={index}
237-
className='absolute h-full'
237+
className='absolute h-full opacity-70'
238238
style={{
239239
left: `${segment.startPercent}%`,
240240
width: `${segment.widthPercent}%`,

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
@@ -257,7 +257,7 @@ export const LogDetails = memo(function LogDetails({
257257
Version
258258
</span>
259259
<div className='flex w-0 flex-1 justify-end'>
260-
<span className='max-w-full truncate rounded-[6px] bg-[#14291B] px-[9px] py-[2px] font-medium text-[#86EFAC] text-[12px]'>
260+
<span className='max-w-full truncate rounded-[6px] bg-[#bbf7d0] px-[9px] py-[2px] font-medium text-[#15803d] text-[12px] dark:bg-[#14291B] dark:text-[#86EFAC]'>
261261
{log.deploymentVersionName || `v${log.deploymentVersion}`}
262262
</span>
263263
</div>

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

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { DatePicker } from '@/components/emcn/components/date-picker/date-picker
1919
import { cn } from '@/lib/core/utils/cn'
2020
import { hasActiveFilters } from '@/lib/logs/filters'
2121
import { getTriggerOptions } from '@/lib/logs/get-trigger-options'
22+
import { type LogStatus, STATUS_CONFIG } from '@/app/workspace/[workspaceId]/logs/utils'
2223
import { getBlock } from '@/blocks/registry'
2324
import { useFolderStore } from '@/stores/folders/store'
2425
import { useFilterStore } from '@/stores/logs/filters/store'
@@ -211,12 +212,12 @@ export function LogsToolbar({
211212
}, [level])
212213

213214
const statusOptions: ComboboxOption[] = useMemo(
214-
() => [
215-
{ value: 'error', label: 'Error', icon: getColorIcon('var(--text-error)') },
216-
{ value: 'info', label: 'Info', icon: getColorIcon('var(--terminal-status-info-color)') },
217-
{ value: 'running', label: 'Running', icon: getColorIcon('#22c55e') },
218-
{ value: 'pending', label: 'Pending', icon: getColorIcon('#f59e0b') },
219-
],
215+
() =>
216+
(Object.keys(STATUS_CONFIG) as LogStatus[]).map((status) => ({
217+
value: status,
218+
label: STATUS_CONFIG[status].label,
219+
icon: getColorIcon(STATUS_CONFIG[status].color),
220+
})),
220221
[]
221222
)
222223

@@ -242,12 +243,8 @@ export function LogsToolbar({
242243

243244
const selectedStatusColor = useMemo(() => {
244245
if (selectedStatuses.length !== 1) return null
245-
const status = selectedStatuses[0]
246-
if (status === 'error') return 'var(--text-error)'
247-
if (status === 'info') return 'var(--terminal-status-info-color)'
248-
if (status === 'running') return '#22c55e'
249-
if (status === 'pending') return '#f59e0b'
250-
return null
246+
const status = selectedStatuses[0] as LogStatus
247+
return STATUS_CONFIG[status]?.color ?? null
251248
}, [selectedStatuses])
252249

253250
const workflowOptions: ComboboxOption[] = useMemo(

apps/sim/app/workspace/[workspaceId]/logs/utils.ts

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { getIntegrationMetadata } from '@/lib/logs/get-trigger-options'
55
import { getBlock } from '@/blocks/registry'
66
import { CORE_TRIGGER_TYPES } from '@/stores/logs/filters/types'
77

8-
/** Column configuration for logs table - shared between header and rows */
98
export const LOG_COLUMNS = {
109
date: { width: 'w-[8%]', minWidth: 'min-w-[70px]', label: 'Date' },
1110
time: { width: 'w-[12%]', minWidth: 'min-w-[90px]', label: 'Time' },
@@ -16,10 +15,8 @@ export const LOG_COLUMNS = {
1615
duration: { width: 'w-[20%]', minWidth: 'min-w-[100px]', label: 'Duration' },
1716
} as const
1817

19-
/** Type-safe column key derived from LOG_COLUMNS */
2018
export type LogColumnKey = keyof typeof LOG_COLUMNS
2119

22-
/** Ordered list of column keys for rendering table headers */
2320
export const LOG_COLUMN_ORDER: readonly LogColumnKey[] = [
2421
'date',
2522
'time',
@@ -30,7 +27,6 @@ export const LOG_COLUMN_ORDER: readonly LogColumnKey[] = [
3027
'duration',
3128
] as const
3229

33-
/** Possible execution status values for workflow logs */
3430
export type LogStatus = 'error' | 'pending' | 'running' | 'info' | 'cancelled'
3531

3632
/**
@@ -53,30 +49,28 @@ export function getDisplayStatus(status: string | null | undefined): LogStatus {
5349
}
5450
}
5551

56-
/** Configuration mapping log status to Badge variant and display label */
57-
const STATUS_VARIANT_MAP: Record<
52+
export const STATUS_CONFIG: Record<
5853
LogStatus,
59-
{ variant: React.ComponentProps<typeof Badge>['variant']; label: string }
54+
{ variant: React.ComponentProps<typeof Badge>['variant']; label: string; color: string }
6055
> = {
61-
error: { variant: 'red', label: 'Error' },
62-
pending: { variant: 'amber', label: 'Pending' },
63-
running: { variant: 'green', label: 'Running' },
64-
cancelled: { variant: 'gray', label: 'Cancelled' },
65-
info: { variant: 'gray', label: 'Info' },
56+
error: { variant: 'red', label: 'Error', color: 'var(--text-error)' },
57+
pending: { variant: 'amber', label: 'Pending', color: '#f59e0b' },
58+
running: { variant: 'green', label: 'Running', color: '#22c55e' },
59+
cancelled: { variant: 'orange', label: 'Cancelled', color: '#f97316' },
60+
info: { variant: 'gray', label: 'Info', color: 'var(--terminal-status-info-color)' },
6661
}
6762

68-
/** Configuration mapping core trigger types to Badge color variants */
6963
const TRIGGER_VARIANT_MAP: Record<string, React.ComponentProps<typeof Badge>['variant']> = {
7064
manual: 'gray-secondary',
7165
api: 'blue',
7266
schedule: 'green',
7367
chat: 'purple',
7468
webhook: 'orange',
69+
mcp: 'cyan',
7570
a2a: 'teal',
7671
}
7772

7873
interface StatusBadgeProps {
79-
/** The execution status to display */
8074
status: LogStatus
8175
}
8276

@@ -86,14 +80,13 @@ interface StatusBadgeProps {
8680
* @returns A Badge with dot indicator and status label
8781
*/
8882
export const StatusBadge = React.memo(({ status }: StatusBadgeProps) => {
89-
const config = STATUS_VARIANT_MAP[status]
83+
const config = STATUS_CONFIG[status]
9084
return React.createElement(Badge, { variant: config.variant, dot: true }, config.label)
9185
})
9286

9387
StatusBadge.displayName = 'StatusBadge'
9488

9589
interface TriggerBadgeProps {
96-
/** The trigger type identifier (e.g., 'manual', 'api', or integration block type) */
9790
trigger: string
9891
}
9992

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export const ActionBar = memo(
142142
</Tooltip.Root>
143143
)}
144144

145-
{!isStartBlock && !isResponseBlock && !isSubflowBlock && (
145+
{!isStartBlock && !isResponseBlock && (
146146
<Tooltip.Root>
147147
<Tooltip.Trigger asChild>
148148
<Button
@@ -213,6 +213,29 @@ export const ActionBar = memo(
213213
</Tooltip.Root>
214214
)}
215215

216+
{isSubflowBlock && (
217+
<Tooltip.Root>
218+
<Tooltip.Trigger asChild>
219+
<Button
220+
variant='ghost'
221+
onClick={(e) => {
222+
e.stopPropagation()
223+
if (!disabled) {
224+
collaborativeBatchToggleBlockEnabled([blockId])
225+
}
226+
}}
227+
className={ACTION_BUTTON_STYLES}
228+
disabled={disabled}
229+
>
230+
{isEnabled ? <Circle className={ICON_SIZE} /> : <CircleOff className={ICON_SIZE} />}
231+
</Button>
232+
</Tooltip.Trigger>
233+
<Tooltip.Content side='top'>
234+
{getTooltipMessage(isEnabled ? 'Disable Block' : 'Enable Block')}
235+
</Tooltip.Content>
236+
</Tooltip.Root>
237+
)}
238+
216239
<Tooltip.Root>
217240
<Tooltip.Trigger asChild>
218241
<Button

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/subflows/subflow-node.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { memo, useMemo, useRef } from 'react'
22
import { RepeatIcon, SplitIcon } from 'lucide-react'
33
import { Handle, type NodeProps, Position, useReactFlow } from 'reactflow'
4+
import { Badge } from '@/components/emcn'
45
import { cn } from '@/lib/core/utils/cn'
56
import { HANDLE_POSITIONS } from '@/lib/workflows/blocks/block-dimensions'
67
import { type DiffStatus, hasDiffStatus } from '@/lib/workflows/diff/types'
@@ -78,6 +79,7 @@ export const SubflowNodeComponent = memo(({ data, id, selected }: NodeProps<Subf
7879
? currentBlock.is_diff
7980
: undefined
8081

82+
const isEnabled = currentBlock?.enabled ?? true
8183
const isPreview = data?.isPreview || false
8284

8385
// Focus state
@@ -184,14 +186,21 @@ export const SubflowNodeComponent = memo(({ data, id, selected }: NodeProps<Subf
184186
<div className='flex min-w-0 flex-1 items-center gap-[10px]'>
185187
<div
186188
className='flex h-[24px] w-[24px] flex-shrink-0 items-center justify-center rounded-[6px]'
187-
style={{ backgroundColor: blockIconBg }}
189+
style={{ backgroundColor: isEnabled ? blockIconBg : 'gray' }}
188190
>
189191
<BlockIcon className='h-[16px] w-[16px] text-white' />
190192
</div>
191-
<span className='font-medium text-[16px]' title={blockName}>
193+
<span
194+
className={cn(
195+
'truncate font-medium text-[16px]',
196+
!isEnabled && 'text-[var(--text-muted)]'
197+
)}
198+
title={blockName}
199+
>
192200
{blockName}
193201
</span>
194202
</div>
203+
{!isEnabled && <Badge variant='gray-secondary'>disabled</Badge>}
195204
</div>
196205

197206
{!isPreview && (

apps/sim/components/emcn/components/badge/badge.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const badgeVariants = cva(
2525
orange: `${STATUS_BASE} bg-[#fed7aa] text-[#c2410c] dark:bg-[rgba(249,115,22,0.2)] dark:text-[#fdba74]`,
2626
amber: `${STATUS_BASE} bg-[#fde68a] text-[#a16207] dark:bg-[rgba(245,158,11,0.2)] dark:text-[#fcd34d]`,
2727
teal: `${STATUS_BASE} bg-[#99f6e4] text-[#0f766e] dark:bg-[rgba(20,184,166,0.2)] dark:text-[#5eead4]`,
28-
cyan: `${STATUS_BASE} bg-[#a5f3fc] text-[#0e7490] dark:bg-[rgba(14,165,233,0.2)] dark:text-[#7dd3fc]`,
28+
cyan: `${STATUS_BASE} bg-[var(--surface-4)] text-[#0891b2] dark:bg-[rgba(14,165,233,0.2)] dark:text-[#7dd3fc]`,
2929
'gray-secondary': `${STATUS_BASE} bg-[var(--surface-4)] text-[var(--text-secondary)]`,
3030
},
3131
size: {

apps/sim/lib/workflows/persistence/utils.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ describe('Database Helpers', () => {
376376
forEachItems: '',
377377
doWhileCondition: '',
378378
whileCondition: '',
379+
enabled: true,
379380
})
380381

381382
expect(result?.parallels['parallel-1']).toEqual({
@@ -384,6 +385,7 @@ describe('Database Helpers', () => {
384385
count: 5,
385386
distribution: ['item1', 'item2'],
386387
parallelType: 'count',
388+
enabled: true,
387389
})
388390
})
389391

apps/sim/lib/workflows/persistence/utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ export async function loadWorkflowFromNormalizedTables(
273273
forEachItems: (config as Loop).forEachItems ?? '',
274274
whileCondition: (config as Loop).whileCondition ?? '',
275275
doWhileCondition: (config as Loop).doWhileCondition ?? '',
276+
enabled: migratedBlocks[subflow.id]?.enabled ?? true,
276277
}
277278
loops[subflow.id] = loop
278279

@@ -301,6 +302,7 @@ export async function loadWorkflowFromNormalizedTables(
301302
(config as Parallel).parallelType === 'collection'
302303
? (config as Parallel).parallelType
303304
: 'count',
305+
enabled: migratedBlocks[subflow.id]?.enabled ?? true,
304306
}
305307
parallels[subflow.id] = parallel
306308
} else {

apps/sim/stores/logs/filters/types.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,14 @@ export type TimeRange =
172172
| 'All time'
173173
| 'Custom range'
174174

175-
export type LogLevel = 'error' | 'info' | 'running' | 'pending' | 'all' | (string & {})
175+
export type LogLevel =
176+
| 'error'
177+
| 'info'
178+
| 'running'
179+
| 'pending'
180+
| 'cancelled'
181+
| 'all'
182+
| (string & {})
176183
/** Core trigger types for workflow execution */
177184
export const CORE_TRIGGER_TYPES = [
178185
'manual',

0 commit comments

Comments
 (0)