From 789c74debd255d7e37b4c8d89f0df9990ede6bd4 Mon Sep 17 00:00:00 2001 From: hexed0ut <102050935+hexed0ut@users.noreply.github.com> Date: Wed, 5 Nov 2025 23:11:03 +0530 Subject: [PATCH 01/30] fix(tags): Fix autocomplete to automatically select the best match Resolves #33747 --- frappe/public/js/frappe/ui/tag_editor.js | 15 +++++++++++++++ frappe/public/js/frappe/ui/tags.js | 10 +++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/ui/tag_editor.js b/frappe/public/js/frappe/ui/tag_editor.js index 059d8bb48e..8473914aa8 100644 --- a/frappe/public/js/frappe/ui/tag_editor.js +++ b/frappe/public/js/frappe/ui/tag_editor.js @@ -99,6 +99,21 @@ frappe.ui.TagEditor = class TagEditor { $input.trigger("input"); } }); + $input.on("enter-pressed-in-addtag", function (e) { + var value = e.target.value; + frappe.call({ + method: "frappe.desk.doctype.tag.tag.get_tags", + args: { + doctype: me.frm.doctype, + txt: value.toLowerCase(), + }, + callback: function (r) { + // Updates input to suggestion value (if any) on + if (r.message.length) $input.val(r.message[0]) + $input.trigger("input-selected"); + }, + }); + }); } get_args(tag) { return { diff --git a/frappe/public/js/frappe/ui/tags.js b/frappe/public/js/frappe/ui/tags.js index 7def9272b6..3c5dd50beb 100644 --- a/frappe/public/js/frappe/ui/tags.js +++ b/frappe/public/js/frappe/ui/tags.js @@ -38,10 +38,18 @@ frappe.ui.Tags = class { }; this.$input.keypress((e) => { - if (e.which == 13 || e.keyCode == 13) select_tag(); + if (e.which == 13 || e.keyCode == 13) { + // Triggers event when is pressed + this.$input.trigger("enter-pressed-in-addtag"); + } }); this.$input.focusout(select_tag); + this.$input.on("input-selected", () => { + // Adds tag if a input is selected + select_tag(); + }); + this.$input.on("blur", () => { this.deactivate(); }); From 009e117f4d08aa3151fb78f6444167bf9130f0d3 Mon Sep 17 00:00:00 2001 From: Abesh Roy <102050935+hexed0ut@users.noreply.github.com> Date: Thu, 13 Nov 2025 18:55:49 +0530 Subject: [PATCH 02/30] chore(tags): Add semi-colon --- frappe/public/js/frappe/ui/tag_editor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/ui/tag_editor.js b/frappe/public/js/frappe/ui/tag_editor.js index 8473914aa8..7fb42caa51 100644 --- a/frappe/public/js/frappe/ui/tag_editor.js +++ b/frappe/public/js/frappe/ui/tag_editor.js @@ -109,7 +109,7 @@ frappe.ui.TagEditor = class TagEditor { }, callback: function (r) { // Updates input to suggestion value (if any) on - if (r.message.length) $input.val(r.message[0]) + if (r.message.length) $input.val(r.message[0]); $input.trigger("input-selected"); }, }); From ae3eb9ff8546ddf4dc76a9130a75797af23bc428 Mon Sep 17 00:00:00 2001 From: Prateek Karamchandani Date: Sat, 22 Nov 2025 09:54:30 +0000 Subject: [PATCH 03/30] fix(link.js): pass value to super.set_formatted_input --- frappe/public/js/frappe/form/controls/link.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/controls/link.js b/frappe/public/js/frappe/form/controls/link.js index 9bb1796272..20803ad0d1 100644 --- a/frappe/public/js/frappe/form/controls/link.js +++ b/frappe/public/js/frappe/form/controls/link.js @@ -90,7 +90,7 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat } } set_formatted_input(value) { - super.set_formatted_input(); + super.set_formatted_input(value); if (!value) return; if (!this.title_value_map) { From 4ff1256fe1f2aba281d21c8bb36ecc09f0273909 Mon Sep 17 00:00:00 2001 From: hexed0ut <102050935+hexed0ut@users.noreply.github.com> Date: Tue, 2 Dec 2025 09:54:44 +0530 Subject: [PATCH 04/30] fix(tags): Close dropdown on tag selection Context - https://github.com/frappe/frappe/pull/34625#pullrequestreview-3521774645 --- frappe/public/js/frappe/ui/tags.js | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/public/js/frappe/ui/tags.js b/frappe/public/js/frappe/ui/tags.js index 3c5dd50beb..6795f04cc3 100644 --- a/frappe/public/js/frappe/ui/tags.js +++ b/frappe/public/js/frappe/ui/tags.js @@ -48,6 +48,7 @@ frappe.ui.Tags = class { this.$input.on("input-selected", () => { // Adds tag if a input is selected select_tag(); + this.deactivate(); }); this.$input.on("blur", () => { From 3989040ab6252907429244f16e77ffab7b4d32c0 Mon Sep 17 00:00:00 2001 From: sokumon Date: Thu, 4 Dec 2025 17:25:12 +0530 Subject: [PATCH 05/30] fix: always show standard items in sidebar --- frappe/public/js/frappe/ui/sidebar/sidebar.js | 10 ++++++---- frappe/public/js/frappe/ui/sidebar/sidebar_header.js | 6 ++++++ frappe/public/js/frappe/ui/sidebar/sidebar_item.js | 5 ++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/frappe/public/js/frappe/ui/sidebar/sidebar.js b/frappe/public/js/frappe/ui/sidebar/sidebar.js index 293aeb5698..db73945880 100644 --- a/frappe/public/js/frappe/ui/sidebar/sidebar.js +++ b/frappe/public/js/frappe/ui/sidebar/sidebar.js @@ -26,6 +26,7 @@ frappe.ui.Sidebar = class Sidebar { prepare() { try { + this.add_standard_items(); this.sidebar_data = frappe.boot.workspace_sidebar_item[this.workspace_title]; this.workspace_sidebar_items = this.sidebar_data.items; if (this.edit_mode) { @@ -213,7 +214,6 @@ frappe.ui.Sidebar = class Sidebar { } create_sidebar(items) { this.empty(); - this.add_standard_items(items); if (items && items.length > 0) { items.forEach((w) => { if (!w.display_depends_on || frappe.utils.eval(w.display_depends_on)) { @@ -403,9 +403,11 @@ frappe.ui.Sidebar = class Sidebar { if (sidebars.length == 0) { let module_name = router.meta?.module; if (module_name) { - frappe.app.sidebar.setup( - this.sidebar_module_map[module_name][0] || module_name - ); + let sidebar_title = + (this.sidebar_module_map[module_name] && + this.sidebar_module_map[module_name][0]) || + module_name; + frappe.app.sidebar.setup(sidebar_title); } } else { if (this.sidebar_title && sidebars.includes(this.workspace_title)) { diff --git a/frappe/public/js/frappe/ui/sidebar/sidebar_header.js b/frappe/public/js/frappe/ui/sidebar/sidebar_header.js index 84f0b5d3ed..997211c63a 100644 --- a/frappe/public/js/frappe/ui/sidebar/sidebar_header.js +++ b/frappe/public/js/frappe/ui/sidebar/sidebar_header.js @@ -99,8 +99,14 @@ frappe.ui.SidebarHeader = class SidebarHeader { false, `var(${this.header_bg_color})` ); + } else { + this.header_icon = this.get_default_icon(); + this.header_icon = ``; } } + get_default_icon() { + return frappe.boot.app_data[0].app_logo_url; + } get_desktop_icon_by_label(title, filters) { if (!filters) { return frappe.boot.desktop_icons.find((f) => f.label === title && f.hidden != 1); diff --git a/frappe/public/js/frappe/ui/sidebar/sidebar_item.js b/frappe/public/js/frappe/ui/sidebar/sidebar_item.js index 5c8235249f..bb88ec5f4a 100644 --- a/frappe/public/js/frappe/ui/sidebar/sidebar_item.js +++ b/frappe/public/js/frappe/ui/sidebar/sidebar_item.js @@ -4,7 +4,10 @@ frappe.ui.sidebar_item.TypeLink = class SidebarItem { this.item = opts.item; this.container = opts.container; this.nested_items = opts.item.nested_items || []; - this.workspace_title = $(".body-sidebar").attr("data-title").toLowerCase(); + this.workspace_title = + ($(".body-sidebar").attr("data-title") && + $(".body-sidebar").attr("data-title").toLowerCase()) || + frappe.app.sidebar.sidebar_title; this.prepare(opts); this.make(); } From e6ebd6ec15f0208fc566b2381790c35e43878c7f Mon Sep 17 00:00:00 2001 From: Pugazhendhi Velu Date: Tue, 11 Nov 2025 20:30:41 +0000 Subject: [PATCH 06/30] feat: add color property to button field --- frappe/core/doctype/docfield/docfield.json | 8 ++++++++ frappe/core/doctype/docfield/docfield.py | 1 + .../doctype/custom_field/custom_field.json | 10 +++++++++- .../doctype/custom_field/custom_field.py | 1 + .../doctype/customize_form/customize_form.py | 1 + .../customize_form_field.json | 10 +++++++++- .../customize_form_field.py | 1 + .../components/controls/ButtonControl.vue | 18 +++++++++++++++++- .../public/js/frappe/form/controls/button.js | 16 +++++++++++++++- 9 files changed, 62 insertions(+), 4 deletions(-) diff --git a/frappe/core/doctype/docfield/docfield.json b/frappe/core/doctype/docfield/docfield.json index 92df52d0aa..4e8cb320c4 100644 --- a/frappe/core/doctype/docfield/docfield.json +++ b/frappe/core/doctype/docfield/docfield.json @@ -32,6 +32,7 @@ "fetch_from", "fetch_if_empty", "visibility_section", + "button_color", "hidden", "show_on_timeline", "bold", @@ -617,6 +618,13 @@ "fieldname": "mask", "fieldtype": "Check", "label": "Mask" + }, + { + "depends_on": "eval:doc.fieldtype===\"Button\"", + "fieldname": "button_color", + "fieldtype": "Select", + "label": "Button Color", + "options": "\nDefault\nPrimary\nInfo\nSuccess\nWarning\nDanger" } ], "grid_page_length": 50, diff --git a/frappe/core/doctype/docfield/docfield.py b/frappe/core/doctype/docfield/docfield.py index 3f6d642e55..6f90b81ce9 100644 --- a/frappe/core/doctype/docfield/docfield.py +++ b/frappe/core/doctype/docfield/docfield.py @@ -18,6 +18,7 @@ class DocField(Document): allow_in_quick_entry: DF.Check allow_on_submit: DF.Check bold: DF.Check + button_color: DF.Literal["", "Default", "Primary", "Info", "Success", "Warning", "Danger"] collapsible: DF.Check collapsible_depends_on: DF.Code | None columns: DF.Int diff --git a/frappe/custom/doctype/custom_field/custom_field.json b/frappe/custom/doctype/custom_field/custom_field.json index 0a97a65c4b..cd0cc57f56 100644 --- a/frappe/custom/doctype/custom_field/custom_field.json +++ b/frappe/custom/doctype/custom_field/custom_field.json @@ -19,6 +19,7 @@ "link_filters", "column_break_6", "fieldtype", + "button_color", "precision", "hide_seconds", "hide_days", @@ -467,6 +468,13 @@ "fieldname": "placeholder", "fieldtype": "Data", "label": "Placeholder" + }, + { + "depends_on": "eval:doc.fieldtype===\"Button\"", + "fieldname": "button_color", + "fieldtype": "Select", + "label": "Button Color", + "options": "\nDefault\nPrimary\nInfo\nSuccess\nWarning\nDanger" } ], "grid_page_length": 50, @@ -474,7 +482,7 @@ "idx": 1, "index_web_pages_for_search": 1, "links": [], - "modified": "2025-10-10 11:10:23.862393", + "modified": "2025-11-12 01:14:24.753774", "modified_by": "Administrator", "module": "Custom", "name": "Custom Field", diff --git a/frappe/custom/doctype/custom_field/custom_field.py b/frappe/custom/doctype/custom_field/custom_field.py index f75dfbd58f..e90a6caf53 100644 --- a/frappe/custom/doctype/custom_field/custom_field.py +++ b/frappe/custom/doctype/custom_field/custom_field.py @@ -25,6 +25,7 @@ class CustomField(Document): allow_in_quick_entry: DF.Check allow_on_submit: DF.Check bold: DF.Check + button_color: DF.Literal["", "Default", "Primary", "Info", "Success", "Warning", "Danger"] collapsible: DF.Check collapsible_depends_on: DF.Code | None columns: DF.Int diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 1fa7a1c4aa..295182f6f2 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -806,6 +806,7 @@ docfield_properties = { "is_virtual": "Check", "link_filters": "JSON", "placeholder": "Data", + "button_color": "Select", } doctype_link_properties = { diff --git a/frappe/custom/doctype/customize_form_field/customize_form_field.json b/frappe/custom/doctype/customize_form_field/customize_form_field.json index 69b22eaf60..499e9f4b18 100644 --- a/frappe/custom/doctype/customize_form_field/customize_form_field.json +++ b/frappe/custom/doctype/customize_form_field/customize_form_field.json @@ -54,6 +54,7 @@ "column_break_33", "read_only_depends_on", "display", + "button_color", "in_filter", "hide_seconds", "hide_days", @@ -485,6 +486,13 @@ "fieldname": "placeholder", "fieldtype": "Data", "label": "Placeholder" + }, + { + "depends_on": "eval:doc.fieldtype===\"Button\"", + "fieldname": "button_color", + "fieldtype": "Select", + "label": "Button Color", + "options": "\nDefault\nPrimary\nInfo\nSuccess\nWarning\nDanger" } ], "grid_page_length": 50, @@ -492,7 +500,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2025-10-14 13:56:58.033573", + "modified": "2025-11-12 01:13:53.053888", "modified_by": "Administrator", "module": "Custom", "name": "Customize Form Field", diff --git a/frappe/custom/doctype/customize_form_field/customize_form_field.py b/frappe/custom/doctype/customize_form_field/customize_form_field.py index 34328ae585..6d30862c4b 100644 --- a/frappe/custom/doctype/customize_form_field/customize_form_field.py +++ b/frappe/custom/doctype/customize_form_field/customize_form_field.py @@ -17,6 +17,7 @@ class CustomizeFormField(Document): allow_in_quick_entry: DF.Check allow_on_submit: DF.Check bold: DF.Check + button_color: DF.Literal["", "Default", "Primary", "Info", "Success", "Warning", "Danger"] collapsible: DF.Check collapsible_depends_on: DF.Code | None columns: DF.Int diff --git a/frappe/public/js/form_builder/components/controls/ButtonControl.vue b/frappe/public/js/form_builder/components/controls/ButtonControl.vue index 6642d5dc49..460ead3055 100644 --- a/frappe/public/js/form_builder/components/controls/ButtonControl.vue +++ b/frappe/public/js/form_builder/components/controls/ButtonControl.vue @@ -1,6 +1,22 @@