Merge branch 'develop' into capture-client-events

This commit is contained in:
mergify[bot] 2026-01-05 07:22:11 +00:00 committed by GitHub
commit efc236ef37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 109 additions and 46 deletions

View file

@ -6,8 +6,9 @@ def execute():
batch_size = 10_000 batch_size = 10_000
while True: while True:
frappe.db.sql( frappe.db.multisql(
""" {
"mariadb": """
update `tabCommunication Link` cl update `tabCommunication Link` cl
inner join `tabCommunication` c on cl.parent = c.name inner join `tabCommunication` c on cl.parent = c.name
set cl.communication_date = c.communication_date set cl.communication_date = c.communication_date
@ -15,9 +16,22 @@ def execute():
and c.communication_date is not null and c.communication_date is not null
limit %s limit %s
""", """,
"postgres": """
UPDATE "tabCommunication Link"
SET communication_date = sub.communication_date
FROM (
SELECT cl.name, c.communication_date
FROM "tabCommunication Link" cl
JOIN "tabCommunication" c ON cl.parent = c.name
WHERE cl.communication_date IS NULL
AND c.communication_date IS NOT NULL
LIMIT %s
) AS sub
WHERE "tabCommunication Link".name = sub.name
""",
},
(batch_size,), (batch_size,),
) )
frappe.db.commit() frappe.db.commit()
if not frappe.db.sql( if not frappe.db.sql(

View file

@ -59,6 +59,7 @@
"view_switcher", "view_switcher",
"form_settings_section", "form_settings_section",
"form_sidebar", "form_sidebar",
"form_navigation_buttons",
"timeline", "timeline",
"dashboard", "dashboard",
"show_absolute_datetime_in_timeline", "show_absolute_datetime_in_timeline",
@ -850,6 +851,12 @@
"is_virtual": 1, "is_virtual": 1,
"label": "Active Sessions", "label": "Active Sessions",
"options": "User Session Display" "options": "User Session Display"
},
{
"default": "1",
"fieldname": "form_navigation_buttons",
"fieldtype": "Check",
"label": "Navigation Buttons"
} }
], ],
"icon": "fa fa-user", "icon": "fa fa-user",
@ -903,7 +910,7 @@
} }
], ],
"make_attachments_public": 1, "make_attachments_public": 1,
"modified": "2025-12-13 12:53:46.486021", "modified": "2026-01-02 16:00:51.406511",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Core", "module": "Core",
"name": "User", "name": "User",

View file

@ -48,6 +48,7 @@ desk_properties = (
"bulk_actions", "bulk_actions",
"view_switcher", "view_switcher",
"form_sidebar", "form_sidebar",
"form_navigation_buttons",
"timeline", "timeline",
"dashboard", "dashboard",
) )
@ -96,6 +97,7 @@ class User(Document):
follow_created_documents: DF.Check follow_created_documents: DF.Check
follow_liked_documents: DF.Check follow_liked_documents: DF.Check
follow_shared_documents: DF.Check follow_shared_documents: DF.Check
form_navigation_buttons: DF.Check
form_sidebar: DF.Check form_sidebar: DF.Check
full_name: DF.Data | None full_name: DF.Data | None
gender: DF.Link | None gender: DF.Link | None

View file

@ -446,9 +446,20 @@
bottom: 4%; bottom: 4%;
right: 4%; right: 4%;
z-index: 100; z-index: 100;
opacity: 0.1; opacity: 0.5;
} }
.desktop-edit:hover{ .desktop-edit:hover{
opacity: 1; opacity: 1;
transition: opacity 0.3s; transition: opacity 0.3s;
} }
[data-theme="dark"] .desktop-edit{
background-color: var(--surface-gray-3);
opacity: 1;
}
[data-theme="dark"] .desktop-edit:hover{
opacity: 0.8;
transition: opacity 0.3s;
}

View file

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: frappe\n" "Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: developers@frappe.io\n" "Report-Msgid-Bugs-To: developers@frappe.io\n"
"POT-Creation-Date: 2025-12-21 09:35+0000\n" "POT-Creation-Date: 2025-12-21 09:35+0000\n"
"PO-Revision-Date: 2025-12-24 20:23\n" "PO-Revision-Date: 2026-01-03 23:05\n"
"Last-Translator: developers@frappe.io\n" "Last-Translator: developers@frappe.io\n"
"Language-Team: Russian\n" "Language-Team: Russian\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -133,7 +133,15 @@ msgid "0 - too guessable: risky password.\n"
"3 - safely unguessable: moderate protection from offline slow-hash scenario.\n" "3 - safely unguessable: moderate protection from offline slow-hash scenario.\n"
"<br>\n" "<br>\n"
"4 - very unguessable: strong protection from offline slow-hash scenario." "4 - very unguessable: strong protection from offline slow-hash scenario."
msgstr "" msgstr "0 - слишком легко угадывается: рискованный пароль.\n"
"<br>\n"
"1 - очень легко угадывается: защита от атак с ограничением скорости. \n"
"<br>\n"
"2 - относительно легко угадывается: защита от атак без ограничения скорости.\n"
"<br>\n"
"3 - практически невозможно угадать: умеренная защита от сценариев с медленным хешированием в офлайн-режиме.\n"
"<br>\n"
"4 - очень трудно угадать: надежная защита от сценариев с медленным хешированием в офлайн-режиме."
#. Description of the 'Priority' (Int) field in DocType 'Web Page' #. Description of the 'Priority' (Int) field in DocType 'Web Page'
#: frappe/website/doctype/web_page/web_page.json #: frappe/website/doctype/web_page/web_page.json
@ -1466,7 +1474,7 @@ msgstr "Добавить новую вкладку"
#: frappe/utils/password_strength.py:191 #: frappe/utils/password_strength.py:191
msgid "Add numbers or special characters." msgid "Add numbers or special characters."
msgstr "" msgstr "Добавьте цифры или специальные символы."
#: frappe/public/js/print_format_builder/PrintFormatSection.vue:125 #: frappe/public/js/print_format_builder/PrintFormatSection.vue:125
msgid "Add page break" msgid "Add page break"
@ -5217,7 +5225,7 @@ msgstr "Распространенные имена и фамилии легко
#: frappe/utils/password_strength.py:190 #: frappe/utils/password_strength.py:190
msgid "Common words are easy to guess." msgid "Common words are easy to guess."
msgstr "" msgstr "Общие слова легко угадать."
#. Name of a DocType #. Name of a DocType
#. Option for the 'Communication Type' (Select) field in DocType #. Option for the 'Communication Type' (Select) field in DocType
@ -5912,7 +5920,7 @@ msgstr "Создать новую Канбан доску"
#: frappe/public/js/frappe/list/list_filter.js:101 #: frappe/public/js/frappe/list/list_filter.js:101
msgid "Create Saved Filter" msgid "Create Saved Filter"
msgstr "" msgstr "Создать сохраненный фильтр"
#: frappe/core/doctype/user/user.js:271 #: frappe/core/doctype/user/user.js:271
msgid "Create User Email" msgid "Create User Email"
@ -12025,7 +12033,7 @@ msgstr "Помощь HTML"
#. Description of the 'Content' (Text Editor) field in DocType 'Note' #. Description of the 'Content' (Text Editor) field in DocType 'Note'
#: frappe/desk/doctype/note/note.json #: frappe/desk/doctype/note/note.json
msgid "Help: To link to another record in the system, use \"/desk/note/[Note Name]\" as the Link URL. (don't use \"http://\")" msgid "Help: To link to another record in the system, use \"/desk/note/[Note Name]\" as the Link URL. (don't use \"http://\")"
msgstr "" msgstr "Помощь: Для ссылки на другую запись в системе используйте \"/desk/note/[Имя заметки]\" в качестве ссылки (не используйте \"http://\")"
#. Label of the helpful (Int) field in DocType 'Help Article' #. Label of the helpful (Int) field in DocType 'Help Article'
#: frappe/website/doctype/help_article/help_article.json #: frappe/website/doctype/help_article/help_article.json
@ -17498,7 +17506,7 @@ msgstr "Не найден шаблон по пути: {0}"
#: frappe/core/page/permission_manager/permission_manager.js:362 #: frappe/core/page/permission_manager/permission_manager.js:362
msgid "No user has the role <strong>{0}</strong>" msgid "No user has the role <strong>{0}</strong>"
msgstr "" msgstr "Нет пользователя с ролью <strong>{0}</strong>"
#: frappe/public/js/frappe/form/controls/multiselect_list.js:276 #: frappe/public/js/frappe/form/controls/multiselect_list.js:276
msgid "No values to show" msgid "No values to show"
@ -19124,7 +19132,7 @@ msgstr "Пароль не найден для {0} {1} {2}"
#: frappe/core/doctype/user/user.py:1307 #: frappe/core/doctype/user/user.py:1307
msgid "Password requirements not met" msgid "Password requirements not met"
msgstr "" msgstr "Пароль не соответствует требованиям"
#: frappe/core/doctype/user/user.py:1140 #: frappe/core/doctype/user/user.py:1140
msgid "Password reset instructions have been sent to {}'s email" msgid "Password reset instructions have been sent to {}'s email"
@ -28580,7 +28588,7 @@ msgstr "Используйте TLS"
#: frappe/utils/password_strength.py:191 #: frappe/utils/password_strength.py:191
msgid "Use a few uncommon words together." msgid "Use a few uncommon words together."
msgstr "" msgstr "Используйте несколько редких слов вместе."
#: frappe/utils/password_strength.py:44 #: frappe/utils/password_strength.py:44
msgid "Use a few words, avoid common phrases." msgid "Use a few words, avoid common phrases."
@ -29334,7 +29342,7 @@ msgstr "Посмотреть веб-сайт"
#: frappe/core/page/permission_manager/permission_manager.js:395 #: frappe/core/page/permission_manager/permission_manager.js:395
msgid "View all {0} users" msgid "View all {0} users"
msgstr "" msgstr "Просмотреть всех {0} пользователей"
#: frappe/www/confirm_workflow_action.html:12 #: frappe/www/confirm_workflow_action.html:12
msgid "View document" msgid "View document"
@ -29456,7 +29464,7 @@ msgstr "Предупреждение: Обновление счетчика мо
#: frappe/core/doctype/doctype/doctype.py:458 #: frappe/core/doctype/doctype/doctype.py:458
msgid "Warning: Usage of 'format:' is discouraged." msgid "Warning: Usage of 'format:' is discouraged."
msgstr "" msgstr "Внимание: использование конструкции 'format:' не рекомендуется."
#: frappe/website/doctype/help_article/templates/help_article.html:24 #: frappe/website/doctype/help_article/templates/help_article.html:24
msgid "Was this article helpful?" msgid "Was this article helpful?"
@ -30472,7 +30480,7 @@ msgstr "Вы можете задать только 3 пользовательс
#: frappe/handler.py:184 #: frappe/handler.py:184
msgid "You can only upload JPG, PNG, GIF, PDF, TXT, CSV or Microsoft documents." msgid "You can only upload JPG, PNG, GIF, PDF, TXT, CSV or Microsoft documents."
msgstr "" msgstr "Вы можете загружать только документы в форматах JPG, PNG, GIF, PDF, TXT, CSV или Microsoft."
#: frappe/core/doctype/data_export/exporter.py:199 #: frappe/core/doctype/data_export/exporter.py:199
msgid "You can only upload upto 5000 records in one go. (may be less in some cases)" msgid "You can only upload upto 5000 records in one go. (may be less in some cases)"
@ -32285,7 +32293,7 @@ msgstr "{0} недель назад"
#: frappe/core/page/permission_manager/permission_manager.js:378 #: frappe/core/page/permission_manager/permission_manager.js:378
msgid "{0} with the role <strong>{1}</strong>" msgid "{0} with the role <strong>{1}</strong>"
msgstr "" msgstr "{0} с ролью <strong>{1}</strong>"
#: frappe/public/js/frappe/utils/pretty_date.js:39 #: frappe/public/js/frappe/utils/pretty_date.js:39
msgid "{0} y" msgid "{0} y"

View file

@ -88,15 +88,17 @@ frappe.ui.form.PrintView = class {
icon: "refresh", icon: "refresh",
}); });
if (frappe.is_mobile()) {
this.page.add_button(__("Form"), () => this.go_to_form_view(), { icon: "small-file" });
} else {
this.page.add_action_icon( this.page.add_action_icon(
"es-line-filetype", "es-line-filetype",
() => { () => this.go_to_form_view(),
this.go_to_form_view();
},
"", "",
__("Form") __("Form")
); );
} }
}
setup_sidebar() { setup_sidebar() {
this.sidebar = this.page.sidebar.addClass("print-preview-sidebar"); this.sidebar = this.page.sidebar.addClass("print-preview-sidebar");

View file

@ -11,7 +11,8 @@ frappe.ui.form.Share = class Share {
} }
render_sidebar() { render_sidebar() {
const shared = this.shared || this.frm.get_docinfo().shared; const shared = this.shared || this.frm.get_docinfo().shared;
const shared_users = shared.filter(Boolean).map((s) => s.user); const has_everyone = shared.some((s) => s && s.everyone);
const shared_users = shared.filter((s) => s && s.user && !s.everyone).map((s) => s.user);
if (this.frm.is_new()) { if (this.frm.is_new()) {
this.parent.find(".share-doc-btn").hide(); this.parent.find(".share-doc-btn").hide();
@ -26,7 +27,7 @@ frappe.ui.form.Share = class Share {
this.shares.empty(); this.shares.empty();
if (!shared_users.length) { if (!shared_users.length && !has_everyone) {
this.shares.hide(); this.shares.hide();
return; return;
} }
@ -36,7 +37,12 @@ frappe.ui.form.Share = class Share {
avatar_group.on("click", () => { avatar_group.on("click", () => {
this.frm.share_doc(); this.frm.share_doc();
}); });
// REDESIGN-TODO: handle "shared with everyone"
if (has_everyone) {
avatar_group.prepend(
frappe.avatar_group(["Everyone"], 1, { align: "left", overlap: true })
);
}
this.shares.append(avatar_group); this.shares.append(avatar_group);
} }
show() { show() {

View file

@ -318,9 +318,12 @@ frappe.ui.form.Toolbar = class Toolbar {
this.page.clear_menu(); this.page.clear_menu();
if (frappe.boot.desk_settings.form_sidebar) { if (frappe.boot.desk_settings.form_sidebar) {
// this.make_navigation();
this.make_menu_items(); this.make_menu_items();
} }
if (frappe.boot.desk_settings.form_navigation_buttons) {
this.make_navigation();
}
} }
make_navigation() { make_navigation() {

View file

@ -770,6 +770,7 @@ frappe.ui.Page = class Page {
if (icon) { if (icon) {
title = `${frappe.utils.icon(icon)} ${title}`; title = `${frappe.utils.icon(icon)} ${title}`;
} }
let title_wrapper = this.$title_area.find(".title-text"); let title_wrapper = this.$title_area.find(".title-text");
title_wrapper.html(title); title_wrapper.html(title);
title_wrapper.attr("title", __(tooltip_label) || this.title); title_wrapper.attr("title", __(tooltip_label) || this.title);

View file

@ -224,7 +224,8 @@ frappe.breadcrumbs = {
if (docname.startsWith("new-" + doctype.toLowerCase().replace(/ /g, "-"))) { if (docname.startsWith("new-" + doctype.toLowerCase().replace(/ /g, "-"))) {
docname_title = __("New {0}", [__(doctype)]); docname_title = __("New {0}", [__(doctype)]);
} else { } else {
docname_title = doc.name; let title = frappe.model.get_doc_title(doc);
docname_title = title || doc.name;
} }
this.append_breadcrumb_element(form_route, docname_title, "title-text-form"); this.append_breadcrumb_element(form_route, docname_title, "title-text-form");
@ -238,7 +239,12 @@ frappe.breadcrumbs = {
last_crumb.css("cursor", "copy"); last_crumb.css("cursor", "copy");
last_crumb.click((event) => { last_crumb.click((event) => {
event.stopImmediatePropagation(); event.stopImmediatePropagation();
frappe.utils.copy_to_clipboard(last_crumb.text()); frappe.utils.copy_to_clipboard(doc.name);
});
last_crumb.attr("title", __("Click to copy name"));
last_crumb.tooltip({
delay: { show: 100, hide: 100 },
trigger: "hover",
}); });
} }
}, },

View file

@ -166,7 +166,7 @@
} }
.nav-item { .nav-item {
margin-left: 0px; margin-left: -5px;
} }
} }

View file

@ -47,6 +47,8 @@ class TestSQLiteSearchAPI(IntegrationTestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
super().setUpClass() super().setUpClass()
frappe.db.delete("Note")
frappe.db.delete("ToDo")
cls.search = TestSQLiteSearch() cls.search = TestSQLiteSearch()
# Clean up any existing test database # Clean up any existing test database
cls.search.drop_index() cls.search.drop_index()

View file

@ -109,9 +109,10 @@ def get_error_metadata() -> str:
metadata["form_dict"] = sanitized_dict(frappe.form_dict) metadata["form_dict"] = sanitized_dict(frappe.form_dict)
metadata["user"] = getattr(frappe.session, "user", "Unidentified") metadata["user"] = getattr(frappe.session, "user", "Unidentified")
finally: except Exception:
# We don't want to bother with exception handling *while* gathering some error's metadata # We don't want to bother with exception handling *while* gathering some error's metadata
return frappe.as_json(metadata) # noqa: B012 pass
return frappe.as_json(metadata)
def log_error_snapshot(exception: Exception): def log_error_snapshot(exception: Exception):

View file

@ -113,7 +113,7 @@
"type": "Link" "type": "Link"
}, },
{ {
"child": 0, "child": 1,
"collapsible": 1, "collapsible": 1,
"icon": "settings", "icon": "settings",
"indent": 0, "indent": 0,
@ -125,7 +125,7 @@
"type": "Link" "type": "Link"
}, },
{ {
"child": 0, "child": 1,
"collapsible": 1, "collapsible": 1,
"icon": "list", "icon": "list",
"indent": 0, "indent": 0,
@ -137,7 +137,7 @@
"type": "Link" "type": "Link"
}, },
{ {
"child": 0, "child": 1,
"collapsible": 1, "collapsible": 1,
"icon": "list", "icon": "list",
"indent": 0, "indent": 0,
@ -149,7 +149,7 @@
"type": "Link" "type": "Link"
} }
], ],
"modified": "2025-12-18 17:22:26.558605", "modified": "2025-12-29 23:46:47.024937",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Integrations", "module": "Integrations",
"name": "Integrations", "name": "Integrations",