From a9133ebcf611f5fc4c303eca148fefa447909fef Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 31 Jan 2020 12:57:35 +0530 Subject: [PATCH 001/140] feat: Optionally trigger doc events while updating doc from notification --- frappe/email/doctype/notification/notification.json | 11 ++++++++++- frappe/email/doctype/notification/notification.py | 13 ++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/frappe/email/doctype/notification/notification.json b/frappe/email/doctype/notification/notification.json index 14eff2251a..40d8de4d29 100644 --- a/frappe/email/doctype/notification/notification.json +++ b/frappe/email/doctype/notification/notification.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_rename": 1, "autoname": "Prompt", "creation": "2014-07-11 17:18:09.923399", @@ -30,6 +31,7 @@ "property_section", "set_property_after_alert", "property_value", + "trigger_document_events", "column_break_5", "recipients", "message_sb", @@ -260,10 +262,17 @@ "fieldtype": "Link", "label": "Print Format", "options": "Print Format" + }, + { + "default": "0", + "fieldname": "trigger_document_events", + "fieldtype": "Check", + "label": "Trigger Document Events" } ], "icon": "fa fa-envelope", - "modified": "2019-07-15 13:17:02.585013", + "links": [], + "modified": "2020-01-24 11:26:48.454013", "modified_by": "Administrator", "module": "Email", "name": "Notification", diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py index d40f64b8bd..a614b7e873 100644 --- a/frappe/email/doctype/notification/notification.py +++ b/frappe/email/doctype/notification/notification.py @@ -129,11 +129,14 @@ def get_context(context): allow_update = True if doc.docstatus == 1 and not doc.meta.get_field(self.set_property_after_alert).allow_on_submit: allow_update = False - - if allow_update: - frappe.db.set_value(doc.doctype, doc.name, self.set_property_after_alert, - self.property_value, update_modified = False) - doc.set(self.set_property_after_alert, self.property_value) + try: + if allow_update: + frappe.db.set_value(doc.doctype, doc.name, self.set_property_after_alert, + self.property_value, update_modified = False) + doc.set(self.set_property_after_alert, self.property_value) + doc.save() + except Exception as e: + frappe.log_error(title=_('Document update failed'), message=frappe.get_traceback()) def send_an_email(self, doc, context): from email.utils import formataddr From 8e4544567adb3fd7ad319e2175cd79702154b8ff Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 3 Feb 2020 08:11:20 +0530 Subject: [PATCH 002/140] fix: Optionally call doc.save() method --- frappe/email/doctype/notification/notification.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py index a614b7e873..bdc1a4a75d 100644 --- a/frappe/email/doctype/notification/notification.py +++ b/frappe/email/doctype/notification/notification.py @@ -134,7 +134,8 @@ def get_context(context): frappe.db.set_value(doc.doctype, doc.name, self.set_property_after_alert, self.property_value, update_modified = False) doc.set(self.set_property_after_alert, self.property_value) - doc.save() + if self.trigger_document_events: + doc.save() except Exception as e: frappe.log_error(title=_('Document update failed'), message=frappe.get_traceback()) From c132938883f911e921329b236bd084245d478bd2 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 6 Feb 2020 10:41:48 +0530 Subject: [PATCH 003/140] fix: Do doc.save() on every update from notification --- frappe/email/doctype/notification/notification.json | 11 +---------- frappe/email/doctype/notification/notification.py | 5 +---- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/frappe/email/doctype/notification/notification.json b/frappe/email/doctype/notification/notification.json index 40d8de4d29..14eff2251a 100644 --- a/frappe/email/doctype/notification/notification.json +++ b/frappe/email/doctype/notification/notification.json @@ -1,5 +1,4 @@ { - "actions": [], "allow_rename": 1, "autoname": "Prompt", "creation": "2014-07-11 17:18:09.923399", @@ -31,7 +30,6 @@ "property_section", "set_property_after_alert", "property_value", - "trigger_document_events", "column_break_5", "recipients", "message_sb", @@ -262,17 +260,10 @@ "fieldtype": "Link", "label": "Print Format", "options": "Print Format" - }, - { - "default": "0", - "fieldname": "trigger_document_events", - "fieldtype": "Check", - "label": "Trigger Document Events" } ], "icon": "fa fa-envelope", - "links": [], - "modified": "2020-01-24 11:26:48.454013", + "modified": "2019-07-15 13:17:02.585013", "modified_by": "Administrator", "module": "Email", "name": "Notification", diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py index 381c18b95a..997aba3069 100644 --- a/frappe/email/doctype/notification/notification.py +++ b/frappe/email/doctype/notification/notification.py @@ -131,11 +131,8 @@ def get_context(context): allow_update = False try: if allow_update: - frappe.db.set_value(doc.doctype, doc.name, self.set_property_after_alert, - self.property_value, update_modified = False) doc.set(self.set_property_after_alert, self.property_value) - if self.trigger_document_events: - doc.save() + doc.save() except Exception as e: frappe.log_error(title=_('Document update failed'), message=frappe.get_traceback()) From 253cc87f2426acfc5845af2139d0651e68ece18b Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 6 Feb 2020 10:43:44 +0530 Subject: [PATCH 004/140] feat: Display system updater reference on timeline --- frappe/core/doctype/version/version.py | 6 ++- .../doctype/notification/notification.py | 4 ++ .../public/js/frappe/form/footer/timeline.js | 38 ++++++++++++------- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/frappe/core/doctype/version/version.py b/frappe/core/doctype/version/version.py index 05cc102ab9..3a97582376 100644 --- a/frappe/core/doctype/version/version.py +++ b/frappe/core/doctype/version/version.py @@ -45,7 +45,11 @@ def get_diff(old, new, for_child=False): # capture data import if set data_import = new.flags.via_data_import - out = frappe._dict(changed = [], added = [], removed = [], row_changed = [], data_import=data_import) + updater_reference = new.flags.updater_reference + + out = frappe._dict(changed = [], added = [], removed = [], + row_changed = [], data_import=data_import, updater_reference=updater_reference) + for df in new.meta.fields: if df.fieldtype in no_value_fields and df.fieldtype not in table_fields: continue diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py index 997aba3069..31a39724ef 100644 --- a/frappe/email/doctype/notification/notification.py +++ b/frappe/email/doctype/notification/notification.py @@ -132,6 +132,10 @@ def get_context(context): try: if allow_update: doc.set(self.set_property_after_alert, self.property_value) + doc.flags.updater_reference = { + 'doctype': self.doctype, + 'docname': self.name + } doc.save() except Exception as e: frappe.log_error(title=_('Document update failed'), message=frappe.get_traceback()) diff --git a/frappe/public/js/frappe/form/footer/timeline.js b/frappe/public/js/frappe/form/footer/timeline.js index e7f5f4023f..5b02f06728 100644 --- a/frappe/public/js/frappe/form/footer/timeline.js +++ b/frappe/public/js/frappe/form/footer/timeline.js @@ -560,12 +560,24 @@ frappe.ui.form.Timeline = class Timeline { return; } - let data_import_link = frappe.utils.get_form_link( - 'Data Import Beta', - data.data_import, - true, - __('via Data Import') - ); + let updater_reference_link = null; + + if (data.data_import) { + updater_reference_link = frappe.utils.get_form_link( + 'Data Import Beta', + data.data_import, + true, + __('via Data Import') + ); + } else if (!$.isEmptyObject(data.updater_reference)) { + let updater_reference = data.updater_reference; + updater_reference_link = frappe.utils.get_form_link( + updater_reference.doctype, + updater_reference.docname, + true, + __('via {0}', [updater_reference.doctype]) + ); + } // value changed in parent if (data.changed && data.changed.length) { @@ -573,13 +585,13 @@ frappe.ui.form.Timeline = class Timeline { data.changed.every(function(p) { if (p[0]==='docstatus') { if (p[2]==1) { - let message = data.data_import - ? __('submitted this document {0}', [data_import_link]) + let message = updater_reference_link + ? __('submitted this document {0}', [updater_reference_link]) : __('submitted this document'); out.push(me.get_version_comment(version, message)); } else if (p[2]==2) { - let message = data.data_import - ? __('cancelled this document {0}', [data_import_link]) + let message = updater_reference_link + ? __('cancelled this document {0}', [updater_reference_link]) : __('cancelled this document'); out.push(me.get_version_comment(version, message)); } @@ -600,10 +612,10 @@ frappe.ui.form.Timeline = class Timeline { } return parts.length < 3; }); - if(parts.length) { + if (parts.length) { let message; - if (data.data_import) { - message = __("changed value of {0} {1}", [parts.join(', ').bold(), data_import_link]); + if (updater_reference_link) { + message = __("changed value of {0} {1}", [parts.join(', ').bold(), updater_reference_link]); } else { message = __("changed value of {0}", [parts.join(', ').bold()]); } From 503ce9a0d97d20418230ca5032d8fde6752c9b12 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 7 Feb 2020 13:14:18 +0530 Subject: [PATCH 005/140] fix: Remove Data Import specific code from timeline --- .../core/doctype/data_import/importer_new.py | 6 +++++- .../public/js/frappe/form/footer/timeline.js | 18 ++++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/frappe/core/doctype/data_import/importer_new.py b/frappe/core/doctype/data_import/importer_new.py index 22c4778147..a2d82d6133 100644 --- a/frappe/core/doctype/data_import/importer_new.py +++ b/frappe/core/doctype/data_import/importer_new.py @@ -799,7 +799,11 @@ class Importer: id_fieldname = self.get_id_fieldname(self.doctype) id_value = doc[id_fieldname] existing_doc = frappe.get_doc(self.doctype, id_value) - existing_doc.flags.via_data_import = self.data_import.name + existing_doc.flags.updater_reference = { + 'doctype': self.data_import.doctype, + 'docname': self.data_import.name, + 'label': _('via Data Import') + } existing_doc.update(doc) existing_doc.save() return existing_doc diff --git a/frappe/public/js/frappe/form/footer/timeline.js b/frappe/public/js/frappe/form/footer/timeline.js index 5b02f06728..593f987a9a 100644 --- a/frappe/public/js/frappe/form/footer/timeline.js +++ b/frappe/public/js/frappe/form/footer/timeline.js @@ -562,20 +562,14 @@ frappe.ui.form.Timeline = class Timeline { let updater_reference_link = null; - if (data.data_import) { - updater_reference_link = frappe.utils.get_form_link( - 'Data Import Beta', - data.data_import, - true, - __('via Data Import') - ); - } else if (!$.isEmptyObject(data.updater_reference)) { + if (!$.isEmptyObject(data.updater_reference)) { + let label = updater_reference.label || __('via {0}', [updater_reference.doctype]); let updater_reference = data.updater_reference; updater_reference_link = frappe.utils.get_form_link( updater_reference.doctype, updater_reference.docname, true, - __('via {0}', [updater_reference.doctype]) + label ); } @@ -650,10 +644,10 @@ frappe.ui.form.Timeline = class Timeline { }); return parts.length < 3; }); - if(parts.length) { + if (parts.length) { let message; - if (data.data_import) { - message = __("changed values for {0} {1}", [parts.join(', '), data_import_link]); + if (updater_reference_link) { + message = __("changed values for {0} {1}", [parts.join(', '), updater_reference_link]); } else { message = __("changed values for {0}", [parts.join(', ')]); } From df669a88cb44ddbf912d021e01e2a436330b401b Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 7 Feb 2020 13:28:18 +0530 Subject: [PATCH 006/140] fix: Trigger notification save after doc update --- frappe/email/doctype/notification/notification.py | 5 +++-- frappe/model/document.py | 7 +++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py index 31a39724ef..cd8e85324a 100644 --- a/frappe/email/doctype/notification/notification.py +++ b/frappe/email/doctype/notification/notification.py @@ -134,7 +134,8 @@ def get_context(context): doc.set(self.set_property_after_alert, self.property_value) doc.flags.updater_reference = { 'doctype': self.doctype, - 'docname': self.name + 'docname': self.name, + 'label': _('via Notification') } doc.save() except Exception as e: @@ -307,7 +308,7 @@ def evaluate_alert(doc, alert, event): if event=="Value Change" and not doc.is_new(): try: - db_value = frappe.db.get_value(doc.doctype, doc.name, alert.value_changed) + db_value = doc._doc_before_save.get(alert.value_changed) except Exception as e: if frappe.db.is_missing_column(e): alert.db_set('enabled', 0) diff --git a/frappe/model/document.py b/frappe/model/document.py index 68a65e0401..68062b2d13 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -842,9 +842,7 @@ class Document(BaseDocument): if not self.flags.in_insert: # value change is not applicable in insert - event_map['validate'] = 'Value Change' - event_map['before_change'] = 'Value Change' - event_map['before_update_after_submit'] = 'Value Change' + event_map['on_change'] = 'Value Change' for alert in self.flags.notifications: event = event_map.get(method, None) @@ -941,7 +939,6 @@ class Document(BaseDocument): elif self._action=="update_after_submit": self.run_method("on_update_after_submit") - self.run_method('on_change') self.clear_cache() self.notify_update() @@ -951,6 +948,8 @@ class Document(BaseDocument): if getattr(self.meta, 'track_changes', False) and self._doc_before_save and not self.flags.ignore_version: self.save_version() + self.run_method('on_change') + if (self.doctype, self.name) in frappe.flags.currently_saving: frappe.flags.currently_saving.remove((self.doctype, self.name)) From d240acaa41a35a37c5b9c6050a4c6496cd464916 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 7 Feb 2020 14:48:35 +0530 Subject: [PATCH 007/140] fix: Value change check --- .../doctype/notification/notification.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py index cd8e85324a..a766e88d55 100644 --- a/frappe/email/doctype/notification/notification.py +++ b/frappe/email/doctype/notification/notification.py @@ -307,18 +307,18 @@ def evaluate_alert(doc, alert, event): return if event=="Value Change" and not doc.is_new(): - try: - db_value = doc._doc_before_save.get(alert.value_changed) - except Exception as e: - if frappe.db.is_missing_column(e): - alert.db_set('enabled', 0) - frappe.log_error('Notification {0} has been disabled due to missing field'.format(alert.name)) - return - else: - raise - db_value = parse_val(db_value) - if (doc.get(alert.value_changed) == db_value) or (not db_value and not doc.get(alert.value_changed)): - return # value not changed + if not frappe.db.has_column(doc.doctype, alert.value_changed): + alert.db_set('enabled', 0) + frappe.log_error('Notification {0} has been disabled due to missing field'.format(alert.name)) + return + + doc_before_save = doc.get_doc_before_save() + field_value_before_save = doc_before_save.get(alert.value_changed) if doc_before_save else None + + field_value_before_save = parse_val(field_value_before_save) + if (doc.get(alert.value_changed) == field_value_before_save): + # value not changed + return if event != "Value Change" and not doc.is_new(): # reload the doc for the latest values & comments, From 592e5a88eee102ae790172ca72df4f6a63ce10bd Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 7 Feb 2020 14:53:00 +0530 Subject: [PATCH 008/140] fix: Do not translate error log title --- frappe/email/doctype/notification/notification.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py index a766e88d55..ad6c79131c 100644 --- a/frappe/email/doctype/notification/notification.py +++ b/frappe/email/doctype/notification/notification.py @@ -139,7 +139,7 @@ def get_context(context): } doc.save() except Exception as e: - frappe.log_error(title=_('Document update failed'), message=frappe.get_traceback()) + frappe.log_error(title='Document update failed', message=frappe.get_traceback()) def send_an_email(self, doc, context): from email.utils import formataddr From 8627cce88e13d34a85a444d0abf4d091ca9cfb07 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 19 Feb 2020 12:36:25 +0530 Subject: [PATCH 009/140] feat: added in_setup_wizard flag --- .../doctype/assignment_rule/assignment_rule.py | 2 +- .../milestone_tracker/milestone_tracker.py | 4 ++++ frappe/cache_manager.py | 18 +++++++++++++++--- frappe/desk/page/setup_wizard/setup_wizard.py | 3 +++ frappe/model/document.py | 2 +- .../energy_point_rule/energy_point_rule.py | 3 ++- 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/frappe/automation/doctype/assignment_rule/assignment_rule.py b/frappe/automation/doctype/assignment_rule/assignment_rule.py index 5d8dab90ce..0a5d85636f 100644 --- a/frappe/automation/doctype/assignment_rule/assignment_rule.py +++ b/frappe/automation/doctype/assignment_rule/assignment_rule.py @@ -165,7 +165,7 @@ def reopen_closed_assignment(doc): return True def apply(doc, method=None, doctype=None, name=None): - if frappe.flags.in_patch or frappe.flags.in_install: + if frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_setup_wizard: return if not doc and doctype and name: diff --git a/frappe/automation/doctype/milestone_tracker/milestone_tracker.py b/frappe/automation/doctype/milestone_tracker/milestone_tracker.py index baa1bcc075..154cb599e1 100644 --- a/frappe/automation/doctype/milestone_tracker/milestone_tracker.py +++ b/frappe/automation/doctype/milestone_tracker/milestone_tracker.py @@ -30,6 +30,10 @@ class MilestoneTracker(Document): )).insert(ignore_permissions=True) def evaluate_milestone(doc, event): + if (frappe.flags.in_install + or frappe.flags.in_migrate + or frappe.flags.in_setup_wizard): + return for d in frappe.cache_manager.get_doctype_map('Milestone Tracker', doc.doctype, dict(document_type = doc.doctype, disabled=0)): frappe.get_doc('Milestone Tracker', d.name).apply(doc) diff --git a/frappe/cache_manager.py b/frappe/cache_manager.py index 1faa02ec63..2578d652b4 100644 --- a/frappe/cache_manager.py +++ b/frappe/cache_manager.py @@ -117,7 +117,11 @@ def clear_doctype_map(doctype, name): frappe.cache().hdel(cache_key, name) def build_table_count_cache(*args, **kwargs): - if frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_import: + if (frappe.flags.in_patch + or frappe.flags.in_install + or frappe.flags.in_migrate + or frappe.flags.in_import + or frappe.flags.in_setup_wizard): return _cache = frappe.cache() data = frappe.db.multisql({ @@ -138,7 +142,11 @@ def build_table_count_cache(*args, **kwargs): return counts def build_domain_restriced_doctype_cache(*args, **kwargs): - if frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_import: + if (frappe.flags.in_patch + or frappe.flags.in_install + or frappe.flags.in_migrate + or frappe.flags.in_import + or frappe.flags.in_setup_wizard): return _cache = frappe.cache() active_domains = frappe.get_active_domains() @@ -149,7 +157,11 @@ def build_domain_restriced_doctype_cache(*args, **kwargs): return doctypes def build_domain_restriced_page_cache(*args, **kwargs): - if frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_import: + if (frappe.flags.in_patch + or frappe.flags.in_install + or frappe.flags.in_migrate + or frappe.flags.in_import + or frappe.flags.in_setup_wizard): return _cache = frappe.cache() active_domains = frappe.get_active_domains() diff --git a/frappe/desk/page/setup_wizard/setup_wizard.py b/frappe/desk/page/setup_wizard/setup_wizard.py index 43d4e8dde4..a8b4b4f280 100755 --- a/frappe/desk/page/setup_wizard/setup_wizard.py +++ b/frappe/desk/page/setup_wizard/setup_wizard.py @@ -61,6 +61,7 @@ def setup_complete(args): stages = get_setup_stages(args) try: + frappe.flags.in_setup_wizard = True current_task = None for idx, stage in enumerate(stages): frappe.publish_realtime('setup_task', {"progress": [idx, len(stages)], @@ -75,6 +76,8 @@ def setup_complete(args): else: run_setup_success(args) return {'status': 'ok'} + finally: + frappe.flags.in_setup_wizard = False def update_global_settings(args): if args.language and args.language != "English": diff --git a/frappe/model/document.py b/frappe/model/document.py index 80f18c74c4..e147bc42b0 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -268,7 +268,7 @@ class Document(BaseDocument): if hasattr(self, "__islocal"): delattr(self, "__islocal") - if not (frappe.flags.in_migrate or frappe.local.flags.in_install): + if not (frappe.flags.in_migrate or frappe.local.flags.in_install or frappe.flags.in_setup_wizard): follow_document(self.doctype, self.name, frappe.session.user) return self diff --git a/frappe/social/doctype/energy_point_rule/energy_point_rule.py b/frappe/social/doctype/energy_point_rule/energy_point_rule.py index 6615c2ab1d..b603cb2b24 100644 --- a/frappe/social/doctype/energy_point_rule/energy_point_rule.py +++ b/frappe/social/doctype/energy_point_rule/energy_point_rule.py @@ -84,7 +84,8 @@ def process_energy_points(doc, state): if (frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_migrate - or frappe.flags.in_import): + or frappe.flags.in_import + or frappe.flags.in_setup_wizard): return if not is_energy_point_enabled(): From 07b0886272922d0d4d4a9729338e80a2b5687bd1 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 19 Feb 2020 12:36:37 +0530 Subject: [PATCH 010/140] feat: rebuild table count cache on trash --- frappe/hooks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/hooks.py b/frappe/hooks.py index a132eb69d5..6389985086 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -140,6 +140,7 @@ doc_events = { "frappe.social.doctype.energy_point_rule.energy_point_rule.process_energy_points" ], "after_insert": "frappe.cache_manager.build_table_count_cache", + "on_trash": "frappe.cache_manager.build_table_count_cache", }, "Event": { "after_insert": "frappe.integrations.doctype.google_calendar.google_calendar.insert_event_in_google_calendar", From 9e68e0285f7835635aacf483a0192e9152290f9e Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 19 Feb 2020 12:34:07 +0530 Subject: [PATCH 011/140] feat: added timing decorator --- frappe/__init__.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/frappe/__init__.py b/frappe/__init__.py index 12e5204001..e6b4000524 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -10,6 +10,8 @@ from six import iteritems, binary_type, text_type, string_types, PY2 from werkzeug.local import Local, release_local import os, sys, importlib, inspect, json from past.builtins import cmp +from functools import wraps +from time import time from faker import Faker @@ -512,6 +514,18 @@ def whitelist(allow_guest=False, xss_safe=False): return innerfn +def timing(f): + + @wraps(f) + def wrap(*args, **kw): + ts = time() + result = f(*args, **kw) + te = time() + print('TIMING: {0} > {1} took: {2:2.4f} sec'.format(f.__module__, f.__name__, te-ts)) + return result + + return wrap + def read_only(): def innfn(fn): def wrapper_fn(*args, **kwargs): From 3f056e4c6e7675dc398e6cf3ea82e3ed40bf6f06 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 19 Feb 2020 13:08:15 +0530 Subject: [PATCH 012/140] feat: enabled logging for setup wizard --- frappe/desk/page/setup_wizard/setup_wizard.py | 5 +++++ frappe/hooks.py | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/frappe/desk/page/setup_wizard/setup_wizard.py b/frappe/desk/page/setup_wizard/setup_wizard.py index a8b4b4f280..2db6a64e5d 100755 --- a/frappe/desk/page/setup_wizard/setup_wizard.py +++ b/frappe/desk/page/setup_wizard/setup_wizard.py @@ -352,6 +352,11 @@ def email_setup_wizard_exception(traceback, args): message=message, delayed=False) +def log_setup_wizard_exception(traceback, args): + with open('../logs/setup-wizard.log', 'w+') as setup_log: + setup_log.write(traceback) + setup_log.write(json.dumps(args)) + def get_language_code(lang): return frappe.db.get_value('Language', {'language_name':lang}) diff --git a/frappe/hooks.py b/frappe/hooks.py index 6389985086..d48ac420b1 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -257,7 +257,10 @@ bot_parsers = [ 'frappe.utils.bot.CountBot' ] -setup_wizard_exception = "frappe.desk.page.setup_wizard.setup_wizard.email_setup_wizard_exception" +setup_wizard_exception = [ + "frappe.desk.page.setup_wizard.setup_wizard.email_setup_wizard_exception", + "frappe.desk.page.setup_wizard.setup_wizard.log_setup_wizard_exception" +] before_migrate = ['frappe.patches.v11_0.sync_user_permission_doctype_before_migrate.execute'] after_migrate = ['frappe.website.doctype.website_theme.website_theme.generate_theme_files_if_not_exist'] From 2e6e32bfc20726e7cb31b48c53073bbc6f366664 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 24 Feb 2020 10:51:59 +0530 Subject: [PATCH 013/140] fix: Avoid recursive save --- frappe/email/doctype/notification/notification.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py index ad6c79131c..582cb5d3c4 100644 --- a/frappe/email/doctype/notification/notification.py +++ b/frappe/email/doctype/notification/notification.py @@ -130,14 +130,16 @@ def get_context(context): if doc.docstatus == 1 and not doc.meta.get_field(self.set_property_after_alert).allow_on_submit: allow_update = False try: - if allow_update: + if allow_update and not doc.flags.in_notification_update: doc.set(self.set_property_after_alert, self.property_value) doc.flags.updater_reference = { 'doctype': self.doctype, 'docname': self.name, 'label': _('via Notification') } - doc.save() + doc.flags.in_notification_update = True + doc.save(ignore_permissions=True) + doc.flags.in_notification_update = False except Exception as e: frappe.log_error(title='Document update failed', message=frappe.get_traceback()) @@ -323,7 +325,7 @@ def evaluate_alert(doc, alert, event): if event != "Value Change" and not doc.is_new(): # reload the doc for the latest values & comments, # except for validate type event. - doc = frappe.get_doc(doc.doctype, doc.name) + doc.reload() alert.send(doc) except TemplateError: frappe.throw(_("Error while evaluating Notification {0}. Please fix your template.").format(alert)) From 7e6a22ac72a64b90daa84992acb9b39c10dd3163 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 6 Mar 2020 21:54:17 +0530 Subject: [PATCH 014/140] feat: add button to go to list in customize form --- frappe/custom/doctype/customize_form/customize_form.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frappe/custom/doctype/customize_form/customize_form.js b/frappe/custom/doctype/customize_form/customize_form.js index 63b094615a..5c9fa37ef5 100644 --- a/frappe/custom/doctype/customize_form/customize_form.js +++ b/frappe/custom/doctype/customize_form/customize_form.js @@ -85,6 +85,10 @@ frappe.ui.form.on("Customize Form", { if(frm.doc.doc_type) { frappe.customize_form.set_primary_action(frm); + frm.add_custom_button(__('Go to {0} List', [frm.doc.doc_type]), function() { + frappe.set_route('List', frm.doc.doc_type); + }); + frm.add_custom_button(__('Refresh Form'), function() { frm.script_manager.trigger("doc_type"); }, "fa fa-refresh", "btn-default"); From fcb54701510fddf8ac511c9a16d5835333c932af Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 11 Mar 2020 12:32:40 +0530 Subject: [PATCH 015/140] fix: use tabs --- frappe/__init__.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index e6b4000524..7cad075e90 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -515,16 +515,14 @@ def whitelist(allow_guest=False, xss_safe=False): return innerfn def timing(f): - - @wraps(f) - def wrap(*args, **kw): - ts = time() - result = f(*args, **kw) - te = time() - print('TIMING: {0} > {1} took: {2:2.4f} sec'.format(f.__module__, f.__name__, te-ts)) - return result - - return wrap + @wraps(f) + def wrap(*args, **kw): + ts = time() + result = f(*args, **kw) + te = time() + print('TIMING: {0} > {1} took: {2:2.4f} sec'.format(f.__module__, f.__name__, te-ts)) + return result + return wrap def read_only(): def innfn(fn): From 3389042656014c79b7c12482daaec7786d492ccf Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Thu, 12 Mar 2020 14:33:50 +0530 Subject: [PATCH 016/140] fix: currency field not found in print formats --- frappe/model/meta.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frappe/model/meta.py b/frappe/model/meta.py index 927a56b6b8..fafaefbfd1 100644 --- a/frappe/model/meta.py +++ b/frappe/model/meta.py @@ -529,7 +529,9 @@ def get_field_currency(df, doc=None): if currency: ref_docname = doc.name else: - currency = frappe.db.get_value(doc.parenttype, doc.parent, df.get("options")) + if frappe.get_meta(doc.parenttype).has_field(df.get("options")): + # only get_value if parent has currency field + currency = frappe.db.get_value(doc.parenttype, doc.parent, df.get("options")) if currency: frappe.local.field_currency.setdefault((doc.doctype, ref_docname), frappe._dict())\ From 1c5ee0530014d696ec77a20741cfd731cc814639 Mon Sep 17 00:00:00 2001 From: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> Date: Thu, 12 Mar 2020 18:27:29 +0530 Subject: [PATCH 017/140] Revert __init__.py --- frappe/__init__.py | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index 7cad075e90..f942e53018 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -10,8 +10,6 @@ from six import iteritems, binary_type, text_type, string_types, PY2 from werkzeug.local import Local, release_local import os, sys, importlib, inspect, json from past.builtins import cmp -from functools import wraps -from time import time from faker import Faker @@ -439,7 +437,7 @@ def sendmail(recipients=[], sender="", subject="No Subject", message="No Message :param recipients: List of recipients. - :param sender: Email sender. Default is current user. + :param sender: Email sender. Default is current user or default outgoing account. :param subject: Email Subject. :param message: (or `content`) Email Content. :param as_markdown: Convert content markdown to HTML. @@ -461,7 +459,6 @@ def sendmail(recipients=[], sender="", subject="No Subject", message="No Message :param args: Arguments for rendering the template :param header: Append header in email """ - text_content = None if template: message, text_content = get_email_from_template(template, args) @@ -514,16 +511,6 @@ def whitelist(allow_guest=False, xss_safe=False): return innerfn -def timing(f): - @wraps(f) - def wrap(*args, **kw): - ts = time() - result = f(*args, **kw) - te = time() - print('TIMING: {0} > {1} took: {2:2.4f} sec'.format(f.__module__, f.__name__, te-ts)) - return result - return wrap - def read_only(): def innfn(fn): def wrapper_fn(*args, **kwargs): @@ -556,7 +543,7 @@ def only_for(roles, message=False): myroles = set(get_roles()) if not roles.intersection(myroles): if message: - msgprint(_('Only for {}').format(', '.join(roles))) + msgprint(_('This action is only allowed for {}').format(bold(', '.join(roles))), _('Not Permitted')) raise PermissionError def get_domain_data(module): From c5c9ae46e605977101ee6d5f53552d621306ded1 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 6 Mar 2020 19:46:20 +0530 Subject: [PATCH 018/140] feat: change fieldtype in db with customize form --- .../doctype/customize_form/customize_form.py | 32 +++++++++++++++++-- frappe/database/schema.py | 8 +++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 8d47a075ba..b35bfddf76 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -166,11 +166,10 @@ class CustomizeForm(Document): self.flags.update_db = False self.flags.rebuild_doctype_for_global_search = False - + validate_fields_for_doctype(self.doc_type) self.set_property_setters() self.update_custom_fields() self.set_name_translation() - validate_fields_for_doctype(self.doc_type) if self.flags.update_db: frappe.db.updatedb(self.doc_type) @@ -362,13 +361,42 @@ class CustomizeForm(Document): def validate_fieldtype_change(self, df, old_value, new_value): allowed = False + self.check_length_for_fieldtypes = [] for allowed_changes in allowed_fieldtype_change: if (old_value in allowed_changes and new_value in allowed_changes): allowed = True + self.flags.update_db = True + if frappe.db.type_map.get(old_value)[1] > frappe.db.type_map.get(new_value)[1]: + + self.check_length_for_fieldtypes.append({'df': df, 'old_value': old_value}) + self.validate_fieldtype_length() break if not allowed: frappe.throw(_("Fieldtype cannot be changed from {0} to {1} in row {2}").format(old_value, new_value, df.idx)) + def validate_fieldtype_length(self): + for field in self.check_length_for_fieldtypes: + df = field.get('df') + max_length = frappe.db.type_map.get(df.fieldtype)[1] + fieldname = df.fieldname + docs = frappe.db.sql('''select name, {fieldname}, length({fieldname}) as len + from `tab{doctype}` + where length({fieldname}) > {max_length} + '''.format( + fieldname = fieldname, + doctype = self.doc_type, + max_length = max_length + ), as_dict = True) + links = [] + label = df.label + for doc in docs: + links.append(frappe.utils.get_link_to_form(self.doc_type, doc.name)) + links_str = ', '.join(links) + + if len(docs): + frappe.throw(_('Value for field {label} is too long in {links_str}. Length should be lesser than {max_length}') + .format(label=label, max_length=max_length, links_str=links_str), title='Data Too Long') + def reset_to_defaults(self): if not self.doc_type: return diff --git a/frappe/database/schema.py b/frappe/database/schema.py index 88cda9340b..73bdf32761 100644 --- a/frappe/database/schema.py +++ b/frappe/database/schema.py @@ -69,6 +69,7 @@ class DBTable: lengths = {} precisions = {} uniques = {} + fieldtype = '' # optional fields like _comments if not self.meta.istable: @@ -100,7 +101,7 @@ class DBTable: filters={ "doc_type": self.doctype, "doctype_or_field": "DocField", - "property": ["in", ["precision", "length", "unique"]] + "property": ["in", ["precision", "length", "unique", "fieldtype"]] }): if ps.property=="length": @@ -112,10 +113,13 @@ class DBTable: elif ps.property=="unique": uniques[ps.field_name] = cint(ps.value) + if ps.property=="fieldtype": + fieldtype = ps.value + for f in fl: self.columns[f['fieldname']] = DbColumn(self, f['fieldname'], - f['fieldtype'], + fieldtype or f['fieldtype'], lengths.get(f["fieldname"]) or f.get('length'), f.get('default'), f.get('search_index'), From 7bb014ee9a4a7b61c8ccf13ab5e84b8b5c5fe5a1 Mon Sep 17 00:00:00 2001 From: prssanna Date: Sat, 7 Mar 2020 15:15:12 +0530 Subject: [PATCH 019/140] fix: update db type map --- frappe/custom/doctype/customize_form/customize_form.py | 10 ++++++---- frappe/database/mariadb/database.py | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index b35bfddf76..a38e8f4fa7 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -166,10 +166,10 @@ class CustomizeForm(Document): self.flags.update_db = False self.flags.rebuild_doctype_for_global_search = False - validate_fields_for_doctype(self.doc_type) self.set_property_setters() self.update_custom_fields() self.set_name_translation() + validate_fields_for_doctype(self.doc_type) if self.flags.update_db: frappe.db.updatedb(self.doc_type) @@ -365,11 +365,11 @@ class CustomizeForm(Document): for allowed_changes in allowed_fieldtype_change: if (old_value in allowed_changes and new_value in allowed_changes): allowed = True - self.flags.update_db = True if frappe.db.type_map.get(old_value)[1] > frappe.db.type_map.get(new_value)[1]: - self.check_length_for_fieldtypes.append({'df': df, 'old_value': old_value}) self.validate_fieldtype_length() + else: + self.flags.update_db = True break if not allowed: frappe.throw(_("Fieldtype cannot be changed from {0} to {1} in row {2}").format(old_value, new_value, df.idx)) @@ -394,8 +394,10 @@ class CustomizeForm(Document): links_str = ', '.join(links) if len(docs): - frappe.throw(_('Value for field {label} is too long in {links_str}. Length should be lesser than {max_length}') + frappe.throw(_('Value for field {label} is too long in {links_str}. Length should be lesser than {max_length} characters') .format(label=label, max_length=max_length, links_str=links_str), title='Data Too Long') + else: + self.flags.update_db = True def reset_to_defaults(self): if not self.doc_type: diff --git a/frappe/database/mariadb/database.py b/frappe/database/mariadb/database.py index cd053569f0..926425f857 100644 --- a/frappe/database/mariadb/database.py +++ b/frappe/database/mariadb/database.py @@ -33,7 +33,7 @@ class MariaDBDatabase(Database): 'Float': ('decimal', '18,6'), 'Percent': ('decimal', '18,6'), 'Check': ('int', '1'), - 'Small Text': ('text', ''), + 'Small Text': ('text', 65535), 'Long Text': ('longtext', ''), 'Code': ('longtext', ''), 'Text Editor': ('longtext', ''), @@ -42,7 +42,7 @@ class MariaDBDatabase(Database): 'Date': ('date', ''), 'Datetime': ('datetime', '6'), 'Time': ('time', '6'), - 'Text': ('text', ''), + 'Text': ('text', 65535), 'Data': ('varchar', self.VARCHAR_LEN), 'Link': ('varchar', self.VARCHAR_LEN), 'Dynamic Link': ('varchar', self.VARCHAR_LEN), From a8861c8ed40a07f2136aa564954ad17967bbc543 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 13 Mar 2020 15:14:54 +0530 Subject: [PATCH 020/140] fix: code formatting --- .../custom/doctype/customize_form/customize_form.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index a38e8f4fa7..61d00984fd 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -379,9 +379,10 @@ class CustomizeForm(Document): df = field.get('df') max_length = frappe.db.type_map.get(df.fieldtype)[1] fieldname = df.fieldname - docs = frappe.db.sql('''select name, {fieldname}, length({fieldname}) as len - from `tab{doctype}` - where length({fieldname}) > {max_length} + docs = frappe.db.sql(''' + SELECT name, {fieldname}, LENGTH({fieldname}) AS len + FROM `tab{doctype}` + WHERE LENGTH({fieldname}) > {max_length} '''.format( fieldname = fieldname, doctype = self.doc_type, @@ -394,8 +395,8 @@ class CustomizeForm(Document): links_str = ', '.join(links) if len(docs): - frappe.throw(_('Value for field {label} is too long in {links_str}. Length should be lesser than {max_length} characters') - .format(label=label, max_length=max_length, links_str=links_str), title='Data Too Long') + frappe.throw(_('Value for field {0} is too long in {1}. Length should be lesser than {2} characters') + .format(frappe.bold(label), links_str, frappe.bold(max_length)), title='Data Too Long') else: self.flags.update_db = True From 83677236f55cc0b58a0ab42b7e87d1a0257e09f3 Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 13 Mar 2020 15:23:17 +0530 Subject: [PATCH 021/140] fix: set is_minimizable as true for error dialog --- frappe/custom/doctype/customize_form/customize_form.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 61d00984fd..0cef12fd7e 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -396,7 +396,7 @@ class CustomizeForm(Document): if len(docs): frappe.throw(_('Value for field {0} is too long in {1}. Length should be lesser than {2} characters') - .format(frappe.bold(label), links_str, frappe.bold(max_length)), title='Data Too Long') + .format(frappe.bold(label), links_str, frappe.bold(max_length)), title='Data Too Long', is_minimizable=True) else: self.flags.update_db = True From 35ae0244ae7c38388b188b05d5758ff683e2c5b1 Mon Sep 17 00:00:00 2001 From: Prssanna Desai Date: Fri, 13 Mar 2020 17:18:02 +0530 Subject: [PATCH 022/140] fix: translate dialog title Co-Authored-By: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> --- frappe/custom/doctype/customize_form/customize_form.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 0cef12fd7e..c8d1bb18b4 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -394,11 +394,11 @@ class CustomizeForm(Document): links.append(frappe.utils.get_link_to_form(self.doc_type, doc.name)) links_str = ', '.join(links) - if len(docs): - frappe.throw(_('Value for field {0} is too long in {1}. Length should be lesser than {2} characters') - .format(frappe.bold(label), links_str, frappe.bold(max_length)), title='Data Too Long', is_minimizable=True) - else: - self.flags.update_db = True + if docs: + frappe.throw(_('Value for field {0} is too long in {1}. Length should be lesser than {2} characters') + .format(frappe.bold(label), links_str, frappe.bold(max_length)), title=_('Data Too Long'), is_minimizable=len(docs) > 1) + + self.flags.update_db = True def reset_to_defaults(self): if not self.doc_type: From d7fd4ecfcc1cc0d95319c2c9e3130b5366476a49 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 13 Mar 2020 19:26:11 +0530 Subject: [PATCH 023/140] refactor: move widgets to a separate folder --- .../js/frappe/views/widgets/chart_widget.js | 60 ------------------- .../frappe/{views => }/widgets/base_widget.js | 4 +- .../{views => }/widgets/links_widget.js | 0 .../{views => }/widgets/onboarding_widget.js | 0 .../{views => }/widgets/shortcut_widget.js | 0 .../js/frappe/{views => }/widgets/utils.js | 0 .../{views => }/widgets/widget_group.js | 6 +- 7 files changed, 8 insertions(+), 62 deletions(-) delete mode 100644 frappe/public/js/frappe/views/widgets/chart_widget.js rename frappe/public/js/frappe/{views => }/widgets/base_widget.js (93%) rename frappe/public/js/frappe/{views => }/widgets/links_widget.js (100%) rename frappe/public/js/frappe/{views => }/widgets/onboarding_widget.js (100%) rename frappe/public/js/frappe/{views => }/widgets/shortcut_widget.js (100%) rename frappe/public/js/frappe/{views => }/widgets/utils.js (100%) rename frappe/public/js/frappe/{views => }/widgets/widget_group.js (96%) diff --git a/frappe/public/js/frappe/views/widgets/chart_widget.js b/frappe/public/js/frappe/views/widgets/chart_widget.js deleted file mode 100644 index 25a70fb525..0000000000 --- a/frappe/public/js/frappe/views/widgets/chart_widget.js +++ /dev/null @@ -1,60 +0,0 @@ -import Widget from "./base_widget.js"; - -export default class ChartWidget extends Widget { - constructor(opts) { - super(opts); - } - - refresh() { - // - } - - customize() { - this.setup_customize_actions(); - } - - make_chart() { - this.body.empty() - frappe.model.with_doc("Dashboard Chart", this.chart_name).then(chart_doc => { - chart_doc.width = 'Full' - this.dashboard = new frappe.ui.DashboardChart(chart_doc, this.body, { hide_title: true, hide_last_sync: true, hide_actions: true }); - this.dashboard.show(); - }); - - this.summary && this.set_summary(); - } - - set_body() { - this.widget.addClass('dashboard-widget-box') - this.make_chart(); - } - - set_summary() { - let summary = $(`$ 54,231`); - this.title_field.addClass('text-muted') - summary.appendTo(this.body); - } - - setup_events() { - // - } - - setup_customize_actions() { - this.action_area.empty() - const buttons = $(` - `); - buttons.appendTo(this.action_area); - } - - set_actions() { - return - this.action_area.empty() - const buttons = $(`
- - - -
- `); - buttons.appendTo(this.action_area); - } -} \ No newline at end of file diff --git a/frappe/public/js/frappe/views/widgets/base_widget.js b/frappe/public/js/frappe/widgets/base_widget.js similarity index 93% rename from frappe/public/js/frappe/views/widgets/base_widget.js rename to frappe/public/js/frappe/widgets/base_widget.js index 1a082f7615..f0d6a22c53 100644 --- a/frappe/public/js/frappe/views/widgets/base_widget.js +++ b/frappe/public/js/frappe/widgets/base_widget.js @@ -5,7 +5,9 @@ export default class Widget { } refresh() { - // + this.set_title(); + this.set_actions(); + this.set_body(); } customize() { diff --git a/frappe/public/js/frappe/views/widgets/links_widget.js b/frappe/public/js/frappe/widgets/links_widget.js similarity index 100% rename from frappe/public/js/frappe/views/widgets/links_widget.js rename to frappe/public/js/frappe/widgets/links_widget.js diff --git a/frappe/public/js/frappe/views/widgets/onboarding_widget.js b/frappe/public/js/frappe/widgets/onboarding_widget.js similarity index 100% rename from frappe/public/js/frappe/views/widgets/onboarding_widget.js rename to frappe/public/js/frappe/widgets/onboarding_widget.js diff --git a/frappe/public/js/frappe/views/widgets/shortcut_widget.js b/frappe/public/js/frappe/widgets/shortcut_widget.js similarity index 100% rename from frappe/public/js/frappe/views/widgets/shortcut_widget.js rename to frappe/public/js/frappe/widgets/shortcut_widget.js diff --git a/frappe/public/js/frappe/views/widgets/utils.js b/frappe/public/js/frappe/widgets/utils.js similarity index 100% rename from frappe/public/js/frappe/views/widgets/utils.js rename to frappe/public/js/frappe/widgets/utils.js diff --git a/frappe/public/js/frappe/views/widgets/widget_group.js b/frappe/public/js/frappe/widgets/widget_group.js similarity index 96% rename from frappe/public/js/frappe/views/widgets/widget_group.js rename to frappe/public/js/frappe/widgets/widget_group.js index 15adb3eebb..36fb2c9efc 100644 --- a/frappe/public/js/frappe/views/widgets/widget_group.js +++ b/frappe/public/js/frappe/widgets/widget_group.js @@ -4,6 +4,8 @@ import ShortcutWidget from "../widgets/shortcut_widget"; import LinksWidget from "../widgets/links_widget"; import OnboardingWidget from "../widgets/onboarding_widget"; +frappe.provide('frappe.widget') + const widget_factory = { chart: ChartWidget, base: BaseWidget, @@ -86,4 +88,6 @@ export default class WidgetGroup { // onStart: (evt) => this.sortable_config.on_start(evt, container) }); } -} \ No newline at end of file +} + +frappe.widget.WidgetGroup = WidgetGroup; \ No newline at end of file From fa32227c270ad595a60204ed6b18fe0a26147f39 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 13 Mar 2020 19:26:36 +0530 Subject: [PATCH 024/140] feat: merge dashboard chart and chart_widget --- .../chart_widget.js} | 147 ++++++++++-------- 1 file changed, 80 insertions(+), 67 deletions(-) rename frappe/public/js/frappe/{ui/dashboard_chart.js => widgets/chart_widget.js} (76%) diff --git a/frappe/public/js/frappe/ui/dashboard_chart.js b/frappe/public/js/frappe/widgets/chart_widget.js similarity index 76% rename from frappe/public/js/frappe/ui/dashboard_chart.js rename to frappe/public/js/frappe/widgets/chart_widget.js index 45150fe81c..1609ce4e8f 100644 --- a/frappe/public/js/frappe/ui/dashboard_chart.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -1,16 +1,36 @@ -frappe.provide('ui') +import Widget from "./base_widget.js"; frappe.provide('frappe.dashboards'); frappe.provide('frappe.dashboards.chart_sources'); -frappe.ui.DashboardChart = class DashboardChart { - constructor(chart_doc, chart_container, options) { - this.chart_doc = chart_doc; - this.container = chart_container; - this.options = options || {}; - this.chart_args = {}; +export default class ChartWidget extends Widget { + constructor(opts) { + super(opts); } - show() { + refresh() { + this.make_chart(); + } + + customize() { + this.setup_customize_actions(); + } + + set_body() { + this.widget.addClass('dashboard-widget-box') + if (this.width == "Full") { + this.widget.addClass('full-width') + } + this.make_chart(); + } + + set_summary() { + let summary = $(`$ 54,231`); + this.title_field.addClass('text-muted') + summary.prependTo(this.body); + } + + make_chart() { + this.body.empty() this.get_settings().then(() => { this.prepare_chart_object(); this.prepare_container(); @@ -20,41 +40,40 @@ frappe.ui.DashboardChart = class DashboardChart { if (this.chart_doc.timeseries && this.chart_doc.chart_type !== 'Custom') { this.render_time_series_filters(); } - - this.prepare_chart_actions(); } - this.fetch(this.filters).then( data => { + this.action_area.empty(); + this.prepare_chart_actions(); + // this.setup_refresh_button(); + // this.setup_filter_button(); + // if (this.chart_doc.timeseries && this.chart_doc.chart_type !== 'Custom') { + // this.render_time_series_filters(); + // } + + this.fetch(this.filters).then(data => { if (this.chart_doc.chart_type == 'Report') { data = this.get_report_chart_data(data); } - if (!this.options.hide_last_sync || this.options.hide_last_sync == undefined) { - this.update_last_synced(); - } + this.update_last_synced(); this.data = data; + // Delete existing chart when refreshing + delete this.dashboardchart; this.render(); }); }); } - prepare_container() { - const column_width_map = { - "Half": "6", - "Full": "12", - }; - let columns = column_width_map[this.chart_doc.width]; - this.chart_container = $(`
-
-
${__("Loading...")}
-
${__("No Data")}
-
-
`); - this.chart_container.appendTo(this.container); + setup_customize_actions() { + this.action_area.empty() + const buttons = $(` + `); + buttons.appendTo(this.action_area); + } - if (!this.options.hide_last_sync || this.options.hide_last_sync == undefined) { - let last_synced_text = $(``); - last_synced_text.prependTo(this.chart_container); - } + setup_refresh_button() { + const refresh_button = $(``); + refresh_button.appendTo(this.action_area); + refresh_button.on('click', () => this.refresh()); } render_time_series_filters() { @@ -85,7 +104,7 @@ frappe.ui.DashboardChart = class DashboardChart { }, ]; - frappe.dashboard_utils.render_chart_filters(filters, 'chart-actions', this.chart_container, 1); + frappe.dashboard_utils.render_chart_filters(filters, 'chart-actions', this.action_area, 1); } fetch_and_update_chart() { @@ -111,7 +130,7 @@ frappe.ui.DashboardChart = class DashboardChart { if (!this.date_field_wrapper || !this.date_field_wrapper.is(':visible')) { this.date_field_wrapper = $(`
`) - .insertBefore(this.chart_container.find('.chart-wrapper')); + .appendTo(this.action_area); this.date_range_field = frappe.ui.form.make_control({ df: { @@ -177,6 +196,7 @@ frappe.ui.DashboardChart = class DashboardChart { } } ]; + if (this.chart_doc.document_type) { actions.push({ label: __("{0} List", [this.chart_doc.document_type]), @@ -198,11 +218,10 @@ frappe.ui.DashboardChart = class DashboardChart { } setup_filter_button() { - this.is_document_type = this.chart_doc.chart_type!== 'Report' && this.chart_doc.chart_type!=='Custom'; this.filter_button = $(`
${__("Filter")}
`); - this.filter_button.prependTo(this.chart_container); + this.filter_button.appendTo(this.action_area); this.filter_button.on('click', () => { let fields; @@ -295,11 +314,11 @@ frappe.ui.DashboardChart = class DashboardChart { const action = o.dataset.action; $(o).click(actions.find(a => a.action === action)); }); - this.chart_actions.prependTo(this.chart_container); + this.chart_actions.appendTo(this.action_area); } fetch(filters, refresh=false, args) { - this.chart_container.find('.chart-loading-state').removeClass('hide'); + // this.chart_container.find('.chart-loading-state').removeClass('hide'); let method = this.settings ? this.settings.method : 'frappe.desk.doctype.dashboard_chart.dashboard_chart.get'; @@ -343,17 +362,8 @@ frappe.ui.DashboardChart = class DashboardChart { colors = [this.chart_doc.color || "light-blue"]; } - this.chart_container.find('.chart-loading-state').addClass('hide'); - if (!this.data) { - this.chart_container.find('.chart-empty-state').removeClass('hide'); - } else { - let title = null; - if (!this.options.hide_title || this.options.hide_title == undefined) { - title = this.chart_doc.chart_name; - } - + if (this.data) { let chart_args = { - title: title, data: this.data, type: chart_type_map[this.chart_doc.type], colors: colors, @@ -362,10 +372,10 @@ frappe.ui.DashboardChart = class DashboardChart { shortenYAxisNumbers: 1 } }; - if (!this.chart) { - this.chart = new frappe.Chart(this.chart_container.find(".chart-wrapper")[0], chart_args); + if (!this.dashboardchart) { + this.dashboardchart = new frappe.Chart(this.body[0], chart_args); } else { - this.chart.update(this.data); + this.dashboardchart.update(this.data); } } } @@ -388,25 +398,28 @@ frappe.ui.DashboardChart = class DashboardChart { } get_settings() { - if (this.chart_doc.chart_type == 'Custom') { - // custom source - if (frappe.dashboards.chart_sources[this.chart_doc.source]) { - this.settings = frappe.dashboards.chart_sources[this.chart_doc.source]; + return frappe.model.with_doc("Dashboard Chart", this.chart_name).then(chart_doc => { + this.chart_doc = chart_doc; + if (this.chart_doc.chart_type == 'Custom') { + // custom source + if (frappe.dashboards.chart_sources[this.chart_doc.source]) { + this.settings = frappe.dashboards.chart_sources[this.chart_doc.source]; + return Promise.resolve(); + } else { + const method = 'frappe.desk.doctype.dashboard_chart_source.dashboard_chart_source.get_config'; + return frappe.xcall(method, {name: this.chart_doc.source}).then(config => { + frappe.dom.eval(config); + this.settings = frappe.dashboards.chart_sources[this.chart_doc.source]; + }); + } + } else if (this.chart_doc.chart_type == 'Report') { + this.settings = { + 'method': 'frappe.desk.query_report.run' + }; return Promise.resolve(); } else { - const method = 'frappe.desk.doctype.dashboard_chart_source.dashboard_chart_source.get_config'; - return frappe.xcall(method, {name: this.chart_doc.source}).then(config => { - frappe.dom.eval(config); - this.settings = frappe.dashboards.chart_sources[this.chart_doc.source]; - }); + return Promise.resolve(); } - } else if (this.chart_doc.chart_type == 'Report') { - this.settings = { - 'method': 'frappe.desk.query_report.run' - }; - return Promise.resolve(); - } else { - return Promise.resolve(); - } + }); } } \ No newline at end of file From 2ebf0a456cf14f9c1125b4977c01ce77543f971e Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 13 Mar 2020 19:26:49 +0530 Subject: [PATCH 025/140] chore: update build --- frappe/public/build.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/public/build.json b/frappe/public/build.json index 9f0ed63c89..a11b6143df 100755 --- a/frappe/public/build.json +++ b/frappe/public/build.json @@ -222,6 +222,8 @@ "public/js/frappe/views/communication.js", "public/js/frappe/views/translation_manager.js", + "public/js/frappe/widgets/widget_group.js", + "public/js/frappe/ui/sort_selector.html", "public/js/frappe/ui/sort_selector.js", @@ -237,7 +239,6 @@ "public/js/frappe/utils/energy_point_utils.js", "public/js/frappe/utils/dashboard_utils.js", "public/js/frappe/ui/chart.js", - "public/js/frappe/ui/dashboard_chart.js", "public/js/frappe/barcode_scanner/index.js" ], "css/module.min.css": [ From bbd283827d4b9bebea8101ba4ccfc798538e01f6 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 13 Mar 2020 19:27:10 +0530 Subject: [PATCH 026/140] refactor: patch desktop for new widget api --- frappe/public/js/frappe/views/desktop/desktop.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/frappe/public/js/frappe/views/desktop/desktop.js b/frappe/public/js/frappe/views/desktop/desktop.js index 13490c656f..e9d9493df9 100644 --- a/frappe/public/js/frappe/views/desktop/desktop.js +++ b/frappe/public/js/frappe/views/desktop/desktop.js @@ -1,6 +1,3 @@ -import ChartWidget from "../widgets/chart_widget"; -import WidgetGroup from "../widgets/widget_group"; - export default class Desktop { constructor({ wrapper }) { this.wrapper = wrapper; @@ -185,7 +182,7 @@ class DesktopPage { this.make_page(); this.get_data().then(res => { this.data = res.message; - // this.make_onboarding() + // this.make_onboarding(); if (!this.data) { delete localStorage.current_desk_page; frappe.set_route('workspace'); @@ -216,7 +213,7 @@ class DesktopPage { } make_onboarding() { - this.sections["onboarding"] = new WidgetGroup({ + this.sections["onboarding"] = new frappe.widget.WidgetGroup({ title: `Getting Started`, container: this.page, type: "onboarding", @@ -253,7 +250,8 @@ class DesktopPage { } make_charts() { - this.sections["charts"] = new WidgetGroup({ + console.log(this.data.charts.items) + this.sections["charts"] = new frappe.widget.WidgetGroup({ title: this.data.charts.label || `${this.page_name} Dashboard`, container: this.page, type: "chart", @@ -264,7 +262,7 @@ class DesktopPage { } make_shortcuts() { - this.sections["shortcuts"] = new WidgetGroup({ + this.sections["shortcuts"] = new frappe.widget.WidgetGroup({ title: this.data.shortcuts.label || `Your Shortcuts`, container: this.page, type: "bookmark", @@ -275,7 +273,7 @@ class DesktopPage { } make_cards() { - let cards = new WidgetGroup({ + let cards = new frappe.widget.WidgetGroup({ title: this.data.cards.label || `Reports & Masters`, container: this.page, type: "links", @@ -284,7 +282,7 @@ class DesktopPage { widgets: this.data.cards.items }); - this.sections["cards"] = cards; + this.sections['cards'] = cards; const legend = [ { From 67b71f78b44e98a4f32811079bad5d92c2a76f7c Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 13 Mar 2020 19:27:24 +0530 Subject: [PATCH 027/140] feat: remove dashboard.css --- frappe/core/page/dashboard/dashboard.css | 62 ---------------------- frappe/public/less/desktop.less | 65 ++++++++++++++---------- 2 files changed, 38 insertions(+), 89 deletions(-) diff --git a/frappe/core/page/dashboard/dashboard.css b/frappe/core/page/dashboard/dashboard.css index cf1a581c6d..e69de29bb2 100644 --- a/frappe/core/page/dashboard/dashboard.css +++ b/frappe/core/page/dashboard/dashboard.css @@ -1,62 +0,0 @@ -.chart-wrapper { - border: 1px solid #d1d8dd; - border-radius: 4px; - margin: 15px 0; - padding-left: 15px; - padding-right: 15px; - height: 320px; -} - -.chart-container { - top: 50%; - transform: translateY(-50%); -} - -.frappe-chart > text.title { - margin: 0px; - font-size: 14px !important; - font-weight: bold; -} - -.chart-loading-state, .chart-empty-state { - height: 100%; - margin-top: 160px; - text-align: center; -} - -.chart-actions { - position: relative; - right: 0px; - top: 20px; - margin-right: 5px; -} - -.filter-chart { - position: relative; - right: 5px; - top: 20px; -} - -.dashboard-date-field { - width: 14%; - height: 0; - margin-right: 10px; - position: relative; - top: 0px; -} - -.chart-column-container { - position: relative; -} - -.last-synced-text { - position: absolute; - top: 28px; - left: 50px; - font-size: 12px; -} - -.dashboard-graph { - padding-top: 15px; - overflow: hidden; -} \ No newline at end of file diff --git a/frappe/public/less/desktop.less b/frappe/public/less/desktop.less index af371c94bb..72e9dbb4cd 100644 --- a/frappe/public/less/desktop.less +++ b/frappe/public/less/desktop.less @@ -76,31 +76,6 @@ position: relative; min-height: 1px; padding-right: 15px; - - .dashboard-summary { - font-size: 32px !important; - margin-top: 0px !important; - margin-bottom: 8px !important; - font-weight: 500; - } - - .grid-col-3 { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); - // grid-auto-rows: minmax(62px, 1fr); - column-gap: 15px; - row-gap: 15px; - align-items: center; - } - - .grid-col-1 { - display: grid; - grid-template-columns: repeat(1fr); - // grid-auto-rows: minmax(62px, 1fr); - column-gap: 15px; - row-gap: 15px; - align-items: center; - } } @media (max-width: 768px) { @@ -138,6 +113,38 @@ } } + .grid-col-3 { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + // grid-auto-rows: minmax(62px, 1fr); + column-gap: 15px; + row-gap: 15px; + align-items: center; + } + + .grid-col-2 { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(550px, 1fr)); + // grid-auto-rows: minmax(62px, 1fr); + column-gap: 15px; + row-gap: 15px; + align-items: center; + + .full-width { + grid-column-start: 1; + grid-column-end: 3; + } + } + + .grid-col-1 { + display: grid; + grid-template-columns: repeat(1fr); + // grid-auto-rows: minmax(62px, 1fr); + column-gap: 15px; + row-gap: 15px; + align-items: center; + } + @media (max-width: 768px) { .legend { display: flex; @@ -184,14 +191,18 @@ // Overrides for each widgets &.dashboard-widget-box { padding-bottom: 10px !important; + min-height: 260px; .chart-column-container { padding-right: 0px !important; padding-left: 0px !important; } - .chart-wrapper { - border-bottom: none !important; + .dashboard-summary { + font-size: 32px !important; + margin-top: 0px !important; + margin-bottom: 8px !important; + font-weight: 500; } } From ed0a8009eeb0988f884525f887ca4e9088e5c8ae Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 13 Mar 2020 19:28:03 +0530 Subject: [PATCH 028/140] feat: use widgets to make dashboards --- frappe/core/page/dashboard/dashboard.js | 26 +++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/frappe/core/page/dashboard/dashboard.js b/frappe/core/page/dashboard/dashboard.js index ac9221265b..e2da785f4e 100644 --- a/frappe/core/page/dashboard/dashboard.js +++ b/frappe/core/page/dashboard/dashboard.js @@ -22,7 +22,7 @@ class Dashboard { constructor(wrapper) { this.wrapper = $(wrapper); $(`
-
+
`).appendTo(this.wrapper.find(".page-content").empty()); this.container = this.wrapper.find(".dashboard-graph"); this.page = wrapper.page; @@ -78,16 +78,22 @@ class Dashboard { refresh() { this.get_dashboard_doc().then((doc) => { this.dashboard_doc = doc; - this.charts = this.dashboard_doc.charts; + this.charts = this.dashboard_doc.charts + .map(chart => { + return { + chart_name: chart.chart, + label: chart.chart, + ...chart + } + }); - this.charts.map((chart) => { - let chart_container = $("
"); - chart_container.appendTo(this.container); - - frappe.model.with_doc("Dashboard Chart", chart.chart).then( chart_doc => { - let dashboard_chart = new frappe.ui.DashboardChart(chart_doc, chart_container); - dashboard_chart.show(); - }); + this.chart_group = new frappe.widget.WidgetGroup({ + title: null, + container: this.container, + type: "chart", + columns: 2, + allow_sorting: true, + widgets: this.charts, }); }); } From 4e7ccff375a5b9d6f6798ab671a35e0dba983d8e Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 13 Mar 2020 19:28:20 +0530 Subject: [PATCH 029/140] feat: move height config to dashboard page --- .../dashboard_chart/dashboard_chart.json | 10 +-- .../dashboard_chart_link.json | 72 +++++-------------- 2 files changed, 19 insertions(+), 63 deletions(-) diff --git a/frappe/desk/doctype/dashboard_chart/dashboard_chart.json b/frappe/desk/doctype/dashboard_chart/dashboard_chart.json index f181f6d7e4..0a017a0de2 100644 --- a/frappe/desk/doctype/dashboard_chart/dashboard_chart.json +++ b/frappe/desk/doctype/dashboard_chart/dashboard_chart.json @@ -31,7 +31,6 @@ "filters_json", "chart_options_section", "type", - "width", "column_break_2", "color", "section_break_10", @@ -127,13 +126,6 @@ "options": "Line\nBar\nPercentage\nPie", "reqd": 1 }, - { - "fieldname": "width", - "fieldtype": "Select", - "label": "Width", - "options": "Half\nFull", - "reqd": 1 - }, { "fieldname": "column_break_2", "fieldtype": "Column Break" @@ -223,7 +215,7 @@ } ], "links": [], - "modified": "2020-03-01 22:08:47.135523", + "modified": "2020-03-13 19:19:37.162771", "modified_by": "Administrator", "module": "Desk", "name": "Dashboard Chart", diff --git a/frappe/desk/doctype/dashboard_chart_link/dashboard_chart_link.json b/frappe/desk/doctype/dashboard_chart_link/dashboard_chart_link.json index df278fb4c1..51b5ed3036 100644 --- a/frappe/desk/doctype/dashboard_chart_link/dashboard_chart_link.json +++ b/frappe/desk/doctype/dashboard_chart_link/dashboard_chart_link.json @@ -1,77 +1,41 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, + "actions": [], "creation": "2019-03-12 15:00:57.052684", - "custom": 0, - "docstatus": 0, "doctype": "DocType", - "document_type": "", "editable_grid": 1, "engine": "InnoDB", + "field_order": [ + "chart", + "width" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, + "columns": 8, "fieldname": "chart", "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, "in_list_view": 1, - "in_standard_filter": 0, "label": "Chart", - "length": 0, - "no_copy": 0, - "options": "Dashboard Chart", - "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 + "options": "Dashboard Chart" + }, + { + "default": "Half", + "fieldname": "width", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Width", + "options": "Half\nFull" } ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, "istable": 1, - "max_attachments": 0, - "modified": "2019-03-12 15:01:31.639414", + "links": [], + "modified": "2020-03-13 19:23:05.561687", "modified_by": "Administrator", "module": "Desk", "name": "Dashboard Chart Link", - "name_case": "", "owner": "Administrator", "permissions": [], "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "ASC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 + "track_changes": 1 } \ No newline at end of file From ff5aa8c96edadbc5fb2d8994dff4d53e0a26fdcd Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 13 Mar 2020 19:45:05 +0530 Subject: [PATCH 030/140] fix (linting): remove unused code --- frappe/public/js/frappe/views/desktop/desktop.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/frappe/public/js/frappe/views/desktop/desktop.js b/frappe/public/js/frappe/views/desktop/desktop.js index e9d9493df9..4391a572af 100644 --- a/frappe/public/js/frappe/views/desktop/desktop.js +++ b/frappe/public/js/frappe/views/desktop/desktop.js @@ -19,7 +19,7 @@ export default class Desktop { this.fetch_desktop_settings().then(() => { this.route(); this.make_sidebar(); - this.setup_events(); + // this.setup_events(); // this.hide_loading_state(); }); } @@ -153,11 +153,11 @@ export default class Desktop { } setup_events() { - $(document).keydown(e => { - if (e.keyCode == 9) { - console.log("navigate"); - } - }); + // $(document).keydown(e => { + // if (e.keyCode == 9) { + // console.log("navigate"); + // } + // }); } } @@ -250,7 +250,6 @@ class DesktopPage { } make_charts() { - console.log(this.data.charts.items) this.sections["charts"] = new frappe.widget.WidgetGroup({ title: this.data.charts.label || `${this.page_name} Dashboard`, container: this.page, From 324403ca3a14dfc7c2c7962fbc9b962cf3e84861 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 13 Mar 2020 19:46:20 +0530 Subject: [PATCH 031/140] chore (linting): added semicolon --- frappe/public/js/frappe/widgets/chart_widget.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index 1609ce4e8f..69cad2b8fb 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -16,21 +16,21 @@ export default class ChartWidget extends Widget { } set_body() { - this.widget.addClass('dashboard-widget-box') + this.widget.addClass('dashboard-widget-box'); if (this.width == "Full") { - this.widget.addClass('full-width') + this.widget.addClass('full-width'); } this.make_chart(); } set_summary() { let summary = $(`$ 54,231`); - this.title_field.addClass('text-muted') + this.title_field.addClass('text-muted'); summary.prependTo(this.body); } make_chart() { - this.body.empty() + this.body.empty(); this.get_settings().then(() => { this.prepare_chart_object(); this.prepare_container(); @@ -47,7 +47,7 @@ export default class ChartWidget extends Widget { // this.setup_refresh_button(); // this.setup_filter_button(); // if (this.chart_doc.timeseries && this.chart_doc.chart_type !== 'Custom') { - // this.render_time_series_filters(); + // this.render_time_series_filters(); // } this.fetch(this.filters).then(data => { @@ -64,7 +64,7 @@ export default class ChartWidget extends Widget { } setup_customize_actions() { - this.action_area.empty() + this.action_area.empty(); const buttons = $(` `); buttons.appendTo(this.action_area); From b3b94197a181c8734c29374444623d50bea8beaf Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2020 12:43:49 +0530 Subject: [PATCH 032/140] chore(deps): [security] bump acorn from 5.7.3 to 5.7.4 (#9695) Bumps [acorn](https://github.com/acornjs/acorn) from 5.7.3 to 5.7.4. **This update includes a security fix.** - [Release notes](https://github.com/acornjs/acorn/releases) - [Commits](https://github.com/acornjs/acorn/compare/5.7.3...5.7.4) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6de2bd96b2..1b3d0a2176 100644 --- a/yarn.lock +++ b/yarn.lock @@ -392,9 +392,9 @@ ace-builds@^1.4.8: integrity sha512-8ZVAxwyCGAxQX8mOp9imSXH0hoSPkGfy8igJy+WO/7axL30saRhKgg1XPACSmxxPA7nfHVwM+ShWXT+vKsNuFg== acorn@^5.2.1: - version "5.7.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" - integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== + version "5.7.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" + integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== acorn@^6.1.1: version "6.1.1" From 98f5366fac3ff4cada8d00340214bbdeaf82b733 Mon Sep 17 00:00:00 2001 From: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> Date: Sat, 14 Mar 2020 16:16:16 +0530 Subject: [PATCH 033/140] fix: Remove duplicate on_trash key --- frappe/hooks.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/hooks.py b/frappe/hooks.py index f8dde91c7b..cdc6e00bdd 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -134,13 +134,13 @@ doc_events = { ], "on_trash": [ "frappe.desk.notifications.clear_doctype_notifications", - "frappe.workflow.doctype.workflow_action.workflow_action.process_workflow_actions" + "frappe.workflow.doctype.workflow_action.workflow_action.process_workflow_actions", + "frappe.cache_manager.build_table_count_cache" ], "on_change": [ "frappe.social.doctype.energy_point_rule.energy_point_rule.process_energy_points" ], - "after_insert": "frappe.cache_manager.build_table_count_cache", - "on_trash": "frappe.cache_manager.build_table_count_cache", + "after_insert": "frappe.cache_manager.build_table_count_cache" }, "Event": { "after_insert": "frappe.integrations.doctype.google_calendar.google_calendar.insert_event_in_google_calendar", From 82038e0d02a2c25b3e64977f52c14c7cdbd64535 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Sat, 14 Mar 2020 17:11:50 +0530 Subject: [PATCH 034/140] refactor: filter alignments --- .../public/js/frappe/widgets/chart_widget.js | 23 +++++++------------ frappe/public/less/desktop.less | 7 ++++++ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index 69cad2b8fb..4226c8463e 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -33,22 +33,15 @@ export default class ChartWidget extends Widget { this.body.empty(); this.get_settings().then(() => { this.prepare_chart_object(); - this.prepare_container(); - - if (!this.options.hide_actions || this.options.hide_actions == undefined) { - this.setup_filter_button(); - if (this.chart_doc.timeseries && this.chart_doc.chart_type !== 'Custom') { - this.render_time_series_filters(); - } - } + // this.prepare_container(); this.action_area.empty(); this.prepare_chart_actions(); // this.setup_refresh_button(); - // this.setup_filter_button(); - // if (this.chart_doc.timeseries && this.chart_doc.chart_type !== 'Custom') { - // this.render_time_series_filters(); - // } + this.setup_filter_button(); + if (this.chart_doc.timeseries && this.chart_doc.chart_type !== 'Custom') { + this.render_time_series_filters(); + } this.fetch(this.filters).then(data => { if (this.chart_doc.chart_type == 'Report') { @@ -104,7 +97,7 @@ export default class ChartWidget extends Widget { }, ]; - frappe.dashboard_utils.render_chart_filters(filters, 'chart-actions', this.action_area, 1); + frappe.dashboard_utils.render_chart_filters(filters, 'chart-actions', this.action_area, 0); } fetch_and_update_chart() { @@ -298,9 +291,9 @@ export default class ChartWidget extends Widget { this.filter_group.add_filters_to_filter_group(this.filters); }); } - +// set_chart_actions(actions) { - this.chart_actions = $(``); this.title_field = this.widget.find(".widget-title"); this.body = this.widget.find(".widget-body"); this.action_area = this.widget.find(".widget-control"); this.head = this.widget.find(".widget-head"); + this.footer = this.widget.find(".widget-footer"); this.set_title(); this.set_actions(); this.set_body(); diff --git a/frappe/public/less/desktop.less b/frappe/public/less/desktop.less index fc11eec93f..eca4903e88 100644 --- a/frappe/public/less/desktop.less +++ b/frappe/public/less/desktop.less @@ -211,6 +211,11 @@ margin-bottom: 8px !important; font-weight: 500; } + + .widget-footer { + font-size: 85%; + color: @text-muted; + } } &.onboarding-widget-box { From 1c65e4ba04d8e60018fbb25801503d527da16b44 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Sun, 15 Mar 2020 19:00:13 +0530 Subject: [PATCH 036/140] feat: show last sync --- frappe/public/js/frappe/widgets/chart_widget.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index 4226c8463e..326b455dac 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -291,7 +291,7 @@ export default class ChartWidget extends Widget { this.filter_group.add_filters_to_filter_group(this.filters); }); } -// + set_chart_actions(actions) { this.chart_actions = $(`
- + + From 57bac6fff88c07f70303bf00a49596acb653ce21 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 17 Mar 2020 19:24:03 +0530 Subject: [PATCH 059/140] fix: Avoid unnecessary cint calls --- frappe/model/meta.py | 2 +- frappe/public/js/frappe/form/formatters.js | 4 ++-- frappe/public/js/frappe/model/meta.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frappe/model/meta.py b/frappe/model/meta.py index d208797644..424856b5cf 100644 --- a/frappe/model/meta.py +++ b/frappe/model/meta.py @@ -549,7 +549,7 @@ def get_field_precision(df, doc=None, currency=None): elif df.fieldtype == "Currency": if df.precision and cint(df.precision) == 0: - precision = cint(df.precision) + precision = 0 else: precision = cint(frappe.db.get_default("currency_precision")) if not precision: diff --git a/frappe/public/js/frappe/form/formatters.js b/frappe/public/js/frappe/form/formatters.js index 5db4bbaced..ef6976e896 100644 --- a/frappe/public/js/frappe/form/formatters.js +++ b/frappe/public/js/frappe/form/formatters.js @@ -63,8 +63,8 @@ frappe.form.formatters = { var currency = frappe.meta.get_field_currency(docfield, doc); var precision; - if (docfield.precision === 0) { - precision = docfield.precision; + if (docfield.precision && cint(docfield.precision) === 0) { + precision = 0; } else { precision = docfield.precision || cint(frappe.boot.sysdefaults.currency_precision) || 2; } diff --git a/frappe/public/js/frappe/model/meta.js b/frappe/public/js/frappe/model/meta.js index c252e6821b..fc815c1d92 100644 --- a/frappe/public/js/frappe/model/meta.js +++ b/frappe/public/js/frappe/model/meta.js @@ -257,7 +257,7 @@ $.extend(frappe.meta, { precision = cint(df.precision); } else if(df && df.fieldtype === "Currency") { if (df.precision && cint(df.precision) === 0) { - precision = cint(df.precision); + precision = 0; } else { precision = cint(frappe.defaults.get_default("currency_precision")); if(!precision) { From f46b3d89a92ac89b2d609f1e52eb820394e37a6a Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 17 Mar 2020 21:20:44 +0530 Subject: [PATCH 060/140] fix: Pass zero precision as string --- frappe/model/meta.py | 13 +++++-------- frappe/public/js/frappe/form/formatters.js | 8 +------- frappe/public/js/frappe/model/meta.js | 16 ++++++---------- 3 files changed, 12 insertions(+), 25 deletions(-) diff --git a/frappe/model/meta.py b/frappe/model/meta.py index 424856b5cf..1938a4a96c 100644 --- a/frappe/model/meta.py +++ b/frappe/model/meta.py @@ -544,17 +544,14 @@ def get_field_precision(df, doc=None, currency=None): """get precision based on DocField options and fieldvalue in doc""" from frappe.utils import get_number_format_info - if cint(df.precision): + if df.precision: precision = cint(df.precision) elif df.fieldtype == "Currency": - if df.precision and cint(df.precision) == 0: - precision = 0 - else: - precision = cint(frappe.db.get_default("currency_precision")) - if not precision: - number_format = frappe.db.get_default("number_format") or "#,###.##" - decimal_str, comma_str, precision = get_number_format_info(number_format) + precision = cint(frappe.db.get_default("currency_precision")) + if not precision: + number_format = frappe.db.get_default("number_format") or "#,###.##" + decimal_str, comma_str, precision = get_number_format_info(number_format) else: precision = cint(frappe.db.get_default("float_precision")) or 3 diff --git a/frappe/public/js/frappe/form/formatters.js b/frappe/public/js/frappe/form/formatters.js index ef6976e896..d178c59100 100644 --- a/frappe/public/js/frappe/form/formatters.js +++ b/frappe/public/js/frappe/form/formatters.js @@ -61,13 +61,7 @@ frappe.form.formatters = { }, Currency: function (value, docfield, options, doc) { var currency = frappe.meta.get_field_currency(docfield, doc); - var precision; - - if (docfield.precision && cint(docfield.precision) === 0) { - precision = 0; - } else { - precision = docfield.precision || cint(frappe.boot.sysdefaults.currency_precision) || 2; - } + var precision = docfield.precision || cint(frappe.boot.sysdefaults.currency_precision) || 2; // If you change anything below, it's going to hurt a company in UAE, a bit. if (precision > 2) { diff --git a/frappe/public/js/frappe/model/meta.js b/frappe/public/js/frappe/model/meta.js index fc815c1d92..b7ad52838c 100644 --- a/frappe/public/js/frappe/model/meta.js +++ b/frappe/public/js/frappe/model/meta.js @@ -253,18 +253,14 @@ $.extend(frappe.meta, { get_field_precision: function(df, doc) { var precision = null; - if (df && cint(df.precision)) { + if (df && df.precision) { precision = cint(df.precision); } else if(df && df.fieldtype === "Currency") { - if (df.precision && cint(df.precision) === 0) { - precision = 0; - } else { - precision = cint(frappe.defaults.get_default("currency_precision")); - if(!precision) { - var number_format = get_number_format(); - var number_format_info = get_number_format_info(number_format); - precision = number_format_info.precision; - } + precision = cint(frappe.defaults.get_default("currency_precision")); + if(!precision) { + var number_format = get_number_format(); + var number_format_info = get_number_format_info(number_format); + precision = number_format_info.precision; } } else { precision = cint(frappe.defaults.get_default("float_precision")) || 3; From f5b5c69b8ff5a57d73c06c85040f36682fdda31a Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 17 Mar 2020 22:04:50 +0530 Subject: [PATCH 061/140] fix: duplicate entry error while renaming item (#9652) From aeb9d87cb7c77886b66ba8393541d7ff089300b7 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Mar 2020 10:16:03 +0530 Subject: [PATCH 062/140] fix: breadcrumbs for new desk --- frappe/public/js/frappe/views/breadcrumbs.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/views/breadcrumbs.js b/frappe/public/js/frappe/views/breadcrumbs.js index 339052342d..2aef1a8218 100644 --- a/frappe/public/js/frappe/views/breadcrumbs.js +++ b/frappe/public/js/frappe/views/breadcrumbs.js @@ -18,7 +18,8 @@ frappe.breadcrumbs = { 'Workflow': 'Settings', 'Printing': 'Settings', 'Setup': 'Settings', - 'Event Streaming': 'Automation' + 'Event Streaming': 'Tools', + 'Automation': 'Tools', }, set_doctype_module: function(doctype, module) { @@ -95,7 +96,7 @@ frappe.breadcrumbs = { if(module_info && !module_info.blocked && frappe.visible_modules.includes(module_info.module_name)) { - $(repl('
  • %(label)s
  • ', + $(repl('
  • %(label)s
  • ', { module: breadcrumbs.module, label: __(label) })) .appendTo($breadcrumbs); } From 83a957bbb85f17427d143c17a055f18307571a1b Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Mar 2020 10:28:17 +0530 Subject: [PATCH 063/140] feat: remove ModuleView --- frappe/public/js/frappe/views/pageview.js | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/frappe/public/js/frappe/views/pageview.js b/frappe/public/js/frappe/views/pageview.js index 71f1e8e9a8..66e9356106 100644 --- a/frappe/public/js/frappe/views/pageview.js +++ b/frappe/public/js/frappe/views/pageview.js @@ -164,26 +164,4 @@ frappe.show_message_page = function(opts) { ); frappe.container.change_to(opts.page_name); -}; - -frappe.views.ModulesFactory = class ModulesFactory extends frappe.views.Factory { - show() { - if (frappe.pages.modules) { - frappe.container.change_to('modules'); - } else { - this.make('modules'); - } - } - - make(page_name) { - const assets = [ - '/assets/js/modules.min.js' - ]; - - frappe.require(assets, () => { - frappe.modules.home = new frappe.modules.Home({ - parent: this.make_page(true, page_name) - }); - }); - } }; \ No newline at end of file From 53bf9989fbaded7598f11d42ad96296945a13388 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Mar 2020 10:33:56 +0530 Subject: [PATCH 064/140] feat: remove module.min.css --- frappe/hooks.py | 1 - frappe/public/build.json | 3 - frappe/public/css/module.css | 113 ------------------------- frappe/public/less/module.less | 147 --------------------------------- 4 files changed, 264 deletions(-) delete mode 100644 frappe/public/css/module.css delete mode 100644 frappe/public/less/module.less diff --git a/frappe/hooks.py b/frappe/hooks.py index cdc6e00bdd..c44c05fdf4 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -42,7 +42,6 @@ app_include_css = [ "assets/css/list.min.css", "assets/css/form.min.css", "assets/css/report.min.css", - "assets/css/module.min.css" ] web_include_js = [ diff --git a/frappe/public/build.json b/frappe/public/build.json index 9f0ed63c89..2999b9b343 100755 --- a/frappe/public/build.json +++ b/frappe/public/build.json @@ -240,9 +240,6 @@ "public/js/frappe/ui/dashboard_chart.js", "public/js/frappe/barcode_scanner/index.js" ], - "css/module.min.css": [ - "public/less/module.less" - ], "css/form.min.css": [ "public/less/form_grid.less" ], diff --git a/frappe/public/css/module.css b/frappe/public/css/module.css deleted file mode 100644 index 9e937b0957..0000000000 --- a/frappe/public/css/module.css +++ /dev/null @@ -1,113 +0,0 @@ -.module-head { - padding: 15px 30px; - border-bottom: 1px solid #EBEFF2; -} -.module-head h1 { - padding: 0px; - margin: 0px; -} -.module-body { - padding: 0px 15px; -} -.module-body .section-head { - margin-bottom: 15px; - margin-top: 0px; -} -.module-section { - border-bottom: 1px solid #EBEFF2; -} -.module-section .module-section-link { - line-height: 1.5em; -} -.module-section-column { - padding: 30px; -} -@media (min-width: 767px) { - .module-section:nth-child(even) { - background-color: #fafbfc; - } - .module-section:last-child { - border-bottom: none; - } -} -@media (max-width: 991px) { - .module-body { - margin-top: 15px; - border-top: 1px solid #d1d8dd; - } -} -@media (max-width: 767px) { - .module-body { - margin-top: 0; - border-top: 1px solid transparent; - } -} -@media (max-width: 767px) { - .module-section { - border: none; - } - .module-section-column { - border-bottom: 1px solid #EBEFF2; - } - .module-section-column:nth-child(even) { - background-color: #fafbfc; - } - .module-section:last-child .module-section-column:last-child { - border-bottom: none; - } -} -.module-item { - margin: 0px; - padding: 7px; - font-weight: 400; - border-bottom: 1px solid #d1d8dd; - cursor: pointer; - transition: 0.2s; - -webkit-transition: 0.2s; -} -.module-item h4 { - display: inline-block; -} -.module-item .module-item-description { - margin-top: -5px; -} -.module-item .badge { - margin-top: -2px; - margin-left: 3px; -} -.module-item:hover, -.module-item:focus { - background-color: #F7FAFC; -} -.module-item:last-child { - border: none; -} -.module-link.active .icon-chevron-right { - margin-top: 4px; - display: block !important; -} -.module-item-progress { - margin-bottom: 10px; - height: 17px; -} -.module-item-progress-total { - height: 7px; - background-color: #999999; - width: 0px; -} -.module-item-progress-open { - height: 7px; - background-color: red; - width: 0px; -} -@media (max-width: 767px) { - body[data-route^="Module"] .page-title { - width: 100%; - } - body[data-route^="Module"] .page-actions { - display: none !important; - } - body[data-route^="Module"] .layout-main-section { - border-bottom: 0px; - } -} diff --git a/frappe/public/less/module.less b/frappe/public/less/module.less deleted file mode 100644 index f924778864..0000000000 --- a/frappe/public/less/module.less +++ /dev/null @@ -1,147 +0,0 @@ -@import "variables.less"; - -.module-head { - padding: 15px 30px; - border-bottom: 1px solid @light-border-color; -} - -.module-head h1 { - padding: 0px; - margin: 0px; -} - -.module-body { - padding: 0px 15px; - - .section-head { - margin-bottom: 15px; - margin-top: 0px; - } -} - -.module-section { - border-bottom: 1px solid @light-border-color; - - .module-section-link { - line-height: 1.5em; - // font-size: 14px; - } -} - -.module-section-column { - padding: 30px; -} - -@media(min-width: @screen-xs) { - .module-section:nth-child(even) { - background-color: @light-bg; - } - - .module-section:last-child { - border-bottom: none; - } -} - -@media(max-width: @screen-sm) { - .module-body { - margin-top: 15px; - border-top: 1px solid @border-color; - } -} - -@media(max-width: @screen-xs) { - .module-body { - margin-top: 0; - border-top: 1px solid transparent; - } -} - -@media(max-width: @screen-xs) { - .module-section { - border: none; - } - - .module-section-column { - border-bottom: 1px solid @light-border-color; - } - - .module-section-column:nth-child(even) { - background-color: @light-bg; - } - - .module-section:last-child .module-section-column:last-child { - border-bottom: none; - } -} - - -.module-item { - margin: 0px; - padding: 7px; - font-weight: 400; - border-bottom: 1px solid @border-color; - cursor: pointer; - transition: 0.2s; - -webkit-transition: 0.2s; -} - -.module-item h4 { - display: inline-block; -} - -.module-item .module-item-description { - margin-top: -5px; -} - -.module-item .badge { - margin-top: -2px; - margin-left: 3px; -} - -.module-item:hover, .module-item:focus { - background-color: @panel-bg; -} - -.module-item:last-child { - border: none; -} - -.module-link.active .icon-chevron-right { - margin-top: 4px; - display: block !important; -} - -.module-item-progress { - margin-bottom: 10px; - height: 17px; -} - -.module-item-progress-total { - height: 7px; - background-color: #999999; - width: 0px; -} - -.module-item-progress-open { - height: 7px; - background-color: red; - width: 0px; -} - -@media(max-width: @screen-xs) { - - body[data-route^="Module"] { - .page-title { - width: 100%; - } - - - .page-actions { - display: none !important; - } - - .layout-main-section { - border-bottom: 0px; - } - } -} From 3f31981e7eaa86b10598d2f7d11d6d383f9f3792 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Mar 2020 12:53:43 +0530 Subject: [PATCH 065/140] refactor: fix padding for dashboard widget --- frappe/public/less/desktop.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/less/desktop.less b/frappe/public/less/desktop.less index ad1f973713..354dad7c5e 100644 --- a/frappe/public/less/desktop.less +++ b/frappe/public/less/desktop.less @@ -197,7 +197,7 @@ // Overrides for each widgets &.dashboard-widget-box { - padding-bottom: 10px !important; + padding: 10px 15px !important; min-height: 260px; .chart-column-container { From 8e392d2dc52f38dc3e69f42c03cc6f6b0e9d3c83 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Mar 2020 13:57:48 +0530 Subject: [PATCH 066/140] refactor: show summary only in full width --- frappe/public/js/frappe/widgets/chart_widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index ca92b1a9d9..e8cfa06108 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -58,7 +58,7 @@ export default class ChartWidget extends Widget { // Delete existing chart when refreshing delete this.dashboardchart; this.render(); - this.set_summary(); + this.width == "Full" && this.set_summary(); }); }); } From ad489fd97d64e89cbc24234dd91063b1f37434c9 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Mar 2020 15:03:57 +0530 Subject: [PATCH 067/140] fix: linitng fixes --- frappe/public/js/frappe/widgets/chart_widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index e8cfa06108..b21f9665d8 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -48,7 +48,7 @@ export default class ChartWidget extends Widget { } this.fetch(this.filters).then(data => { - this.summary = [] + this.summary = []; if (this.chart_doc.chart_type == 'Report') { this.summary = data.report_summary; data = this.get_report_chart_data(data); From 763395d34ba4d3a14e7b92de1728f04644fa0b33 Mon Sep 17 00:00:00 2001 From: prssanna Date: Wed, 18 Mar 2020 15:22:23 +0530 Subject: [PATCH 068/140] fix: update summary when filters are applied on a chart --- frappe/public/js/frappe/widgets/chart_widget.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index b21f9665d8..cc9e97b877 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -25,12 +25,16 @@ export default class ChartWidget extends Widget { } set_summary() { - let $summary = $(`
    `).hide().prependTo(this.body); + if (!this.$summary) { + this.$summary = $(`
    `).hide().prependTo(this.body); + } else { + this.$summary.empty(); + } this.summary.forEach((summary) => { - build_summary_item(summary).appendTo($summary); + build_summary_item(summary).appendTo(this.$summary); }) - this.summary.length && $summary.show(); + this.summary.length && this.$summary.show(); } make_chart() { @@ -58,7 +62,7 @@ export default class ChartWidget extends Widget { // Delete existing chart when refreshing delete this.dashboardchart; this.render(); - this.width == "Full" && this.set_summary(); + this.width == "Full" && this.summary && this.set_summary(); }); }); } @@ -117,12 +121,14 @@ export default class ChartWidget extends Widget { this.fetch(this.filters, true, this.args).then(data => { if (this.chart_doc.chart_type == 'Report') { + this.summary = data.report_summary; data = this.get_report_chart_data(data); } this.update_chart_object(); this.data = data; this.render(); + this.summary && this.set_summary(); }); } From b9bb6e651302ca7a9451df982c7c7e72f995d6a3 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 18 Mar 2020 16:30:53 +0530 Subject: [PATCH 069/140] fix: Updated value of _seen in db while resetting _seen --- frappe/model/document.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/model/document.py b/frappe/model/document.py index cfb8afac4d..41f946efd9 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -978,7 +978,7 @@ class Document(BaseDocument): def reset_seen(self): """Clear _seen property and set current user as seen""" if getattr(self.meta, 'track_seen', False): - self._seen = json.dumps([frappe.session.user]) + self.db_set('_seen', json.dumps([frappe.session.user]), update_modified=False) def notify_update(self): """Publish realtime that the current document is modified""" From 878101d16b37b7503d832f2e1ef9c7dee2cd8096 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 18 Mar 2020 16:46:32 +0530 Subject: [PATCH 070/140] style: Fix codacy --- frappe/email/doctype/notification/notification.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py index 582cb5d3c4..6a3dd89873 100644 --- a/frappe/email/doctype/notification/notification.py +++ b/frappe/email/doctype/notification/notification.py @@ -140,7 +140,7 @@ def get_context(context): doc.flags.in_notification_update = True doc.save(ignore_permissions=True) doc.flags.in_notification_update = False - except Exception as e: + except Exception: frappe.log_error(title='Document update failed', message=frappe.get_traceback()) def send_an_email(self, doc, context): From 02925d8d34b73f8fd1975de39e87d9e9a213ee8e Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Mar 2020 18:30:47 +0530 Subject: [PATCH 071/140] chore: remove commented code --- frappe/public/js/frappe/views/desktop/desktop.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/frappe/public/js/frappe/views/desktop/desktop.js b/frappe/public/js/frappe/views/desktop/desktop.js index 4391a572af..656c5ce021 100644 --- a/frappe/public/js/frappe/views/desktop/desktop.js +++ b/frappe/public/js/frappe/views/desktop/desktop.js @@ -152,13 +152,7 @@ export default class Desktop { return $page; } - setup_events() { - // $(document).keydown(e => { - // if (e.keyCode == 9) { - // console.log("navigate"); - // } - // }); - } + setup_events() { } } class DesktopPage { From 3ac988441b5353d9092dab7e19eed8a1161b766c Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Mar 2020 18:30:55 +0530 Subject: [PATCH 072/140] refactor: better variable names --- frappe/public/js/frappe/widgets/chart_widget.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index cc9e97b877..d92fb80f62 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -60,7 +60,7 @@ export default class ChartWidget extends Widget { this.update_last_synced(); this.data = data; // Delete existing chart when refreshing - delete this.dashboardchart; + delete this.dashboard_chart; this.render(); this.width == "Full" && this.summary && this.set_summary(); }); @@ -378,10 +378,10 @@ export default class ChartWidget extends Widget { shortenYAxisNumbers: 1 } }; - if (!this.dashboardchart) { - this.dashboardchart = new frappe.Chart(this.body[0], chart_args); + if (!this.dashboard_chart) { + this.dashboard_chart = new frappe.Chart(this.body[0], chart_args); } else { - this.dashboardchart.update(this.data); + this.dashboard_chart.update(this.data); } } } From 05599645c86ef8c57e04c17290079a82eb3dadc6 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Mar 2020 18:59:30 +0530 Subject: [PATCH 073/140] refactor: commonify fetch and render --- frappe/public/js/frappe/widgets/chart_widget.js | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index d92fb80f62..1d5f267cf1 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -50,20 +50,7 @@ export default class ChartWidget extends Widget { if (this.chart_doc.timeseries && this.chart_doc.chart_type !== 'Custom') { this.render_time_series_filters(); } - - this.fetch(this.filters).then(data => { - this.summary = []; - if (this.chart_doc.chart_type == 'Report') { - this.summary = data.report_summary; - data = this.get_report_chart_data(data); - } - this.update_last_synced(); - this.data = data; - // Delete existing chart when refreshing - delete this.dashboard_chart; - this.render(); - this.width == "Full" && this.summary && this.set_summary(); - }); + this.fetch_and_update_chart(); }); } From 5fb0cb3c431d6c2270569baad06f6c292ee9b2bc Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 18 Mar 2020 19:31:37 +0530 Subject: [PATCH 074/140] feat: added loading state and empty state --- .../public/js/frappe/widgets/chart_widget.js | 21 ++++++++++++++----- frappe/public/less/desktop.less | 6 ++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index 1d5f267cf1..2b73f54d50 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -24,9 +24,15 @@ export default class ChartWidget extends Widget { this.make_chart(); } + set_loading_state() { + this.loading = $(`
    ${__("Loading...")}
    `) + this.loading.appendTo(this.body) + } + set_summary() { if (!this.$summary) { - this.$summary = $(`
    `).hide().prependTo(this.body); + this.$summary = $(`
    `).hide(); + this.head.after(this.$summary); } else { this.$summary.empty(); } @@ -40,6 +46,7 @@ export default class ChartWidget extends Widget { make_chart() { this.body.empty(); this.get_settings().then(() => { + this.set_loading_state(); this.prepare_chart_object(); // this.prepare_container(); @@ -114,8 +121,8 @@ export default class ChartWidget extends Widget { this.update_chart_object(); this.data = data; + this.loading.remove(); this.render(); - this.summary && this.set_summary(); }); } @@ -178,7 +185,8 @@ export default class ChartWidget extends Widget { label: __("Refresh"), action: 'action-refresh', handler: () => { - this.fetch_and_update_chart(); + delete this.dashboard_chart; + this.make_chart(); } }, { @@ -311,7 +319,6 @@ export default class ChartWidget extends Widget { } fetch(filters, refresh=false, args) { - // this.chart_container.find('.chart-loading-state').removeClass('hide'); let method = this.settings ? this.settings.method : 'frappe.desk.doctype.dashboard_chart.dashboard_chart.get'; @@ -355,7 +362,10 @@ export default class ChartWidget extends Widget { colors = [this.chart_doc.color || "light-blue"]; } - if (this.data) { + if (!this.data || !Object.keys(this.data).length) { + const empty = $(`
    ${__("No Data...")}
    `) + empty.appendTo(this.body) + } else { let chart_args = { data: this.data, type: chart_type_map[this.chart_doc.type], @@ -370,6 +380,7 @@ export default class ChartWidget extends Widget { } else { this.dashboard_chart.update(this.data); } + this.width == "Full" && this.summary && this.set_summary(); } } diff --git a/frappe/public/less/desktop.less b/frappe/public/less/desktop.less index 354dad7c5e..05f1f11113 100644 --- a/frappe/public/less/desktop.less +++ b/frappe/public/less/desktop.less @@ -210,6 +210,12 @@ color: @text-muted; } + .chart-loading-state { + display: flex; + justify-content: center; + align-items: center; + } + .report-summary { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); border: none; From ce5eaf91198d899c77449a25e261d37fcc490375 Mon Sep 17 00:00:00 2001 From: Marica Date: Wed, 18 Mar 2020 22:02:50 +0530 Subject: [PATCH 075/140] fix: Handling datetime objects in Data Import Beta (#9656) * fix: Handling datetime objects in Data Import Co-Authored-By: Shivam Mishra * fix: Avoid calling parse_date_format if already datetime. * fix: Changed type check to isinstance and syntactical improvements * chore: use predefined datetime format Signed-off-by: Chinmay D. Pai * chore: fix deepsource issues Signed-off-by: Chinmay D. Pai Co-authored-by: Shivam Mishra Co-authored-by: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> Co-authored-by: Chinmay D. Pai --- .../core/doctype/data_import/importer_new.py | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/frappe/core/doctype/data_import/importer_new.py b/frappe/core/doctype/data_import/importer_new.py index 5e36c8ad62..1f446cfb39 100644 --- a/frappe/core/doctype/data_import/importer_new.py +++ b/frappe/core/doctype/data_import/importer_new.py @@ -9,7 +9,7 @@ import timeit import frappe from datetime import datetime from frappe import _ -from frappe.utils import cint, flt, update_progress_bar, cstr +from frappe.utils import cint, flt, update_progress_bar, cstr, DATETIME_FORMAT from frappe.utils.csvutils import read_csv_content from frappe.utils.xlsxutils import ( read_xlsx_file_from_attached_file, @@ -345,6 +345,9 @@ class Importer: return columns_with_serial_no, data_with_serial_no def parse_value(self, value, df): + if isinstance(value, datetime) and df.fieldtype in ["Date", "Datetime"]: + return value + value = cstr(value) # convert boolean values to 0 or 1 @@ -362,14 +365,13 @@ class Importer: return value def parse_date_format(self, value, df): - date_format = self.get_date_format_for_df(df) - if date_format: - try: - return datetime.strptime(value, date_format) - except: - # ignore date values that dont match the format - # import will break for these values later - pass + date_format = self.get_date_format_for_df(df) or DATETIME_FORMAT + try: + return datetime.strptime(value, date_format) + except ValueError: + # ignore date values that dont match the format + # import will break for these values later + pass return value def get_date_format_for_df(self, df): @@ -396,7 +398,8 @@ class Importer: date_values = [ row[column_index] for row in self.data[:PARSE_ROW_COUNT] if row[column_index] ] - date_formats = [guess_date_format(d) for d in date_values] + date_formats = [guess_date_format(d) if isinstance(d, str) else None + for d in date_values] if not date_formats: return max_occurred_date_format = max(set(date_formats), key=date_formats.count) From b6e6d274f7f7af3e3ececc58aca944f22ca8eb6a Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 19 Mar 2020 10:30:40 +0530 Subject: [PATCH 076/140] fix (codacy): added semicolon --- frappe/public/js/frappe/widgets/chart_widget.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index 2b73f54d50..a9b6b319d1 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -25,8 +25,8 @@ export default class ChartWidget extends Widget { } set_loading_state() { - this.loading = $(`
    ${__("Loading...")}
    `) - this.loading.appendTo(this.body) + this.loading = $(`
    ${__("Loading...")}
    `); + this.loading.appendTo(this.body); } set_summary() { @@ -363,8 +363,8 @@ export default class ChartWidget extends Widget { } if (!this.data || !Object.keys(this.data).length) { - const empty = $(`
    ${__("No Data...")}
    `) - empty.appendTo(this.body) + const empty = $(`
    ${__("No Data...")}
    `); + empty.appendTo(this.body); } else { let chart_args = { data: this.data, From 8c9d55edcaa3b9e95e2d50528a59b19730b6350b Mon Sep 17 00:00:00 2001 From: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> Date: Thu, 19 Mar 2020 13:25:54 +0530 Subject: [PATCH 077/140] Revert "feat: change fieldtype in db with customize form" --- .../doctype/customize_form/customize_form.py | 33 +------------------ frappe/database/mariadb/database.py | 4 +-- frappe/database/schema.py | 8 ++--- 3 files changed, 5 insertions(+), 40 deletions(-) diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index c8d1bb18b4..8d47a075ba 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -166,6 +166,7 @@ class CustomizeForm(Document): self.flags.update_db = False self.flags.rebuild_doctype_for_global_search = False + self.set_property_setters() self.update_custom_fields() self.set_name_translation() @@ -361,45 +362,13 @@ class CustomizeForm(Document): def validate_fieldtype_change(self, df, old_value, new_value): allowed = False - self.check_length_for_fieldtypes = [] for allowed_changes in allowed_fieldtype_change: if (old_value in allowed_changes and new_value in allowed_changes): allowed = True - if frappe.db.type_map.get(old_value)[1] > frappe.db.type_map.get(new_value)[1]: - self.check_length_for_fieldtypes.append({'df': df, 'old_value': old_value}) - self.validate_fieldtype_length() - else: - self.flags.update_db = True break if not allowed: frappe.throw(_("Fieldtype cannot be changed from {0} to {1} in row {2}").format(old_value, new_value, df.idx)) - def validate_fieldtype_length(self): - for field in self.check_length_for_fieldtypes: - df = field.get('df') - max_length = frappe.db.type_map.get(df.fieldtype)[1] - fieldname = df.fieldname - docs = frappe.db.sql(''' - SELECT name, {fieldname}, LENGTH({fieldname}) AS len - FROM `tab{doctype}` - WHERE LENGTH({fieldname}) > {max_length} - '''.format( - fieldname = fieldname, - doctype = self.doc_type, - max_length = max_length - ), as_dict = True) - links = [] - label = df.label - for doc in docs: - links.append(frappe.utils.get_link_to_form(self.doc_type, doc.name)) - links_str = ', '.join(links) - - if docs: - frappe.throw(_('Value for field {0} is too long in {1}. Length should be lesser than {2} characters') - .format(frappe.bold(label), links_str, frappe.bold(max_length)), title=_('Data Too Long'), is_minimizable=len(docs) > 1) - - self.flags.update_db = True - def reset_to_defaults(self): if not self.doc_type: return diff --git a/frappe/database/mariadb/database.py b/frappe/database/mariadb/database.py index 926425f857..cd053569f0 100644 --- a/frappe/database/mariadb/database.py +++ b/frappe/database/mariadb/database.py @@ -33,7 +33,7 @@ class MariaDBDatabase(Database): 'Float': ('decimal', '18,6'), 'Percent': ('decimal', '18,6'), 'Check': ('int', '1'), - 'Small Text': ('text', 65535), + 'Small Text': ('text', ''), 'Long Text': ('longtext', ''), 'Code': ('longtext', ''), 'Text Editor': ('longtext', ''), @@ -42,7 +42,7 @@ class MariaDBDatabase(Database): 'Date': ('date', ''), 'Datetime': ('datetime', '6'), 'Time': ('time', '6'), - 'Text': ('text', 65535), + 'Text': ('text', ''), 'Data': ('varchar', self.VARCHAR_LEN), 'Link': ('varchar', self.VARCHAR_LEN), 'Dynamic Link': ('varchar', self.VARCHAR_LEN), diff --git a/frappe/database/schema.py b/frappe/database/schema.py index 73bdf32761..88cda9340b 100644 --- a/frappe/database/schema.py +++ b/frappe/database/schema.py @@ -69,7 +69,6 @@ class DBTable: lengths = {} precisions = {} uniques = {} - fieldtype = '' # optional fields like _comments if not self.meta.istable: @@ -101,7 +100,7 @@ class DBTable: filters={ "doc_type": self.doctype, "doctype_or_field": "DocField", - "property": ["in", ["precision", "length", "unique", "fieldtype"]] + "property": ["in", ["precision", "length", "unique"]] }): if ps.property=="length": @@ -113,13 +112,10 @@ class DBTable: elif ps.property=="unique": uniques[ps.field_name] = cint(ps.value) - if ps.property=="fieldtype": - fieldtype = ps.value - for f in fl: self.columns[f['fieldname']] = DbColumn(self, f['fieldname'], - fieldtype or f['fieldtype'], + f['fieldtype'], lengths.get(f["fieldname"]) or f.get('length'), f.get('default'), f.get('search_index'), From ba10ca1a99949b9d09b6d9bbc075185f41488bf2 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 19 Mar 2020 19:12:13 +0530 Subject: [PATCH 078/140] refactor: remove code for loading state --- .../public/js/frappe/views/desktop/desktop.js | 22 ------ frappe/public/less/desktop.less | 77 ------------------- 2 files changed, 99 deletions(-) diff --git a/frappe/public/js/frappe/views/desktop/desktop.js b/frappe/public/js/frappe/views/desktop/desktop.js index 656c5ce021..2d2b1a7353 100644 --- a/frappe/public/js/frappe/views/desktop/desktop.js +++ b/frappe/public/js/frappe/views/desktop/desktop.js @@ -15,12 +15,9 @@ export default class Desktop { make() { this.make_container(); - // this.show_loading_state(); this.fetch_desktop_settings().then(() => { this.route(); this.make_sidebar(); - // this.setup_events(); - // this.hide_loading_state(); }); } @@ -40,25 +37,6 @@ export default class Desktop { this.body = this.container.find(".desk-body"); } - show_loading_state() { - // Add skeleton - let loading_sidebar = $( - '
    ' - ); - let loading_body = $( - `
    ` - ); - - // Append skeleton to body - loading_sidebar.appendTo(this.sidebar); - loading_body.appendTo(this.body); - } - - hide_loading_state() { - // Remove all skeleton - this.container.find(".skeleton").remove(); - } - fetch_desktop_settings() { return frappe .call("frappe.desk.desktop.get_desk_sidebar_items") diff --git a/frappe/public/less/desktop.less b/frappe/public/less/desktop.less index 05f1f11113..f9e40106a6 100644 --- a/frappe/public/less/desktop.less +++ b/frappe/public/less/desktop.less @@ -351,81 +351,4 @@ .pill-orange { background: @orange; -} - -// .pill-green { -// background: @green-light; -// color: @green-dark; -// } - -// .pill-red { -// background: @red-light; -// color: @red-dark; -// } - -// .pill-blue { -// background: @blue-light; -// color: @blue-dark; -// } - -// .pill-yellow { -// background: @yellow-light; -// color: @yellow-dark; -// } - -// .pill-orange { -// background: @orange-light; -// color: @orange-dark; -// } - -.skeleton { - width: 100%; - background-image: linear-gradient(90deg, @btn-bg, @panel-bg, @btn-bg); - // background-image: linear-gradient(90deg, black, white, black); - animation: shine-lines 0.8s infinite cubic-bezier(.65,.05,.36,1) -} - -.skeleton.skeleton-full { - flex: 1 1 auto; -} - -// .skeleton.skeleton-100 { -// height: 90%; -// } - -// .skeleton.skeleton-50 { -// height: 50%; -// } - -// .skeleton.skeleton-40 { -// height: 40%; -// } - -// .skeleton.skeleton-30 { -// height: 30%; -// } - -// .skeleton.skeleton-20 { -// height: 20%; -// } - -// .skeleton.skeleton-10 { -// height: 10%; -// } - -// .skeleton.skeleton-8 { -// height: 8%; -// } - -// .skeleton.skeleton-3 { -// height: 3%; -// } - -@keyframes shine-lines { - 0% { - background-position: -100px; - } - 100% { - background-position: 100px; - } } \ No newline at end of file From 9c42d0f5d6d6e8139030c894b7ab294339007674 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 20 Mar 2020 10:05:15 +0530 Subject: [PATCH 079/140] refactor: remove size option --- frappe/desk/doctype/desk_chart/desk_chart.json | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/frappe/desk/doctype/desk_chart/desk_chart.json b/frappe/desk/doctype/desk_chart/desk_chart.json index c32e774454..c3c9231353 100644 --- a/frappe/desk/doctype/desk_chart/desk_chart.json +++ b/frappe/desk/doctype/desk_chart/desk_chart.json @@ -6,8 +6,7 @@ "engine": "InnoDB", "field_order": [ "chart_name", - "label", - "size" + "label" ], "fields": [ { @@ -23,18 +22,11 @@ "fieldtype": "Data", "in_list_view": 1, "label": "Label" - }, - { - "fieldname": "size", - "fieldtype": "Select", - "in_list_view": 1, - "label": "Size", - "options": "Full\nHalf" } ], "istable": 1, "links": [], - "modified": "2020-01-23 16:47:16.265651", + "modified": "2020-03-20 10:04:13.992228", "modified_by": "Administrator", "module": "Desk", "name": "Desk Chart", From 52ae6bda7b655324ce02fdcab2403cbaf76ccd39 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 20 Mar 2020 11:17:43 +0530 Subject: [PATCH 080/140] fix: dashboard filters spacing --- frappe/public/less/desktop.less | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/frappe/public/less/desktop.less b/frappe/public/less/desktop.less index f9e40106a6..b95e72c471 100644 --- a/frappe/public/less/desktop.less +++ b/frappe/public/less/desktop.less @@ -183,10 +183,23 @@ display: flex; flex-direction: row-reverse; - .btn { + // Any immidiate child + >* { align-self: center; margin-left: 5px; } + + .dashboard-date-field { + .clearfix, + .help-box { + display: none; + } + + .frappe-control, + .form-group { + margin-bottom: 0px !important; + } + } } } From 7f3b14f9f4e89f312c35568e13d2af560beb41d2 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 20 Mar 2020 11:27:15 +0530 Subject: [PATCH 081/140] refactor (style): format code --- frappe/public/js/frappe/views/desktop/desktop.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/frappe/public/js/frappe/views/desktop/desktop.js b/frappe/public/js/frappe/views/desktop/desktop.js index 2d2b1a7353..54a25c3771 100644 --- a/frappe/public/js/frappe/views/desktop/desktop.js +++ b/frappe/public/js/frappe/views/desktop/desktop.js @@ -112,7 +112,9 @@ export default class Desktop { } get_page_to_show() { - const default_page = this.desktop_settings ? this.desktop_settings["Modules"][0].name : "Website"; + const default_page = this.desktop_settings + ? this.desktop_settings["Modules"][0].name + : "Website"; let page = frappe.get_route()[1] || localStorage.current_desk_page || @@ -130,7 +132,7 @@ export default class Desktop { return $page; } - setup_events() { } + setup_events() {} } class DesktopPage { @@ -138,7 +140,7 @@ class DesktopPage { this.container = container; this.page_name = page_name; this.sections = {}; - this.allow_customization = false + this.allow_customization = false; this.make(); } @@ -157,7 +159,7 @@ class DesktopPage { // this.make_onboarding(); if (!this.data) { delete localStorage.current_desk_page; - frappe.set_route('workspace'); + frappe.set_route("workspace"); return; } @@ -253,7 +255,7 @@ class DesktopPage { widgets: this.data.cards.items }); - this.sections['cards'] = cards; + this.sections["cards"] = cards; const legend = [ { @@ -279,4 +281,4 @@ class DesktopPage { ${legend.join("\n")}
    `).insertAfter(cards.body); } -} \ No newline at end of file +} From 07f1427bdde011b87b3301b70a06c635a809093f Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 20 Mar 2020 11:27:25 +0530 Subject: [PATCH 082/140] fix: default chart label --- frappe/desk/desktop.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/frappe/desk/desktop.py b/frappe/desk/desktop.py index 108d02f529..bb9aa44213 100644 --- a/frappe/desk/desktop.py +++ b/frappe/desk/desktop.py @@ -139,12 +139,17 @@ class Workspace: return new_data def get_charts(self): + all_charts = [] if frappe.has_permission("Dashboard Chart", throw=False): charts = self.doc.charts if len(self.extended_charts): charts = charts + self.extended_charts - return [chart for chart in charts] - return [] + + for chart in charts: + chart.label = chart.label if chart.label else chart.chart_name + all_charts.append(chart) + + return all_charts def get_shortcuts(self): From f8cfe70b3009cf562bcbd5b2a363742248d59d2b Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 20 Mar 2020 11:27:53 +0530 Subject: [PATCH 083/140] refactor (style): format code --- .../public/js/frappe/widgets/chart_widget.js | 281 +++++++++++------- 1 file changed, 179 insertions(+), 102 deletions(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index a9b6b319d1..5e6585924f 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -1,7 +1,7 @@ import Widget from "./base_widget.js"; import { build_summary_item } from "./utils"; -frappe.provide('frappe.dashboards'); -frappe.provide('frappe.dashboards.chart_sources'); +frappe.provide("frappe.dashboards"); +frappe.provide("frappe.dashboards.chart_sources"); export default class ChartWidget extends Widget { constructor(opts) { @@ -17,15 +17,19 @@ export default class ChartWidget extends Widget { } set_body() { - this.widget.addClass('dashboard-widget-box'); + this.widget.addClass("dashboard-widget-box"); if (this.width == "Full") { - this.widget.addClass('full-width'); + this.widget.addClass("full-width"); } this.make_chart(); } set_loading_state() { - this.loading = $(`
    ${__("Loading...")}
    `); + this.loading = $( + `
    ${__( + "Loading..." + )}
    ` + ); this.loading.appendTo(this.body); } @@ -37,9 +41,9 @@ export default class ChartWidget extends Widget { this.$summary.empty(); } - this.summary.forEach((summary) => { + this.summary.forEach(summary => { build_summary_item(summary).appendTo(this.$summary); - }) + }); this.summary.length && this.$summary.show(); } @@ -54,7 +58,10 @@ export default class ChartWidget extends Widget { this.prepare_chart_actions(); // this.setup_refresh_button(); this.setup_filter_button(); - if (this.chart_doc.timeseries && this.chart_doc.chart_type !== 'Custom') { + if ( + this.chart_doc.timeseries && + this.chart_doc.chart_type !== "Custom" + ) { this.render_time_series_filters(); } this.fetch_and_update_chart(); @@ -69,40 +76,54 @@ export default class ChartWidget extends Widget { } setup_refresh_button() { - const refresh_button = $(``); + const refresh_button = $( + `` + ); refresh_button.appendTo(this.action_area); - refresh_button.on('click', () => this.refresh()); + refresh_button.on("click", () => this.refresh()); } render_time_series_filters() { let filters = [ { label: this.chart_doc.timespan, - options: ['Select Date Range', 'Last Year', 'Last Quarter', 'Last Month', 'Last Week'], - action: (selected_item) => { + options: [ + "Select Date Range", + "Last Year", + "Last Quarter", + "Last Month", + "Last Week" + ], + action: selected_item => { this.selected_timespan = selected_item; - if (this.selected_timespan === 'Select Date Range') { + if (this.selected_timespan === "Select Date Range") { this.render_date_range_fields(); } else { this.selected_from_date = null; this.selected_to_date = null; - if (this.date_field_wrapper) this.date_field_wrapper.hide(); + if (this.date_field_wrapper) + this.date_field_wrapper.hide(); this.fetch_and_update_chart(); } } }, { label: this.chart_doc.time_interval, - options: ['Yearly', 'Quarterly', 'Monthly', 'Weekly', 'Daily'], - action: (selected_item) => { + options: ["Yearly", "Quarterly", "Monthly", "Weekly", "Daily"], + action: selected_item => { this.selected_time_interval = selected_item; this.fetch_and_update_chart(); } - }, + } ]; - frappe.dashboard_utils.render_chart_filters(filters, 'chart-actions', this.action_area, 0); + frappe.dashboard_utils.render_chart_filters( + filters, + "chart-actions", + this.action_area, + 0 + ); } fetch_and_update_chart() { @@ -114,7 +135,7 @@ export default class ChartWidget extends Widget { }; this.fetch(this.filters, true, this.args).then(data => { - if (this.chart_doc.chart_type == 'Report') { + if (this.chart_doc.chart_type == "Report") { this.summary = data.report_summary; data = this.get_report_chart_data(data); } @@ -127,24 +148,30 @@ export default class ChartWidget extends Widget { } render_date_range_fields() { - if (!this.date_field_wrapper || !this.date_field_wrapper.is(':visible')) { - this.date_field_wrapper = - $(`
    `) - .appendTo(this.action_area); + if ( + !this.date_field_wrapper || + !this.date_field_wrapper.is(":visible") + ) { + this.date_field_wrapper = $( + `
    ` + ).appendTo(this.action_area); this.date_range_field = frappe.ui.form.make_control({ df: { - fieldtype: 'DateRange', - fieldname: 'from_date', - placeholder: 'Date Range', - input_class: 'input-xs', + fieldtype: "DateRange", + fieldname: "from_date", + placeholder: "Date Range", + input_class: "input-xs", 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.fetch_and_update_chart(); } } @@ -160,7 +187,7 @@ export default class ChartWidget extends Widget { return result.chart.data; } else { let y_fields = []; - this.chart_doc.y_axis.map( field => { + this.chart_doc.y_axis.map(field => { y_fields.push(field.y_field); }); @@ -170,11 +197,15 @@ export default class ChartWidget extends Widget { chart_type: this.chart_doc.type, color: this.chart_doc.color }; - let columns = result.columns.map((col)=> { + let columns = result.columns.map(col => { return frappe.report_utils.prepare_field_from_column(col); }); - let data = frappe.report_utils.make_chart_options(columns, result, chart_fields).data; + let data = frappe.report_utils.make_chart_options( + columns, + result, + chart_fields + ).data; return data; } } @@ -183,7 +214,7 @@ export default class ChartWidget extends Widget { let actions = [ { label: __("Refresh"), - action: 'action-refresh', + action: "action-refresh", handler: () => { delete this.dashboard_chart; this.make_chart(); @@ -191,9 +222,13 @@ export default class ChartWidget extends Widget { }, { label: __("Edit..."), - action: 'action-edit', + action: "action-edit", handler: () => { - frappe.set_route('Form', 'Dashboard Chart', this.chart_doc.name); + frappe.set_route( + "Form", + "Dashboard Chart", + this.chart_doc.name + ); } } ]; @@ -201,40 +236,51 @@ export default class ChartWidget extends Widget { if (this.chart_doc.document_type) { actions.push({ label: __("{0} List", [this.chart_doc.document_type]), - action: 'action-list', + action: "action-list", handler: () => { - frappe.set_route('List', this.chart_doc.document_type); + frappe.set_route("List", this.chart_doc.document_type); } }); - } else if (this.chart_doc.chart_type === 'Report') { + } else if (this.chart_doc.chart_type === "Report") { actions.push({ label: __("{0} Report", [this.chart_doc.report_name]), - action: 'action-list', + action: "action-list", handler: () => { - frappe.set_route('query-report', this.chart_doc.report_name); + frappe.set_route( + "query-report", + this.chart_doc.report_name + ); } - }) + }); } this.set_chart_actions(actions); } setup_filter_button() { - this.is_document_type = this.chart_doc.chart_type!== 'Report' && this.chart_doc.chart_type!=='Custom'; - this.filter_button = - $(`
    ${__("Filter")}
    `); + this.is_document_type = + this.chart_doc.chart_type !== "Report" && + this.chart_doc.chart_type !== "Custom"; + this.filter_button = $( + `
    ${__( + "Filter" + )}
    ` + ); this.filter_button.appendTo(this.action_area); - this.filter_button.on('click', () => { + this.filter_button.on("click", () => { let fields; - frappe.dashboard_utils.get_filters_for_chart_type(this.chart_doc) + frappe.dashboard_utils + .get_filters_for_chart_type(this.chart_doc) .then(filters => { if (!this.is_document_type) { if (!filters) { - fields = [{ - fieldtype: "HTML", - options: __("No Filters Set") - }]; + fields = [ + { + fieldtype: "HTML", + options: __("No Filters Set") + } + ]; } else { fields = filters.filter(f => { if (f.on_change && !f.reqd) { @@ -247,10 +293,12 @@ export default class ChartWidget extends Widget { }); } } else { - fields = [{ - fieldtype: 'HTML', - fieldname: 'filter_area', - }]; + fields = [ + { + fieldtype: "HTML", + fieldname: "filter_area" + } + ]; } this.setup_filter_dialog(fields); @@ -259,7 +307,6 @@ export default class ChartWidget extends Widget { } setup_filter_dialog(fields) { - let me = this; let dialog = new frappe.ui.Dialog({ title: __(`Set Filters for ${this.chart_doc.chart_name}`), @@ -280,19 +327,20 @@ export default class ChartWidget extends Widget { }); if (this.is_document_type) { - this.create_filter_group_and_add_filters(dialog.get_field('filter_area').$wrapper); + this.create_filter_group_and_add_filters( + dialog.get_field("filter_area").$wrapper + ); } dialog.show(); dialog.set_values(this.filters); - } create_filter_group_and_add_filters(parent) { this.filter_group = new frappe.ui.FilterGroup({ parent: parent, doctype: this.chart_doc.document_type, - on_change: () => {}, + on_change: () => {} }); frappe.model.with_doctype(this.chart_doc.document_type, () => { @@ -306,7 +354,14 @@ export default class ChartWidget extends Widget {
    `); @@ -318,52 +373,55 @@ export default class ChartWidget extends Widget { this.chart_actions.appendTo(this.action_area); } - fetch(filters, refresh=false, args) { - let method = this.settings ? this.settings.method - : 'frappe.desk.doctype.dashboard_chart.dashboard_chart.get'; + fetch(filters, refresh = false, args) { + let method = this.settings + ? this.settings.method + : "frappe.desk.doctype.dashboard_chart.dashboard_chart.get"; - if (this.chart_doc.chart_type == 'Report') { + if (this.chart_doc.chart_type == "Report") { args = { report_name: this.chart_doc.report_name, - filters: filters, + filters: filters }; } else { args = { chart_name: this.chart_doc.name, 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, + 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 }; } - return frappe.xcall( - method, - args - ); + return frappe.xcall(method, args); } render() { const chart_type_map = { - 'Line': 'line', - 'Bar': 'bar', - 'Percentage': 'percentage', - 'Pie': 'pie' + Line: "line", + Bar: "bar", + Percentage: "percentage", + Pie: "pie" }; let colors = []; if (this.chart_doc.y_axis.length) { - this.chart_doc.y_axis.map( field => { + this.chart_doc.y_axis.map(field => { colors.push(field.color); }); - } else if (['Line', 'Bar'].includes(this.chart_doc.type)) { + } else if (["Line", "Bar"].includes(this.chart_doc.type)) { colors = [this.chart_doc.color || "light-blue"]; } - if (!this.data || !Object.keys(this.data).length) { - const empty = $(`
    ${__("No Data...")}
    `); + if (!this.data.labels || !this.data || !Object.keys(this.data).length) { + const empty = $( + `
    ${__( + "No Data..." + )}
    ` + ); empty.appendTo(this.body); } else { let chart_args = { @@ -376,7 +434,10 @@ export default class ChartWidget extends Widget { } }; if (!this.dashboard_chart) { - this.dashboard_chart = new frappe.Chart(this.body[0], chart_args); + this.dashboard_chart = new frappe.Chart( + this.body[0], + chart_args + ); } else { this.dashboard_chart.update(this.data); } @@ -385,7 +446,9 @@ export default class ChartWidget extends Widget { } update_last_synced() { - let last_synced_text = __("Last synced {0}", [comment_when(this.chart_doc.last_synced_on)]); + let last_synced_text = __("Last synced {0}", [ + comment_when(this.chart_doc.last_synced_on) + ]); this.footer.html(last_synced_text); } @@ -398,32 +461,46 @@ export default class ChartWidget extends Widget { } prepare_chart_object() { - this.filters = this.filters || JSON.parse(this.chart_doc.filters_json || '[]'); + this.filters = + this.filters || JSON.parse(this.chart_doc.filters_json || "[]"); } get_settings() { - return frappe.model.with_doc("Dashboard Chart", this.chart_name).then(chart_doc => { - this.chart_doc = chart_doc; - if (this.chart_doc.chart_type == 'Custom') { - // custom source - if (frappe.dashboards.chart_sources[this.chart_doc.source]) { - this.settings = frappe.dashboards.chart_sources[this.chart_doc.source]; + return frappe.model + .with_doc("Dashboard Chart", this.chart_name) + .then(chart_doc => { + this.chart_doc = chart_doc; + if (this.chart_doc.chart_type == "Custom") { + // custom source + if ( + frappe.dashboards.chart_sources[this.chart_doc.source] + ) { + this.settings = + frappe.dashboards.chart_sources[ + this.chart_doc.source + ]; + return Promise.resolve(); + } else { + const method = + "frappe.desk.doctype.dashboard_chart_source.dashboard_chart_source.get_config"; + return frappe + .xcall(method, { name: this.chart_doc.source }) + .then(config => { + frappe.dom.eval(config); + this.settings = + frappe.dashboards.chart_sources[ + this.chart_doc.source + ]; + }); + } + } else if (this.chart_doc.chart_type == "Report") { + this.settings = { + method: "frappe.desk.query_report.run" + }; return Promise.resolve(); } else { - const method = 'frappe.desk.doctype.dashboard_chart_source.dashboard_chart_source.get_config'; - return frappe.xcall(method, {name: this.chart_doc.source}).then(config => { - frappe.dom.eval(config); - this.settings = frappe.dashboards.chart_sources[this.chart_doc.source]; - }); + return Promise.resolve(); } - } else if (this.chart_doc.chart_type == 'Report') { - this.settings = { - 'method': 'frappe.desk.query_report.run' - }; - return Promise.resolve(); - } else { - return Promise.resolve(); - } - }); + }); } } \ No newline at end of file From 26d9a378e16e39fdf18d1b622a3c9d08a4ad6d23 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 20 Mar 2020 11:28:16 +0530 Subject: [PATCH 084/140] fix: improved grid rules --- frappe/public/less/desktop.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/public/less/desktop.less b/frappe/public/less/desktop.less index b95e72c471..d79c4ce726 100644 --- a/frappe/public/less/desktop.less +++ b/frappe/public/less/desktop.less @@ -124,7 +124,7 @@ .grid-col-2 { display: grid; - grid-template-columns: repeat(auto-fill, minmax(550px, 1fr)); + grid-template-columns: 1fr 1fr; // grid-auto-rows: minmax(62px, 1fr); column-gap: 15px; row-gap: 15px; @@ -138,7 +138,7 @@ .grid-col-1 { display: grid; - grid-template-columns: repeat(1fr); + grid-template-columns: repeat(auto-fill, minmax(550px, 1fr)); // grid-auto-rows: minmax(62px, 1fr); column-gap: 15px; row-gap: 15px; From 6721a4274d4bdb4a723796d78c03ed2dead0c3ca Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 20 Mar 2020 11:43:33 +0530 Subject: [PATCH 085/140] feat: hide title when date range field is shown for half width widget --- frappe/public/js/frappe/widgets/chart_widget.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index 5e6585924f..4f29006550 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -102,8 +102,15 @@ export default class ChartWidget extends Widget { } else { this.selected_from_date = null; this.selected_to_date = null; - if (this.date_field_wrapper) + if (this.date_field_wrapper) { this.date_field_wrapper.hide(); + + // Title maybe hidden becuase of date range fields + // in half width chart + this.title_field.show(); + this.head.css('flex-direction', "row"); + } + this.fetch_and_update_chart(); } } @@ -156,6 +163,11 @@ export default class ChartWidget extends Widget { `
    ` ).appendTo(this.action_area); + if(this.width != "Full" && this.widget.width() < 700) { + this.title_field.hide(); + this.head.css('flex-direction', "row-reverse"); + } + this.date_range_field = frappe.ui.form.make_control({ df: { fieldtype: "DateRange", From 0bfcd4d57460a68d622519d181122e9301c63d83 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 20 Mar 2020 12:29:11 +0530 Subject: [PATCH 086/140] fix: better logic for managing UI states --- .../public/js/frappe/widgets/chart_widget.js | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index 4f29006550..3f1afab67a 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -6,6 +6,7 @@ frappe.provide("frappe.dashboards.chart_sources"); export default class ChartWidget extends Widget { constructor(opts) { super(opts); + this.height = 240; } refresh() { @@ -24,13 +25,25 @@ export default class ChartWidget extends Widget { this.make_chart(); } - set_loading_state() { + setup_container() { + this.body.empty(); + this.loading = $( - `
    ${__( + `
    ${__( "Loading..." )}
    ` ); - this.loading.appendTo(this.body); + this.loading.hide().appendTo(this.body); + + this.empty = $( + `
    ${__( + "No Data..." + )}
    ` + ); + this.empty.hide().appendTo(this.body); + + this.chart_wrapper = $(`
    `); + this.chart_wrapper.appendTo(this.body); } set_summary() { @@ -48,22 +61,20 @@ export default class ChartWidget extends Widget { } make_chart() { - this.body.empty(); this.get_settings().then(() => { - this.set_loading_state(); + this.setup_container(); this.prepare_chart_object(); - // this.prepare_container(); - this.action_area.empty(); this.prepare_chart_actions(); - // this.setup_refresh_button(); this.setup_filter_button(); + if ( this.chart_doc.timeseries && this.chart_doc.chart_type !== "Custom" ) { this.render_time_series_filters(); } + this.fetch_and_update_chart(); }); } @@ -75,14 +86,6 @@ export default class ChartWidget extends Widget { buttons.appendTo(this.action_area); } - setup_refresh_button() { - const refresh_button = $( - `` - ); - refresh_button.appendTo(this.action_area); - refresh_button.on("click", () => this.refresh()); - } - render_time_series_filters() { let filters = [ { @@ -149,7 +152,6 @@ export default class ChartWidget extends Widget { this.update_chart_object(); this.data = data; - this.loading.remove(); this.render(); }); } @@ -428,18 +430,20 @@ export default class ChartWidget extends Widget { colors = [this.chart_doc.color || "light-blue"]; } - if (!this.data.labels || !this.data || !Object.keys(this.data).length) { - const empty = $( - `
    ${__( - "No Data..." - )}
    ` - ); - empty.appendTo(this.body); + if (!this.data || !this.data.labels.length || !Object.keys(this.data).length) { + this.chart_wrapper.hide(); + this.loading.hide(); + this.empty.show(); } else { + this.loading.hide(); + this.empty.hide(); + this.chart_wrapper.show(); + let chart_args = { data: this.data, type: chart_type_map[this.chart_doc.type], colors: colors, + height: this.height, axisOptions: { xIsSeries: this.chart_doc.timeseries, shortenYAxisNumbers: 1 @@ -447,7 +451,7 @@ export default class ChartWidget extends Widget { }; if (!this.dashboard_chart) { this.dashboard_chart = new frappe.Chart( - this.body[0], + this.chart_wrapper[0], chart_args ); } else { From 6afe5552c55d19f7e9d4437e1969e394c4f2e627 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 20 Mar 2020 13:23:40 +0530 Subject: [PATCH 087/140] fix (codacy): linitng fixes --- frappe/public/js/frappe/widgets/chart_widget.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index 3f1afab67a..2f3c70ec15 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -165,7 +165,7 @@ export default class ChartWidget extends Widget { `
    ` ).appendTo(this.action_area); - if(this.width != "Full" && this.widget.width() < 700) { + if (this.width != "Full" && this.widget.width() < 700) { this.title_field.hide(); this.head.css('flex-direction', "row-reverse"); } @@ -363,6 +363,7 @@ export default class ChartWidget extends Widget { } set_chart_actions(actions) { + /* eslint-disable indent */ this.chart_actions = $(`${values.dashboard}`; - let message = + let message = __(`Dashboard Chart ${values.chart_name} add to Dashboard ` + dashboard_route_html); frappe.msgprint(message); }); - + d.hide(); } }); @@ -119,15 +119,13 @@ frappe.ui.form.on('Dashboard Chart', { frm.trigger('set_chart_field_options'); } else { frappe.report_utils.get_report_filters(report_name).then(filters => { - frappe.after_ajax(()=> { - if (filters) { - frm.chart_filters = filters; - let filter_values = frappe.report_utils.get_filter_values(filters); - frm.set_value('filters_json', JSON.stringify(filter_values)); - } - frm.trigger('show_filters'); - frm.trigger('set_chart_field_options'); - }); + if (filters) { + frm.chart_filters = filters; + let filter_values = frappe.report_utils.get_filter_values(filters); + frm.set_value('filters_json', JSON.stringify(filter_values)); + } + frm.trigger('show_filters'); + frm.trigger('set_chart_field_options'); }); } @@ -140,7 +138,8 @@ frappe.ui.form.on('Dashboard Chart', { 'frappe.desk.query_report.run', { report_name: frm.doc.report_name, - filters: filters + filters: filters, + ignore_prepared_report: 1 } ).then(data => { frm.report_data = data; @@ -228,13 +227,11 @@ frappe.ui.form.on('Dashboard Chart', { show_filters: function(frm) { frm.chart_filters = []; frappe.dashboard_utils.get_filters_for_chart_type(frm.doc).then(filters => { - frappe.after_ajax(() => { if (filters) { frm.chart_filters = filters; } frm.trigger('render_filters_table'); - }); }); }, @@ -269,7 +266,7 @@ frappe.ui.form.on('Dashboard Chart', { if (filters.length > 0) { filters.forEach( filter => { - const filter_row = + const filter_row = $(` ${filter[1]} ${filter[2] || ""} @@ -295,7 +292,7 @@ frappe.ui.form.on('Dashboard Chart', { fields.map( f => { if (filters[f.fieldname]) { let condition = '='; - const filter_row = + const filter_row = $(` ${f.label} ${condition} diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index 2f3c70ec15..0b19987e7c 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -397,7 +397,8 @@ export default class ChartWidget extends Widget { if (this.chart_doc.chart_type == "Report") { args = { report_name: this.chart_doc.report_name, - filters: filters + filters: filters, + ignore_prepared_report: 1 }; } else { args = { From f79603e47b61bf3fa9fa0760b92ec1d6c1f20059 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 20 Mar 2020 15:27:44 +0530 Subject: [PATCH 091/140] refactor: use after_ajax to return filters --- frappe/public/js/frappe/views/reports/report_utils.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/views/reports/report_utils.js b/frappe/public/js/frappe/views/reports/report_utils.js index bd01d63c47..218017244e 100644 --- a/frappe/public/js/frappe/views/reports/report_utils.js +++ b/frappe/public/js/frappe/views/reports/report_utils.js @@ -112,13 +112,14 @@ frappe.report_utils = { return frappe.xcall( 'frappe.desk.query_report.get_script', - { + { report_name: report_name } ).then(r => { frappe.dom.eval(r.script || ''); - let filters = frappe.query_reports[report_name].filters; - return Promise.resolve(filters); + frappe.after_ajax(() => { + return frappe.query_reports[report_name].filters; + }) }); }, From 1abc0264c0af9be2cf06fceca06df03fd7e88cbe Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 20 Mar 2020 15:32:43 +0530 Subject: [PATCH 092/140] fix: missing return statement --- frappe/public/js/frappe/views/reports/report_utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/views/reports/report_utils.js b/frappe/public/js/frappe/views/reports/report_utils.js index 218017244e..a8149b9134 100644 --- a/frappe/public/js/frappe/views/reports/report_utils.js +++ b/frappe/public/js/frappe/views/reports/report_utils.js @@ -117,7 +117,7 @@ frappe.report_utils = { } ).then(r => { frappe.dom.eval(r.script || ''); - frappe.after_ajax(() => { + return frappe.after_ajax(() => { return frappe.query_reports[report_name].filters; }) }); From de1d8d0acda7a086a703920372b98b3b6b3b5bcb Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 20 Mar 2020 15:36:39 +0530 Subject: [PATCH 093/140] fix: hide summary if no data --- frappe/public/js/frappe/widgets/chart_widget.js | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index 0b19987e7c..3388890776 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -436,6 +436,7 @@ export default class ChartWidget extends Widget { if (!this.data || !this.data.labels.length || !Object.keys(this.data).length) { this.chart_wrapper.hide(); this.loading.hide(); + this.$summary.hide(); this.empty.show(); } else { this.loading.hide(); From c615042d259797d4110df4e69da38c5983786df4 Mon Sep 17 00:00:00 2001 From: sahil28297 <37302950+sahil28297@users.noreply.github.com> Date: Fri, 20 Mar 2020 16:10:58 +0530 Subject: [PATCH 094/140] fix: develop version as 12.0.0.dev instead of 12.1.0 (#9746) * fix: develop version as 12.x.x instead of 12.1.0 * fix: develop version as 12.0.0.dev * fix: develop version as 12.0.0-dev --- frappe/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index e2d8041992..e19327fcff 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -23,7 +23,7 @@ if PY2: reload(sys) sys.setdefaultencoding("utf-8") -__version__ = '12.1.0' +__version__ = '12.0.0-dev' __title__ = "Frappe Framework" local = Local() From 17f25fafcb082a70d8cc062753180f12766a6b80 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 20 Mar 2020 18:57:40 +0530 Subject: [PATCH 095/140] fix: responsive dashboards --- frappe/public/less/desktop.less | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frappe/public/less/desktop.less b/frappe/public/less/desktop.less index d79c4ce726..a221e4c3d6 100644 --- a/frappe/public/less/desktop.less +++ b/frappe/public/less/desktop.less @@ -154,6 +154,14 @@ margin-right: 20px; } } + + .grid-col-2 { + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + .full-width { + grid-column-start: 1; + grid-column-end: 2; + } + } } } From 3f1ba29620ae1b55ce41480e5cd67523c21cdd89 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 20 Mar 2020 19:04:00 +0530 Subject: [PATCH 096/140] fix: responsive chart widget in desk --- frappe/public/less/desktop.less | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frappe/public/less/desktop.less b/frappe/public/less/desktop.less index a221e4c3d6..9df4addf61 100644 --- a/frappe/public/less/desktop.less +++ b/frappe/public/less/desktop.less @@ -162,6 +162,10 @@ grid-column-end: 2; } } + + .grid-col-1 { + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + } } } From 641892b0cc81e5d2c0a8f9a53da91c4a930753dc Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 20 Mar 2020 19:44:14 +0530 Subject: [PATCH 097/140] feat: disable sortable on dashboard --- frappe/core/page/dashboard/dashboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/core/page/dashboard/dashboard.js b/frappe/core/page/dashboard/dashboard.js index e2da785f4e..511aac7010 100644 --- a/frappe/core/page/dashboard/dashboard.js +++ b/frappe/core/page/dashboard/dashboard.js @@ -92,7 +92,7 @@ class Dashboard { container: this.container, type: "chart", columns: 2, - allow_sorting: true, + allow_sorting: false, widgets: this.charts, }); }); From 64150d471721d4ef8ac40ad3b09bf722db5a880d Mon Sep 17 00:00:00 2001 From: prssanna Date: Fri, 20 Mar 2020 21:13:35 +0530 Subject: [PATCH 098/140] fix: fix dropdown caret spacing in list sidebar --- frappe/public/js/frappe/list/list_sidebar.html | 2 +- frappe/public/js/frappe/list/list_sidebar_group_by.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/list/list_sidebar.html b/frappe/public/js/frappe/list/list_sidebar.html index f8e868da20..90189ccdea 100644 --- a/frappe/public/js/frappe/list/list_sidebar.html +++ b/frappe/public/js/frappe/list/list_sidebar.html @@ -64,7 +64,7 @@