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:
@@ -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"}
|
||||
]
|
||||
|
||||
|
||||
@@ -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.
|
||||
"""
|
||||
|
||||
34
school/www/cohorts/base.html
Normal file
34
school/www/cohorts/base.html
Normal 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 %}
|
||||
|
||||
|
||||
34
school/www/cohorts/index.html
Normal file
34
school/www/cohorts/index.html
Normal 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 %}
|
||||
30
school/www/cohorts/index.py
Normal file
30
school/www/cohorts/index.py
Normal 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]
|
||||
17
school/www/cohorts/utils.py
Normal file
17
school/www/cohorts/utils.py
Normal 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})
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user