feat: let's copy data to clipboard from listview and reportview
This commit is contained in:
parent
370efbd3e8
commit
c0606abfd3
1 changed files with 164 additions and 0 deletions
|
|
@ -2296,6 +2296,170 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
|
|||
};
|
||||
};
|
||||
|
||||
const copy_to_clipboard = () => {
|
||||
return {
|
||||
label: __("Copy to Clipboard"),
|
||||
action: () => {
|
||||
const selected_items = this.get_checked_items();
|
||||
if (selected_items.length === 0) {
|
||||
frappe.show_alert({
|
||||
message: __("No rows selected"),
|
||||
indicator: "orange",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let columns;
|
||||
if (
|
||||
this.columns &&
|
||||
this.columns.length &&
|
||||
(this.columns[0].docfield || this.columns[0].type == "Status")
|
||||
) {
|
||||
// Report View - has columns with docfield property
|
||||
columns = this.columns.map((col) => ({
|
||||
fieldname: col.id || col.field,
|
||||
label: col.content || col.name,
|
||||
docfield: col.docfield, // Keep the docfield for link field processing
|
||||
}));
|
||||
} else if (this.columns && this.columns.length && this.columns[0].type) {
|
||||
// List View - has columns with type and df properties
|
||||
console.log(this.columns);
|
||||
columns = this.columns
|
||||
.filter((col) => {
|
||||
// Include columns with df.fieldname, or Subject/Status types
|
||||
return (
|
||||
(col.df && col.df.fieldname) ||
|
||||
col.type === "Subject" ||
|
||||
col.type === "Status"
|
||||
);
|
||||
})
|
||||
.map((col) => {
|
||||
if (col.type === "Subject") {
|
||||
return {
|
||||
fieldname: col.df?.fieldname || "name",
|
||||
label: __(col.df?.label || "ID"),
|
||||
type: "Subject",
|
||||
};
|
||||
} else if (col.type === "Status") {
|
||||
return {
|
||||
fieldname: "status",
|
||||
label: __("Status"),
|
||||
type: "Status",
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
fieldname: col.df.fieldname,
|
||||
label: __(col.df.label || col.df.fieldname),
|
||||
type: col.type,
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Prepare data for clipboard
|
||||
const headers = columns.map((col) => col.label).join("\t");
|
||||
const rows = selected_items.map((item) => {
|
||||
return columns
|
||||
.map((col) => {
|
||||
console.log("Processing column:", col.fieldname, "col:", col);
|
||||
let value;
|
||||
const df = col.df || col.docfield;
|
||||
|
||||
// Check if this is a Status column (by type) or docstatus field (in Report view)
|
||||
if (col.type === "Status" || col.fieldname === "docstatus") {
|
||||
// For Status columns, get the indicator text
|
||||
const indicator = frappe.get_indicator(item, this.doctype);
|
||||
if (indicator && indicator.length > 0) {
|
||||
value = indicator[0];
|
||||
} else {
|
||||
// Fallback to status field
|
||||
value = item.status || "";
|
||||
}
|
||||
} else {
|
||||
// Check if this is a link field with title field
|
||||
const link_title_fieldname =
|
||||
this.link_field_title_fields?.[col.fieldname];
|
||||
if (link_title_fieldname) {
|
||||
// List view: Use the title field value if available
|
||||
value =
|
||||
item[col.fieldname + "_" + link_title_fieldname] ||
|
||||
item[col.fieldname];
|
||||
console.log(
|
||||
"List view link:",
|
||||
col.fieldname,
|
||||
"title_field:",
|
||||
link_title_fieldname,
|
||||
"value:",
|
||||
value
|
||||
);
|
||||
} else if (
|
||||
df &&
|
||||
df.fieldtype === "Link" &&
|
||||
df.options &&
|
||||
item[col.fieldname]
|
||||
) {
|
||||
// For Link fields, try to get the title
|
||||
console.log(
|
||||
"Processing link field:",
|
||||
col.fieldname,
|
||||
"doctype:",
|
||||
df.options,
|
||||
"item value:",
|
||||
item[col.fieldname],
|
||||
"item:",
|
||||
item
|
||||
);
|
||||
// First check if the doctype has show_title_field_in_link enabled
|
||||
if (
|
||||
frappe.boot.link_title_doctypes?.includes(df.options)
|
||||
) {
|
||||
// Try to get from cache
|
||||
let link_title = frappe.utils.get_link_title(
|
||||
df.options,
|
||||
item[col.fieldname]
|
||||
);
|
||||
console.log(
|
||||
"Link field:",
|
||||
col.fieldname,
|
||||
"doctype:",
|
||||
df.options,
|
||||
"value:",
|
||||
item[col.fieldname],
|
||||
"cached title:",
|
||||
link_title,
|
||||
"cache key:",
|
||||
df.options + "::" + item[col.fieldname]
|
||||
);
|
||||
value = link_title || item[col.fieldname];
|
||||
} else {
|
||||
value = item[col.fieldname];
|
||||
}
|
||||
} else {
|
||||
value = item[col.fieldname];
|
||||
}
|
||||
}
|
||||
// Handle null/undefined values
|
||||
if (value == null) return "";
|
||||
// Convert to string and remove HTML tags if any
|
||||
return String(value).replace(/<[^>]*>/g, "");
|
||||
})
|
||||
.join("\t");
|
||||
});
|
||||
const clipboard_data = [headers, ...rows].join("\n"); // Copy to clipboard
|
||||
frappe.utils.copy_to_clipboard(clipboard_data).then(() => {
|
||||
frappe.show_alert({
|
||||
message: __("{0} row(s) copied to clipboard", [selected_items.length]),
|
||||
indicator: "green",
|
||||
});
|
||||
});
|
||||
},
|
||||
standard: true,
|
||||
};
|
||||
};
|
||||
|
||||
// Copy to clipboard
|
||||
actions_menu_items.push(copy_to_clipboard());
|
||||
|
||||
// bulk edit
|
||||
if (has_editable_fields(doctype) && is_bulk_edit_allowed(doctype)) {
|
||||
actions_menu_items.push(bulk_edit());
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue