diff options
| author | Aaron Bohy <aab@odoo.com> | 2020-12-18 10:52:33 +0000 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2020-12-18 13:39:48 +0000 |
| commit | 47a74f2aaf54bddf51a828c4b5a76c392944bcd5 (patch) | |
| tree | eaf6dcb77fc2f04ba8710f0534a8d3e398ba2e26 /addons/website/static | |
| parent | eb5398cac2bcf671ccadf99b129e661faffa92d7 (diff) | |
[FIX] website: dashboard: mounted called twice
Before this commit, the 'mounted' method of the ControlPanel in
the website dashboard was called twice, when entering the dashboard.
It happened because the dashboard updated the ControlPanel before
being actually mounted, so mounted was called once when the
dashboard was mounted, and once when the update was applied.
Ideally, this should not be an issue (this isn't an issue with owl).
However, in Odoo, we mix layers of Owl Components and legacy
widgets. In these situations, the above scenario isn't properly
handled (and can't be).
As a consequence, in mobile (enterprise), it crashed because an
handler bound in mounted (thus twice) was only unbound once.
This commit avoids the issue by correctly setting the control
panel props before rendering it (the update was actually useless).
opw~2417307
closes odoo/odoo#63574
Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
Diffstat (limited to 'addons/website/static')
| -rw-r--r-- | addons/website/static/src/js/backend/dashboard.js | 46 | ||||
| -rw-r--r-- | addons/website/static/tests/dashboard_tests.js | 67 |
2 files changed, 87 insertions, 26 deletions
diff --git a/addons/website/static/src/js/backend/dashboard.js b/addons/website/static/src/js/backend/dashboard.js index 7b37557987c..d9daa81b45a 100644 --- a/addons/website/static/src/js/backend/dashboard.js +++ b/addons/website/static/src/js/backend/dashboard.js @@ -66,8 +66,8 @@ var Dashboard = AbstractAction.extend({ start: function() { var self = this; + this._computeControlPanelProps(); return this._super().then(function() { - self.update_cp(); self.render_graphs(); }); }, @@ -344,7 +344,6 @@ var Dashboard = AbstractAction.extend({ on_reverse_breadcrumb: function() { var self = this; web_client.do_push_state({}); - this.update_cp(); this.fetch_data().then(function() { self.$('.o_website_dashboard').empty(); self.render_dashboards(); @@ -393,33 +392,28 @@ var Dashboard = AbstractAction.extend({ }); }, - update_cp: function() { - var self = this; - if (!this.$searchview) { - this.$searchview = $(QWeb.render("website.DateRangeButtons", { - widget: this, - })); - this.$searchview.find('button.js_date_range').click(function(ev) { - self.$searchview.find('button.js_date_range.active').removeClass('active'); - $(ev.target).addClass('active'); - self.on_date_range_button($(ev.target).data('date')); - }); - this.$searchview.find('button.js_website').click(function(ev) { - self.$searchview.find('button.js_website.active').removeClass('active'); - $(ev.target).addClass('active'); - self.on_website_button($(ev.target).data('website-id')); - }); - } + /** + * @private + */ + _computeControlPanelProps() { + const $searchview = $(QWeb.render("website.DateRangeButtons", { + widget: this, + })); + $searchview.find('button.js_date_range').click((ev) => { + $searchview.find('button.js_date_range.active').removeClass('active'); + $(ev.target).addClass('active'); + this.on_date_range_button($(ev.target).data('date')); + }); + $searchview.find('button.js_website').click((ev) => { + $searchview.find('button.js_website.active').removeClass('active'); + $(ev.target).addClass('active'); + this.on_website_button($(ev.target).data('website-id')); + }); - var $buttons = $(QWeb.render("website.GoToButtons")); + const $buttons = $(QWeb.render("website.GoToButtons")); $buttons.on('click', this.on_go_to_website.bind(this)); - this.updateControlPanel({ - cp_content: { - $searchview: this.$searchview, - $buttons: $buttons, - }, - }); + this.controlPanelProps.cp_content = { $searchview, $buttons }; }, // Loads Analytics API diff --git a/addons/website/static/tests/dashboard_tests.js b/addons/website/static/tests/dashboard_tests.js new file mode 100644 index 00000000000..37ee6b24a09 --- /dev/null +++ b/addons/website/static/tests/dashboard_tests.js @@ -0,0 +1,67 @@ +odoo.define('website/static/tests/dashboard_tests', function (require) { +"use strict"; + +const ControlPanel = require('web.ControlPanel'); +const Dashboard = require('website.backend.dashboard'); +const testUtils = require("web.test_utils"); + +const { createParent, nextTick, prepareTarget } = testUtils; + +QUnit.module('Website Backend Dashboard', { +}, function () { + QUnit.test("mounted is called once for the dashboarrd's ControlPanel", async function (assert) { + // This test can be removed as soon as we don't mix legacy and owl layers anymore. + assert.expect(5); + + ControlPanel.patch('test.ControlPanel', T => { + class ControlPanelPatchTest extends T { + mounted() { + assert.step('mounted'); + super.mounted(...arguments); + } + willUnmount() { + assert.step('willUnmount'); + super.mounted(...arguments); + } + } + return ControlPanelPatchTest; + }); + + const params = { + mockRPC: (route) => { + if (route === '/website/fetch_dashboard_data') { + return Promise.resolve({ + dashboards: { + visits: {}, + sales: { summary: {} }, + }, + groups: { system: true, website_designer: true }, + websites: [ + {id: 1, name: "My Website", domain: "", selected: true}, + ], + }); + } + return this._super(...arguments); + }, + }; + const parent = await createParent(params); + const dashboard = new Dashboard(parent, {}); + await dashboard.appendTo(document.createDocumentFragment()); + + assert.verifySteps([]); + + dashboard.$el.appendTo(prepareTarget()); + dashboard.on_attach_callback(); + + await nextTick(); + + assert.verifySteps(['mounted']); + + dashboard.destroy(); + assert.verifySteps(['willUnmount']); + + ControlPanel.unpatch('test.ControlPanel'); + }); +}); + +}); |
