Skip to content

Commit

Permalink
Merge branch 'development' into frontend/docutation/readme-update
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerwoud authored May 13, 2024
2 parents c01e755 + 1d0b4f8 commit 13c9296
Show file tree
Hide file tree
Showing 58 changed files with 405 additions and 311 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ def get_last_submissions_per_user(project_id):
(Submission.submission_time == latest_submissions.c.max_time)
).all()

if not submissions:
return {"message": "No submissions found", "url": BASE_URL}, 404

return {"message": "Resource fetched succesfully", "data": submissions}, 200

class SubmissionDownload(Resource):
Expand Down
4 changes: 4 additions & 0 deletions backend/project/endpoints/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ def get(self):
role = Role[role.upper()]
query = query.filter(userModel.role == role)

uid = request.args.getlist("uid")
if len(uid) > 0:
query = query.filter(userModel.uid.in_(uid))

users = query.all()
users = [user.to_dict() for user in users]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@

npm-debug.log*
yarn-debug.log*
yarn-error.log*
yarn-error.log*
27 changes: 27 additions & 0 deletions documentation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# UGent-3 project peristerónas user guide

## Introduction
Project peristerónas has a lot of features, therefore a detailed user guide is available to consult.

## Usage
### Development
If you want to develop on the site, run the following command:
```sh
npm run start
```
This creates a lightweight version of the site, if you want to test a certain language version of the site you can use the command:
```sh
npm run start -- --locale [language]
```

### Deployment
When you're ready to deploy, run the following command to run the proper version of the site:
```sh
npm run build
```

A static version will be built that you can access in the directory `build/`, you can then run the static site by using the command:

```sh
npm run serve
```
File renamed without changes.
File renamed without changes.
File renamed without changes
41 changes: 0 additions & 41 deletions documentation/documentation/README.md

This file was deleted.

This file was deleted.

File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Python evaluator
## Algemeen gebruik
Deze evaluator is verantwoordelijk voor het uitvoeren en testen van de Python-code van een student.

## Structuur
Bij het indienen van het project kan een leraar vereisten toevoegen via het bestand `req-manifest.txt`. Op deze manier zijn alleen de pakketten in het vereistenbestand bruikbaar op de evaluator.

Wanneer er geen manifest aanwezig is, kunnen studenten hun eigen paketten installeren met een `requirements.txt` en een `dev-requirements.txt`.
Of de leraar kan een `requirements.txt` toevoegen als ze paketten vooraf willen installeren die aanwezig moeten zijn voor het testen van het project.

## Tests uitvoeren
Als er een `run_tests.sh` aanwezig is in de projectopdrachtbestanden, wordt dit uitgevoerd wanneer de student zijn code indient.
Bij het uitvoeren van tests is het belangrijk op te merken dat de map van de inzending van de student `/submission` zal zijn.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes.
3 changes: 2 additions & 1 deletion frontend/public/locales/nl/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@
"noFilesPlaceholder": "Nog geen opgave bestanden geupload",
"noRegexPlaceholder": "Nog geen regex toegevoegd",
"unauthorized": "U heeft niet de juiste rechten om een project aan te maken voor dit vak",
"submissionError": "Er is een fout opgetreden bij het indienen van uw project, probeer het later opnieuw."
"submissionError": "Er is een fout opgetreden bij het indienen van uw project, probeer het later opnieuw.",
"clearSelected": "Deselecteer keuze"
},
"projectView": {
"submitNetworkError": "Er is iets mislopen bij het opslaan van uw indiening. Probeer het later opnieuw.",
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import ProjectOverView from "./pages/project/projectOverview.tsx";
import { synchronizeJoinCode } from "./loaders/join-code.ts";
import { fetchMe } from "./utils/fetches/FetchMe.ts";
import {fetchProjectForm} from "./components/ProjectForm/project-form.ts";
import loadSubmissionOverview from "./loaders/submission-overview-loader.ts";

const router = createBrowserRouter(
createRoutesFromElements(
Expand All @@ -34,10 +35,6 @@ const router = createBrowserRouter(
<Route index element={<HomePages />} loader={fetchProjectPage} />
<Route path=":lang" element={<LanguagePath />}>
<Route path="home" element={<HomePages />} loader={fetchProjectPage} />
<Route
path="project/:projectId/overview"
element={<SubmissionsOverview />}
/>
<Route path="courses">
<Route index element={<AllCoursesTeacher />} loader={dataLoaderCourses}/>
<Route path="join" loader={synchronizeJoinCode} />
Expand All @@ -49,6 +46,11 @@ const router = createBrowserRouter(
element={<ProjectOverView />}
loader={fetchProjectPage}
/>
<Route
loader={loadSubmissionOverview}
path=":projectId/overview"
element={<SubmissionsOverview />}
/>
<Route path=":projectId" element={<ProjectView />}></Route>
<Route path="create" element={<ProjectCreateHome />} loader={fetchProjectForm}/>
</Route>
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/components/Courses/AllCoursesTeacher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { SideScrollableCourses } from "./CourseUtilComponents";
import { Course, callToApiToCreateCourse } from "./CourseUtils";
import {Course, callToApiToCreateCourse, ProjectDetail} from "./CourseUtils";
import { Title } from "../Header/Title";
import { useLoaderData } from "react-router-dom";

Expand All @@ -12,7 +12,12 @@ import { useLoaderData } from "react-router-dom";
*/
export function AllCoursesTeacher(): JSX.Element {
const [open, setOpen] = useState(false);
const courses = (useLoaderData() as Course[]);
const loader = useLoaderData() as {
courses: Course[];
projects: { [courseId: string]: ProjectDetail[] }
};
const courses = loader.courses;
const projects = loader.projects;

const [courseName, setCourseName] = useState('');
const [error, setError] = useState('');
Expand Down Expand Up @@ -49,7 +54,7 @@ export function AllCoursesTeacher(): JSX.Element {
<>
<Title title={t('title')}></Title>
<Grid container direction={'column'} style={{marginTop: '1rem', width:'100vw', height: '80vh'}}>
<SideScrollableCourses courses={courses}></SideScrollableCourses>
<SideScrollableCourses courses={courses} projects={projects}></SideScrollableCourses>
<Dialog open={open} onClose={handleClose}>
<DialogTitle>{t('courseForm')}</DialogTitle>
<form style={{ margin: "2rem" }} onSubmit={handleSubmit}>
Expand Down
108 changes: 61 additions & 47 deletions frontend/src/components/Courses/CourseDetailTeacher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
Menu,
MenuItem,
Paper,
Tooltip,
Typography,
} from "@mui/material";
import { ChangeEvent, useCallback, useEffect, useState } from "react";
Expand All @@ -24,7 +25,6 @@ import {
getIdFromLink,
getNearestFutureDate,
getUser,
appHost,
ProjectDetail,
} from "./CourseUtils";
import {
Expand All @@ -39,6 +39,7 @@ import { timeDifference } from "../../utils/date-utils";
import { authenticatedFetch } from "../../utils/authenticated-fetch";
import i18next from "i18next";
import { Me } from "../../types/me";
import ContentCopyIcon from "@mui/icons-material/ContentCopy";

interface UserUid {
uid: string;
Expand Down Expand Up @@ -179,9 +180,17 @@ export function CourseDetailTeacher(): JSX.Element {
return (
<>
<Title title={course.name}></Title>
<Grid container direction={"row"} spacing={2} margin="1rem">
<Grid item xs={5}>
<Paper style={{ height: "90%", maxHeight: "90vh" }}>
<Grid
container
direction={"row"}
spacing={2}
margin="1rem"
style={{ height: "80vh" }}
>
<Grid item xs={5} height="100%">
<Paper
style={{ height: "100%", maxHeight: "100%", overflow: "auto" }}
>
<div style={{ padding: "1rem" }}>
<Typography variant="h5">{t("projects")}:</Typography>
<EmptyOrNotProjects projects={projects} />
Expand All @@ -191,19 +200,12 @@ export function CourseDetailTeacher(): JSX.Element {
<Button>{t("newProject")}</Button>
</Link>
</Grid>
<Grid item xs={6}>
<Grid
container
direction={"column"}
spacing={2}
style={{
height: "100%",
}}
>
<Grid item xs={5} height="100%">
<Grid container direction={"column"} spacing={2} height={"100%"}>
<Grid
item
style={{
height: "45.9%",
height: "50%",
}}
>
<Paper
Expand Down Expand Up @@ -239,7 +241,7 @@ export function CourseDetailTeacher(): JSX.Element {
<Grid
item
style={{
height: "45.9%",
height: "50%",
}}
>
<Paper
Expand All @@ -255,22 +257,6 @@ export function CourseDetailTeacher(): JSX.Element {
handleCheckboxChange={handleCheckboxChange}
/>
</Paper>

<IconButton
style={{ position: "absolute", bottom: 0, left: 0 }}
onClick={() =>
handleDeleteStudent(
navigate,
course.course_id,
selectedStudents
)
}
>
<ClearIcon />
<Typography variant="body1">{t("deleteSelected")}</Typography>
</IconButton>
</Grid>
<Grid item>
<Grid container>
<Grid item>
<Button onClick={handleClickCodes}>{t("joinCodes")}</Button>
Expand All @@ -291,6 +277,20 @@ export function CourseDetailTeacher(): JSX.Element {
</Button>
</Grid>
</Grid>

<IconButton
style={{ position: "absolute", bottom: 0, left: 0 }}
onClick={() =>
handleDeleteStudent(
navigate,
course.course_id,
selectedStudents
)
}
>
<ClearIcon />
<Typography variant="body1">{t("deleteSelected")}</Typography>
</IconButton>
</Grid>
</Grid>
</Grid>
Expand Down Expand Up @@ -486,7 +486,10 @@ function JoinCodeMenu({
};

const handleCopyToClipboard = (join_code: string) => {
navigator.clipboard.writeText(`${appHost}/join-course?code=${join_code}`);
const host = window.location.host;
navigator.clipboard.writeText(
`${host}/${i18next.language}/courses/join?code=${join_code}`
);
};

const getCodes = useCallback(() => {
Expand Down Expand Up @@ -560,6 +563,9 @@ function JoinCodeMenu({
vertical: "bottom",
horizontal: "center",
}}
style={{
width: "25vw",
}}
>
<MenuItem disabled>
<Typography variant="h6">{t("joinCodes")}</Typography>
Expand All @@ -568,25 +574,33 @@ function JoinCodeMenu({
elevation={0}
style={{
margin: "1rem",
width: "100%",
maxHeight: "20vh",
height: "20vh",
overflowY: "auto",
}}
>
{codes.map((code: JoinCode) => (
<MenuItem
onClick={() => handleCopyToClipboard(code.join_code)}
key={code.join_code}
>
<MenuItem style={{ width: "100%" }} key={code.join_code}>
<Grid container direction={"row"}>
<Grid marginRight={"1rem"} item>
<Typography variant="body1">
{code.expiry_time
? timeDifference(code.expiry_time)
: t("noExpiryDate")}
</Typography>
</Grid>
<Grid item>
<Typography variant="body1">
{code.for_admins ? t("forAdmins") : t("forStudents")}
</Typography>
<Grid item flexGrow={1}>
<Box display="flex" gap="1rem">
<Typography variant="body1">
{code.expiry_time
? timeDifference(code.expiry_time)
: t("noExpiryDate")}
</Typography>
<Typography variant="body1">
{code.for_admins ? t("forAdmins") : t("forStudents")}
</Typography>
<Tooltip title={t("copyToClipboard")}>
<IconButton
onClick={() => handleCopyToClipboard(code.join_code)}
>
<ContentCopyIcon />
</IconButton>
</Tooltip>
</Box>
</Grid>
<Grid item>
<IconButton onClick={() => handleDeleteCode(code.join_code)}>
Expand Down
Loading

0 comments on commit 13c9296

Please sign in to comment.