[REF] *: BS5: avoid multiple usage of BS handler

In BS5 there is a check to avoid having multiple handler for one
element and we can't add two components' instance on an element.

So, before disposing a tooltip we check if there is an instance of a
tooltip and we avoid instantiation of tooltip if not already done.

e.g.:
> Bootstrap doesn't allow more than one instance per element. Bound
> instance: bs.collapse.

e.g.:
> Bootstrap doesn't allow more than one instance per element. Bound
> instance: bs.carousel.

> Bootstrap doesn't allow more than one instance per element.
> Bound instance: bs.tooltip.

Task ID: 2766483

Part-of: odoo/odoo#95450
This commit is contained in:
Romeo Fragomeli
2022-07-07 13:30:20 +02:00
parent 0b94da214b
commit f936513466
9 changed files with 51 additions and 15 deletions
@@ -280,6 +280,18 @@ var AbstractController = mvc.Controller.extend(ActionMixin, {
this.renderer.giveFocus();
}
},
/**
* Hide an onboarding banner if present and visible
* @private
*/
_hideBanner: function () {
if (this._$banner.length) {
const $bannerElement = this._$banner.filter('.o_onboarding_container.collapse.show');
if ($bannerElement.length) {
Collapse.getOrCreateInstance($bannerElement[0]).toggle();
}
}
},
/**
* This method is the way a view can notifies the outside world that
* something has changed. The main use for this is to update the url, for
@@ -524,6 +536,9 @@ var AbstractController = mvc.Controller.extend(ActionMixin, {
additional_context: _.extend({}, data.context)
});
}
if (data.oHideBanner) {
self._hideBanner();
}
},
/**
* Called either from the control panel to focus the controller
@@ -93,7 +93,7 @@
const context = this._getRenderButtonContext();
this.$buttons = $(QWeb.render('PivotView.buttons', context));
this.$buttons.click(this._onButtonClick.bind(this));
this.$buttons.find('button').tooltip();
this.$buttons.find('button[title]').tooltip();
if ($node) {
this.$buttons.appendTo($node);
}
@@ -4,20 +4,32 @@ import { loadCSS, loadJS } from "@web/core/assets";
import { useService } from "@web/core/utils/hooks";
import { useActionLinks } from "@web/views/view_hook";
const { Component, markup, onWillStart, xml } = owl;
const { Component, markup, onWillStart, useRef, xml } = owl;
export class OnboardingBanner extends Component {
setup() {
this.rpc = useService("rpc");
this.user = useService("user");
this.onboardingContainerRef = useRef("onboardingContainer");
const resModel = "searchModel" in this.env ? this.env.searchModel.resModel : undefined;
this.handleActionLinks = useActionLinks({
this._handleActionLinks = useActionLinks({
resModel,
reload: async () => {
this.bannerHTML = await this.loadBanner(this.env.config.bannerRoute);
this.render();
},
});
this.handleActionLinks = (event) => {
if (event.target.dataset.oHideBanner) {
const collapseElement = this.onboardingContainerRef.el.querySelector(
".o_onboarding_container.collapse.show"
);
if (collapseElement) {
Collapse.getOrCreateInstance(collapseElement).toggle();
}
}
this._handleActionLinks(event);
};
onWillStart(this.onWillStart);
}
@@ -47,5 +59,5 @@ export class OnboardingBanner extends Component {
}
}
OnboardingBanner.template = xml`<div class="w-100" t-on-click="handleActionLinks" t-out="bannerHTML"/>`;
OnboardingBanner.template = xml`<div class="w-100" t-ref="onboardingContainer" t-on-click="handleActionLinks" t-out="bannerHTML"/>`;
OnboardingBanner.props = {};
@@ -43,12 +43,13 @@ QUnit.module('LegacyViews', {
assert.expect(6);
var banner_html =`
<div class="modal o_onboarding_modal o_technical_modal" tabindex="-1" role="dialog">
<div class="modal o_onboarding_modal o_technical_modal" tabindex="-1" role="dialog"
data-bs-backdrop="false">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-footer">
<a type="action" class="btn btn-primary" data-dismiss="modal"
data-toggle="collapse" href=".o_onboarding_container">
data-o-hide-banner="true">
Remove
</a>
</div>
+4 -4
View File
@@ -1139,14 +1139,14 @@ QUnit.module("Views", (hooks) => {
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Remove Configuration Tips</h5>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Do you want to remove this configuration panel?</p>
</div>
<div class="modal-footer">
<a type="action" class="btn btn-primary" data-dismiss="modal" data-toggle="collapse" href=".o_onboarding_container" data-model="mah.model" data-method="mah_method">Remove</a>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Discard</button>
<a type="action" class="btn btn-primary" data-bs-dismiss="modal" data-model="mah.model" data-method="mah_method" data-o-hide-banner="true">Remove</a>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Discard</button>
</div>
</div>
</div>
@@ -1154,7 +1154,7 @@ QUnit.module("Views", (hooks) => {
<div class="o_onboarding_container collapse show">
<div class="o_onboarding" />
<div class="o_onboarding_wrap" />
<a href="#" data-toggle="modal" data-target=".o_onboarding_modal" class="float-right o_onboarding_btn_close">
<a href="#" data-bs-toggle="modal" data-bs-target=".o_onboarding_modal" class="float-right o_onboarding_btn_close">
<i class="fa fa-times" title="Close the onboarding panel" id="closeOnboarding"></i>
</a>
<div class="bannerContent">Content</div>
@@ -501,7 +501,12 @@ var SnippetEditor = Widget.extend({
// Actually remove the snippet and its option UI.
var $parent = this.$target.parent();
this.$target.find('*').addBack().tooltip('dispose');
this.$target.find('*').addBack().each((index, el) => {
const tooltip = Tooltip.getInstance(el);
if (tooltip) {
tooltip.dispose();
}
});
this.$target.remove();
this.$el.remove();
@@ -60,7 +60,7 @@ const LinkPopoverWidget = Widget.extend({
});
const tooltips = [];
for (const el of this.$('[data-toggle="tooltip"]').toArray()) {
tooltips.push($(el).data('bs.tooltip'));
tooltips.push(Tooltip.getOrCreateInstance(el));
}
let popoverShown = true;
this.$target.popover({
@@ -96,12 +96,13 @@ const LinkPopoverWidget = Widget.extend({
}
})
.on('inserted.bs.popover.link_popover', () => {
this.$target.data('bs.popover').tip.classList.add('o_edit_menu_popover');
const popover = Popover.getInstance(this.target);
popover.tip.classList.add('o_edit_menu_popover');
})
.popover('show');
this.popover = this.$target.data('bs.popover');
this.popover = Popover.getInstance(this.target);
this.$target.on('mousedown.link_popover', (e) => {
if (!popoverShown) {
this.$target.popover('show');
+1 -1
View File
@@ -13,7 +13,7 @@
</div>
<div class="modal-footer">
<a type="action" class="btn btn-primary" data-dismiss="modal"
data-toggle="collapse" href=".o_onboarding_container"
data-o-hide-banner="true"
t-att-data-model="close_model" t-att-data-method="close_method">
Remove
</a>
+2
View File
@@ -38,6 +38,8 @@
"Modal": "readonly",
"Dropdown": "readonly",
"ScrollSpy": "readonly",
"Tooltip": "readonly",
"Collapse": "readonly",
"Alert": "readonly",
"globalThis": "readonly",
"module": "readonly",