diff --git a/ui/src/components/ExecutionDiagram/ExecutionDiagram.module.css b/ui/src/components/ExecutionDiagram/ExecutionDiagram.module.css index 550e4d1f..82418997 100644 --- a/ui/src/components/ExecutionDiagram/ExecutionDiagram.module.css +++ b/ui/src/components/ExecutionDiagram/ExecutionDiagram.module.css @@ -61,6 +61,28 @@ position: relative; } +.downloadBtn { + position: absolute; + top: 8px; + right: 8px; + z-index: 10; + font-size: 10px; + font-family: var(--font-mono, monospace); + padding: 3px 8px; + border: 1px solid var(--border, #E4DFD8); + border-radius: 4px; + background: var(--bg-surface, #FFFFFF); + color: var(--text-secondary, #5C5347); + cursor: pointer; + opacity: 0.7; + transition: opacity 0.15s, background 0.15s; +} + +.downloadBtn:hover { + opacity: 1; + background: var(--bg-hover, #F5F0EA); +} + .splitter { height: 4px; background: var(--border, #E4DFD8); diff --git a/ui/src/components/ExecutionDiagram/ExecutionDiagram.tsx b/ui/src/components/ExecutionDiagram/ExecutionDiagram.tsx index 7a2c355c..96d26154 100644 --- a/ui/src/components/ExecutionDiagram/ExecutionDiagram.tsx +++ b/ui/src/components/ExecutionDiagram/ExecutionDiagram.tsx @@ -154,10 +154,29 @@ export function ExecutionDiagram({ ); } + const handleDownloadJson = useCallback(() => { + if (!detail) return; + const json = JSON.stringify(detail, null, 2); + const blob = new Blob([json], { type: 'application/json' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = `execution-${executionId}.json`; + a.click(); + URL.revokeObjectURL(url); + }, [detail, executionId]); + return (