refactor: menu component

This commit is contained in:
sokumon 2025-11-27 20:43:02 +05:30
parent b958d1bbe8
commit f92226880e
6 changed files with 156 additions and 157 deletions

View file

@ -162,34 +162,36 @@ class DesktopPage {
}
setup_avatar() {
$(".desktop-avatar").html(frappe.avatar(frappe.session.user, "avatar-medium"));
$(".desktop-avatar").data("menu", "user-menu");
let menu_items = [
{
icon: "edit",
label: "Edit Profile",
url: `/update-profile/${frappe.session.user}`,
},
{
icon: "lock",
label: "Reset Password",
url: "/update-password",
},
{
icon: "rotate-ccw",
label: "Reset to Default",
onClick: function () {
reset_to_default();
window.location.reload();
let menu_items = {
name: "user-menu",
items: [
{
icon: "edit",
label: "Edit Profile",
url: `/update-profile/${frappe.session.user}`,
},
},
{
icon: "log-out",
label: "Logout",
onClick: function () {
frappe.app.logout();
{
icon: "lock",
label: "Reset Password",
url: "/update-password",
},
},
];
{
icon: "rotate-ccw",
label: "Reset to Default",
onClick: function () {
reset_to_default();
window.location.reload();
},
},
{
icon: "log-out",
label: "Logout",
onClick: function () {
frappe.app.logout();
},
},
],
};
frappe.ui.create_menu($(".desktop-avatar"), menu_items, null, true);
}
setup_navbar() {

View file

@ -2,9 +2,10 @@ import "../dom";
frappe.provide("frappe.ui");
frappe.ui.menu = class ContextMenu {
constructor(menu_items, left) {
this.template = $(`<div class="dropdown-menu context-menu" role="menu"></div>`);
this.menu_items = menu_items;
constructor(opts, left) {
this.template = $(`<div class="sidebar-header-menu context-menu" role="menu"></div>`);
this.menu_items = opts.items;
this.name = opts.name;
this.open_on_left = left;
}
@ -23,7 +24,7 @@ frappe.ui.menu = class ContextMenu {
const me = this;
let item_wrapper = $(`<div class="dropdown-menu-item">
<a>
<div class="sidebar-item-icon">
<div class="menu-item-icon">
${
item.icon
? frappe.utils.icon(item.icon)
@ -114,50 +115,42 @@ frappe.ui.menu = class ContextMenu {
frappe.menu_map = {};
frappe.ui.create_menu = function attachContextMenuToElement(
element,
menuItems,
right_click,
open_on_left
) {
frappe.ui.create_menu = function (element, opts, right_click, open_on_left) {
$(element).css("cursor", "pointer");
let contextMenu = new frappe.ui.menu(menuItems, open_on_left);
let context_menu = new frappe.ui.menu(opts, open_on_left);
frappe.menu_map[$(element).data("menu")] = contextMenu;
frappe.menu_map[context_menu.name] = context_menu;
if (right_click) {
$(element).on("contextmenu", function (event) {
event.preventDefault();
event.stopPropagation();
if (
frappe.menu_map[$(element).data("menu")] &&
frappe.menu_map[$(element).data("menu")].visible
) {
frappe.menu_map[$(element).data("menu")].hide();
if (frappe.menu_map[context_menu.name] && frappe.menu_map[context_menu.name].visible) {
frappe.menu_map[context_menu.name].hide();
} else {
frappe.menu_map[$(element).data("menu")].show(this);
frappe.menu_map[context_menu.name].show(this);
}
});
} else {
$(element).on("click", function (event) {
event.preventDefault();
event.stopPropagation();
if (frappe.menu_map[$(element).data("menu")].visible) {
frappe.menu_map[$(element).data("menu")].hide();
if (frappe.menu_map[context_menu.name].visible) {
frappe.menu_map[context_menu.name].hide();
} else {
frappe.menu_map[$(element).data("menu")].show(this);
frappe.menu_map[context_menu.name].show(this);
}
});
}
$(document).on("click", function () {
if (frappe.menu_map[$(element).data("menu")].visible) {
frappe.menu_map[$(element).data("menu")].hide();
if (frappe.menu_map[context_menu.name].visible) {
frappe.menu_map[context_menu.name].hide();
}
});
$(document).on("keydown", function (e) {
if (e.key === "Escape" && frappe.menu_map[$(element).data("menu")].visible) {
frappe.menu_map[$(element).data("menu")].hide();
if (e.key === "Escape" && frappe.menu_map[context_menu.name].visible) {
frappe.menu_map[context_menu.name].hide();
}
});
};

View file

@ -77,39 +77,42 @@ frappe.ui.sidebar_item.TypeLink = class SidebarItem {
}
get_menu_items() {
let me = this;
let menu_items = [
{
label: "Edit Item",
icon: "pen",
onClick: () => {
frappe.app.sidebar.edit_item(me.item);
let menu_items = {
name: "edit-item",
items: [
{
label: "Edit Item",
icon: "pen",
onClick: () => {
frappe.app.sidebar.edit_item(me.item);
},
},
},
{
label: "Add Item Below",
icon: "add",
onClick: () => {
frappe.app.sidebar.add_below(me.item);
{
label: "Add Item Below",
icon: "add",
onClick: () => {
frappe.app.sidebar.add_below(me.item);
},
},
},
{
label: "Duplicate",
icon: "copy",
onClick: () => {
console.log("Start Deleting");
frappe.app.sidebar.duplicate_item(me.item);
{
label: "Duplicate",
icon: "copy",
onClick: () => {
console.log("Start Deleting");
frappe.app.sidebar.duplicate_item(me.item);
},
},
},
{
label: "Delete",
icon: "trash-2",
onClick: () => {
console.log(me.item);
frappe.app.sidebar.delete_item(me.item);
console.log("Start Deleting");
{
label: "Delete",
icon: "trash-2",
onClick: () => {
console.log(me.item);
frappe.app.sidebar.delete_item(me.item);
console.log("Start Deleting");
},
},
},
];
],
};
return menu_items;
}
add_menu_items() {}
@ -258,43 +261,46 @@ frappe.ui.sidebar_item.TypeSectionBreak = class SectionBreakSidebarItem extends
get_menu_items() {
let me = this;
let menu_items = [
{
label: "Edit Item",
icon: "pen",
onClick: () => {
console.log("Start ediitng");
frappe.app.sidebar.edit_item(me.item);
let menu_items = {
name: "edit-section-break",
items: [
{
label: "Edit Item",
icon: "pen",
onClick: () => {
console.log("Start ediitng");
frappe.app.sidebar.edit_item(me.item);
},
},
},
{
label: "Add Nested Items",
icon: "add",
onClick: () => {
frappe.app.sidebar.show_new_dialog({
nested: true,
parent_item: me.item,
});
{
label: "Add Nested Items",
icon: "add",
onClick: () => {
frappe.app.sidebar.show_new_dialog({
nested: true,
parent_item: me.item,
});
},
},
},
{
label: "Duplicate",
icon: "copy",
onClick: () => {
console.log("Start Deleting");
frappe.app.sidebar.duplicate_item(me.item);
{
label: "Duplicate",
icon: "copy",
onClick: () => {
console.log("Start Deleting");
frappe.app.sidebar.duplicate_item(me.item);
},
},
},
{
label: "Delete",
icon: "trash-2",
onClick: () => {
console.log(me.item);
frappe.app.sidebar.delete_item(me.item);
console.log("Start Deleting");
{
label: "Delete",
icon: "trash-2",
onClick: () => {
console.log(me.item);
frappe.app.sidebar.delete_item(me.item);
console.log("Start Deleting");
},
},
},
];
],
};
return menu_items;
}
};

View file

@ -52,4 +52,5 @@
@import "../common/quill";
@import "plyr";
@import "version";
@import "menu";
@import "sidebar_header";

View file

@ -0,0 +1,41 @@
.sidebar-header-menu {
position: absolute;
top: 60px;
left: 9px;
width: 200px;
padding: 6px;
border-radius: var(--border-radius-lg);
background: var(--surface-modal);
box-shadow: var(--shadow-xl);
}
.dropdown-menu-item {
// padding: var(--padding-xs);
border-radius: var(--border-radius-sm);
&:hover {
background-color: var(--sidebar-hover-color);
}
a {
height: 28px;
padding: 6px 8px 6px 8px;
gap: 8px;
text-decoration: none;
display: flex;
align-items: center;
gap: var(--margin-sm);
.menu-item-icon {
line-height: 0px;
.app-logo {
width: 16px;
height: 16px;
}
}
}
.menu-item-title {
text-overflow: ellipsis;
text-wrap: nowrap;
overflow: hidden;
}
}

View file

@ -51,47 +51,3 @@
line-height: 1;
margin-top: 4px;
}
.sidebar-header-menu {
position: absolute;
top: 60px;
left: 9px;
width: 200px;
padding: 6px;
border-radius: var(--border-radius-lg);
background: var(--surface-modal);
box-shadow: var(--shadow-xl);
z-index: 1;
}
.dropdown-menu-item {
// padding: var(--padding-xs);
border-radius: var(--border-radius-sm);
opacity: 0px;
&:hover {
background-color: var(--sidebar-hover-color);
}
a {
height: 28px;
padding: 6px 8px 6px 8px;
gap: 8px;
text-decoration: none;
display: flex;
align-items: center;
gap: var(--margin-sm);
.sidebar-item-icon {
line-height: 0px;
.app-logo {
width: 16px;
height: 16px;
}
}
}
.menu-item-title {
text-overflow: ellipsis;
text-wrap: nowrap;
overflow: hidden;
}
}