diff --git a/lms/hooks.py b/lms/hooks.py
index 4f2589f8..3e1e92d2 100644
--- a/lms/hooks.py
+++ b/lms/hooks.py
@@ -191,7 +191,8 @@ jinja = {
"lms.lms.utils.get_signup_optin_checks",
"lms.lms.utils.get_popular_courses",
"lms.lms.utils.format_amount",
- "lms.lms.utils.first_lesson_exists"
+ "lms.lms.utils.first_lesson_exists",
+ "lms.lms.utils.has_course_instructor_role"
],
"filters": []
}
diff --git a/lms/lms/doctype/lms_quiz/test_lms_quiz.py b/lms/lms/doctype/lms_quiz/test_lms_quiz.py
index e778aab8..ef004896 100644
--- a/lms/lms/doctype/lms_quiz/test_lms_quiz.py
+++ b/lms/lms/doctype/lms_quiz/test_lms_quiz.py
@@ -15,7 +15,7 @@ class TestLMSQuiz(unittest.TestCase):
}).save(ignore_permissions=True)
def test_with_multiple_options(self):
- quiz = frappe.get_doc("LMS Quiz", "Test Quiz")
+ quiz = frappe.get_doc("LMS Quiz", "test-quiz")
quiz.append("questions", {
"question": "Question multiple",
"option_1": "Option 1",
@@ -27,7 +27,7 @@ class TestLMSQuiz(unittest.TestCase):
self.assertTrue(quiz.questions[0].multiple)
def test_with_no_correct_option(self):
- quiz = frappe.get_doc("LMS Quiz", "Test Quiz")
+ quiz = frappe.get_doc("LMS Quiz", "test-quiz")
quiz.append("questions", {
"question": "Question no correct option",
"option_1": "Option 1",
@@ -37,5 +37,5 @@ class TestLMSQuiz(unittest.TestCase):
@classmethod
def tearDownClass(cls) -> None:
- frappe.db.delete("LMS Quiz", "Test Quiz")
- frappe.db.delete("LMS Quiz Question", {"parent": "Test Quiz"})
+ frappe.db.delete("LMS Quiz", "test-quiz")
+ frappe.db.delete("LMS Quiz Question", {"parent": "test-quiz"})
diff --git a/lms/lms/doctype/lms_settings/lms_settings.json b/lms/lms/doctype/lms_settings/lms_settings.json
index afbbbc1a..5e0fbbe9 100644
--- a/lms/lms/doctype/lms_settings/lms_settings.json
+++ b/lms/lms/doctype/lms_settings/lms_settings.json
@@ -6,8 +6,8 @@
"engine": "InnoDB",
"field_order": [
"show_search",
- "portal_course_creation",
"force_profile_completion",
+ "portal_course_creation",
"column_break_2",
"search_placeholder",
"custom_certificate_template",
@@ -110,10 +110,11 @@
"fieldtype": "Column Break"
},
{
- "default": "0",
+ "default": "Course Instructor Role",
"fieldname": "portal_course_creation",
- "fieldtype": "Check",
- "label": "Enable Course Creation from Portal"
+ "fieldtype": "Select",
+ "label": "Course Creation Access Through Website To",
+ "options": "Course Instructor Role\nAnyone"
},
{
"fieldname": "column_break_9",
@@ -149,7 +150,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
- "modified": "2022-05-09 09:55:24.519269",
+ "modified": "2022-08-22 10:02:59.988499",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Settings",
diff --git a/lms/lms/utils.py b/lms/lms/utils.py
index 88f617c1..c8c8e28a 100644
--- a/lms/lms/utils.py
+++ b/lms/lms/utils.py
@@ -400,3 +400,10 @@ def first_lesson_exists(course):
def redirect_to_courses_list():
frappe.local.flags.redirect_location = "/courses"
raise frappe.Redirect
+
+
+def has_course_instructor_role():
+ return frappe.db.get_value("Has Role", {
+ "parent": frappe.session.user,
+ "role": "Course Instructor"
+ }, "name")
diff --git a/lms/patches.txt b/lms/patches.txt
index b8c513c6..8014a7a6 100644
--- a/lms/patches.txt
+++ b/lms/patches.txt
@@ -30,3 +30,4 @@ lms.patches.v0_0.move_certification_to_certificate
lms.patches.v0_0.quiz_submission_member
lms.patches.v0_0.delete_old_module_docs #08-07-2022
lms.patches.v0_0.delete_course_web_forms
+lms.patches.v0_0.create_course_instructor_role
diff --git a/lms/patches/v0_0/create_course_instructor_role.py b/lms/patches/v0_0/create_course_instructor_role.py
new file mode 100644
index 00000000..25f5bd91
--- /dev/null
+++ b/lms/patches/v0_0/create_course_instructor_role.py
@@ -0,0 +1,10 @@
+import frappe
+
+def execute():
+ if not frappe.db.exists("Role", "Course Instructor"):
+ role = frappe.get_doc({
+ "doctype": "Role",
+ "role_name": "Course Instructor",
+ "home_page": "/dashboard",
+ })
+ role.save(ignore_permissions=True)
diff --git a/lms/public/css/style.css b/lms/public/css/style.css
index c0c223a4..4060b8d6 100644
--- a/lms/public/css/style.css
+++ b/lms/public/css/style.css
@@ -944,7 +944,7 @@ pre {
float: right;
width: 80%;
display: flex;
- justify-content: end;
+ justify-content: flex-end;
align-items: center;
}
diff --git a/lms/public/js/common_functions.js b/lms/public/js/common_functions.js
index c44dcb9e..abfd3fcb 100644
--- a/lms/public/js/common_functions.js
+++ b/lms/public/js/common_functions.js
@@ -109,7 +109,7 @@ const add_chapter = (e) => {
return;
}
- let next_index = $("[data-index]").last().data("index") || 1;
+ let next_index = $("[data-index]").last().data("index") + 1 || 1;
let add_after = $(`.chapter-parent:last`).length ? $(`.chapter-parent:last`) : $("#outline-heading");
console.log(add_after)
$(`
diff --git a/lms/templates/courses_created.html b/lms/templates/courses_created.html
index 5b18e173..a219ebe1 100644
--- a/lms/templates/courses_created.html
+++ b/lms/templates/courses_created.html
@@ -1,23 +1,20 @@
{% set courses = get_authored_courses(frappe.session.user, only_published=False) %}
+
{% if courses | length %}
- {% for course in courses %}
- {{ widgets.CourseCard(course=course) }}
- {% endfor %}
+ {% for course in courses %}
+ {{ widgets.CourseCard(course=course) }}
+ {% endfor %}
+
{% else %}
-
-

-
-
-
{{ _("No courses created") }}
-
{{ _("Help others learn something new.") }}
-
-
+
+

+
+
+
{{ _("No courses created") }}
+
{{ _("Help others learn something new.") }}
+
{% endif %}
diff --git a/lms/templates/quiz.html b/lms/templates/quiz.html
index a2e885e6..83b67185 100644
--- a/lms/templates/quiz.html
+++ b/lms/templates/quiz.html
@@ -5,7 +5,8 @@
{{ _("Your latest score is {0}.").format(last_attempt_score) }}
{% else %}
-{{ quiz.title }}
+{{ quiz.title }}
diff --git a/lms/templates/search_course/search_course.html b/lms/templates/search_course/search_course.html
index b9fb5900..43dd100d 100644
--- a/lms/templates/search_course/search_course.html
+++ b/lms/templates/search_course/search_course.html
@@ -1,19 +1,22 @@
-{% set show_search = frappe.db.get_single_value("LMS Settings", "show_search") %}
{% set search_placeholder = frappe.db.get_single_value("LMS Settings", "search_placeholder") %}
+{% set portal_course_creation = frappe.db.get_single_value("LMS Settings", "portal_course_creation") %}
-{% if show_search %}
-
+
-
×
-
-

-
-
-
{{ _("No results found") }}
-
{{ _("Try some other keyword or explore our list of courses.") }}
-
+
×
+
+

+
+
+
{{ _("No results found") }}
+
{{ _("Try some other keyword or explore our list of courses.") }}
+
-{% endif %}
diff --git a/lms/www/batch/learn.html b/lms/www/batch/learn.html
index fdb5d9a7..b7de690b 100644
--- a/lms/www/batch/learn.html
+++ b/lms/www/batch/learn.html
@@ -185,7 +185,9 @@
+ {% if lesson.name %}
+ {% endif %}
{{ _("Create a Quiz") }}
diff --git a/lms/www/batch/learn.js b/lms/www/batch/learn.js
index a6227e2f..1fb8facf 100644
--- a/lms/www/batch/learn.js
+++ b/lms/www/batch/learn.js
@@ -1,6 +1,6 @@
frappe.ready(() => {
- localStorage.removeItem($("#quiz-title").text());
+ localStorage.removeItem($("#quiz-title").data("name"));
fetch_assignments();
@@ -200,8 +200,9 @@ const move_to_next_lesson = (status, e) => {
const quiz_summary = (e=undefined) => {
e && e.preventDefault();
- let quiz_name = $("#quiz-title").text();
+ let quiz_name = $("#quiz-title").data("name");
let total_questions = $(".question").length;
+
frappe.call({
method: "lms.lms.doctype.lms_quiz.lms_quiz.quiz_summary",
args: {
@@ -230,7 +231,6 @@ const check_answer = (e=undefined) => {
e && e.preventDefault();
clearInterval(self.timer);
$(".timer").addClass("hide");
- let quiz_name = $("#quiz-title").text();
let total_questions = $(".question").length;
let current_index = $(".active-question").attr("data-qt-index");
@@ -249,7 +249,7 @@ const check_answer = (e=undefined) => {
$("#next").removeClass("hide");
}
let [answer, is_correct] = parse_options();
- add_to_local_storage(quiz_name, current_index, answer, is_correct);
+ add_to_local_storage(current_index, answer, is_correct);
};
@@ -285,13 +285,16 @@ const add_icon = (element, icon) => {
};
-const add_to_local_storage = (quiz_name, current_index, answer, is_correct) => {
+const add_to_local_storage = (current_index, answer, is_correct) => {
+ let quiz_name = $("#quiz-title").data("name")
let quiz_stored = JSON.parse(localStorage.getItem(quiz_name));
+
let quiz_obj = {
"question_index": current_index,
"answer": answer.join(),
"is_correct": is_correct
}
+
quiz_stored ? quiz_stored.push(quiz_obj) : quiz_stored = [quiz_obj]
localStorage.setItem(quiz_name, JSON.stringify(quiz_stored))
};
diff --git a/lms/www/batch/learn.py b/lms/www/batch/learn.py
index 4e705d17..b3f59b76 100644
--- a/lms/www/batch/learn.py
+++ b/lms/www/batch/learn.py
@@ -24,16 +24,17 @@ def get_context(context):
context.lesson = get_current_lesson_details(lesson_number, context)
if not context.lesson:
- context.lessom = frappe._dict()
+ context.lesson = frappe._dict()
if frappe.form_dict.get("edit"):
if not is_instructor(context.course.name):
redirect_to_courses_list()
context.lesson.edit_mode = True
+ else:
+ neighbours = get_neighbours(lesson_number, context.lessons)
+ context.next_url = get_url(neighbours["next"], context.course)
+ context.prev_url = get_url(neighbours["prev"], context.course)
- neighbours = get_neighbours(lesson_number, context.lessons)
- context.next_url = get_url(neighbours["next"], context.course)
- context.prev_url = get_url(neighbours["prev"], context.course)
meta_info = context.lesson.title + " - " + context.course.title if context.lesson.title else "New Lesson"
context.metatags = {
"title": meta_info,
@@ -52,8 +53,13 @@ def get_context(context):
def get_current_lesson_details(lesson_number, context):
details_list = list(filter(lambda x: cstr(x.number) == lesson_number, context.lessons))
+
if not len(details_list):
- redirect_to_lesson(context.course)
+ if frappe.form_dict.get("edit"):
+ return None
+ else:
+ redirect_to_lesson(context.course)
+
lesson_info = details_list[0]
lesson_info.body = lesson_info.body.replace("\"", "'")
return lesson_info
diff --git a/lms/www/courses/course.html b/lms/www/courses/course.html
index 1e5f9e2a..252eb8ba 100644
--- a/lms/www/courses/course.html
+++ b/lms/www/courses/course.html
@@ -188,10 +188,13 @@ data-placeholder="Description">{% if course.description %}{{ frappe.utils.md_to_
{% if course.edit_mode %}
+ {{ _("Save Course Details") }}
+
+ {% if course.name %}
{{ _("Back to Course") }}
+ {% endif %}
{% endif %}
{% endmacro %}
diff --git a/lms/www/courses/index.html b/lms/www/courses/index.html
index 03c49fec..10dc5dd7 100644
--- a/lms/www/courses/index.html
+++ b/lms/www/courses/index.html
@@ -15,11 +15,7 @@
{% else %}
-
-
+ {% include "lms/templates/search_course/search_course.html" %}
{% set courses = live_courses %}
diff --git a/lms/www/dashboard/index.html b/lms/www/dashboard/index.html
index bd37483e..1f6e5855 100644
--- a/lms/www/dashboard/index.html
+++ b/lms/www/dashboard/index.html
@@ -2,48 +2,48 @@
{% block title %}{{ _("Dashboard")}}
{% endblock %}
+
{% block content %}
{% set portal_course_creation = frappe.db.get_single_value("LMS Settings", "portal_course_creation") %}
+{% set show_creators_section = portal_course_creation == "Anyone" or has_course_instructor_role() %}
+