From 77b11dd1ce4567dd37a445b0c0c65ea8a9523d00 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 26 Aug 2024 18:15:59 +0530 Subject: [PATCH] fix(tests): workspace tests and more style fixes --- cypress/integration/workspace.js | 144 +----------- frappe/core/workspace/build/build.json | 6 +- frappe/desk/doctype/workspace/workspace.js | 10 +- frappe/desk/doctype/workspace/workspace.json | 15 +- frappe/desk/doctype/workspace/workspace.py | 65 +----- .../js/frappe/form/sidebar/form_sidebar.js | 4 +- .../js/frappe/form/templates/form_footer.html | 2 +- .../frappe/form/templates/form_sidebar.html | 6 +- frappe/public/js/frappe/list/base_list.js | 21 +- frappe/public/js/frappe/list/list_sidebar.js | 12 +- frappe/public/js/frappe/list/list_view.js | 11 +- frappe/public/js/frappe/router.js | 6 - frappe/public/js/frappe/ui/sidebar.js | 19 +- frappe/public/js/frappe/utils/utils.js | 3 + .../js/frappe/views/reports/report_view.js | 2 +- .../js/frappe/views/workspace/workspace.js | 211 ++---------------- frappe/public/scss/common/css_variables.scss | 2 +- frappe/public/scss/common/grid.scss | 6 +- frappe/public/scss/common/icon_picker.scss | 2 +- frappe/public/scss/common/modal.scss | 2 +- frappe/public/scss/desk/desktop.scss | 11 +- frappe/public/scss/desk/form.scss | 5 +- frappe/public/scss/desk/list.scss | 2 +- frappe/public/scss/desk/mobile.scss | 2 +- frappe/public/scss/desk/navbar.scss | 10 +- frappe/public/scss/desk/page.scss | 12 +- frappe/public/scss/desk/sidebar.scss | 52 +---- 27 files changed, 123 insertions(+), 520 deletions(-) diff --git a/cypress/integration/workspace.js b/cypress/integration/workspace.js index 79800faa01..21687c59c3 100644 --- a/cypress/integration/workspace.js +++ b/cypress/integration/workspace.js @@ -72,84 +72,12 @@ context("Workspace 2.0", () => { cy.wait("@new_page"); }); - it("Duplicate Page", () => { - cy.intercept({ - method: "POST", - url: "api/method/frappe.desk.doctype.workspace.workspace.duplicate_page", - }).as("page_duplicated"); - - cy.get(".codex-editor__redactor .ce-block"); - cy.get(".btn-edit-workspace").click(); - - cy.get('.sidebar-item-container[item-name="Test Private Page"]').as("sidebar-item"); - - cy.get("@sidebar-item").find(".standard-sidebar-item").first().click(); - cy.get("@sidebar-item").find(".dropdown-btn").first().click(); - cy.get("@sidebar-item") - .find(".dropdown-list .dropdown-item") - .contains("Duplicate") - .first() - .click({ force: true }); - - cy.get_open_dialog().fill_field("title", "Duplicate Page", "Data"); - cy.click_modal_primary_button("Duplicate"); - - cy.wait("@page_duplicated"); - }); - - it("Drag Sidebar Item", () => { - cy.intercept({ - method: "POST", - url: "api/method/frappe.desk.doctype.workspace.workspace.sort_pages", - }).as("page_sorted"); - - cy.get('.sidebar-item-container[item-name="Duplicate Page"]').as("sidebar-item"); - - cy.get("@sidebar-item").find(".standard-sidebar-item").first().click(); - cy.get("@sidebar-item").find(".drag-handle").first().move({ deltaX: 0, deltaY: 100 }); - - cy.get('.sidebar-item-container[item-name="Build"]').as("sidebar-item"); - - cy.get("@sidebar-item").find(".standard-sidebar-item").first().click(); - cy.get("@sidebar-item").find(".drag-handle").first().move({ deltaX: 0, deltaY: 100 }); - - cy.wait("@page_sorted"); - }); - - it("Edit Page Detail", () => { - cy.intercept({ - method: "POST", - url: "api/method/frappe.desk.doctype.workspace.workspace.update_page", - }).as("page_updated"); - - cy.get('.sidebar-item-container[item-name="Test Private Page"]').as("sidebar-item"); - - cy.get("@sidebar-item").find(".standard-sidebar-item").first().click(); - cy.get("@sidebar-item").find(".dropdown-btn").first().click(); - cy.get("@sidebar-item") - .find(".dropdown-list .dropdown-item") - .contains("Edit") - .first() - .click({ force: true }); - - cy.get_open_dialog().fill_field("title", " 1", "Data"); - cy.get_open_dialog().find('input[data-fieldname="is_public"]').check(); - cy.click_modal_primary_button("Update"); - - cy.get( - '.standard-sidebar-section:first .sidebar-item-container[item-name="Test Private Page"]' - ).should("not.exist"); - cy.get( - '.standard-sidebar-section:last .sidebar-item-container[item-name="Test Private Page 1"]' - ).should("exist"); - - cy.wait("@page_updated"); - }); - it("Add New Block", () => { - cy.get('.sidebar-item-container[item-name="Duplicate Page"]').as("sidebar-item"); + cy.get('.sidebar-item-container[item-name="Test Private Page"]').as("sidebar-item"); - cy.get("@sidebar-item").find(".standard-sidebar-item").first().click(); + cy.get("@sidebar-item").find(".standard-sidebar-item").first().click({ force: true }); + + cy.get(".btn-edit-workspace").click({ force: true }); cy.get(".ce-block").click().type("{enter}"); cy.get(".block-list-container .block-list-item").contains("Heading").click(); @@ -187,68 +115,4 @@ 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(".btn-edit-workspace").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(".btn-edit-workspace").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", - url: "api/method/frappe.desk.doctype.workspace.workspace.delete_page", - }).as("page_deleted"); - - cy.get(".codex-editor__redactor .ce-block"); - cy.get(".btn-edit-workspace").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="Delete Workspace"]') - .click({ force: true }); - cy.wait(300); - cy.get(".modal-footer > .standard-actions > .btn-modal-primary:visible").first().click(); - cy.get('.sidebar-item-container[item-name="Duplicate Page"]').should("not.exist"); - - cy.wait("@page_deleted"); - }); }); diff --git a/frappe/core/workspace/build/build.json b/frappe/core/workspace/build/build.json index 8ecce4c7e8..b3028f080b 100644 --- a/frappe/core/workspace/build/build.json +++ b/frappe/core/workspace/build/build.json @@ -7,7 +7,7 @@ "doctype": "Workspace", "for_user": "", "hide_custom": 0, - "icon": "tool", + "icon": "organization", "idx": 1, "is_hidden": 0, "label": "Build", @@ -301,7 +301,7 @@ "type": "Link" } ], - "modified": "2024-08-16 12:31:51.279839", + "modified": "2024-08-26 15:14:40.193261", "modified_by": "Administrator", "module": "Core", "name": "Build", @@ -312,7 +312,7 @@ "quick_lists": [], "restrict_to_domain": "", "roles": [], - "sequence_id": 27.0, + "sequence_id": 2.0, "shortcuts": [ { "color": "Grey", diff --git a/frappe/desk/doctype/workspace/workspace.js b/frappe/desk/doctype/workspace/workspace.js index b5f298c477..45277b5782 100644 --- a/frappe/desk/doctype/workspace/workspace.js +++ b/frappe/desk/doctype/workspace/workspace.js @@ -20,15 +20,11 @@ frappe.ui.form.on("Workspace", { .attr("target", "_blank"); frm.layout.message.empty(); - let message = __( - "This document allows you to edit limited fields. For all kinds of workspace customization, use the Edit button located on the workspace page" - ); + let message = __("Please click Edit on the Workspace for best results"); if ( - frm.doc.for_user || - (frm.doc.public && - !frm.has_perm("write") && - !frappe.user.has_role("Workspace Manager")) + frm.doc.for_user !== frappe.session.user || + (frm.doc.public && !frappe.user.has_role("Workspace Manager")) ) { frm.trigger("disable_form"); diff --git a/frappe/desk/doctype/workspace/workspace.json b/frappe/desk/doctype/workspace/workspace.json index 05f33e5ae0..c9c68137fe 100644 --- a/frappe/desk/doctype/workspace/workspace.json +++ b/frappe/desk/doctype/workspace/workspace.json @@ -77,8 +77,7 @@ "in_list_view": 1, "in_standard_filter": 1, "label": "Module", - "options": "Module Def", - "read_only": 1 + "options": "Module Def" }, { "fieldname": "column_break_3", @@ -101,8 +100,7 @@ { "fieldname": "for_user", "fieldtype": "Data", - "label": "For User", - "read_only": 1 + "label": "For User" }, { "default": "0", @@ -114,8 +112,7 @@ { "fieldname": "icon", "fieldtype": "Icon", - "label": "Icon", - "read_only": 1 + "label": "Icon" }, { "fieldname": "links", @@ -137,7 +134,6 @@ "fieldname": "title", "fieldtype": "Data", "label": "Title", - "read_only": 1, "reqd": 1 }, { @@ -156,8 +152,7 @@ { "fieldname": "sequence_id", "fieldtype": "Float", - "label": "Sequence Id", - "read_only": 1 + "label": "Sequence Id" }, { "fieldname": "roles", @@ -219,7 +214,7 @@ ], "in_create": 1, "links": [], - "modified": "2024-05-30 17:30:36.791171", + "modified": "2024-08-26 17:16:05.820503", "modified_by": "Administrator", "module": "Desk", "name": "Workspace", diff --git a/frappe/desk/doctype/workspace/workspace.py b/frappe/desk/doctype/workspace/workspace.py index a4094dee96..7f8bcea15b 100644 --- a/frappe/desk/doctype/workspace/workspace.py +++ b/frappe/desk/doctype/workspace/workspace.py @@ -6,7 +6,7 @@ from json import loads import frappe from frappe import _ -from frappe.desk.desktop import save_new_widget +from frappe.desk.desktop import get_workspace_sidebar_items, save_new_widget from frappe.desk.utils import validate_route_conflict from frappe.model.document import Document from frappe.model.rename_doc import rename_doc @@ -261,7 +261,7 @@ def new_page(new_page): doc = frappe.new_doc("Workspace") doc.title = page.get("title") - doc.icon = page.get("icon") + doc.icon = page.get("icon") or "dashboard" doc.indicator_color = page.get("indicator_color") doc.content = page.get("content") doc.parent_page = page.get("parent_page") @@ -271,7 +271,7 @@ def new_page(new_page): doc.sequence_id = last_sequence_id(doc) + 1 doc.save(ignore_permissions=True) - return doc + return get_workspace_sidebar_items() @frappe.whitelist() @@ -341,65 +341,6 @@ def update_page(name, title, icon, indicator_color, parent, public): return {"name": title, "public": public, "label": new_name} -@frappe.whitelist() -def duplicate_page(page_name, new_page): - if not loads(new_page): - return - - new_page = loads(new_page) - - if new_page.get("is_public") and not is_workspace_manager(): - return - - old_doc = frappe.get_doc("Workspace", page_name) - doc = frappe.copy_doc(old_doc) - doc.title = new_page.get("title") - doc.icon = new_page.get("icon") - doc.indicator_color = new_page.get("indicator_color") - doc.parent_page = new_page.get("parent") or "" - doc.public = new_page.get("is_public") - doc.for_user = "" - doc.label = doc.title - doc.module = "" - if not doc.public: - doc.for_user = doc.for_user or frappe.session.user - doc.label = f"{doc.title}-{doc.for_user}" - doc.name = doc.label - if old_doc.public == doc.public: - doc.sequence_id += 0.1 - else: - doc.sequence_id = last_sequence_id(doc) + 1 - doc.insert(ignore_permissions=True) - - return doc - - -@frappe.whitelist() -def delete_page(page): - if not loads(page): - return - - page = loads(page) - - if page.get("public") and not is_workspace_manager(): - frappe.throw( - _("Cannot delete public workspace without Workspace Manager role"), - frappe.PermissionError, - ) - elif not page.get("public") and not is_workspace_manager(): - workspace_owner = frappe.get_value("Workspace", page.get("name"), "for_user") - if workspace_owner != frappe.session.user: - frappe.throw( - _("Cannot delete private workspace of other users"), - frappe.PermissionError, - ) - - if frappe.db.exists("Workspace", page.get("name")): - frappe.get_doc("Workspace", page.get("name")).delete(ignore_permissions=True) - - return {"name": page.get("name"), "public": page.get("public"), "title": page.get("title")} - - def last_sequence_id(doc): doc_exists = frappe.db.exists({"doctype": "Workspace", "public": doc.public, "for_user": doc.for_user}) diff --git a/frappe/public/js/frappe/form/sidebar/form_sidebar.js b/frappe/public/js/frappe/form/sidebar/form_sidebar.js index 4d62c62766..90fcf408f3 100644 --- a/frappe/public/js/frappe/form/sidebar/form_sidebar.js +++ b/frappe/public/js/frappe/form/sidebar/form_sidebar.js @@ -199,7 +199,9 @@ frappe.ui.form.Sidebar = class { return $("") .html(label) .appendTo( - $('
  • ').appendTo(this.user_actions.removeClass("hidden")) + $('
    ').appendTo( + this.user_actions.removeClass("hidden") + ) ) .on("click", click); } diff --git a/frappe/public/js/frappe/form/templates/form_footer.html b/frappe/public/js/frappe/form/templates/form_footer.html index 56c9c99b93..89a995569e 100644 --- a/frappe/public/js/frappe/form/templates/form_footer.html +++ b/frappe/public/js/frappe/form/templates/form_footer.html @@ -3,7 +3,7 @@
    - diff --git a/frappe/public/js/frappe/form/templates/form_sidebar.html b/frappe/public/js/frappe/form/templates/form_sidebar.html index 00d94d9c35..a6a19691bd 100644 --- a/frappe/public/js/frappe/form/templates/form_sidebar.html +++ b/frappe/public/js/frappe/form/templates/form_sidebar.html @@ -19,11 +19,11 @@ {% if frm.meta.beta %} -
    {% endif %} diff --git a/frappe/public/js/frappe/list/base_list.js b/frappe/public/js/frappe/list/base_list.js index c7ff5d49cf..4d4748a548 100644 --- a/frappe/public/js/frappe/list/base_list.js +++ b/frappe/public/js/frappe/list/base_list.js @@ -435,6 +435,20 @@ frappe.views.BaseList = class BaseList { }); } + set_result_height() { + // place it at the footer of the page + this.$result.css({ + height: + window.innerHeight - + this.$result.get(0).offsetTop - + this.$paging_area.get(0).offsetHeight + + "px", + }); + this.$no_result.css({ + height: window.innerHeight - this.$no_result.get(0).offsetTop + "px", + }); + } + get_fields() { // convert [fieldname, Doctype] => tabDoctype.fieldname return this.fields.map((f) => frappe.model.get_full_column_name(f[0], f[1])); @@ -516,6 +530,7 @@ frappe.views.BaseList = class BaseList { this.before_render(); this.render(); this.after_render(); + this.set_result_height(); this.freeze(false); this.reset_defaults(); if (this.settings.refresh) { @@ -581,8 +596,10 @@ frappe.views.BaseList = class BaseList { this.$paging_area.toggle(this.data.length > 0); this.$no_result.toggle(this.data.length == 0); - const show_more = this.start + this.page_length <= this.data.length; - this.$paging_area.find(".btn-more").toggle(show_more); + if (this.data.length) { + const show_more = this.start + this.page_length <= this.data.length; + this.$paging_area.find(".btn-more").toggle(show_more); + } } call_for_selected_items(method, args = {}) { diff --git a/frappe/public/js/frappe/list/list_sidebar.js b/frappe/public/js/frappe/list/list_sidebar.js index 804a39605e..6ad4e324e3 100644 --- a/frappe/public/js/frappe/list/list_sidebar.js +++ b/frappe/public/js/frappe/list/list_sidebar.js @@ -298,16 +298,8 @@ frappe.views.ListSidebar = class ListSidebar { const cta = "Frappe Insights"; this.insights_banner = $(` -
    -
    - ${message} ${cta} → -
    -
    - - - -
    + `).appendTo(this.sidebar); } catch (error) { diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js index 9e555fdc13..9cc265a8b7 100644 --- a/frappe/public/js/frappe/list/list_view.js +++ b/frappe/public/js/frappe/list/list_view.js @@ -106,8 +106,6 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { }); } - if (this.view_name == "List") this.toggle_paging = true; - this.patch_refresh_and_load_lib(); return this.get_list_view_settings(); } @@ -589,17 +587,11 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { sort_by: this.sort_selector && this.sort_selector.sort_by, sort_order: this.sort_selector && this.sort_selector.sort_order, }); - this.toggle_paging && this.$paging_area.toggle(false); } after_render() { - this.$no_result.html(` -
    - ${this.get_no_result_message()} -
    - `); + this.$no_result.html(this.get_no_result_message()); this.setup_new_doc_event(); - this.toggle_paging && this.$paging_area.toggle(true); } render() { @@ -610,6 +602,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { render_list() { // clear rows this.$result.find(".list-row-container").remove(); + this.render_header(); if (this.data.length > 0) { // append rows diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js index 0501ffe110..80a8917dd1 100644 --- a/frappe/public/js/frappe/router.js +++ b/frappe/public/js/frappe/router.js @@ -169,12 +169,6 @@ frappe.router = { } else if (route[0] == "private") { // private workspace let private_workspace = route[1] && `${route[1]}-${frappe.user.name.toLowerCase()}`; - if (!frappe.workspaces[private_workspace] && localStorage.new_workspace) { - let new_workspace = JSON.parse(localStorage.new_workspace); - if (frappe.router.slug(new_workspace.title) === route[1]) { - frappe.workspaces[private_workspace] = new_workspace; - } - } if (!frappe.workspaces[private_workspace]) { frappe.msgprint(__("Workspace {0} does not exist", [route[1]])); return ["Workspaces"]; diff --git a/frappe/public/js/frappe/ui/sidebar.js b/frappe/public/js/frappe/ui/sidebar.js index 58132e0017..d930c0e644 100644 --- a/frappe/public/js/frappe/ui/sidebar.js +++ b/frappe/public/js/frappe/ui/sidebar.js @@ -36,13 +36,20 @@ frappe.ui.Sidebar = class Sidebar { this.wrapper = $(`
    -