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" ;
63import { Spinner } from "@/components/ui/spinner" ;
7- import { Text } from "@/components/ui/typography" ;
4+ import { Paragraph , Text } from "@/components/ui/typography" ;
85import { useCheckComponentSpecFromPath } from "@/hooks/useCheckComponentSpecFromPath" ;
96import { useUserDetails } from "@/hooks/useUserDetails" ;
107import { useBackend } from "@/providers/BackendProvider" ;
@@ -17,6 +14,14 @@ import {
1714 isStatusInProgress ,
1815} from "@/services/executionService" ;
1916
17+ import {
18+ ActionBlock ,
19+ type ActionOrReactNode ,
20+ } from "../shared/ContextPanel/Blocks/ActionBlock" ;
21+ import { ContentBlock } from "../shared/ContextPanel/Blocks/ContentBlock" ;
22+ import { ListBlock } from "../shared/ContextPanel/Blocks/ListBlock" ;
23+ import { TextBlock } from "../shared/ContextPanel/Blocks/TextBlock" ;
24+ import PipelineIO from "../shared/Execution/PipelineIO" ;
2025import { InfoBox } from "../shared/InfoBox" ;
2126import { StatusBar , StatusText } from "../shared/Status" ;
2227import { TaskImplementation } from "../shared/TaskDetails" ;
@@ -52,29 +57,30 @@ 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 align = "center" inlineAlign = "center" className = "h-full" >
61+ < InfoBox title = "Error" variant = "error" >
62+ Pipeline Run could not be loaded.
63+ </ InfoBox >
64+ </ BlockStack >
6165 ) ;
6266 }
6367
6468 if ( isLoading ) {
6569 return (
66- < div className = "flex items- center justify- center h-full">
70+ < InlineStack align = " center" blockAlign = " center" className = " h-full">
6771 < Spinner className = "mr-2" />
68- < p className = "text-secondary-foreground "> Loading run details...</ p >
69- </ div >
72+ < Paragraph tone = "subdued "> Loading run details...</ Paragraph >
73+ </ InlineStack >
7074 ) ;
7175 }
7276
7377 if ( ! configured ) {
7478 return (
75- < InfoBox title = "Backend not configured" variant = "warning" >
76- Configure a backend to view execution artifacts.
77- </ InfoBox >
79+ < BlockStack align = "center" inlineAlign = "center" className = "h-full" >
80+ < InfoBox title = "Backend not configured" variant = "warning" >
81+ Configure a backend to view execution artifacts.
82+ </ InfoBox >
83+ </ BlockStack >
7884 ) ;
7985 }
8086
@@ -86,133 +92,88 @@ export const RunDetails = () => {
8692
8793 const annotations = componentSpec . metadata ?. annotations || { } ;
8894
95+ const actions : ActionOrReactNode [ ] = [ ] ;
96+
97+ actions . push (
98+ < TaskImplementation
99+ displayName = { componentSpec . name ?? "Pipeline" }
100+ componentSpec = { componentSpec }
101+ showInlineContent = { false }
102+ /> ,
103+ ) ;
104+
105+ if ( canAccessEditorSpec && componentSpec . name ) {
106+ actions . push (
107+ < InspectPipelineButton key = "inspect" pipelineName = { componentSpec . name } /> ,
108+ ) ;
109+ }
110+
111+ actions . push (
112+ < ClonePipelineButton key = "clone" componentSpec = { componentSpec } /> ,
113+ ) ;
114+
115+ if ( isInProgress && isRunCreator ) {
116+ actions . push ( < CancelPipelineRunButton key = "cancel" runId = { runId } /> ) ;
117+ }
118+
119+ if ( isComplete ) {
120+ actions . push (
121+ < RerunPipelineButton key = "rerun" componentSpec = { componentSpec } /> ,
122+ ) ;
123+ }
124+
89125 return (
90126 < BlockStack gap = "6" className = "p-2 h-full" >
91127 < CopyText className = "text-lg font-semibold" >
92128 { componentSpec . name ?? "Unnamed Pipeline" }
93129 </ CopyText >
94130
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 } />
105- { isInProgress && isRunCreator && (
106- < CancelPipelineRunButton runId = { runId } />
107- ) }
108- { isComplete && < RerunPipelineButton componentSpec = { componentSpec } /> }
109- </ InlineStack >
131+ < ActionBlock actions = { actions } />
110132
111133 { 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 >
134+ < ListBlock
135+ title = "Run Info"
136+ items = { [
137+ { label : "Run Id" , value : metadata . id } ,
138+ { label : "Execution Id" , value : metadata . root_execution_id } ,
139+ { label : "Created by" , value : metadata . created_by ?? undefined } ,
140+ {
141+ label : "Created at" ,
142+ value : metadata . created_at
143+ ? new Date ( metadata . created_at ) . toLocaleString ( )
144+ : undefined ,
145+ } ,
146+ ] }
147+ marker = "none"
148+ />
159149 ) }
160150
161151 { 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 >
152+ < TextBlock title = "Description" text = { componentSpec . description } />
170153 ) }
171154
172- < BlockStack >
173- < Text as = "h3" size = "md" weight = "semibold" className = "mb-1" >
174- Status
175- </ Text >
155+ < ContentBlock title = "Status" >
176156 < InlineStack gap = "2" blockAlign = "center" className = "mb-1" >
177157 < Text size = "sm" weight = "semibold" >
178158 { runStatus }
179159 </ Text >
180160 < StatusText statusCounts = { statusCounts } />
181161 </ InlineStack >
182162 < StatusBar statusCounts = { statusCounts } />
183- </ BlockStack >
163+ </ ContentBlock >
184164
185165 { 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 >
166+ < ListBlock
167+ title = "Annotations"
168+ items = { Object . entries ( annotations ) . map ( ( [ key , value ] ) => ( {
169+ label : key ,
170+ value : String ( value ) ,
171+ } ) ) }
172+ marker = "none"
173+ />
203174 ) }
204175
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- />
176+ < PipelineIO readOnly />
216177 </ BlockStack >
217178 ) ;
218179} ;
0 commit comments