diff --git a/backend/fill_database_mock.py b/backend/fill_database_mock.py index dff9e70d..cd3df673 100644 --- a/backend/fill_database_mock.py +++ b/backend/fill_database_mock.py @@ -394,9 +394,11 @@ def fill_database_mock() -> None: admin1 = create_student(session, "Bart Coppens", "bart.coppens@ugent.be") admin2 = create_student(session, "Bart Mesuere", "bart.mesuere@ugent.be") admin3 = create_student(session, "Annick Van Daele", "annick.vandaele@ugent.be") + admin4 = create_student(session, "Charlotte Van Petegem", "charlotte.vanpetegem@ugent.be") modify_user_roles(session, admin1.id, [Role.STUDENT, Role.TEACHER, Role.ADMIN]) modify_user_roles(session, admin2.id, [Role.STUDENT, Role.TEACHER, Role.ADMIN]) modify_user_roles(session, admin3.id, [Role.STUDENT, Role.TEACHER, Role.ADMIN]) + modify_user_roles(session, admin4.id, [Role.STUDENT, Role.TEACHER, Role.ADMIN]) session.commit() session.close() diff --git a/docs/documentatie.md b/docs/documentatie.md index 1a7d506c..08c361d0 100644 --- a/docs/documentatie.md +++ b/docs/documentatie.md @@ -54,6 +54,11 @@ Zie [simple constraints](simple_constraints.md) voor meer uitleg hoe je basis be Hier kan je ook een docker file uploaden voor jouw geautomatiseerde testen. Lees de documentatie van hoe deze werken op de [officiele docker site](https://docs.docker.com/reference/dockerfile/). +Enkele extra dingen om rekening mee te houden. +- Je kan aan de indiening door de kijken in het bestand `/submission` in de docker container. +- status code van het commando geeft aan als het geslaagd is of niet +- alles dat geprint wordt naar stdout tijdens het uitvoeren van de docker file wordt getoond aan de studenten. + ## Cursussen pagina Hier krijg je een oplijsting van al jouw cursussen, ook van de reeds gearchiveerde. diff --git a/frontend/public/locales/en/translation.json b/frontend/public/locales/en/translation.json index 556dc40d..437c3401 100644 --- a/frontend/public/locales/en/translation.json +++ b/frontend/public/locales/en/translation.json @@ -91,7 +91,8 @@ }, "save_button": "Save", "error_title": "Oops, something went wrong!", - "error_text": "You don't have any courses yet, please create a course first in order to create a project" + "error_text": "You don't have any courses yet, please create a course first in order to create a project", + "enable_constraints": "Enable file constraints" }, "submission_files": { "root_switch": { @@ -282,4 +283,4 @@ "download": { "download_all": "Download all submissions" } -} \ No newline at end of file +} diff --git a/frontend/public/locales/nl/translation.json b/frontend/public/locales/nl/translation.json index 7e65eb88..d311ca38 100644 --- a/frontend/public/locales/nl/translation.json +++ b/frontend/public/locales/nl/translation.json @@ -91,7 +91,8 @@ }, "save_button": "Opslaan", "error_title": "Oeps, er is iets fout gegaan!", - "error_text": "Je hebt nog geen vakken, maak eerst een vak aan om een project te kunnen maken." + "error_text": "Je hebt nog geen vakken, maak eerst een vak aan om een project te kunnen maken.", + "enable_constraints": "Zet bestandsvoorwaarden aan" }, "submission_files": { "root_switch": { diff --git a/frontend/src/components/ManageCourse.tsx b/frontend/src/components/ManageCourse.tsx index 29151f5b..cabc6f02 100644 --- a/frontend/src/components/ManageCourse.tsx +++ b/frontend/src/components/ManageCourse.tsx @@ -8,7 +8,6 @@ import adminLoader from "../dataloaders/AdminLoader.ts"; async function get_teachers(current_teachers: { name: string, email: string, id: number }[]) { const data = await adminLoader(); // Replace this with your actual data fetching logic const users = data.users.filter((user) => user.user_roles.includes("TEACHER")); - console.log(users) return users.map((user) => ({ name: user.user_name, email: user.user_email, diff --git a/frontend/src/components/ProjectStudentComponent.tsx b/frontend/src/components/ProjectStudentComponent.tsx index f70cd66b..71dc68bb 100644 --- a/frontend/src/components/ProjectStudentComponent.tsx +++ b/frontend/src/components/ProjectStudentComponent.tsx @@ -38,7 +38,7 @@ function ProjectInfo(props: { project: ProjectStudent }): JSX.Element { " + t('project.description')} fieldBody={props.project.description} arrow={false}/> -
+ {props.project.requiredFiles != null &&
@@ -52,7 +52,7 @@ function ProjectInfo(props: { project: ProjectStudent }): JSX.Element { />
- + } ) } diff --git a/frontend/src/components/ProjectTeacherComponent.tsx b/frontend/src/components/ProjectTeacherComponent.tsx index b5dbbc5c..0c1330ac 100644 --- a/frontend/src/components/ProjectTeacherComponent.tsx +++ b/frontend/src/components/ProjectTeacherComponent.tsx @@ -169,15 +169,31 @@ export function ProjectTeacherComponent(props: { document.body.removeChild(a); } } - + function toggleRequirements(enabled: boolean) { + if (enabled) { + setRequiredFiles({ + type: "SUBMISSION", + root_constraint: { + type: "FILE", + file_name: "CHANGE_ME" + } + }); + } else { + setRequiredFiles(null); + } + } async function handleSaveClick() { + let requirements = ""; + if (requiredFiles != null) { + requirements = JSON.stringify(requiredFiles); + } const projectInput: ProjectInput = { name: projectName, deadline: deadline, visible: visible, archived: archived, description: description, - requirements: JSON.stringify(requiredFiles), + requirements: requirements, max_students: max_students == 0 ? 1 : max_students, dockerfile: dockerString } @@ -395,6 +411,19 @@ export function ProjectTeacherComponent(props: { {/* SUBMISSION FIELD */}
+
+ +
+
+ toggleRequirements(e)} + /> +
+
+ {requiredFiles != null &&
@@ -408,7 +437,7 @@ export function ProjectTeacherComponent(props: { />
- + } {/* VISIBLE FIELD*/}
diff --git a/frontend/src/dataloaders/ProjectsTeacherLoader.ts b/frontend/src/dataloaders/ProjectsTeacherLoader.ts index 74fb9d30..2d95518d 100644 --- a/frontend/src/dataloaders/ProjectsTeacherLoader.ts +++ b/frontend/src/dataloaders/ProjectsTeacherLoader.ts @@ -47,12 +47,12 @@ export async function LoadProjectsForTeacher(filter_on_current: boolean = false, const allGroups: (Group[]|undefined)[] = (await groupPromises) const groups: Group[][] = allGroups.filter(group => group !== undefined) as Group[][] + const groupsR = await Promise.all(groups.map(groupArray => Promise.all(groupArray.map(group => apiFetch(`/groups/${group.group_id}/submission`))))); const amount_of_submissions: number[] = [] - for (const groupArray of groups) { + for (const groupArray of groupsR) { let amount = 0 - for (const group of groupArray) { + for (const submissionData of groupArray) { try { - const submissionData = await apiFetch(`/groups/${group.group_id}/submission`); if (!submissionData.ok){ continue } diff --git a/frontend/src/pages/student/ProjectViewStudent.tsx b/frontend/src/pages/student/ProjectViewStudent.tsx index 8decb801..1de58d26 100644 --- a/frontend/src/pages/student/ProjectViewStudent.tsx +++ b/frontend/src/pages/student/ProjectViewStudent.tsx @@ -41,6 +41,12 @@ export default function ProjectViewStudent(): JSX.Element { lastSubmission: project_data.submission_student_id === member?.user_id } }); + let requiredFiles; + if (project_data.project_requirements == "") { + requiredFiles = null; + } else { + requiredFiles = JSON.parse(project_data.project_requirements) as object + } const project: ProjectStudent = { projectId: project_data.project_id, projectName: project_data.project_name, @@ -48,7 +54,7 @@ export default function ProjectViewStudent(): JSX.Element { deadline: deadline_to_string(project_data.project_deadline), status: project_status, description: project_data.project_description, - requiredFiles: JSON.parse(project_data.project_requirements) as object, + requiredFiles: requiredFiles, group_id: project_data.group_id, groups_info: project_data.groups_info, groupMembers: groupMembers, @@ -71,4 +77,4 @@ export default function ProjectViewStudent(): JSX.Element {
) -} \ No newline at end of file +} diff --git a/frontend/src/pages/teacher/ProjectViewTeacher.tsx b/frontend/src/pages/teacher/ProjectViewTeacher.tsx index 1bc5aa51..88a727cb 100644 --- a/frontend/src/pages/teacher/ProjectViewTeacher.tsx +++ b/frontend/src/pages/teacher/ProjectViewTeacher.tsx @@ -25,7 +25,12 @@ export default function ProjectViewTeacher() { if (!projectName){ setProjectName(project_data.project_name) } - + let requiredFiles; + if (project_data.project_requirements == "") { + requiredFiles = null; + } else { + requiredFiles = JSON.parse(project_data.project_requirements) as object + } const project: ProjectTeacher = { projectId: project_data.project_id, projectName: project_data.project_name, @@ -38,7 +43,7 @@ export default function ProjectViewTeacher() { archived: project_data.project_archived, description: project_data.project_description, maxGroupMembers: project_data.project_max_students, - requiredFiles: JSON.parse(project_data.project_requirements) as object, + requiredFiles: requiredFiles, otherFilesAllow: true, groupProject: project_data.project_max_students > 1, dockerFile: project_data.project_dockerfile, diff --git a/frontend/src/types/project.ts b/frontend/src/types/project.ts index da2a1c5f..09135eef 100644 --- a/frontend/src/types/project.ts +++ b/frontend/src/types/project.ts @@ -15,7 +15,7 @@ export type ProjectTeacher = { visible: boolean, archived: boolean, description: string, - requiredFiles: object, + requiredFiles: object | null, otherFilesAllow: boolean, groupProject: boolean, maxGroupMembers: number, @@ -36,7 +36,7 @@ export type ProjectStudent = { deadline: string, status: ProjectStatus, description: string, - requiredFiles: object, + requiredFiles: object | null, group_id: number, groups_info: GroupInfo[] | undefined, groupMembers: { diff --git a/frontend/src/utils/api/User.ts b/frontend/src/utils/api/User.ts index 0adbdf12..3e01e2a8 100644 --- a/frontend/src/utils/api/User.ts +++ b/frontend/src/utils/api/User.ts @@ -11,7 +11,6 @@ export function modify_language(language: string): void { } export function modify_roles(userId: number, roles: string[]): void { - console.log(JSON.stringify(roles)) void apiFetch(`/users/${userId}?roles=${JSON.stringify({roles})}`, { method: 'PUT', headers: {'Content-Type': 'application/json'},