diff --git a/frappe/public/js/frappe/list/list_renderer.js b/frappe/public/js/frappe/list/list_renderer.js index e9bba83918..762b7b860f 100644 --- a/frappe/public/js/frappe/list/list_renderer.js +++ b/frappe/public/js/frappe/list/list_renderer.js @@ -3,9 +3,10 @@ frappe.provide('frappe.views'); -// Renders customized list -// usually based on `in_list_view` property - +/** +* Renders customized list. Usually based on `in_list_view` property. +* It carries information that is used in frappe.views.ListView +*/ frappe.views.ListRenderer = Class.extend({ name: 'List', init: function (opts) { @@ -38,6 +39,7 @@ frappe.views.ListRenderer = Class.extend({ // default settings this.order_by = this.order_by || 'modified desc'; + this.group_by = this.group_by || ''; this.filters = this.filters || []; this.page_length = this.page_length || 20; }, @@ -53,6 +55,7 @@ frappe.views.ListRenderer = Class.extend({ this.init_user_settings(); this.order_by = this.user_settings.order_by || this.settings.order_by; + this.group_by = this.get_group_by(); this.filters = this.user_settings.filters || this.settings.filters; this.page_length = this.settings.page_length; @@ -61,6 +64,16 @@ frappe.views.ListRenderer = Class.extend({ this.filters = [[this.doctype, "docstatus", "!=", 2]]; } }, + + /** + * Get the name of the column to use in SQL `group by`. + * It defaults to 'creation' + */ + get_group_by: function() { + const default_column = this.settings.group_by || 'creation'; + const group_by = $.format('`tab{0}`.`{1}`', [this.doctype, default_column]); + return group_by; + }, init_user_settings: function () { frappe.provide('frappe.model.user_settings.' + this.doctype + '.' + this.name); this.user_settings = frappe.get_user_settings(this.doctype)[this.name]; diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js index 881c1b62ca..be2934319f 100644 --- a/frappe/public/js/frappe/list/list_view.js +++ b/frappe/public/js/frappe/list/list_view.js @@ -536,16 +536,22 @@ frappe.views.ListView = frappe.ui.BaseList.extend({ }) }, + /* + * Prepares extra information for the SQL query to fetch + * records for the list view. + */ get_args: function () { var args = { doctype: this.doctype, fields: this.list_renderer.fields, filters: this.get_filters_args(), order_by: this.get_order_by_args(), + group_by: this.list_renderer.group_by, with_comment_count: true } return args; }, + get_filters_args: function() { var filters = []; if(this.filter_list) { diff --git a/frappe/public/js/frappe/ui/base_list.js b/frappe/public/js/frappe/ui/base_list.js index 0d3b1957e8..494e2d6656 100644 --- a/frappe/public/js/frappe/ui/base_list.js +++ b/frappe/public/js/frappe/ui/base_list.js @@ -265,6 +265,10 @@ frappe.ui.BaseList = Class.extend({ this.onreset && this.onreset(); }, + /* + * Uses the value of `frappe.route_options` to automatically set + * a filter in a list view. + */ set_filters_from_route_options: function ({clear_filters=true} = {}) { var me = this; if(this.filter_list && clear_filters) { @@ -368,8 +372,12 @@ frappe.ui.BaseList = Class.extend({ } } }, + + /* + * Prepares arguments that will be used to query the database to + * return the desired records for the list view + */ get_call_args: function () { - // load query if (!this.method) { var query = this.get_query && this.get_query() || this.query; query = this.add_limits(query); diff --git a/frappe/public/js/frappe/ui/filters/filters.js b/frappe/public/js/frappe/ui/filters/filters.js index 2ff8b51d5a..ce513bd73e 100644 --- a/frappe/public/js/frappe/ui/filters/filters.js +++ b/frappe/public/js/frappe/ui/filters/filters.js @@ -46,6 +46,9 @@ frappe.ui.FilterList = Class.extend({ } }, + /* + * Removes all filters. + */ clear_filters: function() { $.each(this.filters, function(i, f) { f.remove(true); }); if(this.base_list.page.fields_dict) { @@ -56,6 +59,15 @@ frappe.ui.FilterList = Class.extend({ this.filters = []; }, + /* + * Adds a new filter. + * @param {string} doctype + * @param {string} fieldname + * @param {string} condition + * @param {string} value + * @param {string} hidden + * @returns {Boolean} - Returns true if filter is added + */ add_filter: function(doctype, fieldname, condition, value, hidden) { // adds a new filter, returns true if filter has been added