@@ -21,13 +21,14 @@ const ContainerAutoGraderForm = ({ open, onClose }: Props) => {
21
21
const [ setAlert ] = useActionless ( SET_ALERT )
22
22
const { assignmentId, courseId } = useParams < { assignmentId : string ; courseId : string } > ( ) ;
23
23
// const history = useHistory()
24
- const [ graderFile , setGraderFile ] = useState < File | null > ( )
25
- const [ makefile , setMakefile ] = useState < File | null > ( )
24
+ const [ dockerfile , setDockerfile ] = useState < File | null > ( )
25
+ const [ jobFiles , setJobFiles ] = useState < File [ ] > ( )
26
+
26
27
const [ formData , setFormData ] = useState ( {
27
28
assignmentId : assignmentId ,
28
- autogradingImage : '' ,
29
29
timeout : '' ,
30
30
} )
31
+ formData
31
32
// const [invalidFields, setInvalidFields] = useState(new Map<string, string>())
32
33
33
34
// const handleChange = (value: String, e : React.ChangeEvent<HTMLInputElement>) => {
@@ -39,31 +40,42 @@ const ContainerAutoGraderForm = ({ open, onClose }: Props) => {
39
40
40
41
//This is janky but it works and I'm too tired to come up with a better solution
41
42
//this is done because the files need to be uniquely identified for multer to parse them from the multipart
42
- const handleGraderfileChange = ( e : React . ChangeEvent < HTMLInputElement > ) => {
43
- setGraderFile ( e . target . files ?. item ( 0 ) )
43
+ const handleDockerfile = ( e : React . ChangeEvent < HTMLInputElement > ) => {
44
+ setDockerfile ( e . target . files ?. item ( 0 ) )
44
45
}
45
- const handleMakefileChange = ( e : React . ChangeEvent < HTMLInputElement > ) => {
46
- setMakefile ( e . target . files ?. item ( 0 ) )
46
+ const handleJobFiles = ( e : React . ChangeEvent < HTMLInputElement > ) => {
47
+ if ( ! e . target . files ) { return }
48
+ setJobFiles ( Array . from ( e . target . files ) )
47
49
}
48
50
const handleChange = ( e : React . ChangeEvent < HTMLInputElement > ) => {
49
51
const key = e . target . id ;
50
52
const value = e . target . value ;
51
53
setFormData ( prevState => ( { ...prevState , [ key ] : value } ) ) ;
52
54
} ;
55
+ const isSubmittable = ( ) => {
56
+ if ( dockerfile && jobFiles && formData . timeout . length > 0 ) {
57
+ return true ;
58
+ }
59
+ return false ;
60
+ }
61
+ const handleSubmit = ( ) => {
62
+ if ( ! dockerfile || ! jobFiles ) { return }
53
63
64
+ const body = new FormData
65
+ body . append ( 'assignmentId' , formData . assignmentId )
66
+ body . append ( 'timeoutInSeconds' , formData . timeout )
67
+ body . append ( 'dockerfile' , dockerfile )
54
68
69
+ for ( let i = 0 ; i < jobFiles . length ; i ++ ) {
70
+ const f = jobFiles . at ( i )
71
+ if ( f ) {
72
+ body . append ( 'jobFiles' , f )
73
+ }
74
+ }
75
+
55
76
56
- const handleSubmit = ( ) => {
57
- if ( ! graderFile || ! makefile ) return ;
58
-
59
- const multipart = new FormData
60
- multipart . append ( 'assignmentId' , formData . assignmentId )
61
- multipart . append ( 'autogradingImage' , formData . autogradingImage )
62
- multipart . append ( 'timeout' , String ( formData . timeout ) )
63
- if ( graderFile ) multipart . append ( 'graderFile' , graderFile )
64
- if ( makefile ) multipart . append ( 'makefileFile' , makefile )
65
77
66
- RequestService . postMultipart ( `/api/course/${ courseId } /assignment/${ assignmentId } /container-auto-graders/` , multipart )
78
+ RequestService . postMultipart ( `/api/course/${ courseId } /assignment/${ assignmentId } /container-auto-graders/` , body )
67
79
. then ( ( ) => {
68
80
setAlert ( { autoDelete : true , type : 'success' , message : 'Container Auto-Grader Added' } )
69
81
} )
@@ -79,33 +91,32 @@ const ContainerAutoGraderForm = ({ open, onClose }: Props) => {
79
91
80
92
setFormData ( {
81
93
assignmentId : assignmentId ,
82
- autogradingImage : '' ,
83
94
timeout : '' ,
84
95
} )
85
96
86
97
onClose ( ) ;
87
98
}
88
99
89
100
return (
90
- < Modal title = "Add Container Auto Grader" buttonAction = { handleSubmit } open = { open } onClose = { onClose } >
101
+ < Modal title = "Add Container Auto Grader"
102
+ buttonAction = { handleSubmit }
103
+ open = { open }
104
+ onClose = { onClose }
105
+ isSubmittable = { isSubmittable } >
91
106
< div className = "input-group" >
92
- < label htmlFor = "autogradingImage" > Autograding Image*:</ label >
93
- { /* <input type="text" id="autogradingImage" onChange={(e) => setFormData({ ...formData, autogradingImage: e.target.value })} placeholder="e.g. Assignment 1 Image" /> */ }
94
- < input type = "text" id = "autogradingImage" onChange = { handleChange } placeholder = "e.g. Assignment 1 Image" />
107
+ < label htmlFor = "dockerfile" > Dockerfile*:</ label >
108
+ < input type = "file" id = "graderFile" onChange = { handleDockerfile } />
95
109
</ div >
96
110
< div className = "input-group" >
97
- < label htmlFor = "timeout" > Timeout (ms):</ label >
98
- { /* <input type="number" id="timeout" placeholder="e.g. 3000" onChange={(e) => setFormData({ ...formData, timeout: e.target.value })} /> */ }
99
- < input type = "number" id = "timeout" placeholder = "e.g. 3000" onChange = { handleChange } />
100
- </ div >
101
- < div className = "input-group" >
102
- < label htmlFor = "graderFile" > Graderfile*:</ label >
103
- < input type = "file" id = "graderFile" onChange = { handleGraderfileChange } />
111
+ < label htmlFor = "dockerfile" > Job Files*:</ label >
112
+ < input type = "file" id = "graderFile" multiple onChange = { handleJobFiles } />
104
113
</ div >
105
114
< div className = "input-group" >
106
- < label htmlFor = "makefile" > Makefile*:</ label >
107
- < input type = "file" id = "makefile" onChange = { handleMakefileChange } />
115
+ < label htmlFor = "timeout" > Timeout (s):</ label >
116
+ { /* <input type="number" id="timeout" placeholder="e.g. 3000" onChange={(e) => setFormData({ ...formData, timeout: e.target.value })} /> */ }
117
+ < input type = "number" id = "timeout" placeholder = "e.g. 1" onChange = { handleChange } />
108
118
</ div >
119
+
109
120
</ Modal >
110
121
) ;
111
122
} ;
0 commit comments