From eaec991f475fe14048797a6a3f98323353e593b9 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Thu, 19 Aug 2021 10:06:39 +0530 Subject: [PATCH 1/3] fix: chapter teaser drawer --- community/lms/widgets/ChapterTeaser.html | 18 ++++++++++++++++-- community/www/courses/course.js | 14 -------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/community/lms/widgets/ChapterTeaser.html b/community/lms/widgets/ChapterTeaser.html index 24433cd9..99156592 100644 --- a/community/lms/widgets/ChapterTeaser.html +++ b/community/lms/widgets/ChapterTeaser.html @@ -21,8 +21,7 @@
{% if membership or lesson.include_in_preview %} - {{ lesson.title }} @@ -56,6 +55,11 @@ diff --git a/community/www/courses/course.js b/community/www/courses/course.js index 4429816b..38dab23c 100644 --- a/community/www/courses/course.js +++ b/community/www/courses/course.js @@ -29,10 +29,6 @@ frappe.ready(() => { show_review_dialog(e); }); - $(".chapter-title").click((e) => { - rotate_chapter_icon(e); - }); - $(".icon-rating").click((e) => { highlight_rating(e); }); @@ -168,16 +164,6 @@ var show_review_dialog = (e) => { $("#review-modal").modal("show"); } -var rotate_chapter_icon = (e) => { - e.preventDefault(); - var icon = $(e.currentTarget).children(".chapter-icon"); - if (icon.css("transform") == "none") { - icon.css("transform", "rotate(90deg)"); - } else { - icon.css("transform", "none"); - } -} - var highlight_rating = (e) => { var rating = $(e.currentTarget).attr("data-rating"); $(".icon-rating").removeClass("star-click"); From c6d399438385f26385539d6c7b4553891a282640 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Fri, 20 Aug 2021 14:23:18 +0530 Subject: [PATCH 2/3] fix: course page --- community/lms/doctype/chapter/chapter.json | 14 ++++++- .../lms/doctype/lms_course/lms_course.js | 9 +++++ .../lms/doctype/lms_course/lms_course.json | 37 ++++++++++--------- .../lms/doctype/lms_course/lms_course.py | 2 + community/patches.txt | 1 + .../patches/v0_0/course_instructor_update.py | 7 ++++ community/www/courses/certificate.py | 4 +- community/www/courses/course.html | 2 +- community/www/discussions/__init__.py | 0 9 files changed, 54 insertions(+), 22 deletions(-) create mode 100644 community/patches/v0_0/course_instructor_update.py create mode 100644 community/www/discussions/__init__.py diff --git a/community/lms/doctype/chapter/chapter.json b/community/lms/doctype/chapter/chapter.json index ca5b3fa5..36ab38f5 100644 --- a/community/lms/doctype/chapter/chapter.json +++ b/community/lms/doctype/chapter/chapter.json @@ -8,7 +8,9 @@ "field_order": [ "course", "title", + "column_break_3", "description", + "section_break_5", "lessons" ], "fields": [ @@ -20,7 +22,7 @@ }, { "fieldname": "description", - "fieldtype": "Markdown Editor", + "fieldtype": "Small Text", "label": "Description" }, { @@ -35,6 +37,14 @@ "fieldtype": "Table", "label": "Lessons", "options": "Lessons" + }, + { + "fieldname": "column_break_3", + "fieldtype": "Column Break" + }, + { + "fieldname": "section_break_5", + "fieldtype": "Section Break" } ], "index_web_pages_for_search": 1, @@ -45,7 +55,7 @@ "link_fieldname": "chapter" } ], - "modified": "2021-07-27 16:28:08.667964", + "modified": "2021-08-19 13:43:51.025072", "modified_by": "Administrator", "module": "LMS", "name": "Chapter", diff --git a/community/lms/doctype/lms_course/lms_course.js b/community/lms/doctype/lms_course/lms_course.js index 3bcaaaab..d40f641e 100644 --- a/community/lms/doctype/lms_course/lms_course.js +++ b/community/lms/doctype/lms_course/lms_course.js @@ -4,6 +4,7 @@ frappe.ui.form.on('LMS Course', { onload: function (frm) { + frm.set_query("chapter", "chapters", function () { return { filters: { @@ -11,6 +12,14 @@ frappe.ui.form.on('LMS Course', { } }; }); + + frm.set_query("instructor", function (doc) { + return { + filters: { + "ignore_user_type": 1, + } + }; + }); } }); diff --git a/community/lms/doctype/lms_course/lms_course.json b/community/lms/doctype/lms_course/lms_course.json index 81f00238..82463ede 100644 --- a/community/lms/doctype/lms_course/lms_course.json +++ b/community/lms/doctype/lms_course/lms_course.json @@ -18,17 +18,18 @@ "video_link", "image", "column_break_3", + "instructor", "tags", + "section_break_7", "is_published", + "column_break_9", "upcoming", + "column_break_11", "disable_self_learning", "section_break_5", "short_introduction", "description", - "chapters", - "certification_section", - "enable_certification", - "expiry" + "chapters" ], "fields": [ { @@ -99,23 +100,25 @@ "options": "Chapters" }, { - "fieldname": "certification_section", + "fieldname": "instructor", + "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Instructor", + "options": "User" + }, + { + "fieldname": "section_break_7", "fieldtype": "Section Break", - "label": "Certification" + "label": "Course Settings" }, { - "default": "0", - "fieldname": "enable_certification", - "fieldtype": "Check", - "label": "Enable Certification" + "fieldname": "column_break_9", + "fieldtype": "Column Break" }, { - "default": "0", - "depends_on": "enable_certification", - "fieldname": "expiry", - "fieldtype": "Select", - "label": "Certification Expires After Years", - "options": "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10" + "fieldname": "column_break_11", + "fieldtype": "Column Break" } ], "index_web_pages_for_search": 1, @@ -137,7 +140,7 @@ "link_fieldname": "course" } ], - "modified": "2021-08-18 18:02:12.623807", + "modified": "2021-08-20 11:01:15.795219", "modified_by": "Administrator", "module": "LMS", "name": "LMS Course", diff --git a/community/lms/doctype/lms_course/lms_course.py b/community/lms/doctype/lms_course/lms_course.py index 126f6504..babbe45b 100644 --- a/community/lms/doctype/lms_course/lms_course.py +++ b/community/lms/doctype/lms_course/lms_course.py @@ -144,6 +144,8 @@ class LMSCourse(Document): return batch_name and frappe.get_doc("LMS Batch", batch_name) def get_instructor(self): + if self.instructor: + return frappe.get_doc("User", self.instructor) return frappe.get_doc("User", self.owner) def get_chapters(self): diff --git a/community/patches.txt b/community/patches.txt index 36d99e94..86c39f41 100644 --- a/community/patches.txt +++ b/community/patches.txt @@ -8,3 +8,4 @@ community.patches.replace_member_with_user_in_lms_message community.patches.replace_member_with_user_in_mentor_request community.patches.v0_0.chapter_lesson_index_table execute:frappe.delete_doc("DocType", "LMS Message") +community.patches.v0_0.course_instructor_update diff --git a/community/patches/v0_0/course_instructor_update.py b/community/patches/v0_0/course_instructor_update.py new file mode 100644 index 00000000..f8fd6019 --- /dev/null +++ b/community/patches/v0_0/course_instructor_update.py @@ -0,0 +1,7 @@ +import frappe + +def execute(): + frappe.reload_doc("lms", "doctype", "lms_course") + courses = frappe.get_all("LMS Course", fields=["name", "owner"]) + for course in courses: + frappe.db.set_value("LMS Course", course.name, "instructor", course.owner) diff --git a/community/www/courses/certificate.py b/community/www/courses/certificate.py index d734989f..aae2ba10 100644 --- a/community/www/courses/certificate.py +++ b/community/www/courses/certificate.py @@ -16,9 +16,9 @@ def get_context(context): redirect_to_course_list() context.course = frappe.db.get_value("LMS Course", course_name, - ["owner", "title", "name"], as_dict=True) + ["instructor", "title", "name"], as_dict=True) - context.instructor = frappe.db.get_value("User", context.course.owner, + context.instructor = frappe.db.get_value("User", context.course.instructor, ["full_name", "username"], as_dict=True) context.student = frappe.db.get_value("User", context.certificate.student, diff --git a/community/www/courses/course.html b/community/www/courses/course.html index a7437e5f..da0a9eae 100644 --- a/community/www/courses/course.html +++ b/community/www/courses/course.html @@ -43,7 +43,7 @@
- {% if not course.disable_self_learning and not membership %} + {% if not course.disable_self_learning and not membership and not course.upcoming %}
Start Learning diff --git a/community/www/discussions/__init__.py b/community/www/discussions/__init__.py new file mode 100644 index 00000000..e69de29b From 841819436af6b64ddcfd7f46100e5c69284932ee Mon Sep 17 00:00:00 2001 From: pateljannat Date: Mon, 23 Aug 2021 18:22:36 +0530 Subject: [PATCH 3/3] fix: minor issues --- .../community/widgets/DiscussionMessage.html | 4 +- .../exhibitor_section/exhibitor_section.html | 17 +------ .../speaker_section/speaker_section.html | 16 +------ .../talk_section/talk_section.html | 18 +------- community/hooks.py | 44 ++----------------- .../exercise_submission.py | 7 +-- community/lms/doctype/lesson/lesson.py | 38 ---------------- community/lms/doctype/lms_batch/lms_batch.py | 8 ---- community/lms/doctype/lms_quiz/lms_quiz.py | 2 - community/lms/widgets/ChapterTeaser.html | 3 +- community/overrides/web_template.py | 15 +++++++ community/public/css/style.css | 8 ++-- community/www/batch/learn.html | 7 ++- 13 files changed, 36 insertions(+), 151 deletions(-) create mode 100644 community/overrides/web_template.py diff --git a/community/community/widgets/DiscussionMessage.html b/community/community/widgets/DiscussionMessage.html index e1dc2c5b..7e16d966 100644 --- a/community/community/widgets/DiscussionMessage.html +++ b/community/community/widgets/DiscussionMessage.html @@ -28,9 +28,9 @@ order_by="creation") %}
Want to join the discussion? {% if frappe.session.user == "Guest" %} -
Log In
+
Log In
{% elif not condition %} -
{{ button_name }}
+
{{ button_name }}
{% endif %}
{% else %} diff --git a/community/event_management/web_template/exhibitor_section/exhibitor_section.html b/community/event_management/web_template/exhibitor_section/exhibitor_section.html index c43f6d55..94fc3684 100644 --- a/community/event_management/web_template/exhibitor_section/exhibitor_section.html +++ b/community/event_management/web_template/exhibitor_section/exhibitor_section.html @@ -11,22 +11,7 @@ {% set member = frappe.get_doc("User", exhibitor_doc.user) %}
- {% set color = member.get_palette() %} - - - {% if member.user_image %} - - - {% else %} - - {{ frappe.utils.get_abbr(member.full_name) }} - - {% endif %} - - - + {{ widgets.Avatar(member=member, avatar_class="avatar-large")}}
{{ member.full_name }}
diff --git a/community/event_management/web_template/speaker_section/speaker_section.html b/community/event_management/web_template/speaker_section/speaker_section.html index 84d6b3dc..ed35418a 100644 --- a/community/event_management/web_template/speaker_section/speaker_section.html +++ b/community/event_management/web_template/speaker_section/speaker_section.html @@ -10,21 +10,7 @@ {% set member = frappe.get_doc("User", speaker_doc.user) %}
- {% set color = member.get_palette() %} - - - {% if member.user_image %} - - - {% else %} - - {{ frappe.utils.get_abbr(member.full_name) }} - - {% endif %} - - + {{ widgets.Avatar(member=member, avatar_class="avatar-large") }}
{{ member.full_name }} diff --git a/community/event_management/web_template/talk_section/talk_section.html b/community/event_management/web_template/talk_section/talk_section.html index 5a98159b..77e9f3c0 100644 --- a/community/event_management/web_template/talk_section/talk_section.html +++ b/community/event_management/web_template/talk_section/talk_section.html @@ -20,23 +20,7 @@
{{talk_doc.title}}
- - {% set color = member.get_palette() %} - - - {% if member.user_image %} - - - {% else %} - - {{ frappe.utils.get_abbr(member.full_name) }} - - {% endif %} - - - + {{ widgets.Avatar(member=member, avatar_class="avatar-small")}} {{ member.full_name }} diff --git a/community/hooks.py b/community/hooks.py index 5b2ef4c1..7bb20ad0 100644 --- a/community/hooks.py +++ b/community/hooks.py @@ -85,7 +85,8 @@ web_include_css = "community.bundle.css" # Override standard doctype classes override_doctype_class = { - "User": "community.overrides.user.CustomUser" + "User": "community.overrides.user.CustomUser", + "Web Template": "community.overrides.web_template.CustomWebTemplate" } # Document Events @@ -130,7 +131,7 @@ fixtures = ["Custom Field"] # auto_cancel_exempted_doctypes = ["Auto Repeat"] # Add all simple route rules here -primary_rules = [ +website_route_rules = [ {"from_route": "/sketches/", "to_route": "sketches/sketch"}, {"from_route": "/courses/", "to_route": "courses/course"}, {"from_route": "/courses//", "to_route": "courses/topic"}, @@ -147,46 +148,9 @@ primary_rules = [ {"from_route": "/courses//progress", "to_route": "batch/progress"}, {"from_route": "/courses//join", "to_route": "batch/join"}, {"from_route": "/discussions/", "to_route": "discussions/discussion"}, + {"from_route": "/user/", "to_route": "profiles/profile"}, ] -# Any frappe default URL is blocked by profile-rules, add it here to unblock it -whitelist = [ - "/home", - "/login", - "/update-password", - "/update-profile", - "/third-party-apps", - "/website_script.js", - "/courses", - "/sketches", - "/admin", - "/socket.io", - "/hackathons", - "/dashboard", - "/join-request", - "/add-a-new-batch", - "/new-sign-up", - "/message", - "/about", - "/edit-profile", - "/attendee-registration", - "/speaker-registration", - "/event", - "/hello", - "/exhibitor-registration", - "/discussions", - "/propose-talk", - -] -whitelist_rules = [{"from_route": p, "to_route": p[1:]} for p in whitelist] - -# regex rule to match all profiles -profile_rules = [ - {"from_route": "/", "to_route": "profiles/profile"}, -] - -website_route_rules = primary_rules + whitelist_rules + profile_rules - website_redirects = [ {"source": "/update-profile", "target": "/edit-profile"}, ] diff --git a/community/lms/doctype/exercise_submission/exercise_submission.py b/community/lms/doctype/exercise_submission/exercise_submission.py index 886de170..d588281c 100644 --- a/community/lms/doctype/exercise_submission/exercise_submission.py +++ b/community/lms/doctype/exercise_submission/exercise_submission.py @@ -3,11 +3,6 @@ import frappe from frappe.model.document import Document -from ..lesson.lesson import update_progress class ExerciseSubmission(Document): - - def after_insert(self): - course_details = frappe.get_doc("LMS Course", self.course) - if not (course_details.is_mentor(frappe.session.user) or frappe.flags.in_test): - update_progress(self.lesson) + pass diff --git a/community/lms/doctype/lesson/lesson.py b/community/lms/doctype/lesson/lesson.py index 736fa6bd..d9426524 100644 --- a/community/lms/doctype/lesson/lesson.py +++ b/community/lms/doctype/lesson/lesson.py @@ -93,41 +93,3 @@ def save_progress(lesson, course, status): }).save(ignore_permissions=True) course_details = frappe.get_doc("LMS Course", course) return course_details.get_course_progress() - -def update_progress(lesson): - user = frappe.session.user - if not all_dynamic_content_submitted(lesson, user): - return - if frappe.db.exists("LMS Course Progress", {"lesson": lesson, "owner": user}): - course_progress = frappe.get_doc("LMS Course Progress", {"lesson": lesson, "owner": user}) - course_progress.status = "Complete" - course_progress.save(ignore_permissions=True) - -def all_dynamic_content_submitted(lesson, user): - all_exercises_submitted = check_all_exercise_submission(lesson, user) - all_quiz_submitted = check_all_quiz_submitted(lesson, user) - return all_exercises_submitted and all_quiz_submitted - -def check_all_exercise_submission(lesson, user): - exercise_names = frappe.get_list("Exercise", {"lesson": lesson}, pluck="name", ignore_permissions=True) - if not len(exercise_names): - return True - query = { - "exercise": ["in", exercise_names], - "owner": user - } - if frappe.db.count("Exercise Submission", query) == len(exercise_names): - return True - return False - -def check_all_quiz_submitted(lesson, user): - quizzes = frappe.get_list("LMS Quiz", {"lesson": lesson}, pluck="name", ignore_permissions=True) - if not len(quizzes): - return True - query = { - "quiz": ["in", quizzes], - "owner": user - } - if frappe.db.count("LMS Quiz Submission", query) == len(quizzes): - return True - return False diff --git a/community/lms/doctype/lms_batch/lms_batch.py b/community/lms/doctype/lms_batch/lms_batch.py index 6b870ff4..b2f8096b 100644 --- a/community/lms/doctype/lms_batch/lms_batch.py +++ b/community/lms/doctype/lms_batch/lms_batch.py @@ -35,14 +35,6 @@ class LMSBatch(Document): filters['member_type'] = member_type return frappe.db.exists("LMS Batch Membership", filters) - def get_messages(self): - messages = frappe.get_all("LMS Message", {"batch": self.name}, ["*"], order_by="creation") - for message in messages: - message.message = frappe.utils.md_to_html(message.message) - if message.author == frappe.session.user: - message.author_name = "You" - message.is_author = True - return messages def get_membership(self, email): """Returns the membership document of given user. diff --git a/community/lms/doctype/lms_quiz/lms_quiz.py b/community/lms/doctype/lms_quiz/lms_quiz.py index b1fe65a9..dd0b4809 100644 --- a/community/lms/doctype/lms_quiz/lms_quiz.py +++ b/community/lms/doctype/lms_quiz/lms_quiz.py @@ -1,12 +1,10 @@ # Copyright (c) 2021, FOSS United and contributors # For license information, please see license.txt -from community.lms.doctype.lesson.lesson import update_progress import frappe from frappe.model.document import Document import json from frappe import _ -from ..lesson.lesson import update_progress class LMSQuiz(Document): def validate(self): diff --git a/community/lms/widgets/ChapterTeaser.html b/community/lms/widgets/ChapterTeaser.html index 99156592..8a4f6c6e 100644 --- a/community/lms/widgets/ChapterTeaser.html +++ b/community/lms/widgets/ChapterTeaser.html @@ -14,13 +14,14 @@
{% endif %} + {% set is_instructor = frappe.session.user == course.instructor %}
{% for lesson in course.get_lessons(chapter) %}
- {% if membership or lesson.include_in_preview %} + {% if membership or lesson.include_in_preview or is_instructor %} {{ lesson.title }} diff --git a/community/overrides/web_template.py b/community/overrides/web_template.py new file mode 100644 index 00000000..9f36f4f9 --- /dev/null +++ b/community/overrides/web_template.py @@ -0,0 +1,15 @@ +import frappe +from frappe.website.doctype.web_template.web_template import WebTemplate +from community.widgets import Widgets +import json + +class CustomWebTemplate(WebTemplate): + + def render(self, values=None): + if not values: + values = {} + values = frappe.parse_json(values) + values.update({"values": values}) + values.update({"widgets": Widgets()}) + template = self.get_template(self.standard) + return frappe.render_template(template, values) diff --git a/community/public/css/style.css b/community/public/css/style.css index 63bce99e..dee90122 100644 --- a/community/public/css/style.css +++ b/community/public/css/style.css @@ -630,6 +630,10 @@ input[type=checkbox] { margin-bottom: 0.75rem; } +.course-content-parent .chapter-description { + font-size: 0.7rem; +} + .chapter-icon { margin-right: .25rem; } @@ -1295,10 +1299,6 @@ pre { font-weight: bold; } -a.talk-link { - text-decoration: none; -} - .speaker-cards-parent { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); diff --git a/community/www/batch/learn.html b/community/www/batch/learn.html index 4fbb8b4c..b593bb34 100644 --- a/community/www/batch/learn.html +++ b/community/www/batch/learn.html @@ -29,8 +29,9 @@ {% endif %} {% set title = lesson.title + " - " + course.title %} + {% set condition = membership or is_instructor %} {{ widgets.DiscussionMessage(doctype="Lesson", docname=lesson.name, - title=title, condition=membership, button_name="Start Learning", + title=title, condition=condition, button_name="Start Learning", redirect_to="/courses/" + course.name) }}
@@ -46,7 +47,9 @@ COMPLETED
- {% if membership or lesson.include_in_preview %} + {% set is_instructor = frappe.session.user == course.instructor %} + + {% if membership or lesson.include_in_preview or is_instructor %}
{{ lesson.render_html() }}
{% else %}