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:
commit
3239636e7d
3 changed files with 59 additions and 21 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -165,6 +165,11 @@
|
|||
a {
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
& > [data-sort-by]:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
$level-margin-right: 8px;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue