mirror of https://github.com/OCA/web.git
[REF] use FormViewDialog instead of do_action, allow to unlink a tooltip from the helper, splitted resources into multiple files
parent
04f51fe278
commit
d733c79b5f
|
@ -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.
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
|
@ -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;
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
|
@ -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() {
|
|
||||||
this._super.apply(this, arguments);
|
|
||||||
this.tooltips = undefined;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @override
|
|
||||||
*/
|
|
||||||
_renderTagLabel: function(node) {
|
|
||||||
const self = this;
|
const self = this;
|
||||||
const $result = this._super.apply(this, arguments);
|
new dialogs.FormViewDialog(self, {
|
||||||
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",
|
_onEditTooltip: function(params) {
|
||||||
domain: [["model", "=", self.modelName]],
|
const self = this;
|
||||||
context: {tooltip_model: self.modelName},
|
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,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue