From 3e715985c6921ce4e24288f22aa6d7628bb1cd8b Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 9 Jan 2023 16:53:23 +0530 Subject: [PATCH 01/16] fix: ignore unhandled emails while deleting email account (#19534) [skip ci] --- frappe/hooks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/hooks.py b/frappe/hooks.py index 9ad95e796b..28b2c0dea1 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -392,4 +392,5 @@ ignore_links_on_delete = [ "Email Queue", "Document Share Key", "Integration Request", + "Unhandled Email", ] From f5771baf6637ac461c73e5f4c6a7d4fb5bba24ee Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 9 Jan 2023 17:09:59 +0530 Subject: [PATCH 02/16] ci: use GITHUB_TOKEN for roulette api calls (#19537) This is safe cuz we set read only permission on this token in workflows. NOTE: Changing permission type is dangerous here! --- .github/helper/roulette.py | 7 ++++++- .github/workflows/patch-mariadb-tests.yml | 2 ++ .github/workflows/server-tests.yml | 2 ++ .github/workflows/ui-tests.yml | 2 ++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/helper/roulette.py b/.github/helper/roulette.py index f2a8bcb700..e3b212fa89 100644 --- a/.github/helper/roulette.py +++ b/.github/helper/roulette.py @@ -23,10 +23,15 @@ def fetch_pr_data(pr_number, repo, endpoint=""): def req(url): "Simple resilient request call to handle rate limits." + headers = None + token = os.environ.get("GITHUB_TOKEN") + if token: + headers = {"authorization": f"Bearer {token}"} + retries = 0 while True: try: - req = urllib.request.Request(url) + req = urllib.request.Request(url, headers=headers) return urllib.request.urlopen(req) except HTTPError as exc: if exc.code == 403 and retries < 5: diff --git a/.github/workflows/patch-mariadb-tests.yml b/.github/workflows/patch-mariadb-tests.yml index 57f421cc1b..4b487d2aea 100644 --- a/.github/workflows/patch-mariadb-tests.yml +++ b/.github/workflows/patch-mariadb-tests.yml @@ -9,6 +9,7 @@ concurrency: cancel-in-progress: true permissions: + # Do not change this as GITHUB_TOKEN is being used by roulette contents: read jobs: @@ -31,6 +32,7 @@ jobs: TYPE: "server" PR_NUMBER: ${{ github.event.number }} REPO_NAME: ${{ github.repository }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} test: name: Patch diff --git a/.github/workflows/server-tests.yml b/.github/workflows/server-tests.yml index cc310fd8d7..3b76da1973 100644 --- a/.github/workflows/server-tests.yml +++ b/.github/workflows/server-tests.yml @@ -12,6 +12,7 @@ concurrency: permissions: + # Do not change this as GITHUB_TOKEN is being used by roulette contents: read jobs: @@ -34,6 +35,7 @@ jobs: TYPE: "server" PR_NUMBER: ${{ github.event.number }} REPO_NAME: ${{ github.repository }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} test: name: Unit Tests diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml index f022f10ea4..1b88bc73ce 100644 --- a/.github/workflows/ui-tests.yml +++ b/.github/workflows/ui-tests.yml @@ -11,6 +11,7 @@ concurrency: cancel-in-progress: true permissions: + # Do not change this as GITHUB_TOKEN is being used by roulette contents: read jobs: @@ -33,6 +34,7 @@ jobs: TYPE: "ui" PR_NUMBER: ${{ github.event.number }} REPO_NAME: ${{ github.repository }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} test: runs-on: ubuntu-latest From 97a57f7105a5f22840725ba52cdce5b0f66cecc6 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 9 Jan 2023 17:51:25 +0530 Subject: [PATCH 03/16] feat: hide/unhide workspace from sidebar --- frappe/desk/desktop.py | 14 +++- frappe/desk/doctype/workspace/workspace.json | 9 ++- frappe/desk/doctype/workspace/workspace.py | 26 +++++++ frappe/public/icons/timeless/icons.svg | 10 +++ .../js/frappe/views/workspace/workspace.js | 72 +++++++++++++++++-- frappe/public/scss/desk/desktop.scss | 72 ++++++++++++++----- 6 files changed, 178 insertions(+), 25 deletions(-) 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..7649a2204d 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: int): + 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 = 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..6ff7e8ead0 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 $(` -