diff --git a/web_drop_target/README.rst b/web_drop_target/README.rst index af6e1867..1ba26d84 100644 --- a/web_drop_target/README.rst +++ b/web_drop_target/README.rst @@ -55,7 +55,6 @@ Known issues / Roadmap ====================== * dropping on list or kanban views would be nice too -* handle multiple files * add an upload progress meter for huge files * trigger custom events about different stages of the drop operation for other addons to hook in * Install document module to display attachments in the sidebar @@ -82,7 +81,11 @@ Contributors ~~~~~~~~~~~~ * Holger Brunn +<<<<<<< HEAD * Akim Juillerat +======= +* Pablo Fuentes +>>>>>>> 25dd8787... [IMP] web_drop_target: Upload multiple files Maintainers ~~~~~~~~~~~ diff --git a/web_drop_target/__manifest__.py b/web_drop_target/__manifest__.py index 3c357d1c..831725ac 100644 --- a/web_drop_target/__manifest__.py +++ b/web_drop_target/__manifest__.py @@ -10,8 +10,12 @@ "summary": "Allows to drag files into Odoo", "depends": [ 'web', + 'document' ], "data": [ 'views/templates.xml', ], + "qweb": [ + 'static/src/xml/widgets.xml', + ] } diff --git a/web_drop_target/static/src/css/web_drop_target.css b/web_drop_target/static/src/css/web_drop_target.css deleted file mode 100644 index e69de29b..00000000 diff --git a/web_drop_target/static/src/js/web_drop_target.js b/web_drop_target/static/src/js/web_drop_target.js index 27099d05..fadbd208 100644 --- a/web_drop_target/static/src/js/web_drop_target.js +++ b/web_drop_target/static/src/js/web_drop_target.js @@ -4,16 +4,17 @@ odoo.define('web_drop_target', function(require) { var FormController = require('web.FormController'); + var core = require('web.core'); + var qweb = core.qweb; // this is the main contribution of this addon: A mixin you can use // to make some widget a drop target. Read on how to use this yourself var DropTargetMixin = { // add the mime types you want to support here, leave empty for - // all types. For more control, override _get_drop_item in your class + // all types. For more control, override _get_drop_items in your class _drop_allowed_types: [], - // a class being applied when the user drags something we can handle - _drag_over_class: 'o_drag_over', + _drop_overlay: null, start: function() { var result = this._super.apply(this, arguments); @@ -25,45 +26,45 @@ odoo.define('web_drop_target', function(require) { }, _on_drop: function(e) { - var drop_item = this._get_drop_item(e); - if(!drop_item || !(drop_item.getAsFile() instanceof Blob)) { - return; - } - jQuery(e.delegateTarget).removeClass(this._drag_over_class); - var reader = new FileReader(); - reader.onloadend = this.proxy( - _.partial(this._handle_file_drop, drop_item.getAsFile()) - ); - reader.readAsArrayBuffer(drop_item.getAsFile()); - e.stopPropagation(); + var self = this; + var drop_items = this._get_drop_items(e); + _.each(drop_items, function(drop_item) { + var reader = new FileReader(); + reader.onloadend = self.proxy( + _.partial(self._handle_file_drop, drop_item.getAsFile()) + ); + reader.readAsArrayBuffer(drop_item.getAsFile()); + }); + this._remove_overlay(); e.preventDefault(); }, _on_dragenter: function(e) { - if(this._get_drop_item(e)) { + if(this._get_drop_items(e).length) { e.preventDefault(); - jQuery(e.delegateTarget).addClass(this._drag_over_class); + this._add_overlay(); return false; } }, _on_dragleave: function(e) { - jQuery(e.delegateTarget).removeClass(this._drag_over_class); + this._remove_overlay(); + e.preventDefault(); }, - _get_drop_item: function(e) { + _get_drop_items: function(e) { var self = this, dataTransfer = e.originalEvent.dataTransfer, - drop_item = null; + drop_items = []; _.each(dataTransfer.items, function(item) { if( _.contains(self._drop_allowed_types, item.type) || _.isEmpty(self._drop_allowed_types) ) { - drop_item = item; + drop_items.push(item); } }); - return drop_item; + return drop_items; }, // eslint-disable-next-line no-unused-vars @@ -104,7 +105,30 @@ odoo.define('web_drop_target', function(require) { } } }); - } + }, + + _add_overlay() { + if(!this._drop_overlay){ + var o_content = jQuery('.o_content'), + view_manager = jQuery('.o_view_manager_content'); + this._drop_overlay = jQuery( + qweb.render('web_drop_target.drop_overlay') + ); + var o_content_position = o_content.position(); + this._drop_overlay.css({ + 'top': o_content_position.top, + 'left': o_content_position.left, + 'width': view_manager.width(), + 'height': view_manager.height() + }); + o_content.append(this._drop_overlay); + } + }, + + _remove_overlay() { + this._drop_overlay.remove(); + this._drop_overlay = null; + }, }; // and here we apply the mixin to form views, allowing any files and diff --git a/web_drop_target/static/src/less/web_drop_target.less b/web_drop_target/static/src/less/web_drop_target.less new file mode 100644 index 00000000..97dc557d --- /dev/null +++ b/web_drop_target/static/src/less/web_drop_target.less @@ -0,0 +1,19 @@ +.o_content { + .o_drag_over{ + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(255,255,255,0.6); + border: 1px dashed #4c4c4c; + pointer-events: none; + .o_drag_over_content{ + position: relative; + top: 50%; + transform: translate(0%, -50%); + width: 100%; + text-align: center; + } + } +} diff --git a/web_drop_target/static/src/xml/widgets.xml b/web_drop_target/static/src/xml/widgets.xml new file mode 100644 index 00000000..50142051 --- /dev/null +++ b/web_drop_target/static/src/xml/widgets.xml @@ -0,0 +1,17 @@ + + + + diff --git a/web_drop_target/views/templates.xml b/web_drop_target/views/templates.xml index 318dc7ab..850ad5a1 100644 --- a/web_drop_target/views/templates.xml +++ b/web_drop_target/views/templates.xml @@ -4,7 +4,7 @@ - +