Skip to content

Commit 36dc03f

Browse files
committed
Merge remote-tracking branch 'origin/staging'
2 parents 052a0a6 + 26c3533 commit 36dc03f

14 files changed

Lines changed: 292 additions & 127 deletions

public/locales/de/translation.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,8 @@
6565
"Descending": "Absteigend",
6666
"Default": "Standard",
6767
"redirect_toast": "Weitergeleitet zum veröffentlichten Beispiel",
68-
"Submission Successful": "Abgabe Erfolgreich"
68+
"A new lecture example just has been published": "Eine neues Vorlesungsbeispiel wurde gerade eben veröffentlicht.",
69+
"submission_received": "Abgabe erhalten",
70+
"feedback_info": "Feedback wird nach Ablauf der Zeit bereitgestellt.",
71+
"no_bookmarks": "Es wurden noch keine Lesezeichen gesetzt."
6972
}

public/locales/en/translation.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
"Descending": "Descending",
5858
"Default": "Default",
5959
"redirect_toast": "Redirected to published example",
60-
"Submission Successful": "Submission Successful",
61-
"Correctness": "Correctness"
60+
"Correctness": "Correctness",
61+
"A new lecture example just has been published": "A new lecture example just has has been published",
62+
"submission_received": "Submision received",
63+
"feedback_info": "Feedback will be provided once the time runs out.",
64+
"no_bookmarks": "No bookmarks have been set yet."
6265
}

src/components/BookmarkView.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Button, Flex, Text, VStack } from "@chakra-ui/react"
2+
import { t } from "i18next"
23

34
const Bookmark: React.FC<{
45
bookmark: Bookmark
@@ -39,7 +40,7 @@ export const BookmarkView: React.FC<{
3940
if (!bookmarks)
4041
return (
4142
<Flex justify={"center"} flex={1}>
42-
<Text> There are no Bookmarks yet.</Text>
43+
<Text> {t("no_bookmarks")}</Text>
4344
</Flex>
4445
)
4546

src/components/Buttons.tsx

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { InfoOutlineIcon } from "@chakra-ui/icons"
12
import {
23
Box,
34
BoxProps,
@@ -15,31 +16,43 @@ import {
1516
Tooltip,
1617
VStack,
1718
} from "@chakra-ui/react"
18-
import React from "react"
19-
import { Link } from "react-router-dom"
20-
import { ActionIcon } from "./Icons"
21-
import { FcCalendar } from "react-icons/fc"
22-
import { InfoOutlineIcon } from "@chakra-ui/icons"
2319
import { flatMap, get, keys } from "lodash"
2420
import Countdown, { CountdownProps } from "react-countdown"
2521
import { useTranslation } from "react-i18next"
22+
import { FcCalendar } from "react-icons/fc"
23+
import { Link } from "react-router-dom"
24+
import { ActionIcon } from "./Icons"
2625

2726
type EventBoxProps = {
2827
selected: string
2928
events: Record<string, Record<string, AssignmentProps[]>>
3029
}
3130

32-
export const LogoButton = () => (
33-
<Box
34-
as={Link}
35-
to="/courses"
36-
fontFamily="monospace"
37-
fontSize="4xl"
38-
pt={2}
39-
_hover={{ color: "purple.500" }}
40-
children="ACCESS."
41-
/>
42-
)
31+
export const LogoButton: React.FC<{ disabled?: boolean }> = ({ disabled }) => {
32+
if (disabled) {
33+
return (
34+
<Box
35+
fontFamily="monospace"
36+
fontSize="4xl"
37+
pt={2}
38+
children="ACCESS."
39+
cursor={"not-allowed"}
40+
/>
41+
)
42+
}
43+
44+
return (
45+
<Box
46+
as={Link}
47+
to="/courses"
48+
fontFamily="monospace"
49+
fontSize="4xl"
50+
pt={2}
51+
_hover={{ color: "purple.500" }}
52+
children="ACCESS."
53+
/>
54+
)
55+
}
4356

4457
export const TooltipIconButton = ({
4558
"aria-label": label,
@@ -117,7 +130,7 @@ export const EventBox = ({ selected, events }: EventBoxProps) => {
117130
{get(a, key + "Time")}
118131
</Text>
119132
</HStack>
120-
))
133+
)),
121134
)}
122135
</Stack>
123136
</Stack>

src/components/Hooks.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,7 @@ export const useCourse = (options: UseQueryOptions<CourseProps> = {}) => {
6767
export const usePublish = () => {
6868
const { courseSlug, exampleSlug } = useParams()
6969
// eslint-disable-next-line @typescript-eslint/no-explicit-any
70-
const { mutateAsync } = useMutation<any, AxiosError, any[]>({
71-
// TODO: type this correctly once backend res is known.
72-
onSuccess: () => {
73-
// just for now
74-
console.log("Redirected")
75-
},
76-
})
70+
const { mutateAsync } = useMutation<any, AxiosError, any[]>({})
7771

7872
const publish = (duration: number) =>
7973
mutateAsync([

src/components/SubmissionsCarousel.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ export const SubmissionsCarousel: React.FC<{
235235
lastDisplayedSubmissionId: number | null
236236
selectedFileName: string | null
237237
setSelectedFileName: React.Dispatch<SetStateAction<string | null>>
238+
setTestsPassedCurrentSubmission: React.Dispatch<
239+
SetStateAction<number[] | null>
240+
>
238241
setLastDisplayedSubmissionId: React.Dispatch<SetStateAction<number | null>>
239242
handleOnBookmarkClick: (submission: SubmissionSsePayload) => void
240243
openInEditor: (studentId: string) => Promise<void>
@@ -245,6 +248,7 @@ export const SubmissionsCarousel: React.FC<{
245248
bookmarks,
246249
selectedFileName,
247250
setSelectedFileName,
251+
setTestsPassedCurrentSubmission,
248252
setLastDisplayedSubmissionId,
249253
handleOnBookmarkClick,
250254
openInEditor,
@@ -333,6 +337,12 @@ export const SubmissionsCarousel: React.FC<{
333337
}
334338
}, [fileNames, selectedFileName, setSelectedFileName])
335339

340+
useEffect(() => {
341+
if (submissions && currentIndex !== null) {
342+
setTestsPassedCurrentSubmission(submissions[currentIndex]?.testsPassed)
343+
}
344+
}, [currentIndex, setTestsPassedCurrentSubmission, submissions])
345+
336346
const showPrevButton = currentIndex !== 0
337347
const showJumpToEndButton = currentIndex === 0 && submissions.length > 1
338348
const showNextButton = currentIndex !== submissions.length - 1
@@ -371,13 +381,8 @@ export const SubmissionsCarousel: React.FC<{
371381
height={"auto"}
372382
>
373383
{submissions.map((submission, i) => {
374-
const VISIBLE_RANGE = 3
375-
const isVisible =
376-
Math.abs(i - currentIndex) <= VISIBLE_RANGE ||
377-
(i < VISIBLE_RANGE &&
378-
currentIndex > submissions.length - VISIBLE_RANGE) ||
379-
(i > submissions.length - VISIBLE_RANGE &&
380-
currentIndex < VISIBLE_RANGE)
384+
const VISIBLE_RANGE = 1 // renders 1 to the left and right of current visible editor => 3 in total
385+
const isVisible = Math.abs(i - currentIndex) <= VISIBLE_RANGE
381386

382387
return (
383388
<Slide

src/components/TestCaseBarChart.tsx

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,15 @@ const CustomBar: React.FC<{
1515
name: string
1616
value: number
1717
testCaseSelection: Record<string, boolean> | null
18+
failedForCurrentImplementation: boolean | null
1819
handleOnBarClick: (name: string) => void
19-
}> = ({ name, value, testCaseSelection, handleOnBarClick }) => {
20+
}> = ({
21+
name,
22+
value,
23+
testCaseSelection,
24+
failedForCurrentImplementation,
25+
handleOnBarClick,
26+
}) => {
2027
const selectedColor = "purple.500"
2128
const unselectedColor = "purple.200"
2229

@@ -38,9 +45,19 @@ const CustomBar: React.FC<{
3845
<Text justifyContent={"center"} pl={2} position={"absolute"} zIndex={1}>
3946
{name}
4047
</Text>
41-
<Text position={"absolute"} right={2} zIndex={1}>
42-
{value.toFixed()}%
43-
</Text>
48+
<Flex position={"absolute"} right={2} zIndex={1} align={"center"} gap={2}>
49+
<Text>{value.toFixed()}%</Text>
50+
{failedForCurrentImplementation !== null ? (
51+
<Box
52+
height={2}
53+
width={2}
54+
borderRadius={"full"}
55+
background={
56+
failedForCurrentImplementation ? "red.500" : "green.500"
57+
}
58+
/>
59+
) : null}
60+
</Flex>
4461
<Flex
4562
flex={Math.max(value, 1)}
4663
height={10}
@@ -62,8 +79,14 @@ type BarChartData = {
6279
const CustomBarChart: React.FC<{
6380
data: BarChartData[]
6481
testCaseSelection: Record<string, boolean> | null
82+
namedTestsPassedCurrentSubmission: Record<string, boolean> | null
6583
handleOnBarClick: (name: string) => void
66-
}> = ({ data, testCaseSelection, handleOnBarClick }) => {
84+
}> = ({
85+
data,
86+
testCaseSelection,
87+
namedTestsPassedCurrentSubmission,
88+
handleOnBarClick,
89+
}) => {
6790
return (
6891
<VStack width={"full"} overflow={"auto"} align={"space-around"} gap={3}>
6992
{data.map((entry, i) => (
@@ -72,6 +95,11 @@ const CustomBarChart: React.FC<{
7295
value={entry.value}
7396
testCaseSelection={testCaseSelection}
7497
handleOnBarClick={handleOnBarClick}
98+
failedForCurrentImplementation={
99+
namedTestsPassedCurrentSubmission
100+
? !namedTestsPassedCurrentSubmission[entry.name]
101+
: null
102+
}
75103
key={i}
76104
/>
77105
))}
@@ -85,6 +113,8 @@ export const TestCaseBarChart: React.FC<{
85113
passRatePerTestCase: Record<string, number>
86114
exactMatch: boolean
87115
testCaseSelection: Record<string, boolean> | null
116+
namedTestsPassedCurrentSubmission: Record<string, boolean> | null
117+
88118
setTestCaseSelection: React.Dispatch<
89119
SetStateAction<Record<string, boolean> | null>
90120
>
@@ -93,6 +123,7 @@ export const TestCaseBarChart: React.FC<{
93123
passRatePerTestCase,
94124
exactMatch,
95125
testCaseSelection,
126+
namedTestsPassedCurrentSubmission,
96127
setTestCaseSelection,
97128
setExactMatch,
98129
}) => {
@@ -187,6 +218,7 @@ export const TestCaseBarChart: React.FC<{
187218
data={sortedData}
188219
testCaseSelection={testCaseSelection}
189220
handleOnBarClick={handleOnBarClick}
221+
namedTestsPassedCurrentSubmission={namedTestsPassedCurrentSubmission}
190222
/>
191223
</Box>
192224

src/pages/Examples.tsx

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
Td,
1616
Text,
1717
Tr,
18+
useToast,
1819
VStack,
1920
} from "@chakra-ui/react"
2021
import { useQueryClient } from "@tanstack/react-query"
@@ -47,7 +48,6 @@ export const ExamplesCard: React.FC<{
4748
const { isSupervisor } = useOutletContext<UserContext>()
4849
const [examplesWithSubmissionCount, setExamplesWithSubmissionCount] =
4950
useState<(TaskOverview & { submissionCount: number })[] | null>(null)
50-
5151
useEffect(() => {
5252
if (!isSupervisor) {
5353
// nr of submissions fetchable by supervisor only
@@ -67,7 +67,7 @@ export const ExamplesCard: React.FC<{
6767
queryKey,
6868
})
6969

70-
return data.numberOfStudentsWhoSubmitted
70+
return data.numberOfReceivedSubmissions
7171
}
7272

7373
const fetchAllSubmissionCounts = async () => {
@@ -130,16 +130,19 @@ export const ExamplesCard: React.FC<{
130130
example.information["en"].title}
131131
</Heading>
132132
</Td>
133-
<Td w="17em" maxW="17em">
134-
<VStack>
135-
{published ? (
136-
<Tag bg="transparent">
137-
<TagLeftIcon as={AiOutlineInfoCircle} />
138-
<TagLabel>{example.status}</TagLabel>
139-
</Tag>
140-
) : null}
141-
</VStack>
142-
</Td>
133+
{isAssistant ? (
134+
<Td w="17em" maxW="17em">
135+
<VStack>
136+
{published ? (
137+
<Tag bg="transparent">
138+
<TagLeftIcon as={AiOutlineInfoCircle} />
139+
<TagLabel>{example.status}</TagLabel>
140+
</Tag>
141+
) : null}
142+
</VStack>
143+
</Td>
144+
) : null}
145+
143146
<Td>
144147
{example.start ? (
145148
<VStack>
@@ -197,15 +200,33 @@ export const ExamplesCard: React.FC<{
197200

198201
export default function Examples() {
199202
const { i18n, t } = useTranslation()
203+
const toast = useToast()
200204
const currentLanguage = i18n.language
201205
const { isAssistant } = useOutletContext<UserContext>()
202-
const { data: examples, refetch, isFetching } = useExamples() // TODO: only get TaskOverview, not TaskProps, once related backend problem is fixed
206+
const { data: examples, refetch, isLoading } = useExamples() // TODO: only get TaskOverview, not TaskProps, once related backend problem is fixed
203207

204208
useSSE<ExampleResetSsePayload>("example-reset", () => {
205209
refetch()
206210
})
207211

208-
if (!examples || isFetching) return <Placeholder />
212+
useSSE<string>("published", () => {
213+
refetch()
214+
toast({
215+
title: t("A new lecture example just has been published"),
216+
status: "info",
217+
})
218+
})
219+
220+
useEffect(() => {
221+
// to ensure update of exmaple states when no manual termination was triggered
222+
const interval = setInterval(() => {
223+
refetch()
224+
}, 1000 * 10)
225+
226+
return () => clearInterval(interval)
227+
}, [refetch])
228+
229+
if (!examples || isLoading) return <Placeholder />
209230

210231
const [unpublishedExaples, publishedExamples] = fork(
211232
examples,

src/pages/Landing.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ import {
99
VStack,
1010
} from "@chakra-ui/react"
1111
import { useKeycloak } from "@react-keycloak/web"
12-
import React from "react"
13-
import Typewriter from "typewriter-effect"
14-
import { SWITCHIcon } from "../components/Icons"
1512
import { Navigate } from "react-router-dom"
13+
import Typewriter from "typewriter-effect"
1614
import { LogoButton } from "../components/Buttons"
15+
import { SWITCHIcon } from "../components/Icons"
1716

1817
export function Landing() {
1918
const { keycloak } = useKeycloak()

src/pages/Layout.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,11 @@ export default function Layout() {
115115
zIndex={1}
116116
>
117117
<HStack p={3}>
118-
<LogoButton />
118+
<LogoButton
119+
disabled={
120+
!context.isAssistant && exampleStatusContext.hasInteractive
121+
}
122+
/>
119123
{courseSlug && <CourseNav isAssistant={context.isAssistant} />}
120124
</HStack>
121125
<HStack>

0 commit comments

Comments
 (0)