[IMP] display a helper to add a tooltip on a field. Display the tooltip on list views. One tooltip per field and do not handle user specific tooltips

pull/2553/head
Benjamin Willig 2023-08-01 10:40:55 +02:00
parent 9974308140
commit 3c5ef90a2e
14 changed files with 362 additions and 163 deletions

View File

@ -14,8 +14,8 @@
"data": [
"security/res_groups.xml",
"security/ir_model_access.xml",
"security/ir_rule.xml",
"views/ir_model_fields_tooltip.xml",
"views/res_users.xml",
"views/template.xml",
],
}

View File

@ -6,11 +6,10 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-06 07:59+0000\n"
"PO-Revision-Date: 2023-07-06 07:42+0000\n"
"POT-Creation-Date: 2023-08-01 08:24+0000\n"
"PO-Revision-Date: 2023-08-01 08:24+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
@ -25,7 +24,14 @@ msgstr "Une infobulle existe déjà pour ce champ"
#. module: web_field_tooltip
#: model:ir.model.fields,field_description:web_field_tooltip.field_ir_model_fields_tooltip__active
msgid "Active"
msgstr "Active"
msgstr ""
#. module: web_field_tooltip
#. openerp-web
#: code:addons/web_field_tooltip/static/src/js/web_field_tooltip.js:0
#, python-format
msgid "Add a Tooltip"
msgstr "Ajouter une infobulle"
#. module: web_field_tooltip
#: model_terms:ir.ui.view,arch_db:web_field_tooltip.ir_model_fields_tooltip_form_view
@ -83,10 +89,15 @@ msgstr "Infobulle de Champ"
msgid "Fields Tooltips"
msgstr "Infobulles"
#. module: web_field_tooltip
#: model:ir.model,name:web_field_tooltip.model_ir_http
msgid "HTTP Routing"
msgstr "Routage HTTP"
#. module: web_field_tooltip
#: model:ir.model.fields,field_description:web_field_tooltip.field_ir_model_fields_tooltip__id
msgid "ID"
msgstr "ID"
msgstr ""
#. module: web_field_tooltip
#: model:ir.model.fields,field_description:web_field_tooltip.field_ir_model_fields_tooltip____last_update
@ -113,6 +124,7 @@ msgstr "Dernière mise à jour le"
#. module: web_field_tooltip
#. openerp-web
#: code:addons/web_field_tooltip/static/src/js/web_field_tooltip.js:0
#: code:addons/web_field_tooltip/static/src/js/web_field_tooltip.js:0
#, python-format
msgid "Manage Tooltips"
msgstr "Gérer les Infobulles"
@ -143,27 +155,32 @@ msgid "Set active to false to hide the Tooltip without removing it."
msgstr ""
"Mettre le champ actif à faux pour masquer l'Infobulle sans la supprimer."
#. module: web_field_tooltip
#: model:ir.model.fields,field_description:web_field_tooltip.field_res_users__tooltip_show_add_helper
msgid "Show helper to add tooltips on fields"
msgstr "Afficher l'aide pour l'ajout des infobulles sur les champs"
#. module: web_field_tooltip
#: model:res.groups,comment:web_field_tooltip.group_tooltip_manager
msgid "The user will be able to manage all the tooltips."
msgstr "L'utilisateur pourra gérer toutes les infobulles."
#. module: web_field_tooltip
#: model:res.groups,comment:web_field_tooltip.group_tooltip_user
msgid "The user will be able to manage his own tooltips."
msgstr "L'utilisateur pourra gérer ses infobulles."
#. module: web_field_tooltip
#: model:res.groups,name:web_field_tooltip.group_tooltip_manager
msgid "Tooltip Manager"
msgstr "Gestionnaire des infobulles"
#. module: web_field_tooltip
#: model:ir.model.fields,field_description:web_field_tooltip.field_res_users__tooltip_show_add_helper_allowed
msgid "Tooltip Show Add Helper Allowed"
msgstr ""
#. module: web_field_tooltip
#: model:ir.model.fields,field_description:web_field_tooltip.field_ir_model_fields_tooltip__tooltip_text
msgid "Tooltip Text"
msgstr "Texte de l'Infobulle"
#. module: web_field_tooltip
#: model:res.groups,name:web_field_tooltip.group_tooltip_user
msgid "Tooltip User"
msgstr "Utilisateur des infobulles"
#: model:ir.model,name:web_field_tooltip.model_res_users
msgid "Users"
msgstr "Utilisateurs"

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-06 07:59+0000\n"
"PO-Revision-Date: 2023-07-06 07:59+0000\n"
"POT-Creation-Date: 2023-08-01 08:32+0000\n"
"PO-Revision-Date: 2023-08-01 08:32+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@ -26,6 +26,13 @@ msgstr ""
msgid "Active"
msgstr ""
#. module: web_field_tooltip
#. openerp-web
#: code:addons/web_field_tooltip/static/src/js/web_field_tooltip.js:0
#, python-format
msgid "Add a Tooltip"
msgstr ""
#. module: web_field_tooltip
#: model_terms:ir.ui.view,arch_db:web_field_tooltip.ir_model_fields_tooltip_form_view
#: model_terms:ir.ui.view,arch_db:web_field_tooltip.ir_model_fields_tooltip_search_view
@ -82,6 +89,11 @@ msgstr ""
msgid "Fields Tooltips"
msgstr ""
#. module: web_field_tooltip
#: model:ir.model,name:web_field_tooltip.model_ir_http
msgid "HTTP Routing"
msgstr ""
#. module: web_field_tooltip
#: model:ir.model.fields,field_description:web_field_tooltip.field_ir_model_fields_tooltip__id
msgid "ID"
@ -143,13 +155,13 @@ msgid "Set active to false to hide the Tooltip without removing it."
msgstr ""
#. module: web_field_tooltip
#: model:res.groups,comment:web_field_tooltip.group_tooltip_manager
msgid "The user will be able to manage all the tooltips."
#: model:ir.model.fields,field_description:web_field_tooltip.field_res_users__tooltip_show_add_helper
msgid "Show helper to add tooltips on fields"
msgstr ""
#. module: web_field_tooltip
#: model:res.groups,comment:web_field_tooltip.group_tooltip_user
msgid "The user will be able to manage his own tooltips."
#: model:res.groups,comment:web_field_tooltip.group_tooltip_manager
msgid "The user will be able to manage all the tooltips."
msgstr ""
#. module: web_field_tooltip
@ -157,12 +169,17 @@ msgstr ""
msgid "Tooltip Manager"
msgstr ""
#. module: web_field_tooltip
#: model:ir.model.fields,field_description:web_field_tooltip.field_res_users__tooltip_show_add_helper_allowed
msgid "Tooltip Show Add Helper Allowed"
msgstr ""
#. module: web_field_tooltip
#: model:ir.model.fields,field_description:web_field_tooltip.field_ir_model_fields_tooltip__tooltip_text
msgid "Tooltip Text"
msgstr ""
#. module: web_field_tooltip
#: model:res.groups,name:web_field_tooltip.group_tooltip_user
msgid "Tooltip User"
msgstr ""
#: model:ir.model,name:web_field_tooltip.model_res_users
msgid "Users"
msgstr ""

View File

@ -1 +1,3 @@
from . import ir_http
from . import ir_model_fields_tooltip
from . import res_users

View File

@ -0,0 +1,19 @@
# Copyright 2023 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models
class Http(models.AbstractModel):
_inherit = "ir.http"
def session_info(self):
result = super().session_info()
user = self.env.user
result.update(
{
"can_manage_tooltips": user._is_tooltip_manager(),
"tooltip_show_add_helper": user.tooltip_show_add_helper,
}
)
return result

View File

@ -31,12 +31,27 @@ class IrModelFieldsTooltip(models.Model):
help="Set active to false to hide the Tooltip without removing it.",
)
field_name = fields.Char(related="field_id.name")
tooltip_text = fields.Html(string="Tooltip Text")
tooltip_text = fields.Html(string="Tooltip Text", required=True)
@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
context = self.env.context
default_model = context.get("default_model")
default_field = context.get("default_field_name")
if default_model and default_field:
field = self.env["ir.model.fields"].search(
[("model_id.model", "=", default_model), ("name", "=", default_field)],
limit=1,
)
res.update({"model_id": field.model_id.id, "field_id": field.id})
return res
@api.constrains("model_id", "field_id")
def _check_duplicate_tooltip(self):
all_self = self.with_context(active_test=False)
for rec in self:
if self.search(
if all_self.search(
[
("model_id", "=", rec.model_id.id),
("field_id", "=", rec.field_id.id),

View File

@ -0,0 +1,31 @@
# Copyright 2023 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
TOOLTIP_MANAGER_GROUP = "web_field_tooltip.group_tooltip_manager"
class ResUsers(models.Model):
_inherit = "res.users"
tooltip_show_add_helper = fields.Boolean(
string="Show helper to add tooltips on fields",
)
tooltip_show_add_helper_allowed = fields.Boolean(
compute="_compute_tooltip_show_add_helper_allowed"
)
def __init__(self, pool, cr):
super().__init__(pool, cr)
field_names = ["tooltip_show_add_helper"]
self.SELF_READABLE_FIELDS.extend(field_names)
self.SELF_WRITEABLE_FIELDS.extend(field_names)
def _compute_tooltip_show_add_helper_allowed(self):
for rec in self:
rec.tooltip_show_add_helper_allowed = rec._is_tooltip_manager()
def _is_tooltip_manager(self):
self.ensure_one()
return self.has_group(TOOLTIP_MANAGER_GROUP)

View File

@ -16,7 +16,7 @@
<record model="ir.model.access" id="ir_model_fields_tooltip_access_user">
<field name="name">ir.model.fields.tooltip access user</field>
<field name="model_id" ref="model_ir_model_fields_tooltip" />
<field name="group_id" ref="web_field_tooltip.group_tooltip_user" />
<field name="group_id" ref="web_field_tooltip.group_tooltip_manager" />
<field name="perm_read" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_write" eval="1" />

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2023 ACSONE SA/NV
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="tooltip_manage_all" model="ir.rule">
<field name="name">All Tooltips</field>
<field name="model_id" ref="model_ir_model_fields_tooltip" />
<field name="domain_force">[(1, '=', 1)]</field>
<field
name="groups"
eval="[(4, ref('web_field_tooltip.group_tooltip_manager'))]"
/>
</record>
<record id="tooltip_manage_own" model="ir.rule">
<field name="name">Tooltips per user</field>
<field name="model_id" ref="model_ir_model_fields_tooltip" />
<field name="domain_force">[('create_uid','=', user.id)]</field>
<field
name="groups"
eval="[(4, ref('web_field_tooltip.group_tooltip_user'))]"
/>
</record>
<record id="tooltip_read_all" model="ir.rule">
<field name="name">Tooltips read access is for everyone</field>
<field name="model_id" ref="model_ir_model_fields_tooltip" />
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('base.group_user'))]" />
<field name="perm_create" eval="0" />
<field name="perm_write" eval="0" />
<field name="perm_unlink" eval="0" />
</record>
</odoo>

View File

@ -3,20 +3,9 @@
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="group_tooltip_user" model="res.groups">
<field name="name">Tooltip User</field>
<field name="category_id" ref="base.module_category_hidden" />
<field name="implied_ids" eval="[(6, 0, [ref('base.group_user')])]" />
<field name="comment">The user will be able to manage his own tooltips.</field>
</record>
<record id="group_tooltip_manager" model="res.groups">
<field name="name">Tooltip Manager</field>
<field name="category_id" ref="base.module_category_hidden" />
<field
name="implied_ids"
eval="[(6, 0, [ref('web_field_tooltip.group_tooltip_user')])]"
/>
<field name="comment">The user will be able to manage all the tooltips.</field>
<field
name="users"

View File

@ -1,8 +1,15 @@
sup.field-tooltip {
margin-right: 5px;
}
.tooltip-icon {
color: #666666;
margin-left: 5px;
background: none;
border: none;
display: inline-block;
width: 0;
font-size: 12px;
margin-left: -2px;
}
.popover-footer {

View File

@ -5,112 +5,227 @@
odoo.define("web_field_tooltip.FieldTooltip", function(require) {
"use strict";
var core = require("web.core");
var FormRenderer = require("web.FormRenderer");
var FormController = require("web.FormController");
var field_utils = require("web.field_utils");
var rpc = require("web.rpc");
var _t = core._t;
const FormRenderer = require("web.FormRenderer");
const ListRenderer = require("web.ListRenderer");
const FormController = require("web.FormController");
FormRenderer.include({
/**
* @override
*/
_renderTagLabel: function(node) {
var self = this;
var $result = this._super.apply(this, arguments);
var fieldName = node.tag === "label" ? node.attrs.for : node.attrs.name;
const core = require("web.core");
const field_utils = require("web.field_utils");
const rpc = require("web.rpc");
const session = require("web.session");
const _t = core._t;
const Tooltip = {
add_tooltip: function($result, node) {
const self = this;
const tooltip_title = $result.text();
const fieldName = node.tag === "label" ? node.attrs.for : node.attrs.name;
if (!fieldName) {
return $result;
}
// Check if there's any tooltip that must be rendered for the given view
if (!self.tooltips) {
self.load_tooltips();
}
var tooltips = {};
self.$tooltip_promise.then(function() {
let $tooltip = null;
let allow_add_tooltip_helper =
session.tooltip_show_add_helper && session.can_manage_tooltips;
_.each(self.tooltips, function(tooltip) {
if (tooltip.field_name === fieldName) {
$tooltip = self.get_tooltip_elem(
fieldName,
tooltip_title,
tooltip
);
$result.append($tooltip);
allow_add_tooltip_helper = false;
}
});
if (allow_add_tooltip_helper) {
$result.append(self.get_add_tooltip_elem(fieldName));
}
});
},
if (self.tooltips) {
tooltips = self.tooltips;
} else {
tooltips = rpc.query({
load_tooltips: function() {
const self = this;
self.$tooltip_promise = rpc
.query({
model: "ir.model.fields.tooltip",
method: "search_read",
domain: [["model", "=", self.state.model]],
})
.then(function(result) {
self.tooltips = result;
});
self.tooltips = tooltips;
},
get_add_tooltip_elem: function(fieldName) {
const self = this;
const $after_elem = $("<button>", {
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",
context: {
default_model: self.state.model,
default_field_name: fieldName,
},
});
});
const $sup = $("<sup/>", {
class: "field-tooltip",
});
$sup.append($after_elem);
return $sup;
},
get_tooltip_elem: function(fieldName, tooltip_title, tooltip) {
const self = this;
const $after_elem = $("<button>", {
class: "fa fa fa-question-circle tooltip-icon",
role: "button",
});
const $popup_div = $("<div/>", {
class: "popup-div",
});
const $popup_text = $("<p>", {
html: tooltip.tooltip_text,
});
$popup_div.append($popup_text);
if (session.can_manage_tooltips) {
const $popup_last_edit = $("<p>", {
class: "popover-footer",
html:
_t("Last Updated by: ") +
field_utils.format.many2one(tooltip.write_uid),
});
const $edit_button = $("<button>", {
title: _t("Edit the tooltip"),
class: "fa fa-edit tooltip-icon",
});
$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",
res_id: tooltip.id,
views: [[false, "form"]],
view_mode: "form",
});
});
$popup_last_edit.append($edit_button);
$popup_div.append($popup_last_edit);
}
tooltips.then(function(data) {
if (data) {
_.each(data, function(tooltip) {
if (tooltip.field_name === fieldName) {
var $after_elem = $("<button>", {
class: "fa fa fa-question-circle tooltip-icon",
for: self._getIDForLabel(fieldName),
role: "button",
});
var $popup_div = $("<div/>", {
class: "popup-div",
});
var $popup_text = $("<p>", {
html: tooltip.tooltip_text
? tooltip.tooltip_text
: $result.text(),
});
$popup_div.append($popup_text);
var $popup_last_edit = $("<p>", {
class: "popover-footer",
html:
_t("Last Updated by: ") +
field_utils.format.many2one(tooltip.write_uid),
});
var $edit_button = $("<button>", {
title: _t("Edit the tooltip"),
class: "fa fa-edit tooltip-icon",
});
$edit_button.on("click", function(e) {
e.preventDefault();
return self.do_action({
type: "ir.actions.act_window",
name: _t("Edit a Tooltip"),
res_model: "ir.model.fields.tooltip",
target: "current",
res_id: tooltip.id,
views: [[false, "form"]],
view_mode: "form",
});
});
$popup_last_edit.append($edit_button);
$popup_div.append($popup_last_edit);
var options = {
content: $popup_div,
html: true,
placement: "top",
title: $result.text(),
trigger: "focus",
delay: {
show: 0,
hide: 100,
},
};
$after_elem.popover(options);
$result.append($after_elem);
}
});
}
const options = {
content: $popup_div,
html: true,
placement: "top",
title: tooltip_title,
trigger: "focus",
delay: {
show: 0,
hide: 0,
},
};
$after_elem.popover(options);
$after_elem.on("click", function(e) {
e.preventDefault();
e.stopPropagation();
$after_elem.popover("show");
});
return $result;
const $sup = $("<sup/>", {
class: "field-tooltip",
});
$sup.append($after_elem);
return $sup;
},
});
};
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) {
if (this.sidebar && session.can_manage_tooltips) {
this.sidebar.items.other.push({
label: _t("Manage Tooltips"),
callback: this.on_manage_tooltips,

View File

@ -5,6 +5,7 @@
<record model="ir.ui.view" id="ir_model_fields_tooltip_form_view">
<field name="model">ir.model.fields.tooltip</field>
<field name="inherit_id" eval="0" />
<field name="arch" type="xml">
<form duplicate="0">
<sheet>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2023 ACSONE SA/NV
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="res_users_form_view">
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_form_simple_modif" />
<field name="arch" type="xml">
<xpath expr="//field[@name='email']" position="after">
<field name="tooltip_show_add_helper_allowed" invisible="1" />
<field
name="tooltip_show_add_helper"
widget="boolean_toggle"
readonly="0"
attrs="{'invisible': [('tooltip_show_add_helper_allowed', '=', False)]}"
/>
</xpath>
</field>
</record>
</odoo>