@@ -29,11 +29,13 @@ import {
2929 ChevronUp ,
3030 Clipboard ,
3131 Search ,
32+ SquareArrowUpRight ,
3233 Workflow ,
3334 Wrench ,
3435 X ,
3536} from '@sim/emcn/icons'
3637import { formatDuration } from '@sim/utils/formatting'
38+ import Link from 'next/link'
3739import { useParams , useRouter } from 'next/navigation'
3840import { useQueryState } from 'nuqs'
3941import { createPortal } from 'react-dom'
@@ -59,8 +61,10 @@ import {
5961 DELETED_WORKFLOW_LABEL ,
6062 formatDate ,
6163 getDisplayStatus ,
64+ resolveLogWorkflowId ,
6265 StatusBadge ,
6366 TriggerBadge ,
67+ workflowEditorPath ,
6468} from '@/app/workspace/[workspaceId]/logs/utils'
6569import { useCodeViewerFeatures } from '@/hooks/use-code-viewer'
6670import { usePermissionConfig } from '@/hooks/use-permission-config'
@@ -317,6 +321,19 @@ export function LogDetailsContent({ log, onActiveTabChange }: LogDetailsContentP
317321 const isWorkflowExecutionLog =
318322 ( log . trigger === 'manual' && ! ! log . duration ) || ! ! log . executionData ?. traceSpans
319323
324+ /**
325+ * The workflow this run belongs to, when it is still reachable. Null for Sim
326+ * agent jobs and deleted workflows, which render their label as static text.
327+ */
328+ const openableWorkflowId = resolveLogWorkflowId ( log )
329+
330+ const workflowLabel =
331+ log . trigger === 'mothership'
332+ ? log . jobTitle || 'Untitled Job'
333+ : openableWorkflowId
334+ ? log . workflow ?. name || 'Unknown'
335+ : DELETED_WORKFLOW_LABEL
336+
320337 const hasCostInfo = ! ! ( isWorkflowExecutionLog && log . cost )
321338 const showWorkflowState =
322339 isWorkflowExecutionLog &&
@@ -465,15 +482,31 @@ export function LogDetailsContent({ log, onActiveTabChange }: LogDetailsContentP
465482 < span className = 'font-medium text-[var(--text-tertiary)] text-caption' >
466483 { log . trigger === 'mothership' ? 'Job' : 'Workflow' }
467484 </ span >
468- < div className = 'flex min-w-0 items-center gap-1.5' >
469- < Workflow className = 'size-[14px] flex-shrink-0 text-[var(--text-icon)]' />
470- < span className = 'min-w-0 truncate font-medium text-[var(--text-secondary)] text-sm' >
471- { log . trigger === 'mothership'
472- ? log . jobTitle || 'Untitled Job'
473- : log . workflow ?. name ||
474- ( ! log . workflowId ? DELETED_WORKFLOW_LABEL : 'Unknown' ) }
475- </ span >
476- </ div >
485+ { openableWorkflowId ? (
486+ < Link
487+ href = { workflowEditorPath ( workspaceId , openableWorkflowId ) }
488+ target = '_blank'
489+ rel = 'noopener noreferrer'
490+ prefetch = { false }
491+ className = '-mx-1.5 -my-0.5 group flex w-fit min-w-0 max-w-[calc(100%+0.75rem)] items-center gap-1.5 rounded-[5px] px-1.5 py-0.5 transition-colors hover-hover:bg-[var(--surface-active)] focus-visible:bg-[var(--surface-active)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color-mix(in_srgb,var(--text-muted)_30%,transparent)]'
492+ >
493+ < span className = 'inline-grid size-[14px] shrink-0 place-items-center' >
494+ < Workflow className = 'col-start-1 row-start-1 size-[14px] text-[var(--text-icon)] opacity-100 blur-0 transition-[opacity,filter,transform] duration-200 ease-in-out group-hover-hover:scale-[0.25] group-hover-hover:opacity-0 group-hover-hover:blur-[2px] group-focus-visible:scale-[0.25] group-focus-visible:opacity-0 group-focus-visible:blur-[2px] motion-reduce:transition-none' />
495+ < SquareArrowUpRight className = 'col-start-1 row-start-1 size-[14px] scale-[0.25] text-[var(--text-icon)] opacity-0 blur-[2px] transition-[opacity,filter,transform] duration-200 ease-in-out group-hover-hover:scale-100 group-hover-hover:opacity-100 group-hover-hover:blur-0 group-focus-visible:scale-100 group-focus-visible:opacity-100 group-focus-visible:blur-0 motion-reduce:transition-none' />
496+ </ span >
497+ < span className = 'min-w-0 truncate font-medium text-[var(--text-secondary)] text-sm transition-colors group-hover-hover:text-[var(--text-primary)] group-focus-visible:text-[var(--text-primary)]' >
498+ { workflowLabel }
499+ </ span >
500+ < span className = 'sr-only' > (opens in a new tab)</ span >
501+ </ Link >
502+ ) : (
503+ < div className = 'flex min-w-0 items-center gap-1.5' >
504+ < Workflow className = 'size-[14px] flex-shrink-0 text-[var(--text-icon)]' />
505+ < span className = 'min-w-0 truncate font-medium text-[var(--text-secondary)] text-sm' >
506+ { workflowLabel }
507+ </ span >
508+ </ div >
509+ ) }
477510 </ div >
478511 </ div >
479512
0 commit comments