From bcaea4932d6add18d0da07996057bc7d322f9189 Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 7 Jul 2021 16:30:56 +0530 Subject: [PATCH] fix: Filters state, Search input clearing, Paging buttons - Fixed repetitive calls on checking filter checkbox - Query count of items after offset for accurate Paging button display - Order items by ranking in query - Search results get empty on clearing input --- erpnext/e_commerce/product_query.py | 16 ++++++++---- erpnext/e_commerce/product_search.js | 9 +++++-- erpnext/e_commerce/product_view.js | 39 ++++++++++++++++------------ 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/erpnext/e_commerce/product_query.py b/erpnext/e_commerce/product_query.py index 3c03f7e4065..76cb30e2174 100644 --- a/erpnext/e_commerce/product_query.py +++ b/erpnext/e_commerce/product_query.py @@ -123,12 +123,17 @@ class ProductQuery: def query_items(self, start=0): """Build a query to fetch Website Items based on field filters.""" - count = frappe.db.get_all( + # MySQL does not support offset without limit, + # frappe does not accept two parameters for limit + # https://dev.mysql.com/doc/refman/8.0/en/select.html#id4651989 + count_items = frappe.db.get_all( "Website Item", - fields=["count(*) as count"], filters=self.filters, or_filters=self.or_filters, - limit_start=start)[0].get("count") + limit_page_length=184467440737095516, + limit_start=start, # get all items from this offset for total count ahead + order_by="ranking desc") + count = len(count_items) items = frappe.db.get_all( "Website Item", @@ -136,9 +141,10 @@ class ProductQuery: filters=self.filters, or_filters=self.or_filters, limit_page_length=self.page_length, - limit_start=start) + limit_start=start, + order_by="ranking desc") - return items, count or 0 + return items, count def query_items_with_attributes(self, attributes, start=0): """Build a query to fetch Website Items based on field & attribute filters.""" diff --git a/erpnext/e_commerce/product_search.js b/erpnext/e_commerce/product_search.js index e537688199d..8466b4f58c8 100644 --- a/erpnext/e_commerce/product_search.js +++ b/erpnext/e_commerce/product_search.js @@ -39,6 +39,11 @@ erpnext.ProductSearch = class { this.searchBox.on("input", (e) => { let query = e.target.value; + if (query.length == 0) { + me.populateResults([]); + me.populateCategoriesList([]); + } + if (query.length < 3 || !query.length) return; // Populate recent search chips @@ -191,7 +196,7 @@ erpnext.ProductSearch = class { } populateResults(data) { - if (data.message.results.length === 0) { + if (data.length === 0 || data.message.results.length === 0) { let empty_html = `
${ __('No results') } @@ -220,7 +225,7 @@ erpnext.ProductSearch = class { } populateCategoriesList(data) { - if (data.message.results.length === 0) { + if (data.length === 0 || data.message.results.length === 0) { let empty_html = ` ${__('No results')} diff --git a/erpnext/e_commerce/product_view.js b/erpnext/e_commerce/product_view.js index 67fc91395b6..c083991dc18 100644 --- a/erpnext/e_commerce/product_view.js +++ b/erpnext/e_commerce/product_view.js @@ -10,10 +10,10 @@ erpnext.ProductView = class { this.make(); } - make() { + make(from_filters=false) { this.products_section.empty(); this.prepare_view_toggler(); - this.get_item_filter_data(); + this.get_item_filter_data(from_filters); } prepare_view_toggler() { @@ -24,7 +24,7 @@ erpnext.ProductView = class { } } - get_item_filter_data() { + get_item_filter_data(from_filters=false) { // Get and render all Product related views let me = this; let args = this.get_query_filters(); @@ -43,16 +43,25 @@ erpnext.ProductView = class { if (!result.message["items"].length) { // if result has no items or result is empty me.render_no_products_section(); - - me.bind_filters(); - me.restore_filters_state(); } else { - me.render_filters(result.message["filters"]); + // Add discount filters + me.get_discount_filter_html(result.message["filters"].discount_filters); // Render views me.render_list_view(result.message["items"], result.message["settings"]); me.render_grid_view(result.message["items"], result.message["settings"]); + me.products = result.message["items"]; + me.product_count = result.message["items_count"]; + } + + // Bind filter actions + if (!from_filters) { + // If `get_product_filter_data` was triggered after checking a filter, + // don't touch filters unnecessarily, only data must change + // filter persistence is handle on filter change event + me.bind_filters(); + me.restore_filters_state(); } // Bottom paging @@ -71,12 +80,6 @@ erpnext.ProductView = class { $('#image-view').prop('disabled', disable); } - render_filters(filter_data) { - this.get_discount_filter_html(filter_data.discount_filters); - this.bind_filters(); - this.restore_filters_state(); - } - render_grid_view(items, settings) { // loop over data and add grid html to it let me = this; @@ -143,10 +146,9 @@ erpnext.ProductView = class { let query_params = frappe.utils.get_query_params(); let start = query_params.start ? cint(JSON.parse(query_params.start)) : 0; let page_length = settings.products_per_page || 0; - let no_of_products = this.products.length; let prev_disable = start > 0 ? "" : "disabled"; - let next_disable = (no_of_products > page_length || no_of_products == page_length) ? "" : "disabled"; + let next_disable = (this.product_count > page_length) ? "" : "disabled"; paging_html += `