diff options
14 files changed, 151 insertions, 80 deletions
diff --git a/addons/gamification/static/src/js/crash_manager.js b/addons/gamification/static/src/js/crash_manager.js new file mode 100644 index 00000000000..f655f06dec0 --- /dev/null +++ b/addons/gamification/static/src/js/crash_manager.js @@ -0,0 +1,20 @@ +odoo.define('gamification.CrashManager', function (require) { +"use strict"; + +const core = require('web.core'); +const CrashManager = require('web.CrashManager').CrashManager; + +const _lt = core._lt; + +CrashManager.include({ + /** + * @override + */ + getMapTitle() { + return { + ...this._super(...arguments), + karma_error: _lt("Karma Error"), + }; + }, +}); +}); diff --git a/addons/gamification/views/gamification.xml b/addons/gamification/views/gamification.xml index 08341ac83c0..b9217e26d9a 100644 --- a/addons/gamification/views/gamification.xml +++ b/addons/gamification/views/gamification.xml @@ -4,4 +4,10 @@ <link rel="stylesheet" type="text/scss" href="/gamification/static/src/scss/gamification.scss"/> </xpath> </template> + + <template id="assets_common" inherit_id="web.assets_common"> + <xpath expr="script[last()]" position="after"> + <script type="text/javascript" src="/gamification/static/src/js/crash_manager.js"/> + </xpath> + </template> </odoo> diff --git a/addons/stock/static/src/js/stock_traceability_report_backend.js b/addons/stock/static/src/js/stock_traceability_report_backend.js index 56673f4e094..31e42767cf5 100644 --- a/addons/stock/static/src/js/stock_traceability_report_backend.js +++ b/addons/stock/static/src/js/stock_traceability_report_backend.js @@ -6,7 +6,6 @@ var core = require('web.core'); var session = require('web.session'); var ReportWidget = require('stock.ReportWidget'); var framework = require('web.framework'); -var crash_manager = require('web.crash_manager'); var QWeb = core.qweb; @@ -104,7 +103,7 @@ var stock_report_generic = AbstractAction.extend({ url: url_data.replace('output_format', 'pdf'), data: {data: JSON.stringify(dict)}, complete: framework.unblockUI, - error: crash_manager.rpc_error.bind(crash_manager), + error: () => this.call('crash_manager', 'rpc_error', ...arguments), }); }); return this.$buttons; diff --git a/addons/web/static/src/js/chrome/action_manager_report.js b/addons/web/static/src/js/chrome/action_manager_report.js index 30bac14006d..416cad6a942 100644 --- a/addons/web/static/src/js/chrome/action_manager_report.js +++ b/addons/web/static/src/js/chrome/action_manager_report.js @@ -8,7 +8,6 @@ odoo.define('web.ReportActionManager', function (require) { var ActionManager = require('web.ActionManager'); var core = require('web.core'); -var crash_manager = require('web.crash_manager'); var framework = require('web.framework'); var session = require('web.session'); @@ -54,8 +53,8 @@ ActionManager.include({ data: JSON.stringify([url, type]), }, success: resolve, - error: function () { - crash_manager.rpc_error.apply(crash_manager, arguments); + error: () => { + this.call('crash_manager', 'rpc_error', ...arguments); reject(); }, complete: framework.unblockUI, diff --git a/addons/web/static/src/js/core/misc.js b/addons/web/static/src/js/core/misc.js index 39fd8021071..6260a4ab583 100644 --- a/addons/web/static/src/js/core/misc.js +++ b/addons/web/static/src/js/core/misc.js @@ -2,9 +2,9 @@ odoo.define('web.framework', function (require) { "use strict"; var core = require('web.core'); -var crash_manager = require('web.crash_manager'); var ajax = require('web.ajax'); var Widget = require('web.Widget'); +var disableCrashManager = require('web.CrashManager').disable; var _t = core._t; @@ -101,7 +101,7 @@ function unblockUI() { */ function redirect (url, wait) { // Dont display a dialog if some xmlhttprequest are in progress - crash_manager.disable(); + disableCrashManager(); var load = function() { var old = "" + window.location; diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 4e63e5d3613..322168a7241 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -10,7 +10,6 @@ odoo.define('web.basic_fields', function (require) { var AbstractField = require('web.AbstractField'); var config = require('web.config'); var core = require('web.core'); -var crash_manager = require('web.crash_manager'); var datepicker = require('web.datepicker'); var dom = require('web.dom'); var Domain = require('web.Domain'); @@ -1928,11 +1927,10 @@ var FieldBinaryFile = AbstractFieldBinary.extend({ ev.stopPropagation(); } else if (this.res_id) { framework.blockUI(); - var c = crash_manager; var filename_fieldname = this.attrs.filename; this.getSession().get_file({ - 'url': '/web/content', - 'data': { + complete: framework.unblockUI, + data: { 'model': this.model, 'id': this.res_id, 'field': this.name, @@ -1941,8 +1939,8 @@ var FieldBinaryFile = AbstractFieldBinary.extend({ 'download': true, 'data': utils.is_bin_size(this.value) ? null : this.value, }, - 'complete': framework.unblockUI, - 'error': c.rpc_error.bind(c), + error: () => this.call('crash_manager', 'rpc_error', ...arguments), + url: '/web/content', }); ev.stopPropagation(); } diff --git a/addons/web/static/src/js/public/public_crash_manager.js b/addons/web/static/src/js/public/public_crash_manager.js new file mode 100644 index 00000000000..450753e51ad --- /dev/null +++ b/addons/web/static/src/js/public/public_crash_manager.js @@ -0,0 +1,33 @@ +odoo.define('web.PublicCrashManager', function (require) { +"use strict"; + +const core = require('web.core'); +const CrashManager = require('web.CrashManager').CrashManager; + +const PublicCrashManager = CrashManager.extend({ + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @override + */ + _displayWarning(message, title, subtitle, options) { + this.displayNotification({ + ...options, + title, + message, + subtitle, + sticky: true, + }); + }, +}); + +core.serviceRegistry.add('crash_manager', PublicCrashManager); + +return { + CrashManager: PublicCrashManager, +}; + +}); diff --git a/addons/web/static/src/js/services/crash_manager.js b/addons/web/static/src/js/services/crash_manager.js index 701d97f0a53..6baca444788 100644 --- a/addons/web/static/src/js/services/crash_manager.js +++ b/addons/web/static/src/js/services/crash_manager.js @@ -1,27 +1,22 @@ odoo.define('web.CrashManager', function (require) { "use strict"; +const AbstractService = require('web.AbstractService'); var ajax = require('web.ajax'); var core = require('web.core'); var Dialog = require('web.Dialog'); -var mixins = require('web.mixins'); -var ServicesMixin = require('web.ServicesMixin'); -var ServiceProviderMixin = require('web.ServiceProviderMixin'); var Widget = require('web.Widget'); var _t = core._t; var _lt = core._lt; -var map_title ={ - user_error: _lt("User Error"), - warning: _lt("Warning"), - access_error: _lt("Access Error"), - missing_error: _lt("Missing Record"), - validation_error: _lt("Validation Error"), - except_orm: _lt("Global Business Error"), - access_denied: _lt("Access Denied"), - karma_error: _lt("Karma Error"), -}; +// Register this eventlistener before qunit does. +// Some errors needs to be negated by the crash_manager. +window.addEventListener('unhandledrejection', ev => + core.bus.trigger('crash_manager_unhandledrejection', ev) +); + +let active = true; /** * An extension of Dialog Widget to render the warnings and errors on the website. @@ -78,13 +73,13 @@ var WarningDialog = CrashManagerDialog.extend({ }, }); -var CrashManager = core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, ServiceProviderMixin,{ +var CrashManager = AbstractService.extend({ init: function () { var self = this; - this.active = true; + active = true; this.isConnected = true; - mixins.EventDispatcherMixin.init.call(this); + this._super.apply(this, arguments); // crash manager integration core.bus.on('rpc_error', this, this.rpc_error); @@ -128,7 +123,7 @@ var CrashManager = core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, // listen to unhandled rejected promises, and throw an error when the // promise has been rejected due to a crash - window.addEventListener('unhandledrejection', function (ev) { + core.bus.on('crash_manager_unhandledrejection', this, function (ev) { if (ev.reason && ev.reason instanceof Error) { var traceback = ev.reason.stack; self.show_error({ @@ -144,13 +139,26 @@ var CrashManager = core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, ev.preventDefault(); } }); - ServiceProviderMixin.init.call(this); }, enable: function () { - this.active = true; + active = true; }, disable: function () { - this.active = false; + active = false; + }, + /** + * @return {Object} + */ + getMapTitle() { + return { + access_denied: _lt("Access Denied"), + access_error: _lt("Access Error"), + except_orm: _lt("Global Business Error"), + missing_error: _lt("Missing Record"), + user_error: _lt("User Error"), + validation_error: _lt("Validation Error"), + warning: _lt("Warning"), + }; }, handleLostConnection: function () { var self = this; @@ -175,7 +183,13 @@ var CrashManager = core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, }, delay); }, rpc_error: function(error) { - if (!this.active) { + // Some qunit tests produces errors before the DOM is set. + // This produces an error loop as the modal/toast has no DOM to attach to. + if (!document.body) { + return; + } + var map_title = this.getMapTitle(); + if (!active) { return; } if (this.connection_lost) { @@ -229,21 +243,16 @@ var CrashManager = core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, } }, show_warning: function (error, options) { - if (!this.active) { + if (!active) { return; } var message = error.data ? error.data.message : error.message; var title = _.str.capitalize(error.type) || _t("Oops Something went wrong !"); var subtitle = error.data ? error.data.title : error.title; - this.displayNotification(_.extend({ - title: title, - message: message, - subtitle: subtitle, - sticky: true, - }, options)); + return this._displayWarning(message, title, subtitle, options); }, show_error: function (error) { - if (!this.active) { + if (!active) { return; } var dialog = new ErrorDialog(this, { @@ -297,6 +306,27 @@ var CrashManager = core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, data: {debug: ""} }); }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + * @param {string} message + * @param {string} title + * @param {string} subtitle + * @param {Object} options + */ + _displayWarning: function (message, title, subtitle, options) { + return new WarningDialog(this, { + ...options, + title, + subtitle, + }, { + message, + }).open(); + }, }); /** @@ -375,13 +405,6 @@ return { CrashManager: CrashManager, ErrorDialog: ErrorDialog, WarningDialog: WarningDialog, + disable: () => active = false, }; }); - -odoo.define('web.crash_manager', function (require) { -"use strict"; - -var CrashManager = require('web.CrashManager').CrashManager; -return new CrashManager(); - -}); diff --git a/addons/web/static/src/js/services/crash_manager_service.js b/addons/web/static/src/js/services/crash_manager_service.js new file mode 100644 index 00000000000..44182561a1b --- /dev/null +++ b/addons/web/static/src/js/services/crash_manager_service.js @@ -0,0 +1,9 @@ +odoo.define('crash_manager.service', function (require) { +'use strict'; + +const core = require('web.core'); +const CrashManager = require('web.CrashManager').CrashManager; + +core.serviceRegistry.add('crash_manager', CrashManager); + +}); diff --git a/addons/web/static/src/js/views/pivot/pivot_controller.js b/addons/web/static/src/js/views/pivot/pivot_controller.js index 046c2979063..b5257a987c7 100644 --- a/addons/web/static/src/js/views/pivot/pivot_controller.js +++ b/addons/web/static/src/js/views/pivot/pivot_controller.js @@ -14,7 +14,6 @@ odoo.define('web.PivotController', function (require) { var AbstractController = require('web.AbstractController'); var core = require('web.core'); -var crash_manager = require('web.crash_manager'); var framework = require('web.framework'); var session = require('web.session'); @@ -126,7 +125,7 @@ var PivotController = AbstractController.extend({ _downloadTable: function () { var table = this.model.exportData(); if(table.measure_row.length + 1 > 256) { - crash_manager.show_message(_t("For Excel compatibility, data cannot be exported if there are more than 256 columns.\n\nTip: try to flip axis, filter further or reduce the number of measures.")); + this.call('crash_manager', 'show_message', _t("For Excel compatibility, data cannot be exported if there are more than 256 columns.\n\nTip: try to flip axis, filter further or reduce the number of measures.")); framework.unblockUI(); return; } @@ -136,7 +135,7 @@ var PivotController = AbstractController.extend({ url: '/web/pivot/export_xls', data: {data: JSON.stringify(table)}, complete: framework.unblockUI, - error: crash_manager.rpc_error.bind(crash_manager) + error: () => this.call('crash_manager', 'rpc_error', ...arguments), }); }, /** diff --git a/addons/web/static/src/js/widgets/data_export.js b/addons/web/static/src/js/widgets/data_export.js index 6903e7fea33..9031dd43232 100644 --- a/addons/web/static/src/js/widgets/data_export.js +++ b/addons/web/static/src/js/widgets/data_export.js @@ -3,7 +3,6 @@ odoo.define('web.DataExport', function (require) { var config = require('web.config'); var core = require('web.core'); -var crash_manager = require('web.crash_manager'); var Dialog = require('web.Dialog'); var data = require('web.data'); var framework = require('web.framework'); @@ -168,7 +167,7 @@ var DataExport = Dialog.extend({ }) }, complete: framework.unblockUI, - error: crash_manager.rpc_error.bind(crash_manager), + error: () => this.call('crash_manager', 'rpc_error', ...arguments), }); }, /** diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index c3fc7d15479..2c9000ec0ff 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -251,6 +251,7 @@ <script type="text/javascript" src="/web/static/src/js/core/context.js"></script> <script type="text/javascript" src="/web/static/src/js/core/data_comparison_utils.js"></script> <script type="text/javascript" src="/web/static/src/js/core/misc.js"></script> + <script type="text/javascript" src="/web/static/src/js/services/crash_manager_service.js"></script> <script type="text/javascript" src="/web/static/src/js/services/data_manager.js"></script> <script type="text/javascript" src="/web/static/src/js/services/report_service.js"></script> <script type="text/javascript" src="/web/static/src/js/services/session.js"></script> @@ -386,6 +387,7 @@ <t t-call="web._assets_frontend_minimal_js"/> <script type="text/javascript" src="/web/static/src/js/services/session.js"/> + <script type="text/javascript" src="/web/static/src/js/public/public_crash_manager.js"/> <script type="text/javascript" src="/web/static/src/js/public/public_notification.js"/> <script type="text/javascript" src="/web/static/src/js/public/public_root.js"/> <script type="text/javascript" src="/web/static/src/js/public/public_root_instance.js"/> @@ -572,27 +574,9 @@ <script type="text/javascript" src="/web/static/lib/ace/mode-js.js"></script> <script type="text/javascript"> - odoo.define('web.WebClientWithoutServices', function (require) { - var ServiceProviderMixin = require('web.ServiceProviderMixin'); - var WebClient = require('web.WebClient'); - var WebClientWithoutServices = WebClient.extend({ - /** - * Patch web client so that it is no longer a service provider. - * - * @override - */ - init: function () { - var originalServiceProviderMixinInit = ServiceProviderMixin.init; - ServiceProviderMixin.init = function () {}; - this._super.apply(this, arguments); - ServiceProviderMixin.init = originalServiceProviderMixinInit; - }, - }); - return WebClientWithoutServices; - }); // define the 'web.web_client' module because some other modules require it odoo.define('web.web_client', function (require) { - var WebClient = require('web.WebClientWithoutServices'); + var WebClient = require('web.WebClient'); var web_client = new WebClient(); return web_client; }); diff --git a/addons/website_forum/static/src/js/website_forum.js b/addons/website_forum/static/src/js/website_forum.js index 9528a9b5e73..b364a3f9d1c 100644 --- a/addons/website_forum/static/src/js/website_forum.js +++ b/addons/website_forum/static/src/js/website_forum.js @@ -2,7 +2,6 @@ odoo.define('website_forum.website_forum', function (require) { 'use strict'; var core = require('web.core'); -var crash_manager = require('web.crash_manager'); var Wysiwyg = require('web_editor.wysiwyg.root'); var publicWidget = require('web.public.widget'); var session = require('web.session'); @@ -190,7 +189,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ msg = _t("Sorry you must be logged in to perform this action"); title = _t("Access Denied"); } - crash_manager.show_warning({ + this.call('crash_manager', 'show_warning', { message: msg, title: title, }, { @@ -237,6 +236,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ * @param {Event} ev */ _onFlagAlertClick: function (ev) { + var self = this; ev.preventDefault(); var $link = $(ev.currentTarget); this._rpc({ @@ -251,7 +251,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ } else if (data.error === 'post_non_flaggable') { message = _t("This post can not be flagged"); } - crash_manager.show_warning({ + self.call('crash_manager', 'show_warning', { message: message, title: _t("Access Denied"), }, { @@ -278,6 +278,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ * @param {Event} ev */ _onVotePostClick: function (ev) { + var self = this; ev.preventDefault(); var $link = $(ev.currentTarget); this._rpc({ @@ -290,7 +291,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ } else if (data.error === 'anonymous_user') { message = _t('Sorry you must be logged to vote'); } - crash_manager.show_warning({ + self.call('crash_manager', 'show_warning', { message: message, title: _t("Access Denied"), }, { @@ -334,6 +335,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ * @param {Event} ev */ _onAcceptAnswerClick: function (ev) { + var self = this; ev.preventDefault(); var $link = $(ev.currentTarget); this._rpc({ @@ -343,7 +345,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ if (data.error === 'anonymous_user') { var message = _t("Sorry, anonymous users cannot choose correct answer."); } - crash_manager.show_warning({ + self.call('crash_manager', 'show_warning', { message: message, title: _t("Access Denied"), }, { diff --git a/odoo/addons/test_new_api/static/tests/tours/constraint.js b/odoo/addons/test_new_api/static/tests/tours/constraint.js index 0ef3ba54b77..db08fe178c4 100644 --- a/odoo/addons/test_new_api/static/tests/tours/constraint.js +++ b/odoo/addons/test_new_api/static/tests/tours/constraint.js @@ -27,7 +27,7 @@ odoo.define('web.test.constraint', function (require) { trigger: 'button.o_form_button_save', }, { // check popup content content: "check notification box", - trigger: '.o_notification_content:contains(The color code must be positive !)', + trigger: '.o_dialog_warning pre:contains(The color code must be positive !)', run: function () {}, // it's a check }]); }); |
