[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

This commit is contained in:
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

@@ -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,