fix: minor issues
This commit is contained in:
@@ -28,9 +28,9 @@ order_by="creation") %}
|
|||||||
<div class="d-flex flex-column align-items-center font-weight-bold">
|
<div class="d-flex flex-column align-items-center font-weight-bold">
|
||||||
Want to join the discussion?
|
Want to join the discussion?
|
||||||
{% if frappe.session.user == "Guest" %}
|
{% if frappe.session.user == "Guest" %}
|
||||||
<div class="button is-primary" id="login-from-discussion">Log In</div>
|
<div class="button is-primary mt-5" id="login-from-discussion">Log In</div>
|
||||||
{% elif not condition %}
|
{% elif not condition %}
|
||||||
<div class="button is-primary" id="login-from-discussion" data-redirect="{{ redirect_to }}">{{ button_name }}</div>
|
<div class="button is-primary mt-5" id="login-from-discussion" data-redirect="{{ redirect_to }}">{{ button_name }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@@ -11,22 +11,7 @@
|
|||||||
{% set member = frappe.get_doc("User", exhibitor_doc.user) %}
|
{% set member = frappe.get_doc("User", exhibitor_doc.user) %}
|
||||||
|
|
||||||
<div class="common-card-style member-card">
|
<div class="common-card-style member-card">
|
||||||
{% set color = member.get_palette() %}
|
{{ widgets.Avatar(member=member, avatar_class="avatar-large")}}
|
||||||
<a class="button-links" href="/user/{{member.username}}">
|
|
||||||
<span class="avatar avatar-large" title="{{ member.full_name }}">
|
|
||||||
{% if member.user_image %}
|
|
||||||
<img class="avatar-frame standard-image" style="object-fit: cover;" src="{{ member.user_image }}"
|
|
||||||
title="{{ member.full_name }}">
|
|
||||||
</img>
|
|
||||||
{% else %}
|
|
||||||
<span class="avatar-frame standard-image" title="{{ member.full_name }}"
|
|
||||||
style="background-color: var({{color[0]}}); color: var({{color[1]}});">
|
|
||||||
{{ frappe.utils.get_abbr(member.full_name) }}
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="small-title member-card-title">
|
<div class="small-title member-card-title">
|
||||||
{{ member.full_name }}
|
{{ member.full_name }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,21 +10,7 @@
|
|||||||
{% set member = frappe.get_doc("User", speaker_doc.user) %}
|
{% set member = frappe.get_doc("User", speaker_doc.user) %}
|
||||||
|
|
||||||
<div class="common-card-style member-card">
|
<div class="common-card-style member-card">
|
||||||
{% set color = member.get_palette() %}
|
{{ widgets.Avatar(member=member, avatar_class="avatar-large") }}
|
||||||
<a class="button-links" href="/user/{{member.username}}">
|
|
||||||
<span class="avatar avatar-large" title="{{ member.full_name }}">
|
|
||||||
{% if member.user_image %}
|
|
||||||
<img class="avatar-frame standard-image" style="object-fit: cover;" src="{{ member.user_image }}"
|
|
||||||
title="{{ member.full_name }}">
|
|
||||||
</img>
|
|
||||||
{% else %}
|
|
||||||
<span class="avatar-frame standard-image" title="{{ member.full_name }}"
|
|
||||||
style="background-color: var({{color[0]}}); color: var({{color[1]}});">
|
|
||||||
{{ frappe.utils.get_abbr(member.full_name) }}
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="small-title member-card-title">
|
<div class="small-title member-card-title">
|
||||||
{{ member.full_name }}
|
{{ member.full_name }}
|
||||||
|
|||||||
@@ -20,23 +20,7 @@
|
|||||||
<div class="course-card-title">{{talk_doc.title}}</div>
|
<div class="course-card-title">{{talk_doc.title}}</div>
|
||||||
<div class="card-divider"></div>
|
<div class="card-divider"></div>
|
||||||
<div class="course-card-meta-2">
|
<div class="course-card-meta-2">
|
||||||
|
{{ widgets.Avatar(member=member, avatar_class="avatar-small")}}
|
||||||
{% set color = member.get_palette() %}
|
|
||||||
<a class="button-links" href="/user/{{member.username}}">
|
|
||||||
<span class="avatar avatar-small" title="{{ member.full_name }}">
|
|
||||||
{% if member.user_image %}
|
|
||||||
<img class="avatar-frame standard-image" style="object-fit: cover;" src="{{ member.user_image }}"
|
|
||||||
title="{{ member.full_name }}">
|
|
||||||
</img>
|
|
||||||
{% else %}
|
|
||||||
<span class="avatar-frame standard-image" title="{{ member.full_name }}"
|
|
||||||
style="background-color: var({{color[0]}}); color: var({{color[1]}});">
|
|
||||||
{{ frappe.utils.get_abbr(member.full_name) }}
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
|
|
||||||
<span class="course-instructor"> {{ member.full_name }} </span>
|
<span class="course-instructor"> {{ member.full_name }} </span>
|
||||||
<span class="small-title company-name"></span>
|
<span class="small-title company-name"></span>
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ web_include_css = "community.bundle.css"
|
|||||||
# Override standard doctype classes
|
# Override standard doctype classes
|
||||||
|
|
||||||
override_doctype_class = {
|
override_doctype_class = {
|
||||||
"User": "community.overrides.user.CustomUser"
|
"User": "community.overrides.user.CustomUser",
|
||||||
|
"Web Template": "community.overrides.web_template.CustomWebTemplate"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Document Events
|
# Document Events
|
||||||
@@ -130,7 +131,7 @@ fixtures = ["Custom Field"]
|
|||||||
# auto_cancel_exempted_doctypes = ["Auto Repeat"]
|
# auto_cancel_exempted_doctypes = ["Auto Repeat"]
|
||||||
|
|
||||||
# Add all simple route rules here
|
# Add all simple route rules here
|
||||||
primary_rules = [
|
website_route_rules = [
|
||||||
{"from_route": "/sketches/<sketch>", "to_route": "sketches/sketch"},
|
{"from_route": "/sketches/<sketch>", "to_route": "sketches/sketch"},
|
||||||
{"from_route": "/courses/<course>", "to_route": "courses/course"},
|
{"from_route": "/courses/<course>", "to_route": "courses/course"},
|
||||||
{"from_route": "/courses/<course>/<topic>", "to_route": "courses/topic"},
|
{"from_route": "/courses/<course>/<topic>", "to_route": "courses/topic"},
|
||||||
@@ -147,46 +148,9 @@ primary_rules = [
|
|||||||
{"from_route": "/courses/<course>/progress", "to_route": "batch/progress"},
|
{"from_route": "/courses/<course>/progress", "to_route": "batch/progress"},
|
||||||
{"from_route": "/courses/<course>/join", "to_route": "batch/join"},
|
{"from_route": "/courses/<course>/join", "to_route": "batch/join"},
|
||||||
{"from_route": "/discussions/<discussion>", "to_route": "discussions/discussion"},
|
{"from_route": "/discussions/<discussion>", "to_route": "discussions/discussion"},
|
||||||
|
{"from_route": "/user/<string(minlength=4):username>", "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": "/<string(minlength=4):username>", "to_route": "profiles/profile"},
|
|
||||||
]
|
|
||||||
|
|
||||||
website_route_rules = primary_rules + whitelist_rules + profile_rules
|
|
||||||
|
|
||||||
website_redirects = [
|
website_redirects = [
|
||||||
{"source": "/update-profile", "target": "/edit-profile"},
|
{"source": "/update-profile", "target": "/edit-profile"},
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -3,11 +3,6 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from ..lesson.lesson import update_progress
|
|
||||||
|
|
||||||
class ExerciseSubmission(Document):
|
class ExerciseSubmission(Document):
|
||||||
|
pass
|
||||||
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)
|
|
||||||
|
|||||||
@@ -93,41 +93,3 @@ def save_progress(lesson, course, status):
|
|||||||
}).save(ignore_permissions=True)
|
}).save(ignore_permissions=True)
|
||||||
course_details = frappe.get_doc("LMS Course", course)
|
course_details = frappe.get_doc("LMS Course", course)
|
||||||
return course_details.get_course_progress()
|
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
|
|
||||||
|
|||||||
@@ -35,14 +35,6 @@ class LMSBatch(Document):
|
|||||||
filters['member_type'] = member_type
|
filters['member_type'] = member_type
|
||||||
return frappe.db.exists("LMS Batch Membership", filters)
|
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):
|
def get_membership(self, email):
|
||||||
"""Returns the membership document of given user.
|
"""Returns the membership document of given user.
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
# Copyright (c) 2021, FOSS United and contributors
|
# Copyright (c) 2021, FOSS United and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from community.lms.doctype.lesson.lesson import update_progress
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
import json
|
import json
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from ..lesson.lesson import update_progress
|
|
||||||
|
|
||||||
class LMSQuiz(Document):
|
class LMSQuiz(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
|
|||||||
@@ -14,13 +14,14 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% set is_instructor = frappe.session.user == course.instructor %}
|
||||||
<div class="lessons">
|
<div class="lessons">
|
||||||
|
|
||||||
{% for lesson in course.get_lessons(chapter) %}
|
{% for lesson in course.get_lessons(chapter) %}
|
||||||
|
|
||||||
<div class="lesson-info{% if membership.current_lesson == lesson.name %} active-lesson {% endif %}">
|
<div class="lesson-info{% if membership.current_lesson == lesson.name %} active-lesson {% endif %}">
|
||||||
|
|
||||||
{% if membership or lesson.include_in_preview %}
|
{% if membership or lesson.include_in_preview or is_instructor %}
|
||||||
<a class="lesson-links" href="{{ course.get_learn_url(lesson.number) }}{{course.query_parameter}}"
|
<a class="lesson-links" href="{{ course.get_learn_url(lesson.number) }}{{course.query_parameter}}"
|
||||||
data-course="{{ course.name }}">
|
data-course="{{ course.name }}">
|
||||||
{{ lesson.title }}
|
{{ lesson.title }}
|
||||||
|
|||||||
15
community/overrides/web_template.py
Normal file
15
community/overrides/web_template.py
Normal file
@@ -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)
|
||||||
@@ -630,6 +630,10 @@ input[type=checkbox] {
|
|||||||
margin-bottom: 0.75rem;
|
margin-bottom: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.course-content-parent .chapter-description {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
.chapter-icon {
|
.chapter-icon {
|
||||||
margin-right: .25rem;
|
margin-right: .25rem;
|
||||||
}
|
}
|
||||||
@@ -1295,10 +1299,6 @@ pre {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.talk-link {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.speaker-cards-parent {
|
.speaker-cards-parent {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||||
|
|||||||
@@ -29,8 +29,9 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% set title = lesson.title + " - " + course.title %}
|
{% set title = lesson.title + " - " + course.title %}
|
||||||
|
{% set condition = membership or is_instructor %}
|
||||||
{{ widgets.DiscussionMessage(doctype="Lesson", docname=lesson.name,
|
{{ 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) }}
|
redirect_to="/courses/" + course.name) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -46,7 +47,9 @@
|
|||||||
<span class="lesson-progress {{hide if course.get_progress(lesson.name) != 'Complete' else ''}}">COMPLETED</span>
|
<span class="lesson-progress {{hide if course.get_progress(lesson.name) != 'Complete' else ''}}">COMPLETED</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% 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 %}
|
||||||
<div class="common-card-style lesson-content-card markdown-source">{{ lesson.render_html() }}</div>
|
<div class="common-card-style lesson-content-card markdown-source">{{ lesson.render_html() }}</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="common-card-style lesson-content-card">
|
<div class="common-card-style lesson-content-card">
|
||||||
|
|||||||
Reference in New Issue
Block a user