From f79a43d5f30bb2ec0f5894465dce4def5952168e Mon Sep 17 00:00:00 2001 From: prssanna Date: Wed, 1 Apr 2020 00:09:40 +0530 Subject: [PATCH] feat: save dashboard chart config for user --- frappe/core/page/dashboard/dashboard.js | 36 +++++++------ .../doctype/dashboard_settings/__init__.py | 0 .../dashboard_settings/dashboard_settings.js | 8 +++ .../dashboard_settings.json | 51 +++++++++++++++++++ .../dashboard_settings/dashboard_settings.py | 39 ++++++++++++++ frappe/hooks.py | 1 + .../public/js/frappe/utils/dashboard_utils.js | 21 ++++++++ .../public/js/frappe/views/desktop/desktop.js | 40 ++++++++++----- .../public/js/frappe/widgets/chart_widget.js | 49 ++++++++++++------ 9 files changed, 202 insertions(+), 43 deletions(-) create mode 100644 frappe/desk/doctype/dashboard_settings/__init__.py create mode 100644 frappe/desk/doctype/dashboard_settings/dashboard_settings.js create mode 100644 frappe/desk/doctype/dashboard_settings/dashboard_settings.json create mode 100644 frappe/desk/doctype/dashboard_settings/dashboard_settings.py diff --git a/frappe/core/page/dashboard/dashboard.js b/frappe/core/page/dashboard/dashboard.js index 8705804014..88bfba9e84 100644 --- a/frappe/core/page/dashboard/dashboard.js +++ b/frappe/core/page/dashboard/dashboard.js @@ -80,23 +80,27 @@ class Dashboard { if (!charts.length) { frappe.msgprint(__('No Permitted Charts on this Dashboard'), __('No Permitted Charts')) } - this.charts = charts - .map(chart => { - return { - chart_name: chart.chart, - label: chart.chart, - ...chart - } - }); - this.chart_group = new frappe.widget.WidgetGroup({ - title: null, - container: this.container, - type: "chart", - columns: 2, - allow_sorting: false, - widgets: this.charts, - }); + frappe.dashboard_utils.get_dashboard_settings().then((settings) => { + let chart_config = settings.chart_config? JSON.parse(settings.chart_config): {}; + this.charts = + charts.map(chart => { + return { + chart_name: chart.chart, + label: chart.chart, + chart_settings: chart_config[chart.chart] || {}, + ...chart + } + }); + this.chart_group = new frappe.widget.WidgetGroup({ + title: null, + container: this.container, + type: "chart", + columns: 2, + allow_sorting: false, + widgets: this.charts, + }); + }) }); } diff --git a/frappe/desk/doctype/dashboard_settings/__init__.py b/frappe/desk/doctype/dashboard_settings/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frappe/desk/doctype/dashboard_settings/dashboard_settings.js b/frappe/desk/doctype/dashboard_settings/dashboard_settings.js new file mode 100644 index 0000000000..8e7966366d --- /dev/null +++ b/frappe/desk/doctype/dashboard_settings/dashboard_settings.js @@ -0,0 +1,8 @@ +// Copyright (c) 2020, Frappe Technologies and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Dashboard Settings', { + // refresh: function(frm) { + + // } +}); diff --git a/frappe/desk/doctype/dashboard_settings/dashboard_settings.json b/frappe/desk/doctype/dashboard_settings/dashboard_settings.json new file mode 100644 index 0000000000..e1eb75db47 --- /dev/null +++ b/frappe/desk/doctype/dashboard_settings/dashboard_settings.json @@ -0,0 +1,51 @@ +{ + "actions": [], + "autoname": "Prompt", + "creation": "2020-03-31 19:41:45.785014", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "user", + "chart_config" + ], + "fields": [ + { + "fieldname": "user", + "fieldtype": "Link", + "label": "User", + "options": "User", + "read_only": 1 + }, + { + "fieldname": "chart_config", + "fieldtype": "Code", + "label": "Chart Configuration", + "options": "JSON", + "read_only": 1 + } + ], + "in_create": 1, + "links": [], + "modified": "2020-04-01 00:07:26.489561", + "modified_by": "Administrator", + "module": "Desk", + "name": "Dashboard Settings", + "owner": "Administrator", + "permissions": [ + { + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "All", + "share": 1, + "write": 1 + } + ], + "read_only": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/frappe/desk/doctype/dashboard_settings/dashboard_settings.py b/frappe/desk/doctype/dashboard_settings/dashboard_settings.py new file mode 100644 index 0000000000..ce7f2979c7 --- /dev/null +++ b/frappe/desk/doctype/dashboard_settings/dashboard_settings.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +# import frappe +from frappe.model.document import Document +import frappe +import json + +class DashboardSettings(Document): + pass + + +@frappe.whitelist() +def create_dashboard_settings(user): + if not frappe.db.exists("Dashboard Settings", user): + doc = frappe.new_doc('Dashboard Settings') + doc.name = user + doc.insert(ignore_permissions=True) + frappe.db.commit() + return doc + +def get_permission_query_conditions(user): + if not user: user = frappe.session.user + + return '''(`tabDashboard Settings`.name = '{user}')'''.format(user=user) + +@frappe.whitelist() +def save_chart_config(config, chart_name): + config = frappe.parse_json(config) + doc = frappe.get_doc('Dashboard Settings', frappe.session.user) + chart_config = frappe.parse_json(doc.chart_config) or {} + + if not chart_name in chart_config: + chart_config[chart_name] = {} + + chart_config[chart_name].update(config) + frappe.db.set_value('Dashboard Settings', frappe.session.user, 'chart_config', json.dumps(chart_config)) \ No newline at end of file diff --git a/frappe/hooks.py b/frappe/hooks.py index 733cec7a08..4f65303be9 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -86,6 +86,7 @@ permission_query_conditions = { "Event": "frappe.desk.doctype.event.event.get_permission_query_conditions", "ToDo": "frappe.desk.doctype.todo.todo.get_permission_query_conditions", "User": "frappe.core.doctype.user.user.get_permission_query_conditions", + "Dashboard Settings": "frappe.desk.doctype.dashboard_settings.dashboard_settings.get_permission_query_conditions", "Notification Log": "frappe.desk.doctype.notification_log.notification_log.get_permission_query_conditions", "Dashboard Chart": "frappe.desk.doctype.dashboard_chart.dashboard_chart.get_permission_query_conditions", "Notification Settings": "frappe.desk.doctype.notification_settings.notification_settings.get_permission_query_conditions", diff --git a/frappe/public/js/frappe/utils/dashboard_utils.js b/frappe/public/js/frappe/utils/dashboard_utils.js index 7e64f5c143..66f3d5e21f 100644 --- a/frappe/public/js/frappe/utils/dashboard_utils.js +++ b/frappe/public/js/frappe/utils/dashboard_utils.js @@ -54,5 +54,26 @@ frappe.dashboard_utils = { } else { return Promise.resolve(); } + }, + + get_dashboard_settings() { + return frappe.model.with_doc('Dashboard Settings', frappe.session.user).then(settings => { + if (!settings) { + return this.create_dashboard_settings().then(settings => { + return settings; + }); + } else { + return settings; + } + }); + }, + + create_dashboard_settings() { + return frappe.xcall( + 'frappe.desk.doctype.dashboard_settings.dashboard_settings.create_dashboard_settings', + {user: frappe.session.user} + ).then(settings => { + return settings; + }); } }; \ No newline at end of file diff --git a/frappe/public/js/frappe/views/desktop/desktop.js b/frappe/public/js/frappe/views/desktop/desktop.js index 54a25c3771..3a95ec1d90 100644 --- a/frappe/public/js/frappe/views/desktop/desktop.js +++ b/frappe/public/js/frappe/views/desktop/desktop.js @@ -165,11 +165,18 @@ class DesktopPage { this.allow_customization = this.data.allow_customization || false; - !this.sections["onboarding"] && - this.data.charts.items.length && - this.make_charts(); - this.data.shortcuts.items.length && this.make_shortcuts(); - this.data.cards.items.length && this.make_cards(); + let create_shortcuts_and_cards = () => { + this.data.shortcuts.items.length && this.make_shortcuts(); + this.data.cards.items.length && this.make_cards(); + } + + if (!this.sections["onboarding"] && this.data.charts.items.length) { + this.make_charts().then(() => { + create_shortcuts_and_cards(); + }); + } else { + create_shortcuts_and_cards(); + } }); } @@ -224,13 +231,22 @@ class DesktopPage { } make_charts() { - this.sections["charts"] = new frappe.widget.WidgetGroup({ - title: this.data.charts.label || `${this.page_name} Dashboard`, - container: this.page, - type: "chart", - columns: 1, - allow_sorting: false, - widgets: this.data.charts.items + return frappe.dashboard_utils.get_dashboard_settings().then(settings => { + let chart_config = settings.chart_config? JSON.parse(settings.chart_config): {}; + if (this.data.charts.items) { + this.data.charts.items.map(chart => { + chart.chart_settings = chart_config[chart.chart_name] || {} + }); + } + + this.sections["charts"] = new frappe.widget.WidgetGroup({ + title: this.data.charts.label || `${this.page_name} Dashboard`, + container: this.page, + type: "chart", + columns: 1, + allow_sorting: false, + widgets: this.data.charts.items + }); }); } diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index 3388890776..4fc00ef9c9 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -62,6 +62,9 @@ export default class ChartWidget extends Widget { make_chart() { this.get_settings().then(() => { + if (!this.chart_settings) { + this.chart_settings = {}; + } this.setup_container(); this.prepare_chart_object(); this.action_area.empty(); @@ -89,7 +92,7 @@ export default class ChartWidget extends Widget { render_time_series_filters() { let filters = [ { - label: this.chart_doc.timespan, + label: this.chart_settings.timespan || this.chart_doc.timespan, options: [ "Select Date Range", "Last Year", @@ -116,13 +119,16 @@ export default class ChartWidget extends Widget { this.fetch_and_update_chart(); } + this.save_chart_config_for_user({'timespan': this.selected_timespan}) } }, { - label: this.chart_doc.time_interval, + label: this.chart_settings.time_interval || this.chart_doc.time_interval, options: ["Yearly", "Quarterly", "Monthly", "Weekly", "Daily"], action: selected_item => { this.selected_time_interval = selected_item; + + this.save_chart_config_for_user({'time_interval': this.selected_time_interval}) this.fetch_and_update_chart(); } } @@ -138,10 +144,10 @@ export default class ChartWidget extends Widget { fetch_and_update_chart() { this.args = { - timespan: this.selected_timespan, - time_interval: this.selected_time_interval, - from_date: this.selected_from_date, - to_date: this.selected_to_date + timespan: this.selected_timespan || this.chart_settings.timespan, + time_interval: this.selected_time_interval || this.chart_settings.time_interval, + from_date: this.selected_from_date || this.chart_settings.from_date, + to_date: this.selected_to_date || this.chart_settings.to_date }; this.fetch(this.filters, true, this.args).then(data => { @@ -176,16 +182,18 @@ export default class ChartWidget extends Widget { fieldname: "from_date", placeholder: "Date Range", input_class: "input-xs", + default: [this.chart_settings.from_date, this.chart_settings.to_date], reqd: 1, change: () => { let selected_date_range = this.date_range_field.get_value(); this.selected_from_date = selected_date_range[0]; this.selected_to_date = selected_date_range[1]; - if ( - selected_date_range && - selected_date_range.length == 2 - ) { + if (selected_date_range && selected_date_range.length == 2) { + this.save_chart_config_for_user({ + 'from_date': this.selected_from_date, + 'to_date': this.selected_to_date, + }); this.fetch_and_update_chart(); } } @@ -334,6 +342,7 @@ export default class ChartWidget extends Widget { } else { me.filters = values; } + me.save_chart_config_for_user({'filters': me.filters}); me.fetch_and_update_chart(); } }, @@ -350,6 +359,15 @@ export default class ChartWidget extends Widget { dialog.set_values(this.filters); } + save_chart_config_for_user(config) { + Object.assign(this.chart_settings, config); + frappe.xcall('frappe.desk.doctype.dashboard_settings.dashboard_settings.save_chart_config', + { + 'config': this.chart_settings, + 'chart_name': this.chart_doc.chart_name + }); + } + create_filter_group_and_add_filters(parent) { this.filter_group = new frappe.ui.FilterGroup({ parent: parent, @@ -406,10 +424,10 @@ export default class ChartWidget extends Widget { filters: filters, refresh: refresh ? 1 : 0, time_interval: - args && args.time_interval ? args.time_interval : null, - timespan: args && args.timespan ? args.timespan : null, - from_date: args && args.from_date ? args.from_date : null, - to_date: args && args.to_date ? args.to_date : null + args && args.time_interval? args.time_interval: null, + timespan: args && args.timespan? args.timespan: null, + from_date: args && args.from_date? args.from_date: null, + to_date: args && args.to_date? args.to_date: null }; } return frappe.xcall(method, args); @@ -481,8 +499,9 @@ export default class ChartWidget extends Widget { } prepare_chart_object() { + let saved_filters = this.chart_settings.filters || null; this.filters = - this.filters || JSON.parse(this.chart_doc.filters_json || "[]"); + saved_filters || this.filters || JSON.parse(this.chart_doc.filters_json || "[]"); } get_settings() {