Merge pull request #35086 from iamejaaz/move-help-dropdown

feat: move help to sidebar
This commit is contained in:
Ejaaz Khan 2025-12-06 01:25:20 +05:30 committed by GitHub
commit 5d4e56c0a8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 109 additions and 167 deletions

View file

@ -6,7 +6,8 @@ const jump_to_field = (field_label) => {
.wait(500)
.type("{enter}")
.wait(200)
.type("{enter}")
.findByRole("button", { name: "Go" })
.click()
.wait(1000);
};
@ -99,9 +100,7 @@ context("Form", () => {
cy.new_form("User");
jump_to_field("Location"); // this is in collapsed section
cy.wait(500);
type_value("Bermuda");
cy.wait(500);
cy.get_field("location").should("have.value", "Bermuda");
});

View file

@ -2,18 +2,24 @@ context("List View Settings", () => {
beforeEach(() => {
cy.login();
cy.visit("/desk/website");
cy.visit("/desk/List/DocType/List");
cy.wait(300);
cy.clear_filters();
cy.wait(300);
cy.get(".menu-btn-group button").click({ force: true });
cy.get(".dropdown-menu li").filter(":visible").contains("List Settings").click();
cy.get(".modal-dialog").should("contain", "DocType List View Settings");
cy.findByLabelText("Disable Count").uncheck({ force: true });
cy.findByLabelText("Disable Comment Count").uncheck({ force: true });
cy.findByLabelText("Disable Sidebar Stats").uncheck({ force: true });
cy.findByRole("button", { name: "Save" }).click();
cy.reload({ force: true });
});
it("Default settings", () => {
cy.visit("/desk/List/DocType/List");
cy.clear_filters();
cy.get(".list-count").should("contain", "20 of");
cy.get(".list-stats").should("contain", "Tags");
});
it("disable count and sidebar stats then verify", () => {
cy.wait(300);
cy.visit("/desk/List/DocType/List");
cy.clear_filters();
cy.wait(300);
cy.get(".list-count").should("contain", "20 of");
cy.get(".frappe-list svg.es-icon.es-line").should("be.visible");
cy.get(".menu-btn-group button").click();
@ -29,7 +35,7 @@ context("List View Settings", () => {
cy.get(".list-count").should("be.empty");
cy.get(".list-sidebar .list-tags").should("not.exist");
cy.get("[href='#es-line-chat-alt']").should("not.be.visible");
cy.get("[href='#es-line-chat-alt']").should("not.exist");
cy.get(".menu-btn-group button").click({ force: true });
cy.get(".dropdown-menu li").filter(":visible").contains("List Settings").click();

View file

@ -31,37 +31,46 @@ frappe.ui.menu = class ContextMenu {
}
add_menu_item(item) {
const me = this;
let item_wrapper = $(`<div class="dropdown-menu-item">
<a>
<div class="menu-item-icon">
${
item.icon
? frappe.utils.icon(item.icon)
: `<img
class="logo"
src="${item.icon_url}"
>`
}
</div>
<span class="menu-item-title">${item.label}</span>
<div class="menu-item-icon" style="margin-left:auto">
${item.items && item.items.length ? frappe.utils.icon("chevron-right") : ""}
</div>
</a>
</div>`);
if (!item.url) {
item_wrapper.on("click", function () {
item.onClick && item.onClick();
if (!(item.items && item.items.length)) {
me.opts.onItemClick && me.opts.onItemClick(me.opts.parent);
me.hide();
}
});
} else if (item.items) {
$();
let item_wrapper = $(
`<div class="dropdown-menu-item"><div class="dropdown-divider documentation-links"></div></div>`
);
if (item?.is_divider) {
item_wrapper = $(
`<div class="dropdown-menu-item"><div class="dropdown-divider documentation-links"></div></div>`
);
} else {
$(item_wrapper).find("a").attr("href", item.url);
item_wrapper = $(`<div class="dropdown-menu-item">
<a>
<div class="menu-item-icon" ${!(item.icon || item.icon_url) ? "hidden" : ""}>
${
item.icon
? frappe.utils.icon(item.icon)
: `<img
class="logo"
src="${item.icon_url}"
>`
}
</div>
<span class="menu-item-title">${item.label}</span>
<div class="menu-item-icon" style="margin-left:auto">
${item.items && item.items.length ? frappe.utils.icon("chevron-right") : ""}
</div>
</a>
</div>`);
if (!item.url) {
item_wrapper.on("click", function () {
item.onClick && item.onClick();
if (!(item.items && item.items.length)) {
me.opts.onItemClick && me.opts.onItemClick(me.opts.parent);
me.hide();
}
});
} else if (item.items) {
$();
} else {
$(item_wrapper).find("a").attr("href", item.url);
}
}
item_wrapper.appendTo(this.template);
if (item.items) {

View file

@ -42,6 +42,14 @@ frappe.ui.SidebarHeader = class SidebarHeader {
},
},
];
if (frappe.boot.desk_settings.notifications) {
this.dropdown_items.push({
name: "help",
label: "Help",
icon: "info",
items: this.get_help_siblings(),
});
}
this.make();
this.setup_app_switcher();
this.populate_dropdown_menu();
@ -67,6 +75,51 @@ frappe.ui.SidebarHeader = class SidebarHeader {
return sibling_workspaces;
}
}
get_help_siblings() {
const navbar_settings = frappe.boot.navbar_settings;
let help_dropdown_items = [];
let custom_help_links = this.get_custom_help_links();
help_dropdown_items = custom_help_links.concat(help_dropdown_items);
navbar_settings.help_dropdown.forEach((element) => {
let dropdown_children = {
name: element.name,
label: element.item_label,
};
if (element.item_type === "Route") {
dropdown_children.url = element.route;
}
if (element.item_type === "Action") {
dropdown_children.onClick = function () {
frappe.utils.eval(element.action);
};
}
help_dropdown_items.push(dropdown_children);
});
return help_dropdown_items;
}
get_custom_help_links() {
let route = frappe.get_route_str();
let breadcrumbs = route.split("/");
let links = [];
for (let i = 0; i < breadcrumbs.length; i++) {
let r = route.split("/", i + 1);
let key = r.join("/");
let help_links = frappe.help.help_links[key] || [];
links = $.merge(links, help_links);
}
if (links.length) {
links.push({ is_divider: true });
}
return links;
}
make() {
$(".sidebar-header").remove();
$(".sidebar-header-menu").remove();

View file

@ -24,51 +24,6 @@
</div>
{% endif %}
<ul class="navbar-nav">
<li class="nav-item dropdown dropdown-message dropdown-mobile hidden">
<button
class="btn-reset nav-link notifications-icon text-muted"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="true"
>
<span>
<svg class="es-icon icon-sm"><use href="#es-line-chat-alt"></use></svg>
</span>
</button>
</li>
<li class="vertical-bar d-none d-sm-block"></li>
<li class="nav-item dropdown dropdown-help dropdown-mobile d-none d-lg-block">
<button
class="btn-reset nav-link"
data-toggle="dropdown"
aria-controls="toolbar-help"
aria-label="{{ __("Help Dropdown") }}"
>
<span>
{{ __("Help") }}
<svg class="es-icon icon-xs"><use href="#es-line-down"></use></svg>
</span>
</button>
<div class="dropdown-menu dropdown-menu-right" id="toolbar-help" role="menu">
<div id="help-links"></div>
<div class="dropdown-divider documentation-links"></div>
{% for item in navbar_settings.help_dropdown %}
{% if (!item.hidden) { %}
{% if (item.route) { %}
<a class="dropdown-item" href="{{ item.route }}">
{%= __(item.item_label) %}
</a>
{% } else if (item.action) { %}
<button class="btn-reset dropdown-item" onclick="return {{ item.action }}">
{%= __(item.item_label) %}
</button>
{% } else { %}
<div class="dropdown-divider"></div>
{% } %}
{% } %}
{% endfor %}
</div>
</li>
<li class="nav-item dropdown dropdown-navbar-user dropdown-mobile">
<button
class="btn-reset nav-link"

View file

@ -18,7 +18,6 @@ frappe.ui.toolbar.Toolbar = class {
});
// this.setup_awesomebar();
this.setup_help();
this.setup_read_only_mode();
this.setup_announcement_widget();
this.make();
@ -99,87 +98,6 @@ frappe.ui.toolbar.Toolbar = class {
}
}
setup_help() {
if (!frappe.boot.desk_settings.notifications) {
// hide the help section
$(".navbar .vertical-bar").removeClass("d-sm-block");
$(".dropdown-help").removeClass("d-lg-block");
return;
}
frappe.provide("frappe.help");
frappe.help.show_results = show_results;
this.search = new frappe.search.SearchDialog();
frappe.provide("frappe.searchdialog");
frappe.searchdialog.search = this.search;
$(".dropdown-help .dropdown-toggle").on("click", function () {
$(".dropdown-help input").focus();
});
$(".dropdown-help .dropdown-menu").on("click", "input, button", function (e) {
e.stopPropagation();
});
$("#input-help").on("keydown", function (e) {
if (e.which == 13) {
$(this).val("");
}
});
$(document).on("page-change", function () {
var $help_links = $(".dropdown-help #help-links");
$help_links.html("");
var route = frappe.get_route_str();
var breadcrumbs = route.split("/");
var links = [];
for (let i = 0; i < breadcrumbs.length; i++) {
var r = route.split("/", i + 1);
var key = r.join("/");
var help_links = frappe.help.help_links[key] || [];
links = $.merge(links, help_links);
}
if (links.length === 0) {
$help_links.next().hide();
} else {
$help_links.next().show();
}
for (let i = 0; i < links.length; i++) {
var link = links[i];
var url = link.url;
$("<a>", {
href: url,
class: "dropdown-item",
text: __(link.label),
target: "_blank",
}).appendTo($help_links);
}
$(".dropdown-help .dropdown-menu").on("click", "a", show_results);
});
var $result_modal = frappe.get_modal("", "");
$result_modal.addClass("help-modal");
$(document).on("click", ".help-modal a", show_results);
function show_results(e) {
//edit links
var href = e.target.href;
if (href.indexOf("blob") > 0) {
window.open(href, "_blank");
}
var path = $(e.target).attr("data-path");
if (path) {
e.preventDefault();
}
}
}
add_back_button() {
if (!frappe.is_mobile()) return;
this.navbar = $(".navbar-brand");

View file

@ -157,12 +157,14 @@
}
.standard-items-sections {
margin-top: 14px;
.navbar-search-bar {
background-color: var(--control-bg-on-gray);
border-radius: var(--border-radius);
padding-right: 7px;
.standard-sidebar-item a:hover {
background-color: var(--control-bg-on-gray);
border-radius: var(--border-radius);
}
}
.dropdown-notifications {