From 8e0932b20dadd1ac5f5fc467c91c849a1b66b6f6 Mon Sep 17 00:00:00 2001 From: sokumon Date: Mon, 31 Mar 2025 15:33:37 +0530 Subject: [PATCH 1/5] fix: add a more filter button --- .../js/frappe/views/reports/query_report.js | 54 +++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/views/reports/query_report.js b/frappe/public/js/frappe/views/reports/query_report.js index 50aea2336b..819ce83450 100644 --- a/frappe/public/js/frappe/views/reports/query_report.js +++ b/frappe/public/js/frappe/views/reports/query_report.js @@ -530,12 +530,16 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { const { filters = [] } = this.report_settings; let filter_area = this.page.page_form; + this.filters = []; + this.create_more_filter_button(filters); this.filters = filters - .map((df) => { + .map((df, index) => { if (df.fieldtype === "Break") return; let f = this.page.add_field(df, filter_area); - + if (index == 11) { + this.b = f; + } if (df.default) { f.set_input(df.default); } @@ -574,7 +578,9 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { return f; }) .filter(Boolean); - + this.hide_row(); + this.filters_hidden = true; + this.toggle_filter_visiblity(); this.refresh_filters_dependency(); if (this.filters.length === 0) { // hide page form if no filters @@ -584,6 +590,48 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { } } + hide_row() { + for (let i = 6; i < 11; i++) { + $(this.filters[i].wrapper).css("visibility", "hidden"); + } + } + create_more_filter_button(filters) { + const me = this; + this.hidden_buttons = []; + for (let i = 6; i < 12; i++) { + let button = { + fieldtype: "Button", + label: __("More Filters"), + }; + if (i == 11) { + button.click = function () { + if (me.filters_hidden) { + me.filters_hidden = false; + me.b.df.label = "Less Filters"; + me.b.refresh(); + } else { + me.filters_hidden = true; + me.b.df.label = "More Filters"; + me.b.refresh(); + } + me.toggle_filter_visiblity(); + }; + } + filters.splice(i, 0, button); + } + } + + toggle_filter_visiblity() { + if (this.filters_hidden) { + for (let i = 12; i < this.filters.length; i++) { + $(this.filters[i].wrapper).addClass("hidden"); + } + } else { + for (let i = 6; i < this.filters.length; i++) { + $(this.filters[i].wrapper).removeClass("hidden"); + } + } + } set_filters(filters) { this.filters.map((f) => { if (f.fieldtype == "MultiSelectList") { From 97890229ac45dd6f19929a024d6e1f1f326eb54c Mon Sep 17 00:00:00 2001 From: sokumon Date: Thu, 8 May 2025 10:45:24 +0530 Subject: [PATCH 2/5] refactor: collapsible button for filters, seperate row for check type filters --- frappe/public/icons/timeless/icons.svg | 6 ++ .../js/frappe/views/reports/query_report.js | 96 +++++++++++-------- frappe/public/scss/desk/report.scss | 4 + 3 files changed, 66 insertions(+), 40 deletions(-) diff --git a/frappe/public/icons/timeless/icons.svg b/frappe/public/icons/timeless/icons.svg index d6c409aada..b8dbde9d94 100644 --- a/frappe/public/icons/timeless/icons.svg +++ b/frappe/public/icons/timeless/icons.svg @@ -978,4 +978,10 @@ Tip: use lucide.svg in /icons for all downloaded icons + + + + + + diff --git a/frappe/public/js/frappe/views/reports/query_report.js b/frappe/public/js/frappe/views/reports/query_report.js index 819ce83450..8dbb10fafb 100644 --- a/frappe/public/js/frappe/views/reports/query_report.js +++ b/frappe/public/js/frappe/views/reports/query_report.js @@ -531,14 +531,15 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { let filter_area = this.page.page_form; this.filters = []; - this.create_more_filter_button(filters); + this.setup_check_filter_area(); this.filters = filters .map((df, index) => { if (df.fieldtype === "Break") return; - - let f = this.page.add_field(df, filter_area); - if (index == 11) { - this.b = f; + let f; + if (df.fieldtype === "Check") { + f = this.page.add_field(df, this.check_filter_area); + } else { + f = this.page.add_field(df, filter_area); } if (df.default) { f.set_input(df.default); @@ -578,9 +579,14 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { return f; }) .filter(Boolean); - this.hide_row(); - this.filters_hidden = true; - this.toggle_filter_visiblity(); + this.move_check_filter_area(); + this.filter_row_length = this.get_filter_row_length(); + if (this.report_settings.collapse_button) { + this.filters_hidden = true; + + this.add_collapse_button(); + this.toggle_filter_visiblity(); + } this.refresh_filters_dependency(); if (this.filters.length === 0) { // hide page form if no filters @@ -589,48 +595,58 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { this.page.show_form(); } } - - hide_row() { - for (let i = 6; i < 11; i++) { - $(this.filters[i].wrapper).css("visibility", "hidden"); - } + move_check_filter_area() { + this.page.page_form.append(this.check_filter_area); } - create_more_filter_button(filters) { - const me = this; - this.hidden_buttons = []; - for (let i = 6; i < 12; i++) { - let button = { - fieldtype: "Button", - label: __("More Filters"), - }; - if (i == 11) { - button.click = function () { - if (me.filters_hidden) { - me.filters_hidden = false; - me.b.df.label = "Less Filters"; - me.b.refresh(); - } else { - me.filters_hidden = true; - me.b.df.label = "More Filters"; - me.b.refresh(); - } - me.toggle_filter_visiblity(); - }; - } - filters.splice(i, 0, button); - } + setup_check_filter_area() { + let check_filter_area = "
"; + this.page.page_form.append(check_filter_area); + this.check_filter_area = this.page.page_form.find(".check-filter-area"); + } + get_filter_row_length() { + let max_width = document.documentElement.clientWidth; + let all_filters_position = this.filters.map((f) => f.wrapper.getBoundingClientRect().x); + let closest_width = all_filters_position.reduce(function (prev, curr) { + return Math.abs(curr - max_width) < Math.abs(prev - max_width) ? curr : prev; + }); + return all_filters_position.indexOf(closest_width) + 1; } - toggle_filter_visiblity() { + let icon_name; if (this.filters_hidden) { - for (let i = 12; i < this.filters.length; i++) { + for (let i = this.filter_row_length; i < this.filters.length; i++) { $(this.filters[i].wrapper).addClass("hidden"); } + this.check_filter_area.css("display", "none"); + this.filters_hidden = false; + icon_name = "chevron-down"; } else { - for (let i = 6; i < this.filters.length; i++) { + for (let i = this.filter_row_length; i < this.filters.length; i++) { $(this.filters[i].wrapper).removeClass("hidden"); } + this.filters_hidden = true; + icon_name = "chevron-up"; } + this.$collapse_button.find("use").attr("href", `#icon-${icon_name}`); + } + add_collapse_button() { + const me = this; + if (this.filters[this.filter_row_length - 1]) { + this.$collapse_button = $(this.get_button()); + $(this.filters[5].wrapper).append(this.$collapse_button); + $(this.filters[5].wrapper).css("display", "flex"); + $(this.filters[5].wrapper).css("align-items", "center"); + $(this.filters[5].wrapper).css("gap", "5px"); + this.$collapse_button.on("click", function () { + me.toggle_filter_visiblity(); + }); + } + } + get_button(icon_name) { + return `
+ ${frappe.utils.icon("chevron-down")} +
+ `; } set_filters(filters) { this.filters.map((f) => { diff --git a/frappe/public/scss/desk/report.scss b/frappe/public/scss/desk/report.scss index f5e0367a5b..aae8bbd5d2 100644 --- a/frappe/public/scss/desk/report.scss +++ b/frappe/public/scss/desk/report.scss @@ -297,3 +297,7 @@ .input-group > * { margin-right: 10px; } +.check-filter-area { + display: flex; + flex-wrap: wrap; +} From be3558b3d434e3bfbecf60967b038f7804449a0e Mon Sep 17 00:00:00 2001 From: sokumon Date: Thu, 8 May 2025 10:52:40 +0530 Subject: [PATCH 3/5] fix: make check filter area visible --- frappe/public/js/frappe/views/reports/query_report.js | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/public/js/frappe/views/reports/query_report.js b/frappe/public/js/frappe/views/reports/query_report.js index 8dbb10fafb..a99fde980a 100644 --- a/frappe/public/js/frappe/views/reports/query_report.js +++ b/frappe/public/js/frappe/views/reports/query_report.js @@ -624,6 +624,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { for (let i = this.filter_row_length; i < this.filters.length; i++) { $(this.filters[i].wrapper).removeClass("hidden"); } + this.check_filter_area.css("display", "flex"); this.filters_hidden = true; icon_name = "chevron-up"; } From 92725fa1f839d18e62c98d28196c5e90723d326d Mon Sep 17 00:00:00 2001 From: sokumon Date: Thu, 8 May 2025 12:22:43 +0530 Subject: [PATCH 4/5] fix: code cleanup --- .../js/frappe/views/reports/query_report.js | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/frappe/public/js/frappe/views/reports/query_report.js b/frappe/public/js/frappe/views/reports/query_report.js index a99fde980a..e8b07acde2 100644 --- a/frappe/public/js/frappe/views/reports/query_report.js +++ b/frappe/public/js/frappe/views/reports/query_report.js @@ -531,12 +531,12 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { let filter_area = this.page.page_form; this.filters = []; - this.setup_check_filter_area(); + if (this.report_settings.seperate_check_filters) this.setup_check_filter_area(); this.filters = filters .map((df, index) => { if (df.fieldtype === "Break") return; let f; - if (df.fieldtype === "Check") { + if (df.fieldtype === "Check" && this.check_filter_area) { f = this.page.add_field(df, this.check_filter_area); } else { f = this.page.add_field(df, filter_area); @@ -579,11 +579,10 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { return f; }) .filter(Boolean); - this.move_check_filter_area(); - this.filter_row_length = this.get_filter_row_length(); - if (this.report_settings.collapse_button) { + if (this.report_settings.seperate_check_filters) this.move_check_filter_area(); + if (this.report_settings.collapsible_filters) { this.filters_hidden = true; - + this.filter_row_length = this.get_filter_row_length(); this.add_collapse_button(); this.toggle_filter_visiblity(); } @@ -595,14 +594,17 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { this.page.show_form(); } } + move_check_filter_area() { this.page.page_form.append(this.check_filter_area); } + setup_check_filter_area() { let check_filter_area = "
"; this.page.page_form.append(check_filter_area); this.check_filter_area = this.page.page_form.find(".check-filter-area"); } + get_filter_row_length() { let max_width = document.documentElement.clientWidth; let all_filters_position = this.filters.map((f) => f.wrapper.getBoundingClientRect().x); @@ -611,6 +613,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { }); return all_filters_position.indexOf(closest_width) + 1; } + toggle_filter_visiblity() { let icon_name; if (this.filters_hidden) { @@ -630,25 +633,22 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { } this.$collapse_button.find("use").attr("href", `#icon-${icon_name}`); } + add_collapse_button() { const me = this; - if (this.filters[this.filter_row_length - 1]) { - this.$collapse_button = $(this.get_button()); - $(this.filters[5].wrapper).append(this.$collapse_button); - $(this.filters[5].wrapper).css("display", "flex"); - $(this.filters[5].wrapper).css("align-items", "center"); - $(this.filters[5].wrapper).css("gap", "5px"); + let filter_no = this.filter_row_length - 1; + if (this.filters[filter_no]) { + this.$collapse_button = $(`
${frappe.utils.icon("chevron-down")}
`); + $(this.filters[filter_no].wrapper).append(this.$collapse_button); + $(this.filters[filter_no].wrapper).css("display", "flex"); + $(this.filters[filter_no].wrapper).css("align-items", "center"); + $(this.filters[filter_no].wrapper).css("gap", "5px"); this.$collapse_button.on("click", function () { me.toggle_filter_visiblity(); }); } } - get_button(icon_name) { - return `
- ${frappe.utils.icon("chevron-down")} -
- `; - } + set_filters(filters) { this.filters.map((f) => { if (f.fieldtype == "MultiSelectList") { From ba869e718370aba1f7041226609a100943c20817 Mon Sep 17 00:00:00 2001 From: sokumon Date: Thu, 8 May 2025 14:33:21 +0530 Subject: [PATCH 5/5] fix(minor): drop icon can be md --- frappe/public/js/frappe/views/reports/query_report.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/views/reports/query_report.js b/frappe/public/js/frappe/views/reports/query_report.js index e8b07acde2..d41322e420 100644 --- a/frappe/public/js/frappe/views/reports/query_report.js +++ b/frappe/public/js/frappe/views/reports/query_report.js @@ -638,7 +638,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { const me = this; let filter_no = this.filter_row_length - 1; if (this.filters[filter_no]) { - this.$collapse_button = $(`
${frappe.utils.icon("chevron-down")}
`); + this.$collapse_button = $(`
${frappe.utils.icon("chevron-down", "md")}
`); $(this.filters[filter_no].wrapper).append(this.$collapse_button); $(this.filters[filter_no].wrapper).css("display", "flex"); $(this.filters[filter_no].wrapper).css("align-items", "center");