1
1
import { useQuery , useMutation , gql } from "@apollo/client" ;
2
- import React , { useState , useEffect } from "react" ;
2
+ import React , { useState , useEffect , useCallback } from "react" ;
3
3
4
4
import Link from "@mui/material/Link" ;
5
5
import { Link as ReactLink } from "react-router-dom" ;
@@ -26,23 +26,19 @@ import Chip from "@mui/material/Chip";
26
26
import { ShareProjDialog } from "../components/ShareProjDialog" ;
27
27
import useMe from "../lib/me" ;
28
28
import { getUpTime } from "../lib/utils" ;
29
- import { Button } from "@mui/material" ;
29
+ import {
30
+ Button ,
31
+ Dialog ,
32
+ DialogActions ,
33
+ DialogContent ,
34
+ DialogTitle ,
35
+ } from "@mui/material" ;
30
36
import { useAuth } from "../lib/auth" ;
31
37
import { GoogleSignin } from "./login" ;
32
38
import { timeDifference } from "../lib/utils" ;
33
39
34
- function RepoLine ( { repo, deletable, sharable, runtimeInfo } ) {
40
+ function RepoLine ( { repo, deletable, sharable, runtimeInfo, onDeleteRepo } ) {
35
41
const { me } = useMe ( ) ;
36
- const [ deleteRepo ] = useMutation (
37
- gql `
38
- mutation deleteRepo($id: ID!) {
39
- deleteRepo(id: $id)
40
- }
41
- ` ,
42
- {
43
- refetchQueries : [ "GetRepos" ] ,
44
- }
45
- ) ;
46
42
const [ killRuntime ] = useMutation (
47
43
gql `
48
44
mutation killRuntime($sessionId: String!) {
@@ -99,13 +95,9 @@ function RepoLine({ repo, deletable, sharable, runtimeInfo }) {
99
95
< Tooltip title = "Delete Repo" >
100
96
< IconButton
101
97
size = "small"
102
- onClick = { async ( ) => {
98
+ onClick = { ( ) => {
103
99
// FIXME ensure the runtime is killed
104
- deleteRepo ( {
105
- variables : {
106
- id : repo . id ,
107
- } ,
108
- } ) ;
100
+ onDeleteRepo ( repo ) ;
109
101
} }
110
102
>
111
103
< DeleteIcon fontSize = "inherit" />
@@ -207,6 +199,19 @@ function CreateRepoForm(props) {
207
199
208
200
function RepoList ( { repos } ) {
209
201
const { me } = useMe ( ) ;
202
+ const [ clickedRepo , setClickedRepo ] = useState <
203
+ { id : string ; name : string } | undefined
204
+ > ( ) ;
205
+ const [ deleteRepo ] = useMutation (
206
+ gql `
207
+ mutation deleteRepo($id: ID!) {
208
+ deleteRepo(id: $id)
209
+ }
210
+ ` ,
211
+ {
212
+ refetchQueries : [ "GetRepos" ] ,
213
+ }
214
+ ) ;
210
215
// FIXME once ttl is reached, the runtime is killed, but this query is not
211
216
// updated.
212
217
const { loading, data } = useQuery ( gql `
@@ -217,37 +222,55 @@ function RepoList({ repos }) {
217
222
}
218
223
}
219
224
` ) ;
225
+
226
+ const onConfirmDeleteRepo = useCallback ( ( ) => {
227
+ deleteRepo ( {
228
+ variables : {
229
+ id : clickedRepo ?. id ,
230
+ } ,
231
+ } ) ;
232
+ setClickedRepo ( undefined ) ;
233
+ } , [ clickedRepo , deleteRepo ] ) ;
220
234
return (
221
- < TableContainer component = { Paper } >
222
- < Table >
223
- < TableHead >
224
- < TableRow >
225
- < TableCell align = "left" > Name</ TableCell >
226
- < TableCell align = "left" > Visibility</ TableCell >
227
- < TableCell align = "left" > Status (TTL: 12h)</ TableCell >
228
- < TableCell align = "left" > Last Viewed</ TableCell >
229
- < TableCell align = "left" > Operations</ TableCell >
230
- </ TableRow >
231
- </ TableHead >
232
- < TableBody >
233
- { repos . map ( ( repo ) => (
234
- < RepoLine
235
- repo = { repo }
236
- deletable = { true }
237
- sharable = { true }
238
- runtimeInfo = {
239
- loading
240
- ? null
241
- : data . listAllRuntimes . find (
242
- ( { sessionId } ) => sessionId === `${ me . id } _${ repo . id } `
243
- )
244
- }
245
- key = { repo . id }
246
- />
247
- ) ) }
248
- </ TableBody >
249
- </ Table >
250
- </ TableContainer >
235
+ < >
236
+ < TableContainer component = { Paper } >
237
+ < Table >
238
+ < TableHead >
239
+ < TableRow >
240
+ < TableCell align = "left" > Name</ TableCell >
241
+ < TableCell align = "left" > Visibility</ TableCell >
242
+ < TableCell align = "left" > Status (TTL: 12h)</ TableCell >
243
+ < TableCell align = "left" > Last Viewed</ TableCell >
244
+ < TableCell align = "left" > Operations</ TableCell >
245
+ </ TableRow >
246
+ </ TableHead >
247
+ < TableBody >
248
+ { repos . map ( ( repo ) => (
249
+ < RepoLine
250
+ repo = { repo }
251
+ deletable = { true }
252
+ sharable = { true }
253
+ runtimeInfo = {
254
+ loading
255
+ ? null
256
+ : data . listAllRuntimes . find (
257
+ ( { sessionId } ) => sessionId === `${ me . id } _${ repo . id } `
258
+ )
259
+ }
260
+ key = { repo . id }
261
+ onDeleteRepo = { setClickedRepo }
262
+ />
263
+ ) ) }
264
+ </ TableBody >
265
+ </ Table >
266
+ </ TableContainer >
267
+ < ConfirmDeleteDialog
268
+ repoName = { clickedRepo ?. name }
269
+ open = { Boolean ( clickedRepo ) }
270
+ handleCancel = { ( ) => setClickedRepo ( undefined ) }
271
+ handleConfirm = { onConfirmDeleteRepo }
272
+ />
273
+ </ >
251
274
) ;
252
275
}
253
276
@@ -403,6 +426,32 @@ function RepoLists() {
403
426
) ;
404
427
}
405
428
429
+ function ConfirmDeleteDialog ( {
430
+ open,
431
+ repoName,
432
+ handleConfirm,
433
+ handleCancel,
434
+ } : {
435
+ open : boolean ;
436
+ repoName ?: string ;
437
+ handleConfirm : ( ) => void ;
438
+ handleCancel : ( ) => void ;
439
+ } ) {
440
+ const name = repoName ?? "Repo" ;
441
+ return (
442
+ < Dialog open = { open } onClose = { handleCancel } fullWidth >
443
+ < DialogTitle > { `Delete ${ name } ` } </ DialogTitle >
444
+ < DialogContent > Are you sure?</ DialogContent >
445
+ < DialogActions >
446
+ < Button onClick = { handleCancel } > Cancel</ Button >
447
+ < Button onClick = { handleConfirm } autoFocus >
448
+ Confirm
449
+ </ Button >
450
+ </ DialogActions >
451
+ </ Dialog >
452
+ ) ;
453
+ }
454
+
406
455
export default function Page ( ) {
407
456
const { me } = useMe ( ) ;
408
457
const { hasToken, loginGuest, isSignedIn } = useAuth ( ) ;
0 commit comments