[IMP] *: remove legacy notification service mapper

This commit removes the mapper to the notification service and adapts
widgets that display notifications.

task 3439226

Part-of: odoo/odoo#138348
This commit is contained in:
Michael (mcm)
2023-10-13 09:17:45 +00:00
parent bf6673c375
commit 94824d8767
24 changed files with 114 additions and 177 deletions
@@ -37,6 +37,7 @@ var PortalComposer = publicWidget.Widget.extend({
}, options || {});
this.attachments = [];
this.rpc = this.bindService("rpc");
this.notification = this.bindService("notification");
},
/**
* @override
@@ -124,11 +125,10 @@ var PortalComposer = publicWidget.Widget.extend({
self._updateAttachments();
resolve();
}).guardedCatch(function (error) {
self.displayNotification({
message: _t("Could not save file <strong>%s</strong>", escape(file.name)),
type: 'warning',
sticky: true,
});
self.notification.add(
_t("Could not save file <strong>%s</strong>", escape(file.name)),
{ type: 'warning', sticky: true }
);
resolve();
});
});
@@ -73,20 +73,6 @@ var ServicesMixin = {
});
return result;
},
/**
* Displays a notification.
*
* @param {Object} options
* @param {string} [options.title]
* @param {string} [options.subtitle]
* @param {string} [options.message]
* @param {string} [options.type='warning'] 'info', 'success', 'warning', 'danger' or ''
* @param {boolean} [options.sticky=false]
* @param {string} [options.className]
*/
displayNotification: function (options) {
return this.call('notification', 'notify', options);
},
};
export default ServicesMixin;
@@ -8,11 +8,7 @@ import { registry } from '@web/core/registry';
import lazyloader from "@web/legacy/js/public/lazyloader";
import {
makeLegacyNotificationService,
mapLegacyEnvToWowlEnv,
createWidgetParent,
} from "../../utils";
import { mapLegacyEnvToWowlEnv, createWidgetParent } from "../../utils";
import { makeEnv, startServices } from "@web/env";
import { loadJS, templates } from '@web/core/assets';
@@ -23,8 +19,6 @@ import { App, Component, whenReady } from "@odoo/owl";
const { Settings } = luxon;
const serviceRegistry = registry.category("services");
// Load localizations outside the PublicRoot to not wait for DOM ready (but
// wait for them in PublicRoot)
function getLang() {
@@ -323,9 +317,6 @@ Component.env = legacyEnv;
*/
export async function createPublicRoot(RootWidget) {
await lazyloader.allScriptsLoaded;
// add a bunch of mapping services that will redirect service calls from the legacy env
// to the wowl env
serviceRegistry.add("legacy_notification", makeLegacyNotificationService(legacyEnv));
await whenReady();
const wowlEnv = makeEnv();
@@ -1,7 +1,5 @@
/** @odoo-module alias=web.legacySetup **/
import { registry } from "../core/registry";
import { makeLegacyNotificationService } from "./utils";
import legacyEnv from "@web/legacy/js/env";
import { templates } from "@web/core/assets";
@@ -16,10 +14,6 @@ export const legacySetupProm = new Promise((resolve) => {
// with the starting of the webclient)
(async () => {
Component.env = legacyEnv;
const serviceRegistry = registry.category("services");
// add a service to redirect rpc events triggered on the bus in the
// legacy env on the bus in the wowl env
serviceRegistry.add("legacy_notification", makeLegacyNotificationService(legacyEnv));
await whenReady();
legacyEnv.templates = templates;
legacySetupResolver(legacyEnv);
-67
View File
@@ -1,6 +1,5 @@
/** @odoo-module **/
import { browser } from "../core/browser/browser";
import { useService } from "@web/core/utils/hooks";
import {
App,
@@ -45,72 +44,6 @@ export function cleanDomFromBootstrap() {
}
}
export function makeLegacyNotificationService(legacyEnv) {
return {
dependencies: ["notification"],
start(env, { notification }) {
let notifId = 0;
const idsToRemoveFn = {};
function notify({
title,
message,
subtitle,
buttons = [],
sticky,
type,
className,
onClose,
}) {
if (subtitle) {
title = [title, subtitle].filter(Boolean).join(" ");
}
if (!message && title) {
message = title;
title = undefined;
}
buttons = buttons.map((button) => {
return {
name: button.text,
icon: button.icon,
primary: button.primary,
onClick: button.click,
};
});
const removeFn = notification.add(message, {
sticky,
title,
type,
className,
onClose,
buttons,
});
const id = ++notifId;
idsToRemoveFn[id] = removeFn;
return id;
}
function close(id, _, wait) {
//the legacy close method had 3 arguments : the notification id, silent and wait.
//the new close method only has 2 arguments : the notification id and wait.
const removeFn = idsToRemoveFn[id];
delete idsToRemoveFn[id];
if (wait) {
browser.setTimeout(() => {
removeFn(id);
}, wait);
} else {
removeFn(id);
}
}
legacyEnv.services.notification = { notify, close, add: notification.add };
},
};
}
/**
* This hook allows legacy owl Components to use services coming from the wowl env.
* @param {string} serviceName
@@ -2,4 +2,4 @@
// in tests, there's nothing to setup globally (we don't want to deploy services),
// but this module must exist has it is required by other modules
export const legacySetupProm = Promise.resolve();
@@ -1768,6 +1768,7 @@ var SnippetsMenu = Widget.extend({
this._onClick = this._onClick.bind(this);
this.orm = this.bindService("orm");
this.notification = this.bindService("notification");
},
/**
* @override
@@ -3827,8 +3828,7 @@ var SnippetsMenu = Widget.extend({
reason.event.preventDefault();
this.close();
const message = markup(_t("Could not install module <strong>%s</strong>", escape(name)));
self.displayNotification({
message: message,
self.notification.add(message, {
type: 'danger',
sticky: true,
});
@@ -94,9 +94,8 @@ export class LinkPopoverWidget {
);
clipboard.on('success', () => {
this.$copyLink.tooltip('hide');
this.notify({
this.notify(_t("Link copied to clipboard."), {
type: 'success',
message: _t("Link copied to clipboard."),
});
this.popover.hide();
});
@@ -246,9 +245,8 @@ export class LinkPopoverWidget {
} catch {
// Invalid URL, might happen with editor unsuported protocol. eg type
// `geo:37.786971,-122.399677`, become `http://geo:37.786971,-122.399677`
this.notify({
this.notify(_t("This URL is invalid. Preview couldn't be updated."), {
type: 'danger',
message: _t("This URL is invalid. Preview couldn't be updated."),
});
return;
}
@@ -29,6 +29,7 @@ export const WebsiteRoot = publicRootData.PublicRoot.extend({
init() {
this.isFullscreen = false;
this.rpc = this.bindService("rpc");
this.notification = this.bindService("notification");
return this._super(...arguments);
},
/**
@@ -115,15 +116,13 @@ export const WebsiteRoot = publicRootData.PublicRoot.extend({
if (!editableMode && session.is_admin) {
const message = _t("Cannot load google map.");
const urlTitle = _t("Check your configuration.");
this.displayNotification({
type: 'warning',
sticky: true,
message:
markup(`<div>
<span>${message}</span><br/>
<a href="/web#action=website.action_website_configuration">${urlTitle}</a>
</div>`),
});
this.notification.add(
markup(`<div>
<span>${message}</span><br/>
<a href="/web#action=website.action_website_configuration">${urlTitle}</a>
</div>`),
{ type: 'warning', sticky: true }
);
}
resolve(false);
this._gmapAPILoading = false;
@@ -36,6 +36,13 @@ const wSnippetMenu = weSnippetEditor.SnippetsMenu.extend({
['theme-advanced', _t("Advanced")],
],
/**
* @override
*/
init() {
this._super(...arguments);
this.notification = this.bindService("notification");
},
/**
* @override
*/
@@ -428,11 +435,10 @@ const wSnippetMenu = weSnippetEditor.SnippetsMenu.extend({
});
this.options.wysiwyg.odooEditor.historyStep();
} else {
this.displayNotification({
message: _t("The current text selection cannot be animated. Try clearing the format and try again."),
type: 'danger',
sticky: true,
});
this.notification.add(
_t("The current text selection cannot be animated. Try clearing the format and try again."),
{ type: 'danger', sticky: true }
);
}
}
},
@@ -412,6 +412,8 @@ const GPSPicker = InputUserValueWidget.extend({
// not having to load it in the backend too and just using the iframe
// google object instead.
this.contentWindow = this.$target[0].ownerDocument.defaultView;
this.notification = this.bindService("notification");
},
/**
* @override
@@ -570,11 +572,10 @@ const GPSPicker = InputUserValueWidget.extend({
}
this._gmapErrorNotified = true;
this.displayNotification({
type: 'danger',
sticky: true,
message: _t("A Google Map error occurred. Make sure to read the key configuration popup carefully."),
});
this.notification.add(
_t("A Google Map error occurred. Make sure to read the key configuration popup carefully."),
{ type: 'danger', sticky: true }
);
this.trigger_up('gmap_api_request', {
editableMode: true,
reconfigure: true,
@@ -1577,6 +1578,7 @@ options.registry.menu_data = options.Class.extend({
this._super(...arguments);
this.user = this.bindService("user");
this.orm = this.bindService("orm");
this.notification = this.bindService("notification");
},
/**
@@ -1595,7 +1597,7 @@ options.registry.menu_data = options.Class.extend({
target: this.$target[0],
wysiwyg,
container: popoverContainer,
notify: this.displayNotification.bind(this),
notify: this.notification.add,
checkIsWebsiteDesigner: () => this.user.hasGroup("website.group_website_designer"),
onEditLinkClick: (widget) => {
var $menu = widget.$target.find('[data-oe-id]');
@@ -2658,6 +2660,13 @@ options.registry.HideFooter = VisibilityPageOptionUpdate.extend({
options.registry.anchor = options.Class.extend({
isTopOption: true,
/**
* @override
*/
init() {
this._super(...arguments);
this.notification = this.bindService("notification");
},
/**
* @override
*/
@@ -2705,10 +2714,9 @@ options.registry.anchor = options.Class.extend({
const clipboard = new ClipboardJS(buttonEl, {text: () => this._getAnchorLink()});
clipboard.on("success", () => {
const message = markup(_t("Anchor copied to clipboard<br>Link: %s", this._getAnchorLink()));
this.displayNotification({
this.notification.add(message, {
type: "success",
message: message,
buttons: [{text: _t("Edit"), click: () => this._openAnchorDialog(buttonEl), primary: true}],
buttons: [{name: _t("Edit"), onClick: () => this._openAnchorDialog(buttonEl), primary: true}],
});
});
},
@@ -11,6 +11,7 @@ options.registry.InstagramPage = options.Class.extend({
init() {
this._super(...arguments);
this.orm = this.bindService("orm");
this.notification = this.bindService("notification");
this.instagramUrlStr = "instagram.com/";
},
/**
@@ -54,8 +55,7 @@ options.registry.InstagramPage = options.Class.extend({
widgetValue = this._getInstagramPageNameFromUrl(widgetValue);
}
if (!widgetValue) {
this.displayNotification({
message: _t("The Instagram page name is not valid"),
this.notification.add(_t("The Instagram page name is not valid"), {
type: "warning",
});
}
@@ -359,6 +359,13 @@ options.registry.WebsiteFormEditor = FormEditor.extend({
'click .toggle-edit-message': '_onToggleEndMessageClick',
}),
/**
* @override
*/
init() {
this._super(...arguments);
this.notification = this.bindService("notification");
},
/**
* @override
*/
@@ -517,8 +524,7 @@ options.registry.WebsiteFormEditor = FormEditor.extend({
},
onFailure: () => {
restore();
this.displayNotification({
message: _t("Something went wrong."),
this.notification.add(_t("Something went wrong."), {
type: 'danger',
sticky: true,
});
+2 -2
View File
@@ -61,6 +61,7 @@ options.registry.BlogPostTagSelection = options.Class.extend({
init() {
this._super(...arguments);
this.orm = this.bindService("orm");
this.notification = this.bindService("notification");
},
/**
@@ -122,9 +123,8 @@ options.registry.BlogPostTagSelection = options.Class.extend({
&& (typeof(tag.id) === 'number' || this.tagIDs.includes(tag.id));
});
if (existing) {
return this.displayNotification({
return this.notification.add(_t("This tag already exists"), {
type: 'warning',
message: _t("This tag already exists"),
});
}
const newTagID = uniqueId(NEW_TAG_PREFIX);
@@ -3,11 +3,15 @@
import { _t } from "@web/core/l10n/translation";
import publicWidget from "@web/legacy/js/public/public_widget";
import { markup } from "@odoo/owl";
publicWidget.registry.RegisterToasterWidget = publicWidget.Widget.extend({
selector: '.o_wevent_register_toaster',
/**
* @override
*/
init() {
this._super(...arguments);
this.notification = this.bindService("notification");
},
/**
* This widget allows to display a toast message on the page.
*
@@ -16,9 +20,8 @@ publicWidget.registry.RegisterToasterWidget = publicWidget.Widget.extend({
start: function () {
const message = this.$el.data('message');
if (message && message.length) {
this.displayNotification({
this.notification.add(message, {
title: _t("Register"),
message: markup(message),
type: 'info',
});
}
@@ -18,6 +18,7 @@ publicWidget.registry.websiteEventTrackReminder = publicWidget.Widget.extend({
this._super.apply(this, arguments);
this._onReminderToggleClick = debounce(this._onReminderToggleClick, 500, true);
this.rpc = this.bindService("rpc");
this.notification = this.bindService("notification");
},
//--------------------------------------------------------------------------
@@ -45,10 +46,9 @@ publicWidget.registry.websiteEventTrackReminder = publicWidget.Widget.extend({
set_reminder_on: reminderOnValue,
}).then(function (result) {
if (result.error && result.error === 'ignored') {
self.displayNotification({
self.notification.add(_t('Talk already in your Favorites'), {
type: 'info',
title: _t('Error'),
message: _t('Talk already in your Favorites'),
});
} else {
self.reminderOn = reminderOnValue;
@@ -56,9 +56,8 @@ publicWidget.registry.websiteEventTrackReminder = publicWidget.Widget.extend({
self.$('.o_wetrack_js_reminder_text').text(reminderText);
self._updateDisplay();
var message = self.reminderOn ? _t('Talk added to your Favorites') : _t('Talk removed from your Favorites');
self.displayNotification({
self.notification.add(message, {
type: 'info',
title: message
});
if (self.reminderOn) {
core.bus.trigger('open_notification_request', 'add_track_to_favorite', {
@@ -47,6 +47,7 @@ var Quiz = publicWidget.Widget.extend({
this.redirectURL = encodeURIComponent(document.URL);
this.rpc = this.bindService("rpc");
this.notification = this.bindService("notification");
},
/**
@@ -87,10 +88,9 @@ var Quiz = publicWidget.Widget.extend({
message = _t('This quiz is already done. Retaking it is not possible.');
}
this.displayNotification({
this.notification.add(message, {
type: 'warning',
title: _t('Quiz validation error'),
message: message,
sticky: true
});
},
@@ -37,6 +37,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
this._super(...arguments);
this.rpc = this.bindService("rpc");
this.orm = this.bindService("orm");
this.notification = this.bindService("notification");
},
/**
@@ -281,11 +282,11 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
</a>`)
: "";
const translatedText = _t("karma is required to perform this action. ");
this.displayNotification({
const message = markup(`${karma} ${translatedText}${additionalInfoWithForumID}`);
this.notification.add(message, {
type: "warning",
sticky: false,
title: _t("Karma Error"),
message: markup(`${karma} ${translatedText}${additionalInfoWithForumID}`)
});
},
/**
@@ -579,8 +580,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
});
},
_displayAccessDeniedNotification(message) {
this.displayNotification({
message: message,
this.notification.add(message, {
title: _t('Access Denied'),
sticky: false,
type: 'warning',
@@ -18,6 +18,7 @@ publicWidget.registry.subscribe = publicWidget.Widget.extend({
this._super(...arguments);
this._recaptcha = new ReCaptcha();
this.rpc = this.bindService("rpc");
this.notification = this.bindService("notification");
},
/**
* @override
@@ -99,10 +100,9 @@ publicWidget.registry.subscribe = publicWidget.Widget.extend({
this.$el.removeClass('o_has_error').find('.form-control').removeClass('is-invalid');
const tokenObj = await this._recaptcha.getToken('website_mass_mailing_subscribe');
if (tokenObj.error) {
self.displayNotification({
self.notification.add(tokenObj.error, {
type: 'danger',
title: _t("Error"),
message: tokenObj.error,
sticky: true,
});
return false;
@@ -123,10 +123,9 @@ publicWidget.registry.subscribe = publicWidget.Widget.extend({
$popup.modal('hide');
}
}
self.displayNotification({
self.notification.add(result.toast_content, {
type: toastType,
title: toastType === 'success' ? _t('Success') : _t('Error'),
message: result.toast_content,
sticky: true,
});
});
@@ -459,6 +459,7 @@ options.registry.WebsiteSaleProductPage = options.Class.extend({
this._super(...arguments);
this.rpc = this.bindService("rpc");
this.orm = this.bindService("orm");
this.notification = this.bindService("notification");
},
/**
@@ -560,10 +561,10 @@ options.registry.WebsiteSaleProductPage = options.Class.extend({
*/
addImages: function () {
if(this.mode === 'product.template'){
this.displayNotification({
type: 'info',
message: 'Pictures will be added to the main image. Use "Instant" attributes to set pictures on each variants'
});
this.notification.add(
'Pictures will be added to the main image. Use "Instant" attributes to set pictures on each variants',
{ type: 'info' }
);
}
let extraImageEls;
this.call("dialog", "add", AttachmentMediaDialog, {
@@ -11,6 +11,11 @@ publicWidget.registry.AddToCartSnippet = WebsiteSale.extend(cartHandlerMixin, {
'click': '_onClickAddToCartButton',
},
init() {
this._super(...arguments);
this.notification = this.bindService("notification");
},
_onClickAddToCartButton: async function (ev) {
const dataset = ev.currentTarget.dataset;
@@ -29,11 +34,10 @@ publicWidget.registry.AddToCartSnippet = WebsiteSale.extend(cartHandlerMixin, {
product_id: productId,
});
if (!isAddToCartAllowed) {
this.displayNotification({
title: 'User Error',
message: _t('This product does not exist therefore it cannot be added to cart.'),
type: 'warning'
});
this.notification.add(
_t('This product does not exist therefore it cannot be added to cart.'),
{ title: 'User Error', type: 'warning' }
);
return;
}
this.isBuyNow = action === 'buy_now';
@@ -4,24 +4,32 @@ import publicWidget from '@web/legacy/js/public/public_widget';
import {registry} from "@web/core/registry";
const CouponToasterWidget = publicWidget.Widget.extend({
init() {
this._super(...arguments);
this.notification = this.bindService("notification");
},
start() {
let options = {};
const $content = this.$('.coupon-message-content');
const $title = this.$('.coupon-message-title');
let message = null;
if ($content.length) {
Object.assign(options, {message: $content[0].innerHTML});
}
if ($title.length) {
Object.assign(options, {title: $title[0].innerHTML});
message = $content[0].innerHTML;
if ($title.length) {
Object.assign(options, {title: $title[0].innerHTML});
}
} else if ($title.length) {
message = $title[0].innerHTML;
}
if (this.$el.hasClass('coupon-info-message')) {
this.displayNotification(Object.assign({type: 'success'}, options));
this.notification.add(message, Object.assign({type: 'success'}, options));
} else if (this.$el.hasClass('coupon-error-message')) {
this.displayNotification(Object.assign({type: 'danger'}, options));
this.notification.add(message, Object.assign({type: 'danger'}, options));
} else if (this.$el.hasClass('coupon-warning-message')) {
this.displayNotification(Object.assign({type: 'warning'}, options));
this.notification.add(message, Object.assign({type: 'warning'}, options));
}
return this._super(...arguments);
@@ -385,6 +385,7 @@
this.session = session;
this.rpc = this.bindService("rpc");
this.notification = this.bindService("notification");
},
//--------------------------------------------------------------------------
@@ -419,13 +420,13 @@
form.find('.alert-info').removeClass('d-none');
form.find('.input-group').addClass('d-none');
} else {
this.displayNotification({ message: _t('Please enter valid email(s)'), type: 'danger' });
this.notification.add(_t('Please enter valid email(s)'), { type: 'danger' });
form.addClass('o_has_error').find('.form-control, .form-select').addClass('is-invalid');
input.focus();
}
});
} else {
this.displayNotification({ message: _t('Please enter valid email(s)'), type: 'danger' });
this.notification.add(_t('Please enter valid email(s)'), { type: 'danger' });
form.addClass('o_has_error').find('.form-control, .form-select').addClass('is-invalid');
input.focus();
}
@@ -13,6 +13,7 @@ export const ShareMail = publicWidget.Widget.extend({
init() {
this._super(...arguments);
this.rpc = this.bindService("rpc");
this.notification = this.bindService("notification");
},
//--------------------------------------------------------------------------
@@ -57,13 +58,13 @@ export const ShareMail = publicWidget.Widget.extend({
this.$('.alert-info').removeClass('d-none');
this.$('.input-group').addClass('d-none');
} else {
this.displayNotification({ message: _t('Please enter valid email(s)'), type: 'danger' });
this.notification.add(_t('Please enter valid email(s)'), { type: 'danger' });
this.$el.addClass('o_has_error').find('.form-control, .form-select').addClass('is-invalid');
input.focus();
}
});
} else {
this.displayNotification({ message: _t('Please enter valid email(s)'), type: 'danger' });
this.notification.add(_t('Please enter valid email(s)'), { type: 'danger' });
this.$el.addClass('o_has_error').find('.form-control, .form-select').addClass('is-invalid');
input.focus();
}