From f45edfbe6d03b15977392dda9561cd7a3e16ce34 Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Mon, 23 Oct 2017 11:53:29 +0200 Subject: [PATCH] [FIX] web: image widget is dependent on its record's last_update As a way to optimize loading, images are not necessarily fetched in db. They have, in their url a "unique" parameter, which is the last_update date on **the record** and controls on the python-side whether it should get the image from a cache or from the db. Before this commit, this __last_update field wasn't present in the view, so it wasn't fetched, and writes on a model's image worked but did not refresh. The image displayed was the old one. After this commit, when the image field widget is present, we force the loading of the __last_update field of the record. Upon update, the image displayed is the new one. OPW 777552 closes #20457 --- addons/web/static/src/js/fields/abstract_field.js | 9 +++++++++ addons/web/static/src/js/fields/basic_fields.js | 7 ++++++- addons/web/static/src/js/services/data_manager.js | 14 ++++++++++++++ .../web/static/tests/fields/basic_fields_tests.js | 9 +++++++-- 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/js/fields/abstract_field.js b/addons/web/static/src/js/fields/abstract_field.js index 957d8233410..07918f8cbd0 100644 --- a/addons/web/static/src/js/fields/abstract_field.js +++ b/addons/web/static/src/js/fields/abstract_field.js @@ -40,6 +40,15 @@ var AbstractField = Widget.extend({ custom_events: { navigation_move: '_onNavigationMove', }, + + /** + * An object representing fields to be fetched by the model eventhough not present in the view + * This object contains "field name" as key and an object as value. + * That value object must contain the key "type" + * see FieldBinaryImage for an example. + */ + fieldDependencies: {}, + /** * If this flag is set to true, the field widget will be reset on every * change which is made in the view (if the view supports it). This is diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 7a7b3fa370f..ce1a305277f 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -21,6 +21,7 @@ var framework = require('web.framework'); var session = require('web.session'); var utils = require('web.utils'); var view_dialogs = require('web.view_dialogs'); +var field_utils = require('web.field_utils'); var qweb = core.qweb; var _t = core._t; @@ -1127,6 +1128,10 @@ var AbstractFieldBinary = AbstractField.extend({ }); var FieldBinaryImage = AbstractFieldBinary.extend({ + fieldDependencies: _.extend({}, AbstractFieldBinary.prototype.fieldDependencies, { + __last_update: {type: 'datetime'}, + }), + template: 'FieldBinaryImage', placeholder: "/web/static/src/img/placeholder.png", events: _.extend({}, AbstractFieldBinary.prototype.events, { @@ -1149,7 +1154,7 @@ var FieldBinaryImage = AbstractFieldBinary.extend({ id: JSON.stringify(this.res_id), field: this.nodeOptions.preview_image || this.name, // unique forces a reload of the image when the record has been updated - unique: (this.recordData.__last_update || '').replace(/[^0-9]/g, ''), + unique: field_utils.format.datetime(this.recordData.__last_update).replace(/[^0-9]/g, ''), }); } } diff --git a/addons/web/static/src/js/services/data_manager.js b/addons/web/static/src/js/services/data_manager.js index 4bf1748fbab..7e938770ba3 100644 --- a/addons/web/static/src/js/services/data_manager.js +++ b/addons/web/static/src/js/services/data_manager.js @@ -377,6 +377,11 @@ return core.Class.extend({ } } } + + if (attrs.Widget.prototype.fieldDependencies) { + attrs.fieldDependencies = attrs.Widget.prototype.fieldDependencies; + } + return attrs; }, /** @@ -397,6 +402,15 @@ return core.Class.extend({ if (node.tag === 'field') { fieldsInfo[node.attrs.name] = self._processField(viewType, fields[node.attrs.name], node.attrs ? _.clone(node.attrs) : {}); + + if (fieldsInfo[node.attrs.name].fieldDependencies) { + var deps = fieldsInfo[node.attrs.name].fieldDependencies; + for (var dependency_name in deps) { + if (!(dependency_name in fieldsInfo)) { + fieldsInfo[dependency_name] = {'name': dependency_name, 'type': deps[dependency_name].type}; + } + } + } return false; } return node.tag !== 'arch'; diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js index f05d7abf08e..1d1eccf207d 100644 --- a/addons/web/static/tests/fields/basic_fields_tests.js +++ b/addons/web/static/tests/fields/basic_fields_tests.js @@ -1427,8 +1427,10 @@ QUnit.module('basic_fields', { QUnit.module('FieldImage'); QUnit.test('image fields are correctly rendered', function (assert) { - assert.expect(5); + assert.expect(6); + this.data.partner.fields.__last_update = {string: "Last updated", type: "datetime"}; + this.data.partner.records[0].__last_update = '2017-02-08 10:00:00'; this.data.partner.records[0].document = 'myimage'; var form = createView({ @@ -1439,7 +1441,10 @@ QUnit.module('basic_fields', { ' ' + '', res_id: 1, - mockRPC: function (route) { + mockRPC: function (route, args) { + if (route === '/web/dataset/call_kw/partner/read') { + assert.deepEqual(args.args[1], ['document', '__last_update', 'display_name'], "The fields document, display_name and __last_update should be present when reading an image"); + } if (route === 'data:image/png;base64,myimage') { assert.ok(true, "should called the correct route"); return $.when('wow');