From fdacab66f7389078c598a51e96e7a5674cb310e1 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Fri, 13 Dec 2024 10:44:56 +0530 Subject: [PATCH 1/3] feat: show student course and assessment progress on batch page --- frontend/src/components/BatchCourses.vue | 5 +- frontend/src/components/BatchStudents.vue | 77 +++++++++++++------ .../src/components/Modals/StudentModal.vue | 6 +- lms/lms/utils.py | 71 +++++++++-------- 4 files changed, 104 insertions(+), 55 deletions(-) diff --git a/frontend/src/components/BatchCourses.vue b/frontend/src/components/BatchCourses.vue index 9134c42c7..e29169d56 100644 --- a/frontend/src/components/BatchCourses.vue +++ b/frontend/src/components/BatchCourses.vue @@ -110,6 +110,7 @@ const openCourseModal = () => { } const getCoursesColumns = () => { + console.log(courses.data) return [ { label: 'Title', @@ -118,13 +119,13 @@ const getCoursesColumns = () => { }, { label: 'Lessons', - key: 'lesson_count', + key: 'lessons', align: 'right', }, { label: 'Enrollments', align: 'right', - key: 'enrollment_count', + key: 'enrollments', }, ] } diff --git a/frontend/src/components/BatchStudents.vue b/frontend/src/components/BatchStudents.vue index 496a10ecc..099abfa42 100644 --- a/frontend/src/components/BatchStudents.vue +++ b/frontend/src/components/BatchStudents.vue @@ -20,10 +20,10 @@ > @@ -42,9 +42,19 @@ /> -
+
{{ row[column.key] }}
+
+ {{ Math.ceil(row.courses[column.key]) }} +
+ + {{ row.assessments[column.key] }} + @@ -74,7 +84,11 @@ diff --git a/frontend/src/components/Modals/StudentModal.vue b/frontend/src/components/Modals/StudentModal.vue index 54bd05b71..a6bab4000 100644 --- a/frontend/src/components/Modals/StudentModal.vue +++ b/frontend/src/components/Modals/StudentModal.vue @@ -28,6 +28,7 @@ import { Dialog, createResource } from 'frappe-ui' import { ref } from 'vue' import Link from '@/components/Controls/Link.vue' +import { showToast } from '@/utils' const students = defineModel('reloadStudents') const student = ref() @@ -61,8 +62,11 @@ const addStudent = (close) => { { onSuccess() { students.value.reload() - close() student.value = null + close() + }, + onError(err) { + showToast(__('Error'), __(err.messages?.[0] || err), 'x') }, } ) diff --git a/lms/lms/utils.py b/lms/lms/utils.py index 933d626dc..7b8d7430a 100644 --- a/lms/lms/utils.py +++ b/lms/lms/utils.py @@ -874,26 +874,6 @@ def is_onboarding_complete(): } -def has_submitted_assessment(assessment, type, member=None): - if not member: - member = frappe.session.user - - doctype = ( - "LMS Assignment Submission" if type == "LMS Assignment" else "LMS Quiz Submission" - ) - docfield = "assignment" if type == "LMS Assignment" else "quiz" - - filters = {} - filters[docfield] = assessment - filters["member"] = member - return frappe.db.exists(doctype, filters) - - -def has_graded_assessment(submission): - status = frappe.db.get_value("LMS Assignment Submission", submission, "status") - return False if status == "Not Graded" else True - - def get_evaluator(course, batch): evaluator = None evaluator = frappe.db.get_value( @@ -1459,13 +1439,11 @@ def get_quiz_details(assessment, member): @frappe.whitelist() def get_batch_students(batch): students = [] - students_list = frappe.get_all( "Batch Student", filters={"parent": batch}, fields=["student", "name"] ) - batch_courses = frappe.get_all("Batch Course", {"parent": batch}, pluck="course") - + batch_courses = frappe.get_all("Batch Course", {"parent": batch}, ["course", "title"]) assessments = frappe.get_all( "LMS Assessment", filters={"parent": batch}, @@ -1483,29 +1461,62 @@ def get_batch_students(batch): ) detail.last_active = format_datetime(detail.last_active, "dd MMM YY") detail.name = student.name - students.append(detail) + detail.courses = frappe._dict() + detail.assessments = frappe._dict() + """ Iterate through courses and track their progress """ for course in batch_courses: progress = frappe.db.get_value( - "LMS Enrollment", {"course": course, "member": student.student}, "progress" + "LMS Enrollment", {"course": course.course, "member": student.student}, "progress" ) - + detail.courses[course.title] = progress if progress == 100: courses_completed += 1 - detail.courses_completed = courses_completed - + """ Iterate through assessments and track their progress """ for assessment in assessments: - if has_submitted_assessment( + title = frappe.db.get_value("LMS Assignment", assessment.assessment_name, "title") + status = has_submitted_assessment( assessment.assessment_name, assessment.assessment_type, student.student - ): + ) + detail.assessments[title] = status + if status not in ["Not Attempted", 0]: assessments_completed += 1 + detail.courses_completed = courses_completed detail.assessments_completed = assessments_completed + students.append(detail) return students +def has_submitted_assessment(assessment, assessment_type, member=None): + if not member: + member = frappe.session.user + + if assessment_type == "LMS Assignment": + doctype = "LMS Assignment Submission" + docfield = "assignment" + fields = ["status"] + not_attempted = "Not Attempted" + elif assessment_type == "LMS Quiz": + doctype = "LMS Quiz Submission" + docfield = "quiz" + fields = ["score"] + not_attempted = 0 + + filters = {} + filters[docfield] = assessment + filters["member"] = member + + attempt = frappe.db.exists(doctype, filters) + if attempt: + attempt_details = frappe.db.get_value(doctype, filters, fields) + return attempt_details + else: + return not_attempted + + @frappe.whitelist() def get_discussion_topics(doctype, docname, single_thread): if single_thread: From 6cdfb822b4f715e0cd5fa8b8c3cf1a23bc7abd19 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Fri, 13 Dec 2024 11:45:54 +0530 Subject: [PATCH 2/3] fix: batch time issue --- frontend/src/components/BatchStudents.vue | 43 +++++++++++++++-------- frontend/src/pages/BatchForm.vue | 6 +++- lms/lms/utils.py | 6 ++-- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/frontend/src/components/BatchStudents.vue b/frontend/src/components/BatchStudents.vue index 099abfa42..cf2bafe5c 100644 --- a/frontend/src/components/BatchStudents.vue +++ b/frontend/src/components/BatchStudents.vue @@ -18,7 +18,11 @@ - + @@ -125,30 +132,32 @@ const getStudentColumns = () => { { label: 'Full Name', key: 'full_name', - width: 1, + width: '10rem', }, ] if (students.data?.[0].courses) { Object.keys(students.data?.[0].courses).forEach((course) => { columns.push({ - label: `${course} (%)`, + label: course, key: course, - width: 1, + width: '10rem', icon: 'book-open', align: 'center', }) }) } - + console.log(students.data?.[0].assessments) if (students.data?.[0].assessments) { Object.keys(students.data?.[0].assessments).forEach((assessment) => { columns.push({ label: assessment, key: assessment, - width: 1, + width: '10rem', icon: 'help-circle', - align: 'left', + align: isAssignment(students.data?.[0].assessments[assessment]) + ? 'left' + : 'center', }) }) } @@ -193,4 +202,8 @@ const getStatusTheme = (status) => { return 'red' } } + +const isAssignment = (value) => { + return isNaN(value) +} diff --git a/frontend/src/pages/BatchForm.vue b/frontend/src/pages/BatchForm.vue index 14c16c922..1979c9f18 100644 --- a/frontend/src/pages/BatchForm.vue +++ b/frontend/src/pages/BatchForm.vue @@ -252,7 +252,7 @@ import { } from 'frappe-ui' import Link from '@/components/Controls/Link.vue' import { useRouter } from 'vue-router' -import { showToast } from '../utils' +import { showToast } from '@/utils' import { Image } from 'lucide-vue-next' import { capture } from '@/telemetry' import MultiSelect from '@/components/Controls/MultiSelect.vue' @@ -345,6 +345,10 @@ const batchDetail = createResource({ data.instructors.forEach((instructor) => { instructors.value.push(instructor.instructor) }) + } else if (['start_time', 'end_time'].includes(key)) { + let [hours, minutes, seconds] = data[key].split(':') + hours = hours.length == 1 ? '0' + hours : hours + batch[key] = `${hours}:${minutes}` } else if (Object.hasOwn(batch, key)) batch[key] = data[key] }) let checkboxes = ['published', 'paid_batch', 'allow_self_enrollment'] diff --git a/lms/lms/utils.py b/lms/lms/utils.py index 7b8d7430a..ece56ca4a 100644 --- a/lms/lms/utils.py +++ b/lms/lms/utils.py @@ -1475,7 +1475,9 @@ def get_batch_students(batch): """ Iterate through assessments and track their progress """ for assessment in assessments: - title = frappe.db.get_value("LMS Assignment", assessment.assessment_name, "title") + title = frappe.db.get_value( + assessment.assessment_type, assessment.assessment_name, "title" + ) status = has_submitted_assessment( assessment.assessment_name, assessment.assessment_type, student.student ) @@ -1502,7 +1504,7 @@ def has_submitted_assessment(assessment, assessment_type, member=None): elif assessment_type == "LMS Quiz": doctype = "LMS Quiz Submission" docfield = "quiz" - fields = ["score"] + fields = ["percentage"] not_attempted = 0 filters = {} From 40aefba2031a4cb1a56e4fbca4b415849c273d42 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Fri, 13 Dec 2024 12:03:00 +0530 Subject: [PATCH 3/3] fix: styling of batch list headers --- frontend/src/components/Assessments.vue | 12 +++++++++--- frontend/src/components/BatchCourses.vue | 3 +-- frontend/src/components/BatchStudents.vue | 20 +++++++++++--------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/Assessments.vue b/frontend/src/components/Assessments.vue index 55c849dd7..ac0664ef9 100644 --- a/frontend/src/components/Assessments.vue +++ b/frontend/src/components/Assessments.vue @@ -1,7 +1,7 @@