Merge pull request #375 from pateljannat/fixes

This commit is contained in:
Jannat Patel
2022-09-14 20:42:54 +05:30
committed by GitHub
8 changed files with 180 additions and 195 deletions

View File

@@ -114,7 +114,8 @@
], ],
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"links": [], "links": [],
"modified": "2022-07-28 13:41:29.224332", "make_attachments_public": 1,
"modified": "2022-09-14 12:47:20.840223",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Job", "module": "Job",
"name": "Job Opportunity", "name": "Job Opportunity",

View File

@@ -260,7 +260,8 @@
"link_fieldname": "course" "link_fieldname": "course"
} }
], ],
"modified": "2022-05-19 16:59:21.933367", "make_attachments_public": 1,
"modified": "2022-09-14 13:26:53.153822",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "LMS", "module": "LMS",
"name": "LMS Course", "name": "LMS Course",

View File

@@ -9,12 +9,14 @@ from ...utils import generate_slug
from frappe.utils import flt, cint from frappe.utils import flt, cint
from lms.lms.utils import get_chapters from lms.lms.utils import get_chapters
class LMSCourse(Document): class LMSCourse(Document):
def validate(self): def validate(self):
self.validate_instructors() self.validate_instructors()
self.validate_status() self.validate_status()
def validate_instructors(self): def validate_instructors(self):
if self.is_new() and not self.instructors: if self.is_new() and not self.instructors:
frappe.get_doc({ frappe.get_doc({
@@ -25,14 +27,17 @@ class LMSCourse(Document):
"parenttype": "LMS Course" "parenttype": "LMS Course"
}).save(ignore_permissions=True) }).save(ignore_permissions=True)
def validate_status(self): def validate_status(self):
if self.published: if self.published:
self.status = "Approved" self.status = "Approved"
def on_update(self): def on_update(self):
if not self.upcoming and self.has_value_changed("upcoming"): if not self.upcoming and self.has_value_changed("upcoming"):
self.send_email_to_interested_users() self.send_email_to_interested_users()
def send_email_to_interested_users(self): def send_email_to_interested_users(self):
interested_users = frappe.get_all("LMS Course Interest", { interested_users = frappe.get_all("LMS Course Interest", {
"course": self.name "course": self.name
@@ -67,6 +72,7 @@ class LMSCourse(Document):
def __repr__(self): def __repr__(self):
return f"<Course#{self.name}>" return f"<Course#{self.name}>"
def has_mentor(self, email): def has_mentor(self, email):
"""Checks if this course has a mentor with given email. """Checks if this course has a mentor with given email.
""" """
@@ -76,6 +82,7 @@ class LMSCourse(Document):
mapping = frappe.get_all("LMS Course Mentor Mapping", {"course": self.name, "mentor": email}) mapping = frappe.get_all("LMS Course Mentor Mapping", {"course": self.name, "mentor": email})
return mapping != [] return mapping != []
def add_mentor(self, email): def add_mentor(self, email):
"""Adds a new mentor to the course. """Adds a new mentor to the course.
""" """
@@ -96,7 +103,6 @@ class LMSCourse(Document):
doc.insert() doc.insert()
def get_student_batch(self, email): def get_student_batch(self, email):
"""Returns the batch the given student is part of. """Returns the batch the given student is part of.
@@ -115,6 +121,7 @@ class LMSCourse(Document):
fieldname="batch") fieldname="batch")
return batch_name and frappe.get_doc("LMS Batch", batch_name) return batch_name and frappe.get_doc("LMS Batch", batch_name)
def get_batches(self, mentor=None): def get_batches(self, mentor=None):
batches = frappe.get_all("LMS Batch", {"course": self.name}) batches = frappe.get_all("LMS Batch", {"course": self.name})
if mentor: if mentor:
@@ -126,17 +133,21 @@ class LMSCourse(Document):
batch_names = {m.batch for m in memberships} batch_names = {m.batch for m in memberships}
return [b for b in batches if b.name in batch_names] return [b for b in batches if b.name in batch_names]
def get_cohorts(self): def get_cohorts(self):
return frappe.get_all("Cohort", {"course": self.name}, order_by="creation") return frappe.get_all("Cohort", {"course": self.name}, order_by="creation")
def get_cohort(self, cohort_slug): def get_cohort(self, cohort_slug):
name = frappe.get_value("Cohort", {"course": self.name, "slug": cohort_slug}) name = frappe.get_value("Cohort", {"course": self.name, "slug": cohort_slug})
return name and frappe.get_doc("Cohort", name) return name and frappe.get_doc("Cohort", name)
def reindex_exercises(self): def reindex_exercises(self):
for i, c in enumerate(get_chapters(self.name), start=1): for i, c in enumerate(get_chapters(self.name), start=1):
self._reindex_exercises_in_chapter(c, i) self._reindex_exercises_in_chapter(c, i)
def _reindex_exercises_in_chapter(self, c, index): def _reindex_exercises_in_chapter(self, c, index):
i = 1 i = 1
for lesson in self.get_lessons(c): for lesson in self.get_lessons(c):
@@ -146,12 +157,14 @@ class LMSCourse(Document):
exercise.save() exercise.save()
i += 1 i += 1
def get_all_memberships(self, member): def get_all_memberships(self, member):
all_memberships = frappe.get_all("LMS Batch Membership", {"member": member, "course": self.name}, ["batch"]) all_memberships = frappe.get_all("LMS Batch Membership", {"member": member, "course": self.name}, ["batch"])
for membership in all_memberships: for membership in all_memberships:
membership.batch_title = frappe.db.get_value("LMS Batch", membership.batch, "title") membership.batch_title = frappe.db.get_value("LMS Batch", membership.batch, "title")
return all_memberships return all_memberships
@frappe.whitelist() @frappe.whitelist()
def reindex_exercises(doc): def reindex_exercises(doc):
course_data = json.loads(doc) course_data = json.loads(doc)
@@ -159,6 +172,7 @@ def reindex_exercises(doc):
course.reindex_exercises() course.reindex_exercises()
frappe.msgprint("All exercises in this course have been re-indexed.") frappe.msgprint("All exercises in this course have been re-indexed.")
@frappe.whitelist(allow_guest=True) @frappe.whitelist(allow_guest=True)
def search_course(text): def search_course(text):
search_courses = [] search_courses = []
@@ -184,6 +198,7 @@ def search_course(text):
return courses return courses
@frappe.whitelist() @frappe.whitelist()
def submit_for_review(course): def submit_for_review(course):
chapters = frappe.get_all("Chapter Reference", {"parent": course}) chapters = frappe.get_all("Chapter Reference", {"parent": course})
@@ -209,8 +224,8 @@ def save_course(tags, title, short_introduction, video_link, description, course
"image": image, "image": image,
"description": description, "description": description,
"tags": tags, "tags": tags,
"published": published, "published": cint(published),
"upcoming": upcoming "upcoming": cint(upcoming)
}) })
doc.save(ignore_permissions=True) doc.save(ignore_permissions=True)
return doc.name return doc.name

View File

@@ -9,7 +9,7 @@
</span> </span>
{% elif not is_instructor(course.name) and frappe.session.user == "Guest" %} {% elif not is_instructor(course.name) and frappe.session.user == "Guest" %}
<a class="btn btn-secondary btn-s pull-rightm" href="/login?redirect-to=/courses/{{ course.name }}"> {{ _("Login") }} </a> <a class="btn btn-secondary btn-s pull-rightm" href="/login?redirect-to=/courses/{{ course.name }}"> {{ _("Login") }} </a>
{% elif not is_instructor(course.name) and not membership %} {% elif not is_instructor(course.name) and not membership and course.status == "Approved" %}
<div class="btn btn-secondary btn-sm join-batch pull-right" data-course="{{ course.name | urlencode }}"> {{ _("Start Learning") }} </div> <div class="btn btn-secondary btn-sm join-batch pull-right" data-course="{{ course.name | urlencode }}"> {{ _("Start Learning") }} </div>
{% endif %} {% endif %}
</div> </div>

View File

@@ -1545,7 +1545,7 @@ li {
} }
} }
[contenteditable] { [contenteditable="true"] {
outline: none; outline: none;
background-color: var(--bg-light-gray); background-color: var(--bg-light-gray);
border-radius: var(--border-radius); border-radius: var(--border-radius);
@@ -1554,7 +1554,7 @@ li {
color: var(--gray-900); color: var(--gray-900);
} }
[contenteditable]:empty:before { [contenteditable="true"]:empty:before {
content: attr(data-placeholder); content: attr(data-placeholder);
color: var(--gray-600); color: var(--gray-600);
} }
@@ -1592,7 +1592,7 @@ li {
padding: 0.5rem 0; padding: 0.5rem 0;
} }
.course-card-pills[contenteditable] { .course-card-pills[contenteditable="true"] {
box-shadow: none; box-shadow: none;
} }

View File

@@ -26,7 +26,7 @@
{{ instructors }} {{ instructors }}
</div> </div>
<hr style="margin: 0.5rem 0;"> <hr style="margin: 0.5rem 0;">
<div> {{ _("Course Instructor") }} </div> <div class="text-center"> {{ _("Course Instructor") }} </div>
</div> </div>
{% endif %} {% endif %}
@@ -36,7 +36,7 @@
{{ frappe.utils.format_date(certificate.expiry_date, "medium") }} {{ frappe.utils.format_date(certificate.expiry_date, "medium") }}
</div> </div>
<hr style="margin: 0.5rem 0;"> <hr style="margin: 0.5rem 0;">
<div> {{ _("Expiry date") }} </div> <div class="text-center"> {{ _("Expiry date") }} </div>
</div> </div>
{% endif %} {% endif %}
</div> </div>

View File

@@ -73,4 +73,4 @@ def get_user_interest(course):
def show_start_learing_cta(course, membership, restriction): def show_start_learing_cta(course, membership, restriction):
return not course.disable_self_learning and not membership and not course.upcoming and not restriction.get("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) and course.status == "Approved"

View File

@@ -53,14 +53,16 @@
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id="profile" role="tabpanel" aria-labelledby="profile"> <div class="tab-pane active" id="profile" role="tabpanel" aria-labelledby="profile">
{{ About(member) }} <div class="common-card-style column-card mt-5">
{{ EducationDetails(member) }} {{ About(member) }}
{{ WorkDetails(member) }} {{ EducationDetails(member) }}
{{ ExternalCertification(member) }} {{ WorkDetails(member) }}
{{ Contact(member) }} {{ ExternalCertification(member) }}
{{ Skills(member) }} {{ Contact(member) }}
{{ CareerPreference(member) }} {{ Skills(member) }}
{{ ProfileTabs(profile_tabs) }} {{ CareerPreference(member) }}
{{ ProfileTabs(profile_tabs) }}
</div>
</div> </div>
{% if courses_created | length %} {% if courses_created | length %}
@@ -91,7 +93,7 @@
<!-- Banner --> <!-- Banner -->
{% macro ProfileBanner(member) %} {% macro ProfileBanner(member) %}
{% set cover_image = member.cover_image if member.cover_image else "/assets/lms/images/profile-banner.png" %} {% set cover_image = member.cover_image if member.cover_image else "/assets/lms/images/profile-banner.png" %}
{% set enrollment = get_course_membership(None, member_type="Student") | length %} {% set enrollment = get_course_membership(member.name, 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">
@@ -194,236 +196,202 @@
<!-- About Section --> <!-- About Section -->
{% macro About(member) %} {% macro About(member) %}
<div class="education-details"> <div class="course-home-headings"> {{ _("About") }} </div>
<div class="common-card-style column-card"> <div class="description">
<div class="course-home-headings"> {{ _("About") }} </div> {% if member.bio %}
<div class="description"> {{ member.bio }}
{% if member.bio %} {% else %}
{{ member.bio }} {{ _("Hey, my name is ") }} {{ member.full_name }}
{% else %} {% endif %}
{{ _("Hey, my name is ") }} {{ member.full_name }}
{% endif %}
</div>
</div>
</div> </div>
{% endmacro %} {% endmacro %}
<!-- Work Preference --> <!-- Work Preference -->
{% macro WorkPreference(member) %} {% macro WorkPreference(member) %}
<div class="education-details"> <div class="course-home-headings mt-10"> {{ _("Work Preference") }} </div>
<div class="common-card-style column-card"> <div> {{ member.attire }} </div>
<div class="course-home-headings"> {{ _("Work Preference") }} </div> <div> {{ member.collaboration }} </div>
<div> {{ member.attire }} </div> <div> {{ member.role }} </div>
<div> {{ member.collaboration }} </div> <div> {{ member.location_preference }} </div>
<div> {{ member.role }} </div> <div> {{ member.time }} </div>
<div> {{ member.location_preference }} </div> <div> {{ member.company_type }} </div>
<div> {{ member.time }} </div>
<div> {{ member.company_type }} </div>
</div>
</div>
{% endmacro %} {% endmacro %}
<!-- Career Preference --> <!-- Career Preference -->
{% macro CareerPreference(member) %} {% macro CareerPreference(member) %}
{% if member.preferred_functions or member.preferred_industries or member.preferred_location or member.dream_companies %} {% if member.preferred_functions or member.preferred_industries or member.preferred_location or member.dream_companies %}
<div class="education-details"> <div class="course-home-headings mt-10"> {{ _("Career Preference") }} </div>
<div class="common-card-style column-card"> <div class="profile-column-grid">
<div class="course-home-headings"> {{ _("Career Preference") }} </div>
<div class="profile-column-grid">
{% if member.preferred_functions | length %}
<div>
<b>{{ _("Preferred Functions:") }}</b>
{% for function in member.preferred_functions %}
<div class="description">{{ function.function }}</div>
{% endfor %}
</div>
{% endif %}
{% if member.preferred_industries | length %}
<div>
<b>{{ _("Preferred Industries:") }}</b>
{% for industry in member.preferred_industries %}
<div class="description">{{ industry.industry }}</div>
{% endfor %}
</div>
{% endif %}
{% if member.preferred_location %}
<div>
<b> {{ _("Preferred Locations:") }} </b>
<div class="description"> {{ member.preferred_location }} </div>
</div>
{% endif %}
{% if member.dream_companies %}
<div>
<b> {{ _("Dream Companies:") }} </b>
<div class="description"> {{ member.dream_companies }} </div>
</div>
{% endif %}
{% if member.preferred_functions | length %}
<div>
<b>{{ _("Preferred Functions:") }}</b>
{% for function in member.preferred_functions %}
<div class="description">{{ function.function }}</div>
{% endfor %}
</div> </div>
{% endif %}
{% if member.preferred_industries | length %}
<div>
<b>{{ _("Preferred Industries:") }}</b>
{% for industry in member.preferred_industries %}
<div class="description">{{ industry.industry }}</div>
{% endfor %}
</div>
{% endif %}
{% if member.preferred_location %}
<div>
<b> {{ _("Preferred Locations:") }} </b>
<div class="description"> {{ member.preferred_location }} </div>
</div>
{% endif %}
{% if member.dream_companies %}
<div>
<b> {{ _("Dream Companies:") }} </b>
<div class="description"> {{ member.dream_companies }} </div>
</div>
{% endif %}
</div> </div>
</div> {% endif %}
{% endif %}
{% endmacro %} {% endmacro %}
<!-- Contact Section --> <!-- Contact Section -->
{% macro Contact(member) %} {% macro Contact(member) %}
{% if member.linkedin or member.medium or member.github %} {% if member.linkedin or member.medium or member.github %}
<div class="education-details"> <div class="course-home-headings mt-10"> {{ _("Contact") }} </div>
<div class="common-card-style column-card"> <div class="profile-column-grid">
<div class="course-home-headings"> {{ _("Contact") }} </div> {% if member.linkedin %}
<div class="profile-column-grid"> {% set linkedin = member.linkedin[:-1] if member.linkedin[-1] == "/" else member.linkedin %}
{% if member.linkedin %} <a class="button-links description" href="{{ member.linkedin }}">
{% set linkedin = member.linkedin[:-1] if member.linkedin[-1] == "/" else member.linkedin %} <img src="/assets/lms/icons/linkedin.svg"> {{ linkedin.split("/")[-1] }}
<a class="button-links description" href="{{ member.linkedin }}"> </a>
<img src="/assets/lms/icons/linkedin.svg"> {{ linkedin.split("/")[-1] }} {% endif %}
</a>
{% endif %}
{% if member.medium %} {% if member.medium %}
<a class="button-links description" href="{{ member.medium}}"> <a class="button-links description" href="{{ member.medium}}">
<img src="/assets/lms/icons/medium.svg"> {{ member.medium.split("/")[-1] }} <img src="/assets/lms/icons/medium.svg"> {{ member.medium.split("/")[-1] }}
</a> </a>
{% endif %} {% endif %}
{% if member.github %} {% if member.github %}
<a class="button-links description" href="{{ member.github }}"> <a class="button-links description" href="{{ member.github }}">
<img src="/assets/lms/icons/github.svg"> {{ member.github.split("/")[-1] }} <img src="/assets/lms/icons/github.svg"> {{ member.github.split("/")[-1] }}
</a> </a>
{% endif %} {% endif %}
</div>
</div> </div>
</div> {% endif %}
{% endif %}
{% endmacro %} {% endmacro %}
<!-- Skills --> <!-- Skills -->
{% macro Skills(member) %} {% macro Skills(member) %}
{% if member.skill | length %} {% if member.skill | length %}
<div class="education-details"> <div class="course-home-headings mt-10"> {{ _("Skills")}} </div>
<div class="common-card-style column-card"> <div class="profile-column-grid">
<div class="course-home-headings"> {{ _("Skills")}} </div> {% for skill in member.skill %}
<div class="profile-column-grid"> <div class="description"> {{ skill.skill_name }} </div>
{% for skill in member.skill %} {% endfor %}
<div class="description"> {{ skill.skill_name }} </div>
{% endfor %}
</div>
</div> </div>
</div> {% endif %}
{% endif %}
{% endmacro %} {% endmacro %}
<!-- Education Details --> <!-- Education Details -->
{% macro EducationDetails(member) %} {% macro EducationDetails(member) %}
{% if member.education %} {% if member.education %}
<div class="education-details"> <div class="course-home-headings mt-10"> {{ _("Education") }} </div>
<div class="common-card-style column-card"> <div class="profile-grid-card">
<div class="course-home-headings"> {{ _("Education") }} </div> {% for edu in member.education %}
<div class="column-card-row">
<div class="profile-grid-card"> <div class="bold-title"> {{ edu.institution_name }} </div>
{% for edu in member.education %} <div class="profile-item"> {{ edu.degree_type }} <span></span> {{ edu.major }}
<div class="column-card-row"> {% if not member.hide_private %}
<div class="bold-title"> {{ edu.institution_name }} </div> <!-- {% if edu.grade_type %} {{ edu.grade_type }} {% endif %} -->
<div class="profile-item"> {{ edu.degree_type }} <span></span> {{ edu.major }} {% if edu.grade %} <span></span> {{ edu.grade }} {% endif %}
{% if not member.hide_private %} {% endif %}
<!-- {% if edu.grade_type %} {{ edu.grade_type }} {% endif %} -->
{% if edu.grade %} <span></span> {{ edu.grade }} {% endif %}
{% endif %}
</div>
<div class="description">
{% if edu.start_date %}
{{ frappe.utils.format_date(edu.start_date, "MMM YYYY") }} -
{% endif %}
{{ frappe.utils.format_date(edu.end_date, "MMM YYYY") }}
</div>
<div class="description"> {{ edu.location }} </div>
</div> </div>
{% endfor %}
<div class="description">
{% if edu.start_date %}
{{ frappe.utils.format_date(edu.start_date, "MMM YYYY") }} -
{% endif %}
{{ frappe.utils.format_date(edu.end_date, "MMM YYYY") }}
</div>
<div class="description"> {{ edu.location }} </div>
</div> </div>
{% endfor %}
</div> </div>
</div> {% endif %}
{% endif %}
{% endmacro %} {% endmacro %}
<!-- Work Details --> <!-- Work Details -->
{% macro WorkDetails(member) %} {% macro WorkDetails(member) %}
{% set work_details = member.work_experience + member.internship %} {% set work_details = member.work_experience + member.internship %}
{% if work_details | length %} {% if work_details | length %}
<div class="education-details"> <div class="course-home-headings mt-10"> {{ _("Work Experience") }} </div>
<div class="common-card-style column-card"> <div class="profile-grid-card">
<div class="course-home-headings"> {{ _("Work Experience") }} </div>
<div class="profile-grid-card">
{% for work in work_details %} {% for work in work_details %}
<div class=""> <div class="">
<div class="bold-title"> {{ work.title }} </div> <div class="bold-title"> {{ work.title }} </div>
<div class="profile-item"> {{ work.company }} </div> <div class="profile-item"> {{ work.company }} </div>
<div class="description"> <div class="description">
{{ frappe.utils.format_date(work.from_date, "MMM YYYY") }} - {{ frappe.utils.format_date(work.from_date, "MMM YYYY") }} -
{% if work.to_date %} {{ frappe.utils.format_date(work.to_date, "MMM YYYY") }} {% if work.to_date %} {{ frappe.utils.format_date(work.to_date, "MMM YYYY") }}
{% else %} Present {% endif %} {% else %} Present {% endif %}
</div>
<div class="description"> {{ work.location }} </div>
{% if work.description %}
<div class="profile-item">
{{ work.description }}
</div>
{% endif %}
</div> </div>
{% endfor %}
<div class="description"> {{ work.location }} </div>
{% if work.description %}
<div class="profile-item">
{{ work.description }}
</div>
{% endif %}
</div> </div>
{% endfor %}
</div> </div>
</div> {% endif %}
{% endif %}
{% endmacro %} {% endmacro %}
<!-- Certifications --> <!-- Certifications -->
{% macro ExternalCertification(member) %} {% macro ExternalCertification(member) %}
{% if member.certification %} {% if member.certification %}
<div class="education-details"> <div class="course-home-headings mt-10"> {{ _("External Certification") }} </div>
<div class="common-card-style column-card"> <div class="profile-grid-card">
<div class="course-home-headings"> {{ _("External Certification") }} </div> {% for cert in member.certification %}
<div class="profile-grid-card"> <div class="">
{% for cert in member.certification %}
<div class="">
<div class="bold-title"> {{ cert.certification_name }} </div> <div class="bold-title"> {{ cert.certification_name }} </div>
<div class="profile-item"> {{ cert.organization }} </div> <div class="profile-item"> {{ cert.organization }} </div>
<div class="description"> <div class="description">
{{ frappe.utils.format_date(cert.issue_date, "MMM YYYY") }} {{ frappe.utils.format_date(cert.issue_date, "MMM YYYY") }}
{% if cert.expiration_date %} {% if cert.expiration_date %}
- {{ frappe.utils.format_date(cert.expiration_date, "MMM YYYY") }} - {{ frappe.utils.format_date(cert.expiration_date, "MMM YYYY") }}
{% endif %}
</div>
{% if cert.description %}
<div class="profile-item">
{{ cert.description }}
</div>
{% endif %} {% endif %}
</div> </div>
{% endfor %}
{% if cert.description %}
<div class="profile-item">
{{ cert.description }}
</div>
{% endif %}
</div> </div>
{% endfor %}
</div> </div>
</div> {% endif %}
{% endif %}
{% endmacro %} {% endmacro %}