Merge branch 'main' of https://github.com/frappe/lms into classes
This commit is contained in:
@@ -58,6 +58,7 @@ web_include_js = ["website.bundle.js"]
|
|||||||
# ------------
|
# ------------
|
||||||
|
|
||||||
# before_install = "lms.install.before_install"
|
# before_install = "lms.install.before_install"
|
||||||
|
after_install = "lms.install.add_pages_to_nav"
|
||||||
after_sync = "lms.install.after_sync"
|
after_sync = "lms.install.after_sync"
|
||||||
after_uninstall = "lms.install.after_uninstall"
|
after_uninstall = "lms.install.after_uninstall"
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ import frappe
|
|||||||
from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to
|
from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to
|
||||||
|
|
||||||
|
|
||||||
|
def after_install():
|
||||||
|
add_pages_to_nav()
|
||||||
|
|
||||||
|
|
||||||
def after_sync():
|
def after_sync():
|
||||||
create_lms_roles()
|
create_lms_roles()
|
||||||
set_default_home()
|
set_default_home()
|
||||||
@@ -91,3 +95,41 @@ def delete_custom_fields():
|
|||||||
for field in fields:
|
for field in fields:
|
||||||
frappe.db.delete("Custom Field", {"fieldname": field})
|
frappe.db.delete("Custom Field", {"fieldname": field})
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def add_pages_to_nav():
|
||||||
|
pages = [
|
||||||
|
{"label": "Courses", "url": "/courses", "parent": "Explore", "idx": 2},
|
||||||
|
{"label": "Statistics", "url": "/statistics", "parent": "Explore", "idx": 3},
|
||||||
|
{"label": "Jobs", "url": "/jobs", "parent": "Explore", "idx": 4},
|
||||||
|
{"label": "People", "url": "/community", "parent": "Explore", "idx": 5},
|
||||||
|
]
|
||||||
|
|
||||||
|
if not frappe.db.exists("Top Bar Item", {"label": "Explore"}):
|
||||||
|
frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Top Bar Item",
|
||||||
|
"label": "Explore",
|
||||||
|
"parent": "Website Settings",
|
||||||
|
"parenttype": "Website Settings",
|
||||||
|
"parentfield": "top_bar_items",
|
||||||
|
"idx": 1,
|
||||||
|
}
|
||||||
|
).save()
|
||||||
|
|
||||||
|
for page in pages:
|
||||||
|
if not frappe.db.exists(
|
||||||
|
"Top Bar Item", {"url": ["like", "%" + page.get("url") + "%"]}
|
||||||
|
):
|
||||||
|
frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Top Bar Item",
|
||||||
|
"label": page.get("label"),
|
||||||
|
"url": page.get("url"),
|
||||||
|
"parent_label": page.get("parent"),
|
||||||
|
"idx": page.get("idx"),
|
||||||
|
"parent": "Website Settings",
|
||||||
|
"parenttype": "Website Settings",
|
||||||
|
"parentfield": "top_bar_items",
|
||||||
|
}
|
||||||
|
).save()
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"based_on": "creation",
|
||||||
|
"chart_name": "Lesson Completion",
|
||||||
|
"chart_type": "Count",
|
||||||
|
"color": "#4463F0",
|
||||||
|
"creation": "2022-11-09 16:52:19.021695",
|
||||||
|
"custom_options": "{\"type\": \"line\", \"axisOptions\": {\"xIsSeries\": 1}, \"lineOptions\": {\"regionFill\": 1}}",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Dashboard Chart",
|
||||||
|
"document_type": "LMS Course Progress",
|
||||||
|
"dynamic_filters_json": "[]",
|
||||||
|
"filters_json": "[]",
|
||||||
|
"group_by_type": "Count",
|
||||||
|
"idx": 0,
|
||||||
|
"is_public": 1,
|
||||||
|
"is_standard": 1,
|
||||||
|
"modified": "2022-11-09 16:52:52.241756",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "Lesson Completion",
|
||||||
|
"number_of_groups": 0,
|
||||||
|
"owner": "Administrator",
|
||||||
|
"parent_document_type": "",
|
||||||
|
"roles": [],
|
||||||
|
"source": "",
|
||||||
|
"time_interval": "Daily",
|
||||||
|
"timeseries": 1,
|
||||||
|
"timespan": "Last Month",
|
||||||
|
"type": "Line",
|
||||||
|
"use_report_chart": 0,
|
||||||
|
"value_based_on": "",
|
||||||
|
"y_axis": []
|
||||||
|
}
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "progress",
|
"fieldname": "progress",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Float",
|
||||||
"label": "Progress",
|
"label": "Progress",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-10-10 12:38:17.839525",
|
"modified": "2022-10-10 12:38:17.839526",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Batch Membership",
|
"name": "LMS Batch Membership",
|
||||||
|
|||||||
@@ -654,3 +654,19 @@ def get_chart_data(chart_name, timespan, timegrain, from_date, to_date):
|
|||||||
],
|
],
|
||||||
"datasets": [{"name": chart.name, "values": [r[1] for r in result]}],
|
"datasets": [{"name": chart.name, "values": [r[1] for r in result]}],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist(allow_guest=True)
|
||||||
|
def get_course_completion_data():
|
||||||
|
all_membership = frappe.db.count("LMS Batch Membership")
|
||||||
|
completed = frappe.db.count("LMS Batch Membership", {"progress": ["like", "%100%"]})
|
||||||
|
|
||||||
|
return {
|
||||||
|
"labels": ["Completed", "In Progress"],
|
||||||
|
"datasets": [
|
||||||
|
{
|
||||||
|
"name": "Course Completion",
|
||||||
|
"values": [completed, all_membership - completed],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|||||||
@@ -143,7 +143,7 @@
|
|||||||
"type": "Link"
|
"type": "Link"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2022-11-07 18:49:38.954136",
|
"modified": "2022-11-09 17:16:03.973258",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS",
|
"name": "LMS",
|
||||||
@@ -169,7 +169,7 @@
|
|||||||
"format": "{} Completed",
|
"format": "{} Completed",
|
||||||
"label": "Course Completed",
|
"label": "Course Completed",
|
||||||
"link_to": "LMS Batch Membership",
|
"link_to": "LMS Batch Membership",
|
||||||
"stats_filter": "{\"progress\":[\"=\",\"100\"]}",
|
"stats_filter": "{\"progress\":[\"like\",\"%100%\"]}",
|
||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,4 +34,6 @@ lms.patches.v0_0.create_course_instructor_role #29-08-2022
|
|||||||
lms.patches.v0_0.create_course_moderator_role
|
lms.patches.v0_0.create_course_moderator_role
|
||||||
lms.patches.v0_0.set_dashboard #11-10-2022
|
lms.patches.v0_0.set_dashboard #11-10-2022
|
||||||
lms.patches.v0_0.set_courses_page_as_home
|
lms.patches.v0_0.set_courses_page_as_home
|
||||||
lms.patches.v0_0.set_member_in_progress
|
lms.patches.v0_0.set_member_in_progress #09-11-2022
|
||||||
|
lms.patches.v0_0.convert_progress_to_float
|
||||||
|
lms.patches.v0_0.add_pages_to_nav #11-11-2022
|
||||||
|
|||||||
6
lms/patches/v0_0/add_pages_to_nav.py
Normal file
6
lms/patches/v0_0/add_pages_to_nav.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import frappe
|
||||||
|
from lms.install import add_pages_to_nav
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
add_pages_to_nav()
|
||||||
11
lms/patches/v0_0/convert_progress_to_float.py
Normal file
11
lms/patches/v0_0/convert_progress_to_float.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import frappe
|
||||||
|
from frappe.utils import flt
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.reload_doc("lms", "doctype", "lms_course_progress")
|
||||||
|
progress_records = frappe.get_all("LMS Batch Membership", fields=["name", "progress"])
|
||||||
|
for progress in progress_records:
|
||||||
|
frappe.db.set_value(
|
||||||
|
"LMS Batch Membership", progress.name, "progress", flt(progress.progress)
|
||||||
|
)
|
||||||
@@ -2,6 +2,7 @@ import frappe
|
|||||||
|
|
||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
|
frappe.reload_doc("lms", "doctype", "lms_course_progress")
|
||||||
progress_records = frappe.get_all("LMS Course Progress", fields=["name", "owner"])
|
progress_records = frappe.get_all("LMS Course Progress", fields=["name", "owner"])
|
||||||
|
|
||||||
for progress in progress_records:
|
for progress in progress_records:
|
||||||
|
|||||||
@@ -1715,7 +1715,7 @@ li {
|
|||||||
grid-gap: 2rem;
|
grid-gap: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-pane .stats-parent {
|
.statistics .stats-parent {
|
||||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||||
grid-gap: 1rem;
|
grid-gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,13 @@ frappe.ready(() => {
|
|||||||
$(document).on("click", ".btn-save-chapter", (e) => {
|
$(document).on("click", ".btn-save-chapter", (e) => {
|
||||||
save_chapter(e);
|
save_chapter(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (window.location.pathname == "/statistics") {
|
||||||
|
generate_graph("New Signups", "#new-signups");
|
||||||
|
generate_graph("Course Enrollments", "#course-enrollments");
|
||||||
|
generate_graph("Lesson Completion", "#lesson-completion");
|
||||||
|
generate_course_completion_graph();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const setup_file_size = () => {
|
const setup_file_size = () => {
|
||||||
@@ -155,3 +162,51 @@ const save_chapter = (e) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const generate_graph = (chart_name, element, type = "line") => {
|
||||||
|
let date = frappe.datetime;
|
||||||
|
|
||||||
|
frappe.call({
|
||||||
|
method: "lms.lms.utils.get_chart_data",
|
||||||
|
args: {
|
||||||
|
chart_name: chart_name,
|
||||||
|
timespan: "Select Date Range",
|
||||||
|
timegrain: "Daily",
|
||||||
|
from_date: date.add_days(date.get_today(), -30),
|
||||||
|
to_date: date.add_days(date.get_today(), +1),
|
||||||
|
},
|
||||||
|
callback: (data) => {
|
||||||
|
render_chart(data.message, chart_name, element, type);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const render_chart = (data, chart_name, element, type) => {
|
||||||
|
const chart = new frappe.Chart(element, {
|
||||||
|
title: chart_name,
|
||||||
|
data: data,
|
||||||
|
type: type,
|
||||||
|
height: 250,
|
||||||
|
colors: ["#4563f1"],
|
||||||
|
axisOptions: {
|
||||||
|
xIsSeries: 1,
|
||||||
|
},
|
||||||
|
lineOptions: {
|
||||||
|
regionFill: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const generate_course_completion_graph = () => {
|
||||||
|
frappe.call({
|
||||||
|
method: "lms.lms.utils.get_course_completion_data",
|
||||||
|
callback: (data) => {
|
||||||
|
render_chart(
|
||||||
|
data.message,
|
||||||
|
"Course Completion",
|
||||||
|
"#course-completion",
|
||||||
|
"pie"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
{% if course_completion %}
|
{% if course_completion %}
|
||||||
{% set course_completion_count = frappe.db.count("LMS Batch Membership", {
|
{% set course_completion_count = frappe.db.count("LMS Batch Membership", {
|
||||||
"progress":["=","100"]
|
"progress":["like","%100%"]
|
||||||
}) %}
|
}) %}
|
||||||
<div class="common-card-style p-4 flex-column">
|
<div class="common-card-style p-4 flex-column">
|
||||||
<div class="stats-label">
|
<div class="stats-label">
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
{% set published_courses = True %}
|
|
||||||
{% set total_signups = True %}
|
|
||||||
{% set enrollment_count = True %}
|
|
||||||
{% set course_completion = True %}
|
|
||||||
{% set lesson_completion = True %}
|
|
||||||
{% set quiz_completion = True %}
|
|
||||||
|
|
||||||
<div class="mt-10">
|
|
||||||
{% include "lms/templates/statistics.html" %}
|
|
||||||
|
|
||||||
<div class="row mt-10">
|
|
||||||
<div class="col">
|
|
||||||
<div class="common-card-style p-4" id="new-signups"></div>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div class="common-card-style p-4" id="course-enrollments"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -84,11 +84,6 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" data-toggle="tab" href="#stats">
|
|
||||||
{{ _("Statistics") }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="border-bottom mb-4"></div>
|
<div class="border-bottom mb-4"></div>
|
||||||
@@ -126,10 +121,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="tab-pane fade" id="stats" role="tabpanel" aria-labelledby="stats">
|
|
||||||
{% include "lms/templates/stats.html" %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
frappe.ready(() => {
|
frappe.ready(() => {
|
||||||
generate_graph("New Signups");
|
|
||||||
generate_graph("Course Enrollments");
|
|
||||||
|
|
||||||
$(".nav-link").click((e) => {
|
$(".nav-link").click((e) => {
|
||||||
change_hash(e);
|
change_hash(e);
|
||||||
});
|
});
|
||||||
@@ -11,44 +8,6 @@ frappe.ready(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const generate_graph = (chart_name) => {
|
|
||||||
let date = frappe.datetime;
|
|
||||||
|
|
||||||
frappe.call({
|
|
||||||
method: "lms.lms.utils.get_chart_data",
|
|
||||||
args: {
|
|
||||||
chart_name: chart_name,
|
|
||||||
timespan: "Select Date Range",
|
|
||||||
timegrain: "Daily",
|
|
||||||
from_date: date.add_days(date.get_today(), -30),
|
|
||||||
to_date: date.add_days(date.get_today(), +1),
|
|
||||||
},
|
|
||||||
callback: (data) => {
|
|
||||||
render_chart(data.message, chart_name);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const render_chart = (data, chart_name) => {
|
|
||||||
let dom_element =
|
|
||||||
chart_name == "Course Enrollments"
|
|
||||||
? "#course-enrollments"
|
|
||||||
: "#new-signups";
|
|
||||||
const chart = new frappe.Chart(dom_element, {
|
|
||||||
title: chart_name,
|
|
||||||
data: data,
|
|
||||||
type: "line",
|
|
||||||
height: 250,
|
|
||||||
colors: ["#4563f1"],
|
|
||||||
axisOptions: {
|
|
||||||
xIsSeries: 1,
|
|
||||||
},
|
|
||||||
lineOptions: {
|
|
||||||
regionFill: 1,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const change_hash = (e) => {
|
const change_hash = (e) => {
|
||||||
window.location.hash = $(e.currentTarget).attr("href");
|
window.location.hash = $(e.currentTarget).attr("href");
|
||||||
};
|
};
|
||||||
|
|||||||
0
lms/www/statistics/__init__.py
Normal file
0
lms/www/statistics/__init__.py
Normal file
46
lms/www/statistics/index.html
Normal file
46
lms/www/statistics/index.html
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
{% extends "templates/base.html" %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
{{ _("Statistics") }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="common-page-style statistics">
|
||||||
|
<div class="container">
|
||||||
|
<div class="course-home-headings">
|
||||||
|
{{ _("Statistics") }}
|
||||||
|
</div>
|
||||||
|
{% set published_courses = True %}
|
||||||
|
{% set total_signups = True %}
|
||||||
|
{% set enrollment_count = True %}
|
||||||
|
{% set course_completion = True %}
|
||||||
|
{% set lesson_completion = True %}
|
||||||
|
{% set quiz_completion = True %}
|
||||||
|
|
||||||
|
<div class="mt-10">
|
||||||
|
{% include "lms/templates/statistics.html" %}
|
||||||
|
|
||||||
|
<div class="row mt-10">
|
||||||
|
<div class="col">
|
||||||
|
<div class="common-card-style p-2" id="new-signups"></div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="common-card-style p-2" id="course-enrollments"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-8">
|
||||||
|
<div class="col">
|
||||||
|
<div class="common-card-style p-2" id="lesson-completion"></div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="common-card-style p-2" id="course-completion"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user