From bd32719d32f8c20db76d74f1648fad86e87d5f81 Mon Sep 17 00:00:00 2001 From: Corentin Forler <10946971+cogk@users.noreply.github.com> Date: Thu, 24 Aug 2023 16:44:55 +0200 Subject: [PATCH 1/3] refactor(SortSelector): Add method set_value(by, order) --- frappe/public/js/frappe/ui/sort_selector.js | 31 +++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/frappe/public/js/frappe/ui/sort_selector.js b/frappe/public/js/frappe/ui/sort_selector.js index eb59bec8c7..88fc32d8a3 100644 --- a/frappe/public/js/frappe/ui/sort_selector.js +++ b/frappe/public/js/frappe/ui/sort_selector.js @@ -23,26 +23,35 @@ frappe.ui.SortSelector = class SortSelector { // order this.wrapper.find(".btn-order").on("click", function () { - let btn = $(this); const order = $(this).attr("data-value") === "desc" ? "asc" : "desc"; - const title = - $(this).attr("data-value") === "desc" ? __("ascending") : __("descending"); - - btn.attr("data-value", order); - btn.attr("title", title); - me.sort_order = order; - const icon_name = order === "asc" ? "sort-ascending" : "sort-descending"; - btn.find(".sort-order").html(frappe.utils.icon(icon_name, "sm")); + me.set_value(me.sort_by, order); (me.onchange || me.change)(me.sort_by, me.sort_order); }); // select field this.wrapper.find(".dropdown-menu a.option").on("click", function () { - me.sort_by = $(this).attr("data-value"); - me.wrapper.find(".dropdown-text").html($(this).html()); + me.set_value($(this).attr("data-value"), me.sort_order); (me.onchange || me.change)(me.sort_by, me.sort_order); }); } + set_value(sort_by, sort_order) { + const $btn = this.wrapper.find(".btn-order"); + const $icon = $btn.find(".sort-order"); + const $text = this.wrapper.find(".dropdown-text"); + + if (this.sort_by !== sort_by) { + this.sort_by = sort_by; + $text.html(__(this.get_label(sort_by))); + } + if (this.sort_order !== sort_order) { + this.sort_order = sort_order; + const title = sort_order === "desc" ? __("ascending") : __("descending"); + const icon_name = sort_order === "asc" ? "sort-ascending" : "sort-descending"; + $btn.attr("data-value", sort_order); + $btn.attr("title", title); + $icon.html(frappe.utils.icon(icon_name, "sm")); + } + } prepare_args() { var me = this; if (!this.args) { From 601478cb900e728b832a71d69eb919be7144912b Mon Sep 17 00:00:00 2001 From: Corentin Forler <10946971+cogk@users.noreply.github.com> Date: Thu, 24 Aug 2023 16:47:51 +0200 Subject: [PATCH 2/3] feat(list): Sort by column by clicking on col title --- frappe/public/js/frappe/list/list_view.js | 40 +++++++++++++++++------ frappe/public/scss/desk/list.scss | 5 +++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js index b6c1e8ae5b..23ab7aee9c 100644 --- a/frappe/public/js/frappe/list/list_view.js +++ b/frappe/public/js/frappe/list/list_view.js @@ -634,7 +634,9 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { - ${__(subject_field.label)} + + ${__(subject_field.label)} + `; const $columns = this.columns .map((col) => { @@ -645,15 +647,18 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { frappe.model.is_numeric_field(col.df) ? "text-right" : "", ].join(" "); - return ` -
- ${ - col.type === "Subject" - ? subject_html - : ` - ${__((col.df && col.df.label) || col.type)}` - } -
+ let html = ""; + if (col.type === "Subject") { + html = subject_html; + } else { + const fieldname = col.df?.fieldname; + const attrs = fieldname ? ` data-sort-by="${fieldname}"` : ""; + html = ` + ${__(col.df?.label || col.type)} + `; + } + + return `
${html}
`; }) .join(""); @@ -1046,6 +1051,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { setup_events() { this.setup_filterable(); + this.setup_sort_by(); this.setup_list_click(); this.setup_drag_click(); this.setup_tag_event(); @@ -1187,6 +1193,20 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { }); } + setup_sort_by() { + this.$result.on("click", "[data-sort-by]", (e) => { + const sort_by = e.currentTarget.getAttribute("data-sort-by"); + if (!sort_by) return; + let sort_order = "asc"; // always start with asc + if (this.sort_by === sort_by) { + // unless it's the same field, then toggle + sort_order = this.sort_order === "asc" ? "desc" : "asc"; + } + this.sort_selector.set_value(sort_by, sort_order); + this.on_sort_change(sort_by, sort_order); + }); + } + setup_list_click() { this.$result.on("click", ".list-row, .image-view-header, .file-header", (e) => { const $target = $(e.target); diff --git a/frappe/public/scss/desk/list.scss b/frappe/public/scss/desk/list.scss index d464e6dec1..f65e65741b 100644 --- a/frappe/public/scss/desk/list.scss +++ b/frappe/public/scss/desk/list.scss @@ -165,6 +165,11 @@ a { color: var(--text-light); } + + & > [data-sort-by]:hover { + cursor: pointer; + text-decoration: underline; + } } $level-margin-right: 8px; From a8fadf1208429ddea6823314eb72456affce5de3 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Sat, 2 Sep 2023 15:48:47 +0530 Subject: [PATCH 3/3] fix(UX): add `title` for sort functionality --- frappe/public/js/frappe/list/list_view.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js index 7b4882a52e..a578312e34 100644 --- a/frappe/public/js/frappe/list/list_view.js +++ b/frappe/public/js/frappe/list/list_view.js @@ -634,7 +634,8 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { - + ${__(subject_field.label)} `; @@ -652,8 +653,11 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { html = subject_html; } else { const fieldname = col.df?.fieldname; - const attrs = fieldname ? ` data-sort-by="${fieldname}"` : ""; - html = ` + const attrs = fieldname + ? ` data-sort-by="${fieldname}" + title="${__("Click to sort by {0}", [col.df?.label])}"` + : ""; + html = ` ${__(col.df?.label || col.type)} `; }