diff --git a/web_field_tooltip/i18n/fr.po b/web_field_tooltip/i18n/fr.po index 4ac5d91b7..88e5012e0 100644 --- a/web_field_tooltip/i18n/fr.po +++ b/web_field_tooltip/i18n/fr.po @@ -183,4 +183,4 @@ msgstr "Texte de l'Infobulle" #. module: web_field_tooltip #: model:ir.model,name:web_field_tooltip.model_res_users msgid "Users" -msgstr "Utilisateurs" \ No newline at end of file +msgstr "Utilisateurs" diff --git a/web_field_tooltip/readme/USAGE.rst b/web_field_tooltip/readme/USAGE.rst index 8e86a2098..432794b17 100644 --- a/web_field_tooltip/readme/USAGE.rst +++ b/web_field_tooltip/readme/USAGE.rst @@ -9,8 +9,5 @@ To use this module, you need to: add a tooltip and use the Manage tooltips Action to add a new tooltip, or edit or delete existing tooltips for this model. -* Internal Users can read all created tooltips. Then there are two new groups: - - * Tooltip users who are able to manage their own tooltips. - - * Tooltip managers who are able to manage all tooltips. +* For manager users, they can decide to display an helper to add a tooltip + on a field as some fields are not displayed with a label. diff --git a/web_field_tooltip/static/src/css/web_field_tooltip.css b/web_field_tooltip/static/src/css/web_field_tooltip.css index 425deeceb..b2fea36f2 100644 --- a/web_field_tooltip/static/src/css/web_field_tooltip.css +++ b/web_field_tooltip/static/src/css/web_field_tooltip.css @@ -2,6 +2,10 @@ sup.field-tooltip { margin-right: 5px; } +sup.field-tooltip:hover { + cursor: pointer; +} + .tooltip-icon { color: #666666; background: none; @@ -9,7 +13,7 @@ sup.field-tooltip { display: inline-block; width: 0; font-size: 12px; - margin-left: -2px; + margin-left: 0px; } .popover-footer { diff --git a/web_field_tooltip/static/src/js/controller.js b/web_field_tooltip/static/src/js/controller.js new file mode 100644 index 000000000..49f82e99f --- /dev/null +++ b/web_field_tooltip/static/src/js/controller.js @@ -0,0 +1,59 @@ +/* Copyright 2023 ACSONE SA/NV + Copyright 2019 TODAY Serpent Consulting Services Pvt. Ltd. + License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ + +odoo.define("web_field_tooltip.controller", function(require) { + "use strict"; + + const FormController = require("web.FormController"); + const ListController = require("web.ListController"); + const tooltips = require("web_field_tooltip.FieldTooltip"); + + const core = require("web.core"); + const session = require("web.session"); + const _t = core._t; + + ListController.include( + Object.assign({}, tooltips.TooltipController, { + custom_events: _.extend({}, ListController.prototype.custom_events, { + add_tooltip: "_onAddTooltip", + edit_tooltip: "_onEditTooltip", + }), + }) + ); + + FormController.include( + Object.assign({}, tooltips.TooltipController, { + custom_events: _.extend({}, FormController.prototype.custom_events, { + add_tooltip: "_onAddTooltip", + edit_tooltip: "_onEditTooltip", + }), + + renderSidebar: function($node) { + this._super($node); + if (this.sidebar && session.can_manage_tooltips) { + this.sidebar.items.other.push({ + label: _t("Manage Tooltips"), + callback: this.on_manage_tooltips, + }); + } + }, + on_manage_tooltips: function() { + const self = this; + return self.do_action({ + type: "ir.actions.act_window", + name: _t("Manage Tooltips"), + res_model: "ir.model.fields.tooltip", + target: "current", + views: [ + [false, "list"], + [false, "form"], + ], + view_mode: "list", + domain: [["model", "=", self.modelName]], + context: {tooltip_model: self.modelName}, + }); + }, + }) + ); +}); diff --git a/web_field_tooltip/static/src/js/renderer.js b/web_field_tooltip/static/src/js/renderer.js new file mode 100644 index 000000000..95fbf1267 --- /dev/null +++ b/web_field_tooltip/static/src/js/renderer.js @@ -0,0 +1,61 @@ +/* Copyright 2023 ACSONE SA/NV + Copyright 2019 TODAY Serpent Consulting Services Pvt. Ltd. + License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ + +odoo.define("web_field_tooltip.renderer", function(require) { + "use strict"; + + const FormRenderer = require("web.FormRenderer"); + const ListRenderer = require("web.ListRenderer"); + const tooltips = require("web_field_tooltip.FieldTooltip"); + + FormRenderer.include( + Object.assign({}, tooltips.TooltipRenderer, { + init: function() { + this._super.apply(this, arguments); + this.tooltips = undefined; + }, + + /** + * @override + */ + _renderTagLabel: function(node) { + const self = this; + const $result = this._super.apply(this, arguments); + const fieldName = + node.tag === "label" ? node.attrs.for : node.attrs.name; + if (!fieldName) { + return $result; + } + self.add_tooltip($result, node); + + return $result; + }, + }) + ); + + ListRenderer.include( + Object.assign({}, tooltips.TooltipRenderer, { + init: function() { + this._super.apply(this, arguments); + this.tooltips = undefined; + }, + + /** + * @override + */ + _renderHeaderCell: function(node) { + const self = this; + const $result = this._super.apply(this, arguments); + const fieldName = + node.tag === "label" ? node.attrs.for : node.attrs.name; + if (!fieldName) { + return $result; + } + self.add_tooltip($result, node); + + return $result; + }, + }) + ); +}); diff --git a/web_field_tooltip/static/src/js/web_field_tooltip.js b/web_field_tooltip/static/src/js/web_field_tooltip.js index c93c57654..06c732bda 100644 --- a/web_field_tooltip/static/src/js/web_field_tooltip.js +++ b/web_field_tooltip/static/src/js/web_field_tooltip.js @@ -5,17 +5,14 @@ odoo.define("web_field_tooltip.FieldTooltip", function(require) { "use strict"; - const FormRenderer = require("web.FormRenderer"); - const ListRenderer = require("web.ListRenderer"); - const FormController = require("web.FormController"); - const core = require("web.core"); + const dialogs = require("web.view_dialogs"); const field_utils = require("web.field_utils"); const rpc = require("web.rpc"); const session = require("web.session"); const _t = core._t; - const Tooltip = { + const TooltipRenderer = { add_tooltip: function($result, node) { const self = this; const tooltip_title = $result.text(); @@ -66,21 +63,14 @@ odoo.define("web_field_tooltip.FieldTooltip", function(require) { get_add_tooltip_elem: function(fieldName) { const self = this; - const $after_elem = $("<button>", { + const $after_elem = $("<a>", { class: "fa fa fa-question-circle tooltip-icon text-info", - role: "button", }); $after_elem.on("click", function(e) { e.preventDefault(); e.stopPropagation(); - self.do_action({ - type: "ir.actions.act_window", - name: _t("Add a Tooltip"), - res_model: "ir.model.fields.tooltip", - target: "new", - views: [[false, "form"]], - view_mode: "form", + self.trigger_up("add_tooltip", { context: { default_model: self.state.model, default_field_name: fieldName, @@ -96,9 +86,9 @@ odoo.define("web_field_tooltip.FieldTooltip", function(require) { get_tooltip_elem: function(fieldName, tooltip_title, tooltip) { const self = this; - const $after_elem = $("<button>", { + const $after_elem = $("<a>", { class: "fa fa fa-question-circle tooltip-icon", - role: "button", + tabIndex: 0, }); const $popup_div = $("<div/>", { @@ -127,14 +117,8 @@ odoo.define("web_field_tooltip.FieldTooltip", function(require) { $edit_button.on("click", function(e) { e.preventDefault(); e.stopPropagation(); - self.do_action({ - type: "ir.actions.act_window", - name: _t("Edit a Tooltip"), - res_model: "ir.model.fields.tooltip", - target: "new", + self.trigger_up("edit_tooltip", { res_id: tooltip.id, - views: [[false, "form"]], - view_mode: "form", }); }); @@ -167,86 +151,39 @@ odoo.define("web_field_tooltip.FieldTooltip", function(require) { }, }; - FormRenderer.include( - Object.assign({}, Tooltip, { - init: function() { - this._super.apply(this, arguments); - this.tooltips = undefined; - }, - - /** - * @override - */ - _renderTagLabel: function(node) { - const self = this; - const $result = this._super.apply(this, arguments); - const fieldName = - node.tag === "label" ? node.attrs.for : node.attrs.name; - if (!fieldName) { - return $result; - } - self.add_tooltip($result, node); - - return $result; - }, - }) - ); - - ListRenderer.include( - Object.assign({}, Tooltip, { - init: function() { - this._super.apply(this, arguments); - this.tooltips = undefined; - }, - - /** - * @override - */ - _renderHeaderCell: function(node) { - const self = this; - const $result = this._super.apply(this, arguments); - const fieldName = - node.tag === "label" ? node.attrs.for : node.attrs.name; - if (!fieldName) { - return $result; - } - self.add_tooltip($result, node); - - return $result; - }, - }) - ); - - FormController.include({ - init: function() { - console.log("FormController"); - this._super.apply(this, arguments); - }, - - renderSidebar: function($node) { - this._super($node); - if (this.sidebar && session.can_manage_tooltips) { - this.sidebar.items.other.push({ - label: _t("Manage Tooltips"), - callback: this.on_manage_tooltips, - }); - } - }, - on_manage_tooltips: function() { - var self = this; - return self.do_action({ - type: "ir.actions.act_window", - name: _t("Manage Tooltips"), + const TooltipController = { + _onAddTooltip: function(params) { + const self = this; + new dialogs.FormViewDialog(self, { res_model: "ir.model.fields.tooltip", - target: "current", - views: [ - [false, "list"], - [false, "form"], - ], - view_mode: "list", - domain: [["model", "=", self.modelName]], - context: {tooltip_model: self.modelName}, - }); + context: _.extend(session.user_context, params.data.context), + title: _t("Add a tooltip"), + disable_multiple_selection: true, + }).open(); }, - }); + _onEditTooltip: function(params) { + const self = this; + const tooltipId = params.data.res_id; + new dialogs.FormViewDialog(self, { + res_model: "ir.model.fields.tooltip", + res_id: tooltipId, + context: session.user_context, + title: _t("Edit a tooltip"), + disable_multiple_selection: false, + deletable: true, + on_remove: function() { + rpc.query({ + model: "ir.model.fields.tooltip", + method: "unlink", + args: [tooltipId], + }); + }, + }).open(); + }, + }; + + return { + TooltipRenderer: TooltipRenderer, + TooltipController: TooltipController, + }; }); diff --git a/web_field_tooltip/tests/test_web_field_tooltip.py b/web_field_tooltip/tests/test_web_field_tooltip.py index 3d6a66f50..ac2754055 100644 --- a/web_field_tooltip/tests/test_web_field_tooltip.py +++ b/web_field_tooltip/tests/test_web_field_tooltip.py @@ -18,17 +18,23 @@ class TestWebFieldTooltip(SavepointCase): [("model", "=", cls.partner_model_name), ("name", "=", "email")] ) cls.email_tooltip = cls.Tooltip.create( - {"model_id": cls.partner_model.id, "field_id": cls.email_partner_field.id} + { + "model_id": cls.partner_model.id, + "field_id": cls.email_partner_field.id, + "tooltip_text": "this explains a lot", + } ) def test_duplicate_constrains(self): - with self.assertRaises(UserError): + with self.assertRaises(UserError) as e: self.email_tooltip = self.Tooltip.create( { "model_id": self.partner_model.id, "field_id": self.email_partner_field.id, + "tooltip_text": "this explains a lot", } ) + self.assertIn(e.exception.name, "A tooltip already exists for this field") def test_tooltip_name(self): self.assertEqual( diff --git a/web_field_tooltip/views/template.xml b/web_field_tooltip/views/template.xml index a69194ff5..e884a3411 100644 --- a/web_field_tooltip/views/template.xml +++ b/web_field_tooltip/views/template.xml @@ -12,6 +12,14 @@ rel="stylesheet" href="web_field_tooltip/static/src/css/web_field_tooltip.css" /> + <script + type="text/javascript" + src="/web_field_tooltip/static/src/js/controller.js" + /> + <script + type="text/javascript" + src="/web_field_tooltip/static/src/js/renderer.js" + /> <script type="text/javascript" src="/web_field_tooltip/static/src/js/web_field_tooltip.js"