1- import { Frown } from "lucide-react" ;
2-
3- import { ArtifactsList } from "@/components/shared/ArtifactsList/ArtifactsList" ;
41import { CopyText } from "@/components/shared/CopyText/CopyText" ;
52import { BlockStack , InlineStack } from "@/components/ui/layout" ;
6- import { Spinner } from "@/components/ui/spinner" ;
73import { Text } from "@/components/ui/typography" ;
84import { useCheckComponentSpecFromPath } from "@/hooks/useCheckComponentSpecFromPath" ;
95import { useUserDetails } from "@/hooks/useUserDetails" ;
@@ -17,7 +13,16 @@ import {
1713 isStatusInProgress ,
1814} from "@/services/executionService" ;
1915
16+ import {
17+ ActionBlock ,
18+ type ActionOrReactNode ,
19+ } from "../shared/ContextPanel/Blocks/ActionBlock" ;
20+ import { ContentBlock } from "../shared/ContextPanel/Blocks/ContentBlock" ;
21+ import { ListBlock } from "../shared/ContextPanel/Blocks/ListBlock" ;
22+ import { TextBlock } from "../shared/ContextPanel/Blocks/TextBlock" ;
23+ import PipelineIO from "../shared/Execution/PipelineIO" ;
2024import { InfoBox } from "../shared/InfoBox" ;
25+ import { LoadingScreen } from "../shared/LoadingScreen" ;
2126import { StatusBar , StatusText } from "../shared/Status" ;
2227import { TaskImplementation } from "../shared/TaskDetails" ;
2328import { CancelPipelineRunButton } from "./components/CancelPipelineRunButton" ;
@@ -52,29 +57,25 @@ export const RunDetails = () => {
5257
5358 if ( error || ! details || ! state || ! componentSpec ) {
5459 return (
55- < div className = "flex flex-col gap-8 items-center justify-center h-full" >
56- < Frown className = "w-12 h-12 text-secondary-foreground" />
57- < div className = "text-secondary-foreground" >
58- Error loading run details.
59- </ div >
60- </ div >
60+ < BlockStack fill >
61+ < InfoBox title = "Error" variant = "error" >
62+ Pipeline Run could not be loaded.
63+ </ InfoBox >
64+ </ BlockStack >
6165 ) ;
6266 }
6367
6468 if ( isLoading ) {
65- return (
66- < div className = "flex items-center justify-center h-full" >
67- < Spinner className = "mr-2" />
68- < p className = "text-secondary-foreground" > Loading run details...</ p >
69- </ div >
70- ) ;
69+ return < LoadingScreen message = "Loading run details..." /> ;
7170 }
7271
7372 if ( ! configured ) {
7473 return (
75- < InfoBox title = "Backend not configured" variant = "warning" >
76- Configure a backend to view execution artifacts.
77- </ InfoBox >
74+ < BlockStack fill >
75+ < InfoBox title = "Backend not configured" variant = "warning" >
76+ Configure a backend to view execution artifacts.
77+ </ InfoBox >
78+ </ BlockStack >
7879 ) ;
7980 }
8081
@@ -86,133 +87,92 @@ export const RunDetails = () => {
8687
8788 const annotations = componentSpec . metadata ?. annotations || { } ;
8889
90+ const actions : ActionOrReactNode [ ] = [ ] ;
91+
92+ actions . push (
93+ < TaskImplementation
94+ displayName = { componentSpec . name ?? "Pipeline" }
95+ componentSpec = { componentSpec }
96+ showInlineContent = { false }
97+ /> ,
98+ ) ;
99+
100+ if ( canAccessEditorSpec && componentSpec . name ) {
101+ actions . push (
102+ < InspectPipelineButton key = "inspect" pipelineName = { componentSpec . name } /> ,
103+ ) ;
104+ }
105+
106+ actions . push (
107+ < ClonePipelineButton
108+ key = "clone"
109+ componentSpec = { componentSpec }
110+ runId = { runId }
111+ /> ,
112+ ) ;
113+
114+ if ( isInProgress && isRunCreator ) {
115+ actions . push ( < CancelPipelineRunButton key = "cancel" runId = { runId } /> ) ;
116+ }
117+
118+ if ( isComplete ) {
119+ actions . push (
120+ < RerunPipelineButton key = "rerun" componentSpec = { componentSpec } /> ,
121+ ) ;
122+ }
123+
89124 return (
90125 < BlockStack gap = "6" className = "p-2 h-full" >
91126 < CopyText className = "text-lg font-semibold" >
92127 { componentSpec . name ?? "Unnamed Pipeline" }
93128 </ CopyText >
94129
95- < InlineStack gap = "2" >
96- < TaskImplementation
97- displayName = { componentSpec . name ?? "Pipeline" }
98- componentSpec = { componentSpec }
99- showInlineContent = { false }
100- />
101- { canAccessEditorSpec && componentSpec . name && (
102- < InspectPipelineButton pipelineName = { componentSpec . name } />
103- ) }
104- < ClonePipelineButton componentSpec = { componentSpec } runId = { runId } />
105- { isInProgress && isRunCreator && (
106- < CancelPipelineRunButton runId = { runId } />
107- ) }
108- { isComplete && < RerunPipelineButton componentSpec = { componentSpec } /> }
109- </ InlineStack >
130+ < ActionBlock actions = { actions } />
110131
111132 { metadata && (
112- < BlockStack >
113- < Text as = "h3" size = "md" weight = "semibold" className = "mb-1" >
114- Run Info
115- </ Text >
116- < dl className = "flex flex-col gap-1 text-xs text-secondary-foreground" >
117- { metadata . id && (
118- < InlineStack as = "div" gap = "1" blockAlign = "center" >
119- < Text as = "dt" weight = "semibold" className = "shrink-0" >
120- Run Id:
121- </ Text >
122- < dd >
123- < CopyText className = "font-mono truncate max-w-[180px]" >
124- { metadata . id }
125- </ CopyText >
126- </ dd >
127- </ InlineStack >
128- ) }
129- { metadata . root_execution_id && (
130- < InlineStack as = "div" gap = "1" blockAlign = "center" >
131- < Text as = "dt" weight = "semibold" className = "shrink-0" >
132- Execution Id:
133- </ Text >
134- < dd >
135- < CopyText className = "font-mono truncate max-w-[180px]" >
136- { metadata . root_execution_id }
137- </ CopyText >
138- </ dd >
139- </ InlineStack >
140- ) }
141- { metadata . created_by && (
142- < InlineStack as = "div" gap = "1" blockAlign = "center" >
143- < Text as = "dt" weight = "semibold" >
144- Created by:
145- </ Text >
146- < dd > { metadata . created_by } </ dd >
147- </ InlineStack >
148- ) }
149- { metadata . created_at && (
150- < InlineStack as = "div" gap = "1" blockAlign = "center" >
151- < Text as = "dt" weight = "semibold" >
152- Created at:
153- </ Text >
154- < dd > { new Date ( metadata . created_at ) . toLocaleString ( ) } </ dd >
155- </ InlineStack >
156- ) }
157- </ dl >
158- </ BlockStack >
133+ < ListBlock
134+ title = "Run Info"
135+ items = { [
136+ { label : "Run Id" , value : metadata . id } ,
137+ { label : "Execution Id" , value : metadata . root_execution_id } ,
138+ { label : "Created by" , value : metadata . created_by ?? undefined } ,
139+ {
140+ label : "Created at" ,
141+ value : metadata . created_at
142+ ? new Date ( metadata . created_at ) . toLocaleString ( )
143+ : undefined ,
144+ } ,
145+ ] }
146+ marker = "none"
147+ />
159148 ) }
160149
161150 { componentSpec . description && (
162- < BlockStack >
163- < Text as = "h3" size = "md" weight = "semibold" className = "mb-1" >
164- Description
165- </ Text >
166- < Text as = "p" size = "sm" className = "whitespace-pre-line" >
167- { componentSpec . description }
168- </ Text >
169- </ BlockStack >
151+ < TextBlock title = "Description" text = { componentSpec . description } />
170152 ) }
171153
172- < BlockStack >
173- < Text as = "h3" size = "md" weight = "semibold" className = "mb-1" >
174- Status
175- </ Text >
154+ < ContentBlock title = "Status" >
176155 < InlineStack gap = "2" blockAlign = "center" className = "mb-1" >
177156 < Text size = "sm" weight = "semibold" >
178157 { runStatus }
179158 </ Text >
180159 < StatusText statusCounts = { statusCounts } />
181160 </ InlineStack >
182161 < StatusBar statusCounts = { statusCounts } />
183- </ BlockStack >
162+ </ ContentBlock >
184163
185164 { Object . keys ( annotations ) . length > 0 && (
186- < BlockStack >
187- < Text as = "h3" size = "md" weight = "semibold" className = "mb-1" >
188- Annotations
189- </ Text >
190- < ul className = "text-xs text-secondary-foreground" >
191- { Object . entries ( annotations ) . map ( ( [ key , value ] ) => (
192- < li key = { key } >
193- < Text as = "span" weight = "semibold" >
194- { key } :
195- </ Text > { " " }
196- < Text as = "span" className = "break-all" >
197- { String ( value ) }
198- </ Text >
199- </ li >
200- ) ) }
201- </ ul >
202- </ BlockStack >
165+ < ListBlock
166+ title = "Annotations"
167+ items = { Object . entries ( annotations ) . map ( ( [ key , value ] ) => ( {
168+ label : key ,
169+ value : String ( value ) ,
170+ } ) ) }
171+ marker = "none"
172+ />
203173 ) }
204174
205- < ArtifactsList
206- inputs = { ( componentSpec . inputs ?? [ ] ) . map ( ( input ) => ( {
207- name : input . name ,
208- type : typeof input . type === "string" ? input . type : "object" ,
209- value : input . value ?? input . default ,
210- } ) ) }
211- outputs = { ( componentSpec . outputs ?? [ ] ) . map ( ( output ) => ( {
212- name : output . name ,
213- type : typeof output . type === "string" ? output . type : "object" ,
214- } ) ) }
215- />
175+ < PipelineIO readOnly />
216176 </ BlockStack >
217177 ) ;
218178} ;
0 commit comments