Merge branch 'develop' into move-notification-to-sidebar

This commit is contained in:
Ejaaz Khan 2025-12-04 11:30:19 +05:30 committed by GitHub
commit c5dca5e0b9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 82 additions and 52 deletions

View file

@ -41,9 +41,9 @@
.desktop-navbar-modal-search{
background-color: var(--control-bg);
border-radius: var(--border-radius-sm);
padding: 6px 10px;
width: 100%;
border-radius: var(--border-radius-sm);
padding: 6px 10px;
width: 100%;
}
#brand-logo{
width: auto;

View file

@ -16,7 +16,7 @@
>
<span class="desktop-search-icon">
<svg class="icon icon-sm"><use href="#icon-search"></use></svg>
Search
{{ _("Search") }}
</span>
<span>
{{ "⌘ K" if is_mac else "Ctrl K" }}

View file

@ -44,7 +44,6 @@ def search_link(
reference_doctype: str | None = None,
ignore_user_permissions: bool = False,
*,
form_doctype: str | None = None,
link_fieldname: str | None = None,
) -> list[LinkSearchResults]:
results = search_widget(
@ -56,7 +55,6 @@ def search_link(
filters=filters,
reference_doctype=reference_doctype,
ignore_user_permissions=ignore_user_permissions,
form_doctype=form_doctype,
link_fieldname=link_fieldname,
)
return build_for_autosuggest(results, doctype=doctype)
@ -77,18 +75,15 @@ def search_widget(
reference_doctype: str | None = None,
ignore_user_permissions: bool = False,
*,
form_doctype: str | None = None,
link_fieldname: str | None = None,
):
if ignore_user_permissions:
if form_doctype and link_fieldname:
validate_ignore_user_permissions(form_doctype, link_fieldname, doctype)
if reference_doctype and link_fieldname:
validate_ignore_user_permissions(reference_doctype, link_fieldname, doctype)
else:
frappe.logger().error(
"setting ignore_user_permissions=True in search_link requires "
"form_doctype and link_fieldname to be set. "
f"Got form_doctype={form_doctype}, link_fieldname={link_fieldname}. "
"Ignoring flag."
"setting ignore_user_permissions=True requires reference_doctype and link_fieldname to be set. "
f"Got reference_doctype={reference_doctype}, link_fieldname={link_fieldname}. Ignoring flag."
)
ignore_user_permissions = False
@ -122,7 +117,6 @@ def search_widget(
as_dict=as_dict,
reference_doctype=reference_doctype,
ignore_user_permissions=ignore_user_permissions,
form_doctype=form_doctype,
link_fieldname=link_fieldname,
)
except (frappe.PermissionError, frappe.AppNotInstalledError, ImportError):

View file

@ -359,7 +359,6 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat
ignore_user_permissions: this.df.ignore_user_permissions,
reference_doctype: this.get_reference_doctype() || "",
page_length: cint(frappe.boot.sysdefaults?.link_field_results_limit) || 10,
form_doctype: this.doctype,
link_fieldname: this.df.fieldname,
};

View file

@ -14,7 +14,14 @@ frappe.ui.menu = class ContextMenu {
this.template.empty();
this.menu_items.forEach((f) => {
this.add_menu_item(f);
f.condition =
f.condition ||
function () {
return true;
};
if (f.condition()) {
this.add_menu_item(f);
}
});
// if (!$.contains(document.body, this.template[0])) {

View file

@ -217,6 +217,7 @@ frappe.ui.Sidebar = class Sidebar {
if (items && items.length > 0) {
items.forEach((w) => {
if (!w.display_depends_on || frappe.utils.eval(w.display_depends_on)) {
w.label = __(w.label);
this.add_item(this.$items_container, w);
}
});
@ -234,8 +235,9 @@ frappe.ui.Sidebar = class Sidebar {
}
add_standard_items(items) {
if (this.standard_items_setup) return;
this.standard_items = [
{
this.standard_items = [];
if (!frappe.is_mobile()) {
this.standard_items.push({
label: "Search",
icon: "search",
type: "Button",
@ -244,7 +246,9 @@ frappe.ui.Sidebar = class Sidebar {
keyboard_shortcut: "CtrlK",
},
class: "navbar-search-bar hidden",
},
});
}
this.standard_items.push(
{
label: "Notification",
icon: "bell",
@ -256,8 +260,8 @@ frappe.ui.Sidebar = class Sidebar {
this.wrapper.removeClass("expanded");
}
},
},
];
}
);
this.standard_items.forEach((w) => {
this.add_item(this.$standard_items_sections, w);
});

View file

@ -5,13 +5,16 @@ frappe.ui.SidebarHeader = class SidebarHeader {
this.drop_down_expanded = false;
this.title = this.sidebar.sidebar_title;
const me = this;
this.fetch;
this.sibling_workspaces = this.fetch_sibling_workspaces();
this.dropdown_items = [
{
name: "workspaces",
label: "Workspaces",
icon: "wallpaper",
items: this.fetch_sibling_workspaces(),
condition: function () {
return me.sibling_workspaces.length > 0;
},
items: this.sibling_workspaces,
},
{
name: "desktop",
@ -46,18 +49,23 @@ frappe.ui.SidebarHeader = class SidebarHeader {
}
fetch_sibling_workspaces() {
let sibling_workspaces = [];
let workspaces = frappe.current_app.workspaces;
workspaces.splice(workspaces.indexOf(this.title), 1);
workspaces.forEach((w) => {
let item = {
name: w.toLowerCase(),
label: w,
icon: "wallpaper",
url: frappe.utils.generate_route({ type: "Workspace", route: w.toLowerCase() }),
};
sibling_workspaces.push(item);
});
return sibling_workspaces;
if (frappe.current_app) {
let workspaces = [...frappe.current_app.workspaces];
workspaces.splice(workspaces.indexOf(this.title), 1);
workspaces.forEach((w) => {
let item = {
name: w.toLowerCase(),
label: w,
icon: "wallpaper",
url: frappe.utils.generate_route({
type: "Workspace",
route: w.toLowerCase(),
}),
};
sibling_workspaces.push(item);
});
return sibling_workspaces;
}
}
make() {
$(".sidebar-header").remove();

View file

@ -21,8 +21,10 @@
</div>
{% } else { %}
<a
href="{{ path }}"
target="{%= item.link_type === "URL" ? "_blank" : "" %}"
{% if (path) { %}
href="{{ path }}"
target="{%= item.link_type === "URL" ? "_blank" : "" %}"
{% } %}
class="item-anchor"
>
{% let icon = item.icon %}

View file

@ -10,6 +10,21 @@
</a>
<ul class="nav navbar-nav d-none d-sm-flex" id="navbar-breadcrumbs"></ul>
<div class="collapse navbar-collapse justify-content-end">
{% if frappe.is_mobile() %}
<div class="search-bar text-muted hidden">
<div
id="navbar-modal-search"
class="navbar-modal-search-mobile"
placeholder="Search for type a command"
>
<span class="search-icon">
<svg class="icon icon-sm"><use href="#icon-search"></use></svg>
{{ __("Search") }}
</span>
<span>{%= frappe.utils.is_mac() ? '⌘ + K' : 'Ctrl + K' %}</span>
</div>
</div>
{% endif %}
<ul class="navbar-nav">
<li class="nav-item dropdown dropdown-message dropdown-mobile hidden">
<button

View file

@ -54,14 +54,7 @@
svg {
stroke: var(--text-light);
}
.search-icon {
position: absolute;
margin-left: 12px;
display: flex;
align-items: center;
height: 100%;
margin-bottom: 2px;
}
.awesomplete {
width: 100%;
@ -88,6 +81,14 @@
color: var(--text-light);
}
}
.navbar-modal-search-mobile {
background-color: var(--control-bg);
border-radius: var(--border-radius-sm);
padding: 6px 10px;
width: 100%;
display: flex;
justify-content: space-between;
}
}
.navbar-modal-wrapper {

View file

@ -261,25 +261,25 @@ class TestSearch(IntegrationTestCase):
self.assertIn(allowed_doc.name, result_values)
self.assertNotIn(restricted_doc.name, result_values)
# With ignore_user_permissions + form_doctype + link_fieldname, both should be returned
# With ignore_user_permissions + reference_doctype + link_fieldname, both should be returned
results_with_ignore = search_link(
doctype="Test Search Linked",
txt="Document",
ignore_user_permissions=True,
form_doctype="Test Search Form",
reference_doctype="Test Search Form",
link_fieldname="linked_doc",
)
result_values = [r["value"] for r in results_with_ignore]
self.assertIn(allowed_doc.name, result_values)
self.assertIn(restricted_doc.name, result_values)
# With ignore_user_permissions=True but WITHOUT form_doctype/link_fieldname,
# With ignore_user_permissions=True but WITHOUT reference_doctype/link_fieldname,
# the flag should be silently ignored and user permissions should apply
results_without_context = search_link(
doctype="Test Search Linked",
txt="Document",
ignore_user_permissions=True,
# form_doctype and link_fieldname not provided
# reference_doctype and link_fieldname not provided
)
result_values = [r["value"] for r in results_without_context]
self.assertIn(allowed_doc.name, result_values)
@ -334,7 +334,7 @@ class TestSearch(IntegrationTestCase):
doctype="Test Search Linked2",
txt="test",
ignore_user_permissions=True,
form_doctype="Test Search Form No Ignore",
reference_doctype="Test Search Form No Ignore",
link_fieldname="linked_doc",
)
@ -345,7 +345,7 @@ class TestSearch(IntegrationTestCase):
doctype="Test Search Linked2",
txt="test",
ignore_user_permissions=True,
form_doctype="Test Search Form No Ignore",
reference_doctype="Test Search Form No Ignore",
link_fieldname="nonexistent_field",
)
@ -370,7 +370,7 @@ class TestSearch(IntegrationTestCase):
doctype="Test Search Linked2",
txt="test",
ignore_user_permissions=True,
form_doctype="Test Search Form Wrong Link",
reference_doctype="Test Search Form Wrong Link",
link_fieldname="wrong_link",
)