diff --git a/frappe/core/page/dashboard/dashboard.js b/frappe/core/page/dashboard/dashboard.js index 655bbe7444..cf082d8d27 100644 --- a/frappe/core/page/dashboard/dashboard.js +++ b/frappe/core/page/dashboard/dashboard.js @@ -1,3 +1,8 @@ +// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors +// MIT License. See license.txt + +frappe.provide("frappe.dashboard_chart_sources"); + frappe.pages['dashboard'].on_page_load = function(wrapper) { frappe.ui.make_app_page({ parent: wrapper, @@ -60,12 +65,14 @@ class DashboardChart { } show() { - this.prepare_chart_object(); - this.prepare_container(); - this.fetch().then((data) => { - this.update_last_synced(); - this.data = data; - this.render(); + this.get_settings().then(() => { + this.prepare_chart_object(); + this.prepare_container(); + this.fetch().then((data) => { + this.update_last_synced(); + this.data = data; + this.render(); + }); }); } @@ -90,7 +97,7 @@ class DashboardChart { handler: () => { const d = new frappe.ui.Dialog({ title: __('Set Filters'), - fields: this.filter_fields, + fields: this.settings.filters, }); d.set_values(this.filters); d.show(); @@ -109,7 +116,7 @@ class DashboardChart { d.hide(); }; - this.filter_fields.map(field => field.onchange = e => { + this.settings.filters.map(field => field.onchange = e => { if(e) { d.set_primary_action(__('Save Filters'), set_filters); } @@ -150,10 +157,9 @@ class DashboardChart { fetch(refresh=false) { return frappe.xcall( - "frappe.core.page.dashboard.dashboard.get_data", + this.settings.method_path, { - chart_name: this.chart_doc.name, - refresh: refresh, + filters: this.filters, } ); } @@ -191,6 +197,23 @@ class DashboardChart { prepare_chart_object() { this.filters = JSON.parse(this.chart_doc.filters_json || '{}'); - this.filter_fields = JSON.parse(this.chart_doc.filter_fields || '[]'); + } + + get_settings() { + if (frappe.dashboard_chart_sources && frappe.dashboard_chart_sources[this.chart_doc.source]) { + return this._load_script; + } + this._load_script = new Promise(resolve => frappe.call({ + method: 'frappe.core.page.dashboard.dashboard.get_script', + args: { + source_name: this.chart_doc.source + }, + callback: result => { + frappe.dom.eval(result.message.script || ''); + this.settings = frappe.dashboard_chart_sources[this.chart_doc.source]; + resolve(); + } + })); + return this._load_script; } } \ No newline at end of file diff --git a/frappe/core/page/dashboard/dashboard.py b/frappe/core/page/dashboard/dashboard.py index e88d990788..3c3aae3800 100644 --- a/frappe/core/page/dashboard/dashboard.py +++ b/frappe/core/page/dashboard/dashboard.py @@ -2,7 +2,10 @@ # MIT License. See license.txt from __future__ import unicode_literals import json +import os import frappe +from frappe.modules import get_module_path +from frappe.model.utils import render_include @frappe.whitelist() @@ -30,3 +33,19 @@ def generate_and_cache_results(chart, filters, cache_key): frappe.cache().set_value(cache_key, json.dumps(results, default=str)) frappe.db.set_value("Dashboard Chart", chart.name, "last_synced_on", frappe.utils.now()) return results + + +@frappe.whitelist() +def get_script(source_name): + source = frappe.get_doc("Dashboard Chart Source", source_name) + module_path = get_module_path(source.module) + scrubbed_source_name = frappe.scrub(source_name) + script_path = os.path.join(module_path, "dashboard_chart_source", scrubbed_source_name, scrubbed_source_name + ".js") + + if os.path.exists(script_path): + with open(script_path, "r") as f: + script = f.read() + + return { + "script": render_include(script), + } diff --git a/frappe/desk/doctype/dashboard_chart/dashboard_chart.json b/frappe/desk/doctype/dashboard_chart/dashboard_chart.json index fa606abb88..9cb71f2a34 100644 --- a/frappe/desk/doctype/dashboard_chart/dashboard_chart.json +++ b/frappe/desk/doctype/dashboard_chart/dashboard_chart.json @@ -4,6 +4,7 @@ "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, + "autoname": "field:chart_name", "beta": 0, "creation": "2019-01-10 12:28:06.282875", "custom": 0, @@ -43,7 +44,7 @@ "search_index": 0, "set_only_once": 0, "translatable": 0, - "unique": 0 + "unique": 1 }, { "allow_bulk_edit": 0, @@ -52,7 +53,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "column_break_2", + "fieldname": "column_break_6", "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, @@ -83,18 +84,19 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "method_path", - "fieldtype": "Data", + "fieldname": "source", + "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 1, + "in_list_view": 0, "in_standard_filter": 0, - "label": "Method Path", + "label": "Chart Source", "length": 0, "no_copy": 0, + "options": "Dashboard Chart Source", "permlevel": 0, "precision": "", "print_hide": 0, @@ -115,7 +117,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "chart_details_section", + "fieldname": "filters_section", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -124,7 +126,72 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Chart Details", + "label": "Filters", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "filters_json", + "fieldtype": "Code", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Filters JSON", + "length": 0, + "no_copy": 0, + "options": "JSON", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "chart_options_section", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Chart Options", "length": 0, "no_copy": 0, "permlevel": 0, @@ -213,7 +280,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "column_break_6", + "fieldname": "column_break_2", "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, @@ -276,7 +343,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "filter_details_section", + "fieldname": "section_break_10", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -285,7 +352,6 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Filter Details", "length": 0, "no_copy": 0, "permlevel": 0, @@ -301,70 +367,6 @@ "translatable": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_9", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "filter_fields", - "fieldtype": "Code", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Filter Fields", - "length": 0, - "no_copy": 0, - "options": "JSON", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -388,7 +390,7 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, @@ -396,70 +398,6 @@ "set_only_once": 0, "translatable": 0, "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_11", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "filters_json", - "fieldtype": "Code", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Filters JSON", - "length": 0, - "no_copy": 0, - "options": "JSON", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 } ], "has_web_view": 0, @@ -472,7 +410,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2019-01-16 20:10:54.811477", + "modified": "2019-02-06 09:27:26.109148", "modified_by": "Administrator", "module": "Desk", "name": "Dashboard Chart", @@ -505,7 +443,7 @@ "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", - "title_field": "chart_name", + "title_field": "", "track_changes": 1, "track_seen": 0, "track_views": 0