From 3692ebac0fe5ee9f2092e99f350923a6d7191e20 Mon Sep 17 00:00:00 2001 From: bsilkyn Date: Fri, 3 May 2024 20:40:10 +0200 Subject: [PATCH 01/13] chore: first try at adding download button of scores in csv form #400 --- .../src/components/projects/DownloadCSV.vue | 65 +++++++++++++++++++ .../projects/roles/TeacherProjectView.vue | 6 ++ 2 files changed, 71 insertions(+) create mode 100644 frontend/src/components/projects/DownloadCSV.vue diff --git a/frontend/src/components/projects/DownloadCSV.vue b/frontend/src/components/projects/DownloadCSV.vue new file mode 100644 index 00000000..ec14b2d2 --- /dev/null +++ b/frontend/src/components/projects/DownloadCSV.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/frontend/src/views/projects/roles/TeacherProjectView.vue b/frontend/src/views/projects/roles/TeacherProjectView.vue index b83406b8..7d5c5e01 100644 --- a/frontend/src/views/projects/roles/TeacherProjectView.vue +++ b/frontend/src/views/projects/roles/TeacherProjectView.vue @@ -5,6 +5,7 @@ import { type Teacher } from '@/types/users/Teacher.ts'; import { type Project } from '@/types/Project.ts'; import ProjectInfo from '@/components/projects/ProjectInfo.vue'; import ProjectMeter from '@/components/projects/ProjectMeter.vue'; +import DownloadCSV from '@/components/projects/DownloadCSV.vue'; /* Props */ defineProps<{ @@ -36,6 +37,11 @@ defineProps<{
+
+ +
From 74559e482bfe25667aa3674d80c536c583a3c64a Mon Sep 17 00:00:00 2001 From: bsilkyn Date: Fri, 3 May 2024 23:17:09 +0200 Subject: [PATCH 02/13] chore: logs for debugging #400 --- frontend/src/components/projects/DownloadCSV.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/components/projects/DownloadCSV.vue b/frontend/src/components/projects/DownloadCSV.vue index ec14b2d2..07e5cea2 100644 --- a/frontend/src/components/projects/DownloadCSV.vue +++ b/frontend/src/components/projects/DownloadCSV.vue @@ -30,7 +30,9 @@ const generateCSVAndDownload = async () => { // construct for every group's student a csv line according to ufora grade csv standard // and concatenate them all into one csv csv_content.value = groups.value?.map(group => { + console.log(group); return group.students?.map(student => { + console.log(student); return `#${student.studentId},${student.last_name},${student.first_name},${student.email},${group.score},#` }).join('\n'); }).join('\n'); From 06344041a9638abdcb77dfff21cb1b88b9e498aa Mon Sep 17 00:00:00 2001 From: bsilkyn Date: Sat, 4 May 2024 15:10:54 +0200 Subject: [PATCH 03/13] chore: csv download button implemented #400 --- .../src/components/projects/DownloadCSV.vue | 61 ++++++++++--------- .../projects/roles/TeacherProjectView.vue | 2 +- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/frontend/src/components/projects/DownloadCSV.vue b/frontend/src/components/projects/DownloadCSV.vue index 07e5cea2..2220f160 100644 --- a/frontend/src/components/projects/DownloadCSV.vue +++ b/frontend/src/components/projects/DownloadCSV.vue @@ -1,22 +1,19 @@ diff --git a/frontend/src/views/projects/roles/TeacherProjectView.vue b/frontend/src/views/projects/roles/TeacherProjectView.vue index 7d5c5e01..513c1839 100644 --- a/frontend/src/views/projects/roles/TeacherProjectView.vue +++ b/frontend/src/views/projects/roles/TeacherProjectView.vue @@ -39,7 +39,7 @@ defineProps<{
From b4c8b09c13f603b34a5960d4a4b49e43ada2ae2b Mon Sep 17 00:00:00 2001 From: bsilkyn Date: Sat, 4 May 2024 15:16:11 +0200 Subject: [PATCH 04/13] chore: add translations #400 --- frontend/src/assets/lang/app/en.json | 3 ++- frontend/src/assets/lang/app/nl.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/src/assets/lang/app/en.json b/frontend/src/assets/lang/app/en.json index d2f951a7..6478779f 100644 --- a/frontend/src/assets/lang/app/en.json +++ b/frontend/src/assets/lang/app/en.json @@ -167,7 +167,8 @@ "searchCourse": "Search a course", "createCourse": "Create a new course", "public": "Public", - "protected": "Protected" + "protected": "Protected", + "csv": "Download grades as a .csv file" }, "card": { "open": "Details", diff --git a/frontend/src/assets/lang/app/nl.json b/frontend/src/assets/lang/app/nl.json index 92456aa0..2cca7874 100644 --- a/frontend/src/assets/lang/app/nl.json +++ b/frontend/src/assets/lang/app/nl.json @@ -164,7 +164,8 @@ "searchCourse": "Zoek een vak", "createCourse": "Maak een vak", "public": "Publiek", - "protected": "Besloten" + "protected": "Besloten", + "csv": "Download punten als een .csv bestand" }, "card": { "open": "Details", From 7806b2fcc0ce63fc3177ab08f70bf42ba3b9d12b Mon Sep 17 00:00:00 2001 From: bsilkyn Date: Sun, 5 May 2024 21:45:13 +0200 Subject: [PATCH 05/13] chore: add proper extension to grades csv file #400 --- frontend/src/components/projects/DownloadCSV.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/projects/DownloadCSV.vue b/frontend/src/components/projects/DownloadCSV.vue index 2220f160..508ac7a5 100644 --- a/frontend/src/components/projects/DownloadCSV.vue +++ b/frontend/src/components/projects/DownloadCSV.vue @@ -51,7 +51,7 @@ const generateCSVAndDownload = async (): Promise => { // create an anchor element for downloading the file const a = document.createElement('a'); a.href = url; - a.download = (props.projectName ?? props.projectId) + '.scores'; + a.download = props.projectName + '.csv'; // click anchor element a.click(); From fd4d88208f7c8953be5f0d76aa9833f5c9a0c86e Mon Sep 17 00:00:00 2001 From: bsilkyn Date: Tue, 7 May 2024 17:10:35 +0200 Subject: [PATCH 06/13] chore: add csv header + fix user type + convert score to score with max_score 10 #400 --- frontend/cypress.config.js | 2 +- frontend/src/components/projects/DownloadCSV.vue | 15 +++++++++------ frontend/src/types/users/Student.ts | 4 ++-- .../views/projects/roles/TeacherProjectView.vue | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/frontend/cypress.config.js b/frontend/cypress.config.js index 6b759d73..5975fc9d 100644 --- a/frontend/cypress.config.js +++ b/frontend/cypress.config.js @@ -2,7 +2,7 @@ import { defineConfig } from 'cypress'; export default defineConfig({ e2e: { - baseUrl: 'http://nginx', + baseUrl: 'https://localhost', specPattern: 'src/test/e2e/**/*.cy.{js,jsx,ts,tsx}', }, }); diff --git a/frontend/src/components/projects/DownloadCSV.vue b/frontend/src/components/projects/DownloadCSV.vue index 508ac7a5..f668d757 100644 --- a/frontend/src/components/projects/DownloadCSV.vue +++ b/frontend/src/components/projects/DownloadCSV.vue @@ -3,11 +3,11 @@ import Button from 'primevue/button'; import { useI18n } from 'vue-i18n'; import { useGroup } from '@/composables/services/group.service.ts'; import { useStudents } from '@/composables/services/student.service.ts'; +import { type Project } from '@/types/Project.ts'; /* Props */ const props = defineProps<{ - projectId: string; - projectName: string; + project: Project; }>(); /* Injections */ @@ -15,6 +15,9 @@ const { t } = useI18n(); const { groups, getGroupsByProject } = useGroup(); const { students, getStudentsByGroup } = useStudents(); +/* Constants */ +const header = 'OrgDefinedId,Last Name,First Name,Email,Grade,End-of-Line Indicator\n'; + /* Functions */ /** * generateCSVAndDownload generates a csv combining all the scores for all students in all groups associated @@ -23,7 +26,7 @@ const { students, getStudentsByGroup } = useStudents(); */ const generateCSVAndDownload = async (): Promise => { // retrieve all the groups associated with a given project - await getGroupsByProject(props.projectId); + await getGroupsByProject(props.project.id); // construct for every group's student a csv line according to ufora grade csv standard // and concatenate them all into one csv const csvPromises = @@ -33,14 +36,14 @@ const generateCSVAndDownload = async (): Promise => { students.value ?.map((student) => { // single csv line - return `#${student.id},${student.last_name},${student.first_name},${student.email},${group.score},#`; + return `#${student.student_id},${student.last_name},${student.first_name},${student.email},${group.score * 10 / props.project.max_score},#`; }) .join('\n') ?? '' ); }) ?? []; const csvList = await Promise.all(csvPromises); - const csvContent = csvList.join('\n'); + const csvContent = header + csvList.join('\n'); // create a blob from the csv content const blob = new Blob([csvContent], { type: 'text/plain' }); @@ -51,7 +54,7 @@ const generateCSVAndDownload = async (): Promise => { // create an anchor element for downloading the file const a = document.createElement('a'); a.href = url; - a.download = props.projectName + '.csv'; + a.download = props.project.name + '.csv'; // click anchor element a.click(); diff --git a/frontend/src/types/users/Student.ts b/frontend/src/types/users/Student.ts index 8ba17f8c..34285a98 100644 --- a/frontend/src/types/users/Student.ts +++ b/frontend/src/types/users/Student.ts @@ -14,7 +14,7 @@ export class Student extends User { public last_enrolled: number, public create_time: Date, public last_login: Date | null, - public studentId: string, + public student_id: string, public roles: Role[] = [], public courses: Course[] = [], public groups: Group[] = [], @@ -51,7 +51,7 @@ export class Student extends User { student.last_enrolled, new Date(student.create_time), student.last_login !== null ? new Date(student.last_login) : null, - student.studentId, + student.student_id, ); } diff --git a/frontend/src/views/projects/roles/TeacherProjectView.vue b/frontend/src/views/projects/roles/TeacherProjectView.vue index 513c1839..10385344 100644 --- a/frontend/src/views/projects/roles/TeacherProjectView.vue +++ b/frontend/src/views/projects/roles/TeacherProjectView.vue @@ -39,7 +39,7 @@ defineProps<{
From 2857be5c391c7c360164e6202d02c5b134ae0d51 Mon Sep 17 00:00:00 2001 From: bsilkyn Date: Tue, 7 May 2024 17:17:09 +0200 Subject: [PATCH 07/13] chore: lint fix #400 --- frontend/src/components/projects/DownloadCSV.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/projects/DownloadCSV.vue b/frontend/src/components/projects/DownloadCSV.vue index f668d757..4f6915c3 100644 --- a/frontend/src/components/projects/DownloadCSV.vue +++ b/frontend/src/components/projects/DownloadCSV.vue @@ -36,7 +36,7 @@ const generateCSVAndDownload = async (): Promise => { students.value ?.map((student) => { // single csv line - return `#${student.student_id},${student.last_name},${student.first_name},${student.email},${group.score * 10 / props.project.max_score},#`; + return `#${student.student_id},${student.last_name},${student.first_name},${student.email},${(group.score * 10) / props.project.max_score},#`; }) .join('\n') ?? '' ); From ffec7198b7dd011f0a88c229251e827b788408a5 Mon Sep 17 00:00:00 2001 From: bsilkyn Date: Tue, 7 May 2024 17:23:11 +0200 Subject: [PATCH 08/13] test: test update #400 --- .../unit/services/student_service.test.ts | 20 +++++++++---------- frontend/src/test/unit/types/data.ts | 2 +- frontend/src/test/unit/types/student.test.ts | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/frontend/src/test/unit/services/student_service.test.ts b/frontend/src/test/unit/services/student_service.test.ts index d8c18467..5b9fc047 100644 --- a/frontend/src/test/unit/services/student_service.test.ts +++ b/frontend/src/test/unit/services/student_service.test.ts @@ -38,7 +38,7 @@ describe('students', (): void => { expect(student.value?.first_name).toBe('John'); expect(student.value?.last_name).toBe('Doe'); expect(student.value?.last_enrolled).toBe(2023); - expect(student.value?.studentId).toBeNull(); + expect(student.value?.student_id).toBeNull(); expect(student.value?.last_login).toBeNull(); expect(student.value?.create_time.toISOString()).toEqual('2024-07-20T23:15:00.000Z'); expect(student.value?.courses).toEqual([]); @@ -60,7 +60,7 @@ describe('students', (): void => { expect(students.value?.[0]?.first_name).toBe('John'); expect(students.value?.[0]?.last_name).toBe('Doe'); expect(students.value?.[0]?.last_enrolled).toBe(2023); - expect(students.value?.[0]?.studentId).toBeNull(); + expect(students.value?.[0]?.student_id).toBeNull(); expect(students.value?.[0]?.last_login).toBeNull(); expect(students.value?.[0]?.create_time).toEqual(new Date('July 21, 2024 01:15:00')); expect(students.value?.[0]?.courses).toEqual([]); @@ -73,7 +73,7 @@ describe('students', (): void => { expect(students.value?.[1]?.first_name).toBe('Bartje'); expect(students.value?.[1]?.last_name).toBe('Verhaege'); expect(students.value?.[1]?.last_enrolled).toBe(2023); - expect(students.value?.[1]?.studentId).toBeNull(); + expect(students.value?.[1]?.student_id).toBeNull(); expect(students.value?.[1]?.last_login).toBeNull(); expect(students.value?.[1]?.create_time).toEqual(new Date('July 21, 2024 01:15:00')); expect(students.value?.[1]?.courses).toEqual([]); @@ -86,7 +86,7 @@ describe('students', (): void => { expect(students.value?.[2]?.first_name).toBe('Tybo'); expect(students.value?.[2]?.last_name).toBe('Verslype'); expect(students.value?.[2]?.last_enrolled).toBe(2023); - expect(students.value?.[2]?.studentId).toBe('02012470'); + expect(students.value?.[2]?.student_id).toBe('02012470'); expect(students.value?.[2]?.last_login).toEqual(new Date('July 30, 2024 01:15:00')); expect(students.value?.[2]?.create_time).toEqual(new Date('July 21, 2024 01:15:00')); expect(students.value?.[2]?.courses).toEqual([]); @@ -99,7 +99,7 @@ describe('students', (): void => { expect(students.value?.[3]?.first_name).toBe('somtin'); expect(students.value?.[3]?.last_name).toBe('somtin'); expect(students.value?.[3]?.last_enrolled).toBe(2023); - expect(students.value?.[3]?.studentId).toBeNull(); + expect(students.value?.[3]?.student_id).toBeNull(); expect(students.value?.[3]?.last_login).toBeNull(); expect(students.value?.[3]?.create_time).toEqual(new Date('July 21, 2024 01:15:00')); expect(students.value?.[3]?.courses).toEqual([]); @@ -121,7 +121,7 @@ describe('students', (): void => { expect(students.value?.[0]?.first_name).toBe('John'); expect(students.value?.[0]?.last_name).toBe('Doe'); expect(students.value?.[0]?.last_enrolled).toBe(2023); - expect(students.value?.[0]?.studentId).toBeNull(); + expect(students.value?.[0]?.student_id).toBeNull(); expect(students.value?.[0]?.last_login).toBeNull(); expect(students.value?.[0]?.create_time).toEqual(new Date('July 21, 2024 01:15:00')); expect(students.value?.[0]?.courses).toEqual([]); @@ -134,7 +134,7 @@ describe('students', (): void => { expect(students.value?.[1]?.first_name).toBe('Bartje'); expect(students.value?.[1]?.last_name).toBe('Verhaege'); expect(students.value?.[1]?.last_enrolled).toBe(2023); - expect(students.value?.[1]?.studentId).toBeNull(); + expect(students.value?.[1]?.student_id).toBeNull(); expect(students.value?.[1]?.last_login).toBeNull(); expect(students.value?.[1]?.create_time).toEqual(new Date('July 21, 2024 01:15:00')); expect(students.value?.[1]?.courses).toEqual([]); @@ -147,7 +147,7 @@ describe('students', (): void => { expect(students.value?.[2]?.first_name).toBe('Tybo'); expect(students.value?.[2]?.last_name).toBe('Verslype'); expect(students.value?.[2]?.last_enrolled).toBe(2023); - expect(students.value?.[2]?.studentId).toBe('02012470'); + expect(students.value?.[2]?.student_id).toBe('02012470'); expect(students.value?.[2]?.last_login).toEqual(new Date('July 30, 2024 01:15:00')); expect(students.value?.[2]?.create_time).toEqual(new Date('July 21, 2024 01:15:00')); expect(students.value?.[2]?.courses).toEqual([]); @@ -160,7 +160,7 @@ describe('students', (): void => { expect(students.value?.[3]?.first_name).toBe('somtin'); expect(students.value?.[3]?.last_name).toBe('somtin'); expect(students.value?.[3]?.last_enrolled).toBe(2023); - expect(students.value?.[3]?.studentId).toBeNull(); + expect(students.value?.[3]?.student_id).toBeNull(); expect(students.value?.[3]?.last_login).toBeNull(); expect(students.value?.[3]?.create_time).toEqual(new Date('July 21, 2024 01:15:00')); expect(students.value?.[3]?.courses).toEqual([]); @@ -202,6 +202,6 @@ describe('students', (): void => { // Only check for fields that are sent to the backend expect(students.value?.[prevLength]?.id).toBe('id'); - expect(students.value?.[prevLength]?.studentId).toBe('studentId'); + expect(students.value?.[prevLength]?.student_id).toBe('studentId'); }); }); diff --git a/frontend/src/test/unit/types/data.ts b/frontend/src/test/unit/types/data.ts index 307e73bf..9c004c27 100644 --- a/frontend/src/test/unit/types/data.ts +++ b/frontend/src/test/unit/types/data.ts @@ -26,7 +26,7 @@ export const studentData = { courses: [], create_time: new Date(), last_login: null, - studentId: '1', + student_id: '1', groups: [], }; diff --git a/frontend/src/test/unit/types/student.test.ts b/frontend/src/test/unit/types/student.test.ts index 07f7856c..a1a1978e 100644 --- a/frontend/src/test/unit/types/student.test.ts +++ b/frontend/src/test/unit/types/student.test.ts @@ -18,7 +18,7 @@ describe('student type', () => { expect(student.last_enrolled).toBe(studentData.last_enrolled); expect(student.create_time).toStrictEqual(studentData.create_time); expect(student.last_login).toStrictEqual(studentData.last_login); - expect(student.studentId).toBe(studentData.studentId); + expect(student.student_id).toBe(studentData.student_id); expect(student.roles).toStrictEqual(studentData.roles); expect(student.courses).toStrictEqual(studentData.courses); expect(student.groups).toStrictEqual(studentData.groups); @@ -39,7 +39,7 @@ describe('student type', () => { expect(student.last_enrolled).toBe(studentData.last_enrolled); expect(student.create_time).toStrictEqual(studentData.create_time); expect(student.last_login).toStrictEqual(studentData.last_login); - expect(student.studentId).toBe(studentData.studentId); + expect(student.student_id).toBe(studentData.student_id); expect(student.roles).toStrictEqual(studentData.roles); expect(student.courses).toStrictEqual(studentData.courses); expect(student.groups).toStrictEqual(studentData.groups); From 872afe8f9878287e6289080844a3ed707feb148f Mon Sep 17 00:00:00 2001 From: bsilkyn Date: Tue, 7 May 2024 18:27:23 +0200 Subject: [PATCH 09/13] test: test update #400 --- frontend/cypress.config.js | 2 +- frontend/src/composables/services/student.service.ts | 2 +- frontend/src/test/unit/services/setup/data.ts | 8 ++++---- frontend/src/test/unit/services/setup/post_handlers.ts | 2 +- frontend/src/test/unit/services/student_service.test.ts | 4 ++-- frontend/src/test/unit/types/helper.ts | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/frontend/cypress.config.js b/frontend/cypress.config.js index 5975fc9d..6b759d73 100644 --- a/frontend/cypress.config.js +++ b/frontend/cypress.config.js @@ -2,7 +2,7 @@ import { defineConfig } from 'cypress'; export default defineConfig({ e2e: { - baseUrl: 'https://localhost', + baseUrl: 'http://nginx', specPattern: 'src/test/e2e/**/*.cy.{js,jsx,ts,tsx}', }, }); diff --git a/frontend/src/composables/services/student.service.ts b/frontend/src/composables/services/student.service.ts index 8c1e62b2..c70c67bd 100644 --- a/frontend/src/composables/services/student.service.ts +++ b/frontend/src/composables/services/student.service.ts @@ -73,7 +73,7 @@ export function useStudents(): StudentsState { endpoint, { user: studentData.id, - student_id: studentData.studentId, + student_id: studentData.student_id, }, student, Student.fromJSON, diff --git a/frontend/src/test/unit/services/setup/data.ts b/frontend/src/test/unit/services/setup/data.ts index 1ad12327..f25084c9 100644 --- a/frontend/src/test/unit/services/setup/data.ts +++ b/frontend/src/test/unit/services/setup/data.ts @@ -158,7 +158,7 @@ export const students = [ last_name: 'Doe', last_enrolled: 2023, create_time: new Date('July 21, 2024 01:15:00'), - studentId: null, + student_id: null, roles: ['student'], courses: ['1', '2', '3'], groups: ['0'], @@ -174,7 +174,7 @@ export const students = [ last_name: 'Verhaege', last_enrolled: 2023, create_time: new Date('July 21, 2024 01:15:00'), - studentId: null, + student_id: null, roles: ['student'], courses: [], groups: [], @@ -190,7 +190,7 @@ export const students = [ last_name: 'Verslype', last_enrolled: 2023, create_time: new Date('July 21, 2024 01:15:00'), - studentId: '02012470', + student_id: '02012470', roles: ['student'], courses: [], groups: [], @@ -206,7 +206,7 @@ export const students = [ last_name: 'somtin', last_enrolled: 2023, create_time: new Date('July 21, 2024 01:15:00'), - studentId: null, + student_id: null, roles: ['student'], courses: [], groups: [], diff --git a/frontend/src/test/unit/services/setup/post_handlers.ts b/frontend/src/test/unit/services/setup/post_handlers.ts index 6ae01af8..5409c5df 100644 --- a/frontend/src/test/unit/services/setup/post_handlers.ts +++ b/frontend/src/test/unit/services/setup/post_handlers.ts @@ -37,7 +37,7 @@ export const postHandlers = [ const buffer = await request.arrayBuffer(); const requestBody = new TextDecoder().decode(buffer); const newStudent = JSON.parse(requestBody); - students.push({ id: newStudent.user, studentId: newStudent.student_id, ...newStudent }); + students.push({ id: newStudent.user, student_id: newStudent.student_id, ...newStudent }); return HttpResponse.json(students); }), http.post(baseUrl + endpoints.courses.index, async ({ request }) => { diff --git a/frontend/src/test/unit/services/student_service.test.ts b/frontend/src/test/unit/services/student_service.test.ts index 5b9fc047..6b8ddc12 100644 --- a/frontend/src/test/unit/services/student_service.test.ts +++ b/frontend/src/test/unit/services/student_service.test.ts @@ -181,7 +181,7 @@ describe('students', (): void => { 2024, // last_enrolled new Date(), // create_time null, // last_login - 'studentId', // studentId + 'student_id', // student_id [], [], [], @@ -202,6 +202,6 @@ describe('students', (): void => { // Only check for fields that are sent to the backend expect(students.value?.[prevLength]?.id).toBe('id'); - expect(students.value?.[prevLength]?.student_id).toBe('studentId'); + expect(students.value?.[prevLength]?.student_id).toBe('student_id'); }); }); diff --git a/frontend/src/test/unit/types/helper.ts b/frontend/src/test/unit/types/helper.ts index 97604c47..60c32d6b 100644 --- a/frontend/src/test/unit/types/helper.ts +++ b/frontend/src/test/unit/types/helper.ts @@ -25,7 +25,7 @@ export function createStudent(studentData: any): Student { studentData.last_enrolled, studentData.create_time, studentData.last_login, - studentData.studentId, + studentData.student_id, studentData.roles.slice(), studentData.courses.slice(), studentData.groups.slice(), From 50a48a4a7f645bf76a1ce84123655d594b0350df Mon Sep 17 00:00:00 2001 From: bsilkyn Date: Fri, 10 May 2024 18:01:24 +0200 Subject: [PATCH 10/13] chore: show scores when student but not part of course related to project #400 --- backend/api/serializers/group_serializer.py | 22 +++++++++++++++------ frontend/src/views/admin/UsersView.vue | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/backend/api/serializers/group_serializer.py b/backend/api/serializers/group_serializer.py index 3496bcbc..08954943 100644 --- a/backend/api/serializers/group_serializer.py +++ b/backend/api/serializers/group_serializer.py @@ -1,6 +1,8 @@ from api.models.group import Group from api.models.student import Student -from api.permissions.role_permissions import is_student +from api.models.assistant import Assistant +from api.models.teacher import Teacher +from api.permissions.role_permissions import is_student, is_assistant, is_teacher from api.serializers.project_serializer import ProjectSerializer from api.serializers.student_serializer import StudentIDSerializer from django.utils.translation import gettext @@ -30,12 +32,20 @@ class Meta: def to_representation(self, instance): data = super().to_representation(instance) - # If you are not a student, you can always see the score - if is_student(self.context["request"].user): - # Student can not see the score if they are not part of the group, or it is not visible yet - if not instance.students.filter(id=self.context["request"].user.student.id).exists() or\ - not instance.project.score_visible: + user = self.context["request"].user + course_id = instance.project.course.id + # If you are not a student, you can always see the score + # Same with being a student, but not being part of the course affiliated with this group + if is_student(user) and \ + not ((is_assistant(user) or is_teacher(user)) and + not user.student.courses.filter(id=instance.project.course.id).exists()): + student_in_course = user.student.courses.filter(id=instance.project.course.id).exists() + print(student_in_course, flush=True) + # Student can not see the score if they are not part of the course associated with group, + # or it is not visible yet + if not student_in_course or \ + not instance.project.score_visible and student_in_course: data.pop("score") return data diff --git a/frontend/src/views/admin/UsersView.vue b/frontend/src/views/admin/UsersView.vue index 42c329ac..c073e34b 100644 --- a/frontend/src/views/admin/UsersView.vue +++ b/frontend/src/views/admin/UsersView.vue @@ -104,7 +104,7 @@ const saveItem = async (): Promise => { if (role === 'student') { const data: Record = { ...editItem.value, - studentId: editItem.value.id, + student_id: editItem.value.id, }; await func(data); } else { From 0714779aa658a38269db98c0408a757a831420ce Mon Sep 17 00:00:00 2001 From: bsilkyn Date: Fri, 10 May 2024 18:33:52 +0200 Subject: [PATCH 11/13] chore: linting fix #400 --- backend/api/serializers/group_serializer.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/api/serializers/group_serializer.py b/backend/api/serializers/group_serializer.py index 08954943..38af2554 100644 --- a/backend/api/serializers/group_serializer.py +++ b/backend/api/serializers/group_serializer.py @@ -39,9 +39,8 @@ def to_representation(self, instance): # Same with being a student, but not being part of the course affiliated with this group if is_student(user) and \ not ((is_assistant(user) or is_teacher(user)) and - not user.student.courses.filter(id=instance.project.course.id).exists()): - student_in_course = user.student.courses.filter(id=instance.project.course.id).exists() - print(student_in_course, flush=True) + not user.student.courses.filter(id=course_id).exists()): + student_in_course = user.student.courses.filter(id=course_id).exists() # Student can not see the score if they are not part of the course associated with group, # or it is not visible yet if not student_in_course or \ From 1a6bc8ca4aab47790210c0f66612eaeb2287b8aa Mon Sep 17 00:00:00 2001 From: bsilkyn Date: Mon, 13 May 2024 14:57:57 +0200 Subject: [PATCH 12/13] chore: simplify "if" in Group Serializer representation --- backend/api/serializers/group_serializer.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/backend/api/serializers/group_serializer.py b/backend/api/serializers/group_serializer.py index 38af2554..3865f7a2 100644 --- a/backend/api/serializers/group_serializer.py +++ b/backend/api/serializers/group_serializer.py @@ -36,14 +36,12 @@ def to_representation(self, instance): course_id = instance.project.course.id # If you are not a student, you can always see the score - # Same with being a student, but not being part of the course affiliated with this group - if is_student(user) and \ - not ((is_assistant(user) or is_teacher(user)) and - not user.student.courses.filter(id=course_id).exists()): + if is_student(user): student_in_course = user.student.courses.filter(id=course_id).exists() - # Student can not see the score if they are not part of the course associated with group, - # or it is not visible yet - if not student_in_course or \ + # Student can not see the score if they are not part of the course associated with group and + # neither an assistant or a teacher, + # or it is not visible yet when they are part of the course associated with the group + if not student_in_course and not is_assistant(user) and not is_teacher(user) or \ not instance.project.score_visible and student_in_course: data.pop("score") From 11b3b6684f8328f9e972e4dc9af11aa31ff803da Mon Sep 17 00:00:00 2001 From: bsilkyn Date: Mon, 13 May 2024 15:23:51 +0200 Subject: [PATCH 13/13] chore: rename component file #402 --- .../projects/{DownloadCSV.vue => DownloadCSVButton.vue} | 0 frontend/src/views/projects/roles/TeacherProjectView.vue | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) rename frontend/src/components/projects/{DownloadCSV.vue => DownloadCSVButton.vue} (100%) diff --git a/frontend/src/components/projects/DownloadCSV.vue b/frontend/src/components/projects/DownloadCSVButton.vue similarity index 100% rename from frontend/src/components/projects/DownloadCSV.vue rename to frontend/src/components/projects/DownloadCSVButton.vue diff --git a/frontend/src/views/projects/roles/TeacherProjectView.vue b/frontend/src/views/projects/roles/TeacherProjectView.vue index 10385344..328b22d6 100644 --- a/frontend/src/views/projects/roles/TeacherProjectView.vue +++ b/frontend/src/views/projects/roles/TeacherProjectView.vue @@ -5,7 +5,7 @@ import { type Teacher } from '@/types/users/Teacher.ts'; import { type Project } from '@/types/Project.ts'; import ProjectInfo from '@/components/projects/ProjectInfo.vue'; import ProjectMeter from '@/components/projects/ProjectMeter.vue'; -import DownloadCSV from '@/components/projects/DownloadCSV.vue'; +import DownloadCSVButton from '@/components/projects/DownloadCSVButton.vue'; /* Props */ defineProps<{ @@ -37,9 +37,9 @@ defineProps<{
-
+