@@ -21,13 +21,14 @@ const ContainerAutoGraderForm = ({ open, onClose }: Props) => {
2121 const [ setAlert ] = useActionless ( SET_ALERT )
2222 const { assignmentId, courseId } = useParams < { assignmentId : string ; courseId : string } > ( ) ;
2323 // 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+
2627 const [ formData , setFormData ] = useState ( {
2728 assignmentId : assignmentId ,
28- autogradingImage : '' ,
2929 timeout : '' ,
3030 } )
31+ formData
3132 // const [invalidFields, setInvalidFields] = useState(new Map<string, string>())
3233
3334 // const handleChange = (value: String, e : React.ChangeEvent<HTMLInputElement>) => {
@@ -39,31 +40,42 @@ const ContainerAutoGraderForm = ({ open, onClose }: Props) => {
3940
4041 //This is janky but it works and I'm too tired to come up with a better solution
4142 //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 ) )
4445 }
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 ) )
4749 }
4850 const handleChange = ( e : React . ChangeEvent < HTMLInputElement > ) => {
4951 const key = e . target . id ;
5052 const value = e . target . value ;
5153 setFormData ( prevState => ( { ...prevState , [ key ] : value } ) ) ;
5254 } ;
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 }
5363
64+ const body = new FormData
65+ body . append ( 'assignmentId' , formData . assignmentId )
66+ body . append ( 'timeoutInSeconds' , formData . timeout )
67+ body . append ( 'dockerfile' , dockerfile )
5468
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+
5576
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 )
6577
66- RequestService . postMultipart ( `/api/course/${ courseId } /assignment/${ assignmentId } /container-auto-graders/` , multipart )
78+ RequestService . postMultipart ( `/api/course/${ courseId } /assignment/${ assignmentId } /container-auto-graders/` , body )
6779 . then ( ( ) => {
6880 setAlert ( { autoDelete : true , type : 'success' , message : 'Container Auto-Grader Added' } )
6981 } )
@@ -79,33 +91,32 @@ const ContainerAutoGraderForm = ({ open, onClose }: Props) => {
7991
8092 setFormData ( {
8193 assignmentId : assignmentId ,
82- autogradingImage : '' ,
8394 timeout : '' ,
8495 } )
8596
8697 onClose ( ) ;
8798 }
8899
89100 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 } >
91106 < 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 } />
95109 </ div >
96110 < 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 } />
104113 </ div >
105114 < 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 } />
108118 </ div >
119+
109120 </ Modal >
110121 ) ;
111122} ;
0 commit comments