[REF] use FormViewDialog instead of do_action, allow to unlink a tooltip from the helper, splitted resources into multiple files

pull/2553/head
Benjamin Willig 2023-08-03 12:40:08 +02:00
parent 3c5ef90a2e
commit c35d5a9891
8 changed files with 184 additions and 112 deletions

View File

@ -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 add a tooltip and use the Manage tooltips Action to add a new tooltip, or edit
or delete existing tooltips for this model. or delete existing tooltips for this model.
* Internal Users can read all created tooltips. Then there are two new groups: * 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.
* Tooltip users who are able to manage their own tooltips.
* Tooltip managers who are able to manage all tooltips.

View File

@ -2,6 +2,10 @@ sup.field-tooltip {
margin-right: 5px; margin-right: 5px;
} }
sup.field-tooltip:hover {
cursor: pointer;
}
.tooltip-icon { .tooltip-icon {
color: #666666; color: #666666;
background: none; background: none;
@ -9,7 +13,7 @@ sup.field-tooltip {
display: inline-block; display: inline-block;
width: 0; width: 0;
font-size: 12px; font-size: 12px;
margin-left: -2px; margin-left: 0px;
} }
.popover-footer { .popover-footer {

View File

@ -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},
});
},
})
);
});

View File

@ -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;
},
})
);
});

View File

@ -5,17 +5,14 @@
odoo.define("web_field_tooltip.FieldTooltip", function(require) { odoo.define("web_field_tooltip.FieldTooltip", function(require) {
"use strict"; "use strict";
const FormRenderer = require("web.FormRenderer");
const ListRenderer = require("web.ListRenderer");
const FormController = require("web.FormController");
const core = require("web.core"); const core = require("web.core");
const dialogs = require("web.view_dialogs");
const field_utils = require("web.field_utils"); const field_utils = require("web.field_utils");
const rpc = require("web.rpc"); const rpc = require("web.rpc");
const session = require("web.session"); const session = require("web.session");
const _t = core._t; const _t = core._t;
const Tooltip = { const TooltipRenderer = {
add_tooltip: function($result, node) { add_tooltip: function($result, node) {
const self = this; const self = this;
const tooltip_title = $result.text(); const tooltip_title = $result.text();
@ -66,21 +63,14 @@ odoo.define("web_field_tooltip.FieldTooltip", function(require) {
get_add_tooltip_elem: function(fieldName) { get_add_tooltip_elem: function(fieldName) {
const self = this; const self = this;
const $after_elem = $("<button>", { const $after_elem = $("<a>", {
class: "fa fa fa-question-circle tooltip-icon text-info", class: "fa fa fa-question-circle tooltip-icon text-info",
role: "button",
}); });
$after_elem.on("click", function(e) { $after_elem.on("click", function(e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
self.do_action({ self.trigger_up("add_tooltip", {
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: { context: {
default_model: self.state.model, default_model: self.state.model,
default_field_name: fieldName, default_field_name: fieldName,
@ -96,9 +86,9 @@ odoo.define("web_field_tooltip.FieldTooltip", function(require) {
get_tooltip_elem: function(fieldName, tooltip_title, tooltip) { get_tooltip_elem: function(fieldName, tooltip_title, tooltip) {
const self = this; const self = this;
const $after_elem = $("<button>", { const $after_elem = $("<a>", {
class: "fa fa fa-question-circle tooltip-icon", class: "fa fa fa-question-circle tooltip-icon",
role: "button", tabIndex: 0,
}); });
const $popup_div = $("<div/>", { const $popup_div = $("<div/>", {
@ -127,14 +117,8 @@ odoo.define("web_field_tooltip.FieldTooltip", function(require) {
$edit_button.on("click", function(e) { $edit_button.on("click", function(e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
self.do_action({ self.trigger_up("edit_tooltip", {
type: "ir.actions.act_window",
name: _t("Edit a Tooltip"),
res_model: "ir.model.fields.tooltip",
target: "new",
res_id: tooltip.id, res_id: tooltip.id,
views: [[false, "form"]],
view_mode: "form",
}); });
}); });
@ -167,86 +151,39 @@ odoo.define("web_field_tooltip.FieldTooltip", function(require) {
}, },
}; };
FormRenderer.include( const TooltipController = {
Object.assign({}, Tooltip, { _onAddTooltip: function(params) {
init: function() { const self = this;
this._super.apply(this, arguments); new dialogs.FormViewDialog(self, {
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"),
res_model: "ir.model.fields.tooltip", res_model: "ir.model.fields.tooltip",
target: "current", context: _.extend(session.user_context, params.data.context),
views: [ title: _t("Add a tooltip"),
[false, "list"], disable_multiple_selection: true,
[false, "form"], }).open();
],
view_mode: "list",
domain: [["model", "=", self.modelName]],
context: {tooltip_model: self.modelName},
});
}, },
}); _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,
};
}); });

View File

@ -18,17 +18,23 @@ class TestWebFieldTooltip(SavepointCase):
[("model", "=", cls.partner_model_name), ("name", "=", "email")] [("model", "=", cls.partner_model_name), ("name", "=", "email")]
) )
cls.email_tooltip = cls.Tooltip.create( 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): def test_duplicate_constrains(self):
with self.assertRaises(UserError): with self.assertRaises(UserError) as e:
self.email_tooltip = self.Tooltip.create( self.email_tooltip = self.Tooltip.create(
{ {
"model_id": self.partner_model.id, "model_id": self.partner_model.id,
"field_id": self.email_partner_field.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): def test_tooltip_name(self):
self.assertEqual( self.assertEqual(

View File

@ -12,6 +12,14 @@
rel="stylesheet" rel="stylesheet"
href="web_field_tooltip/static/src/css/web_field_tooltip.css" 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 <script
type="text/javascript" type="text/javascript"
src="/web_field_tooltip/static/src/js/web_field_tooltip.js" src="/web_field_tooltip/static/src/js/web_field_tooltip.js"