diff --git a/cypress/integration/control_link.js b/cypress/integration/control_link.js index 3929222ea0..240515be45 100644 --- a/cypress/integration/control_link.js +++ b/cypress/integration/control_link.js @@ -26,15 +26,15 @@ context("Control Link", () => { }); } - function get_dialog_with_user_link() { + function get_dialog_with_gender_link() { return cy.dialog({ title: "Link", fields: [ { - label: "Select User", + label: "Select Gender", fieldname: "link", fieldtype: "Link", - options: "User", + options: "Gender", }, ], }); @@ -43,19 +43,6 @@ context("Control Link", () => { it("should set the valid value", () => { get_dialog_with_link().as("dialog"); - cy.insert_doc( - "Property Setter", - { - doctype: "Property Setter", - doc_type: "User", - property: "translate_link_fields", - property_type: "Check", - doctype_or_field: "DocType", - value: "0", - }, - true - ); - cy.insert_doc( "Property Setter", { @@ -133,19 +120,6 @@ context("Control Link", () => { }); it("show title field in link", () => { - cy.insert_doc( - "Property Setter", - { - doctype: "Property Setter", - doc_type: "User", - property: "translate_link_fields", - property_type: "Check", - doctype_or_field: "DocType", - value: "0", - }, - true - ); - cy.insert_doc( "Property Setter", { @@ -275,142 +249,54 @@ context("Control Link", () => { ); }); - it("show translated text for link with show_title_field_in_link enabled", () => { - cy.insert_doc( - "Property Setter", - { - doctype: "Property Setter", - doc_type: "ToDo", - property: "translate_link_fields", - property_type: "Check", - doctype_or_field: "DocType", - value: "1", - }, - true - ); - - cy.insert_doc( - "Property Setter", - { - doctype: "Property Setter", - doc_type: "ToDo", - property: "show_title_field_in_link", - property_type: "Check", - doctype_or_field: "DocType", - value: "1", - }, - true - ); - - cy.window() - .its("frappe") - .then((frappe) => { - cy.insert_doc("Translation", { - doctype: "Translation", - language: frappe.boot.lang, - source_text: "this is a test todo for link", - translated_text: "this is a translated test todo for link", + it("show translated text for Gender link field with language de with input in de", () => { + cy.call("frappe.tests.ui_test_helpers.insert_translations").then(() => { + cy.window() + .its("frappe") + .then((frappe) => { + cy.set_value("User", frappe.user.name, { language: "de" }); }); - }); - cy.clear_cache(); - cy.wait(500); + cy.clear_cache(); + cy.wait(500); - cy.window() - .its("frappe") - .then((frappe) => { - if (!frappe.boot) { - frappe.boot = { - link_title_doctypes: ["ToDo"], - translatable_doctypes: ["ToDo"], - }; - } else { - frappe.boot.link_title_doctypes = ["ToDo"]; - frappe.boot.translatable_doctypes = ["ToDo"]; - } - }); + get_dialog_with_gender_link().as("dialog"); + cy.intercept("POST", "/api/method/frappe.desk.search.search_link").as("search_link"); - get_dialog_with_link().as("dialog"); - cy.intercept("POST", "/api/method/frappe.desk.search.search_link").as("search_link"); - - cy.get(".frappe-control[data-fieldname=link] input").focus().as("input"); - cy.wait("@search_link"); - cy.get("@input").type("todo for link", { delay: 100 }); - cy.wait("@search_link"); - cy.get(".frappe-control[data-fieldname=link] ul").should("be.visible"); - cy.get(".frappe-control[data-fieldname=link] input").type("{enter}", { delay: 100 }); - cy.get(".frappe-control[data-fieldname=link] input").blur(); - cy.get("@dialog").then((dialog) => { - cy.get("@todos").then((todos) => { + cy.get(".frappe-control[data-fieldname=link] input").focus().as("input"); + cy.wait("@search_link"); + cy.get("@input").type("Sonstiges", { delay: 100 }); + cy.wait("@search_link"); + cy.get(".frappe-control[data-fieldname=link] ul").should("be.visible"); + cy.get(".frappe-control[data-fieldname=link] input").type("{enter}", { delay: 100 }); + cy.get(".frappe-control[data-fieldname=link] input").blur(); + cy.get("@dialog").then((dialog) => { let field = dialog.get_field("link"); let value = field.get_value(); let label = field.get_label_value(); - expect(value).to.eq(todos[0]); - expect(label).to.eq("this is a translated test todo for link"); + expect(value).to.eq("Other"); + expect(label).to.eq("Sonstiges"); }); }); }); - it("show translated text for link with show_title_field_in_link disabled", () => { - cy.insert_doc( - "Property Setter", - { - doctype: "Property Setter", - doc_type: "User", - property: "translate_link_fields", - property_type: "Check", - doctype_or_field: "DocType", - value: "1", - }, - true - ); - - cy.insert_doc( - "Property Setter", - { - doctype: "Property Setter", - doc_type: "ToDo", - property: "show_title_field_in_link", - property_type: "Check", - doctype_or_field: "DocType", - value: "0", - }, - true - ); - + it("show text for Gender link field with language en", () => { cy.window() .its("frappe") .then((frappe) => { - cy.insert_doc("Translation", { - doctype: "Translation", - language: frappe.boot.lang, - source_text: "test@erpnext.com", - translated_text: "translatedtest@erpnext.com", - }); + cy.set_value("User", frappe.user.name, { language: "en" }); }); cy.clear_cache(); cy.wait(500); - cy.window() - .its("frappe") - .then((frappe) => { - if (!frappe.boot) { - frappe.boot = { - translatable_doctypes: ["User"], - }; - } else { - frappe.boot.translatable_doctypes = ["User"]; - } - }); - - get_dialog_with_user_link().as("dialog"); + get_dialog_with_gender_link().as("dialog"); cy.intercept("POST", "/api/method/frappe.desk.search.search_link").as("search_link"); cy.get(".frappe-control[data-fieldname=link] input").focus().as("input"); cy.wait("@search_link"); - cy.get("@input").type("test@erpnext.com", { delay: 100 }); + cy.get("@input").type("Non-Conforming", { delay: 100 }); cy.wait("@search_link"); cy.get(".frappe-control[data-fieldname=link] ul").should("be.visible"); cy.get(".frappe-control[data-fieldname=link] input").type("{enter}", { delay: 100 }); @@ -420,8 +306,8 @@ context("Control Link", () => { let value = field.get_value(); let label = field.get_label_value(); - expect(value).to.eq("test@erpnext.com"); - expect(label).to.eq("translatedtest@erpnext.com"); + expect(value).to.eq("Non-Conforming"); + expect(label).to.eq("Non-Conforming"); }); }); diff --git a/cypress/integration/web_form.js b/cypress/integration/web_form.js index 4c99451146..9173bfaeb3 100644 --- a/cypress/integration/web_form.js +++ b/cypress/integration/web_form.js @@ -237,7 +237,7 @@ context("Web Form", () => { cy.get(".web-form-actions a").contains("Edit").click(); - cy.fill_field("last_name", "_Test User"); + cy.fill_field("middle_name", "_Test User"); cy.get(".web-form-actions .btn-primary").click(); cy.url().should("include", "/me"); @@ -249,7 +249,7 @@ context("Web Form", () => { cy.get(".web-form-actions a").contains("Edit").click(); - cy.fill_field("last_name", "_Test User"); + cy.fill_field("middle_name", "_Test User"); cy.get(".btn-next").should("be.visible"); cy.get(".btn-next").click(); diff --git a/frappe/boot.py b/frappe/boot.py index 98d1e59a57..5121215106 100644 --- a/frappe/boot.py +++ b/frappe/boot.py @@ -19,7 +19,7 @@ from frappe.social.doctype.energy_point_log.energy_point_log import get_energy_p from frappe.social.doctype.energy_point_settings.energy_point_settings import ( is_energy_point_enabled, ) -from frappe.translate import get_lang_dict, get_messages_for_boot +from frappe.translate import get_lang_dict, get_messages_for_boot, get_translated_doctypes from frappe.utils import add_user_info, cstr, get_time_zone from frappe.utils.change_log import get_versions from frappe.website.doctype.web_page_view.web_page_view import is_tracking_enabled @@ -100,7 +100,7 @@ def get_bootinfo(): bootinfo.desk_settings = get_desk_settings() bootinfo.app_logo_url = get_app_logo() bootinfo.link_title_doctypes = get_link_title_doctypes() - bootinfo.translatable_doctypes = get_translatable_doctypes() + bootinfo.translated_doctypes = get_translated_doctypes() return bootinfo @@ -399,14 +399,6 @@ def set_time_zone(bootinfo): } -def get_translatable_doctypes(): - dts = frappe.get_all("DocType", {"translate_link_fields": 1}, pluck="name") - custom_dts = frappe.get_all( - "Property Setter", {"property": "translate_link_fields", "value": "1"}, pluck="doc_type" - ) - return dts + custom_dts - - def load_country_doc(bootinfo): country = frappe.db.get_default("country") if not country: diff --git a/frappe/contacts/doctype/gender/gender.json b/frappe/contacts/doctype/gender/gender.json index 20d0210f05..34e1ddaee6 100644 --- a/frappe/contacts/doctype/gender/gender.json +++ b/frappe/contacts/doctype/gender/gender.json @@ -17,7 +17,7 @@ } ], "links": [], - "modified": "2022-08-03 12:20:48.408685", + "modified": "2022-08-05 18:33:28.043370", "modified_by": "Administrator", "module": "Contacts", "name": "Gender", @@ -43,5 +43,6 @@ "sort_field": "modified", "sort_order": "DESC", "states": [], - "track_changes": 1 + "track_changes": 1, + "translated_doctype": 1 } \ No newline at end of file diff --git a/frappe/contacts/doctype/salutation/salutation.json b/frappe/contacts/doctype/salutation/salutation.json index c80faf1cda..98ed082e69 100644 --- a/frappe/contacts/doctype/salutation/salutation.json +++ b/frappe/contacts/doctype/salutation/salutation.json @@ -18,7 +18,7 @@ } ], "links": [], - "modified": "2022-08-03 12:20:48.954912", + "modified": "2022-08-05 18:33:28.196387", "modified_by": "Administrator", "module": "Contacts", "name": "Salutation", @@ -56,5 +56,6 @@ "sort_field": "modified", "sort_order": "DESC", "states": [], - "track_changes": 1 + "track_changes": 1, + "translated_doctype": 1 } \ No newline at end of file diff --git a/frappe/core/doctype/doctype/doctype.json b/frappe/core/doctype/doctype/doctype.json index 4e110202d2..b7b93a8f37 100644 --- a/frappe/core/doctype/doctype/doctype.json +++ b/frappe/core/doctype/doctype/doctype.json @@ -47,7 +47,7 @@ "view_settings", "title_field", "show_title_field_in_link", - "translate_link_fields", + "translated_doctype", "search_fields", "default_print_format", "sort_field", @@ -595,7 +595,7 @@ }, { "default": "0", - "fieldname": "translate_link_fields", + "fieldname": "translated_doctype", "fieldtype": "Check", "label": "Translate Link Fields" } @@ -680,7 +680,7 @@ "link_fieldname": "reference_doctype" } ], - "modified": "2022-02-28 21:56:52.116915", + "modified": "2022-08-05 18:33:27.315351", "modified_by": "Administrator", "module": "Core", "name": "DocType", @@ -716,5 +716,5 @@ "sort_order": "DESC", "states": [], "track_changes": 1, - "translate_link_fields": 1 + "translated_doctype": 1 } \ No newline at end of file diff --git a/frappe/core/doctype/role/role.json b/frappe/core/doctype/role/role.json index e370082fb5..2039d3889d 100644 --- a/frappe/core/doctype/role/role.json +++ b/frappe/core/doctype/role/role.json @@ -148,7 +148,7 @@ "idx": 1, "index_web_pages_for_search": 1, "links": [], - "modified": "2022-01-12 20:18:18.496230", + "modified": "2022-08-05 18:33:27.694065", "modified_by": "Administrator", "module": "Core", "name": "Role", @@ -171,5 +171,6 @@ "sort_field": "modified", "sort_order": "ASC", "states": [], - "track_changes": 1 + "track_changes": 1, + "translated_doctype": 1 } \ No newline at end of file diff --git a/frappe/custom/doctype/customize_form/customize_form.json b/frappe/custom/doctype/customize_form/customize_form.json index 0011f51af4..d66d779963 100644 --- a/frappe/custom/doctype/customize_form/customize_form.json +++ b/frappe/custom/doctype/customize_form/customize_form.json @@ -29,7 +29,7 @@ "view_settings_section", "title_field", "show_title_field_in_link", - "translate_link_fields", + "translated_doctype", "image_field", "default_print_format", "column_break_29", @@ -315,7 +315,7 @@ }, { "default": "0", - "fieldname": "translate_link_fields", + "fieldname": "translated_doctype", "fieldtype": "Check", "label": "Translate Link Fields" } @@ -326,7 +326,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2022-05-13 15:36:16.772277", + "modified": "2022-08-04 15:36:16.772277", "modified_by": "Administrator", "module": "Custom", "name": "Customize Form", diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index dc625d1a58..32f0f165dc 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -585,7 +585,7 @@ doctype_properties = { "naming_rule": "Data", "autoname": "Data", "show_title_field_in_link": "Check", - "translate_link_fields": "Check", + "translated_doctype": "Check", } docfield_properties = { diff --git a/frappe/database/mariadb/framework_mariadb.sql b/frappe/database/mariadb/framework_mariadb.sql index dc91873a82..83b6f6b171 100644 --- a/frappe/database/mariadb/framework_mariadb.sql +++ b/frappe/database/mariadb/framework_mariadb.sql @@ -226,7 +226,7 @@ CREATE TABLE `tabDocType` ( `sender_field` varchar(255) DEFAULT NULL, `show_title_field_in_link` int(1) NOT NULL DEFAULT 0, `migration_hash` varchar(255) DEFAULT NULL, - `translate_link_fields` int(1) NOT NULL DEFAULT 0, + `translated_doctype` int(1) NOT NULL DEFAULT 0, PRIMARY KEY (`name`) ) ENGINE=InnoDB ROW_FORMAT=DYNAMIC CHARACTER SET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/frappe/database/postgres/framework_postgres.sql b/frappe/database/postgres/framework_postgres.sql index 99e94a226f..bc39449113 100644 --- a/frappe/database/postgres/framework_postgres.sql +++ b/frappe/database/postgres/framework_postgres.sql @@ -231,7 +231,7 @@ CREATE TABLE "tabDocType" ( "sender_field" varchar(255) DEFAULT NULL, "show_title_field_in_link" smallint NOT NULL DEFAULT 0, "migration_hash" varchar(255) DEFAULT NULL, - "translate_link_fields" smallint NOT NULL DEFAULT 0, + "translated_doctype" smallint NOT NULL DEFAULT 0, PRIMARY KEY ("name") ) ; diff --git a/frappe/desk/search.py b/frappe/desk/search.py index 8ae635093c..53a8c39ee5 100644 --- a/frappe/desk/search.py +++ b/frappe/desk/search.py @@ -8,6 +8,7 @@ import re import frappe from frappe import _, is_whitelisted from frappe.permissions import has_permission +from frappe.translate import get_translated_doctypes from frappe.utils import cint, cstr, unique @@ -115,7 +116,10 @@ def search_widget( raise e else: frappe.respond_as_web_page( - title="Invalid Method", html="Method not found", indicator_color="red", http_status_code=404 + title="Invalid Method", + html="Method not found", + indicator_color="red", + http_status_code=404, ) return except Exception as e: @@ -146,9 +150,22 @@ def search_widget( filters = [] or_filters = [] - translated_search_doctypes = frappe.get_hooks("translated_search_doctypes") + translated_doctypes = frappe.cache().hget( + "translated_doctypes", "doctypes", get_translated_doctypes + ) + # build from doctype if txt: + field_types = [ + "Data", + "Text", + "Small Text", + "Long Text", + "Link", + "Select", + "Read Only", + "Text Editor", + ] search_fields = ["name"] if meta.title_field: search_fields.append(meta.title_field) @@ -158,13 +175,8 @@ def search_widget( for f in search_fields: fmeta = meta.get_field(f.strip()) - if (doctype not in translated_search_doctypes) and ( - f == "name" - or ( - fmeta - and fmeta.fieldtype - in ["Data", "Text", "Small Text", "Long Text", "Link", "Select", "Read Only", "Text Editor"] - ) + if (doctype not in translated_doctypes) and ( + f == "name" or (fmeta and fmeta.fieldtype in field_types) ): or_filters.append([doctype, f.strip(), "like", f"%{txt}%"]) @@ -188,7 +200,8 @@ def search_widget( # find relevance as location of search term from the beginning of string `name`. used for sorting results. formatted_fields.append( """locate({_txt}, `tab{doctype}`.`name`) as `_relevance`""".format( - _txt=frappe.db.escape((txt or "").replace("%", "").replace("@", "")), doctype=doctype + _txt=frappe.db.escape((txt or "").replace("%", "").replace("@", "")), + doctype=doctype, ) ) @@ -206,7 +219,7 @@ def search_widget( else (cint(ignore_user_permissions) and has_permission(doctype, ptype=ptype)) ) - if doctype in translated_search_doctypes: + if doctype in translated_doctypes: page_length = None values = frappe.get_list( @@ -223,7 +236,7 @@ def search_widget( strict=False, ) - if doctype in translated_search_doctypes: + if doctype in translated_doctypes: # Filtering the values array so that query is included in very element values = ( v diff --git a/frappe/geo/doctype/country/country.json b/frappe/geo/doctype/country/country.json index 8ac3741865..2cbd0a296f 100644 --- a/frappe/geo/doctype/country/country.json +++ b/frappe/geo/doctype/country/country.json @@ -54,7 +54,7 @@ "icon": "fa fa-globe", "idx": 1, "links": [], - "modified": "2020-02-24 15:44:31.837133", + "modified": "2022-08-05 18:33:27.880783", "modified_by": "Administrator", "module": "Geo", "name": "Country", @@ -84,5 +84,7 @@ "quick_entry": 1, "sort_field": "country_name", "sort_order": "ASC", - "track_changes": 1 + "states": [], + "track_changes": 1, + "translated_doctype": 1 } \ No newline at end of file diff --git a/frappe/hooks.py b/frappe/hooks.py index 14e76adc22..85aeea7418 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -373,5 +373,3 @@ override_whitelisted_methods = { "frappe.core.doctype.file.file.move_file": "frappe.core.api.file.move_file", "frappe.core.doctype.file.file.zip_files": "frappe.core.api.file.zip_files", } - -translated_search_doctypes = ["DocType", "Role", "Country", "Gender", "Salutation"] diff --git a/frappe/public/js/frappe/form/controls/link.js b/frappe/public/js/frappe/form/controls/link.js index abb00de8ac..e34fd01008 100644 --- a/frappe/public/js/frappe/form/controls/link.js +++ b/frappe/public/js/frappe/form/controls/link.js @@ -87,7 +87,7 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat return this.is_translatable() ? __(value) : value; } is_translatable() { - return in_list(frappe.boot?.translatable_doctypes || [], this.get_options()); + return in_list(frappe.boot?.translated_doctypes || [], this.get_options()); } set_link_title(value) { let doctype = this.get_options(); @@ -391,22 +391,6 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat me.$input.val(""); } }); - - this.$input.on("focus", function () { - if (!frappe.boot.translated_search_doctypes.includes(me.df.options)) { - me.show_untranslated(); - } - }); - - this.$input.keydown((e) => { - let BACKSPACE = 8; - if ( - e.keyCode === BACKSPACE && - !frappe.boot.translated_search_doctypes.includes(me.df.options) - ) { - me.show_untranslated(); - } - }); } show_untranslated() { diff --git a/frappe/sessions.py b/frappe/sessions.py index f7c4b34470..acc09dc03c 100644 --- a/frappe/sessions.py +++ b/frappe/sessions.py @@ -184,7 +184,6 @@ def get(): frappe.get_attr(hook)(bootinfo=bootinfo) bootinfo["lang"] = frappe.translate.get_user_lang() - bootinfo["translated_search_doctypes"] = frappe.get_hooks("translated_search_doctypes") bootinfo["disable_async"] = frappe.conf.disable_async bootinfo["setup_complete"] = cint(frappe.get_system_settings("setup_complete")) diff --git a/frappe/tests/ui_test_helpers.py b/frappe/tests/ui_test_helpers.py index b3501e7f09..b0ef472cbd 100644 --- a/frappe/tests/ui_test_helpers.py +++ b/frappe/tests/ui_test_helpers.py @@ -333,3 +333,37 @@ def insert_doctype_with_child_table_record(name): insert_child(doc, "Drag", "08189DIHAA2981", 0, 0.7, 342628, "2022-05-04") doc.insert() + + +@frappe.whitelist() +def insert_translations(): + translation = [ + { + "doctype": "Translation", + "language": "de", + "source_text": "Other", + "translated_text": "Sonstiges", + }, + { + "doctype": "Translation", + "language": "de", + "source_text": "Genderqueer", + "translated_text": "Nichtbinär", + }, + { + "doctype": "Translation", + "language": "de", + "source_text": "Non-Conforming", + "translated_text": "Nicht konform", + }, + { + "doctype": "Translation", + "language": "de", + "source_text": "Prefer not to say", + "translated_text": "Keine Angabe", + }, + ] + + for doc in translation: + if not frappe.db.exists("doc"): + frappe.get_doc(doc).insert() diff --git a/frappe/translate.py b/frappe/translate.py index 06176e28ba..c644636332 100644 --- a/frappe/translate.py +++ b/frappe/translate.py @@ -23,7 +23,7 @@ from pypika.terms import PseudoColumn import frappe from frappe.model.utils import InvalidIncludePath, render_include from frappe.query_builder import DocType, Field -from frappe.utils import cstr, get_bench_path, is_html, strip, strip_html_tags +from frappe.utils import cstr, get_bench_path, is_html, strip, strip_html_tags, unique TRANSLATE_PATTERN = re.compile( r"_\(\s*" # starts with literal `_(`, ignore following whitespace/newlines @@ -1294,3 +1294,11 @@ def set_preferred_language_cookie(preferred_language): def get_preferred_language_cookie(): return frappe.request.cookies.get("preferred_language") + + +def get_translated_doctypes(): + dts = frappe.get_all("DocType", {"translated_doctype": 1}, pluck="name") + custom_dts = frappe.get_all( + "Property Setter", {"property": "translated_doctype", "value": "1"}, pluck="doc_type" + ) + return unique(dts + custom_dts) diff --git a/frappe/utils/boilerplate.py b/frappe/utils/boilerplate.py index c34ab2d591..f0f3173425 100644 --- a/frappe/utils/boilerplate.py +++ b/frappe/utils/boilerplate.py @@ -79,7 +79,8 @@ def is_valid_title(title) -> bool: def _create_app_boilerplate(dest, hooks, no_git=False): frappe.create_folder( - os.path.join(dest, hooks.app_name, hooks.app_name, frappe.scrub(hooks.app_title)), with_init=True + os.path.join(dest, hooks.app_name, hooks.app_name, frappe.scrub(hooks.app_title)), + with_init=True, ) frappe.create_folder( os.path.join(dest, hooks.app_name, hooks.app_name, "templates"), with_init=True @@ -249,8 +250,8 @@ app_license = "{app_license}" # add methods and filters to jinja environment # jinja = {{ -# "methods": "{app_name}.utils.jinja_methods", -# "filters": "{app_name}.utils.jinja_filters" +# "methods": "{app_name}.utils.jinja_methods", +# "filters": "{app_name}.utils.jinja_filters" # }} # Installation @@ -276,11 +277,11 @@ app_license = "{app_license}" # Permissions evaluated in scripted ways # permission_query_conditions = {{ -# "Event": "frappe.desk.doctype.event.event.get_permission_query_conditions", +# "Event": "frappe.desk.doctype.event.event.get_permission_query_conditions", # }} # # has_permission = {{ -# "Event": "frappe.desk.doctype.event.event.has_permission", +# "Event": "frappe.desk.doctype.event.event.has_permission", # }} # DocType Class @@ -288,7 +289,7 @@ app_license = "{app_license}" # Override standard doctype classes # override_doctype_class = {{ -# "ToDo": "custom_app.overrides.CustomToDo" +# "ToDo": "custom_app.overrides.CustomToDo" # }} # Document Events @@ -296,10 +297,10 @@ app_license = "{app_license}" # Hook on document methods and events # doc_events = {{ -# "*": {{ -# "on_update": "method", -# "on_cancel": "method", -# "on_trash": "method" +# "*": {{ +# "on_update": "method", +# "on_cancel": "method", +# "on_trash": "method" # }} # }} @@ -307,21 +308,21 @@ app_license = "{app_license}" # --------------- # scheduler_events = {{ -# "all": [ -# "{app_name}.tasks.all" -# ], -# "daily": [ -# "{app_name}.tasks.daily" -# ], -# "hourly": [ -# "{app_name}.tasks.hourly" -# ], -# "weekly": [ -# "{app_name}.tasks.weekly" -# ], -# "monthly": [ -# "{app_name}.tasks.monthly" -# ], +# "all": [ +# "{app_name}.tasks.all" +# ], +# "daily": [ +# "{app_name}.tasks.daily" +# ], +# "hourly": [ +# "{app_name}.tasks.hourly" +# ], +# "weekly": [ +# "{app_name}.tasks.weekly" +# ], +# "monthly": [ +# "{app_name}.tasks.monthly" +# ], # }} # Testing @@ -333,14 +334,14 @@ app_license = "{app_license}" # ------------------------------ # # override_whitelisted_methods = {{ -# "frappe.desk.doctype.event.event.get_events": "{app_name}.event.get_events" +# "frappe.desk.doctype.event.event.get_events": "{app_name}.event.get_events" # }} # # each overriding function accepts a `data` argument; # generated from the base implementation of the doctype dashboard, # along with any modifications made in other Frappe apps # override_doctype_dashboards = {{ -# "Task": "{app_name}.task.get_dashboard_data" +# "Task": "{app_name}.task.get_dashboard_data" # }} # exempt linked doctypes from being automatically cancelled @@ -352,40 +353,32 @@ app_license = "{app_license}" # -------------------- # user_data_fields = [ -# {{ -# "doctype": "{{doctype_1}}", -# "filter_by": "{{filter_by}}", -# "redact_fields": ["{{field_1}}", "{{field_2}}"], -# "partial": 1, -# }}, -# {{ -# "doctype": "{{doctype_2}}", -# "filter_by": "{{filter_by}}", -# "partial": 1, -# }}, -# {{ -# "doctype": "{{doctype_3}}", -# "strict": False, -# }}, -# {{ -# "doctype": "{{doctype_4}}" -# }} +# {{ +# "doctype": "{{doctype_1}}", +# "filter_by": "{{filter_by}}", +# "redact_fields": ["{{field_1}}", "{{field_2}}"], +# "partial": 1, +# }}, +# {{ +# "doctype": "{{doctype_2}}", +# "filter_by": "{{filter_by}}", +# "partial": 1, +# }}, +# {{ +# "doctype": "{{doctype_3}}", +# "strict": False, +# }}, +# {{ +# "doctype": "{{doctype_4}}" +# }} # ] # Authentication and authorization # -------------------------------- # auth_hooks = [ -# "{app_name}.auth.validate" +# "{app_name}.auth.validate" # ] - -# Translation -# -------------------------------- - -# Make link fields search translated document names for these DocTypes -# Recommended only for DocTypes which have limited documents with untranslated names -# For example: Role, Gender, etc. -# translated_search_doctypes = [] """ desktop_template = """from frappe import _