From 93daaddc109c40a26a25a3619e1399875eea00b2 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 20 May 2019 14:49:50 +0530 Subject: [PATCH 01/22] feat: Add minimize modal feature --- frappe/public/js/frappe/dom.js | 5 ++++- frappe/public/js/frappe/router.js | 6 +++++- frappe/public/js/frappe/ui/dialog.js | 13 +++++++++++++ frappe/public/js/frappe/views/container.js | 6 +++++- frappe/public/less/desk.less | 18 ++++++++++++++++++ 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/dom.js b/frappe/public/js/frappe/dom.js index 830ed0a5ce..18a338bf25 100644 --- a/frappe/public/js/frappe/dom.js +++ b/frappe/public/js/frappe/dom.js @@ -296,7 +296,10 @@ frappe.get_modal = function(title, content) {
-
+
+
- - - -
-
-
-
- + + + - `) + `); }; frappe.is_online = function() { diff --git a/frappe/public/less/desk.less b/frappe/public/less/desk.less index 00a3aa3f67..56f4a57f03 100644 --- a/frappe/public/less/desk.less +++ b/frappe/public/less/desk.less @@ -1104,5 +1104,4 @@ body.full-width { .modal-body { display: none; } - } \ No newline at end of file From 1907e8ad7eed0166d73fa011b57e44527ea2fc37 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 27 May 2019 14:44:51 +0530 Subject: [PATCH 07/22] fix: Modal z-index --- frappe/public/less/desk.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/less/desk.less b/frappe/public/less/desk.less index 56f4a57f03..08466ace02 100644 --- a/frappe/public/less/desk.less +++ b/frappe/public/less/desk.less @@ -1089,12 +1089,12 @@ body.full-width { } .modal-minimize { - z-index: 2; position: initial; .modal-backdrop { display: none; } .modal-dialog { + z-index: 101; position: fixed; right: 0; bottom: 0; From 2c5b5ba45a0f2c1b5ce36430acc58c4570ed2011 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Mon, 27 May 2019 18:39:24 +0530 Subject: [PATCH 08/22] fix: Skip website attr for Custom DocTypes --- frappe/website/router.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frappe/website/router.py b/frappe/website/router.py index 4e172b5290..d22bacf282 100644 --- a/frappe/website/router.py +++ b/frappe/website/router.py @@ -99,7 +99,10 @@ def get_page_info_from_doctypes(path=None): values = [] controller = get_controller(doctype) meta = frappe.get_meta(doctype) - condition_field = meta.is_published_field or controller.website.condition_field + + condition_field = (meta.is_published_field or + # custom doctypes dont have controllers and no website attribute + (controller.website.condition_field if not meta.custom else None)) if condition_field: condition ="where {0}=1".format(condition_field) From 3a5288c661d2af37af6f003642299d3fbbacf1c6 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 28 May 2019 08:20:22 +0530 Subject: [PATCH 09/22] fix: Show name of the user who actually reverted points --- frappe/public/js/frappe/utils/energy_point_utils.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/frappe/public/js/frappe/utils/energy_point_utils.js b/frappe/public/js/frappe/utils/energy_point_utils.js index 05b3347fdc..1a22fd5077 100644 --- a/frappe/public/js/frappe/utils/energy_point_utils.js +++ b/frappe/public/js/frappe/utils/energy_point_utils.js @@ -32,7 +32,6 @@ Object.assign(frappe.energy_points, { }, get_history_log_message(log) { const owner_name = frappe.user.full_name(log.owner).bold(); - const user = frappe.user.full_name(log.user).bold(); const ref_doc = log.reference_name; if (log.type === 'Appreciation') { @@ -42,7 +41,7 @@ Object.assign(frappe.energy_points, { return __('{0} criticized on {1}', [owner_name, ref_doc]); } if (log.type === 'Revert') { - return __('{0} reverted {1}', [user, log.revert_of]); + return __('{0} reverted {1}', [owner_name, log.revert_of]); } return __('via automatic rule {0} on {1}', [log.rule.bold(), ref_doc]); }, @@ -57,8 +56,7 @@ Object.assign(frappe.energy_points, { return __('{0} criticized {1}', [owner_name, user]); } if (log.type === 'Revert') { - return __('{0} reverted {1}', [user, - frappe.utils.get_form_link('Energy Point Log', log.revert_of, true)]); + return __('{0} reverted {1}', [owner_name, log.revert_of]); } return __('gained by {0} via automatic rule {1}', [user, log.rule.bold()]); }, From 7e42520554c17f2429c96e1ec8d429467b03f6c0 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 28 May 2019 12:27:40 +0530 Subject: [PATCH 10/22] fix(minor): frappe.conf.db_type in sql exception --- frappe/database/database.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frappe/database/database.py b/frappe/database/database.py index 72e6715e69..19cc1d93d6 100644 --- a/frappe/database/database.py +++ b/frappe/database/database.py @@ -178,10 +178,11 @@ class Database(object): frappe.errprint(("Execution time: {0} sec").format(round(time_end - time_start, 2))) except Exception as e: - if(frappe.db.db_type == 'postgres'): + if frappe.conf.db_type == 'postgres': self.rollback() - if frappe.db.db_type == 'mariadb' and self.is_syntax_error(e): + elif self.is_syntax_error(e): + # only for mariadb frappe.errprint('Syntax error in query:') frappe.errprint(query) From f75aa3beffe1639b999cb60e93707a494e6c61b3 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Tue, 28 May 2019 14:21:20 +0530 Subject: [PATCH 11/22] fix: add rating field in docfield (#7571) --- frappe/core/doctype/docfield/docfield.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/core/doctype/docfield/docfield.json b/frappe/core/doctype/docfield/docfield.json index c78495898e..622663bca4 100644 --- a/frappe/core/doctype/docfield/docfield.json +++ b/frappe/core/doctype/docfield/docfield.json @@ -108,7 +108,7 @@ "no_copy": 0, "oldfieldname": "fieldtype", "oldfieldtype": "Select", - "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nGeolocation\nHeading\nHTML\nHTML Editor\nImage\nInt\nLink\nLong Text\nMarkdown Editor\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nTable MultiSelect\nText\nText Editor\nTime\nSignature", + "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nGeolocation\nHeading\nHTML\nHTML Editor\nImage\nInt\nLink\nLong Text\nMarkdown Editor\nPassword\nPercent\nRead Only\nRating\nSection Break\nSelect\nSmall Text\nTable\nTable MultiSelect\nText\nText Editor\nTime\nSignature", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, @@ -1710,7 +1710,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2019-04-08 12:19:53.415372", + "modified": "2019-05-28 12:19:53.415372", "modified_by": "Administrator", "module": "Core", "name": "DocField", From 7788b807e0cd51d70b64a4947e97efe2eec0f408 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 14 May 2019 21:02:26 +0530 Subject: [PATCH 12/22] feat: added more button in the multi select modal --- .../js/frappe/form/multi_select_dialog.js | 77 ++++++++++--------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/frappe/public/js/frappe/form/multi_select_dialog.js b/frappe/public/js/frappe/form/multi_select_dialog.js index 61ebee4ba1..3438c59a1f 100644 --- a/frappe/public/js/frappe/form/multi_select_dialog.js +++ b/frappe/public/js/frappe/form/multi_select_dialog.js @@ -19,6 +19,7 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ let me = this; this.page_length = 20; + this.start = 0; let fields = [ { @@ -55,7 +56,12 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ }, { fieldtype: "Section Break" }, { fieldtype: "HTML", fieldname: "results_area" }, - { fieldtype: "Button", fieldname: "make_new", label: __('Create a new ' + me.doctype) } + { fieldtype: "Button", fieldname: "more_btn", label: __("More"), + click: function(){ + me.start += 20; + me.get_results(); + } + } ]); let doctype_plural = !this.doctype.endsWith('y') ? this.doctype + 's' @@ -65,25 +71,30 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ title: __("Select {0}", [(this.doctype=='[Select]') ? __("value") : __(doctype_plural)]), fields: fields, primary_action_label: __("Get Items"), + secondary_action_label: __("Make {0}", [me.doctype]), primary_action: function() { me.action(me.get_checked_values(), me.args); + }, + secondary_action: function(e) { + // If user wants to close the modal + if (e) { + frappe.route_options = {}; + + Object.keys(me.setters).forEach(function(setter) { + frappe.route_options[setter] = me.dialog.fields_dict[setter].get_value() || undefined; + }); + + frappe.new_doc(me.doctype, true); + } } }); this.$parent = $(this.dialog.body); this.$wrapper = this.dialog.fields_dict.results_area.$wrapper.append(`
`); - this.$results = this.$wrapper.find('.results'); - this.$make_new_btn = this.dialog.fields_dict.make_new.$wrapper; - this.$placeholder = $(`
- - -

No ${this.doctype} found

- -
-
`); + this.$results = this.$wrapper.find('.results'); + this.$results.append(this.make_list_row()); this.args = {}; @@ -94,6 +105,7 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ bind_events: function() { let me = this; + this.$results.on('click', '.list-item-container', function (e) { if (!$(e.target).is(':checkbox') && !$(e.target).is('a')) { $(this).find(':checkbox').trigger('click'); @@ -119,14 +131,6 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ me.get_results(); }, 300)); }); - - this.$parent.on('click', '.btn[data-fieldname="make_new"]', (e) => { - frappe.route_options = {}; - Object.keys(this.setters).forEach(function(setter) { - frappe.route_options[setter] = me.dialog.fields_dict[setter].get_value() || undefined; - }); - frappe.new_doc(this.doctype, true); - }); }, get_checked_values: function() { @@ -170,23 +174,21 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ render_result_list: function(results, more = 0) { var me = this; - this.$results.empty(); - if(results.length === 0) { - this.$make_new_btn.addClass('hide'); - this.$results.append(me.$placeholder); - return; - } - this.$make_new_btn.removeClass('hide'); - this.$results.append(this.make_list_row()); + var more_btn = me.dialog.fields_dict.more_btn.$wrapper; + if(results.length === 0) { + this.$results.empty(); + more_btn.hide(); + return; + } else { + more_btn.show(); + } + results.forEach((result) => { me.$results.append(me.make_list_row(result)); - }) - if (more) { - let message = __("Only {0} entries shown. Please filter for more specific results.", [this.page_length]); - me.$results.append($(`
${message}
`)); - } + }); + + this.$results.animate({scrollTop: me.$results.prop('scrollHeight')}, 500); }, get_results: function() { @@ -208,6 +210,7 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ txt: me.dialog.fields_dict["search_term"].get_value(), filters: filters, filter_fields: Object.keys(me.setters).concat([me.date_field]), + start: this.start, page_length: this.page_length + 1, query: this.get_query ? this.get_query().query : '', as_dict: 1 @@ -219,8 +222,8 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ args: args, callback: function(r) { let results = [], more = 0; - if(r.values.length) { - if(r.values.length > me.page_length){ + if (r.values.length) { + if (r.values.length > me.page_length) { r.values.pop(); more = 1; } @@ -241,7 +244,9 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ }); // Preselect oldest entry - results[0].checked = 1 + if (me.start < 1) { + results[0].checked = 1; + } } me.render_result_list(results, more); } From fa799d57340c587773f54062ca2f4d3ffd56dbe9 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 28 May 2019 20:39:12 +0530 Subject: [PATCH 13/22] fix: same result set shwoing multiple times in the multi-select popup --- .../public/js/frappe/form/multi_select_dialog.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/form/multi_select_dialog.js b/frappe/public/js/frappe/form/multi_select_dialog.js index 3438c59a1f..4e569033ba 100644 --- a/frappe/public/js/frappe/form/multi_select_dialog.js +++ b/frappe/public/js/frappe/form/multi_select_dialog.js @@ -59,6 +59,7 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ { fieldtype: "Button", fieldname: "more_btn", label: __("More"), click: function(){ me.start += 20; + frappe.flags.auto_scroll = true; me.get_results(); } } @@ -117,10 +118,12 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ }); this.$parent.find('.input-with-feedback').on('change', (e) => { + frappe.flags.auto_scroll = false; this.get_results(); }); this.$parent.find('[data-fieldname="date_range"]').on('blur', (e) => { + frappe.flags.auto_scroll = false; this.get_results(); }); @@ -128,6 +131,7 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ var $this = $(this); clearTimeout($this.data('timeout')); $this.data('timeout', setTimeout(function() { + frappe.flags.auto_scroll = false; me.get_results(); }, 300)); }); @@ -176,11 +180,17 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ var me = this; var more_btn = me.dialog.fields_dict.more_btn.$wrapper; + + // Make empty result set if filter is set + if (!frappe.flags.auto_scroll) { + this.$results.empty(); + } + if(results.length === 0) { this.$results.empty(); more_btn.hide(); return; - } else { + } else if(more) { more_btn.show(); } @@ -188,7 +198,9 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ me.$results.append(me.make_list_row(result)); }); - this.$results.animate({scrollTop: me.$results.prop('scrollHeight')}, 500); + if (frappe.flags.auto_scroll) { + this.$results.animate({scrollTop: me.$results.prop('scrollHeight')}, 500); + } }, get_results: function() { From 2ae48532be422a978e6e2995c6200f4ff58ebdb6 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Wed, 29 May 2019 10:07:23 +0530 Subject: [PATCH 14/22] fix: Update frappe-datatable (#7580) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index dd5a96d741..352ba6d492 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "cookie": "^0.3.1", "express": "^4.16.2", "fast-deep-equal": "^2.0.1", - "frappe-datatable": "^1.13.1", + "frappe-datatable": "^1.13.2", "frappe-gantt": "^0.1.0", "fuse.js": "^3.2.0", "highlight.js": "^9.12.0", diff --git a/yarn.lock b/yarn.lock index 64bc06edff..bfe0d375f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1753,10 +1753,10 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -frappe-datatable@^1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/frappe-datatable/-/frappe-datatable-1.13.1.tgz#dbfa27fe735832cea54a0b35e3d3bfb839778c8d" - integrity sha512-FOC8dpsOSI+KnF5sBrYja9b2Y+3qUvYy/H6108QchKSvXYvuWVr/uuLk2N5xlz38PWU3d7n5lK0dkx+zXTKJ0w== +frappe-datatable@^1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/frappe-datatable/-/frappe-datatable-1.13.2.tgz#8b36c7cfc0ea660fc72eea8b1ae3c5dcc2a7d67d" + integrity sha512-4PyPDX22K4e4S3WGlLQx3oyxIW+ENsbGiN9L6aUpmjU+fOCC7J/FfSwGKdua2f+4yD+2ObpkyJYazBl3inAeCA== dependencies: hyperlist "^1.0.0-beta" lodash "^4.17.5" From 5af58d429c6ab49d6b531eee972c69ccc4f24305 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 29 May 2019 10:09:40 +0530 Subject: [PATCH 15/22] fix(energy point): Negative values for review point in leaderboard (#7577) * fix: Show available review points * style: Simplify formatting --- .../energy_point_log/energy_point_log.py | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/frappe/social/doctype/energy_point_log/energy_point_log.py b/frappe/social/doctype/energy_point_log/energy_point_log.py index c94c1bd371..fdea818991 100644 --- a/frappe/social/doctype/energy_point_log/energy_point_log.py +++ b/frappe/social/doctype/energy_point_log/energy_point_log.py @@ -131,26 +131,35 @@ def get_energy_points(user): @frappe.whitelist() def get_user_energy_and_review_points(user=None, from_date=None, as_dict=True): conditions = '' - values = [] + given_points_condition = '' + values = frappe._dict() if user: - conditions = 'WHERE `user` = %s' - values.append(user) + conditions = 'WHERE `user` = %(user)s' + values.user = user if from_date: conditions += 'WHERE' if not conditions else 'AND' - conditions += ' `creation` >= %s' - values.append(from_date) + given_points_condition += "AND `creation` >= %(from_date)s" + conditions += " `creation` >= %(from_date)s OR `type`='Review'" + values.from_date = from_date points_list = frappe.db.sql(""" SELECT - SUM(CASE WHEN `type`!= 'Review' THEN `points` ELSE 0 END) as energy_points, - SUM(CASE WHEN `type`='Review' THEN `points` ELSE 0 END) as review_points, - SUM(CASE WHEN `type`='Review' and `points` < 0 THEN ABS(`points`) ELSE 0 END) as given_points, + SUM(CASE WHEN `type` != 'Review' THEN `points` ELSE 0 END) AS energy_points, + SUM(CASE WHEN `type` = 'Review' THEN `points` ELSE 0 END) AS review_points, + SUM(CASE + WHEN `type`='Review' AND `points` < 0 {given_points_condition} + THEN ABS(`points`) + ELSE 0 + END) as given_points, `user` FROM `tabEnergy Point Log` {conditions} GROUP BY `user` ORDER BY `energy_points` DESC - """.format(conditions=conditions), values=tuple(values), as_dict=1) + """.format( + conditions=conditions, + given_points_condition=given_points_condition + ), values=values, as_dict=1) if not as_dict: return points_list From f3471fe5f9046707b99787185844b2bc355b2794 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Wed, 29 May 2019 10:12:39 +0530 Subject: [PATCH 16/22] fix: Handle file not found exception while extracting messages (#7574) --- frappe/translate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/translate.py b/frappe/translate.py index 44edcf999f..829ae6a609 100644 --- a/frappe/translate.py +++ b/frappe/translate.py @@ -507,7 +507,7 @@ def extract_messages_from_code(code, is_py=False): :param is_py: include messages in triple quotes e.g. `_('''message''')`""" try: code = frappe.as_unicode(render_include(code)) - except (TemplateError, ImportError, InvalidIncludePath): + except (TemplateError, ImportError, InvalidIncludePath, IOError): # Exception will occur when it encounters John Resig's microtemplating code pass From 704b091c4ce671dd1033ed268ae176b5207c0d2a Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 29 May 2019 10:15:10 +0530 Subject: [PATCH 17/22] fix: Add a patch to apply customization to custom doctype (#7546) This patch aims to apply & delete all the customization on custom doctypes done through customize form This is required because customize form in now blocked for custom doctypes and user may not be able to see previous customization --- frappe/patches.txt | 1 + .../apply_customization_to_custom_doctype.py | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 frappe/patches/v11_0/apply_customization_to_custom_doctype.py diff --git a/frappe/patches.txt b/frappe/patches.txt index b2276d5d81..ac3b3501f5 100644 --- a/frappe/patches.txt +++ b/frappe/patches.txt @@ -242,6 +242,7 @@ frappe.patches.v12_0.replace_null_values_in_tables frappe.patches.v12_0.reset_home_settings frappe.patches.v12_0.update_print_format_type frappe.patches.v11_0.remove_doctype_user_permissions_for_page_and_report #2019-05-01 +frappe.patches.v11_0.apply_customization_to_custom_doctype frappe.patches.v12_0.remove_feedback_rating frappe.patches.v12_0.move_form_attachments_to_attachments_folder frappe.patches.v12_0.move_timeline_links_to_dynamic_links diff --git a/frappe/patches/v11_0/apply_customization_to_custom_doctype.py b/frappe/patches/v11_0/apply_customization_to_custom_doctype.py new file mode 100644 index 0000000000..3b313d4529 --- /dev/null +++ b/frappe/patches/v11_0/apply_customization_to_custom_doctype.py @@ -0,0 +1,51 @@ +import frappe +from frappe.utils import cint + +# This patch aims to apply & delete all the customization +# on custom doctypes done through customize form + +# This is required because customize form in now blocked +# for custom doctypes and user may not be able to +# see previous customization + +def execute(): + custom_doctypes = frappe.get_all('DocType', filters={ + 'custom': 1 + }) + + for doctype in custom_doctypes: + property_setters = frappe.get_all('Property Setter', filters={ + 'doc_type': doctype.name, + 'doctype_or_field': 'DocField' + }, fields=['name', 'property', 'value', 'property_type', 'field_name']) + + custom_fields = frappe.get_all('Custom Field', + filters={'dt': doctype.name}, + fields=['*'] + ) + + property_setter_map = {} + + for prop in property_setters: + property_setter_map[prop.field_name] = prop + frappe.db.sql('DELETE FROM `tabProperty Setter` WHERE `name`=%s', prop.name) + + meta = frappe.get_doc('DocType', doctype.name) + + for df in meta.fields: + ps = property_setter_map.get(df.fieldname, None) + if ps: + value = cint(ps.value) if ps.property_type == 'Int' else ps.value + df.set(ps.property, value) + + for cf in custom_fields: + df = frappe.new_doc('DocField', meta, 'fields') + cf.pop('parenttype') + cf.pop('parentfield') + cf.pop('parent') + cf.pop('name') + df.update(cf) + meta.fields.append(df) + frappe.db.sql('DELETE FROM `tabCustom Field` WHERE name=%s', cf.name) + + meta.save() \ No newline at end of file From 736d4db135bcd6682af6d9bea11087deb30af0c9 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 29 May 2019 10:47:22 +0530 Subject: [PATCH 18/22] fix: Use different class for link preview popover (#7582) * fix: Add different class for link preview popover - Because the style changes for it used to affect other popovers * fix: Re-arrange popover style for proper style override --- frappe/public/js/frappe/ui/link_preview.js | 7 ++-- frappe/public/less/desk.less | 42 +++++++++++----------- frappe/public/less/link_preview.less | 2 +- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/frappe/public/js/frappe/ui/link_preview.js b/frappe/public/js/frappe/ui/link_preview.js index 962adcf344..4db3050b83 100644 --- a/frappe/public/js/frappe/ui/link_preview.js +++ b/frappe/public/js/frappe/ui/link_preview.js @@ -175,9 +175,10 @@ frappe.ui.LinkPreview = class { animation: false, }); - if(!this.is_link) { - this.element.data('bs.popover').tip().addClass('control-field-popover'); - } + const $popover = this.element.data('bs.popover').tip(); + + $popover.addClass('link-preview-popover'); + $popover.toggleClass('control-field-popover', this.is_link); this.$links.push(this.element); diff --git a/frappe/public/less/desk.less b/frappe/public/less/desk.less index 08466ace02..945c23e423 100644 --- a/frappe/public/less/desk.less +++ b/frappe/public/less/desk.less @@ -464,27 +464,6 @@ li.user-progress { border-radius: 0px; } -// like pop-over -.liked-by-popover { - .popover-content { - padding: 0px; - overflow: scroll; - max-height: 150px; - } - min-width: 100px; - ul { - margin: 0px; - li { - padding: 10px; - cursor: pointer; - &:hover { - background: @btn-bg; - } - } - } - -} - .screenshot { border: 1px solid @border-color; box-shadow: 1px 1px 7px rgba(0,0,0,0.15); @@ -1074,6 +1053,27 @@ img.img-loading:after { } } +// like pop-over +.liked-by-popover { + .popover-content { + padding: 0px; + overflow: scroll; + max-height: 150px; + } + min-width: 100px; + ul { + margin: 0px; + li { + padding: 10px; + cursor: pointer; + &:hover { + background: @btn-bg; + } + } + } + +} + body.full-width { @media (min-width: @screen-md) { .container { diff --git a/frappe/public/less/link_preview.less b/frappe/public/less/link_preview.less index 9e8ed30e57..5bc9767815 100644 --- a/frappe/public/less/link_preview.less +++ b/frappe/public/less/link_preview.less @@ -1,4 +1,4 @@ -.popover { +.link-preview-popover { border-radius: 0; max-width: 100%; .popover-content { From 9f798e291363fc09943bfb591ace9541c48ce4ac Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 29 May 2019 13:03:48 +0530 Subject: [PATCH 19/22] fix: UniqueFieldnameError while migration --- .../v11_0/apply_customization_to_custom_doctype.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frappe/patches/v11_0/apply_customization_to_custom_doctype.py b/frappe/patches/v11_0/apply_customization_to_custom_doctype.py index 3b313d4529..69db27368b 100644 --- a/frappe/patches/v11_0/apply_customization_to_custom_doctype.py +++ b/frappe/patches/v11_0/apply_customization_to_custom_doctype.py @@ -39,13 +39,17 @@ def execute(): df.set(ps.property, value) for cf in custom_fields: - df = frappe.new_doc('DocField', meta, 'fields') cf.pop('parenttype') cf.pop('parentfield') cf.pop('parent') cf.pop('name') - df.update(cf) - meta.fields.append(df) + field = meta.get_field(cf.fieldname) + if field: + field.update(cf) + else: + df = frappe.new_doc('DocField', meta, 'fields') + df.update(cf) + meta.fields.append(df) frappe.db.sql('DELETE FROM `tabCustom Field` WHERE name=%s', cf.name) meta.save() \ No newline at end of file From 42f84f59148758076d0e645678a9750e30c144df Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 29 May 2019 13:13:10 +0530 Subject: [PATCH 20/22] fix: issue in the latest version of babel, set it to 2.6.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d61cadd4c4..bed4601951 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ rauth>=0.6.2 requests redis==2.10.6 selenium -babel +babel==2.6.0 ipython html2text==2016.9.19 email_reply_parser From 2c93dc74fef92f0f0d9c7fd68492708b52450870 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Wed, 29 May 2019 14:51:19 +0530 Subject: [PATCH 21/22] fix: Update regex for capturing touched tables from query (#7588) Previous regex used to yield false positives and false negatives for queries like UPDATE tabToDo SET description = "something" Instead of yielding "tabToDo" it used to yield "tabToDo SET". Now two separate regexes handle single word and multi-word names In case of multi-word surrounding quotes are a must --- frappe/database/database.py | 20 +++++++++++++++++--- frappe/tests/test_db.py | 6 ++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/frappe/database/database.py b/frappe/database/database.py index 19cc1d93d6..3aab284de0 100644 --- a/frappe/database/database.py +++ b/frappe/database/database.py @@ -930,12 +930,26 @@ class Database(object): if values: query = frappe.safe_decode(self._cursor.mogrify(query, values)) if query.strip().lower().split()[0] in ('insert', 'delete', 'update', 'alter'): - # ([`\"']?) Captures ', " or ` at the begining of the table name (if provided) + # single_word_regex is designed to match following patterns + # `tabXxx`, tabXxx and "tabXxx" + + # multi_word_regex is designed to match following patterns + # `tabXxx Xxx` and "tabXxx Xxx" + + # ([`"]?) Captures " or ` at the begining of the table name (if provided) + # \1 matches the first captured group (quote character) at the end of the table name + # multi word table name must have surrounding quotes. + # (tab([A-Z]\w+)( [A-Z]\w+)*) Captures table names that start with "tab" # and are continued with multiple words that start with a captital letter # e.g. 'tabXxx' or 'tabXxx Xxx' or 'tabXxx Xxx Xxx' and so on - # \1 matches the first captured group (quote character) at the end of the table name - tables = [groups[1] for groups in re.findall(r'([`"\']?)(tab([A-Z]\w+)( [A-Z]\w+)*)\1', query)] + + single_word_regex = r'([`"]?)(tab([A-Z]\w+))\1' + multi_word_regex = r'([`"])(tab([A-Z]\w+)( [A-Z]\w+)+)\1' + tables = [] + for regex in (single_word_regex, multi_word_regex): + tables += [groups[1] for groups in re.findall(regex, query)] + if frappe.flags.touched_tables is None: frappe.flags.touched_tables = set() frappe.flags.touched_tables.update(tables) diff --git a/frappe/tests/test_db.py b/frappe/tests/test_db.py index 974d3e770e..bb479d67c7 100644 --- a/frappe/tests/test_db.py +++ b/frappe/tests/test_db.py @@ -48,6 +48,12 @@ class TestDB(unittest.TestCase): todo.save() self.assertIn('tabToDo', frappe.flags.touched_tables) + if frappe.db.db_type != "postgres": + frappe.flags.touched_tables = set() + frappe.db.sql("UPDATE tabToDo SET description = 'Updated Description'") + self.assertNotIn('tabToDo SET', frappe.flags.touched_tables) + self.assertIn('tabToDo', frappe.flags.touched_tables) + frappe.flags.touched_tables = set() todo.delete() self.assertIn('tabToDo', frappe.flags.touched_tables) From df58d1e1c41515590d04be25d61625296adfa883 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Wed, 29 May 2019 17:57:19 +0530 Subject: [PATCH 22/22] fix(email): Search contacts by email_id as well Email auto suggest now performs lookup on contact name and email_id fields --- frappe/email/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/email/__init__.py b/frappe/email/__init__.py index 2875ba6c74..494a6e2bb3 100644 --- a/frappe/email/__init__.py +++ b/frappe/email/__init__.py @@ -23,7 +23,7 @@ def get_contact_list(txt, page_length=20): out = frappe.db.sql("""select email_id as value, concat(first_name, ifnull(concat(' ',last_name), '' )) as description from tabContact - where name like %(txt)s + where name like %(txt)s or email_id like %(txt)s %(condition)s limit %(page_length)s""", { 'txt': '%' + txt + '%',