diff --git a/cypress/integration/workspace_blocks.js b/cypress/integration/workspace_blocks.js index ba707499c9..d6aceae8f4 100644 --- a/cypress/integration/workspace_blocks.js +++ b/cypress/integration/workspace_blocks.js @@ -71,6 +71,11 @@ context('Workspace Blocks', () => { } ]); + cy.intercept({ + method: 'GET', + url: 'api/method/frappe.desk.form.load.getdoctype' + }).as('get_doctype'); + cy.get('.codex-editor__redactor .ce-block'); cy.get('.standard-actions .btn-secondary[data-label=Edit]').click(); @@ -82,6 +87,7 @@ context('Workspace Blocks', () => { cy.fill_field('document_type', 'ToDo', 'Link').blur(); cy.fill_field('label', 'ToDo', 'Data').blur(); + cy.wait('@get_doctype'); cy.get_open_dialog().find('.filter-edit-area').should('contain', 'No filters selected'); cy.get_open_dialog().find('.filter-area .add-filter').click(); @@ -102,7 +108,7 @@ context('Workspace Blocks', () => { cy.get('@todo-quick-list').find('.quick-list-item .status').should('contain', 'Open'); // test filter-list - cy.get('@todo-quick-list').find('.widget-control .filter-list').click(); + cy.get('@todo-quick-list').realHover().find('.widget-control .filter-list').click(); cy.get_open_dialog().find('select.input-with-feedback').select('Closed'); cy.get_open_dialog().find('.modal-header').click(); @@ -117,12 +123,12 @@ context('Workspace Blocks', () => { url: 'api/method/frappe.desk.reportview.get' }).as('refresh-list'); - cy.get('@todo-quick-list').find('.widget-control .refresh-list').click(); + cy.get('@todo-quick-list').realHover().find('.widget-control .refresh-list').click(); cy.wait('@refresh-list'); // test add-new - cy.get('@todo-quick-list').find('.widget-control .add-new').click(); + cy.get('@todo-quick-list').realHover().find('.widget-control .add-new').click(); cy.url().should('include', `/todo/new-todo-1`); cy.go('back'); diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 7686626fea..61ddb33af1 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -1,6 +1,7 @@ import 'cypress-file-upload'; import '@testing-library/cypress/add-commands'; import '@4tw/cypress-drag-drop'; +import "cypress-real-events/support"; // *********************************************** // This example commands.js shows you how to // create various custom commands and overwrite diff --git a/frappe/commands/utils.py b/frappe/commands/utils.py index 499dd61421..663f1a6f7c 100644 --- a/frappe/commands/utils.py +++ b/frappe/commands/utils.py @@ -870,7 +870,7 @@ def run_ui_tests( # install cypress click.secho("Installing Cypress...", fg="yellow") frappe.commands.popen( - "yarn add cypress@^6 cypress-file-upload@^5 @4tw/cypress-drag-drop@^2 @testing-library/cypress@^8 @cypress/code-coverage@^3 --no-lockfile" + "yarn add cypress@^6 cypress-file-upload@^5 @4tw/cypress-drag-drop@^2 cypress-real-events @testing-library/cypress@^8 @cypress/code-coverage@^3 --no-lockfile" ) # run for headless mode diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js index 1b038b6265..39e6555654 100644 --- a/frappe/public/js/frappe/router.js +++ b/frappe/public/js/frappe/router.js @@ -59,10 +59,12 @@ $('body').on('click', 'a', function(e) { if (frappe.router.is_app_route(e.currentTarget.pathname)) { // target has "/app, this is a v2 style route. - frappe.route_options = {}; - let params = new URLSearchParams(e.currentTarget.search); - for (const [key, value] of params) { - frappe.route_options[key] = value; + if (e.currentTarget.search) { + frappe.route_options = {}; + let params = new URLSearchParams(e.currentTarget.search); + for (const [key, value] of params) { + frappe.route_options[key] = value; + } } return override(e.currentTarget.pathname + e.currentTarget.hash); } diff --git a/frappe/public/js/frappe/widgets/quick_list_widget.js b/frappe/public/js/frappe/widgets/quick_list_widget.js index ce81333147..f59443efe3 100644 --- a/frappe/public/js/frappe/widgets/quick_list_widget.js +++ b/frappe/public/js/frappe/widgets/quick_list_widget.js @@ -104,6 +104,7 @@ export default class QuickListWidget extends Widget { if (old_filter != me.quick_list_filter) { me.body.empty(); + me.set_footer(); me.set_body(); } }, @@ -191,6 +192,10 @@ export default class QuickListWidget extends Widget { if (this.has_status_field) { fields.push('status'); fields.push('docstatus'); + + // add workflow state field if workflow exist & is active + let workflow_fieldname = frappe.workflow.get_state_fieldname(this.document_type); + workflow_fieldname && fields.push(workflow_fieldname); } fields.push('modified'); @@ -230,18 +235,15 @@ export default class QuickListWidget extends Widget { } set_footer() { - if (!this.see_all_button) { - this.see_all_button = $(` -
See all
- `).appendTo(this.footer); + this.footer.empty(); - this.see_all_button.click(() => { - let filters = frappe.utils.get_filter_from_json(this.quick_list_filter); - if (filters) { - frappe.route_options = filters; - } - frappe.set_route(frappe.utils.generate_route({type: 'doctype', name: this.document_type})); - }); + let filters = frappe.utils.get_filter_from_json(this.quick_list_filter); + if (filters) { + frappe.route_options = filters; } + let route = frappe.utils.generate_route({type: 'doctype', name: this.document_type}); + this.see_all_button = $(` + View List + `).appendTo(this.footer); } } diff --git a/frappe/public/scss/desk/desktop.scss b/frappe/public/scss/desk/desktop.scss index bd363cc49d..695273e7a9 100644 --- a/frappe/public/scss/desk/desktop.scss +++ b/frappe/public/scss/desk/desktop.scss @@ -734,6 +734,27 @@ body { } } + &:hover { + .widget-head .widget-control { + width: auto; + visibility: visible; + opacity: 1; + } + } + + .widget-head { + .widget-label { + padding-left: 6px; + } + + .widget-control { + width: 0px; + visibility: hidden; + opacity: 0; + transition: visibility 0s, opacity 0.5s ease-in-out; + } + } + .widget-body { display: flex; flex-direction: column; @@ -757,7 +778,6 @@ body { display: flex; flex-direction: column; flex: 1; - margin-left: 3px; .timestamp { font-size: smaller; @@ -770,14 +790,16 @@ body { .right-arrow { margin-left: 6px; + margin-right: -2px; } } } .widget-footer { .see-all { - background-color: var(--btn-default-bg); width: 100%; + text-decoration: none; + background-color: var(--btn-default-bg); &:hover { background-color: var(--btn-default-hover-bg);