From a63a953a2dd216d313a7adaeb21345f5258247fa Mon Sep 17 00:00:00 2001 From: Tejas Shahu Date: Mon, 20 Aug 2018 13:27:54 +0000 Subject: [PATCH] [FIX] web: translation issue fixed Before this commit: Editing a translatable field -> clicking on a translation warning -> come back through breadcrumb do not preserve translation warning. After this commit: Editing a translatable field -> clicking on a translation warning -> come back through breadcrumb preserves translation warning. Technical note: alertFields is now an object and an attribute of the form renderer that stores translation alerts per record. The translation alerts created for a given record are maintained unless they are closed manually or the renderer is destroyed. Issue-ID: 1877480 Co-authored-by: Mohammed Shekha closes odoo/odoo#29377 --- .../src/js/views/form/form_controller.js | 9 +- .../static/src/js/views/form/form_renderer.js | 45 ++++-- addons/web/static/src/xml/base.xml | 2 +- addons/web/static/tests/views/form_tests.js | 147 +++++++++++++++++- 4 files changed, 184 insertions(+), 19 deletions(-) diff --git a/addons/web/static/src/js/views/form/form_controller.js b/addons/web/static/src/js/views/form/form_controller.js index 625bca3cc5e..6b6baa1ec74 100644 --- a/addons/web/static/src/js/views/form/form_controller.js +++ b/addons/web/static/src/js/views/form/form_controller.js @@ -216,17 +216,16 @@ var FormController = BasicController.extend({ // are displayed with an alert var fields = self.renderer.state.fields; var data = self.renderer.state.data; - var alertFields = []; + var alertFields = {}; for (var k = 0; k < changedFields.length; k++) { var field = fields[changedFields[k]]; var fieldData = data[changedFields[k]]; if (field.translate && fieldData) { - alertFields.push(field); + alertFields[changedFields[k]] = field; } } - if (alertFields.length) { - self.renderer.alertFields = alertFields; - self.renderer.displayTranslationAlert(); + if (!_.isEmpty(alertFields)) { + self.renderer.updateAlertFields(alertFields); } } return changedFields; diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js index 232da4d25c1..6ceafa5d43b 100644 --- a/addons/web/static/src/js/views/form/form_renderer.js +++ b/addons/web/static/src/js/views/form/form_renderer.js @@ -13,6 +13,7 @@ var FormRenderer = BasicRenderer.extend({ className: "o_form_view", events: _.extend({}, BasicRenderer.prototype.events, { 'click .o_notification_box .oe_field_translate': '_onTranslate', + 'click .o_notification_box .close': '_onTranslateNotificationClose', 'click .oe_title, .o_inner_group': '_onClick', }), custom_events: _.extend({}, BasicRenderer.prototype.custom_events, { @@ -30,6 +31,7 @@ var FormRenderer = BasicRenderer.extend({ this._super.apply(this, arguments); this.idsForLabels = {}; this.lastActivatedFieldIndex = -1; + this.alertFields = {}; }, /** * @override @@ -103,23 +105,32 @@ var FormRenderer = BasicRenderer.extend({ }); return fieldNames; }, + /* + * Updates translation alert fields for the current state and display updated fields + * + * @param {Object} alertFields + */ + updateAlertFields: function (alertFields) { + this.alertFields[this.state.res_id] = _.extend(this.alertFields[this.state.res_id] || {}, alertFields); + this.displayTranslationAlert(); + }, /** * Show a warning message if the user modified a translated field. For each * field, the notification provides a link to edit the field's translations. - * - * @param {Object[]} alertFields field list */ displayTranslationAlert: function () { this.$('.o_notification_box').remove(); - var $notification = $(qweb.render('notification-box', {type: 'info'})) - .append(qweb.render('translation-alert', { - fields: this.alertFields, - lang: _t.database.parameters.name - })); - if (this.$('.o_form_statusbar').length) { - this.$('.o_form_statusbar').after($notification); - } else { - this.$el.prepend($notification); + if (this.alertFields[this.state.res_id]) { + var $notification = $(qweb.render('notification-box', {type: 'info'})) + .append(qweb.render('translation-alert', { + fields: this.alertFields[this.state.res_id], + lang: _t.database.parameters.name + })); + if (this.$('.o_form_statusbar').length) { + this.$('.o_form_statusbar').after($notification); + } else { + this.$el.prepend($notification); + } } }, /** @@ -865,6 +876,9 @@ var FormRenderer = BasicRenderer.extend({ return $.when.apply($, defs).then(function () { self._updateView($form.contents()); + if (self.state.res_id in self.alertFields) { + self.displayTranslationAlert(); + } }, function () { $form.remove(); }).then(function(){ @@ -970,6 +984,15 @@ var FormRenderer = BasicRenderer.extend({ event.preventDefault(); this.trigger_up('translate', {fieldName: event.target.name, id: this.state.id}); }, + /** + * remove alert fields of record from alertFields object + * + * @private + * @param {MouseEvent} ev + */ + _onTranslateNotificationClose: function(ev) { + delete this.alertFields[this.state.res_id]; + }, }); return FormRenderer; diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 49c3aa73b6e..26fad2dfd40 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -1326,7 +1326,7 @@
Please update translations of : - , + ,
diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index 53a46b2a558..3f7c3d942bd 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -15,6 +15,7 @@ var Widget = require('web.Widget'); var _t = core._t; var createView = testUtils.createView; +var createActionManager = testUtils.createActionManager; var createAsyncView = testUtils.createAsyncView; QUnit.module('Views', { @@ -5472,9 +5473,10 @@ QUnit.module('Views', { }); QUnit.test('display translation alert', function (assert) { - assert.expect(1); + assert.expect(2); this.data.partner.fields.foo.translate = true; + this.data.partner.fields.display_name.translate = true; var multi_lang = _t.database.multi_lang; _t.database.multi_lang = true; @@ -5487,6 +5489,7 @@ QUnit.module('Views', { '' + '' + '' + + '' + '' + '' + '', @@ -5496,14 +5499,154 @@ QUnit.module('Views', { form.$buttons.find('.o_form_button_edit').click(); form.$('input[name="foo"]').val("test").trigger("input"); form.$buttons.find('.o_form_button_save').click(); + assert.strictEqual(form.$('.o_form_view > .alert > div .oe_field_translate').length, 1, + "should have single translation alert"); - assert.strictEqual(form.$('.o_form_view > .alert > div').length, 1,"should have a translation alert"); + form.$buttons.find('.o_form_button_edit').click(); + form.$('input[name="display_name"]').val("test2").trigger("input"); + form.$buttons.find('.o_form_button_save').click(); + assert.strictEqual(form.$('.o_form_view > .alert > div .oe_field_translate').length, 2, + "should have two translate fields in translation alert"); form.destroy(); _t.database.multi_lang = multi_lang; }); + QUnit.test('translation alerts are preserved on pager change', function (assert) { + assert.expect(5); + + this.data.partner.fields.foo.translate = true; + + var multi_lang = _t.database.multi_lang; + _t.database.multi_lang = true; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '' + + '' + + '
', + viewOptions: { + ids: [1, 2], + index: 0, + }, + res_id: 1, + }); + + form.$buttons.find('.o_form_button_edit').click(); + form.$('input[name="foo"]').val("test").trigger("input"); + form.$buttons.find('.o_form_button_save').click(); + + assert.strictEqual(form.$('.o_form_view > .alert > div').length, 1, + "should have a translation alert"); + + // click on the pager to switch to the next record + form.pager.$('.o_pager_next').click(); + assert.strictEqual(form.$('.o_form_view > .alert > div').length, 0, + "should not have a translation alert"); + + // click on the pager to switch back to the previous record + form.pager.$('.o_pager_previous').click(); + assert.strictEqual(form.$('.o_form_view > .alert > div').length, 1, + "should have a translation alert"); + + // remove translation alert by click X and check alert even after form reload + form.$('.o_form_view > .alert > .close').click(); + assert.strictEqual(form.$('.o_form_view > .alert > div').length, 0, + "should not have a translation alert"); + form.reload(); + assert.strictEqual(form.$('.o_form_view > .alert > div').length, 0, + "should not have a translation alert after reload"); + + form.destroy(); + _t.database.multi_lang = multi_lang; + }); + + QUnit.test('translation alerts preseved on reverse breadcrumb', function (assert) { + assert.expect(2); + + this.data['ir.translation'] = { + fields: { + name: { string: "name", type: "char" }, + source: {string: "Source", type: "char"}, + value: {string: "Value", type: "char"}, + }, + records: [], + }; + + this.data.partner.fields.foo.translate = true; + + var multi_lang = _t.database.multi_lang; + _t.database.multi_lang = true; + + var archs = { + 'partner,false,form': '
' + + '' + + '' + + '' + + '
', + 'partner,false,search': '', + 'ir.translation,false,list': '' + + '' + + '' + + '' + + '', + 'ir.translation,false,search': '', + }; + + var actions = [{ + id: 1, + name: 'Partner', + res_model: 'partner', + type: 'ir.actions.act_window', + views: [[false, 'form']], + }, { + id: 2, + name: 'Translate', + res_model: 'ir.translation', + type: 'ir.actions.act_window', + views: [[false, 'list']], + target: 'current', + flags: {'search_view': true, 'action_buttons': true}, + }]; + + var actionManager = createActionManager({ + actions: actions, + archs: archs, + data: this.data, + }); + + actionManager.doAction(1); + + actionManager.controlPanel.$el.find('.o_form_button_edit').click(); + actionManager.$('input[name="foo"]').val("test").trigger("input"); + actionManager.controlPanel.$el.find('.o_form_button_save').click(); + + assert.strictEqual(actionManager.$('.o_form_view > .alert > div').length, 1, + "should have a translation alert"); + + var currentController = actionManager.getCurrentController().widget; + actionManager.doAction(2, { + on_reverse_breadcrumb: function () { + if (!_.isEmpty(currentController.renderer.alertFields)) { + currentController.renderer.displayTranslationAlert(); + } + return false; + }, + }); + + $('.o_control_panel .breadcrumb a:first').click(); + assert.strictEqual(actionManager.$('.o_form_view > .alert > div').length, 1, + "should have a translation alert"); + + actionManager.destroy(); + _t.database.multi_lang = multi_lang; + }); + QUnit.test('translate event correctly handled with multiple controllers', function (assert) { assert.expect(3);