From 495451371447bdd8de1c02aac90402c0b61a6576 Mon Sep 17 00:00:00 2001 From: fshah Date: Wed, 3 Feb 2021 10:25:27 +0530 Subject: [PATCH] [IMP]web_translate_dialog: black, isort, prettier --- .../odoo/addons/web_translate_dialog | 1 + setup/web_translate_dialog/setup.py | 6 + web_translate_dialog/__manifest__.py | 21 +- web_translate_dialog/models/base.py | 30 +- web_translate_dialog/models/res_lang.py | 8 +- web_translate_dialog/static/src/css/base.css | 8 +- .../static/src/js/web_translate_dialog.js | 513 +++++++++--------- web_translate_dialog/static/src/xml/base.xml | 135 +++-- web_translate_dialog/views/res_lang.xml | 7 +- web_translate_dialog/views/web_translate.xml | 23 +- 10 files changed, 415 insertions(+), 337 deletions(-) create mode 120000 setup/web_translate_dialog/odoo/addons/web_translate_dialog create mode 100644 setup/web_translate_dialog/setup.py diff --git a/setup/web_translate_dialog/odoo/addons/web_translate_dialog b/setup/web_translate_dialog/odoo/addons/web_translate_dialog new file mode 120000 index 000000000..a6d6ae992 --- /dev/null +++ b/setup/web_translate_dialog/odoo/addons/web_translate_dialog @@ -0,0 +1 @@ +../../../../web_translate_dialog \ No newline at end of file diff --git a/setup/web_translate_dialog/setup.py b/setup/web_translate_dialog/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/web_translate_dialog/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/web_translate_dialog/__manifest__.py b/web_translate_dialog/__manifest__.py index 05f3f9b48..6d5ca9986 100644 --- a/web_translate_dialog/__manifest__.py +++ b/web_translate_dialog/__manifest__.py @@ -5,23 +5,14 @@ { "name": "Web Translate Dialog", "summary": "Easy-to-use pop-up to translate fields in several languages", - "version": "12.0.1.1.3", + "version": "13.0.1.0.0", "category": "Web", "website": "https://github.com/OCA/web", - "author": "Camptocamp, " - "Tecnativa, " - "Odoo Community Association (OCA)", + "author": "Camptocamp, " "Tecnativa, " "Odoo Community Association (OCA)", "license": "AGPL-3", "application": False, - 'installable': True, - "depends": [ - "web", - ], - "data": [ - "views/res_lang.xml", - "views/web_translate.xml", - ], - "qweb": [ - "static/src/xml/base.xml", - ] + "installable": True, + "depends": ["web"], + "data": ["views/res_lang.xml", "views/web_translate.xml"], + "qweb": ["static/src/xml/base.xml"], } diff --git a/web_translate_dialog/models/base.py b/web_translate_dialog/models/base.py index d2a3aed28..e10bd3f3d 100644 --- a/web_translate_dialog/models/base.py +++ b/web_translate_dialog/models/base.py @@ -1,11 +1,11 @@ # Copyright 2019 Camptocamp SA # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) -from odoo import models, api +from odoo import api, models class BaseModel(models.BaseModel): - _inherit = 'base' + _inherit = "base" @api.multi def get_field_translations(self, field_names): @@ -15,22 +15,24 @@ class BaseModel(models.BaseModel): :return: dict of {self.id: {'lang_code': {'field_name':ir.translation,value}} """ - read_res = self.with_context(lang='en_US').read(fields=field_names) + read_res = self.with_context(lang="en_US").read(fields=field_names) res = {} for rec in read_res: - rec_id = rec.get('id') - del rec['id'] - res[rec_id] = {'en_US': rec} + rec_id = rec.get("id") + del rec["id"] + res[rec_id] = {"en_US": rec} for rec_id, values in res.items(): for name in field_names: - tr_read_res = self.env['ir.translation'].search_read([ - ('name', '=', '%s,%s' % (self._name, name)), - ('res_id', '=', rec_id), - ('lang', '!=', 'en_US') - ]) + tr_read_res = self.env["ir.translation"].search_read( + [ + ("name", "=", "{},{}".format(self._name, name)), + ("res_id", "=", rec_id), + ("lang", "!=", "en_US"), + ] + ) for tr_res in tr_read_res: - if not tr_res.get('lang') in values: - values[tr_res.get('lang')] = {} - values[tr_res.get('lang')][name] = tr_res.get('value') + if not tr_res.get("lang") in values: + values[tr_res.get("lang")] = {} + values[tr_res.get("lang")][name] = tr_res.get("value") return res diff --git a/web_translate_dialog/models/res_lang.py b/web_translate_dialog/models/res_lang.py index 37e63d251..9f497b21d 100644 --- a/web_translate_dialog/models/res_lang.py +++ b/web_translate_dialog/models/res_lang.py @@ -1,14 +1,14 @@ # Copyright 2019 Camptocamp SA # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) -from odoo import models, fields +from odoo import fields, models class ResLang(models.Model): - _inherit = 'res.lang' + _inherit = "res.lang" tr_sequence = fields.Integer( - string='Translation sequence', - help='Defines the order of language to appear in translation dialog', + string="Translation sequence", + help="Defines the order of language to appear in translation dialog", default=10, ) diff --git a/web_translate_dialog/static/src/css/base.css b/web_translate_dialog/static/src/css/base.css index 88ed980fc..78fce0c8d 100644 --- a/web_translate_dialog/static/src/css/base.css +++ b/web_translate_dialog/static/src/css/base.css @@ -2,14 +2,14 @@ * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ .oe_translation_field { - width: 95%; - margin-top: 5px; + width: 95%; + margin-top: 5px; } .oe_translation_field.touched { - border: 1px solid green !important; + border: 1px solid green !important; } .modal-xl { - max-width: 90%; + max-width: 90%; } .oe_form_frame_cell.field_name { diff --git a/web_translate_dialog/static/src/js/web_translate_dialog.js b/web_translate_dialog/static/src/js/web_translate_dialog.js index aa59193ed..533dcc5f0 100644 --- a/web_translate_dialog/static/src/js/web_translate_dialog.js +++ b/web_translate_dialog/static/src/js/web_translate_dialog.js @@ -2,183 +2,212 @@ Copyright 2016 Antonio Espinosa * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ -odoo.define('web_translate_dialog.translate_dialog', function(require){ -"use strict"; +odoo.define("web_translate_dialog.translate_dialog", function(require) { + "use strict"; -var core = require('web.core'); -var BasicController = require('web.BasicController'); -var data = require('web.data'); -var Context = require('web.Context'); -var concurrency = require('web.concurrency'); -var Dialog = require('web.Dialog'); -var FormView = require('web.FormView'); -var View = require('web.AbstractView'); -var session = require('web.session'); -var rpc = require('web.rpc'); -var FormController = require('web.FormController'); -var _t = core._t; -var QWeb = core.qweb; -var Mutex = concurrency.Mutex; + var core = require("web.core"); + var BasicController = require("web.BasicController"); + var data = require("web.data"); + var Context = require("web.Context"); + var concurrency = require("web.concurrency"); + var Dialog = require("web.Dialog"); + var session = require("web.session"); + var rpc = require("web.rpc"); + var FormController = require("web.FormController"); + var _t = core._t; + var QWeb = core.qweb; + var Mutex = concurrency.Mutex; -var TranslateDialog = Dialog.extend({ - template: "TranslateDialog", - init: function(parent, options) { - var title_string = _t("Translate fields: /"); - var field_names; - var single_field = false; - if (options.field){ - field_names = [options.field.fieldName]; - single_field = true; - title_string = title_string.replace('/', field_names); - } - else { - field_names = this.get_translatable_fields(parent); - } - this._super(parent, - {title: title_string , size: 'x-large'}); - this.view_language = session.user_context.lang; - this.view = parent; - this.view_type = parent.viewType || ''; - this.translatable_fields = field_names; - this.res_id = options.res_id; - this.single_field = single_field; - this.languages = null; - this.languages_loaded = $.Deferred(); - this.lang_data = new data.DataSetSearch( - this, 'res.lang', parent.searchView.dataset.get_context(), - [['translatable', '=', '1']] - ); - this.lang_data.set_sort(['tr_sequence asc','id asc']); - this.lang_data.read_slice(['code', 'name']).then(this.on_languages_loaded); - }, - willStart: function () { - var self = this; - return this._super.apply(this, arguments).then(function () { - if (self.size == 'x-large') { - self.$modal.find('.modal-dialog').addClass('modal-xl'); + var TranslateDialog = Dialog.extend({ + template: "TranslateDialog", + init: function(parent, options) { + var title_string = _t("Translate fields: /"); + var single_field = false; + if (options.field) { + var field_names = [options.field.fieldName]; + single_field = true; + title_string = title_string.replace("/", field_names); + } else { + field_names = this.get_translatable_fields(parent); } - }); - }, - get_translatable_fields: function(parent) { - var field_list = []; - _.each(parent.renderer.state.fields, function(field, name){ - var related_readonly = typeof field.related !== 'undefined' && field.readonly; - if (field.translate == true && !related_readonly && parent.renderer.state.getFieldNames().includes(name)){ - field_list.push(name); - } - }); - return field_list; - }, - on_languages_loaded: function(langs) { - this.languages = langs; - this.languages_loaded.resolve(); - }, - open: function() { - // the template needs the languages - return $.when(this.languages_loaded).then($.proxy(this._super, this)); - }, - start: function() { - var self = this; - this.$('.oe_translation_field').change(function() { - $(this).toggleClass('touched', $(this).val() !== $(this).attr('data-value')); - }); - this.$footer.html(QWeb.render("TranslateDialog.buttons")); - this.$footer.find(".oe_form_translate_dialog_save_button").click(function(){ - self.on_button_save(); - self.on_button_close(); - }); - this.$footer.find(".oe_form_translate_dialog_cancel_button").click(function(){ - self.on_button_close(); - }); - - this.do_load_fields_values(); - }, - resize_textareas: function(){ - var textareas = this.$('textarea.oe_translation_field'); - var max_height = 100; - // Resize textarea either to the max height of its content if it stays - // in the modal or to the max height available in the modal - if (textareas.length) { - _.each(textareas, function(textarea) { - if (textarea.scrollHeight > max_height) { - max_height = textarea.scrollHeight; + this._super(parent, {title: title_string, size: "x-large"}); + this.view_language = session.user_context.lang; + this.view = parent; + this.view_type = parent.viewType || ""; + this.translatable_fields = field_names; + this.res_id = options.res_id; + this.single_field = single_field; + this.languages = null; + this.languages_loaded = $.Deferred(); + this.lang_data = new data.DataSetSearch( + this, + "res.lang", + parent.searchView.dataset.get_context(), + [["translatable", "=", "1"]] + ); + this.lang_data.set_sort(["tr_sequence asc", "id asc"]); + this.lang_data.read_slice(["code", "name"]).then(this.on_languages_loaded); + }, + willStart: function() { + var self = this; + return this._super.apply(this, arguments).then(function() { + if (self.size === "x-large") { + self.$modal.find(".modal-dialog").addClass("modal-xl"); } }); - var max_client_height = $(window).height() - $('.modal-content').height() - var new_height = Math.min(max_height, max_client_height) - textareas.css({'minHeight': new_height}); - } - }, - set_maxlength: function(){ - // set maxlength if initial field has size attr - _.each(this.translatable_fields, function(field_name){ - var size = $('[name='+field_name+']')[0].maxLength; - if (size > 0){ - this.$('input.oe_translation_field[name$="'+field_name+'"], textarea.oe_translation_field[name$="'+field_name+'"]').attr('maxlength', size); - } - }, this); - }, - initialize_html_fields: function(lang) { - // Initialize summernote if HTML field - this.$('.oe_form_field_html .oe_translation_field[name^="' + lang + '-"]').each(function() { - var $parent = $(this).summernote({ - 'focus': false, - 'toolbar': [ - ['style', ['style']], - ['font', ['bold', 'italic', 'underline', 'clear']], - ['fontsize', ['fontsize']], - ['color', ['color']], - ['para', ['ul', 'ol', 'paragraph']], - ['table', ['table']], - ['insert', ['link', 'picture']], - ['misc', ['codeview']], - ['history', ['undo', 'redo']] - ], - 'prettifyHtml': false, - 'styleWithSpan': false, - 'inlinemedia': ['p'], - 'lang': "odoo", - 'onChange': function (value) { - $(this).toggleClass('touched', value !== $(this).attr('data-value')); + }, + get_translatable_fields: function(parent) { + var field_list = []; + _.each(parent.renderer.state.fields, function(field, name) { + var related_readonly = + typeof field.related !== "undefined" && field.readonly; + if ( + field.translate === true && + !related_readonly && + parent.renderer.state.getFieldNames().includes(name) + ) { + field_list.push(name); } - }).parent(); - // Triggers a mouseup to refresh the editor toolbar - $parent.find('.note-editable').trigger('mouseup'); - $parent.find('.note-editing-area').css({ - minHeight:'100px', - minWidth:'260px', }); - }); + return field_list; + }, + on_languages_loaded: function(langs) { + this.languages = langs; + this.languages_loaded.resolve(); + }, + open: function() { + // The template needs the languages + return $.when(this.languages_loaded).then($.proxy(this._super, this)); + }, + start: function() { + var self = this; + this.$(".oe_translation_field").change(function() { + $(this).toggleClass( + "touched", + $(this).val() !== $(this).attr("data-value") + ); + }); + this.$footer.html(QWeb.render("TranslateDialog.buttons")); + this.$footer + .find(".oe_form_translate_dialog_save_button") + .click(function() { + self.on_button_save(); + self.on_button_close(); + }); + this.$footer + .find(".oe_form_translate_dialog_cancel_button") + .click(function() { + self.on_button_close(); + }); - }, - set_fields_values: function(lang, tr_value) { - _.each(tr_value, function(translation, field){ - this.$('.oe_translation_field[name="' + lang + - '-' + field + '"]').val(translation || '').attr( - 'data-value', translation || ''); - }, this); - this.initialize_html_fields(lang); - }, - do_load_fields_values: function() { - var self = this, - deferred = []; + this.do_load_fields_values(); + }, + resize_textareas: function() { + var textareas = this.$("textarea.oe_translation_field"); + var max_height = 100; + // Resize textarea either to the max height of its content if it stays + // in the modal or to the max height available in the modal + if (textareas.length) { + _.each(textareas, function(textarea) { + if (textarea.scrollHeight > max_height) { + max_height = textarea.scrollHeight; + } + }); + var max_client_height = + $(window).height() - $(".modal-content").height(); + var new_height = Math.min(max_height, max_client_height); + textareas.css({minHeight: new_height}); + } + }, + set_maxlength: function() { + // Set maxlength if initial field has size attr + _.each( + this.translatable_fields, + function(field_name) { + var size = $("[name=" + field_name + "]")[0].maxLength; + if (size > 0) { + this.$( + 'input.oe_translation_field[name$="' + + field_name + + '"], textarea.oe_translation_field[name$="' + + field_name + + '"]' + ).attr("maxlength", size); + } + }, + this + ); + }, + initialize_html_fields: function(lang) { + // Initialize summernote if HTML field + this.$( + '.oe_form_field_html .oe_translation_field[name^="' + lang + '-"]' + ).each(function() { + var $parent = $(this) + .summernote({ + focus: false, + toolbar: [ + ["style", ["style"]], + ["font", ["bold", "italic", "underline", "clear"]], + ["fontsize", ["fontsize"]], + ["color", ["color"]], + ["para", ["ul", "ol", "paragraph"]], + ["table", ["table"]], + ["insert", ["link", "picture"]], + ["misc", ["codeview"]], + ["history", ["undo", "redo"]], + ], + prettifyHtml: false, + styleWithSpan: false, + inlinemedia: ["p"], + lang: "odoo", + onChange: function(value) { + $(this).toggleClass( + "touched", + value !== $(this).attr("data-value") + ); + }, + }) + .parent(); + // Triggers a mouseup to refresh the editor toolbar + $parent.find(".note-editable").trigger("mouseup"); + $parent.find(".note-editing-area").css({ + minHeight: "100px", + minWidth: "260px", + }); + }); + }, + set_fields_values: function(lang, tr_value) { + _.each( + tr_value, + function(translation, field) { + this.$('.oe_translation_field[name="' + lang + "-" + field + '"]') + .val(translation || "") + .attr("data-value", translation || ""); + }, + this + ); + this.initialize_html_fields(lang); + }, + do_load_fields_values: function() { + var self = this, + deferred = []; - this.$('.oe_translation_field').val('').removeClass('touched'); + this.$(".oe_translation_field") + .val("") + .removeClass("touched"); - var def = $.Deferred(); - deferred.push(def); - rpc.query({ - model: this.view.modelName, - method: 'get_field_translations', - args: [ - [this.res_id], - ], - kwargs: { - field_names: this.translatable_fields, - }, - }).done( - function (res) { - if (res[self.res_id]){ + var def = $.Deferred(); + deferred.push(def); + rpc.query({ + model: this.view.modelName, + method: "get_field_translations", + args: [[this.res_id]], + kwargs: { + field_names: this.translatable_fields, + }, + }).done(function(res) { + if (res[self.res_id]) { _.each(res[self.res_id], function(translation, lang) { self.set_fields_values(lang, translation); }); @@ -188,86 +217,86 @@ var TranslateDialog = Dialog.extend({ } }); - return deferred; - }, - on_button_save: function() { - var translations = {}, - self = this, - save_mutex = new Mutex(); - this.$('.oe_translation_field.touched').each(function() { - var field = $(this).attr('name').split('-'); - if (!translations[field[0]]) { - translations[field[0]] = {}; - } - translations[field[0]][field[1]] = $(this).val(); - }); - _.each(translations, function(text, code) { - save_mutex.exec(function() { - var done = new $.Deferred(); // holds the mutex - - var context = new Context(session.user_context, {lang: code}); - rpc.query({ - model: self.view.modelName, - method: 'write', - args: [self.res_id, text], - kwargs: {context: context.eval()} - }).then(function() { - done.resolve(); - }); - if (code === self.view_language) { - _.each(text, function(value, key) { - var view_elem = self.view.$( ":input[name='" + key +"']") - view_elem.val(value).trigger('change'); - }); + return deferred; + }, + on_button_save: function() { + var translations = {}, + self = this, + save_mutex = new Mutex(); + this.$(".oe_translation_field.touched").each(function() { + var field = $(this) + .attr("name") + .split("-"); + if (!translations[field[0]]) { + translations[field[0]] = {}; } - return done; + translations[field[0]][field[1]] = $(this).val(); }); - }); - this.close(); - }, - on_button_close: function() { - this.close(); - }, + _.each(translations, function(text, code) { + save_mutex.exec(function() { + var done = new $.Deferred(); // Holds the mutex -}); + var context = new Context(session.user_context, {lang: code}); + rpc.query({ + model: self.view.modelName, + method: "write", + args: [self.res_id, text], + kwargs: {context: context.eval()}, + }).then(function() { + done.resolve(); + }); + if (code === self.view_language) { + _.each(text, function(value, key) { + var view_elem = self.view.$(":input[name='" + key + "']"); + view_elem.val(value).trigger("change"); + }); + } + return done; + }); + }); + this.close(); + }, + on_button_close: function() { + this.close(); + }, + }); - -FormController.include({ - renderSidebar: function($node) { - this._super($node); - if (this.sidebar) { - var item = this.is_action_enabled('edit') && { - label: _t('Translate'), - callback: this.on_button_translate + FormController.include({ + renderSidebar: function($node) { + this._super($node); + if (this.sidebar) { + var item = this.is_action_enabled("edit") && { + label: _t("Translate"), + callback: this.on_button_translate, }; - if (item){ - this.sidebar.items.other.push(item); + if (item) { + this.sidebar.items.other.push(item); + } } - } - }, - on_button_translate: function() { - var self = this; - $.when(this.has_been_loaded).then(function() { - self.open_translate_dialog(null, self.initialState.res_id); - }); - }, - -}); - -BasicController.include({ - open_translate_dialog: function(field, res_id) { - new TranslateDialog(this, {'field': field, 'res_id': res_id}).open(); - }, - - _onTranslate: function(event) { - // the image next to the fields opens the translate dialog - var res_id = event.target.res_id ? event.target.res_id : event.target.state.res_id; - this.open_translate_dialog(event.data, res_id); - }, -}); - -return { - TranslateDialog: TranslateDialog, -}; + }, + on_button_translate: function() { + var self = this; + $.when(this.has_been_loaded).then(function() { + self.open_translate_dialog(null, self.initialState.res_id); + }); + }, + }); + BasicController.include({ + open_translate_dialog: function(field, res_id) { + new TranslateDialog(this, {field: field, res_id: res_id}).open(); + }, + + _onTranslate: function(event) { + // The image next to the fields opens the translate dialog + var res_id = event.target.res_id + ? event.target.res_id + : event.target.state.res_id; + this.open_translate_dialog(event.data, res_id); + }, + }); + + return { + TranslateDialog: TranslateDialog, + }; }); diff --git a/web_translate_dialog/static/src/xml/base.xml b/web_translate_dialog/static/src/xml/base.xml index 3306c7e42..b8d7b9d2e 100644 --- a/web_translate_dialog/static/src/xml/base.xml +++ b/web_translate_dialog/static/src/xml/base.xml @@ -1,53 +1,92 @@ - +