fix: dashboard links, web form redirects and patch for status

This commit is contained in:
Jannat Patel
2022-03-15 16:51:39 +05:30
parent aa9ef65375
commit 27e1aec001
18 changed files with 99 additions and 46 deletions

View File

@@ -1,5 +1,6 @@
{ {
"actions": [], "actions": [],
"autoname": "hash",
"creation": "2021-07-27 16:25:02.903245", "creation": "2021-07-27 16:25:02.903245",
"doctype": "DocType", "doctype": "DocType",
"editable_grid": 1, "editable_grid": 1,
@@ -20,13 +21,15 @@
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"istable": 1, "istable": 1,
"links": [], "links": [],
"modified": "2021-09-30 10:35:30.014950", "modified": "2022-03-15 09:39:41.937565",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "LMS", "module": "LMS",
"name": "Chapter Reference", "name": "Chapter Reference",
"naming_rule": "Random",
"owner": "Administrator", "owner": "Administrator",
"permissions": [], "permissions": [],
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"states": [],
"track_changes": 1 "track_changes": 1
} }

View File

@@ -110,11 +110,5 @@ def save_progress(lesson, course, status):
return progress return progress
@frappe.whitelist() @frappe.whitelist()
def get_lesson_info(lesson_name): def get_lesson_info(chapter):
chapter = frappe.db.get_value("Course Lesson", lesson_name, "chapter") return frappe.db.get_value("Course Chapter", chapter, "course")
course = frappe.db.get_value("Course Chapter", chapter, "course")
lesson_idx = frappe.db.get_value("Lesson Reference", {"lesson": lesson_name}, ["idx"])
chapter_idx = frappe.db.get_value("Chapter Reference", {"chapter": chapter}, ["idx"])
return get_lesson_url(course, f"{chapter_idx}.{lesson_idx}")

View File

@@ -1,5 +1,6 @@
{ {
"actions": [], "actions": [],
"autoname": "hash",
"creation": "2021-07-27 16:25:48.269536", "creation": "2021-07-27 16:25:48.269536",
"doctype": "DocType", "doctype": "DocType",
"editable_grid": 1, "editable_grid": 1,
@@ -20,13 +21,15 @@
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"istable": 1, "istable": 1,
"links": [], "links": [],
"modified": "2021-09-30 10:35:47.832547", "modified": "2022-03-15 09:39:29.495991",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "LMS", "module": "LMS",
"name": "Lesson Reference", "name": "Lesson Reference",
"naming_rule": "Random",
"owner": "Administrator", "owner": "Administrator",
"permissions": [], "permissions": [],
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"states": [],
"track_changes": 1 "track_changes": 1
} }

View File

@@ -144,8 +144,10 @@
"fieldname": "status", "fieldname": "status",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 1, "hidden": 1,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Status", "label": "Status",
"options": "In Progress\nReady for Review\nApproved", "options": "In Progress\nUnder Review\nApproved",
"read_only": 1 "read_only": 1
}, },
{ {
@@ -184,7 +186,7 @@
"link_fieldname": "course" "link_fieldname": "course"
} }
], ],
"modified": "2022-03-14 17:56:46.514391", "modified": "2022-03-15 10:16:53.796878",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "LMS", "module": "LMS",
"name": "LMS Course", "name": "LMS Course",

View File

@@ -208,5 +208,5 @@ def submit_for_review(course):
chapters = frappe.get_all("Chapter Reference", {"parent": course}) chapters = frappe.get_all("Chapter Reference", {"parent": course})
if not len(chapters): if not len(chapters):
return "No Chp" return "No Chp"
frappe.db.set_value("LMS Course", course, "status", "Ready for Review") frappe.db.set_value("LMS Course", course, "status", "Under Review")
return "OK" return "OK"

View File

@@ -1,5 +1,6 @@
frappe.ready(function() { frappe.ready(function() {
frappe.web_form.after_save = () => { frappe.web_form.after_save = () => {
window.location.href = `/dashboard#courses-created`; let route = frappe.web_form.doc.name ? `/courses/${frappe.web_form.doc.name}` : `/course`;
window.location.href = route;
} }
}); });

View File

@@ -1,5 +1,15 @@
frappe.ready(function() { frappe.ready(function() {
frappe.web_form.after_save = () => { frappe.web_form.after_save = () => {
window.location.href = `/courses/` setTimeout(() => {
frappe.call({
method: "school.lms.doctype.course_lesson.course_lesson.get_lesson_info",
args: {
"chapter": frappe.web_form.doc.chapter
},
callback: (data) => {
window.location.href = `/courses/${data.message}`;
}
});
});
}; };
}); });

View File

@@ -17,9 +17,11 @@
<div class="course-card-content"> <div class="course-card-content">
<div class="course-card-meta"> <div class="course-card-meta">
{% if get_lessons(course.name) | length %} {% if get_lessons(course.name) | length %}
<span> <span> {{ get_lessons(course.name) | length }} {{ _("Lessons") }} </span>
{{ get_lessons(course.name) | length }} {{ _("Lessons") }} {% endif %}
</span> {% if course.status and course.status != "Approved"%}
{% set pill_color = "gray" if course.status == "In Progress" else "orange" %}
<span class="pull-right indicator-pill {{ pill_color }} "> {{ course.status }} </span>
{% endif %} {% endif %}
</div> </div>
<div class="course-card-title">{{ course.title }}</div> <div class="course-card-title">{{ course.title }}</div>

View File

@@ -124,7 +124,7 @@ class CustomUser(User):
def get_enrolled_courses(): def get_enrolled_courses():
in_progress = [] in_progress = []
completed = [] completed = []
memberships = get_course_membership(member_type="Student") memberships = get_course_membership(frappe.session.user, member_type="Student")
for membership in memberships: for membership in memberships:
course = frappe.db.get_value("LMS Course", membership.course, course = frappe.db.get_value("LMS Course", membership.course,
["name", "upcoming", "title", "image", "enable_certification"], as_dict=True) ["name", "upcoming", "title", "image", "enable_certification"], as_dict=True)
@@ -139,7 +139,7 @@ def get_enrolled_courses():
"completed": completed "completed": completed
} }
def get_course_membership(member=frappe.session.user, member_type=None): def get_course_membership(member, member_type=None):
""" Returns all memberships of the user """ """ Returns all memberships of the user """
filters = { filters = {
"member": member "member": member
@@ -150,7 +150,7 @@ def get_course_membership(member=frappe.session.user, member_type=None):
return frappe.get_all("LMS Batch Membership", filters, ["name", "course", "progress"]) return frappe.get_all("LMS Batch Membership", filters, ["name", "course", "progress"])
def get_authored_courses(member=frappe.session.user, only_published=True): def get_authored_courses(member, only_published=True):
"""Returns the number of courses authored by this user. """Returns the number of courses authored by this user.
""" """
course_details = [] course_details = []
@@ -164,7 +164,7 @@ def get_authored_courses(member=frappe.session.user, only_published=True):
for course in courses: for course in courses:
course_details.append(frappe.db.get_value("LMS Course", course, course_details.append(frappe.db.get_value("LMS Course", course,
["name", "upcoming", "title", "image", "enable_certification"], as_dict=True)) ["name", "upcoming", "title", "image", "enable_certification", "status"], as_dict=True))
return course_details return course_details

View File

@@ -23,3 +23,4 @@ execute:frappe.delete_doc("Workspace", "LMS", ignore_missing=True, force=True) #
execute:frappe.delete_doc("Custom Field", "User-verify_age", ignore_missing=True, force=True) execute:frappe.delete_doc("Custom Field", "User-verify_age", ignore_missing=True, force=True)
school.patches.v0_0.multiple_instructors #11-02-2022 school.patches.v0_0.multiple_instructors #11-02-2022
school.patches.v0_0.set_course_in_lesson #14-03-2022 school.patches.v0_0.set_course_in_lesson #14-03-2022
school.patches.v0_0.set_status_in_course

View File

@@ -0,0 +1,7 @@
import frappe
def execute():
courses = frappe.get_all("LMS Course", {"status": ("is", "not set")}, ["name", "is_published"])
for course in courses:
status = "Approved" if course.is_published else "In Progress"
frappe.db.set_value("LMS Course", course.name, "status", status)

View File

@@ -73,7 +73,7 @@ input[type=checkbox] {
} }
.common-page-style { .common-page-style {
padding: 4rem 0 5rem; padding: 2rem 0 5rem;
min-height: 60vh; min-height: 60vh;
font-size: var(--text-base); font-size: var(--text-base);
} }
@@ -347,7 +347,7 @@ input[type=checkbox] {
.is-secondary { .is-secondary {
background: #FFFFFF; background: #FFFFFF;
color: inherit; color: var(--gray-900);
} }
.is-secondary:hover { .is-secondary:hover {
@@ -357,7 +357,7 @@ input[type=checkbox] {
.is-default { .is-default {
background: var(--gray-100); background: var(--gray-100);
color: var(--gray-700); color: var(--gray-900);
} }
.is-default:disabled { .is-default:disabled {
@@ -1238,7 +1238,6 @@ pre {
} }
.course-intructor-rating-section .seperator::before { .course-intructor-rating-section .seperator::before {
content: "\00B7";
margin: 0 0.25rem; margin: 0 0.25rem;
} }
} }
@@ -1428,8 +1427,8 @@ pre {
} }
.dashboard .nav-link { .dashboard .nav-link {
color: var(--text-muted); color: var(--text-muted);
padding: var(--padding-md) 0; padding: 0 0 var(--padding-md);
margin-right: var(--margin-xl); margin-right: var(--margin-xl);
} }
@@ -1443,6 +1442,8 @@ pre {
color: inherit; color: inherit;
} }
.dashboard .nav { .dashboard-button {
border-bottom: 1px solid var(--border-color); position: relative;
top: -50px;
margin-left: auto;
} }

View File

@@ -1,4 +1,4 @@
{% set courses = get_authored_courses(only_published=False) %} {% set courses = get_authored_courses(frappe.session.user, only_published=False) %}
{% if courses | length %} {% if courses | length %}
<div class="cards-parent"> <div class="cards-parent">
{% for course in courses %} {% for course in courses %}

View File

@@ -29,8 +29,14 @@
{% else %} background-color: var(--gray-200) {% endif %}"> {% else %} background-color: var(--gray-200) {% endif %}">
<div class="container pt-10 pb-10"> <div class="container pt-10 pb-10">
{% if is_instructor(course.name) %} {% if is_instructor(course.name) %}
<a class="button is-default button-links pull-right" href="/lesson?new=1"> {{ _("New Lesson") }} </a> <a class="button is-default button-links pull-right" href="/lesson">
<a class="button is-default button-links pull-right mr-2" href="/chapter?new=1"> {{ _("New Chapter") }} </a> <svg class="icon icon-sm mr-1"><use href="#icon-add"></use></svg>
{{ _("Add Lesson") }}
</a>
<a class="button is-default button-links pull-right mr-2" href="/chapter">
<svg class="icon icon-sm mr-1"><use href="#icon-add"></use></svg>
{{ _("Add Chapter") }}
</a>
<a class="button is-default button-links pull-right mr-2" href="/course?name={{ course.name }}"> {{ _("Edit") }} </a> <a class="button is-default button-links pull-right mr-2" href="/course?name={{ course.name }}"> {{ _("Edit") }} </a>
{% endif %} {% endif %}
{{ BreadCrumb(course) }} {{ BreadCrumb(course) }}
@@ -131,9 +137,15 @@
<div class="course-home-headings"> {{ course.title }} </div> <div class="course-home-headings"> {{ course.title }} </div>
<div id="interest-alert" class="{% if not is_user_interested %} hide {% endif %}"> <div id="interest-alert" class="{% if not is_user_interested %} hide {% endif %}">
You have opted to be notified for this course. You will receive an email when the course becomes available. {{ _("You have opted to be notified for this course. You will receive an email when the course becomes available.") }}
</div> </div>
{% if course.status == "Under Review" %}
<div>
{{ _("Your course is currently under review. Once the review is complete, the System Admins will publish it on the website.") }}
</div>
{% endif %}
{% if get_lessons(course.name) | length %} {% if get_lessons(course.name) | length %}
<div class="mt-3 mb-4"> <div class="mt-3 mb-4">
<img class="mr-3" src="/assets/school/icons/book.svg"> <img class="mr-3" src="/assets/school/icons/book.svg">
@@ -162,14 +174,13 @@
{% set lesson_index = get_lesson_index(membership.current_lesson) if membership and {% set lesson_index = get_lesson_index(membership.current_lesson) if membership and
membership.current_lesson membership.current_lesson
else '1.1' %} else '1.1' %}
{% if show_start_learing_cta %} {% if show_start_learing_cta %}
<div class="button wide-button is-primary join-batch" data-course="{{ course.name | urlencode }}"> <div class="button wide-button is-primary join-batch" data-course="{{ course.name | urlencode }}">
{{ _("Start Learning") }} {{ _("Start Learning") }}
<img class="ml-2" src="/assets/school/icons/white-arrow.svg" /> <img class="ml-2" src="/assets/school/icons/white-arrow.svg" />
</div> </div>
{% elif is_instructor(course.name) and not course.is_published and status != "Ready for Review" %} {% elif is_instructor(course.name) and not course.is_published and course.status != "Under Review" %}
<div class="button wide-button is-primary" id="submit-for-review" data-course="{{ course.name | urlencode }}"> <div class="button wide-button is-primary" id="submit-for-review" data-course="{{ course.name | urlencode }}">
{{ _("Submit for Review") }} {{ _("Submit for Review") }}
<img class="ml-2" src="/assets/school/icons/white-arrow.svg" /> <img class="ml-2" src="/assets/school/icons/white-arrow.svg" />

View File

@@ -274,6 +274,7 @@ const submit_for_review = (e) => {
Please add chapters and lessons to your course before you submit it for review.`)); Please add chapters and lessons to your course before you submit it for review.`));
} else if (data.message == "OK") { } else if (data.message == "OK") {
frappe.msgprint(__("Your course has been submitted for review.")) frappe.msgprint(__("Your course has been submitted for review."))
window.location.reload();
} }
} }
}) })

View File

@@ -13,7 +13,7 @@ def get_context(context):
course = frappe.db.get_value("LMS Course", course_name, course = frappe.db.get_value("LMS Course", course_name,
["name", "title", "image", "short_introduction", "description", "is_published", "upcoming", ["name", "title", "image", "short_introduction", "description", "is_published", "upcoming",
"disable_self_learning", "video_link", "enable_certification"], "disable_self_learning", "video_link", "enable_certification", "status"],
as_dict=True) as_dict=True)
related_courses = frappe.get_all("Related Courses", {"parent": course.name}, ["course"]) related_courses = frappe.get_all("Related Courses", {"parent": course.name}, ["course"])
@@ -33,7 +33,7 @@ def get_context(context):
if context.course.upcoming: if context.course.upcoming:
context.is_user_interested = get_user_interest(context.course.name) context.is_user_interested = get_user_interest(context.course.name)
context.restriction = check_profile_restriction() context.restriction = check_profile_restriction()
context.show_start_learing_cta = show_start_learing_cta(course, membership) context.show_start_learing_cta = show_start_learing_cta(course, membership, context.restriction)
context.metatags = { context.metatags = {
"title": course.title, "title": course.title,
"image": course.image, "image": course.image,
@@ -48,5 +48,5 @@ def get_user_interest(course):
"user": frappe.session.user "user": frappe.session.user
}) })
def show_start_learing_cta(course, membership): def show_start_learing_cta(course, membership, restriction):
return not course.disable_self_learning and not membership and not course.upcoming and not restriction.restrict and not is_instructor(course.name) return not course.disable_self_learning and not membership and not course.upcoming and not restriction.get("restrict") and not is_instructor(course.name)

View File

@@ -3,23 +3,32 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{% set portal_course_creation = frappe.db.get_single_value("LMS Settings", "portal_course_creation") %}
<div class="common-page-style dashboard"> <div class="common-page-style dashboard">
<div class="container"> <div class="container">
<ul class="nav mb-8"> {% if portal_course_creation %}
<a class="button is-default button-links pull-right hide" id="create-course-link" href="/course">
<svg class="icon icon-sm mr-1"><use href="#icon-add"></use></svg>
{{ _("New Course")}}
</a>
{% endif %}
<ul class="nav" id="courses-tab">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#courses-enrolled"> {{ _("Courses Enrolled") }} </a> <a class="nav-link active" data-toggle="tab" href="#courses-enrolled"> {{ _("Courses Enrolled") }} </a>
</li> </li>
{% if frappe.db.get_single_value("LMS Settings", "portal_course_creation") %} {% if portal_course_creation %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#courses-created">{{ _("Courses Created") }}</a> <a class="nav-link" data-toggle="tab" href="#courses-created">{{ _("Courses Created") }}
</a>
</li> </li>
{% endif %} {% endif %}
</ul> </ul>
<div class="border-bottom mb-4"></div>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id="courses-enrolled" role="tabpanel" aria-labelledby="courses-enrolled"> <div class="tab-pane active" id="courses-enrolled" role="tabpanel" aria-labelledby="courses-enrolled">
{% include "school/lms/web_template/courses_enrolled/courses_enrolled.html" %} {% include "school/lms/web_template/courses_enrolled/courses_enrolled.html" %}
</div> </div>
{% if frappe.db.get_single_value("LMS Settings", "portal_course_creation") %} {% if portal_course_creation %}
<div class="tab-pane fade" id="courses-created" role="tabpanel" aria-labelledby="courses-created"> <div class="tab-pane fade" id="courses-created" role="tabpanel" aria-labelledby="courses-created">
{% include "school/templates/courses_created.html" %} {% include "school/templates/courses_created.html" %}
</div> </div>
@@ -29,4 +38,12 @@
</div> </div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script>
frappe.ready(() => {
$('#courses-tab a[data-toggle="tab"]').on('shown.bs.tab', (e) => {
let link = $("#create-course-link");
$(e.currentTarget).attr("href") == "#courses-created" ? link.removeClass("hide") : link.addClass("hide");
});
})
</script>
{% endblock %} {% endblock %}

View File

@@ -29,7 +29,7 @@
{% macro ProfileBanner(member) %} {% macro ProfileBanner(member) %}
{% set cover_image = member.cover_image if member.cover_image else "/assets/school/images/profile-banner.png" %} {% set cover_image = member.cover_image if member.cover_image else "/assets/school/images/profile-banner.png" %}
{% set enrollment = get_course_membership(member_type="Student") | length %} {% set enrollment = get_course_membership(frappe.session.user, member_type="Student") | length %}
{% set enrollment_suffix = _("Courses") if enrollment > 1 else _("Course") %} {% set enrollment_suffix = _("Courses") if enrollment > 1 else _("Course") %}
<div class="container"> <div class="container">
<div class="profile-banner" style="background-image: url({{ cover_image }})"> <div class="profile-banner" style="background-image: url({{ cover_image }})">