Skip to content

Commit

Permalink
Revert "Merge branch 'develop' of github.com:SELab-2/UGent-1 into dev…
Browse files Browse the repository at this point in the history
…elop"

This reverts commit 4b12cfd, reversing
changes made to 7f49112.
  • Loading branch information
PJDeSmijter committed May 23, 2024
1 parent 4b12cfd commit 25c6157
Show file tree
Hide file tree
Showing 50 changed files with 263 additions and 404 deletions.
27 changes: 15 additions & 12 deletions backend/pigeonhole/apps/projects/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import zipfile
from os.path import basename, realpath

from django.db import transaction
Expand All @@ -15,7 +16,7 @@
from backend.pigeonhole.apps.groups.models import GroupSerializer
from backend.pigeonhole.apps.submissions.models import (
Submissions,
SubmissionsSerializer, submission_folder_path,
SubmissionsSerializer,
)
from backend.pigeonhole.apps.users.models import User
from backend.pigeonhole.filters import (
Expand All @@ -25,7 +26,6 @@
)
from .models import Project, ProjectSerializer
from .permissions import CanAccessProject
from ..submissions.views import ZipUtilities


class CsrfExemptSessionAuthentication(SessionAuthentication):
Expand Down Expand Up @@ -253,19 +253,22 @@ def download_submissions(self, request, *args, **kwargs):
if len(submissions) == 0:
return Response(status=status.HTTP_400_BAD_REQUEST)

path = 'backend/downloads/submissions.zip'
submission_folders = []
path = ""

for submission in submissions:
submission_folders.append(
submission_folder_path(
submission.group_id.group_id, submission.submission_id
if len(submissions) == 1:
path = submissions[0].file.path

else:
path = "backend/downloads/submissions.zip"
zipf = zipfile.ZipFile(file=path, mode="w", compression=zipfile.ZIP_STORED)

for submission in submissions:
zipf.write(
filename=submission.file.path,
arcname=basename(submission.file.path),
)
)

utilities = ZipUtilities()
filename = path
utilities.toZip(submission_folders, filename)
zipf.close()

path = realpath(path)
response = FileResponse(
Expand Down
40 changes: 27 additions & 13 deletions backend/pigeonhole/apps/submissions/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,26 +206,40 @@ def download_selection(self, request, *args, **kwargs):
if not ids:
return Response(status=status.HTTP_400_BAD_REQUEST)

path = 'backend/downloads/submissions.zip'
submission_folders = []
path = ""

for sid in ids:
submission = Submissions.objects.get(submission_id=sid)
if len(ids) == 1:
submission = Submissions.objects.get(submission_id=ids[0])
if submission is None:
return Response(
{"message": f"Submission with id {id} not found",
{"message": f"Submission with id {ids[0]} not found",
"errorcode": "ERROR_SUBMISSION_NOT_FOUND"},
status=status.HTTP_404_NOT_FOUND
status=status.HTTP_404_NOT_FOUND,
)
submission_folders.append(
submission_folder_path(
submission.group_id.group_id, submission.submission_id

path = submission.file.path

else:
path = 'backend/downloads/submissions.zip'
submission_folders = []

for sid in ids:
submission = Submissions.objects.get(submission_id=sid)
if submission is None:
return Response(
{"message": f"Submission with id {id} not found",
"errorcode": "ERROR_SUBMISSION_NOT_FOUND"},
status=status.HTTP_404_NOT_FOUND
)
submission_folders.append(
submission_folder_path(
submission.group_id.group_id, submission.submission_id
)
)
)

utilities = ZipUtilities()
filename = path
utilities.toZip(submission_folders, filename)
utilities = ZipUtilities()
filename = path
utilities.toZip(submission_folders, filename)

path = realpath(path)
response = FileResponse(
Expand Down
2 changes: 2 additions & 0 deletions frontend/__test__/AccountMenu.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ describe('AccountMenu', () => {
fireEvent.click(screen.getByRole('button'));
const menu = screen.getByRole('menu');
expect(menu).toBeVisible();
fireEvent.click(screen.getByRole('menuitem', {name: 'settings'}));
expect(menu).not.toBeVisible();
});


Expand Down
10 changes: 10 additions & 0 deletions frontend/__test__/course_components/CancelButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {render, screen} from "@testing-library/react";
import React from "react";
import CancelButton from "@app/[locale]/components/course_components/CancelButton";

describe("CancelButton", () => {
it("renders cancel button and click", async () => {
render(<CancelButton/>);
screen.getByText(/cancel/i).click();
});
});
22 changes: 14 additions & 8 deletions frontend/app/[locale]/components/AccountMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,13 @@ import {useEffect, useState} from "react";
const backend_url = process.env['NEXT_PUBLIC_BACKEND_URL'];

export default function AccountMenu() {
/*
* Account menu component, used to display the user's name and a dropdown menu with options to go to the profile page and logout(right side of the navbar)
* */
const [user, setUser] = useState<UserData | null>(null);
const [error, setError] = useState<APIError | null>(null);
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const { t } = useTranslation()

useEffect(() => {


const fetchCourses = async () => {
try{
setUser(await getUserData());
Expand All @@ -42,23 +39,26 @@ export default function AccountMenu() {
fetchCourses();
}, []);

//Utility & navigation functions


const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
//TODO: Handle settings and My profile actions!!
setAnchorEl(null);
};

const toProfile = () => {
window.location.href = '/profile'
};
}

const handleLogout = () => {
setAnchorEl(null);
window.location.href = backend_url + "/auth/logout";
};

return (
<React.Fragment>
<Box sx={{ display: 'flex', alignItems: 'center', textAlign: 'center' }}>
Expand Down Expand Up @@ -108,6 +108,12 @@ export default function AccountMenu() {
<Avatar /> {t('my_profile')}
</MenuItem>
<Divider />
<MenuItem onClick={handleClose}>
<ListItemIcon>
<Settings fontSize="small" />
</ListItemIcon>
{t('settings')}
</MenuItem>
<MenuItem onClick={handleLogout}>
<ListItemIcon>
<Logout fontSize="small" />
Expand Down
6 changes: 1 addition & 5 deletions frontend/app/[locale]/components/AddButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@ import { Button } from '@mui/material';
import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline';
import {useTranslation} from "react-i18next";

//TODO: route to add project page
function AddButton({translationkey, href} : {translationkey: string, href : string|undefined}){
/*
* General add button component
* @param translationkey: The key of the translation in the i18n file
* @param href: The href of the button
* */
const { t } = useTranslation()

return(
Expand Down
6 changes: 1 addition & 5 deletions frontend/app/[locale]/components/AddProjectButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ interface EditCourseButtonProps{
}

const AddProjectButton = ({course_id}: EditCourseButtonProps) => {
/*
* Specific add project button component
* @param course_id: The id of the course to which the project will be added
* */
const {t} = useTranslation();
const [user, setUser] = useState<UserData | null>(null);
const [loading, setLoading] = useState(true);
Expand Down Expand Up @@ -42,7 +38,7 @@ const AddProjectButton = ({course_id}: EditCourseButtonProps) => {
}}
/> :
<>
{user?.role !== 3 && ( // If the user is not a student
{user?.role !== 3 && (
<Button
variant="contained"
color="secondary"
Expand Down
6 changes: 1 addition & 5 deletions frontend/app/[locale]/components/BackButton.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client'
import React from 'react';
import {Button} from "@mui/material";
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
Expand All @@ -9,11 +10,6 @@ interface BackButtonProps {

// back button has to take the destination as a prop and navigate to it
export default function BackButton({destination, text}: BackButtonProps) {
/*
* general back button component
* @param destination: The destination of the button
* @param text: The text of the button
* */

return (
<Button
Expand Down
4 changes: 1 addition & 3 deletions frontend/app/[locale]/components/CASButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ const backend_url = process.env['NEXT_PUBLIC_BACKEND_URL'];
const redirect_url = process.env['NEXT_PUBLIC_REDIRECT_URL'];

const CASButton = () => {
/*
* Button to login with CAS
* */
const handleCASLogin = (): void => {
// Implement CAS login logic here
console.log('Login with CAS');
window.location.href = backend_url + "/microsoft/to-auth-redirect?next=" + redirect_url + "/home"
};
Expand Down
4 changes: 0 additions & 4 deletions frontend/app/[locale]/components/CopyToClipboardButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ interface CopyToClipboardButtonProps {
}

const CopyToClipboardButton = ({text}: CopyToClipboardButtonProps) => {
/*
* General Button that copies text to clipboard.
* @param text: text that has to be copied to clipboard.
* */
const [open, setOpen] = useState(false);
const {t} = useTranslation();

Expand Down
8 changes: 2 additions & 6 deletions frontend/app/[locale]/components/CourseBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ interface CourseBannerProps {
}

const CourseBanner = ({course_id}: CourseBannerProps) => {
/*
* Banner component displayed in the course details page
* @param course_id: id of the course.
* */
const [user, setUser] = useState<UserData | null>(null);
const [course, setCourse] = useState<Course | null>(null);
const [error, setError] = useState<APIError | null>(null);
Expand Down Expand Up @@ -81,10 +77,10 @@ const CourseBanner = ({course_id}: CourseBannerProps) => {
textOverflow: 'ellipsis',
}}
>
{course?.name + (course?.year === null ? "" : " " + course?.year) /*Display the course name + the year of the course*/}
{course?.name + (course?.year === null ? "" : " " + course?.year)}
</Typography>
</Box>
{user?.role !== 3 ? ( //Do not display edit button if the user is a student.
{user?.role !== 3 ? (
<Box
display="flex"
justifyContent={{ xs: 'center', sm: 'flex-start' }}
Expand Down
6 changes: 1 addition & 5 deletions frontend/app/[locale]/components/CourseCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ import AccesAlarm from '@mui/icons-material/AccessAlarm';
import Person from '@mui/icons-material/Person';

const CourseCard = ({params: {course}}: { params: { course: Course } }) => {
/*
* Card component displayed in the home page that represent a course
* @param course: Course object of the course that is to be displayed in the card
* */
const [projects, setProjects] = useState<Project[]>([]);
const [last_submission, setSubmission] =
useState<Submission>({
Expand Down Expand Up @@ -48,7 +44,7 @@ const CourseCard = ({params: {course}}: { params: { course: Course } }) => {
};

fetchProjects();
}, [course.course_id, last_submission, projects]);
}, [course.course_id]);



Expand Down
11 changes: 4 additions & 7 deletions frontend/app/[locale]/components/CourseControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ import {useTranslation} from "react-i18next";
import {APIError, fetchUserData, UserData} from "@lib/api";

const CourseControls = ({selectedYear, onYearChange}) => {
/*
* Component containing the text and buttons displayed at the top of the home page
* @param selectedYear: currently selected year
* @param onYearChange: function that shows course cards of the selected year
* */
const currentYear = new Date().getFullYear();
const academicYear = `${currentYear - 1}-${currentYear.toString().slice(-2)}`;

Expand All @@ -38,7 +33,9 @@ const CourseControls = ({selectedYear, onYearChange}) => {
setLoading(false);
}, []);

// displayed academic year



const years = [
`${currentYear - 2}-${(currentYear - 1).toString().slice(-2)}`,
academicYear,
Expand Down Expand Up @@ -108,7 +105,7 @@ const CourseControls = ({selectedYear, onYearChange}) => {
height={'fit-content'}
gap={2}
>
{user?.role !== 3 ? ( // Students may not see the add course button.
{user?.role !== 3 ? (
<Button
variant="contained"
color="secondary"
Expand Down
4 changes: 0 additions & 4 deletions frontend/app/[locale]/components/CourseDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ interface CourseDetailsProps {
}

export default function CourseDetails({course_id}: CourseDetailsProps) {
/*
* Component used in course details page that shows the information of the course(not the title, this is displayed in the courseBanner).
* @param course_id: id of the course
* */
const [user, setUser] = useState<UserData | null>(null);
const [course, setCourse] = useState<Course | null>(null);
const [error, setError] = useState<APIError | null>(null);
Expand Down
11 changes: 4 additions & 7 deletions frontend/app/[locale]/components/CoursesGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@ import React, {useEffect, useState} from 'react';
import {APIError, Course, getCoursesForUser} from '@lib/api';
import { Grid, Skeleton } from '@mui/material';
import CourseCard from '@app/[locale]/components/CourseCard';
import {useTranslation} from "react-i18next";

const CoursesGrid = ({selectedYear}) => {
/*
* Grid component that displays the course cards on the home page
* @param selectedYear: currently selected year
* */
const [courses, setCourses] = useState<Course[]>([]);
const [filteredCourses, setFilteredCourses] = useState<Course[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<APIError | null>(null);

const {t} = useTranslation()

const loadingArray = [1, 2, 3, 4, 5, 6];

useEffect(() => {
Expand All @@ -22,15 +21,13 @@ const CoursesGrid = ({selectedYear}) => {
setCourses(await getCoursesForUser());
} catch (error) {
if (error instanceof APIError) setError(error);
} finally {
setLoading(false);
}
};

fetchCourses();
setLoading(false);
}, []);

// filter courses by selected year
useEffect(() => {
const [startYear, endYearSuffix] = selectedYear.split('-');
const startYearNumber = parseInt(startYear, 10);
Expand Down
Loading

0 comments on commit 25c6157

Please sign in to comment.