From c329e2c2ced232f6d490dbe7d03718dc496756b8 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Wed, 24 Aug 2022 16:13:14 +0530 Subject: [PATCH] feat: make attachments public on doctypes When this checkbox is checked, while uploading docs using fileuploader the default visibility will be set to "public". At present all uploaded attachments are private, however in following cases it makes sense to set default as public: 1. Blog post 2. Item catalog 3. Website item Considering this we decided to add this configurtion so developers can specify sane default while user still has control over it using "Customize form" Enabled this for "blog post" doctype Unrelatd change: consistent "form settings" section on DocType and customize form (cherry picked from commit e8af6b2c160bc4717651cd0bd2ab0c27ac5b3d35) --- cypress/integration/sidebar.js | 27 ++++++++++++++++- frappe/core/doctype/doctype/doctype.json | 9 +++++- .../customize_form/customize_form.json | 27 ++++++++++++++--- .../doctype/customize_form/customize_form.py | 1 + .../js/frappe/file_uploader/FileUploader.vue | 5 +++- .../public/js/frappe/file_uploader/index.js | 2 ++ .../public/js/frappe/form/controls/attach.js | 1 + .../js/frappe/form/sidebar/attachments.js | 1 + frappe/tests/ui_test_helpers.py | 30 +++++++++++++++++++ .../website/doctype/blog_post/blog_post.json | 3 +- 10 files changed, 98 insertions(+), 8 deletions(-) diff --git a/cypress/integration/sidebar.js b/cypress/integration/sidebar.js index 6ed2d4022c..ee724ffda2 100644 --- a/cypress/integration/sidebar.js +++ b/cypress/integration/sidebar.js @@ -1,11 +1,36 @@ +const verify_attachment_visibility = (document, is_private) => { + cy.visit(`/app/${document}`); + + const assertion = is_private ? "be.checked" : "not.be.checked"; + cy.findByRole("button", { name: "Attach File" }).click(); + + cy.get_open_dialog().find(".file-upload-area").attachFile("sample_image.jpg", { + subjectType: "drag-n-drop", + }); + + cy.get_open_dialog().findByRole("checkbox", { name: "Private" }).should(assertion); +}; + context("Sidebar", () => { before(() => { cy.visit("/login"); cy.login(); - cy.visit("/app/doctype"); + + return cy + .window() + .its("frappe") + .then((frappe) => { + return frappe.call("frappe.tests.ui_test_helpers.create_blog_post"); + }); + }); + + it("Verify attachment visibility config", () => { + verify_attachment_visibility("doctype/Blog Post", true); + verify_attachment_visibility("blog-post/test-blog-attachment-post", false); }); it('Test for checking "Assigned To" counter value, adding filter and adding & removing an assignment', () => { + cy.visit("/app/doctype"); cy.click_sidebar_button("Assigned To"); //To check if no filter is available in "Assigned To" dropdown diff --git a/frappe/core/doctype/doctype/doctype.json b/frappe/core/doctype/doctype/doctype.json index b7b93a8f37..bfa91cea75 100644 --- a/frappe/core/doctype/doctype/doctype.json +++ b/frappe/core/doctype/doctype/doctype.json @@ -44,6 +44,7 @@ "allow_import", "allow_events_in_timeline", "allow_auto_repeat", + "make_attachments_public", "view_settings", "title_field", "show_title_field_in_link", @@ -598,6 +599,12 @@ "fieldname": "translated_doctype", "fieldtype": "Check", "label": "Translate Link Fields" + }, + { + "default": "0", + "fieldname": "make_attachments_public", + "fieldtype": "Check", + "label": "Make Attachments Public by Default" } ], "icon": "fa fa-bolt", @@ -680,7 +687,7 @@ "link_fieldname": "reference_doctype" } ], - "modified": "2022-08-05 18:33:27.315351", + "modified": "2022-08-24 06:42:27.779699", "modified_by": "Administrator", "module": "Core", "name": "DocType", diff --git a/frappe/custom/doctype/customize_form/customize_form.json b/frappe/custom/doctype/customize_form/customize_form.json index d66d779963..05989eaa00 100644 --- a/frappe/custom/doctype/customize_form/customize_form.json +++ b/frappe/custom/doctype/customize_form/customize_form.json @@ -10,10 +10,8 @@ "doc_type", "properties", "label", - "max_attachments", "search_fields", "column_break_5", - "allow_copy", "istable", "editable_grid", "quick_entry", @@ -26,11 +24,16 @@ "naming_section", "naming_rule", "autoname", + "form_settings_section", + "image_field", + "max_attachments", + "column_break_21", + "allow_copy", + "make_attachments_public", "view_settings_section", "title_field", "show_title_field_in_link", "translated_doctype", - "image_field", "default_print_format", "column_break_29", "show_preview_popup", @@ -318,6 +321,22 @@ "fieldname": "translated_doctype", "fieldtype": "Check", "label": "Translate Link Fields" + }, + { + "collapsible": 1, + "fieldname": "form_settings_section", + "fieldtype": "Section Break", + "label": "Form Settings" + }, + { + "fieldname": "column_break_21", + "fieldtype": "Column Break" + }, + { + "default": "0", + "fieldname": "make_attachments_public", + "fieldtype": "Check", + "label": "Make Attachments Public by Default" } ], "hide_toolbar": 1, @@ -326,7 +345,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2022-08-04 15:36:16.772277", + "modified": "2022-08-24 06:57:47.966331", "modified_by": "Administrator", "module": "Custom", "name": "Customize Form", diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 32f0f165dc..cacd38397a 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -573,6 +573,7 @@ doctype_properties = { "quick_entry": "Check", "editable_grid": "Check", "max_attachments": "Int", + "make_attachments_public": "Check", "track_changes": "Check", "track_views": "Check", "allow_auto_repeat": "Check", diff --git a/frappe/public/js/frappe/file_uploader/FileUploader.vue b/frappe/public/js/frappe/file_uploader/FileUploader.vue index 11b7ef2a5a..0775b2f65d 100644 --- a/frappe/public/js/frappe/file_uploader/FileUploader.vue +++ b/frappe/public/js/frappe/file_uploader/FileUploader.vue @@ -167,6 +167,9 @@ export default { on_success: { default: null }, + make_attachments_public: { + default: null, + }, restrictions: { default: () => ({ max_file_size: null, // 2048 -> 2KB @@ -320,7 +323,7 @@ export default { request_succeeded: false, error_message: null, uploading: false, - private: true + private: !this.make_attachments_public, }; }); diff --git a/frappe/public/js/frappe/file_uploader/index.js b/frappe/public/js/frappe/file_uploader/index.js index 3508a44bc0..bb700f0b0d 100644 --- a/frappe/public/js/frappe/file_uploader/index.js +++ b/frappe/public/js/frappe/file_uploader/index.js @@ -18,6 +18,7 @@ export default class FileUploader { dialog_title, attach_doc_image, frm, + make_attachments_public, } = {}) { frm && frm.attachments.max_reached(true); @@ -45,6 +46,7 @@ export default class FileUploader { as_dataurl, disable_file_browser, attach_doc_image, + make_attachments_public, }, }), }); diff --git a/frappe/public/js/frappe/form/controls/attach.js b/frappe/public/js/frappe/form/controls/attach.js index 0c854f6a0a..fc8aef72b8 100644 --- a/frappe/public/js/frappe/form/controls/attach.js +++ b/frappe/public/js/frappe/form/controls/attach.js @@ -80,6 +80,7 @@ frappe.ui.form.ControlAttach = class ControlAttach extends frappe.ui.form.Contro options.doctype = this.frm.doctype; options.docname = this.frm.docname; options.fieldname = this.df.fieldname; + options.make_attachments_public = this.frm.meta.make_attachments_public; } if (this.df.options) { diff --git a/frappe/public/js/frappe/form/sidebar/attachments.js b/frappe/public/js/frappe/form/sidebar/attachments.js index 471b2db2ae..b7763c397d 100644 --- a/frappe/public/js/frappe/form/sidebar/attachments.js +++ b/frappe/public/js/frappe/form/sidebar/attachments.js @@ -175,6 +175,7 @@ frappe.ui.form.Attachments = class Attachments { this.attachment_uploaded(file_doc); }, restrictions, + make_attachments_public: this.frm.meta.make_attachments_public, }); } get_args() { diff --git a/frappe/tests/ui_test_helpers.py b/frappe/tests/ui_test_helpers.py index c43ec2e98a..f9be638385 100644 --- a/frappe/tests/ui_test_helpers.py +++ b/frappe/tests/ui_test_helpers.py @@ -367,3 +367,33 @@ def insert_translations(): for doc in translation: if not frappe.db.exists("doc"): frappe.get_doc(doc).insert() + + +@frappe.whitelist() +def create_blog_post(): + + blog_category = frappe.get_doc( + {"name": "general", "doctype": "Blog Category", "title": "general"} + ).insert(ignore_if_duplicate=True) + + blogger = frappe.get_doc( + { + "name": "attachment blogger", + "doctype": "Blogger", + "full_name": "attachment blogger", + "short_name": "attachment blogger", + } + ).insert(ignore_if_duplicate=True) + + doc = frappe.get_doc( + { + "name": "test-blog-attachment-post", + "doctype": "Blog Post", + "title": "test-blog-attachment-post", + "blog_category": blog_category.name, + "blogger": blogger.name, + "content_type": "Rich Text", + }, + ).insert(ignore_if_duplicate=True) + + return doc diff --git a/frappe/website/doctype/blog_post/blog_post.json b/frappe/website/doctype/blog_post/blog_post.json index cd88e655d2..dff5daf752 100644 --- a/frappe/website/doctype/blog_post/blog_post.json +++ b/frappe/website/doctype/blog_post/blog_post.json @@ -214,7 +214,8 @@ "index_web_pages_for_search": 1, "is_published_field": "published", "links": [], - "modified": "2022-07-12 17:40:10.221000", + "make_attachments_public": 1, + "modified": "2022-08-24 07:10:08.620136", "modified_by": "Administrator", "module": "Website", "name": "Blog Post",