@@ -29,7 +29,7 @@ export default function NewProject() {
29
29
const [ reposInAccounts , setReposInAccounts ] = useState < ProviderRepository [ ] > ( [ ] ) ;
30
30
const [ repoSearchFilter , setRepoSearchFilter ] = useState < string > ( "" ) ;
31
31
const [ selectedAccount , setSelectedAccount ] = useState < string | undefined > ( undefined ) ;
32
- const [ showGitProviders , setShowGitProviders ] = useState < boolean > ( true ) ;
32
+ const [ showGitProviders , setShowGitProviders ] = useState < boolean > ( false ) ;
33
33
const [ selectedRepo , setSelectedRepo ] = useState < ProviderRepository | undefined > ( undefined ) ;
34
34
const [ selectedTeamOrUser , setSelectedTeamOrUser ] = useState < Team | User | undefined > ( undefined ) ;
35
35
@@ -42,8 +42,7 @@ export default function NewProject() {
42
42
43
43
const [ authProviders , setAuthProviders ] = useState < AuthProviderInfo [ ] > ( [ ] ) ;
44
44
const [ isGitHubAppEnabled , setIsGitHubAppEnabled ] = useState < boolean > ( ) ;
45
-
46
- console . log ( "isGitHubAppEnabled" , isGitHubAppEnabled ) ;
45
+ const [ isGitHubWebhooksUnauthorized , setIsGitHubWebhooksUnauthorized ] = useState < boolean > ( ) ;
47
46
48
47
useEffect ( ( ) => {
49
48
const { server } = getGitpodService ( ) ;
@@ -67,7 +66,25 @@ export default function NewProject() {
67
66
}
68
67
}
69
68
}
70
- } , [ user , authProviders ] ) ;
69
+ } , [ user , authProviders , selectedProviderHost ] ) ;
70
+
71
+ useEffect ( ( ) => {
72
+ setIsGitHubWebhooksUnauthorized ( false ) ;
73
+ if ( ! authProviders || ! selectedProviderHost || isGitHubAppEnabled ) {
74
+ return ;
75
+ }
76
+ const ap = authProviders . find ( ( ap ) => ap . host === selectedProviderHost ) ;
77
+ if ( ! ap || ap . authProviderType !== "GitHub" ) {
78
+ return ;
79
+ }
80
+ getGitpodService ( )
81
+ . server . getToken ( { host : ap . host } )
82
+ . then ( ( token ) => {
83
+ if ( ! token || ! token . scopes . includes ( "repo" ) ) {
84
+ setIsGitHubWebhooksUnauthorized ( true ) ;
85
+ }
86
+ } ) ;
87
+ } , [ authProviders , isGitHubAppEnabled , selectedProviderHost ] ) ;
71
88
72
89
useEffect ( ( ) => {
73
90
const params = new URLSearchParams ( location . search ) ;
@@ -215,6 +232,25 @@ export default function NewProject() {
215
232
} ) ;
216
233
} ;
217
234
235
+ const authorize = ( ) => {
236
+ const ap = authProviders . find ( ( ap ) => ap . host === selectedProviderHost ) ;
237
+ if ( ! ap ) {
238
+ return ;
239
+ }
240
+ openAuthorizeWindow ( {
241
+ host : ap . host ,
242
+ scopes : ap . authProviderType === "GitHub" ? [ "repo" ] : ap . requirements ?. default ,
243
+ onSuccess : async ( ) => {
244
+ if ( ap . authProviderType === "GitHub" ) {
245
+ setIsGitHubWebhooksUnauthorized ( false ) ;
246
+ }
247
+ } ,
248
+ onError : ( payload ) => {
249
+ console . error ( "Authorization failed" , selectedProviderHost , payload ) ;
250
+ } ,
251
+ } ) ;
252
+ } ;
253
+
218
254
const createProject = async ( teamOrUser : Team | User , repo : ProviderRepository ) => {
219
255
if ( ! selectedProviderHost ) {
220
256
return ;
@@ -298,10 +334,15 @@ export default function NewProject() {
298
334
} ;
299
335
300
336
const renderSelectRepository = ( ) => {
301
- const noReposAvailable = reposInAccounts . length === 0 ;
302
- const filteredRepos = Array . from ( reposInAccounts ) . filter (
303
- ( r ) => r . account === selectedAccount && `${ r . name } ` . toLowerCase ( ) . includes ( repoSearchFilter . toLowerCase ( ) ) ,
304
- ) ;
337
+ // Don't list GitHub projects if we cannot install webhooks on them (project creation would eventually fail)
338
+ const noReposAvailable = reposInAccounts . length === 0 || isGitHubWebhooksUnauthorized ;
339
+ const filteredRepos = isGitHubWebhooksUnauthorized
340
+ ? [ ]
341
+ : Array . from ( reposInAccounts ) . filter (
342
+ ( r ) =>
343
+ r . account === selectedAccount &&
344
+ `${ r . name } ` . toLowerCase ( ) . includes ( repoSearchFilter . toLowerCase ( ) ) ,
345
+ ) ;
305
346
const icon = selectedAccount && accounts . get ( selectedAccount ) ?. avatarUrl ;
306
347
307
348
const showSearchInput = ! ! repoSearchFilter || filteredRepos . length > 0 ;
@@ -430,13 +471,19 @@ export default function NewProject() {
430
471
< div >
431
472
< div className = "px-12 py-20 text-center text-gray-500 bg-gray-50 dark:bg-gray-800 rounded-xl" >
432
473
< span className = "dark:text-gray-400" >
433
- Additional authorization is required for our GitHub App to watch your
474
+ Additional authorization is required for Gitpod to watch your GitHub
434
475
repositories and trigger prebuilds.
435
476
</ span >
436
477
< br />
437
- < button className = "mt-6" onClick = { ( ) => reconfigure ( ) } >
438
- Configure Gitpod App
439
- </ button >
478
+ { isGitHubWebhooksUnauthorized ? (
479
+ < button className = "mt-6" onClick = { ( ) => authorize ( ) } >
480
+ Authorize GitHub
481
+ </ button >
482
+ ) : (
483
+ < button className = "mt-6" onClick = { ( ) => reconfigure ( ) } >
484
+ Configure Gitpod App
485
+ </ button >
486
+ ) }
440
487
</ div >
441
488
</ div >
442
489
) }
0 commit comments