diff --git a/addons/mrp/static/src/js/mrp.js b/addons/mrp/static/src/js/mrp.js index a40f43beabb..d078bffe1b4 100644 --- a/addons/mrp/static/src/js/mrp.js +++ b/addons/mrp/static/src/js/mrp.js @@ -2,22 +2,129 @@ odoo.define('mrp.mrp_state', function (require) { "use strict"; var AbstractField = require('web.AbstractField'); +var basic_fields = require('web.basic_fields'); var core = require('web.core'); -var time = require('web.time'); var field_registry = require('web.field_registry'); +var time = require('web.time'); +var utils = require('web.utils'); +var FieldBinaryFile = basic_fields.FieldBinaryFile; var _t = core._t; +var FieldPdfViewer = FieldBinaryFile.extend({ + supportedFieldTypes: ['binary'], + template: 'FieldPdfViewer', + /** + * @override + */ + init: function () { + this._super.apply(this, arguments); + this.PDFViewerApplication = false; + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + * @param {DOMElement} iframe + */ + _disableButtons: function (iframe) { + if (this.mode === 'readonly') { + $(iframe).contents().find('button#download').hide(); + } + $(iframe).contents().find('button#openFile').hide(); + }, + /** + * @private + * @returns {string} the pdf viewer URI + */ + _getURI: function () { + var queryObj = { + model: this.model, + field: this.name, + id: this.res_id, + }; + var queryString = $.param(queryObj); + var url = encodeURIComponent('/web/image?' + queryString); + var viewerURL = '/web/static/lib/pdfjs/web/viewer.html?file='; + return viewerURL + url; + }, + /** + * @private + * @override + */ + _render: function () { + var self = this; + var $pdfViewer = this.$('.o_form_pdf_controls').children().add(this.$('.o_pdfview_iframe')); + var $selectUpload = this.$('.o_select_file_button').first(); + var $iFrame = this.$('.o_pdfview_iframe'); + + $iFrame.on('load', function () { + self.PDFViewerApplication = this.contentWindow.window.PDFViewerApplication; + self._disableButtons(this); + }); + if (this.mode === "readonly" && this.value) { + $iFrame.attr('src', this._getURI()); + } else { + if (this.value) { + var binSize = utils.is_bin_size(this.value); + $pdfViewer.removeClass('o_hidden'); + $selectUpload.addClass('o_hidden'); + if (binSize) { + $iFrame.attr('src', this._getURI()); + } + } else { + $pdfViewer.addClass('o_hidden'); + $selectUpload.removeClass('o_hidden'); + } + } + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @override + * @private + * @param {Event} ev + */ + on_file_change: function (ev) { + this._super.apply(this, arguments); + if (this.PDFViewerApplication) { + var files = ev.target.files; + if (!files || files.length === 0) { + return; + } + var file = files[0]; + // TOCheck: is there requirement to fallback on FileReader if browser don't support URL + this.PDFViewerApplication.open(URL.createObjectURL(file), 0); + } + }, + /** + * Remove the behaviour of on_save_as in FieldBinaryFile. + * + * @override + * @private + * @param {MouseEvent} ev + */ + on_save_as: function (ev) { + ev.stopPropagation(); + }, + +}); var SetBulletStatus = AbstractField.extend({ - init: function() { + init: function () { this._super.apply(this, arguments); this.classes = this.nodeOptions && this.nodeOptions.classes || {}; }, - render_readonly: function() { + render_readonly: function () { this._super.apply(this, arguments); var bullet_class = this.classes[this.value] || 'default'; - if (this.value){ + if (this.value) { var title = this.value === 'waiting'? _t('Waiting Materials') : _t('Ready to produce'); this.$el.attr({'title': title, 'style': 'display:inline'}); this.$el.removeClass('text-success text-danger text-default'); @@ -27,12 +134,12 @@ var SetBulletStatus = AbstractField.extend({ }); var TimeCounter = AbstractField.extend({ - start_time_counter: function(){ + start_time_counter: function () { var self = this; clearTimeout(this.timer); if (this.record.data.is_user_working) { this.duration += 1000; - this.timer = setTimeout(function() { + this.timer = setTimeout(function () { self.start_time_counter(); }, 1000); } else { @@ -40,7 +147,7 @@ var TimeCounter = AbstractField.extend({ } this.$el.html($('' + moment.utc(this.duration).format("HH:mm:ss") + '')); }, - render: function() { + render: function () { var self = this; this._super.apply(this, arguments); var productivity_domain = [['workorder_id', '=', this.record.data.id], ['user_id', '=', self.session.uid]]; @@ -52,7 +159,7 @@ var TimeCounter = AbstractField.extend({ if (self.mode === "readonly") { var current_date = new Date(); self.duration = 0; - _.each(result, function(data) { + _.each(result, function (data) { self.duration += data.date_end ? self.get_date_difference(data.date_start, data.date_end) : self.get_date_difference(time.auto_str_to_date(data.date_start), current_date); }); self.start_time_counter(); @@ -60,11 +167,11 @@ var TimeCounter = AbstractField.extend({ }, }); }, - get_date_difference: function(date_start, date_end) { + get_date_difference: function (date_start, date_end) { var difference = moment(date_end).diff(moment(date_start)); return moment.duration(difference); }, - has_no_value: function() { + has_no_value: function () { return false; } }); @@ -72,6 +179,6 @@ var TimeCounter = AbstractField.extend({ field_registry .add('bullet_state', SetBulletStatus) .add('mrp_time_counter', TimeCounter) - .add('pdf_viewer', AbstractField); // TODO + .add('pdf_viewer', FieldPdfViewer); }); diff --git a/addons/mrp/static/src/xml/mrp.xml b/addons/mrp/static/src/xml/mrp.xml index 7f86a6a20dd..98e0ea126ed 100644 --- a/addons/mrp/static/src/xml/mrp.xml +++ b/addons/mrp/static/src/xml/mrp.xml @@ -2,7 +2,7 @@ - + Uploading... Upload your file diff --git a/addons/mrp/static/tests/mrp_tests.js b/addons/mrp/static/tests/mrp_tests.js new file mode 100644 index 00000000000..3502b438100 --- /dev/null +++ b/addons/mrp/static/tests/mrp_tests.js @@ -0,0 +1,79 @@ +odoo.define('mrp.tests', function (require) { +"use strict"; + +var FormView = require('web.FormView'); +var testUtils = require("web.test_utils"); + +var createView = testUtils.createView; + +QUnit.module('mrp', { + beforeEach: function () { + this.data = { + partner: { + fields: { + document: {string: "Document", type: "binary"}, + }, + records: [{ + id: 1, + document: 'coucou==\n', + }], + onchanges: {}, + }, + }; + }, +}, function () { + QUnit.test("pdf_viewer without data", function (assert) { + assert.expect(3); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: + '' + + '' + + '', + }); + + assert.ok(form.$('.o_form_field').hasClass('o_form_field_pdfviewer')); + assert.strictEqual(form.$('.o_select_file_button:not(.o_hidden)').length, 1, + "there should be a visible 'Upload' button"); + assert.ok(form.$('.o_form_field iframe.o_pdfview_iframe').hasClass('o_hidden'), + "there should be an invisible iframe"); + + form.destroy(); + }); + + QUnit.test("pdf_viewer: basic rendering", function (assert) { + assert.expect(4); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + res_id: 1, + arch: + '' + + '' + + '', + mockRPC: function (route) { + if (route.indexOf('/web/static/lib/pdfjs/web/viewer.html') !== -1) { + return $.when(); + } + return this._super.apply(this, arguments); + } + }); + + assert.ok(form.$('.o_form_field').hasClass('o_form_field_pdfviewer')); + assert.strictEqual(form.$('.o_select_file_button:not(.o_hidden)').length, 0, + "there should not be a any visible 'Upload' button"); + assert.notOk(form.$('.o_form_field iframe.o_pdfview_iframe').hasClass('o_hidden'), + "there should be an visible iframe"); + assert.strictEqual(form.$('.o_form_field iframe.o_pdfview_iframe').attr('src'), + '#test:/web/static/lib/pdfjs/web/viewer.html?file=%2Fweb%2Fimage%3Fmodel%3Dpartner%26field%3Ddocument%26id%3D1', + "the src attribute should be correctly set on the iframe"); + + form.destroy(); + }); +}); +}); diff --git a/addons/mrp/views/mrp_templates.xml b/addons/mrp/views/mrp_templates.xml index 7cf706e0bf4..f66d4d496a1 100644 --- a/addons/mrp/views/mrp_templates.xml +++ b/addons/mrp/views/mrp_templates.xml @@ -7,4 +7,10 @@ + + + + + + diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 852154def91..fec8dd8c7ee 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -1023,7 +1023,7 @@ - +