feat: Sidebar Attachments accessibility
- Issue: With a large volume of attachments, the "Attach File" button is pushed to the bottom - "Attach File" stays at the top of the pile - Small explore files button added so that users can use the File View to navigate/filter through files - Expanded Explore Files button when attach file action is hidden - Added `file_type` to Files, this is useful for filtering and visibility - Added "Type" to File List View - Patch to set File Type in all files
This commit is contained in:
parent
89b9b64a55
commit
fa241580d9
9 changed files with 126 additions and 16 deletions
|
|
@ -24,8 +24,7 @@ frappe.ui.form.on("File", {
|
|||
|
||||
preview_file: function (frm) {
|
||||
let $preview = "";
|
||||
let file_name = frm.doc.file_name.split("?")[0];
|
||||
let file_extension = file_name.split(".").pop()?.toLowerCase();
|
||||
let file_extension = frm.doc.file_type.toLowerCase();
|
||||
|
||||
if (frappe.utils.is_image_file(frm.doc.file_url)) {
|
||||
$preview = $(`<div class="img_preview">
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
"field_order": [
|
||||
"file_name",
|
||||
"is_private",
|
||||
"column_break_7jmm",
|
||||
"file_type",
|
||||
"preview",
|
||||
"preview_html",
|
||||
"section_break_5",
|
||||
|
|
@ -168,13 +170,25 @@
|
|||
"fieldtype": "Check",
|
||||
"label": "Uploaded To Google Drive",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_7jmm",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "file_type",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "File Type",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"force_re_route_to_default_view": 1,
|
||||
"icon": "fa fa-file",
|
||||
"idx": 1,
|
||||
"links": [],
|
||||
"modified": "2023-05-02 15:42:14.274901",
|
||||
"modified": "2023-07-26 14:03:49.456951",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "File",
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ class File(Document):
|
|||
content_hash: DF.Data | None
|
||||
file_name: DF.Data | None
|
||||
file_size: DF.Int
|
||||
file_type: DF.Data | None
|
||||
file_url: DF.Code | None
|
||||
folder: DF.Link | None
|
||||
is_attachments_folder: DF.Check
|
||||
|
|
@ -86,6 +87,7 @@ class File(Document):
|
|||
self.set_folder_name()
|
||||
self.set_file_name()
|
||||
self.validate_attachment_limit()
|
||||
self.set_file_type()
|
||||
|
||||
if self.is_folder:
|
||||
return
|
||||
|
|
@ -330,6 +332,15 @@ class File(Document):
|
|||
elif not self.is_home_folder:
|
||||
self.folder = "Home"
|
||||
|
||||
def set_file_type(self):
|
||||
if self.is_folder:
|
||||
return
|
||||
|
||||
file_name = self.file_name.split("?")[0]
|
||||
file_extension = file_name.split(".")[-1].upper() if file_name.split(".")[-1] else None
|
||||
if file_extension:
|
||||
self.file_type = file_extension
|
||||
|
||||
def validate_file_on_disk(self):
|
||||
"""Validates existence file"""
|
||||
full_path = self.get_full_path()
|
||||
|
|
|
|||
|
|
@ -227,3 +227,4 @@ execute:frappe.delete_doc_if_exists("Workspace", "Customization")
|
|||
execute:frappe.db.set_single_value("Document Naming Settings", "default_amend_naming", "Amend Counter")
|
||||
execute:frappe.delete_doc_if_exists("DocType", "Error Snapshot")
|
||||
frappe.patches.v15_0.move_event_cancelled_to_status
|
||||
frappe.patches.v15_0.set_file_type
|
||||
|
|
|
|||
18
frappe/patches/v15_0/set_file_type.py
Normal file
18
frappe/patches/v15_0/set_file_type.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import frappe
|
||||
|
||||
|
||||
def execute():
|
||||
"""Set 'File Type' for all files based on file extension."""
|
||||
files = frappe.db.get_all(
|
||||
"File",
|
||||
fields=["name", "file_name", "is_folder"],
|
||||
)
|
||||
|
||||
for file in files:
|
||||
if file.get("is_folder"):
|
||||
continue
|
||||
|
||||
file_name = file.get("file_name").split("?")[0]
|
||||
file_extension = file_name.split(".")[-1].upper() if file_name.split(".")[-1] else None
|
||||
if file_extension:
|
||||
frappe.db.set_value("File", file.get("name"), "file_type", file_extension)
|
||||
|
|
@ -11,7 +11,16 @@ frappe.ui.form.Attachments = class Attachments {
|
|||
this.parent.find(".add-attachment-btn").click(function () {
|
||||
me.new_attachment();
|
||||
});
|
||||
this.add_attachment_wrapper = this.parent.find(".add-attachment-btn");
|
||||
|
||||
this.parent.find(".explore-btn").click(() => {
|
||||
frappe.open_in_new_tab = true;
|
||||
frappe.set_route("List", "File", {
|
||||
attached_to_doctype: this.frm.doctype,
|
||||
attached_to_name: this.frm.docname,
|
||||
});
|
||||
});
|
||||
|
||||
this.add_attachment_wrapper = this.parent.find(".attachments-actions");
|
||||
this.attachments_label = this.parent.find(".attachments-label");
|
||||
}
|
||||
max_reached(raise_exception = false) {
|
||||
|
|
@ -42,6 +51,7 @@ frappe.ui.form.Attachments = class Attachments {
|
|||
|
||||
var max_reached = this.max_reached();
|
||||
this.add_attachment_wrapper.toggle(!max_reached);
|
||||
this.setup_expanded_explore_button(max_reached);
|
||||
|
||||
// add attachment objects
|
||||
var attachments = this.get_attachments();
|
||||
|
|
@ -57,11 +67,29 @@ frappe.ui.form.Attachments = class Attachments {
|
|||
});
|
||||
} else {
|
||||
this.attachments_label.removeClass("has-attachments");
|
||||
this.parent.find(".explore-btn").toggle(false); // hide explore icon button
|
||||
}
|
||||
}
|
||||
|
||||
setup_expanded_explore_button(max_reached) {
|
||||
if (!max_reached) {
|
||||
this.parent.find(".explore-full-btn").addClass("hidden");
|
||||
return;
|
||||
}
|
||||
|
||||
this.parent.find(".explore-full-btn").removeClass("hidden");
|
||||
this.parent.find(".explore-full-btn").click(() => {
|
||||
frappe.set_route("List", "File", {
|
||||
attached_to_doctype: this.frm.doctype,
|
||||
attached_to_name: this.frm.docname,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
get_attachments() {
|
||||
return this.frm.get_docinfo().attachments || [];
|
||||
}
|
||||
|
||||
add_attachment(attachment) {
|
||||
var file_name = attachment.file_name;
|
||||
var file_url = this.get_file_url(attachment);
|
||||
|
|
@ -101,8 +129,11 @@ frappe.ui.form.Attachments = class Attachments {
|
|||
|
||||
$(`<li class="attachment-row">`)
|
||||
.append(frappe.get_data_pill(file_label, fileid, remove_action, icon))
|
||||
.insertAfter(this.attachments_label.addClass("has-attachments"));
|
||||
.insertAfter(this.add_attachment_wrapper);
|
||||
|
||||
this.parent.find(".explore-btn").toggle(true); // show explore icon button if hidden
|
||||
}
|
||||
|
||||
get_file_url(attachment) {
|
||||
var file_url = attachment.file_url;
|
||||
if (!file_url) {
|
||||
|
|
|
|||
|
|
@ -54,17 +54,37 @@
|
|||
<li class="sidebar-label attachments-label">
|
||||
<svg class="icon icon-sm"><use href="#icon-attachment"></use></svg>
|
||||
{%= __("Attachments") %}
|
||||
|
||||
<li class="explore-full-btn hidden">
|
||||
<button class="data-pill btn">
|
||||
<span class="pill-label ellipsis">
|
||||
{%= __("Explore Files") %}
|
||||
</span>
|
||||
<svg class="icon icon-sm">
|
||||
<use href="#icon-projects"></use>
|
||||
</svg>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<li class="attachments-actions">
|
||||
<button class="data-pill btn add-attachment-btn">
|
||||
<span class="pill-label ellipsis">
|
||||
{%= __("Attach File") %}
|
||||
</span>
|
||||
<svg class="icon icon-sm">
|
||||
<use href="#icon-add"></use>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button class="text-muted btn btn-default icon-btn explore-btn">
|
||||
<svg class="icon icon-sm">
|
||||
<use href="#icon-projects"></use>
|
||||
</svg>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
</li>
|
||||
<li class="add-attachment-btn">
|
||||
<button class="data-pill btn">
|
||||
<span class="pill-label ellipsis">
|
||||
{%= __("Attach File") %}
|
||||
</span>
|
||||
<svg class="icon icon-sm">
|
||||
<use href="#icon-add"></use>
|
||||
</svg>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu form-reviews">
|
||||
<li class="sidebar-label reviews-label">
|
||||
|
|
|
|||
|
|
@ -319,6 +319,9 @@ frappe.views.FileView = class FileView extends frappe.views.ListView {
|
|||
? `<div class="list-row-col ellipsis hidden-xs">
|
||||
<span>${__("Size")}</span>
|
||||
</div>
|
||||
<div class="list-row-col ellipsis hidden-xs">
|
||||
<span>${__("Type")}</span>
|
||||
</div>
|
||||
<div class="list-row-col ellipsis hidden-xs">
|
||||
<span>${__("Created")}</span>
|
||||
</div>`
|
||||
|
|
@ -370,6 +373,9 @@ frappe.views.FileView = class FileView extends frappe.views.ListView {
|
|||
<div class="list-row-col ellipsis hidden-xs text-muted">
|
||||
<span>${file_size}</span>
|
||||
</div>
|
||||
<div class="list-row-col ellipsis hidden-xs text-muted">
|
||||
<span>${file.file_type || ""}</span>
|
||||
</div>
|
||||
<div class="list-row-col ellipsis hidden-xs text-muted">
|
||||
<span>${this.get_creation_date(file)}</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -389,7 +389,17 @@ body[data-route^="Module"] .main-menu {
|
|||
display: inline-flex;
|
||||
}
|
||||
|
||||
.add-attachment-btn,
|
||||
.attachments-actions {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.explore-full-btn,
|
||||
.attachments-actions {
|
||||
margin-bottom: var(--margin-md);
|
||||
}
|
||||
|
||||
.shares,
|
||||
.followed-by {
|
||||
max-width: 100%;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue