11import { Button , Collapse , Icon , PopoverPosition , Tooltip } from '@blueprintjs/core' ;
22import { IconNames } from '@blueprintjs/icons' ;
3- import React from 'react' ;
3+ import { useCallback , useMemo , useState } from 'react' ;
4+ import { useTranslation } from 'react-i18next' ;
45
56import { AutogradingResult , Testcase } from '../../assessment/AssessmentTypes' ;
67import ControlButton from '../../ControlButton' ;
@@ -28,12 +29,50 @@ type OwnProps = {
2829} ;
2930
3031const SideContentAutograder : React . FC < SideContentAutograderProps > = props => {
31- const [ showsTestcases , setTestcasesShown ] = React . useState ( true ) ;
32- const [ showsResults , setResultsShown ] = React . useState ( true ) ;
32+ const { t } = useTranslation ( 'sideContent' , { keyPrefix : 'autograder' } ) ;
33+ const [ showsTestcases , setTestcasesShown ] = useState ( true ) ;
34+ const [ showsResults , setResultsShown ] = useState ( true ) ;
3335
3436 const { testcases, autogradingResults, handleTestcaseEval, workspaceLocation } = props ;
3537
36- const testcaseCards = React . useMemo (
38+ const autograderTooltip = useMemo (
39+ ( ) => (
40+ < div className = "autograder-help-tooltip" >
41+ < p > { t ( 'tooltip.clickTestcase' ) } </ p >
42+ < p > { t ( 'tooltip.executeAll' ) } </ p >
43+ < p > { t ( 'tooltip.backgroundInfo' ) } </ p >
44+ < p > { t ( 'tooltip.privateTestcases' ) } </ p >
45+ </ div >
46+ ) ,
47+ [ t ]
48+ ) ;
49+
50+ const testcasesHeader = useMemo (
51+ ( ) => (
52+ < div className = "testcases-header" data-testid = "testcases-header" >
53+ { columnHeader ( 'header-fn' , t ( 'headers.testcase' ) ) }
54+ { columnHeader ( 'header-expected' , t ( 'headers.expected' ) ) }
55+ { columnHeader ( 'header-actual' , t ( 'headers.actual' ) ) }
56+ </ div >
57+ ) ,
58+ [ t ]
59+ ) ;
60+
61+ const resultsHeader = useMemo (
62+ ( ) => (
63+ < div className = "results-header" data-testid = "results-header" >
64+ < div className = "header-data" >
65+ { columnHeader ( 'header-sn' , t ( 'headers.sn' ) ) }
66+ { columnHeader ( 'header-status' , t ( 'headers.status' ) ) }
67+ </ div >
68+ { columnHeader ( 'header-expected' , t ( 'headers.expected' ) ) }
69+ { columnHeader ( 'header-actual' , t ( 'headers.actual' ) ) }
70+ </ div >
71+ ) ,
72+ [ t ]
73+ ) ;
74+
75+ const testcaseCards = useMemo (
3776 ( ) =>
3877 testcases . length > 0 ? (
3978 < div className = "testcaseCards" >
@@ -50,13 +89,13 @@ const SideContentAutograder: React.FC<SideContentAutograderProps> = props => {
5089 </ div >
5190 ) : (
5291 < div className = "noResults" data-testid = "noResults" >
53- There are no testcases provided for this question.
92+ { t ( 'noTestcases' ) }
5493 </ div >
5594 ) ,
56- [ testcases , handleTestcaseEval , workspaceLocation ]
95+ [ testcases , testcasesHeader , t , handleTestcaseEval , workspaceLocation ]
5796 ) ;
5897
59- const resultCards = React . useMemo (
98+ const resultCards = useMemo (
6099 ( ) =>
61100 autogradingResults . length > 0 ? (
62101 < div >
@@ -67,17 +106,17 @@ const SideContentAutograder: React.FC<SideContentAutograderProps> = props => {
67106 </ div >
68107 ) : (
69108 < div className = "noResults" data-testid = "noResults" >
70- There are no results to show.
109+ { t ( 'noResults' ) }
71110 </ div >
72111 ) ,
73- [ autogradingResults ]
112+ [ autogradingResults , resultsHeader , t ]
74113 ) ;
75114
76- const toggleTestcases = React . useCallback ( ( ) => {
115+ const toggleTestcases = useCallback ( ( ) => {
77116 setTestcasesShown ( ! showsTestcases ) ;
78117 } , [ showsTestcases ] ) ;
79118
80- const toggleResults = React . useCallback ( ( ) => setResultsShown ( ! showsResults ) , [ showsResults ] ) ;
119+ const toggleResults = useCallback ( ( ) => setResultsShown ( ! showsResults ) , [ showsResults ] ) ;
81120
82121 return (
83122 < div className = "Autograder" >
@@ -87,59 +126,29 @@ const SideContentAutograder: React.FC<SideContentAutograderProps> = props => {
87126 minimal = { true }
88127 onClick = { toggleTestcases }
89128 >
90- < span > Testcases </ span >
129+ < span > { t ( 'testcases' ) } </ span >
91130 < Tooltip content = { autograderTooltip } placement = { PopoverPosition . LEFT } >
92131 < Icon icon = { IconNames . HELP } />
93132 </ Tooltip >
94133 </ Button >
95134 < Collapse isOpen = { showsTestcases } keepChildrenMounted = { true } >
96135 { testcaseCards }
97136 </ Collapse >
98- { collapseButton ( 'Autograder Results' , showsResults , toggleResults ) }
137+ { collapseButton ( t ( 'results' ) , showsResults , toggleResults ) }
99138 < Collapse isOpen = { showsResults } keepChildrenMounted = { true } >
100139 { resultCards }
101140 </ Collapse >
102141 </ div >
103142 ) ;
104143} ;
105144
106- const autograderTooltip = (
107- < div className = "autograder-help-tooltip" >
108- < p > Click on each testcase below to execute it with the program in the editor.</ p >
109- < p >
110- To execute all testcases at once, evaluate the program in the editor with this tab active.
111- </ p >
112- < p > A green or red background indicates a passed or failed testcase respectively.</ p >
113- < p > Private testcases (only visible to staff when grading) have a grey background.</ p >
114- </ div >
115- ) ;
116-
117145const columnHeader = ( colClass : string , colTitle : string ) => (
118146 < div className = { colClass } >
119147 { colTitle }
120148 < Icon icon = { IconNames . CARET_DOWN } />
121149 </ div >
122150) ;
123151
124- const testcasesHeader = (
125- < div className = "testcases-header" data-testid = "testcases-header" >
126- { columnHeader ( 'header-fn' , 'Testcase' ) }
127- { columnHeader ( 'header-expected' , 'Expected result' ) }
128- { columnHeader ( 'header-actual' , 'Actual result' ) }
129- </ div >
130- ) ;
131-
132- const resultsHeader = (
133- < div className = "results-header" data-testid = "results-header" >
134- < div className = "header-data" >
135- { columnHeader ( 'header-sn' , 'S/N' ) }
136- { columnHeader ( 'header-status' , 'Testcase status' ) }
137- </ div >
138- { columnHeader ( 'header-expected' , 'Expected result' ) }
139- { columnHeader ( 'header-actual' , 'Actual result' ) }
140- </ div >
141- ) ;
142-
143152const collapseButton = ( label : string , isOpen : boolean , toggleFunc : ( ) => void ) => (
144153 < ControlButton
145154 label = { label }
0 commit comments