Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add multiple buttons (dropdown) in listview row #26162

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
70 changes: 66 additions & 4 deletions frappe/public/js/frappe/list/list_view.js
Expand Up @@ -315,6 +315,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
this.update_checkbox();
this.update_url_with_filters();
this.setup_realtime_updates();
this.apply_styles_basedon_dropdown();
});
}

Expand Down Expand Up @@ -915,8 +916,10 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {

get_meta_html(doc) {
let html = "";
let settings_button = "";
let button_section = "";
const dropdown_button = this.generate_dropdown_html(doc);

let settings_button = null;
if (this.settings.button && this.settings.button.show(doc)) {
settings_button = `
<span class="list-actions">
Expand All @@ -929,6 +932,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
`;
}

button_section = settings_button + dropdown_button;
const modified = comment_when(doc.modified, true);

let assigned_to = ``;
Expand All @@ -950,13 +954,13 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {

html += `
<div class="level-item list-row-activity hidden-xs">
<div class="hidden-md hidden-xs">
${settings_button || assigned_to}
<div class="hidden-md hidden-xs d-flex">
${button_section || assigned_to}
</div>
<span class="modified">${modified}</span>
${comment_count || ""}
${comment_count ? '<span class="mx-2">·</span>' : ""}
<span class="list-row-like hidden-xs style="margin-bottom: 1px;">
<span class="list-row-like hidden-xs" style="margin-bottom: 1px;">
${this.get_like_html(doc)}
</span>
</div>
Expand All @@ -968,6 +972,47 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
return html;
}

generate_dropdown_html(doc) {
let dropdown_button = "";
if (this.settings.dropdown_button) {
let button_actions = "";
this.settings.dropdown_button.buttons.forEach((button, index) => {
if (!button.show || button.show(doc)) {
let description = button.get_description ? button.get_description(doc) : "";
button_actions += `
<a class="dropdown-item" href="#" onclick="return false;" data-idx="${doc._idx}" button-idx="${index}" title="${description}">
${button.get_label}
</a>
`;
}
});

if (button_actions) {
dropdown_button = `
<div class="inner-group-button mr-2" data-name="${doc.name}" data-label="${
this.settings.dropdown_button.get_label
}">
<button type="button" class="btn btn-xs btn-default ellipsis" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
${this.settings.dropdown_button.get_label}
${frappe.utils.icon("select", "xs")}
</button>
<div role="menu" class="dropdown-menu">${button_actions}</div>
</div>
`;
}
}
return dropdown_button;
}

apply_styles_basedon_dropdown() {
if ($(".list-actions").length > 0 && $(".inner-group-button").length > 0) {
$(".list-row .level-left, .list-row-head .level-left").css({
flex: "2",
"min-width": "72%",
});
}
}

get_count_str() {
let current_count = this.data.length;
let count_without_children = this.data.uniqBy((d) => d.name).length;
Expand Down Expand Up @@ -1277,6 +1322,9 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
this.on_row_checked();
return;
}

if ($target.is("[data-toggle='dropdown']")) return true;

// don't open form when checkbox, like, filterable are clicked
if (
$target.hasClass("filterable") ||
Expand Down Expand Up @@ -1342,6 +1390,20 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
e.stopPropagation();
return false;
});

this.$result.on("click", ".inner-group-button .dropdown-item", (e) => {
const $button = $(e.currentTarget);
const doc = this.data[$button.attr("data-idx")];
const btn_idx = parseInt($button.attr("button-idx"), 10);
const button = this.settings.dropdown_button.buttons[btn_idx];

if (button && button.action) {
button.action(doc);
}

e.stopPropagation();
return false;
});
}

setup_check_events() {
Expand Down