5
5
*/
6
6
7
7
import moment from "moment" ;
8
- import { PrebuildInfo , PrebuildWithStatus , PrebuiltWorkspaceState , Project , WorkspaceInstance } from "@gitpod/gitpod-protocol" ;
8
+ import { PrebuildWithStatus , PrebuiltWorkspaceState , Project , WorkspaceInstance } from "@gitpod/gitpod-protocol" ;
9
9
import { useContext , useEffect , useState } from "react" ;
10
- import { useHistory , useLocation , useRouteMatch } from "react-router" ;
10
+ import { useLocation , useRouteMatch } from "react-router" ;
11
11
import Header from "../components/Header" ;
12
12
import DropDown , { DropDownEntry } from "../components/DropDown" ;
13
13
import { ItemsList , Item , ItemField , ItemFieldContextMenu } from "../components/ItemsList" ;
@@ -22,7 +22,6 @@ import { ContextMenuEntry } from "../components/ContextMenu";
22
22
import { shortCommitMessage } from "./render-utils" ;
23
23
24
24
export default function ( ) {
25
- const history = useHistory ( ) ;
26
25
const location = useLocation ( ) ;
27
26
28
27
const { teams } = useContext ( TeamsContext ) ;
@@ -45,7 +44,7 @@ export default function () {
45
44
const registration = getGitpodService ( ) . registerClient ( {
46
45
onPrebuildUpdate : ( update : PrebuildWithStatus ) => {
47
46
if ( update . info . projectId === project . id ) {
48
- setPrebuilds ( prev => [ update , ...prev . filter ( p => p . info . id !== update . info . id ) ] )
47
+ setPrebuilds ( prev => [ update , ...prev . filter ( p => p . info . id !== update . info . id ) ] ) ;
49
48
}
50
49
}
51
50
} ) ;
@@ -77,18 +76,17 @@ export default function () {
77
76
} , [ teams ] ) ;
78
77
79
78
const prebuildContextMenu = ( p : PrebuildWithStatus ) => {
80
- const running = p . status === "building" ;
79
+ const isFailed = p . status === "aborted" || p . status === "timeout" || ! ! p . error ;
80
+ const isRunning = p . status === "building" ;
81
81
const entries : ContextMenuEntry [ ] = [ ] ;
82
- entries . push ( {
83
- title : "View Prebuild" ,
84
- onClick : ( ) => openPrebuild ( p . info )
85
- } ) ;
86
- entries . push ( {
87
- title : "Trigger Prebuild" ,
88
- onClick : ( ) => triggerPrebuild ( p . info . branch ) ,
89
- separator : running
90
- } ) ;
91
- if ( running ) {
82
+ if ( isFailed ) {
83
+ entries . push ( {
84
+ title : `Rerun Prebuild (${ p . info . branch } )` ,
85
+ onClick : ( ) => triggerPrebuild ( p . info . branch ) ,
86
+ separator : isRunning
87
+ } ) ;
88
+ }
89
+ if ( isRunning ) {
92
90
entries . push ( {
93
91
title : "Cancel Prebuild" ,
94
92
customFontStyle : 'text-red-600 dark:text-red-400 hover:text-red-800 dark:hover:text-red-300' ,
@@ -131,10 +129,6 @@ export default function () {
131
129
return - 1 ;
132
130
}
133
131
134
- const openPrebuild = ( pb : PrebuildInfo ) => {
135
- history . push ( `/${ ! ! team ? 't/' + team . slug : 'projects' } /${ projectName } /${ pb . id } ` ) ;
136
- }
137
-
138
132
const triggerPrebuild = ( branchName : string | null ) => {
139
133
if ( project ) {
140
134
getGitpodService ( ) . server . triggerPrebuild ( project . id , branchName ) ;
@@ -159,7 +153,8 @@ export default function () {
159
153
< div className = "py-3 pl-3" >
160
154
< DropDown prefix = "Prebuild Status: " contextMenuWidth = "w-32" entries = { statusFilterEntries ( ) } />
161
155
</ div >
162
- < button disabled = { ! project } onClick = { ( ) => triggerPrebuild ( null ) } className = "ml-2" > Trigger Prebuild</ button >
156
+ { ( ! ! project && prebuilds . length === 0 ) &&
157
+ < button onClick = { ( ) => triggerPrebuild ( null ) } className = "ml-2" > Run Prebuild</ button > }
163
158
</ div >
164
159
< ItemsList className = "mt-2" >
165
160
< Item header = { true } className = "grid grid-cols-3" >
@@ -175,13 +170,13 @@ export default function () {
175
170
</ Item >
176
171
{ prebuilds . filter ( filter ) . sort ( prebuildSorter ) . map ( ( p , index ) => < Item key = { `prebuild-${ p . info . id } ` } className = "grid grid-cols-3" >
177
172
< ItemField className = "flex items-center" >
178
- < div className = "cursor-pointer" onClick = { ( ) => openPrebuild ( p . info ) } >
173
+ < a href = { `/ ${ ! ! team ? 't/' + team . slug : 'projects' } / ${ projectName } / ${ p . info . id } ` } className = "cursor-pointer" >
179
174
< div className = "text-base text-gray-900 dark:text-gray-50 font-medium uppercase mb-1" >
180
- < div className = "inline-block align-text-bottom mr-2 w-4 h-4" > { prebuildStatusIcon ( p . status ) } </ div >
181
- { prebuildStatusLabel ( p . status ) }
175
+ < div className = "inline-block align-text-bottom mr-2 w-4 h-4" > { prebuildStatusIcon ( p ) } </ div >
176
+ { prebuildStatusLabel ( p ) }
182
177
</ div >
183
178
< p > { p . info . startedByAvatar && < img className = "rounded-full w-4 h-4 inline-block align-text-bottom mr-2" src = { p . info . startedByAvatar || '' } alt = { p . info . startedBy } /> } Triggered { formatDate ( p . info . startedAt ) } </ p >
184
- </ div >
179
+ </ a >
185
180
</ ItemField >
186
181
< ItemField className = "flex items-center" >
187
182
< div >
@@ -203,41 +198,39 @@ export default function () {
203
198
</ > ;
204
199
}
205
200
206
- export function prebuildStatusLabel ( status : PrebuiltWorkspaceState | undefined ) {
207
- switch ( status ) {
208
- case "aborted" :
201
+ export function prebuildStatusLabel ( prebuild ?: PrebuildWithStatus ) {
202
+ if ( prebuild ?. error ) {
203
+ return ( < span className = "font-medium text-red-500 uppercase" > failed</ span > ) ;
204
+ }
205
+ switch ( prebuild ?. status ) {
206
+ case undefined : // Fall through
207
+ case "queued" :
208
+ return ( < span className = "font-medium text-orange-500 uppercase" > pending</ span > ) ;
209
+ case "building" :
210
+ return ( < span className = "font-medium text-blue-500 uppercase" > running</ span > ) ;
211
+ case "aborted" : // Fall through
212
+ case "timeout" :
209
213
return ( < span className = "font-medium text-red-500 uppercase" > failed</ span > ) ;
210
214
case "available" :
211
215
return ( < span className = "font-medium text-green-500 uppercase" > ready</ span > ) ;
212
- case "building" :
213
- return ( < span className = "font-medium text-blue-500 uppercase" > running</ span > ) ;
214
- case "queued" :
215
- return ( < span className = "font-medium text-orange-500 uppercase" > pending</ span > ) ;
216
- default :
217
- break ;
218
216
}
219
217
}
220
218
221
- export function prebuildStatusIcon ( status : PrebuiltWorkspaceState | undefined ) {
222
- switch ( status ) {
223
- case "aborted" :
224
- return ( < svg width = "16" height = "16" viewBox = "0 0 16 16" fill = "none" xmlns = "http://www.w3.org/2000/svg" >
225
- < path fill-rule = "evenodd" clip-rule = "evenodd" d = "M8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16ZM6.70711 5.29289C6.31658 4.90237 5.68342 4.90237 5.29289 5.29289C4.90237 5.68342 4.90237 6.31658 5.29289 6.70711L6.58579 8L5.29289 9.29289C4.90237 9.68342 4.90237 10.3166 5.29289 10.7071C5.68342 11.0976 6.31658 11.0976 6.70711 10.7071L8 9.41421L9.29289 10.7071C9.68342 11.0976 10.3166 11.0976 10.7071 10.7071C11.0976 10.3166 11.0976 9.68342 10.7071 9.29289L9.41421 8L10.7071 6.70711C11.0976 6.31658 11.0976 5.68342 10.7071 5.29289C10.3166 4.90237 9.68342 4.90237 9.29289 5.29289L8 6.58579L6.70711 5.29289Z" fill = "#F87171" />
226
- </ svg > )
227
- case "available" :
228
- return ( < svg width = "16" height = "16" viewBox = "0 0 16 16" fill = "none" xmlns = "http://www.w3.org/2000/svg" >
229
- < path fill-rule = "evenodd" clip-rule = "evenodd" d = "M8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16ZM11.7071 6.70711C12.0976 6.31658 12.0976 5.68342 11.7071 5.29289C11.3166 4.90237 10.6834 4.90237 10.2929 5.29289L7 8.58578L5.7071 7.29289C5.31658 6.90237 4.68342 6.90237 4.29289 7.29289C3.90237 7.68342 3.90237 8.31658 4.29289 8.70711L6.29289 10.7071C6.68342 11.0976 7.31658 11.0976 7.7071 10.7071L11.7071 6.70711Z" fill = "#84CC16" />
230
- </ svg > ) ;
231
- case "building" :
232
- return ( < svg width = "17" height = "16" viewBox = "0 0 17 16" fill = "none" xmlns = "http://www.w3.org/2000/svg" >
233
- < path fill-rule = "evenodd" clip-rule = "evenodd" d = "M8.99609 16C13.4144 16 16.9961 12.4183 16.9961 8C16.9961 3.58172 13.4144 0 8.99609 0C4.57781 0 0.996094 3.58172 0.996094 8C0.996094 12.4183 4.57781 16 8.99609 16ZM9.99609 4C9.99609 3.44772 9.54837 3 8.99609 3C8.4438 3 7.99609 3.44772 7.99609 4V8C7.99609 8.26522 8.10144 8.51957 8.28898 8.70711L11.1174 11.5355C11.5079 11.9261 12.1411 11.9261 12.5316 11.5355C12.9221 11.145 12.9221 10.5118 12.5316 10.1213L9.99609 7.58579V4Z" fill = "#60A5FA" />
234
- </ svg > ) ;
219
+ export function prebuildStatusIcon ( prebuild ?: PrebuildWithStatus ) {
220
+ if ( prebuild ?. error ) {
221
+ return < img className = "h-4 w-4" src = { StatusFailed } /> ;
222
+ }
223
+ switch ( prebuild ?. status ) {
224
+ case undefined : // Fall through
235
225
case "queued" :
236
- return ( < svg width = "16" height = "16" viewBox = "0 0 16 16" fill = "none" xmlns = "http://www.w3.org/2000/svg" >
237
- < path fill-rule = "evenodd" clip-rule = "evenodd" d = "M16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8ZM5 6C5 5.44772 5.44772 5 6 5C6.55228 5 7 5.44772 7 6V10C7 10.5523 6.55228 11 6 11C5.44772 11 5 10.5523 5 10V6ZM10 5C9.44771 5 9 5.44772 9 6V10C9 10.5523 9.44771 11 10 11C10.5523 11 11 10.5523 11 10V6C11 5.44772 10.5523 5 10 5Z" fill = "#FBBF24" />
238
- </ svg > ) ;
239
- default :
240
- break ;
226
+ return < img className = "h-4 w-4" src = { StatusPaused } /> ;
227
+ case "building" :
228
+ return < img className = "h-4 w-4" src = { StatusRunning } /> ;
229
+ case "aborted" : // Fall through
230
+ case "timeout" :
231
+ return < img className = "h-4 w-4" src = { StatusFailed } /> ;
232
+ case "available" :
233
+ return < img className = "h-4 w-4" src = { StatusDone } /> ;
241
234
}
242
235
}
243
236
@@ -285,7 +278,7 @@ export function PrebuildInstanceStatus(props: { prebuildInstance?: WorkspaceInst
285
278
</ div > ;
286
279
break ;
287
280
}
288
- if ( props . prebuildInstance ?. status . conditions . failed ) {
281
+ if ( props . prebuildInstance ?. status . conditions . failed || props . prebuildInstance ?. status . conditions . headlessTaskFailed ) {
289
282
status = < div className = "flex space-x-1 items-center text-gitpod-red" >
290
283
< img className = "h-4 w-4" src = { StatusFailed } />
291
284
< span > FAILED</ span >
0 commit comments