diff --git a/frappe/__init__.py b/frappe/__init__.py index 6029351ae3..353e77e848 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -17,7 +17,7 @@ from faker import Faker from .exceptions import * from .utils.jinja import (get_jenv, get_template, render_template, get_email_from_template, get_jloader) -__version__ = '10.1.53' +__version__ = '10.1.54' __title__ = "Frappe Framework" local = Local() diff --git a/frappe/contacts/report/addresses_and_contacts/addresses_and_contacts.py b/frappe/contacts/report/addresses_and_contacts/addresses_and_contacts.py index 94613a5e95..10a1f0f4cd 100644 --- a/frappe/contacts/report/addresses_and_contacts/addresses_and_contacts.py +++ b/frappe/contacts/report/addresses_and_contacts/addresses_and_contacts.py @@ -91,10 +91,10 @@ def get_reference_details(reference_doctype, reference_list, doctype, reference_ records = frappe.get_list(doctype, filters=filters, fields=fields, as_list=True) for d in records: - details = reference_details.get(d[0]) + details = reference_details.get(d[0]) or {} details.setdefault(frappe.scrub(doctype), []).append(d[1:]) return reference_details def add_blank_columns_for(doctype): - return ["" for field in field_map.get(doctype, [])] \ No newline at end of file + return ["" for field in field_map.get(doctype, [])] diff --git a/frappe/core/doctype/sms_settings/sms_settings.py b/frappe/core/doctype/sms_settings/sms_settings.py index 7e735d87de..8472ba8f2b 100644 --- a/frappe/core/doctype/sms_settings/sms_settings.py +++ b/frappe/core/doctype/sms_settings/sms_settings.py @@ -52,11 +52,9 @@ def send_sms(receiver_list, msg, sender_name = '', success_msg = True): receiver_list = validate_receiver_nos(receiver_list) - if six.PY3: unicode = str - arg = { 'receiver_list' : receiver_list, - 'message' : unicode(msg).encode('utf-8'), + 'message' : frappe.safe_decode(msg).encode('utf-8'), 'success_msg' : success_msg } diff --git a/frappe/desk/page/setup_wizard/setup_wizard.py b/frappe/desk/page/setup_wizard/setup_wizard.py index 82f44ee249..4093f8b894 100755 --- a/frappe/desk/page/setup_wizard/setup_wizard.py +++ b/frappe/desk/page/setup_wizard/setup_wizard.py @@ -53,9 +53,12 @@ def setup_complete(args): and clears cache. If wizard breaks, calls `setup_wizard_exception` hook""" # Setup complete: do not throw an exception, let the user continue to desk - if cint(frappe.db.get_single_value('System Settings', 'setup_complete')): + if (frappe.cache().hget("setup_wizard", "in_setup") or + cint(frappe.db.get_single_value('System Settings', 'setup_complete'))): return + frappe.cache().hset("setup_wizard", "in_setup", True) + args = parse_args(args) stages = get_setup_stages(args) @@ -69,17 +72,19 @@ def setup_complete(args): for task in stage.get('tasks'): current_task = task task.get('fn')(task.get('args')) - except Exception: handle_setup_exception(args) return {'status': 'fail', 'fail': current_task.get('fail_msg')} else: run_setup_success(args) return {'status': 'ok'} + finally: + frappe.cache().hdel("setup_wizard", "in_setup") def update_global_settings(args): - if args.language and args.language != "english": + if args.language and args.language != "English": set_default_language(get_language_code(args.lang)) + frappe.db.commit() frappe.clear_cache() update_system_settings(args) @@ -243,6 +248,7 @@ def load_messages(language): javascript files""" frappe.clear_cache() set_default_language(get_language_code(language)) + frappe.db.commit() m = get_dict("page", "setup-wizard") for path in frappe.get_hooks("setup_wizard_requires"): diff --git a/frappe/hooks.py b/frappe/hooks.py index 3b2092f047..de1c15fc2e 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -12,7 +12,7 @@ source_link = "https://github.com/frappe/frappe" app_license = "MIT" develop_version = '12.x.x-develop' -staging_version = '11.0.3-beta.11' +staging_version = '11.0.3-beta.12' app_email = "info@frappe.io" @@ -172,7 +172,6 @@ scheduler_events = { "frappe.email.doctype.auto_email_report.auto_email_report.send_daily", "frappe.core.doctype.feedback_request.feedback_request.delete_feedback_request", "frappe.core.doctype.activity_log.activity_log.clear_authentication_logs", - "frappe.utils.change_log.check_for_update" ], "daily_long": [ "frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backups_daily", @@ -180,7 +179,8 @@ scheduler_events = { ], "weekly_long": [ "frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backups_weekly", - "frappe.integrations.doctype.s3_backup_settings.s3_backup_settings.take_backups_weekly" + "frappe.integrations.doctype.s3_backup_settings.s3_backup_settings.take_backups_weekly", + "frappe.utils.change_log.check_for_update" ], "monthly": [ "frappe.email.doctype.auto_email_report.auto_email_report.send_monthly" diff --git a/frappe/permissions.py b/frappe/permissions.py index 0d3feef062..3e87a343a7 100644 --- a/frappe/permissions.py +++ b/frappe/permissions.py @@ -89,6 +89,9 @@ def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None): if not perm: perm = false_if_not_shared() + if perm and frappe.message_log: + frappe.message_log.pop() + if verbose: print("Final Permission: {0}".format(perm)) return perm diff --git a/frappe/public/js/frappe/form/controls/comment.js b/frappe/public/js/frappe/form/controls/comment.js index 6ce9defa3b..c343e2f878 100644 --- a/frappe/public/js/frappe/form/controls/comment.js +++ b/frappe/public/js/frappe/form/controls/comment.js @@ -1,4 +1,4 @@ -import 'quill-mention'; +import 'quill-mention/dist/quill.mention.min'; frappe.ui.form.ControlComment = frappe.ui.form.ControlTextEditor.extend({ make_wrapper() { @@ -68,9 +68,9 @@ frappe.ui.form.ControlComment = frappe.ui.form.ControlTextEditor.extend({ const options = this._super(); return Object.assign(options, { theme: 'bubble', - // modules: Object.assign(options.modules, { - // mention: this.get_mention_options() - // }) + modules: Object.assign(options.modules, { + mention: this.get_mention_options() + }) }); }, @@ -90,7 +90,7 @@ frappe.ui.form.ControlComment = frappe.ui.form.ControlTextEditor.extend({ allowedChars: /^[A-Za-z0-9_]*$/, mentionDenotationChars: ["@"], isolateCharacter: true, - source: function(searchTerm, renderList, mentionChar) { + source: function (searchTerm, renderList, mentionChar) { let values; if (mentionChar === "@") { diff --git a/frappe/public/js/frappe/form/controls/text_editor.js b/frappe/public/js/frappe/form/controls/text_editor.js index 39d433f2bf..af306d461a 100644 --- a/frappe/public/js/frappe/form/controls/text_editor.js +++ b/frappe/public/js/frappe/form/controls/text_editor.js @@ -1,6 +1,9 @@ -import Quill from 'quill/dist/quill'; +import Quill from 'quill'; import { ImageDrop } from 'quill-image-drop-module'; +// required for quill-mention +window.Quill = Quill; + Quill.register('modules/imageDrop', ImageDrop); // replace

tag with

@@ -10,7 +13,13 @@ Quill.register(Block, true); // table const Table = Quill.import('formats/table-container'); -Table.className = 'table'; +const superCreate = Table.create.bind(Table); +Table.create = (value) => { + const node = superCreate(value); + node.classList.add('table'); + node.classList.add('table-bordered'); + return node; +} Quill.register(Table, true); // inline style diff --git a/frappe/public/js/frappe/ui/field_group.js b/frappe/public/js/frappe/ui/field_group.js index 71464adc37..57050298ca 100644 --- a/frappe/public/js/frappe/ui/field_group.js +++ b/frappe/public/js/frappe/ui/field_group.js @@ -24,7 +24,13 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({ // set default $.each(this.fields_list, function(i, field) { if (field.df["default"]) { - field.set_input(field.df["default"]); + let def_value = field.df["default"]; + + if (def_value == 'Today' && field.df["fieldtype"] == 'Date') { + def_value = frappe.datetime.get_today(); + } + + field.set_input(def_value); // if default and has depends_on, render its fields. me.refresh_dependency(); } diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js index 4923add7bc..9ea08bc9e4 100755 --- a/frappe/public/js/frappe/views/communication.js +++ b/frappe/public/js/frappe/views/communication.js @@ -78,8 +78,14 @@ frappe.views.CommunicationComposer = Class.extend({ {label:__("Subject"), fieldtype:"Data", reqd: 1, fieldname:"subject", length:524288}, {fieldtype: "Section Break"}, - {label:__("Message"), fieldtype:"Text Editor", reqd: 1, - fieldname:"content"}, + { + label:__("Message"), + fieldtype:"Text Editor", reqd: 1, + fieldname:"content", + onchange: frappe.utils.debounce(this.save_as_draft.bind(this), 300), + default: localStorage.getItem(this.frm.doctype + this.frm.docname) || '' + }, + {fieldtype: "Section Break"}, {fieldtype: "Column Break"}, {label:__("Send me a copy"), fieldtype:"Check", @@ -113,7 +119,7 @@ frappe.views.CommunicationComposer = Class.extend({ }, prepare: function() { this.setup_subject_and_recipients(); - this.setup_print_language() + this.setup_print_language(); this.setup_print(); this.setup_attach(); this.setup_email(); @@ -128,7 +134,10 @@ frappe.views.CommunicationComposer = Class.extend({ this.dialog.fields_dict.sender.set_value(this.sender || ''); } this.dialog.fields_dict.subject.set_value(this.subject || ''); - this.setup_earlier_reply(); + + if(!localStorage.getItem(this.frm.doctype + this.frm.docname)) { + this.setup_earlier_reply(); + } }, setup_subject_and_recipients: function() { @@ -488,6 +497,18 @@ frappe.views.CommunicationComposer = Class.extend({ return form_values; }, + save_as_draft: function() { + if (this.dialog) { + try { + localStorage.setItem(this.frm.doctype + this.frm.docname, this.dialog.get_value('content')); + } catch (e) { + // silently fail + console.log(e); + console.warn('[Communication] localStorage is full. Cannot save message as draft'); + } + } + }, + send_email: function(btn, form_values, selected_attachments, print_html, print_format) { var me = this; me.dialog.hide(); @@ -549,6 +570,16 @@ frappe.views.CommunicationComposer = Class.extend({ cur_frm.reload_doc(); } + if (localStorage.getItem(this.frm.doctype + this.frm.docname)) { + try { + localStorage.removeItem(this.frm.doctype + this.frm.docname); + } catch (e) { + // silently fail + console.log(e); + console.warn('[Communication] Failed to delete draft.'); + } + } + // try the success callback if it exists if (me.success) { try { diff --git a/frappe/templates/web.html b/frappe/templates/web.html index 5724141618..2a8460ac76 100644 --- a/frappe/templates/web.html +++ b/frappe/templates/web.html @@ -7,7 +7,7 @@ id="page-{{ name or route }}" data-path="{{ pathname }}" {% endmacro %} {% block content %} -
+
{% if show_sidebar %}