feat: statistics page

This commit is contained in:
Jannat Patel
2022-11-10 20:21:43 +05:30
parent f1746978b2
commit c8dbc18179
15 changed files with 186 additions and 97 deletions

View File

@@ -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": []
}

View File

@@ -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",

View File

@@ -654,3 +654,24 @@ 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
],
}
],
}

View File

@@ -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"
}, },
{ {

View File

@@ -34,4 +34,5 @@ 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

View File

@@ -0,0 +1,8 @@
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))

View File

@@ -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:

View File

@@ -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;
} }

View File

@@ -16,6 +16,14 @@ 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 = () => {
@@ -51,13 +59,10 @@ const join_course = (e) => {
callback: (data) => { callback: (data) => {
if (data.message == "OK") { if (data.message == "OK") {
$(".no-preview-modal").modal("hide"); $(".no-preview-modal").modal("hide");
frappe.show_alert( frappe.show_alert({
{ message: __("Enrolled successfully"),
message: __("Enrolled successfully"), indicator: "green",
indicator: "green", }, 3);
},
3
);
setTimeout(function () { setTimeout(function () {
window.location.href = `/courses/${course}/learn/1.1`; window.location.href = `/courses/${course}/learn/1.1`;
}, 1000); }, 1000);
@@ -81,15 +86,12 @@ const notify_user = (e) => {
}, },
callback: (data) => { callback: (data) => {
$(".no-preview-modal").modal("hide"); $(".no-preview-modal").modal("hide");
frappe.show_alert( frappe.show_alert({
{ message: __(
message: __( "You have opted to be notified for this course. You will receive an email when the course becomes available."
"You have opted to be notified for this course. You will receive an email when the course becomes available." ),
), indicator: "green",
indicator: "green", }, 3);
},
3
);
setTimeout(() => { setTimeout(() => {
window.location.reload(); window.location.reload();
}, 3000); }, 3000);
@@ -121,16 +123,15 @@ const add_chapter = (e) => {
scroll_to_chapter_container(); scroll_to_chapter_container();
}; };
const scroll_to_chapter_container = () => { const scroll_to_chapter_container = () => {
$([document.documentElement, document.body]).animate( $([document.documentElement, document.body]).animate({
{ scrollTop: $(".new-chapter").offset().top,
scrollTop: $(".new-chapter").offset().top, }, 1000);
},
1000
);
$(".new-chapter").find(".chapter-title-main").focus(); $(".new-chapter").find(".chapter-title-main").focus();
}; };
const save_chapter = (e) => { const save_chapter = (e) => {
let target = $(e.currentTarget); let target = $(e.currentTarget);
let parent = target.closest(".chapter-parent"); let parent = target.closest(".chapter-parent");
@@ -155,3 +156,47 @@ 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")
}
})
}

View File

@@ -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">

View File

@@ -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>

View File

@@ -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 %}

View File

@@ -1,6 +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);
@@ -9,45 +7,9 @@ frappe.ready(() => {
if (window.location.hash) { if (window.location.hash) {
open_tab(); open_tab();
} }
}); });
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");

View File

View 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 %}