1+ import Copy from "@/assets/icons/copy.svg?react" ;
12import { calculateTimeDifference } from "@/lib/dates" ;
23import { Step } from "@/types/steps" ;
34import { clsx } from "clsx" ;
45import { NodeProps , ReactFlowState , useStore } from "reactflow" ;
56import { ExecutionStatusIcon , getExecutionStatusBackgroundColor } from "../ExecutionStatus" ;
67import { StepSheet } from "../steps/step-sheet" ;
78import { BaseNode } from "./BaseNode" ;
9+ import { CopyNodeButton } from "./NodeCopyButton" ;
810
911const selector = ( state : ReactFlowState ) => ( {
1012 unselectAll : state . unselectNodesAndEdges
@@ -30,7 +32,7 @@ export function StepNode({ data, selected }: NodeProps<Step>) {
3032 data-failed = { isFailed }
3133 data-selected = { ! ! selected }
3234 className = { clsx (
33- "max-h-[80px] max-w-[300px] overflow-hidden rounded-md border bg-theme-surface-primary transition-all duration-200 hover:shadow-md data-[selected=true]:shadow-md" ,
35+ "group max-h-[80px] max-w-[300px] overflow-hidden rounded-md border bg-theme-surface-primary transition-all duration-200 hover:shadow-md data-[selected=true]:shadow-md" ,
3436 {
3537 "border-theme-border-moderate hover:border-neutral-400 data-[selected=true]:border-theme-border-bold" :
3638 ! isFailed ,
@@ -45,6 +47,16 @@ export function StepNode({ data, selected }: NodeProps<Step>) {
4547 < ExecutionStatusIcon status = { data . body ?. status } className = "h-4 w-4" />
4648 </ div >
4749 < p className = "truncate font-semibold" > { data . name } </ p >
50+ < CopyNodeButton
51+ className = "h-4 w-4 shrink-0 rounded-sm hover:bg-theme-surface-secondary active:bg-neutral-300"
52+ code = { `from zenml.client import Client
53+ step = Client().get_run_step(${ data . id } )
54+ config = step.config` }
55+ type = "step"
56+ >
57+ < Copy className = "h-3 w-3 fill-theme-text-tertiary" />
58+ < div className = "sr-only" > Copy code to load step</ div >
59+ </ CopyNodeButton >
4860 </ div >
4961 < div
5062 data-failed = { isFailed }
0 commit comments