diff --git a/cypress/integration/workspace.js b/cypress/integration/workspace.js index e7d97c705b..d52417b234 100644 --- a/cypress/integration/workspace.js +++ b/cypress/integration/workspace.js @@ -190,6 +190,48 @@ context("Workspace 2.0", () => { cy.get('.standard-actions .btn-primary[data-label="Save"]').click(); }); + it("Hide/Unhide Workspaces", () => { + // hide + cy.intercept({ + method: "POST", + url: "api/method/frappe.desk.doctype.workspace.workspace.hide_page", + }).as("hide_page"); + + cy.get(".codex-editor__redactor .ce-block"); + cy.get(".standard-actions .btn-secondary[data-label=Edit]").click(); + + cy.get('.sidebar-item-container[item-name="Duplicate Page"]') + .find(".sidebar-item-control .setting-btn") + .click(); + cy.get('.sidebar-item-container[item-name="Duplicate Page"]') + .find('.dropdown-item[title="Hide Workspace"]') + .click({ force: true }); + cy.wait(300); + cy.get('.standard-actions .btn-secondary[data-label="Discard"]').click(); + cy.get('.sidebar-item-container[item-name="Duplicate Page"]').should("not.be.visible"); + + cy.wait("@hide_page"); + + // unhide + cy.intercept({ + method: "POST", + url: "api/method/frappe.desk.doctype.workspace.workspace.unhide_page", + }).as("unhide_page"); + + cy.get(".codex-editor__redactor .ce-block"); + cy.get(".standard-actions .btn-secondary[data-label=Edit]").click(); + + cy.get('.sidebar-item-container[item-name="Duplicate Page"]') + .find('[title="Unhide Workspace"]') + .click({ force: true }); + cy.wait(300); + + cy.get('.standard-actions .btn-secondary[data-label="Discard"]').click(); + cy.get('.sidebar-item-container[item-name="Duplicate Page"]').should("be.visible"); + + cy.wait("@unhide_page"); + }); + it("Delete Duplicate Page", () => { cy.intercept({ method: "POST", diff --git a/frappe/desk/desktop.py b/frappe/desk/desktop.py index dfe7850349..f2243c2e56 100644 --- a/frappe/desk/desktop.py +++ b/frappe/desk/desktop.py @@ -379,7 +379,17 @@ def get_workspace_sidebar_items(): # pages sorted based on sequence id order_by = "sequence_id asc" - fields = ["name", "title", "for_user", "parent_page", "content", "public", "module", "icon"] + fields = [ + "name", + "title", + "for_user", + "parent_page", + "content", + "public", + "module", + "icon", + "is_hidden", + ] all_pages = frappe.get_all( "Workspace", fields=fields, filters=filters, order_by=order_by, ignore_permissions=True ) @@ -391,7 +401,7 @@ def get_workspace_sidebar_items(): try: workspace = Workspace(page, True) if has_access or workspace.is_permitted(): - if page.public: + if page.public and (has_access or not page.is_hidden): pages.append(page) elif page.for_user == frappe.session.user: private_pages.append(page) diff --git a/frappe/desk/doctype/workspace/workspace.json b/frappe/desk/doctype/workspace/workspace.json index 58a1f718fd..edd5c32e99 100644 --- a/frappe/desk/doctype/workspace/workspace.json +++ b/frappe/desk/doctype/workspace/workspace.json @@ -19,6 +19,7 @@ "restrict_to_domain", "hide_custom", "public", + "is_hidden", "content", "tab_break_2", "charts", @@ -174,11 +175,17 @@ "fieldtype": "Table", "label": "Quick Lists", "options": "Workspace Quick List" + }, + { + "default": "0", + "fieldname": "is_hidden", + "fieldtype": "Check", + "label": "Is Hidden" } ], "in_create": 1, "links": [], - "modified": "2023-01-07 17:02:48.278025", + "modified": "2023-01-07 19:37:39.512482", "modified_by": "Administrator", "module": "Desk", "name": "Workspace", diff --git a/frappe/desk/doctype/workspace/workspace.py b/frappe/desk/doctype/workspace/workspace.py index c4110f52a7..f7d9e8ac3e 100644 --- a/frappe/desk/doctype/workspace/workspace.py +++ b/frappe/desk/doctype/workspace/workspace.py @@ -247,6 +247,32 @@ def update_page(name, title, icon, parent, public): return {"name": title, "public": public, "label": new_name} +def hide_unhide_page(page_name: str, is_hidden: bool): + page = frappe.get_doc("Workspace", page_name) + + if page.get("public") and not is_workspace_manager(): + frappe.throw( + _("Need Workspace Manager role to hide/unhide public workspaces"), frappe.PermissionError + ) + + if not page.get("public") and page.get("for_user") != frappe.session.user: + frappe.throw(_("Cannot update private workspace of other users"), frappe.PermissionError) + + page.is_hidden = int(is_hidden) + page.save(ignore_permissions=True) + return True + + +@frappe.whitelist() +def hide_page(page_name: str): + return hide_unhide_page(page_name, 1) + + +@frappe.whitelist() +def unhide_page(page_name: str): + return hide_unhide_page(page_name, 0) + + @frappe.whitelist() def duplicate_page(page_name, new_page): if not loads(new_page): diff --git a/frappe/public/icons/timeless/icons.svg b/frappe/public/icons/timeless/icons.svg index 69e9e920e6..fed77e7df1 100644 --- a/frappe/public/icons/timeless/icons.svg +++ b/frappe/public/icons/timeless/icons.svg @@ -48,6 +48,16 @@ + + + + + + + + + + diff --git a/frappe/public/js/frappe/views/workspace/workspace.js b/frappe/public/js/frappe/views/workspace/workspace.js index cbcea38f38..ee5d2c92a0 100644 --- a/frappe/public/js/frappe/views/workspace/workspace.js +++ b/frappe/public/js/frappe/views/workspace/workspace.js @@ -78,9 +78,13 @@ frappe.views.Workspace = class Workspace { sidebar_item_container(item) { return $(` -