diff --git a/frappe/boot.py b/frappe/boot.py index 3414ea7b18..b06a74b852 100644 --- a/frappe/boot.py +++ b/frappe/boot.py @@ -544,7 +544,7 @@ def get_sidebar_items(): ) module_sidebars = auto_generate_sidebar_from_module() sidebars.extend(module_sidebars) - add_user_specific_sidebar(sidebars) + add_private_workspace_sidebar(sidebars) sidebar_items = {} for s in sidebars: @@ -592,18 +592,21 @@ def get_sidebar_items(): or w.is_item_allowed(si.link_to, si.link_type) ): sidebar_items[sidebar_title.lower()]["items"].append(workspace_sidebar) - - old_name = f"my workspaces-{frappe.session.user.lower()}" - if old_name in sidebar_items.keys(): - sidebar_items["my workspaces"] = sidebar_items.pop(old_name) + add_user_specific_sidebar(sidebar_items) + # old_name = f"my workspaces-{frappe.session.user.lower()}" + # if old_name in sidebar_items.keys(): + # sidebar_items["my workspaces"] = sidebar_items.pop(old_name) return sidebar_items -def add_user_specific_sidebar(sidebars): +def add_private_workspace_sidebar(sidebars): try: my_workspace_for_user = frappe.get_doc("Workspace Sidebar", f"My Workspaces-{frappe.session.user}") sidebars.append( - {"name": my_workspace_for_user.name, "header_icon": my_workspace_for_user.header_icon} + { + "name": my_workspace_for_user.name, + "header_icon": my_workspace_for_user.header_icon, + } ) except frappe.DoesNotExistError: my_workspace = frappe.get_doc("Workspace Sidebar", "My Workspaces") @@ -635,3 +638,14 @@ def get_desktop_icon_urls(): icons_map[app][variant].append(assets_path) return icons_map + + +def add_user_specific_sidebar(sidebar_items): + sidebars_to_remove = [] + for sidebar in sidebar_items.keys(): + if f"-{frappe.session.user.lower()}" in sidebar: + sidebars_to_remove.append(sidebar) + + for sidebar in sidebars_to_remove: + sidebar_name = sidebar.replace(f"-{frappe.session.user.lower()}", "") + sidebar_items[sidebar_name] = sidebar_items.pop(sidebar) diff --git a/frappe/desk/doctype/workspace_sidebar/workspace_sidebar.json b/frappe/desk/doctype/workspace_sidebar/workspace_sidebar.json index a101799603..5c27986964 100644 --- a/frappe/desk/doctype/workspace_sidebar/workspace_sidebar.json +++ b/frappe/desk/doctype/workspace_sidebar/workspace_sidebar.json @@ -24,6 +24,7 @@ "fieldname": "items", "fieldtype": "Table", "label": "Items", + "no_copy": 1, "options": "Workspace Sidebar Item" }, { @@ -53,7 +54,7 @@ "grid_page_length": 50, "index_web_pages_for_search": 1, "links": [], - "modified": "2025-11-17 01:17:20.583501", + "modified": "2025-12-10 20:20:26.518699", "modified_by": "Administrator", "module": "Desk", "name": "Workspace Sidebar", diff --git a/frappe/desk/doctype/workspace_sidebar/workspace_sidebar.py b/frappe/desk/doctype/workspace_sidebar/workspace_sidebar.py index 4cb038773d..c0dc38b2b0 100644 --- a/frappe/desk/doctype/workspace_sidebar/workspace_sidebar.py +++ b/frappe/desk/doctype/workspace_sidebar/workspace_sidebar.py @@ -179,13 +179,19 @@ def create_workspace_sidebar_for_workspaces(): @frappe.whitelist() def add_sidebar_items(sidebar_title, sidebar_items): sidebar_items = loads(sidebar_items) + title = f"{sidebar_title}-{frappe.session.user}" w = frappe.get_doc("Workspace Sidebar", sidebar_title) + try: + w = frappe.get_doc("Workspace Sidebar", title) + except frappe.DoesNotExistError: + frappe.clear_messages() + w = frappe.copy_doc(w, ignore_no_copy=False) + w.title = title items = [] current_idx = 1 for item in sidebar_items: si = frappe.new_doc("Workspace Sidebar Item") si.update(item) - items.append(si) si.idx = current_idx items.append(si) current_idx += 1 diff --git a/frappe/public/js/frappe/ui/sidebar/sidebar.js b/frappe/public/js/frappe/ui/sidebar/sidebar.js index 2eab820268..ae637dde41 100644 --- a/frappe/public/js/frappe/ui/sidebar/sidebar.js +++ b/frappe/public/js/frappe/ui/sidebar/sidebar.js @@ -97,8 +97,9 @@ frappe.ui.Sidebar = class Sidebar { } setup(workspace_title) { this.sidebar_title = workspace_title; - this.workspace_title = workspace_title.toLowerCase(); this.check_for_private_workspace(workspace_title); + this.workspace_title = this.sidebar_title.toLowerCase(); + this.prepare(); this.$sidebar.attr("data-title", this.sidebar_title); this.sidebar_header = new frappe.ui.SidebarHeader(this); diff --git a/frappe/public/js/frappe/ui/sidebar/sidebar_editor.js b/frappe/public/js/frappe/ui/sidebar/sidebar_editor.js index 5a7f32023a..9b781f7b9f 100644 --- a/frappe/public/js/frappe/ui/sidebar/sidebar_editor.js +++ b/frappe/public/js/frappe/ui/sidebar/sidebar_editor.js @@ -5,10 +5,9 @@ export class SidebarEditor { this.setup(); } setup() { - console.log("Setting Up Editor"); - this.setup_editing_off(); + this.handle_route_change(); } - setup_editing_off() { + handle_route_change() { const me = this; frappe.router.on("change", function () { if (frappe.get_prev_route().length == 0) return; @@ -28,7 +27,6 @@ export class SidebarEditor { start() { const me = this; this.edit_mode = true; - console.log("Start Editing"); this.sidebar.open(); this.sidebar.wrapper.attr("data-mode", "edit"); @@ -99,6 +97,14 @@ export class SidebarEditor { this.sortable = Sortable.create($(".sidebar-items").get(0), { handler: ".drag-handle", group: "sidebar-item", + onAdd: function (event) { + let old_index = event.oldIndex; + let section_name = $(event.from).parent().attr("item-name"); + let item_data = me.get_item_data(section_name).nested_items[old_index]; + me.get_item_data(section_name).nested_items.splice(old_index, 1); + item_data.child = 0; + me.new_sidebar_items.splice(event.newIndex, 0, item_data); + }, onMove: function (evt, originalEvent) { me.close_section = false; let item_name = $(evt.related).attr("item-name"); @@ -117,7 +123,6 @@ export class SidebarEditor { .first() .get(0) .getBoundingClientRect(); - console.log(nested_container.top > originalEvent.clientY); if ( nested_container.top > originalEvent.clientY || originalEvent.clientY < nested_container.bottom @@ -434,7 +439,6 @@ export class SidebarEditor { if (opts && opts.nested) { values.child = 1; console.log("Add it as a nested item"); - console.log(opts.parent_item); let index = me.new_sidebar_items.findIndex((f) => { return f.label == opts.parent_item.label; }); @@ -445,11 +449,11 @@ export class SidebarEditor { me.new_sidebar_items[index].nested_items.push(values); } else if (opts && opts.item) { if (opts.item.child) { - let parent_icon = me.find_parent(me.new_sidebar_items, opts.item); - if (parent_icon) { - let index = parent_icon.nested_items.indexOf(opts.item); - let parent_icon_index = me.new_sidebar_items.indexOf(parent_icon); - me.new_sidebar_items[parent_icon_index].nested_items[index] = values; + let parent_item = me.find_parent(me.new_sidebar_items, opts.item); + if (parent_item) { + let index = parent_item.nested_items.indexOf(opts.item); + let parent_item_index = me.new_sidebar_items.indexOf(parent_item); + me.new_sidebar_items[parent_item_index].nested_items[index] = values; } } else { let index = me.new_sidebar_items.indexOf(opts.item); @@ -518,9 +522,11 @@ export class SidebarEditor { delete_item(item) { let index; if (item.child) { - let parent_icon = this.find_parent(this.new_sidebar_items, item); - index = parent_icon.nested_items.indexOf(item); - parent_icon.nested_items.splice(index, 1); + let parent_item = this.find_parent(this.new_sidebar_items, item); + if (parent_item) { + index = parent_item.nested_items.indexOf(item); + parent_item.nested_items.splice(index, 1); + } } else { index = this.new_sidebar_items.indexOf(item); this.new_sidebar_items.splice(index, 1); diff --git a/frappe/public/js/frappe/ui/sidebar/sidebar_header.js b/frappe/public/js/frappe/ui/sidebar/sidebar_header.js index eb579b8583..5d2a5a4441 100644 --- a/frappe/public/js/frappe/ui/sidebar/sidebar_header.js +++ b/frappe/public/js/frappe/ui/sidebar/sidebar_header.js @@ -190,19 +190,11 @@ frappe.ui.SidebarHeader = class SidebarHeader { populate_dropdown_menu() { const me = this; - this.check_editing_access(); this.dropdown_items.forEach((d) => { me.add_app_item(d); }); } - check_editing_access() { - if (!frappe.boot.developer_mode) { - let edit_sidebar_index = this.dropdown_items.findIndex((f) => { - return f.name == "edit-sidebar"; - }); - this.dropdown_items.splice(edit_sidebar_index, 1); - } - } + add_app_item(item) { $(`