From 74d9c622bc12b05b0fb7b8ee248eab9eb99be102 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 8 Aug 2024 17:48:22 +0530 Subject: [PATCH 1/3] fix(minor): Quick Entry now subclasses from Dialog --- frappe/public/js/frappe/form/quick_entry.js | 47 ++++++++++--------- .../public/js/frappe/form/script_manager.js | 1 + frappe/public/js/frappe/ui/dialog.js | 20 ++++---- frappe/public/js/frappe/ui/field_group.js | 41 ++++++++++++++++ 4 files changed, 74 insertions(+), 35 deletions(-) diff --git a/frappe/public/js/frappe/form/quick_entry.js b/frappe/public/js/frappe/form/quick_entry.js index 1a535ce666..0c43fb70ef 100644 --- a/frappe/public/js/frappe/form/quick_entry.js +++ b/frappe/public/js/frappe/form/quick_entry.js @@ -25,13 +25,15 @@ frappe.ui.form.make_quick_entry = (doctype, after_insert, init_callback, doc, fo return frappe.quick_entry.setup(); }; -frappe.ui.form.QuickEntryForm = class QuickEntryForm { +frappe.ui.form.QuickEntryForm = class QuickEntryForm extends frappe.ui.Dialog { constructor(doctype, after_insert, init_callback, doc, force) { + super({ auto_make: false }); this.doctype = doctype; this.after_insert = after_insert; this.init_callback = init_callback; this.doc = doc; this.force = force ? force : false; + this.dialog = this; // for backward compatibility } setup() { @@ -70,6 +72,8 @@ frappe.ui.form.QuickEntryForm = class QuickEntryForm { df.fieldtype !== "Tab Break" ); }); + + this.mandatory = this.docfields; // backward compatibility } check_quick_entry_doc() { @@ -134,27 +138,24 @@ frappe.ui.form.QuickEntryForm = class QuickEntryForm { render_dialog() { var me = this; + this.fields = this.docfields; + this.title = this.get_title(); - this.dialog = new frappe.ui.Dialog({ - title: this.get_title(), - fields: this.docfields, - doc: this.doc, - }); - + super.make(); this.register_primary_action(); this.render_edit_in_full_page_link(); this.setup_cmd_enter_for_save(); - this.dialog.onhide = () => (frappe.quick_entry = null); - this.dialog.show(); + this.onhide = () => (frappe.quick_entry = null); + this.show(); - this.dialog.refresh_dependency(); + this.refresh_dependency(); this.set_defaults(); this.script_manager.trigger("refresh"); if (this.init_callback) { - this.init_callback(this.dialog); + this.init_callback(this); } } @@ -170,7 +171,7 @@ frappe.ui.form.QuickEntryForm = class QuickEntryForm { register_primary_action() { var me = this; - this.dialog.set_primary_action(__("Save"), function () { + this.set_primary_action(__("Save"), function () { if (me.dialog.working) { return; } @@ -247,14 +248,14 @@ frappe.ui.form.QuickEntryForm = class QuickEntryForm { process_after_insert(r) { // delete the old doc - frappe.model.clear_doc(this.dialog.doc.doctype, this.dialog.doc.name); - this.dialog.doc = r.message; + frappe.model.clear_doc(this.doc.doctype, this.doc.name); + this.doc = r.message; if (this.script_manager.has_handler("after_save")) { return this.script_manager.trigger("after_save"); } else if (frappe._from_link) { - frappe.ui.form.update_calling_link(this.dialog.doc); + frappe.ui.form.update_calling_link(this.doc); } else if (this.after_insert) { - this.after_insert(this.dialog.doc); + this.after_insert(this.doc); } else { this.open_form_if_not_list(); } @@ -263,7 +264,7 @@ frappe.ui.form.QuickEntryForm = class QuickEntryForm { setup_cmd_enter_for_save() { var me = this; // ctrl+enter to save - this.dialog.wrapper.keydown(function (e) { + this.wrapper.keydown(function (e) { if ((e.ctrlKey || e.metaKey) && e.which == 13) { if (!frappe.request.ajax_count) { // not already working -- double entry @@ -278,7 +279,7 @@ frappe.ui.form.QuickEntryForm = class QuickEntryForm { open_form_if_not_list() { if (this.meta.issingle) return; let route = frappe.get_route(); - let doc = this.dialog.doc; + let doc = this.doc; if (route && !(route[0] === "List" && route[1] === doc.doctype)) { frappe.run_serially([() => frappe.set_route("Form", doc.doctype, doc.name)]); } @@ -286,17 +287,17 @@ frappe.ui.form.QuickEntryForm = class QuickEntryForm { update_doc() { var me = this; - var data = this.dialog.get_values(true); + var data = this.get_values(true); $.each(data, function (key, value) { if (!is_null(value)) { me.dialog.doc[key] = value; } }); - return this.dialog.doc; + return this.doc; } open_doc(set_hooks) { - this.dialog.hide(); + this.hide(); this.update_doc(); if (set_hooks && this.after_insert) { frappe.route_options = frappe.route_options || {}; @@ -309,13 +310,13 @@ frappe.ui.form.QuickEntryForm = class QuickEntryForm { render_edit_in_full_page_link() { if (this.force || this.hide_full_form_button) return; - this.dialog.add_custom_action(__("Edit Full Form"), () => this.open_doc(true)); + this.add_custom_action(__("Edit Full Form"), () => this.open_doc(true)); } set_defaults() { var me = this; // set defaults - $.each(this.dialog.fields_dict, function (fieldname, field) { + $.each(this.fields_dict, function (fieldname, field) { field.doctype = me.doc.doctype; field.docname = me.doc.name; diff --git a/frappe/public/js/frappe/form/script_manager.js b/frappe/public/js/frappe/form/script_manager.js index badce4460f..3ff3fb92cb 100644 --- a/frappe/public/js/frappe/form/script_manager.js +++ b/frappe/public/js/frappe/form/script_manager.js @@ -245,6 +245,7 @@ frappe.ui.form.ScriptManager = class ScriptManager { this.trigger("setup"); } + log_error(caller, e) { frappe.show_alert({ message: __("Error in Client Script."), indicator: "error" }); console.group && console.group(); diff --git a/frappe/public/js/frappe/ui/dialog.js b/frappe/public/js/frappe/ui/dialog.js index eea34bb65e..da288621b8 100644 --- a/frappe/public/js/frappe/ui/dialog.js +++ b/frappe/public/js/frappe/ui/dialog.js @@ -13,8 +13,10 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { this.display = false; this.is_dialog = true; - $.extend(this, { animate: true, size: null }, opts); - this.make(); + $.extend(this, { animate: true, size: null, auto_make: true }, opts); + if (this.auto_make) { + this.make(); + } } make() { @@ -127,10 +129,6 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { }); } - get $backdrop() { - return $(this.$wrapper.data("bs.modal")?._backdrop); - } - set_modal_size() { if (!this.fields) { this.size = ""; @@ -259,7 +257,7 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { this.$wrapper.removeClass("modal-minimize"); if (this.minimizable && this.is_minimized) { - this.$backdrop.show(); + $(".modal-backdrop").toggle(); this.is_minimized = false; } @@ -272,10 +270,6 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { } hide() { - if (this.animate && this.animation_speed === "slow") { - this.$wrapper.addClass("slow"); - this.$backdrop.addClass("slow"); - } this.$wrapper.modal("hide"); this.is_visible = false; } @@ -297,7 +291,7 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { } toggle_minimize() { - this.$backdrop.toggle(); + $(".modal-backdrop").toggle(); let modal = this.$wrapper.closest(".modal").toggleClass("modal-minimize"); modal.attr("tabindex") ? modal.removeAttr("tabindex") : modal.attr("tabindex", -1); this.is_minimized = !this.is_minimized; @@ -323,6 +317,8 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { action && action_button.click(action); } + + add_custom_button() {} }; frappe.ui.hide_open_dialog = () => { diff --git a/frappe/public/js/frappe/ui/field_group.js b/frappe/public/js/frappe/ui/field_group.js index 27fe08439c..4a1022ec9f 100644 --- a/frappe/public/js/frappe/ui/field_group.js +++ b/frappe/public/js/frappe/ui/field_group.js @@ -6,6 +6,8 @@ frappe.ui.FieldGroup = class FieldGroup extends frappe.ui.form.Layout { constructor(opts) { super(opts); this.dirty = false; + this.fetch_dict = {}; + $.each(this.fields || [], function (i, f) { if (!f.fieldname && f.label) { f.fieldname = f.label.replace(/ /g, "_").toLowerCase(); @@ -197,4 +199,43 @@ frappe.ui.FieldGroup = class FieldGroup extends frappe.ui.form.Layout { field.df[prop] = value; field.refresh(); } + + set_query(fieldname, opt1, opt2) { + if (opt2) { + // on child table + // set_query(fieldname, parent fieldname, query) + if (this.fields_dict[opt1]) + this.fields_dict[opt1].grid.get_field(fieldname).get_query = opt2; + } else { + // on parent table + // set_query(fieldname, query) + if (this.fields_dict[fieldname]) { + this.fields_dict[fieldname].get_query = opt1; + } + } + } + + // UTILITIES + add_fetch(link_field, source_field, target_field, target_doctype) { + /* + Example fetch dict to get sender_email from email_id field in sender: + { + "Notification": { + "sender": { + "sender_email": "email_id" + } + } + } + */ + + if (!target_doctype) target_doctype = "*"; + + // Target field kept as key because source field could be non-unique + this.fetch_dict.setDefault(target_doctype, {}).setDefault(link_field, {})[target_field] = + source_field; + } + + is_new() { + return this.doc.__islocal; + } }; From a6ab011208c90d6f6c80b0827caa6a943ccb3a3c Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 8 Aug 2024 21:01:49 +0530 Subject: [PATCH 2/3] fix(minor): quick_entry.js - use this.mandatory if set for backward compatibility --- frappe/public/js/frappe/form/quick_entry.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/form/quick_entry.js b/frappe/public/js/frappe/form/quick_entry.js index 0c43fb70ef..fbb02274db 100644 --- a/frappe/public/js/frappe/form/quick_entry.js +++ b/frappe/public/js/frappe/form/quick_entry.js @@ -72,8 +72,6 @@ frappe.ui.form.QuickEntryForm = class QuickEntryForm extends frappe.ui.Dialog { df.fieldtype !== "Tab Break" ); }); - - this.mandatory = this.docfields; // backward compatibility } check_quick_entry_doc() { @@ -138,6 +136,12 @@ frappe.ui.form.QuickEntryForm = class QuickEntryForm extends frappe.ui.Dialog { render_dialog() { var me = this; + + if (this.mandatory) { + // overridden in several places in erpnext + this.docfields = this.mandatory; + } + this.fields = this.docfields; this.title = this.get_title(); From 864c82bbb5cd5b483baf354a991b23153bf3c6cf Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 8 Aug 2024 21:50:24 +0530 Subject: [PATCH 3/3] fix(minor): quick_entry.js - getter/setter for mandatory property --- frappe/public/js/frappe/form/quick_entry.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/frappe/public/js/frappe/form/quick_entry.js b/frappe/public/js/frappe/form/quick_entry.js index fbb02274db..3cfb3aa530 100644 --- a/frappe/public/js/frappe/form/quick_entry.js +++ b/frappe/public/js/frappe/form/quick_entry.js @@ -134,14 +134,21 @@ frappe.ui.form.QuickEntryForm = class QuickEntryForm extends frappe.ui.Dialog { this.script_manager.setup(); } + get mandatory() { + // Backwards compatibility + console.warn("QuickEntryForm: .mandatory is deprecated, use .docfields instead"); + return this.docfields; + } + + set mandatory(value) { + // Backwards compatibility + console.warn("QuickEntryForm: .mandatory is deprecated, use .docfields instead"); + this.docfields = value; + } + render_dialog() { var me = this; - if (this.mandatory) { - // overridden in several places in erpnext - this.docfields = this.mandatory; - } - this.fields = this.docfields; this.title = this.get_title();