Merge pull request #31287 from sokumon/better-sidebar

fix: more sidebar improvements
This commit is contained in:
Soham Kulkarni 2025-02-28 23:54:08 +05:30 committed by GitHub
commit d95386edd8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 126 additions and 40 deletions

View file

@ -41,6 +41,8 @@ describe(
before(() => {
cy.login();
cy.visit(`/app/note/new`);
// close the sidebar cause default is expanded
cy.get(".body-sidebar .collapse-sidebar-link").click();
});
test_button_names.forEach((button_name) => {

View file

@ -417,8 +417,7 @@ Tip: use lucide.svg in /icons for all downloaded icons
</symbol>
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-users">
<path d="M17.727 18.728H20a1 1 0 0 0 1-1v-2.537a.818.818 0 0 0-.515-.76l-3.061-1.226a.819.819 0 0 1-.515-.758v-.718a3.258 3.258 0 0 0 1.636-2.82V7.274a3.272 3.272 0 0 0-4.909-2.835m.304 10.811l-3.062-1.227a.818.818 0 0 1-.514-.758v-.369c2.675-.357 3.272-1.532 3.272-1.532S12 9.728 12 8.092a3.273 3.273 0 1 0-6.545 0c0 1.636-1.637 3.272-1.637 3.272s.597 1.175 3.273 1.532v.37a.818.818 0 0 1-.515.758l-3.061 1.228a.819.819 0 0 0-.515.757v1.72a1 1 0 0 0 1 1h9.454a1 1 0 0 0 1-1v-1.72a.818.818 0 0 0-.514-.759z"
stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M18 21a8 8 0 0 0-16 0" /> <circle cx="10" cy="8" r="5" /> <path d="M22 20c0-3.37-2-6.5-4-8a5 5 0 0 0-.45-8.3" />
</symbol>
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-tool">
@ -545,8 +544,7 @@ Tip: use lucide.svg in /icons for all downloaded icons
</symbol>
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-integration">
<path d="M2.5 20.503l2.218-2.218m1.35-7.717l-1.35 1.35a4.5 4.5 0 1 0 6.364 6.365l1.35-1.35-6.364-6.365zM20.5 2.5l-2.218 2.218m-1.35 7.712l1.35-1.35a4.5 4.5 0 0 0-6.365-6.365l-1.35 1.35 6.365 6.365zM9.7 10.604l-1.8 1.8m4.5.898l-1.8 1.8"
stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="m19 5 3-3" /> <path d="m2 22 3-3" /> <path d="M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z" /> <path d="M7.5 13.5 10 11" /> <path d="M10.5 16.5 13 14" /> <path d="m12 6 6 6 2.3-2.3a2.4 2.4 0 0 0 0-3.4l-2.6-2.6a2.4 2.4 0 0 0-3.4 0Z" />
</symbol>
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-hr">
@ -876,7 +874,6 @@ Tip: use lucide.svg in /icons for all downloaded icons
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-hammer" stroke-linejoin="round">
<path d="m15 12-8.373 8.373a1 1 0 1 1-3-3L12 9"/><path d="m18 15 4-4"/><path d="m21.5 11.5-1.914-1.914A2 2 0 0 1 19 8.172V7l-2.26-2.26a6 6 0 0 0-4.202-1.756L9 2.96l.92.82A6.18 6.18 0 0 1 12 8.4V10l2 2h1.172a2 2 0 0 1 1.414.586L18.5 14.5"/>
</symbol>
<symbol viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" id="icon-help">
<path stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M8.208 8.115v-.099a2.021 2.021 0 0 1 1.114-1.809l.057-.028a1.85 1.85 0 0 1 1.278-.142l.121.03c.623.156 1.1.659 1.223 1.289v0c.04.208.04.421 0 .63l-.029.153a1.805 1.805 0 0 1-.97 1.276l-.2.1a1.446 1.446 0 0 0-.804 1.297v0L10 11.5"/>
<path fill="#20272E" d="M10.307 13.804a.304.304 0 1 1-.607 0 .304.304 0 0 1 .607 0Z"/>

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 86 KiB

View file

@ -3,22 +3,17 @@ frappe.ui.AppsSwitcher = class AppsSwitcher {
this.drop_down_state = false;
this.sidebar_wrapper = sidebar.wrapper;
this.sidebar = sidebar;
this.app_switcher = $(sidebar.app_switcher_dropdown[0]);
this.setup_app_switcher();
this.set_hover();
}
setup_app_switcher() {
this.app_switcher_menu = $(".app-switcher-menu");
$(".app-switcher-dropdown").on("click", () => {
this.set_active();
this.app_switcher_menu.toggleClass("hidden");
});
// hover out of the sidebar move this to sidebar.js
this.sidebar_wrapper.find(".body-sidebar").on("mouseleave", () => {
this.app_switcher_menu.addClass("hidden");
// hide any expanded menus as they leave a blank space in the sidebar
this.sidebar_wrapper.find(".drop-icon[data-state='opened'").click();
});
}
create_app_data_map() {
frappe.boot.app_data_map = {};
@ -152,4 +147,23 @@ frappe.ui.AppsSwitcher = class AppsSwitcher {
// re-render the sidebar
frappe.app.sidebar.make_sidebar();
}
set_hover() {
this.app_switcher.on("mouseover", function (event) {
if ($(this).hasClass("active-sidebar")) return;
$(this).addClass("hover");
if (!this.sidebar.sidebar_expanded) {
$(this).removeClass("hover");
}
});
this.app_switcher.on("mouseleave", function () {
$(this).removeClass("hover");
});
}
set_active() {
this.app_switcher.toggleClass("active-sidebar");
if (!this.sidebar.sidebar_expanded) {
this.app_switcher.removeClass("active-sidebar");
}
}
};

View file

@ -1,6 +1,7 @@
frappe.ui.Sidebar = class Sidebar {
constructor() {
this.items = {};
this.child_items = [];
this.sidebar_expanded = false;
if (!frappe.boot.setup_complete) {
@ -79,16 +80,65 @@ frappe.ui.Sidebar = class Sidebar {
}
set_active_workspace_item() {
if (this.is_route_in_sidebar(decodeURIComponent(window.location.pathname))) {
if (!frappe.get_route()) return;
if (frappe.get_route()[0] == "") return;
let current_route = frappe.get_route();
let doctype = frappe.get_route()[1];
let current_item = doctype;
if (current_route[0] != "Workspaces") {
let meta_info = frappe.get_meta(doctype);
if (meta_info) {
let active_workspace = meta_info.module;
if (meta_info.__workspaces) {
active_workspace = meta_info.__workspaces[0];
}
current_item = active_workspace;
}
}
if (this.is_route_in_sidebar(current_item)) {
this.active_item.addClass("active-sidebar");
}
if (this.active_item) {
if (this.is_nested_item(this.active_item.parent())) {
let current_item = this.active_item.parent();
this.expand_parent_item(current_item);
}
}
}
expand_parent_item(item) {
let parent_title = item.attr("item-parent");
if (!parent_title) return;
let parent = this.get_sidebar_item(parent_title);
$($(parent).children()[1]).removeClass("hidden");
if (parent) {
if (this.is_nested_item($(parent))) {
this.expand_parent_item($(parent));
}
}
}
is_nested_item(item) {
if (item.attr("item-parent")) {
return true;
} else {
return false;
}
}
is_route_in_sidebar(route_name) {
get_sidebar_item(name) {
let sidebar_item = "";
$(".sidebar-item-container").each(function () {
if ($(this).attr("item-name") == name) {
sidebar_item = this;
}
});
return sidebar_item;
}
is_route_in_sidebar(active_module) {
let match = false;
const that = this;
$(".item-anchor").each(function () {
if ($(this).attr("href") == route_name) {
if ($(this).attr("title") == active_module) {
match = true;
if (that.active_item) that.active_item.removeClass("active-sidebar");
that.active_item = $(this).parent();
@ -126,12 +176,19 @@ frappe.ui.Sidebar = class Sidebar {
this.make_sidebar();
}
this.set_hover();
this.set_sidebar_state();
if (!this.sidebar_expanded) this.close_children_item();
}
set_sidebar_state() {
this.sidebar_expanded = true;
if (localStorage.getItem("sidebar-expanded") !== null) {
this.sidebar_expanded = JSON.parse(localStorage.getItem("sidebar-expanded"));
this.expand_sidebar();
}
if (frappe.is_mobile()) {
this.sidebar_expanded = false;
}
this.expand_sidebar();
}
make_sidebar() {
if (this.wrapper.find(".standard-sidebar-section")[0]) {
this.wrapper.find(".standard-sidebar-section").remove();
@ -242,6 +299,7 @@ frappe.ui.Sidebar = class Sidebar {
let child_container = $item_container.find(".sidebar-child-item");
child_container.addClass("hidden");
this.prepare_sidebar(child_items, child_container, $item_container);
this.child_items.push(child_container);
}
$item_container.appendTo(container);
@ -394,10 +452,18 @@ frappe.ui.Sidebar = class Sidebar {
close_sidebar() {
this.sidebar_expanded = false;
this.expand_sidebar();
this.close_children_item();
}
open_sidebar() {
this.sidebar_expanded = true;
this.expand_sidebar();
this.set_active_workspace_item();
}
close_children_item() {
this.child_items.forEach((i) => {
i.addClass("hidden");
});
}
reload() {
@ -406,4 +472,9 @@ frappe.ui.Sidebar = class Sidebar {
this.setup_pages();
});
}
set_height() {
$(".body-sidebar").css("height", window.innerHeight + "px");
$(".overlay").css("height", window.innerHeight + "px");
document.body.style.overflow = "hidden";
}
};

View file

@ -29,6 +29,7 @@ frappe.ui.toolbar.Toolbar = class {
this.bind_events();
$(document).trigger("toolbar_setup");
$(".navbar-brand .app-logo").on("click", () => {
frappe.app.sidebar.set_height();
frappe.app.sidebar.toggle_sidebar();
});
}

View file

@ -9,7 +9,9 @@
background-position: 50% 50%;
fill: var(--icon-fill);
stroke: var(--icon-stroke);
stroke-width: 1.25px;
stroke-width: 1.5px;
stroke-linecap: round;
stroke-linejoin: round;
}
.es-icon {

View file

@ -6,6 +6,7 @@
--surface-modal: rgba(255, 255, 255, 1);
--divider-color: rgba(237, 237, 237, 1);
--sidebar-width: 220px;
--left-sidebar-width: 240px;
}
[data-theme="dark"] {
--sidebar-hover-color: rgba(43, 43, 43, 1);
@ -122,7 +123,7 @@ body {
}
.sidebar-items {
width: 204px;
width: 224px;
padding-left: 1px;
padding-right: 1px;
width: 100%;
@ -172,7 +173,7 @@ body {
}
svg {
margin: -1px;
margin: -2px;
}
}
@ -248,17 +249,17 @@ body {
.body-sidebar {
// make it an overlay on hover
position: absolute;
width: var(--sidebar-width);
width: var(--left-sidebar-width);
.app-switcher-dropdown {
width: 204px;
width: 224px;
left: 0px;
padding: 2px 0px 2px 3px;
padding: 3px;
}
.body-sidebar-top {
width: 204px;
width: 224px;
overflow-y: hidden;
.app-switcher-dropdown {
width: 204px;
width: 224px;
}
}
.sidebar-item-container {
@ -279,7 +280,7 @@ body {
visibility: visible;
}
.body-sidebar-bottom {
width: var(--sidebar-width);
width: 224px;
position: static;
}
}
@ -287,7 +288,7 @@ body {
// show placeholder so that main section remains static
.body-sidebar-placeholder {
display: flex;
width: var(--sidebar-width);
width: var(--left-sidebar-width);
}
}
@ -310,7 +311,7 @@ body {
position: relative;
.body-sidebar {
padding: 8px 8px 10px 8px;
width: var(--sidebar-width);
width: var(--left-sidebar-width);
height: 100%;
position: absolute;
bottom: 0;
@ -319,10 +320,10 @@ body {
.overlay {
display: block;
position: absolute;
width: 100vw;
width: calc(100vw - 240px);
height: 100%;
z-index: 1021;
left: var(--sidebar-width);
left: var(--left-sidebar-width);
overflow: auto;
background-color: rgba(128, 128, 128, 0.5);
}
@ -347,15 +348,15 @@ body {
text-decoration: none;
width: 38px;
height: 38px;
left: -2px;
padding: 3px;
margin-left: -2px;
.standard-sidebar-item {
padding-top: 1px;
padding-bottom: 1px;
.d-flex {
width: 161px;
}
gap: 8px;
gap: 30px;
}
.sidebar-item-control {
margin: 2px;
@ -365,15 +366,13 @@ body {
.app-switcher-menu {
position: absolute;
top: 44px;
left: 7px;
width: 205px;
top: 50px;
left: 9px;
width: 220px;
padding: 6px;
border-radius: var(--border-radius-lg);
background: var(--surface-modal);
box-shadow: 0px 10px 24px -3px rgba(0, 0, 0, 0.1);
// box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.05);
// box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.2);
box-shadow: var(--shadow-xl);
z-index: 1;
}
@ -421,7 +420,7 @@ body {
.active-sidebar {
background: var(--sidebar-active-color);
box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);
box-shadow: var(--shadow-sm);
border-radius: 8px;
}
.overlay {