Merge pull request #434 from pateljannat/student-class-view

This commit is contained in:
Jannat Patel
2022-11-28 10:13:41 +05:30
committed by GitHub
16 changed files with 182 additions and 141 deletions

View File

@@ -242,6 +242,10 @@ jinja = {
# "lms.plugins.LiveCodeExtension"
# ]
has_website_permission = {
"LMS Certificate Evaluation": "lms.lms.doctype.lms_certificate_evaluation.lms_certificate_evaluation.has_website_permission"
}
profile_mandatory_fields = [
"first_name",
"last_name",

View File

@@ -100,9 +100,10 @@ def delete_custom_fields():
def add_pages_to_nav():
pages = [
{"label": "Courses", "url": "/courses", "parent": "Explore", "idx": 2},
{"label": "Statistics", "url": "/statistics", "parent": "Explore", "idx": 3},
{"label": "Jobs", "url": "/jobs", "parent": "Explore", "idx": 4},
{"label": "People", "url": "/community", "parent": "Explore", "idx": 5},
{"label": "Classes", "url": "/classes", "parent": "Explore", "idx": 3},
{"label": "Statistics", "url": "/statistics", "parent": "Explore", "idx": 4},
{"label": "Jobs", "url": "/jobs", "parent": "Explore", "idx": 5},
{"label": "People", "url": "/community", "parent": "Explore", "idx": 6},
]
if not frappe.db.exists("Top Bar Item", {"label": "Explore"}):

View File

@@ -4,12 +4,19 @@
import frappe
from frappe.model.document import Document
from frappe.model.mapper import get_mapped_doc
from lms.lms.utils import has_course_moderator_role
class LMSCertificateEvaluation(Document):
pass
def has_website_permission(doc, ptype, user, verbose=False):
if has_course_moderator_role() or doc.member == frappe.session.user:
return True
return False
@frappe.whitelist()
def create_lms_certificate(source_name, target_doc=None):
doc = get_mapped_doc(

View File

@@ -15,7 +15,8 @@
"description",
"section_break_6",
"students",
"courses"
"courses",
"custom_component"
],
"fields": [
{
@@ -61,11 +62,18 @@
"fieldtype": "Date",
"label": "Start Date",
"reqd": 1
},
{
"description": "The HTML code entered here will be displayed on the class details page.",
"fieldname": "custom_component",
"fieldtype": "Code",
"label": "Custom Component",
"options": "HTML"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2022-11-21 10:55:50.067225",
"modified": "2022-11-25 10:37:24.250557",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Class",

View File

@@ -20,7 +20,7 @@
"list_columns": [],
"login_required": 1,
"max_attachment_size": 0,
"modified": "2022-11-23 14:57:47.700695",
"modified": "2022-11-25 17:05:30.851109",
"modified_by": "Administrator",
"module": "LMS",
"name": "evaluation",
@@ -29,7 +29,7 @@
"published": 1,
"route": "evaluation",
"show_attachments": 0,
"show_list": 1,
"show_list": 0,
"show_sidebar": 0,
"title": "Evaluation",
"web_form_fields": [
@@ -146,4 +146,4 @@
"show_in_filter": 0
}
]
}
}

View File

@@ -1,13 +1,6 @@
import frappe
from frappe import _
from lms.lms.utils import has_course_moderator_role
def get_context(context):
if not has_course_moderator_role():
message = "Only Moderators have access to this page."
if frappe.session.user == "Guest":
message = "Please login to access this page."
raise frappe.PermissionError(_(message))
pass

View File

@@ -36,6 +36,6 @@ lms.patches.v0_0.set_dashboard #11-10-2022
lms.patches.v0_0.set_courses_page_as_home
lms.patches.v0_0.set_member_in_progress #09-11-2022
lms.patches.v0_0.convert_progress_to_float
lms.patches.v0_0.add_pages_to_nav #11-11-2022
lms.patches.v0_0.add_pages_to_nav #25-11-2022
lms.patches.v0_0.change_role_names
lms.patches.v0_0.quiz_submission_result

View File

@@ -45,7 +45,8 @@
<div class="form-group">
<label> {{ _("Result") }} </label>
<div class="control-input flex align-center form-control">
<select class="input-with-feedback form-control pl-0" id="result" data-type="{{ assignment.status }}">
<select class="input-with-feedback form-control pl-0" id="result"
{% if not is_moderator %} disabled {% endif %} data-type="{{ assignment.status }}">
<option selected> {{ _("Not Graded") }} </option>
<option value="Pass"> {{ _("Pass") }} </option>
<option value="Fail"> {{ _("Fail") }} </option>
@@ -61,7 +62,8 @@
<div class="form-group col-md-6">
<label>{{ _("Comments") }}</label>
<textarea class="form-control" id="comments">{% if assignment.comments %}{{ assignment.comments }}{% endif %}</textarea>
<textarea class="form-control" id="comments" {% if not is_moderator %} disabled readonly {% endif %}
>{% if assignment.comments %}{{ assignment.comments }}{% endif %}</textarea>
</div>
</div>
</div>

View File

@@ -7,16 +7,29 @@ def get_context(context):
context.no_cache = 1
assignment = frappe.form_dict["assignment"]
if not has_course_moderator_role():
message = "Only Moderators have access to this page."
context.assignment = frappe.db.get_value(
"Lesson Assignment",
assignment,
[
"assignment",
"comments",
"status",
"name",
"member",
"member_name",
"course",
"lesson",
],
as_dict=True,
)
context.is_moderator = has_course_moderator_role()
if (
not has_course_moderator_role()
and not frappe.session.user == context.assignment.member
):
message = "You don't have the permissions to access this page."
if frappe.session.user == "Guest":
message = "Please login to access this page."
raise frappe.PermissionError(_(message))
context.assignment = frappe.db.get_value(
"Lesson Assignment",
assignment,
["assignment", "comments", "status", "name", "member_name", "course", "lesson"],
as_dict=True,
)

View File

@@ -50,6 +50,9 @@
</span>
{% endif %}
</div>
{% if class_info.custom_component %}
{{ class_info.custom_component }}
{% endif %}
</div>
{% endmacro %}
@@ -94,7 +97,8 @@
{% for course in published_courses %}
{% set checked = course.name in class_courses %}
<label class="class-course" data-course="{{ course.name }}">
<input type="checkbox" {% if checked %} checked {% endif %}>
<input type="checkbox" {% if checked %} checked {% endif %}
{% if not is_moderator %} disabled {% endif %}>
{{ course.title }}
</label>
{% endfor %}
@@ -105,10 +109,12 @@
{% macro StudentsSection(class_info, class_students) %}
<div class="medium">
{% if is_moderator %}
{{ AddStudents() }}
{% endif %}
{% if class_students | length %}
<table class="table mt-10">
<table class="table">
<tr>
<th style="width: 70%">
{{ _("Student") }}
@@ -116,7 +122,9 @@
<th style="width: 20%">
{{ _("Last Active") }}
</th>
{% if is_moderator %}
<th style="width: 10%"></th>
{% endif %}
</tr>
{% for student in class_students %}
{% set last_active = frappe.db.get_value("User", student.student, "last_active") %}
@@ -129,11 +137,13 @@
<td>
{{ frappe.utils.format_datetime(last_active, "medium") }}
</td>
{% if is_moderator %}
<td>
<svg class="icon icon-md pull-right remove-student" data-student="{{ student.student }}">
<use href="#icon-delete"></use>
</svg>
</td>
{% endif %}
</tr>
{% endfor %}
@@ -147,7 +157,7 @@
{% macro AddStudents() %}
<div>
<div class="mb-10">
<div class="mb-2">
{{ _("Add Student") }}
</div>
@@ -158,7 +168,9 @@
spellcheck="false">
</div>
</div>
<button class="btn btn-primary btn-sm" id="submit-student"> {{ _("Add") }} </button>
<button class="btn btn-primary btn-sm" id="submit-student">
{{ _("Add") }}
</button>
</form>
</div>
{% endmacro %}

View File

@@ -5,20 +5,12 @@ from frappe import _
def get_context(context):
context.no_cache = 1
if not has_course_moderator_role():
message = "Only Moderators have access to this page."
if frappe.session.user == "Guest":
message = "Please login to access this page."
raise frappe.PermissionError(_(message))
class_name = frappe.form_dict["classname"]
context.class_info = frappe.db.get_value(
"LMS Class",
class_name,
["name", "title", "start_date", "end_date", "description"],
["name", "title", "start_date", "end_date", "description", "custom_component"],
as_dict=True,
)
@@ -33,3 +25,5 @@ def get_context(context):
context.class_students = frappe.get_all(
"Class Student", {"parent": class_name}, ["student", "student_name", "username"]
)
context.is_moderator = has_course_moderator_role()

View File

@@ -6,9 +6,11 @@
{% block content %}
<div class="common-page-style">
<div class="container">
{% if has_course_moderator_role() %}
<a class="btn btn-default btn-sm pull-right" href="/class/new">
{{ _("Create Class") }}
</a>
{% endif %}
<div class="course-home-headings"> {{ _("All Classes") }} </div>
{% if classes %}
{{ ClassCards(classes) }}
@@ -63,4 +65,4 @@
</div>
{% endfor %}
</div>
{% endmacro %}
{% endmacro %}

View File

@@ -1,18 +1,10 @@
import frappe
from lms.lms.utils import has_course_moderator_role
from frappe import _
def get_context(context):
context.no_cache = 1
if not has_course_moderator_role():
message = "Only Moderators have access to this page."
if frappe.session.user == "Guest":
message = "Please login to access this page."
raise frappe.PermissionError(_(message))
context.classes = frappe.get_all(
"LMS Class", fields=["name", "title", "start_date", "end_date"]
)

View File

@@ -19,9 +19,11 @@
<span>
{{ frappe.utils.format_datetime(student.last_active, "medium") }}
</span>
{% if is_moderator %}
<a class="btn btn-secondary btn-sm ml-3" href="/evaluation/new?member={{student.name}}&date={{frappe.utils.getdate()}}">
{{ _("Evaluate") }}
</a>
{% endif %}
</div>
<div class="course-home-headings">
{{ student.full_name }}
@@ -55,7 +57,7 @@
<div class="ml-3"> {{ frappe.utils.cint(course.membership.progress) }}% </div>
</div>
{% if course.quizzes | length or course.assignments | length %}
{% if course.quizzes | length or course.assignments | length or course.evaluations | length %}
<div class="my-5">
<table class="table">
<tr>
@@ -73,90 +75,10 @@
</th>
</tr>
{% for quiz in course.quizzes %}
{% set filters = { "member": student.name, "course": course.course } %}
{% set has_submitted = frappe.db.exists("LMS Quiz Submission", filters) %}
{% set submission = frappe.db.get_value("LMS Quiz Submission", filters, ["score", "creation"], as_dict=True) %}
{% set total_questions = frappe.db.count("LMS Quiz Question", {"parent": quiz.name}) %}
{{ Quiz(course, student) }}
{{ Assignment(course, student, is_moderator) }}
{{ Evaluation(course, student, is_moderator) }}
<tr>
<td class="vertically-center">
<svg class="icon icon-sm">
<use href="#icon-quiz"></use>
</svg>
{{ _("Quiz") }}
</td>
<td>{{ quiz.title }}</td>
{% if has_submitted %}
<td>{{ submission.score }}/{{ total_questions }}</td>
<td>{{ frappe.utils.format_date(submission.creation, "medium") }}</td>
{% else %}
<td>-</td>
<td>
<div class="indicator-pill red">
{{ _("Not Attempted") }}
</div>
</td>
{% endif %}
</tr>
{% endfor %}
{% for assignment in course.assignments %}
{% set filters = { "member": student.name, "course": course.course, "lesson": assignment.name } %}
{% set has_submitted = frappe.db.exists("Lesson Assignment", filters) %}
{% set submission = frappe.db.get_value("Lesson Assignment", filters, ["assignment", "creation", "status"], as_dict=True) %}
{% set status = submission.status %}
{% set color = "green" if status == "Pass" else "red" if status == "Fail" else "orange" %}
<tr {% if has_submitted %} class="clickable-row" data-href="/assignments/{{ has_submitted }}" {% endif %}>
<td class="{% if has_submitted %} subheading {% endif %} vertically-center">
<svg class="icon icon-md">
<use href="#icon-file"></use>
</svg>
{{ _("Assignment") }}
</td>
<td>{{ assignment.title }}</td>
{% if has_submitted %}
<td>
<div class="indicator-pill {{ color }}">
{{ status }}
</div>
</td>
<td>{{ frappe.utils.format_date(submission.creation, "medium") }}</td>
{% else %}
<td>-</td>
<td>
<div class="indicator-pill red">
{{ _("Not Attempted") }}
</div>
</td>
{% endif %}
</tr>
{% endfor %}
{% for evaluation in course.evaluations %}
{% set color = "green" if evaluation.status == "Pass" else "red" %}
<tr class="clickable-row" data-href="/evaluation/{{evaluation.name}}">
<td class="subheading vertically-center">
<svg class="icon icon-md">
<use href="#icon-quality"></use>
</svg>
{{ _("Evaluation") }}
</td>
<td> - </td>
<td>
<div class="indicator-pill {{ color }}">
{{ evaluation.status }}
</div>
</td>
<td>{{ frappe.utils.format_date(evaluation.creation, "medium") }}</td>
</tr>
{% endfor %}
</table>
</div>
{% else %}
@@ -168,3 +90,100 @@
{% endfor %}
</div>
{% endmacro %}
{% macro Quiz(course, student) %}
{% for quiz in course.quizzes %}
{% set filters = { "member": student.name, "course": course.course } %}
{% set has_submitted = frappe.db.exists("LMS Quiz Submission", filters) %}
{% set submission = frappe.db.get_value("LMS Quiz Submission", filters, ["score", "creation"], as_dict=True) %}
{% set total_questions = frappe.db.count("LMS Quiz Question", {"parent": quiz.name}) %}
<tr>
<td class="vertically-center">
<svg class="icon icon-sm">
<use href="#icon-quiz"></use>
</svg>
{{ _("Quiz") }}
</td>
<td>{{ quiz.title }}</td>
{% if has_submitted %}
<td>{{ submission.score }}/{{ total_questions }}</td>
<td>{{ frappe.utils.format_date(submission.creation, "medium") }}</td>
{% else %}
<td>-</td>
<td>
<div class="indicator-pill red">
{{ _("Not Attempted") }}
</div>
</td>
{% endif %}
</tr>
{% endfor %}
{% endmacro %}
{% macro Assignment(course, student, is_moderator) %}
{% for assignment in course.assignments %}
{% set filters = { "member": student.name, "course": course.course, "lesson": assignment.name } %}
{% set has_submitted = frappe.db.exists("Lesson Assignment", filters) %}
{% set submission = frappe.db.get_value("Lesson Assignment", filters, ["assignment", "creation", "status"], as_dict=True) %}
{% set status = submission.status %}
{% set color = "green" if status == "Pass" else "red" if status == "Fail" else "orange" %}
{% set can_see_details = has_submitted and (is_moderator or frappe.session.user == student.name) %}
<tr {% if can_see_details %} class="clickable-row" data-href="/assignments/{{ has_submitted }}" {% endif %}>
<td class="{% if can_see_details %} subheading {% endif %} vertically-center">
<svg class="icon icon-md">
<use href="#icon-file"></use>
</svg>
{{ _("Assignment") }}
</td>
<td>{{ assignment.title }}</td>
{% if has_submitted %}
<td>
<div class="indicator-pill {{ color }}">
{{ status }}
</div>
</td>
<td>{{ frappe.utils.format_date(submission.creation, "medium") }}</td>
{% else %}
<td>-</td>
<td>
<div class="indicator-pill red">
{{ _("Not Attempted") }}
</div>
</td>
{% endif %}
</tr>
{% endfor %}
{% endmacro %}
{% macro Evaluation(course, student, is_moderator) %}
{% for evaluation in course.evaluations %}
{% set color = "green" if evaluation.status == "Pass" else "red" %}
{% set can_see_details = is_moderator or frappe.session.user == student.name %}
<tr {% if can_see_details %} class="clickable-row" data-href="/evaluation/{{evaluation.name}}" {% endif %}>
<td class="{% if can_see_details %} subheading {% endif %} vertically-center">
<svg class="icon icon-md">
<use href="#icon-quality"></use>
</svg>
{{ _("Evaluation") }}
</td>
<td> - </td>
<td>
<div class="indicator-pill {{ color }}">
{{ evaluation.status }}
</div>
</td>
<td>{{ frappe.utils.format_date(evaluation.creation, "medium") }}</td>
</tr>
{% endfor %}
{% endmacro %}

View File

@@ -6,15 +6,9 @@ from frappe import _
def get_context(context):
context.no_cache = 1
if not has_course_moderator_role():
message = "Only Moderators have access to this page."
if frappe.session.user == "Guest":
message = "Please login to access this page."
raise frappe.PermissionError(_(message))
student = frappe.form_dict["username"]
classname = frappe.form_dict["classname"]
context.is_moderator = has_course_moderator_role()
context.student = frappe.db.get_value(
"User",

View File