Merge pull request #22187 from cogk/ux-list-view-sort-columns

feat(list): Sort by column by clicking on col title
This commit is contained in:
mergify[bot] 2023-09-17 07:19:26 +00:00 committed by GitHub
commit 3239636e7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 21 deletions

View file

@ -634,7 +634,10 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
<span class="level-item list-liked-by-me hidden-xs">
<span title="${__("Likes")}">${frappe.utils.icon("heart", "sm", "like-icon")}</span>
</span>
<span class="level-item">${__(subject_field.label)}</span>
<span class="level-item" data-sort-by="${subject_field.fieldname}"
title="${__("Click to sort by {0}", [subject_field.label])}">
${__(subject_field.label)}
</span>
`;
const $columns = this.columns
.map((col) => {
@ -645,15 +648,21 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
frappe.model.is_numeric_field(col.df) ? "text-right" : "",
].join(" ");
return `
<div class="${classes}">
${
col.type === "Subject"
? subject_html
: `
<span>${__((col.df && col.df.label) || col.type)}</span>`
}
</div>
let html = "";
if (col.type === "Subject") {
html = subject_html;
} else {
const fieldname = col.df?.fieldname;
const attrs = fieldname
? ` data-sort-by="${fieldname}"
title="${__("Click to sort by {0}", [col.df?.label])}"`
: "";
html = `<span ${attrs}>
${__(col.df?.label || col.type)}
</span>`;
}
return `<div class="${classes}">${html}</div>
`;
})
.join("");
@ -1061,6 +1070,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();
@ -1202,6 +1212,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);

View file

@ -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) {

View file

@ -165,6 +165,11 @@
a {
color: var(--text-light);
}
& > [data-sort-by]:hover {
cursor: pointer;
text-decoration: underline;
}
}
$level-margin-right: 8px;