fix(patch): create a user specific sidebar for showing private workspaces

This commit is contained in:
sokumon 2025-11-16 20:06:32 +05:30
parent 3033877373
commit 10093febf1
7 changed files with 82 additions and 20 deletions

View file

@ -527,7 +527,10 @@ def get_sentry_dsn():
def get_sidebar_items():
sidebars = frappe.get_all("Workspace Sidebar", fields=["name", "header_icon"])
sidebars = frappe.get_all(
"Workspace Sidebar", fields=["name", "header_icon"], filters={"name": ["not like", "%My Workspaces%"]}
)
add_user_specific_sidebar(sidebars)
sidebar_items = {}
for s in sidebars:
@ -558,7 +561,26 @@ def get_sidebar_items():
"report_type": report_type,
"ref_doctype": ref_doctype,
}
if si.type == "Section Break" or w.is_item_allowed(si.link_to, si.link_type):
if (
"My Workspaces" in s["name"]
or si.type == "Section Break"
or w.is_item_allowed(si.link_to, si.link_type)
):
sidebar_items[s["name"].lower()]["items"].append(workspace_sidebar)
old_name = f"my workspaces-{frappe.session.user}"
if old_name in sidebar_items:
sidebar_items["my workspaces"] = sidebar_items.pop(old_name)
return sidebar_items
def add_user_specific_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}
)
except frappe.DoesNotExistError:
my_workspace = frappe.get_doc("Workspace Sidebar", "My Workspaces")
sidebars.append({"name": my_workspace.name, "header_icon": my_workspace.header_icon})

View file

@ -9,6 +9,7 @@
"title",
"header_icon",
"app",
"for_user",
"items"
],
"fields": [
@ -34,12 +35,18 @@
"fieldtype": "Autocomplete",
"label": "App",
"options": "Installed Applications"
},
{
"fieldname": "for_user",
"fieldtype": "Link",
"label": "For User",
"options": "User"
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2025-10-26 23:21:30.166695",
"modified": "2025-11-16 10:54:04.080590",
"modified_by": "Administrator",
"module": "Desk",
"name": "Workspace Sidebar",

View file

@ -24,10 +24,11 @@ class WorkspaceSidebar(Document):
from frappe.types import DF
app: DF.Autocomplete | None
for_user: DF.Link | None
items: DF.Table[WorkspaceSidebarItem]
title: DF.Data | None
# end: auto-generated types
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if not frappe.flags.in_migrate:
@ -181,16 +182,38 @@ def add_sidebar_items(sidebar_title, sidebar_items):
def add_to_my_workspace(workspace):
private_sidebar = frappe.get_doc("Workspace Sidebar", "My Workspaces")
try:
if not workspace.for_user:
return
workspace_sidebar = {
"label": workspace.title,
"type": "Link",
"link_to": f"{workspace.title}-{workspace.for_user}",
"link_type": "Workspace",
"icon": workspace.icon,
}
sidebar_name = f"My Workspaces-{workspace.for_user}"
existing_sidebar = frappe.db.exists("Workspace Sidebar", sidebar_name)
private_sidebar.append("items", workspace_sidebar)
if existing_sidebar:
private_sidebar = frappe.get_doc("Workspace Sidebar", existing_sidebar)
else:
# clone sidebar
base_sidebar = frappe.get_doc("Workspace Sidebar", "My Workspaces")
private_sidebar = frappe.copy_doc(base_sidebar)
private_sidebar.title = sidebar_name
private_sidebar.for_user = workspace.for_user
private_sidebar.owner = workspace.for_user
private_sidebar.items = []
private_sidebar.save()
sidebar_item = {
"label": workspace.title,
"type": "Link",
"link_to": f"{workspace.title}-{workspace.for_user}",
"link_type": "Workspace",
"icon": workspace.icon,
}
private_sidebar.append("items", sidebar_item)
if existing_sidebar:
private_sidebar.save()
else:
private_sidebar.insert()
except Exception as e:
frappe.log_error(title="Error in Adding Private Workspaces", message=e)

View file

@ -46,7 +46,7 @@ frappe.ui.Sidebar = class Sidebar {
for (const app of frappe.boot.app_data) {
if (app.workspaces.includes(this.workspace_title)) {
this.app_name = app.app_title;
this.header_subtitle = app.app_title;
this.app_logo_url = app.app_logo_url;
return;
}
@ -54,7 +54,11 @@ frappe.ui.Sidebar = class Sidebar {
const icon = frappe.boot.desktop_icons.find((i) => i.label === this.workspace_title);
if (icon) {
this.app_name = icon.parent_icon;
this.header_subtitle = icon.parent_icon;
}
if (this.workspace_title == "My Workspaces") {
this.header_subtitle = frappe.session.user;
}
}
@ -87,7 +91,7 @@ frappe.ui.Sidebar = class Sidebar {
this.setup_complete = true;
}
check_for_private_workspace(workspace_title) {
if (workspace_title == "private") {
if (workspace_title == "private" || workspace_title == "Personal") {
this.workspace_title = "My Workspaces";
}
}

View file

@ -15,7 +15,7 @@
{% } %}
</div>
<div class="sidebar-item-label header-subtitle">
{%= frappe.app.sidebar.app_name %}
{%= frappe.app.sidebar.header_subtitle %}
</div>
</div>
<button class="btn-reset drop-icon show-in-edit-mode">

View file

@ -26,7 +26,13 @@ frappe.ui.sidebar_item.TypeLink = class SidebarItem {
path = frappe.utils.generate_route(args);
} else if (this.item.link_type == "Workspace") {
path = "/desk/" + frappe.router.slug(this.item.link_to);
let workspaces = frappe.workspaces[this.item.link_to.toLowerCase()];
if (workspaces.public) {
path = "/desk/" + frappe.router.slug(this.item.link_to);
} else {
path = "/desk/private/" + frappe.router.slug(workspaces.title);
}
if (this.item.route) {
path = this.item.route;
}

View file

@ -3,7 +3,7 @@
"creation": "2025-11-03 03:11:08.482620",
"docstatus": 0,
"doctype": "Workspace Sidebar",
"header_icon": "user",
"header_icon": "user-round",
"idx": 0,
"items": [],
"modified": "2025-11-13 16:03:59.720330",