feat: added a page to list cohorts of a course

- added a page /courses/<course>/manage that lists the active cohorts
- only accessible to mentors and staff
- also added a "manage the course" button on course page for mentors/staff

Issue #271
This commit is contained in:
Anand Chitipothu
2021-11-29 17:33:45 +05:30
parent 7cd57cadb2
commit 102fa9c0a8
7 changed files with 141 additions and 0 deletions

View File

@@ -141,6 +141,7 @@ website_route_rules = [
{"from_route": "/courses/<course>/learn/<int:chapter>.<int:lesson>", "to_route": "batch/learn"},
{"from_route": "/courses/<course>/progress", "to_route": "batch/progress"},
{"from_route": "/courses/<course>/join", "to_route": "batch/join"},
{"from_route": "/courses/<course>/manage", "to_route": "cohorts"},
{"from_route": "/users", "to_route": "profiles/profile"}
]

View File

@@ -210,6 +210,24 @@ class LMSCourse(Document):
visibility="Public")
return batches
def get_cohorts(self):
return find_all("Cohort", course=self.name, order_by="creation")
def is_cohort_staff(self, user_email):
"""Returns True if the user is either a mentor or a staff for one or more active cohorts of this course.
"""
q1 = {
"doctype": "Cohort Staff",
"course": self.name,
"email": user_email
}
q2 = {
"doctype": "Cohort Mentor",
"course": self.name,
"email": user_email
}
return frappe.db.exists(q1) or frappe.db.exists(q2)
def get_lesson_index(self, lesson_name):
"""Returns the {chapter_index}.{lesson_index} for the lesson.
"""

View File

@@ -0,0 +1,34 @@
{% extends "templates/base.html" %}
{% macro render_nav(nav) %}
<div class="breadcrumb">
{% for link in nav %}
<a class="dark-links" href="{{ link.href }}">{{ link.title }}</a>
{% if not loop.last %}
<img class="ml-1 mr-1" src="/assets/school/icons/chevron-right.svg">
{% endif %}
{% endfor %}
</div>
{% endmacro %}
{% block title %}Cohorts{% endblock %}
{% block head_include %}
<meta name="description" content="Cohorts" />
<meta name="keywords" content="Cohorts" />
{% endblock %}
{% block content %}
<div class="common-page-style">
<div class='container'>
{{ render_nav(nav | default([])) }}
{% block page_content %}
Hello, world!
{% endblock %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,34 @@
{% extends "www/cohorts/base.html" %}
{% block title %}Manage {{ course.title }}{% endblock %}
{% block page_content %}
<div class="common-page-style">
<div class="container">
{% if cohorts %}
<h2>Cohorts</h2>
<div class="row">
{% for cohort in cohorts %}
<div class="col-md-4">
{{ render_cohort(course, cohort) }}
</div>
{% endfor %}
{% else %}
<h2>Permission Denied</h2>
<p>You don't have permission to manage this course.</p>
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% macro render_cohort(course, cohort) %}
<div class="card">
<div class="card-body">
<h5 class="card-title">{{cohort.title}}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{cohort.begin_date}} - {{cohort.end_date}}</h6>
<a href="/courses/{{course.name}}/cohorts/{{cohort.slug}}" class="card-link">Manage</a>
</div>
</div>
{% endmacro %}

View File

@@ -0,0 +1,30 @@
import frappe
from .utils import get_course, add_nav
def get_context(context):
context.no_cache = 1
context.course = get_course()
if frappe.session.user == "Guest":
frappe.local.flags.redirect_location = "/login?redirect-to=" + frappe.request.path
raise frappe.Redirect()
if not context.course:
context.template = "www/404.html"
return
context.cohorts = get_cohorts(context.course)
add_nav(context, "All Courses", "/courses")
add_nav(context, context.course.title, "/courses/" + context.course.name)
def get_cohorts(course):
if "System Manager" in frappe.get_roles():
return course.get_cohorts()
staff_roles = frappe.get_all("Cohort Staff", filters={"course": course.name}, fields=["cohort"])
mentor_roles = frappe.get_all("Cohort Mentor", filters={"course": course.name}, fields=["cohort"])
roles = staff_roles + mentor_roles
print(roles)
names = {role.cohort for role in roles}
print(names)
return [frappe.get_doc("Cohort", name) for name in names]

View File

@@ -0,0 +1,17 @@
import frappe
def get_course(course_name=None):
course_name = course_name or frappe.form_dict["course"]
return course_name and get_doc("LMS Course", course_name)
def get_doc(doctype, name):
try:
return frappe.get_doc(doctype, name)
except frappe.exceptions.DoesNotExistError:
return
def add_nav(context, title, href):
"""Adds a breadcrumb to the navigation.
"""
nav = context.setdefault("nav", [])
nav.append({"title": title, "href": href})

View File

@@ -70,6 +70,13 @@
<img class="ml-2" src="/assets/school/images/play.png" />
</div>
{% endif %}
{% if course.is_cohort_staff(frappe.session.user) %}
<a class="button wide-button" style="position: absolute; right: 0;"
href="/courses/{{course.name}}/manage">
Manage the course
</a>
{% endif %}
</div>
</div>
</div>