fix: conflicts
This commit is contained in:
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -6,7 +6,7 @@ on:
|
|||||||
pull_request: {}
|
pull_request: {}
|
||||||
jobs:
|
jobs:
|
||||||
tests:
|
tests:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-latest
|
||||||
services:
|
services:
|
||||||
redis-cache:
|
redis-cache:
|
||||||
image: redis:alpine
|
image: redis:alpine
|
||||||
@@ -32,7 +32,7 @@ jobs:
|
|||||||
- name: setup python
|
- name: setup python
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: 3.9
|
python-version: '3.9'
|
||||||
- name: setup node
|
- name: setup node
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
version: "3"
|
version: "3"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
redis-cache:
|
|
||||||
image: redis:alpine
|
|
||||||
redis-queue:
|
|
||||||
image: redis:alpine
|
|
||||||
redis-socketio:
|
|
||||||
image: redis:alpine
|
|
||||||
mariadb:
|
mariadb:
|
||||||
image: mariadb
|
image: mariadb
|
||||||
volumes:
|
volumes:
|
||||||
@@ -15,18 +9,15 @@ services:
|
|||||||
- MYSQL_ROOT_PASSWORD=root
|
- MYSQL_ROOT_PASSWORD=root
|
||||||
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||||
bench:
|
bench:
|
||||||
image: anandology/frappe-bench
|
image: anandology/frappe-bench:2021.10
|
||||||
volumes:
|
volumes:
|
||||||
- .:/home/bench/frappe-bench/apps/school
|
- .:/opt/frappe-bench/apps/school
|
||||||
environment:
|
environment:
|
||||||
- FRAPPE_APPS=school
|
- FRAPPE_APPS=school
|
||||||
- FRAPPE_ALLOW_TESTS=true
|
- FRAPPE_ALLOW_TESTS=true
|
||||||
- FRAPPE_SITE_NAME=frappe.localhost
|
- FRAPPE_SITE_NAME=frappe.localhost
|
||||||
depends_on:
|
depends_on:
|
||||||
- mariadb
|
- mariadb
|
||||||
- redis-cache
|
|
||||||
- redis-queue
|
|
||||||
- redis-socketio
|
|
||||||
ports:
|
ports:
|
||||||
- 8000:8000
|
- 8000:8000
|
||||||
- 9000:9000
|
- 9000:9000
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"based_on": "creation",
|
||||||
|
"chart_name": "Course Enrollments",
|
||||||
|
"chart_type": "Count",
|
||||||
|
"creation": "2021-09-30 12:23:09.414853",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Dashboard Chart",
|
||||||
|
"document_type": "LMS Batch Membership",
|
||||||
|
"dynamic_filters_json": "[]",
|
||||||
|
"filters_json": "[]",
|
||||||
|
"group_by_type": "Count",
|
||||||
|
"idx": 0,
|
||||||
|
"is_public": 1,
|
||||||
|
"is_standard": 1,
|
||||||
|
"last_synced_on": "2021-10-17 13:32:21.745498",
|
||||||
|
"modified": "2021-10-21 17:31:06.997133",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "Course Enrollments",
|
||||||
|
"number_of_groups": 0,
|
||||||
|
"owner": "basawaraj@erpnext.com",
|
||||||
|
"source": "",
|
||||||
|
"time_interval": "Daily",
|
||||||
|
"timeseries": 1,
|
||||||
|
"timespan": "Last Quarter",
|
||||||
|
"type": "Line",
|
||||||
|
"use_report_chart": 0,
|
||||||
|
"value_based_on": "",
|
||||||
|
"y_axis": []
|
||||||
|
}
|
||||||
@@ -65,11 +65,12 @@ class CourseLesson(Document):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def save_progress(lesson, course, status):
|
def save_progress(lesson, course, status):
|
||||||
if not frappe.db.exists("LMS Batch Membership",
|
membership = frappe.db.exists("LMS Batch Membership",
|
||||||
{
|
{
|
||||||
"member": frappe.session.user,
|
"member": frappe.session.user,
|
||||||
"course": course
|
"course": course
|
||||||
}):
|
})
|
||||||
|
if not membership:
|
||||||
return
|
return
|
||||||
|
|
||||||
if frappe.db.exists("LMS Course Progress",
|
if frappe.db.exists("LMS Course Progress",
|
||||||
@@ -92,5 +93,8 @@ def save_progress(lesson, course, status):
|
|||||||
"lesson": lesson,
|
"lesson": lesson,
|
||||||
"status": status,
|
"status": 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()
|
progress = course_details.get_course_progress()
|
||||||
|
frappe.db.set_value("LMS Batch Membership", membership, "progress", progress)
|
||||||
|
return progress
|
||||||
|
|||||||
@@ -5,15 +5,16 @@
|
|||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"batch",
|
"course",
|
||||||
"member",
|
"member",
|
||||||
"member_name",
|
"member_name",
|
||||||
"member_username",
|
"member_username",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"course",
|
"batch",
|
||||||
"member_type",
|
"member_type",
|
||||||
"role",
|
"progress",
|
||||||
"current_lesson"
|
"current_lesson",
|
||||||
|
"role"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -65,6 +66,7 @@
|
|||||||
"fieldname": "course",
|
"fieldname": "course",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
"label": "Course",
|
"label": "Course",
|
||||||
"options": "LMS Course"
|
"options": "LMS Course"
|
||||||
},
|
},
|
||||||
@@ -80,11 +82,18 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Memeber Username",
|
"label": "Memeber Username",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "progress",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Progress",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-09-29 15:27:58.765399",
|
"migration_hash": "fe10c462acf5e727d864305d7ce90e73",
|
||||||
|
"modified": "2021-10-20 15:10:33.767419",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Batch Membership",
|
"name": "LMS Batch Membership",
|
||||||
@@ -105,6 +114,5 @@
|
|||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC"
|
||||||
"track_changes": 1
|
|
||||||
}
|
}
|
||||||
@@ -251,7 +251,7 @@ class LMSCourse(Document):
|
|||||||
|
|
||||||
membership = frappe.db.get_value("LMS Batch Membership",
|
membership = frappe.db.get_value("LMS Batch Membership",
|
||||||
filters,
|
filters,
|
||||||
["name", "batch", "current_lesson", "member_type"],
|
["name", "batch", "current_lesson", "member_type", "progress"],
|
||||||
as_dict=True)
|
as_dict=True)
|
||||||
|
|
||||||
if membership and membership.batch:
|
if membership and membership.batch:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# License: MIT. See LICENSE
|
# License: MIT. See LICENSE
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import rounded
|
from frappe.utils import cint
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
@@ -23,21 +23,16 @@ def get_data(filters=None):
|
|||||||
memberships = frappe.get_all(
|
memberships = frappe.get_all(
|
||||||
"LMS Batch Membership",
|
"LMS Batch Membership",
|
||||||
query_filter,
|
query_filter,
|
||||||
["name", "course", "member", "member_name"],
|
["name", "course", "member", "member_name", "progress"],
|
||||||
order_by="course")
|
order_by="course")
|
||||||
|
|
||||||
current_course = memberships[0].course
|
|
||||||
for membership in memberships:
|
for membership in memberships:
|
||||||
if current_course != membership.course:
|
|
||||||
current_course = membership.course
|
|
||||||
|
|
||||||
course_details = frappe.get_doc("LMS Course", current_course)
|
|
||||||
summary.append(frappe._dict({
|
summary.append(frappe._dict({
|
||||||
"course": course_details.name,
|
"course": membership.name,
|
||||||
"course_name": course_details.title,
|
"course_name": frappe.db.get_value("LMS Course", membership.course, "title"),
|
||||||
"member": membership.member,
|
"member": membership.member,
|
||||||
"member_name": membership.member_name,
|
"member_name": membership.member_name,
|
||||||
"progress": rounded(course_details.get_course_progress(membership.member))
|
"progress": cint(membership.progress)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return summary
|
return summary
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{% set member = frappe.get_doc("User", frappe.session.user) %}
|
||||||
|
<div class="mt-10">
|
||||||
|
{% set enrolled = member.get_enrolled_courses().in_progress + member.get_enrolled_courses().completed %}
|
||||||
|
{% if enrolled | length %}
|
||||||
|
<div class="mt-8">
|
||||||
|
<div class="course-home-headings">
|
||||||
|
{{ _("Courses Enrolled") }}
|
||||||
|
</div>
|
||||||
|
<div class="cards-parent">
|
||||||
|
{% for course in enrolled %}
|
||||||
|
{{ widgets.CourseCard(course=course) }}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="common-card-style thread-card">
|
||||||
|
<div class="w-25 text-center" style="margin: 0 auto;">
|
||||||
|
<span class="font-weight-bold"> No Enrolled Courses </span>
|
||||||
|
<div class="small">
|
||||||
|
You have not enrolled in any course yet.
|
||||||
|
</div>
|
||||||
|
<a class="button is-primary ml-auto mr-auto mt-3" href="/courses">
|
||||||
|
Explore Courses
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"__unsaved": 1,
|
||||||
|
"creation": "2021-10-21 11:29:50.424865",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Web Template",
|
||||||
|
"fields": [],
|
||||||
|
"idx": 0,
|
||||||
|
"modified": "2021-10-21 12:02:23.837501",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "Courses Enrolled",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"standard": 1,
|
||||||
|
"template": "",
|
||||||
|
"type": "Section"
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{% set member = frappe.get_doc("User", frappe.session.user) %}
|
||||||
|
<div class="mt-10">
|
||||||
|
{% if member.get_mentored_courses() | length %}
|
||||||
|
<div class="course-home-headings"> {{ _("Courses Mentored") }} </div>
|
||||||
|
<div class="cards-parent">
|
||||||
|
{% for course in member.get_mentored_courses() %}
|
||||||
|
{{ widgets.CourseCard(course=course) }}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"__unsaved": 1,
|
||||||
|
"creation": "2021-10-21 11:32:57.411626",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Web Template",
|
||||||
|
"fields": [],
|
||||||
|
"idx": 0,
|
||||||
|
"modified": "2021-10-21 12:01:56.270656",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "Courses Mentored",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"standard": 1,
|
||||||
|
"template": "",
|
||||||
|
"type": "Section"
|
||||||
|
}
|
||||||
@@ -1,116 +1,188 @@
|
|||||||
{% set membership = course.get_membership(frappe.session.user) %}
|
{% set membership = course.get_membership(frappe.session.user) %}
|
||||||
{% set progress = course.get_course_progress() %}
|
{% set progress = frappe.utils.cint(membership.progress) %}
|
||||||
<div class="common-card-style course-card">
|
<div class="common-card-style course-card">
|
||||||
|
|
||||||
<div class="course-image {% if not course.image %}default-image{% endif %}"
|
<div class="course-image
|
||||||
{% if course.image %} style="background-image: url( {{ course.image }} );" {% endif %}>
|
{% if not course.image %}default-image{% endif %}"
|
||||||
<div class="course-tags">
|
{% if course.image %}style="background-image: url( {{ course.image }} );" {% endif %}>
|
||||||
{% for tag in course.get_tags() %}
|
<div class="course-tags">
|
||||||
<div class="course-card-pills">{{ tag }}</div>
|
{% for tag in course.get_tags() %}
|
||||||
{% endfor %}
|
<div class="course-card-pills">{{ tag }}</div>
|
||||||
{% if membership and not read_only %}
|
{% endfor %}
|
||||||
{% if progress < 100 %}
|
{% if membership and not read_only %}
|
||||||
<div class="course-card-pills dark-pills ml-auto">{{ frappe.utils.rounded(progress) }}% {{ _("Completed") }}</div>
|
{% if progress < 100 %}
|
||||||
{% else %}
|
<div class="course-card-pills dark-pills ml-auto">{
|
||||||
<div class="course-card-pills dark-pills ml-auto"> <img src="/assets/school/icons/check.svg"> {{ _("Completed") }} </div>
|
{ frappe.utils.rounded(progress) }}% {{ _("Completed") }}
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
{% if not course.image %}
|
{% else %}
|
||||||
<div class="default-image-text">{{ course.title[0] }}</div>
|
<div class="course-card-pills dark-pills ml-auto">
|
||||||
|
<img src="/assets/community/icons/check.svg"> {{ _("Completed")}}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
{% if not course.image %}
|
||||||
|
<div class="default-image-text">{{ course.title[0] }}</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="course-card-content">
|
<div class="course-card-content">
|
||||||
<div class="course-card-meta muted-text">
|
<div class="course-card-meta muted-text">
|
||||||
{% if course.get_chapters() | length %}
|
{% if course.get_chapters() | length %}
|
||||||
<span>
|
<span>
|
||||||
{{ course.get_chapters() | length }} {{ _("Chapters") }}
|
{{ course.get_chapters() | length }} {{ _("Chapters") }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if course.get_chapters() | length and course.get_upcoming_batches() | length %}
|
{% if course.get_chapters() | length and course.get_upcoming_batches() | length %}
|
||||||
<span class="font-weight-bold ml-3 mr-3"> . </span>
|
<span class="font-weight-bold ml-3 mr-3"> . </span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if course.get_upcoming_batches() | length %}
|
{% if course.get_upcoming_batches() | length %}
|
||||||
<span class="">
|
<span class="">
|
||||||
{{ course.get_upcoming_batches() | length }} {{ _("Open Batches") }}
|
{{ course.get_upcoming_batches() | length }} {{ _("Open Batches") }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="course-card-title">{{ course.title }}</div>
|
<div class="course-card-title">{{ course.title }}</div>
|
||||||
<div {% if not read_only %} class="mb-4" {% endif %}>
|
<div {% if not read_only %} class="mb-4" {% endif %}>
|
||||||
<span class="zindex">
|
<span class="zindex">
|
||||||
{{ widgets.Avatar(member=course.get_instructor(), avatar_class="avatar-small") }}
|
{{ widgets.Avatar(member=course.get_instructor(), avatar_class="avatar-small") }}
|
||||||
<a class="button-links" href="{{ get_profile_url(course.get_instructor().username) }}">
|
<a class="button-links" href="{{ get_profile_url(course.get_instructor().username) }}">
|
||||||
<span class="course-instructor">
|
<span class="course-instructor">
|
||||||
{{ course.get_instructor().full_name }}
|
{{ course.get_instructor().full_name }}
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span class="course-student-count">
|
|
||||||
{% if course.get_students() | length %}
|
|
||||||
<span class="mr-4">
|
|
||||||
<img class="icon-background" src="/assets/school/icons/user.svg" />
|
|
||||||
{{ course.get_students() | length }}
|
|
||||||
</span> {% endif %}
|
|
||||||
{% set avg_rating = course.get_average_rating() %}
|
|
||||||
{% if avg_rating %}
|
|
||||||
<span class="">
|
|
||||||
<img class="icon-background" src="/assets/school/icons/rating.svg" />
|
|
||||||
{{ frappe.utils.flt(avg_rating, frappe.get_system_settings("float_precision") or 3) }}
|
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
</a>
|
||||||
|
</span>
|
||||||
|
<span class="course-student-count">
|
||||||
|
{% if course.get_students() | length %}
|
||||||
|
<span class="mr-4">
|
||||||
|
<img class="icon-background" src="/assets/community/icons/user.svg" />
|
||||||
|
{{ course.get_students() | length }}
|
||||||
|
</span> {% endif %}
|
||||||
|
{% set avg_rating = course.get_average_rating() %}
|
||||||
|
{% if avg_rating %}
|
||||||
|
<span class="">
|
||||||
|
<img class="icon-background" src="/assets/community/icons/rating.svg" />
|
||||||
|
{{ frappe.utils.flt(avg_rating, frappe.get_system_settings("float_precision") or 3) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
{% endif %}
|
||||||
|
<<<<<<< HEAD:school/lms/widgets/CourseCard.html </div>
|
||||||
|
<div class="course-card-title">{{ course.title }}</div>
|
||||||
|
<div {% if not read_only %} class="mb-4" {% endif %}>
|
||||||
|
<span class="zindex">
|
||||||
|
{{ widgets.Avatar(member=course.get_instructor(), avatar_class="avatar-small") }}
|
||||||
|
<a class="button-links" href="{{ get_profile_url(course.get_instructor().username) }}">
|
||||||
|
<span class="course-instructor">
|
||||||
|
{{ course.get_instructor().full_name }}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
<span class="course-student-count">
|
||||||
|
{% if course.get_students() | length %}
|
||||||
|
<span class="mr-4">
|
||||||
|
<img class="icon-background" src="/assets/school/icons/user.svg" />
|
||||||
|
{{ course.get_students() | length }}
|
||||||
|
</span> {% endif %}
|
||||||
|
{% set avg_rating = course.get_average_rating() %}
|
||||||
|
{% if avg_rating %}
|
||||||
|
<span class="">
|
||||||
|
<img class="icon-background" src="/assets/school/icons/rating.svg" />
|
||||||
|
{{ frappe.utils.flt(avg_rating, frappe.get_system_settings("float_precision") or 3) }}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if read_only %}
|
{% if read_only %}
|
||||||
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
=======
|
||||||
{% set lesson_index = course.get_lesson_index(membership.current_lesson) if membership and
|
</span>
|
||||||
membership.current_lesson else '1.1' %}
|
|
||||||
{% set query_parameter = "?batch=" + membership.batch if membership and
|
|
||||||
membership.batch else "" %}
|
|
||||||
{% set certificate = course.is_certified() %}
|
|
||||||
|
|
||||||
{% if certificate %}
|
|
||||||
<div class="view-course-link is-default">
|
|
||||||
_("Get Certificate") <img class="ml-3" src="/assets/school/icons/black-arrow.svg" />
|
|
||||||
</div>
|
|
||||||
<a class="stretched-link" href="/courses/{{ course.name }}/{{ certificate }}"></a>
|
|
||||||
|
|
||||||
{% elif course.enable_certification and progress == 100 %}
|
|
||||||
<div class="view-course-link is-default" id="certification" data-course="{{ course.name }}">
|
|
||||||
{{ _("Get Certificate") }} <img class="ml-3" src="/assets/school/icons/black-arrow.svg" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% elif progress == 100 %}
|
|
||||||
<div class="view-course-link is-default">
|
|
||||||
{{ _("Course Completed") }} <img class="ml-3" src="/assets/school/icons/black-arrow.svg" />
|
|
||||||
</div>
|
|
||||||
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
|
||||||
|
|
||||||
{% elif course.upcoming %}
|
|
||||||
<div class="view-course-link is-secondary border">
|
|
||||||
{{ _("Upcoming Course") }} <img class="ml-3" src="/assets/school/icons/black-arrow.svg" />
|
|
||||||
</div>
|
|
||||||
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
|
||||||
|
|
||||||
{% elif membership %}
|
|
||||||
<div class="view-course-link is-primary">
|
|
||||||
{{ _("Continue Course") }} <img class="ml-3" src="/assets/school/icons/white-arrow.svg" />
|
|
||||||
</div>
|
|
||||||
<a class="stretched-link" href="{{ course.get_learn_url(lesson_index) }}{{ query_parameter }}"></a>
|
|
||||||
|
|
||||||
{% else %}
|
|
||||||
<div class="view-course-link is-default">
|
|
||||||
{{ _("View Course") }} <img class="ml-3" src="/assets/school/icons/black-arrow.svg" />
|
|
||||||
</div>
|
|
||||||
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
>>>>>>> 866829af97608c49779499d9a2eba3999b24eed7:community/lms/widgets/CourseCard.html
|
||||||
|
|
||||||
|
{% if read_only %}
|
||||||
|
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
<<<<<<< HEAD:school/lms/widgets/CourseCard.html {% if certificate %} <div class="view-course-link is-default">
|
||||||
|
_("Get Certificate") <img class="ml-3" src="/assets/school/icons/black-arrow.svg" />
|
||||||
|
</div>
|
||||||
|
<a class="stretched-link" href="/courses/{{ course.name }}/{{ certificate }}"></a>
|
||||||
|
|
||||||
|
{% elif course.enable_certification and progress == 100 %}
|
||||||
|
<div class="view-course-link is-default" id="certification" data-course="{{ course.name }}">
|
||||||
|
{{ _("Get Certificate") }} <img class="ml-3" src="/assets/school/icons/black-arrow.svg" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% elif progress == 100 %}
|
||||||
|
<div class="view-course-link is-default">
|
||||||
|
{{ _("Course Completed") }} <img class="ml-3" src="/assets/school/icons/black-arrow.svg" />
|
||||||
|
</div>
|
||||||
|
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
||||||
|
|
||||||
|
{% elif course.upcoming %}
|
||||||
|
<div class="view-course-link is-secondary border">
|
||||||
|
{{ _("Upcoming Course") }} <img class="ml-3" src="/assets/school/icons/black-arrow.svg" />
|
||||||
|
</div>
|
||||||
|
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
||||||
|
|
||||||
|
{% elif membership %}
|
||||||
|
<div class="view-course-link is-primary">
|
||||||
|
{{ _("Continue Course") }} <img class="ml-3" src="/assets/school/icons/white-arrow.svg" />
|
||||||
|
</div>
|
||||||
|
<a class="stretched-link" href="{{ course.get_learn_url(lesson_index) }}{{ query_parameter }}"></a>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<div class="view-course-link is-default">
|
||||||
|
{{ _("View Course") }} <img class="ml-3" src="/assets/school/icons/black-arrow.svg" />
|
||||||
|
</div>
|
||||||
|
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
||||||
|
=======
|
||||||
|
{% set lesson_index = course.get_lesson_index(membership.current_lesson) if membership and
|
||||||
|
membership.current_lesson else '1.1' %}
|
||||||
|
{% set query_parameter = "?batch=" + membership.batch if membership and
|
||||||
|
membership.batch else "" %}
|
||||||
|
{% set certificate = course.is_certified() %}
|
||||||
|
|
||||||
|
{% if certificate %}
|
||||||
|
<div class="view-course-link is-default">
|
||||||
|
_("Get Certificate") <img class="ml-3" src="/assets/community/icons/black-arrow.svg" />
|
||||||
|
</div>
|
||||||
|
<a class="stretched-link" href="/courses/{{ course.name }}/{{ certificate }}"></a>
|
||||||
|
|
||||||
|
{% elif course.enable_certification and progress == 100 %}
|
||||||
|
<div class="view-course-link is-default" id="certification" data-course="{{ course.name }}">
|
||||||
|
{{ _("Get Certificate") }} <img class="ml-3" src="/assets/community/icons/black-arrow.svg" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% elif progress == 100 %}
|
||||||
|
<div class="view-course-link is-default">
|
||||||
|
{{ _("Course Completed") }} <img class="ml-3" src="/assets/community/icons/black-arrow.svg" />
|
||||||
|
</div>
|
||||||
|
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
||||||
|
|
||||||
|
{% elif course.upcoming %}
|
||||||
|
<div class="view-course-link is-secondary border">
|
||||||
|
{{ _("Upcoming Course") }} <img class="ml-3" src="/assets/community/icons/black-arrow.svg" />
|
||||||
|
</div>
|
||||||
|
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
||||||
|
|
||||||
|
{% elif membership %}
|
||||||
|
<div class="view-course-link is-primary">
|
||||||
|
{{ _("Continue Course") }} <img class="ml-3" src="/assets/community/icons/white-arrow.svg" />
|
||||||
|
</div>
|
||||||
|
<a class="stretched-link" href="{{ course.get_learn_url(lesson_index) }}{{ query_parameter }}"></a>
|
||||||
|
>>>>>>> 866829af97608c49779499d9a2eba3999b24eed7:community/lms/widgets/CourseCard.html
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<div class="view-course-link is-default">
|
||||||
|
{{ _("View Course") }} <img class="ml-3" src="/assets/community/icons/black-arrow.svg" />
|
||||||
|
</div>
|
||||||
|
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
131
school/lms/workspace/school/school.json
Normal file
131
school/lms/workspace/school/school.json
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
{
|
||||||
|
"category": "Modules",
|
||||||
|
"charts": [
|
||||||
|
{
|
||||||
|
"chart_name": "Course Enrollments",
|
||||||
|
"label": "Course Enrollments"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"content": "[{\"type\":\"chart\",\"data\":{\"chart_name\":\"Course Enrollments\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Course\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Course Enrollments\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Course Completed\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Course Data\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Course Stats\",\"col\":4}}]",
|
||||||
|
"creation": "2021-10-21 17:20:01.358903",
|
||||||
|
"developer_mode_only": 0,
|
||||||
|
"disable_user_customization": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Workspace",
|
||||||
|
"extends_another_page": 0,
|
||||||
|
"hide_custom": 0,
|
||||||
|
"icon": "education",
|
||||||
|
"idx": 0,
|
||||||
|
"is_default": 0,
|
||||||
|
"is_standard": 1,
|
||||||
|
"label": "School",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"hidden": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"label": "Course Data",
|
||||||
|
"link_count": 3,
|
||||||
|
"onboard": 0,
|
||||||
|
"type": "Card Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"label": "Chapter",
|
||||||
|
"link_count": 0,
|
||||||
|
"link_to": "Course Chapter",
|
||||||
|
"link_type": "DocType",
|
||||||
|
"onboard": 0,
|
||||||
|
"type": "Link"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"label": "Lesson",
|
||||||
|
"link_count": 0,
|
||||||
|
"link_to": "Course Lesson",
|
||||||
|
"link_type": "DocType",
|
||||||
|
"onboard": 0,
|
||||||
|
"type": "Link"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"label": "Quiz",
|
||||||
|
"link_count": 0,
|
||||||
|
"link_to": "LMS Quiz",
|
||||||
|
"link_type": "DocType",
|
||||||
|
"onboard": 0,
|
||||||
|
"type": "Link"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"label": "Course Stats",
|
||||||
|
"link_count": 2,
|
||||||
|
"onboard": 0,
|
||||||
|
"type": "Card Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"label": "Interest",
|
||||||
|
"link_count": 0,
|
||||||
|
"link_to": "LMS Course Interest",
|
||||||
|
"link_type": "DocType",
|
||||||
|
"onboard": 0,
|
||||||
|
"type": "Link"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden": 0,
|
||||||
|
"is_query_report": 0,
|
||||||
|
"label": "Review",
|
||||||
|
"link_count": 0,
|
||||||
|
"link_to": "LMS Course Review",
|
||||||
|
"link_type": "DocType",
|
||||||
|
"onboard": 0,
|
||||||
|
"type": "Link"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"modified": "2021-10-21 18:18:02.114827",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "School",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"parent_page": "",
|
||||||
|
"pin_to_bottom": 0,
|
||||||
|
"pin_to_top": 1,
|
||||||
|
"public": 1,
|
||||||
|
"roles": [],
|
||||||
|
"sequence_id": 1,
|
||||||
|
"shortcuts": [
|
||||||
|
{
|
||||||
|
"color": "Green",
|
||||||
|
"doc_view": "List",
|
||||||
|
"format": "{} Published",
|
||||||
|
"label": "Course",
|
||||||
|
"link_to": "LMS Course",
|
||||||
|
"stats_filter": "{\"is_published\":[\"=\",1]}",
|
||||||
|
"type": "DocType"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "Orange",
|
||||||
|
"doc_view": "List",
|
||||||
|
"format": "{} Completed",
|
||||||
|
"label": "Course Completed",
|
||||||
|
"link_to": "LMS Batch Membership",
|
||||||
|
"stats_filter": "{\"progress\":[\"=\",\"100\"]}",
|
||||||
|
"type": "DocType"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "Green",
|
||||||
|
"doc_view": "List",
|
||||||
|
"format": "{} Enrolled",
|
||||||
|
"label": "Course Enrollments",
|
||||||
|
"link_to": "LMS Batch Membership",
|
||||||
|
"stats_filter": "{\"member_type\":[\"=\",\"Student\"]}",
|
||||||
|
"type": "DocType"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "School"
|
||||||
|
}
|
||||||
@@ -109,7 +109,7 @@ class CustomUser(User):
|
|||||||
if member_type:
|
if member_type:
|
||||||
filters["member_type"] = member_type
|
filters["member_type"] = member_type
|
||||||
|
|
||||||
return frappe.get_all("LMS Batch Membership", filters, ["name", "course"])
|
return frappe.get_all("LMS Batch Membership", filters, ["name", "course", "progress"])
|
||||||
|
|
||||||
def get_mentored_courses(self):
|
def get_mentored_courses(self):
|
||||||
""" Returns all courses mentored by this user """
|
""" Returns all courses mentored by this user """
|
||||||
@@ -123,17 +123,18 @@ class CustomUser(User):
|
|||||||
|
|
||||||
for map in mapping:
|
for map in mapping:
|
||||||
if frappe.db.get_value("LMS Course", map.course, "is_published"):
|
if frappe.db.get_value("LMS Course", map.course, "is_published"):
|
||||||
mentored_courses.append(map)
|
course = frappe.get_doc("LMS Course", map.course)
|
||||||
|
mentored_courses.append(course)
|
||||||
|
|
||||||
return mentored_courses
|
return mentored_courses
|
||||||
|
|
||||||
def get_enrolled_courses(self):
|
def get_enrolled_courses(self):
|
||||||
in_progress = []
|
in_progress = []
|
||||||
completed = []
|
completed = []
|
||||||
memberships = self.get_course_membership("Student");
|
memberships = self.get_course_membership("Student")
|
||||||
for membership in memberships:
|
for membership in memberships:
|
||||||
course = frappe.get_doc("LMS Course", membership.course)
|
course = frappe.get_doc("LMS Course", membership.course)
|
||||||
progress = course.get_course_progress(member=self.name)
|
progress = cint(membership.progress)
|
||||||
if progress < 100:
|
if progress < 100:
|
||||||
in_progress.append(course)
|
in_progress.append(course)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -18,3 +18,5 @@ execute:frappe.delete_doc("DocType", "Lessons") #06-10-2021
|
|||||||
execute:frappe.delete_doc("DocType", "Chapter") #06-10-2021
|
execute:frappe.delete_doc("DocType", "Chapter") #06-10-2021
|
||||||
execute:frappe.delete_doc("DocType", "Lesson") #06-10-2021
|
execute:frappe.delete_doc("DocType", "Lesson") #06-10-2021
|
||||||
execute:frappe.delete_doc("DocType", "LMS Topic") #06-10-2021
|
execute:frappe.delete_doc("DocType", "LMS Topic") #06-10-2021
|
||||||
|
community.patches.v0_0.add_progress_to_membership #20-10-2021
|
||||||
|
execute:frappe.delete_doc("Workspace", "LMS", ignore_missing=True, force=True) #24-10-2021
|
||||||
|
|||||||
22
school/patches/v0_0/add_progress_to_membership.py
Normal file
22
school/patches/v0_0/add_progress_to_membership.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import frappe
|
||||||
|
from frappe.utils import rounded
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.reload_doc("lms", "doctype", "lms_batch_membership")
|
||||||
|
memberships = frappe.get_all(
|
||||||
|
"LMS Batch Membership",
|
||||||
|
["name", "course", "member"],
|
||||||
|
order_by="course")
|
||||||
|
|
||||||
|
if len(memberships):
|
||||||
|
current_course = memberships[0].course
|
||||||
|
for membership in memberships:
|
||||||
|
if current_course != membership.course:
|
||||||
|
current_course = membership.course
|
||||||
|
|
||||||
|
course_details = frappe.get_doc("LMS Course", current_course)
|
||||||
|
progress = rounded(course_details.get_course_progress(membership.member))
|
||||||
|
frappe.db.set_value("LMS Batch Membership", membership.name, "progress", progress)
|
||||||
|
|
||||||
|
frappe.db.delete("Prepared Report", {"ref_report_doctype": "Course Progress Summary"})
|
||||||
|
frappe.db.set_value("Report", "Course Progress Summary", "prepared_report", 0)
|
||||||
@@ -212,7 +212,6 @@ input[type=checkbox] {
|
|||||||
|
|
||||||
.courses-header {
|
.courses-header {
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
padding: 0 1rem;
|
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
@@ -739,7 +738,6 @@ input[type=checkbox] {
|
|||||||
letter-spacing: -0.0175em;
|
letter-spacing: -0.0175em;
|
||||||
color: #192734;
|
color: #192734;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
padding: 0 1rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.course-detail-headings {
|
.course-detail-headings {
|
||||||
|
|||||||
@@ -47,9 +47,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="quiz-footer">
|
<div class="quiz-footer">
|
||||||
<span class="font-weight-bold"> <span class="current-question">1</span> of {{ quiz.questions | length }}</span>
|
<span class="font-weight-bold"> <span class="current-question">1</span> of {{ quiz.questions | length }}</span>
|
||||||
<button class="btn btn-primary pull-right" id="check" disabled>Check</button>
|
<button class="button pull-right" id="check" disabled>Check</button>
|
||||||
<button class="btn btn-primary hide" id="next">Next</button>
|
<button class="button hide" id="next">Next Question</button>
|
||||||
<button class="btn btn-primary hide" id="summary">Summary</button>
|
<button class="button is-default hide" id="summary">Summary</button>
|
||||||
<small id="submission-message" class="font-weight-bold hide"> Please join the course to submit the Quiz.</small>
|
<small id="submission-message" class="font-weight-bold hide"> Please join the course to submit the Quiz.</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="button is-secondary pull-right hide" id="try-again">Try Again</div>
|
<div class="button is-secondary pull-right hide" id="try-again">Try Again</div>
|
||||||
|
|||||||
@@ -99,7 +99,7 @@
|
|||||||
<img class="ml-2" src="/assets/school/icons/side-arrow-white.svg">
|
<img class="ml-2" src="/assets/school/icons/side-arrow-white.svg">
|
||||||
</a>
|
</a>
|
||||||
{% elif course.enable_certification %}
|
{% elif course.enable_certification %}
|
||||||
<div class="button is-primary {% if course.get_course_progress() != 100 %} hide {% endif %}" id="certification">
|
<div class="button is-primary {% if membership.progress != 100 %} hide {% endif %}" id="certification">
|
||||||
Get Certificate
|
Get Certificate
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{{ widgets.MemberCard(member=course.get_instructor(), show_course_count=True, dimension_class="member-card-large") }}
|
{{ widgets.MemberCard(member=course.get_instructor(), show_course_count=True, dimension_class="member-card-large") }}
|
||||||
</div>
|
</div>
|
||||||
{% set progress = course.get_course_progress() %}
|
{% set progress = frappe.utils.cint(membership.progress) %}
|
||||||
{% if progress %}
|
{% if progress %}
|
||||||
<div class="course-progress-section">
|
<div class="course-progress-section">
|
||||||
<div class="course-home-headings">
|
<div class="course-home-headings">
|
||||||
|
|||||||
@@ -130,9 +130,8 @@
|
|||||||
Courses Mentored
|
Courses Mentored
|
||||||
</div>
|
</div>
|
||||||
<div class="cards-parent">
|
<div class="cards-parent">
|
||||||
{% for mentorship in member.get_mentored_courses() %}
|
{% for course in member.get_mentored_courses() %}
|
||||||
{% set course_details = frappe.get_doc("LMS Course", mentorship.course) %}
|
{{ widgets.CourseCard(course=course, read_only=read_only) }}
|
||||||
{{ widgets.CourseCard(course=course_details, read_only=read_only) }}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user