Merge branch 'develop' into capture-client-events
This commit is contained in:
commit
efc236ef37
14 changed files with 109 additions and 46 deletions
|
|
@ -6,18 +6,32 @@ def execute():
|
|||
batch_size = 10_000
|
||||
|
||||
while True:
|
||||
frappe.db.sql(
|
||||
"""
|
||||
update `tabCommunication Link` cl
|
||||
inner join `tabCommunication` c on cl.parent = c.name
|
||||
set cl.communication_date = c.communication_date
|
||||
where cl.communication_date is null
|
||||
and c.communication_date is not null
|
||||
limit %s
|
||||
""",
|
||||
frappe.db.multisql(
|
||||
{
|
||||
"mariadb": """
|
||||
update `tabCommunication Link` cl
|
||||
inner join `tabCommunication` c on cl.parent = c.name
|
||||
set cl.communication_date = c.communication_date
|
||||
where cl.communication_date is null
|
||||
and c.communication_date is not null
|
||||
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,),
|
||||
)
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
if not frappe.db.sql(
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
"view_switcher",
|
||||
"form_settings_section",
|
||||
"form_sidebar",
|
||||
"form_navigation_buttons",
|
||||
"timeline",
|
||||
"dashboard",
|
||||
"show_absolute_datetime_in_timeline",
|
||||
|
|
@ -850,6 +851,12 @@
|
|||
"is_virtual": 1,
|
||||
"label": "Active Sessions",
|
||||
"options": "User Session Display"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "form_navigation_buttons",
|
||||
"fieldtype": "Check",
|
||||
"label": "Navigation Buttons"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-user",
|
||||
|
|
@ -903,7 +910,7 @@
|
|||
}
|
||||
],
|
||||
"make_attachments_public": 1,
|
||||
"modified": "2025-12-13 12:53:46.486021",
|
||||
"modified": "2026-01-02 16:00:51.406511",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "User",
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ desk_properties = (
|
|||
"bulk_actions",
|
||||
"view_switcher",
|
||||
"form_sidebar",
|
||||
"form_navigation_buttons",
|
||||
"timeline",
|
||||
"dashboard",
|
||||
)
|
||||
|
|
@ -96,6 +97,7 @@ class User(Document):
|
|||
follow_created_documents: DF.Check
|
||||
follow_liked_documents: DF.Check
|
||||
follow_shared_documents: DF.Check
|
||||
form_navigation_buttons: DF.Check
|
||||
form_sidebar: DF.Check
|
||||
full_name: DF.Data | None
|
||||
gender: DF.Link | None
|
||||
|
|
|
|||
|
|
@ -446,9 +446,20 @@
|
|||
bottom: 4%;
|
||||
right: 4%;
|
||||
z-index: 100;
|
||||
opacity: 0.1;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.desktop-edit:hover{
|
||||
opacity: 1;
|
||||
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;
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ msgstr ""
|
|||
"Project-Id-Version: frappe\n"
|
||||
"Report-Msgid-Bugs-To: developers@frappe.io\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"
|
||||
"Language-Team: Russian\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"
|
||||
"<br>\n"
|
||||
"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'
|
||||
#: frappe/website/doctype/web_page/web_page.json
|
||||
|
|
@ -1466,7 +1474,7 @@ msgstr "Добавить новую вкладку"
|
|||
|
||||
#: frappe/utils/password_strength.py:191
|
||||
msgid "Add numbers or special characters."
|
||||
msgstr ""
|
||||
msgstr "Добавьте цифры или специальные символы."
|
||||
|
||||
#: frappe/public/js/print_format_builder/PrintFormatSection.vue:125
|
||||
msgid "Add page break"
|
||||
|
|
@ -5217,7 +5225,7 @@ msgstr "Распространенные имена и фамилии легко
|
|||
|
||||
#: frappe/utils/password_strength.py:190
|
||||
msgid "Common words are easy to guess."
|
||||
msgstr ""
|
||||
msgstr "Общие слова легко угадать."
|
||||
|
||||
#. Name of a DocType
|
||||
#. Option for the 'Communication Type' (Select) field in DocType
|
||||
|
|
@ -5912,7 +5920,7 @@ msgstr "Создать новую Канбан доску"
|
|||
|
||||
#: frappe/public/js/frappe/list/list_filter.js:101
|
||||
msgid "Create Saved Filter"
|
||||
msgstr ""
|
||||
msgstr "Создать сохраненный фильтр"
|
||||
|
||||
#: frappe/core/doctype/user/user.js:271
|
||||
msgid "Create User Email"
|
||||
|
|
@ -12025,7 +12033,7 @@ msgstr "Помощь HTML"
|
|||
#. Description of the 'Content' (Text Editor) field in DocType 'Note'
|
||||
#: 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://\")"
|
||||
msgstr ""
|
||||
msgstr "Помощь: Для ссылки на другую запись в системе используйте \"/desk/note/[Имя заметки]\" в качестве ссылки (не используйте \"http://\")"
|
||||
|
||||
#. Label of the helpful (Int) field in DocType 'Help Article'
|
||||
#: frappe/website/doctype/help_article/help_article.json
|
||||
|
|
@ -17498,7 +17506,7 @@ msgstr "Не найден шаблон по пути: {0}"
|
|||
|
||||
#: frappe/core/page/permission_manager/permission_manager.js:362
|
||||
msgid "No user has the role <strong>{0}</strong>"
|
||||
msgstr ""
|
||||
msgstr "Нет пользователя с ролью <strong>{0}</strong>"
|
||||
|
||||
#: frappe/public/js/frappe/form/controls/multiselect_list.js:276
|
||||
msgid "No values to show"
|
||||
|
|
@ -19124,7 +19132,7 @@ msgstr "Пароль не найден для {0} {1} {2}"
|
|||
|
||||
#: frappe/core/doctype/user/user.py:1307
|
||||
msgid "Password requirements not met"
|
||||
msgstr ""
|
||||
msgstr "Пароль не соответствует требованиям"
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1140
|
||||
msgid "Password reset instructions have been sent to {}'s email"
|
||||
|
|
@ -28580,7 +28588,7 @@ msgstr "Используйте TLS"
|
|||
|
||||
#: frappe/utils/password_strength.py:191
|
||||
msgid "Use a few uncommon words together."
|
||||
msgstr ""
|
||||
msgstr "Используйте несколько редких слов вместе."
|
||||
|
||||
#: frappe/utils/password_strength.py:44
|
||||
msgid "Use a few words, avoid common phrases."
|
||||
|
|
@ -29334,7 +29342,7 @@ msgstr "Посмотреть веб-сайт"
|
|||
|
||||
#: frappe/core/page/permission_manager/permission_manager.js:395
|
||||
msgid "View all {0} users"
|
||||
msgstr ""
|
||||
msgstr "Просмотреть всех {0} пользователей"
|
||||
|
||||
#: frappe/www/confirm_workflow_action.html:12
|
||||
msgid "View document"
|
||||
|
|
@ -29456,7 +29464,7 @@ msgstr "Предупреждение: Обновление счетчика мо
|
|||
|
||||
#: frappe/core/doctype/doctype/doctype.py:458
|
||||
msgid "Warning: Usage of 'format:' is discouraged."
|
||||
msgstr ""
|
||||
msgstr "Внимание: использование конструкции 'format:' не рекомендуется."
|
||||
|
||||
#: frappe/website/doctype/help_article/templates/help_article.html:24
|
||||
msgid "Was this article helpful?"
|
||||
|
|
@ -30472,7 +30480,7 @@ msgstr "Вы можете задать только 3 пользовательс
|
|||
|
||||
#: frappe/handler.py:184
|
||||
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
|
||||
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
|
||||
msgid "{0} with the role <strong>{1}</strong>"
|
||||
msgstr ""
|
||||
msgstr "{0} с ролью <strong>{1}</strong>"
|
||||
|
||||
#: frappe/public/js/frappe/utils/pretty_date.js:39
|
||||
msgid "{0} y"
|
||||
|
|
|
|||
|
|
@ -88,14 +88,16 @@ frappe.ui.form.PrintView = class {
|
|||
icon: "refresh",
|
||||
});
|
||||
|
||||
this.page.add_action_icon(
|
||||
"es-line-filetype",
|
||||
() => {
|
||||
this.go_to_form_view();
|
||||
},
|
||||
"",
|
||||
__("Form")
|
||||
);
|
||||
if (frappe.is_mobile()) {
|
||||
this.page.add_button(__("Form"), () => this.go_to_form_view(), { icon: "small-file" });
|
||||
} else {
|
||||
this.page.add_action_icon(
|
||||
"es-line-filetype",
|
||||
() => this.go_to_form_view(),
|
||||
"",
|
||||
__("Form")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
setup_sidebar() {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ frappe.ui.form.Share = class Share {
|
|||
}
|
||||
render_sidebar() {
|
||||
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()) {
|
||||
this.parent.find(".share-doc-btn").hide();
|
||||
|
|
@ -26,7 +27,7 @@ frappe.ui.form.Share = class Share {
|
|||
|
||||
this.shares.empty();
|
||||
|
||||
if (!shared_users.length) {
|
||||
if (!shared_users.length && !has_everyone) {
|
||||
this.shares.hide();
|
||||
return;
|
||||
}
|
||||
|
|
@ -36,7 +37,12 @@ frappe.ui.form.Share = class Share {
|
|||
avatar_group.on("click", () => {
|
||||
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);
|
||||
}
|
||||
show() {
|
||||
|
|
|
|||
|
|
@ -318,9 +318,12 @@ frappe.ui.form.Toolbar = class Toolbar {
|
|||
this.page.clear_menu();
|
||||
|
||||
if (frappe.boot.desk_settings.form_sidebar) {
|
||||
// this.make_navigation();
|
||||
this.make_menu_items();
|
||||
}
|
||||
|
||||
if (frappe.boot.desk_settings.form_navigation_buttons) {
|
||||
this.make_navigation();
|
||||
}
|
||||
}
|
||||
|
||||
make_navigation() {
|
||||
|
|
|
|||
|
|
@ -770,6 +770,7 @@ frappe.ui.Page = class Page {
|
|||
if (icon) {
|
||||
title = `${frappe.utils.icon(icon)} ${title}`;
|
||||
}
|
||||
|
||||
let title_wrapper = this.$title_area.find(".title-text");
|
||||
title_wrapper.html(title);
|
||||
title_wrapper.attr("title", __(tooltip_label) || this.title);
|
||||
|
|
|
|||
|
|
@ -224,7 +224,8 @@ frappe.breadcrumbs = {
|
|||
if (docname.startsWith("new-" + doctype.toLowerCase().replace(/ /g, "-"))) {
|
||||
docname_title = __("New {0}", [__(doctype)]);
|
||||
} 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");
|
||||
|
||||
|
|
@ -238,7 +239,12 @@ frappe.breadcrumbs = {
|
|||
last_crumb.css("cursor", "copy");
|
||||
last_crumb.click((event) => {
|
||||
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",
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@
|
|||
}
|
||||
|
||||
.nav-item {
|
||||
margin-left: 0px;
|
||||
margin-left: -5px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ class TestSQLiteSearchAPI(IntegrationTestCase):
|
|||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
frappe.db.delete("Note")
|
||||
frappe.db.delete("ToDo")
|
||||
cls.search = TestSQLiteSearch()
|
||||
# Clean up any existing test database
|
||||
cls.search.drop_index()
|
||||
|
|
|
|||
|
|
@ -109,9 +109,10 @@ def get_error_metadata() -> str:
|
|||
metadata["form_dict"] = sanitized_dict(frappe.form_dict)
|
||||
|
||||
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
|
||||
return frappe.as_json(metadata) # noqa: B012
|
||||
pass
|
||||
return frappe.as_json(metadata)
|
||||
|
||||
|
||||
def log_error_snapshot(exception: Exception):
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@
|
|||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"child": 0,
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"icon": "settings",
|
||||
"indent": 0,
|
||||
|
|
@ -125,7 +125,7 @@
|
|||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"child": 0,
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"icon": "list",
|
||||
"indent": 0,
|
||||
|
|
@ -137,7 +137,7 @@
|
|||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"child": 0,
|
||||
"child": 1,
|
||||
"collapsible": 1,
|
||||
"icon": "list",
|
||||
"indent": 0,
|
||||
|
|
@ -149,7 +149,7 @@
|
|||
"type": "Link"
|
||||
}
|
||||
],
|
||||
"modified": "2025-12-18 17:22:26.558605",
|
||||
"modified": "2025-12-29 23:46:47.024937",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Integrations",
|
||||
"name": "Integrations",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue