diff --git a/cypress/integration/workspace.js b/cypress/integration/workspace.js index 5283fadcbd..97db14d683 100644 --- a/cypress/integration/workspace.js +++ b/cypress/integration/workspace.js @@ -20,6 +20,7 @@ context("Workspace 2.0", () => { cy.get(".codex-editor__redactor .ce-block"); cy.get(".btn-new-workspace").click(); cy.fill_field("title", "Test Private Page", "Data"); + cy.fill_field("type", "Workspace", "Select"); cy.wait(300); cy.get_open_dialog().find(".modal-header").click(); @@ -53,6 +54,7 @@ context("Workspace 2.0", () => { cy.get(".btn-new-workspace").click(); cy.fill_field("title", "Test Child Page", "Data"); cy.fill_field("parent", "Test Private Page", "Select"); + cy.fill_field("type", "Workspace", "Select"); cy.get_open_dialog().find(".modal-header").click(); cy.wait(300); cy.get_open_dialog().find(".btn-primary").click(); diff --git a/cypress/integration/workspace_blocks.js b/cypress/integration/workspace_blocks.js index 7c89c70c01..70159150e2 100644 --- a/cypress/integration/workspace_blocks.js +++ b/cypress/integration/workspace_blocks.js @@ -20,6 +20,7 @@ context("Workspace Blocks", () => { cy.get(".codex-editor__redactor .ce-block"); cy.get(".btn-new-workspace").click(); cy.fill_field("title", "Test Block Page", "Data"); + cy.fill_field("type", "Workspace", "Select"); cy.get_open_dialog().find(".modal-header").click(); cy.get_open_dialog().find(".btn-primary").click(); diff --git a/frappe/desk/desktop.py b/frappe/desk/desktop.py index d96de2a415..53e61bf76f 100644 --- a/frappe/desk/desktop.py +++ b/frappe/desk/desktop.py @@ -447,6 +447,10 @@ def get_workspace_sidebar_items(): "indicator_color", "is_hidden", "app", + "type", + "link_type", + "link_to", + "external_link", ] all_pages = frappe.get_all( "Workspace", fields=fields, filters=filters, order_by=order_by, ignore_permissions=True @@ -480,6 +484,14 @@ def get_workspace_sidebar_items(): page["app"] = frappe.db.get_value("Module Def", page["module"], "app_name") or get_module_app( page["module"] ) + if page["link_type"] == "Report": + report_type, ref_doctype = frappe.db.get_value( + "Report", page["link_to"], ["report_type", "ref_doctype"] + ) + page["report"] = { + "report_type": report_type, + "ref_doctype": ref_doctype, + } except frappe.PermissionError: pass diff --git a/frappe/desk/doctype/workspace/workspace.json b/frappe/desk/doctype/workspace/workspace.json index e27f820385..f3422cd6eb 100644 --- a/frappe/desk/doctype/workspace/workspace.json +++ b/frappe/desk/doctype/workspace/workspace.json @@ -15,6 +15,10 @@ "parent_page", "module", "app", + "type", + "link_type", + "link_to", + "external_link", "column_break_3", "icon", "indicator_color", @@ -49,6 +53,7 @@ { "collapsible": 1, "collapsible_depends_on": "charts", + "depends_on": "eval:doc.type===\"Workspace\"", "fieldname": "tab_break_2", "fieldtype": "Tab Break", "label": "Dashboards" @@ -87,6 +92,7 @@ { "collapsible": 1, "collapsible_depends_on": "shortcuts", + "depends_on": "eval:doc.type===\"Workspace\"", "fieldname": "tab_break_15", "fieldtype": "Tab Break", "label": "Shortcuts" @@ -94,6 +100,7 @@ { "collapsible": 1, "collapsible_depends_on": "links", + "depends_on": "eval:doc.type===\"Workspace\"", "fieldname": "tab_break_18", "fieldtype": "Tab Break", "label": "Link Cards" @@ -167,6 +174,7 @@ "label": "Roles" }, { + "depends_on": "eval:doc.type===\"Workspace\"", "fieldname": "quick_lists_tab", "fieldtype": "Tab Break", "label": "Quick Lists" @@ -184,6 +192,7 @@ "label": "Is Hidden" }, { + "depends_on": "eval:doc.type===\"Workspace\"", "fieldname": "number_cards_tab", "fieldtype": "Tab Break", "label": "Number Cards" @@ -195,6 +204,7 @@ "options": "Workspace Number Card" }, { + "depends_on": "eval:doc.type===\"Workspace\"", "fieldname": "custom_blocks_tab", "fieldtype": "Tab Break", "label": "Custom Blocks" @@ -216,11 +226,43 @@ "fieldname": "app", "fieldtype": "Data", "label": "App" + }, + { + "default": "Workspace", + "fieldname": "type", + "fieldtype": "Select", + "label": "Type", + "options": "Workspace\nLink\nURL", + "reqd": 1 + }, + { + "depends_on": "eval:doc.type==\"Link\"", + "fieldname": "link_type", + "fieldtype": "Select", + "label": "Link Type", + "mandatory_depends_on": "eval:doc.type==\"Link\"", + "options": "DocType\nPage\nReport" + }, + { + "depends_on": "eval:doc.type==\"Link\"", + "fieldname": "link_to", + "fieldtype": "Dynamic Link", + "label": "Link To", + "mandatory_depends_on": "eval:doc.type==\"Link\"", + "options": "link_type" + }, + { + "depends_on": "eval:doc.type==\"URL\"", + "fieldname": "external_link", + "fieldtype": "Data", + "label": "External Link", + "mandatory_depends_on": "eval:doc.type==\"URL\"", + "options": "URL" } ], "in_create": 1, "links": [], - "modified": "2024-09-04 22:24:24.780174", + "modified": "2024-09-26 15:47:24.710881", "modified_by": "Administrator", "module": "Desk", "name": "Workspace", diff --git a/frappe/desk/doctype/workspace/workspace.py b/frappe/desk/doctype/workspace/workspace.py index 946dc87451..831819e959 100644 --- a/frappe/desk/doctype/workspace/workspace.py +++ b/frappe/desk/doctype/workspace/workspace.py @@ -34,6 +34,7 @@ class Workspace(Document): charts: DF.Table[WorkspaceChart] content: DF.LongText | None custom_blocks: DF.Table[WorkspaceCustomBlock] + external_link: DF.Data | None for_user: DF.Data | None hide_custom: DF.Check indicator_color: DF.Literal[ @@ -52,6 +53,8 @@ class Workspace(Document): ] is_hidden: DF.Check label: DF.Data + link_to: DF.DynamicLink | None + link_type: DF.Literal["DocType", "Page", "Report"] links: DF.Table[WorkspaceLink] module: DF.Link | None number_cards: DF.Table[WorkspaceNumberCard] @@ -63,6 +66,7 @@ class Workspace(Document): sequence_id: DF.Float shortcuts: DF.Table[WorkspaceShortcut] title: DF.Data + type: DF.Literal["Workspace", "Link", "URL"] # end: auto-generated types def validate(self): @@ -275,6 +279,10 @@ def new_page(new_page): doc.for_user = page.get("for_user") doc.public = page.get("public") doc.app = page.get("app") + doc.type = page.get("type") + doc.link_to = page.get("link_to") + doc.link_type = page.get("link_type") + doc.external_link = page.get("external_link") doc.sequence_id = last_sequence_id(doc) + 1 doc.save(ignore_permissions=True) diff --git a/frappe/public/js/frappe/ui/sidebar.js b/frappe/public/js/frappe/ui/sidebar.js index 1214304088..70393c9b41 100644 --- a/frappe/public/js/frappe/ui/sidebar.js +++ b/frappe/public/js/frappe/ui/sidebar.js @@ -296,6 +296,27 @@ frappe.ui.Sidebar = class Sidebar { sidebar_item_container(item) { item.indicator_color = item.indicator_color || this.indicator_colors[Math.floor(Math.random() * 12)]; + let path; + if (item.type === "Link") { + if (item.link_type === "Report") { + path = frappe.utils.generate_route({ + type: item.link_type, + name: item.link_to, + is_query_report: item.report.report_type === "Query Report", + report_ref_doctype: item.report.ref_doctype, + }); + } else { + path = frappe.utils.generate_route({ type: item.link_type, name: item.link_to }); + } + } else if (item.type === "URL") { + path = item.external_link; + } else { + if (item.public) { + path = "/app/" + frappe.router.slug(item.name); + } else { + path = "/app/private/" + frappe.router.slug(item.name.split("-")[0]); + } + } return $(`