From 08da14996faa1185665d936b67131089dda31a2b Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Fri, 7 Apr 2017 13:37:08 +0530 Subject: [PATCH] Enhance multi file upload (#2912) * Allow multiple file upload, show progress while uploading * Enhance multi file upload You can now upload files programmatically like ``` frappe.upload.make({ ... files: fileobj_array, ... }) ``` No need to use `multifile_upload` method. Multiple file upload is enabled by default on all Attach dialogs. * Don't `allow_multiple` in data import tool * ControlAttach don't allow_multiple * Show files in a table view * Narrow width for Is Private column --- .../page/data_import_tool/data_import_tool.js | 1 + frappe/public/css/desk.css | 13 +- frappe/public/js/frappe/form/control.js | 1 + .../js/frappe/form/footer/attachments.js | 1 + frappe/public/js/frappe/ui/upload.html | 4 +- frappe/public/js/frappe/upload.js | 196 ++++++++++++++---- frappe/public/js/legacy/form.js | 8 +- frappe/public/less/desk.less | 16 +- frappe/utils/file_manager.py | 1 + 9 files changed, 195 insertions(+), 46 deletions(-) diff --git a/frappe/core/page/data_import_tool/data_import_tool.js b/frappe/core/page/data_import_tool/data_import_tool.js index a98877c392..e461203fdd 100644 --- a/frappe/core/page/data_import_tool/data_import_tool.js +++ b/frappe/core/page/data_import_tool/data_import_tool.js @@ -119,6 +119,7 @@ frappe.DataImportTool = Class.extend({ args: { method: 'frappe.core.page.data_import_tool.importer.upload', }, + allow_multiple: 0, onerror: function(r) { me.onerror(r); }, diff --git a/frappe/public/css/desk.css b/frappe/public/css/desk.css index b8e3009073..5c4359f239 100644 --- a/frappe/public/css/desk.css +++ b/frappe/public/css/desk.css @@ -569,8 +569,19 @@ fieldset[disabled] .form-control { display: inline-block; vertical-align: middle; } +.file-upload .input-upload { + vertical-align: top; +} +.file-upload .uploaded-filename { + border: 1px solid #d1d8dd; + border-radius: 3px; +} +.file-upload .uploaded-filename .btn-group { + margin-right: 5px; + margin-bottom: 5px; +} .file-upload .uploaded-filename-display { - max-width: 194px; + max-width: 150px; } .frappe-rtl input, .frappe-rtl textarea { diff --git a/frappe/public/js/frappe/form/control.js b/frappe/public/js/frappe/form/control.js index 9144ba9931..7ba068dbb5 100644 --- a/frappe/public/js/frappe/form/control.js +++ b/frappe/public/js/frappe/form/control.js @@ -1000,6 +1000,7 @@ frappe.ui.form.ControlAttach = frappe.ui.form.ControlData.extend({ this.upload_options = { parent: this.dialog.get_field("upload_area").$wrapper, args: {}, + allow_multiple: 0, max_width: this.df.max_width, max_height: this.df.max_height, options: this.df.options, diff --git a/frappe/public/js/frappe/form/footer/attachments.js b/frappe/public/js/frappe/form/footer/attachments.js index 13645e7083..59138c5500 100644 --- a/frappe/public/js/frappe/form/footer/attachments.js +++ b/frappe/public/js/frappe/form/footer/attachments.js @@ -234,6 +234,7 @@ frappe.ui.get_upload_dialog = function(opts){ } }, callback: function(r){ + if(!r.message) return; dialog.$wrapper.find('[name="file_url"]').val(r.message.file_url); dialog.$wrapper.find('.private-file input').prop('checked', r.message.is_private); opts.args.filename = r.message.file_name diff --git a/frappe/public/js/frappe/ui/upload.html b/frappe/public/js/frappe/ui/upload.html index 23b4a8b4de..08977e0be0 100644 --- a/frappe/public/js/frappe/ui/upload.html +++ b/frappe/public/js/frappe/ui/upload.html @@ -1,9 +1,9 @@
- +
- + +
+ ` + return $(template); + }, + upload_multiple_files: function(files /*FileData array*/, args, opts) { + var i = -1; + + // upload the first file + upload_next(); + // subsequent files will be uploaded after + // upload_complete event is fired for the previous file + $(document).on('upload_complete', on_upload); + + function upload_next() { + i += 1; + var file = files[i]; + args.is_private = file.is_private; + frappe.upload.upload_file(file, args, opts); + frappe.show_progress(__('Uploading'), i+1, files.length); + } + + function on_upload(e, attachment) { + if (i === files.length - 1) { + $(document).off('upload_complete', on_upload); + frappe.hide_progress(); + return; + } + upload_next(); + } + }, upload_file: function(fileobj, args, opts) { if(!fileobj && !args.file_url) { if(opts.on_no_attach) { @@ -153,7 +270,7 @@ frappe.upload = { }, upload_to_server: function(fileobj, args, opts, dataurl) { - var msgbox = msgprint(__("Uploading...")); + // var msgbox = msgprint(__("Uploading...")); if(opts.start) { opts.start(); } @@ -162,11 +279,12 @@ frappe.upload = { args: args, callback: function(r) { if(!r._server_messages) { - msgbox.hide(); + // msgbox.hide(); } if(r.exc) { // if no onerror, assume callback will handle errors opts.onerror ? opts.onerror(r) : opts.callback(null, r); + frappe.hide_progress(); return; } var attachment = r.message; @@ -177,6 +295,7 @@ frappe.upload = { error: function(r) { // if no onerror, assume callback will handle errors opts.onerror ? opts.onerror(r) : opts.callback(null, null, r); + frappe.hide_progress(); return; } } @@ -216,7 +335,7 @@ frappe.upload = { for (var i =0,j = fileobjs.length;i