diff --git a/lms/hooks.py b/lms/hooks.py index db6a33de..6d5b87f1 100644 --- a/lms/hooks.py +++ b/lms/hooks.py @@ -21,7 +21,7 @@ app_license = "AGPL" # include js, css files in header of web template web_include_css = "lms.bundle.css" # web_include_css = "/assets/lms/css/lms.css" -web_include_js = ["website.bundle.js", "controls.bundle.js"] +web_include_js = ["website.bundle.js"] # include custom scss in every website theme (without file extension ".scss") # website_theme_scss = "lms/public/scss/website" diff --git a/lms/lms/dashboard_chart/new_signups/new_signups.json b/lms/lms/dashboard_chart/new_signups/new_signups.json new file mode 100644 index 00000000..a72c7438 --- /dev/null +++ b/lms/lms/dashboard_chart/new_signups/new_signups.json @@ -0,0 +1,32 @@ +{ + "based_on": "creation", + "chart_name": "New Signups", + "chart_type": "Count", + "color": "#4463F0", + "creation": "2021-09-28 18:57:50.047656", + "docstatus": 0, + "doctype": "Dashboard Chart", + "document_type": "User", + "dynamic_filters_json": "[]", + "filters_json": "[]", + "group_by_type": "Count", + "idx": 1, + "is_public": 1, + "is_standard": 1, + "last_synced_on": "2022-10-14 15:57:47.583435", + "modified": "2022-10-14 17:20:21.880532", + "modified_by": "Administrator", + "module": "LMS", + "name": "New Signups", + "number_of_groups": 0, + "owner": "basawaraj@erpnext.com", + "roles": [], + "source": "", + "time_interval": "Daily", + "timeseries": 1, + "timespan": "Last Quarter", + "type": "Line", + "use_report_chart": 0, + "value_based_on": "", + "y_axis": [] +} \ No newline at end of file diff --git a/lms/lms/utils.py b/lms/lms/utils.py index baf6dbee..04939d1b 100644 --- a/lms/lms/utils.py +++ b/lms/lms/utils.py @@ -1,10 +1,13 @@ import re import frappe -from frappe.utils import flt, cint, cstr, getdate, add_months, fmt_money +from frappe.utils import flt, cint, cstr, getdate, add_months, fmt_money, get_datetime, format_date from lms.lms.md import markdown_to_html, find_macros import string from frappe import _ from frappe.desk.doctype.notification_log.notification_log import make_notification_logs +from frappe.desk.doctype.dashboard_chart.dashboard_chart import get_result +from frappe.utils.dateutils import get_period + RE_SLUG_NOTALLOWED = re.compile("[^a-z0-9]+") @@ -546,3 +549,38 @@ def get_filtered_membership(course, memberships): def show_start_learing_cta(course, membership): return not course.disable_self_learning and not membership and not course.upcoming \ and not check_profile_restriction() and not is_instructor(course.name) and course.status == "Approved" + + +@frappe.whitelist(allow_guest=True) +def get_chart_data(chart_name, timespan, timegrain, from_date, to_date): + chart = frappe.get_doc("Dashboard Chart", chart_name) + filters = [([chart.document_type, "docstatus", "<", 2, False])] + doctype = chart.document_type + datefield = chart.based_on + value_field = chart.value_based_on or "1" + from_date = get_datetime(from_date).strftime("%Y-%m-%d") + to_date = get_datetime(to_date) + + filters.append([doctype, datefield, ">=", from_date, False]) + filters.append([doctype, datefield, "<=", to_date, False]) + + data = frappe.db.get_all( + doctype, + fields=[f"{datefield} as _unit", f"SUM({value_field})", "COUNT(*)"], + filters=filters, + group_by="_unit", + order_by="_unit asc", + as_list=True, + ) + + result = get_result(data, timegrain, from_date, to_date, chart.chart_type) + + return { + "labels": [ + format_date(get_period(r[0], timegrain), parse_day_first=True) + if timegrain in ("Daily", "Weekly") + else get_period(r[0], timegrain) + for r in result + ], + "datasets": [{"name": chart.name, "values": [r[1] for r in result]}], + } diff --git a/lms/public/css/style.css b/lms/public/css/style.css index 6a6846a5..c5a6a861 100644 --- a/lms/public/css/style.css +++ b/lms/public/css/style.css @@ -1718,20 +1718,15 @@ li { } .stats-label { - color: var(--text-muted); - font-weight: bold; + color: var(--gray-900); + font-weight: 500; } .stats-value { color: var(--gray-900); - font-weight: 600; - font-size: 2rem; -} - -.stats-card { - display: flex; - flex-direction: column; - align-items: center; + font-weight: 500; + font-size: 1.5rem; + margin-top: 2rem; } .indicator-pill.green::before { @@ -1774,3 +1769,9 @@ li { .modal-header .modal-title { color: var(--gray-900); } + +.frappe-chart .title { + font-size: 1rem; + font-weight: bold; + color: var(--gray-900); +} diff --git a/lms/public/js/common_functions.js b/lms/public/js/common_functions.js index 88fa7aec..c8815f85 100644 --- a/lms/public/js/common_functions.js +++ b/lms/public/js/common_functions.js @@ -1,6 +1,6 @@ frappe.ready(() => { - setup_vue_and_file_size(); + setup_file_size(); $(".join-batch").click((e) => { join_course(e); @@ -21,12 +21,7 @@ frappe.ready(() => { }); -const setup_vue_and_file_size = () => { - frappe.require("/assets/frappe/node_modules/vue/dist/vue.js", () => { - Vue.prototype.__ = window.__; - Vue.prototype.frappe = window.frappe; - }); - +const setup_file_size = () => { frappe.provide("frappe.form.formatters"); frappe.form.formatters.FileSize = file_size; }; diff --git a/lms/public/js/website.bundle.js b/lms/public/js/website.bundle.js index 628957f6..d32bbaa5 100644 --- a/lms/public/js/website.bundle.js +++ b/lms/public/js/website.bundle.js @@ -1,2 +1,3 @@ import "./profile.js" import "./common_functions.js" +import "../../../../frappe/frappe/public/js/frappe/ui/chart.js" diff --git a/lms/templates/courses_created.html b/lms/templates/courses_created.html index 1bcc0d4a..2711bc02 100644 --- a/lms/templates/courses_created.html +++ b/lms/templates/courses_created.html @@ -1,4 +1,4 @@ -{% set courses = get_authored_courses(user or None, only_published or False) %} +{% set courses = courses_created if courses_created else get_authored_courses(user or None, only_published or False) %} {% if courses | length %}