From 95048fff047b5c4ae796920f2a3d97777fb2ad8a Mon Sep 17 00:00:00 2001 From: Demesmaeker Date: Thu, 6 Oct 2022 13:33:57 +0000 Subject: [PATCH] [IMP] web_tour,*: add dynamic step skipper in tours Some onboarding tours were conflicting between themselves, with some common steps. This commit introduces the possibility to skip a step depending on the current DOM, making dynamic tours and ensuring tours compatibility task-3002442 X-original-commit: 1e4fb74f2cb8d500effa54d548dc9c29f12b32c1 Part-of: odoo/odoo#103036 --- addons/account/static/src/js/tours/account.js | 4 ++++ addons/sale/static/src/js/tours/sale.js | 6 +++++ addons/sale_management/tests/test_sale_ui.py | 4 ++++ addons/web_tour/static/src/js/tour_manager.js | 22 ++++++++++++++++++- 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/addons/account/static/src/js/tours/account.js b/addons/account/static/src/js/tours/account.js index 1cf010417b5..bf56c65a128 100644 --- a/addons/account/static/src/js/tours/account.js +++ b/addons/account/static/src/js/tours/account.js @@ -16,20 +16,24 @@ tour.register('account_tour', { trigger: "a.o_onboarding_step_action[data-method=action_open_base_onboarding_company]", content: _t("Start by checking your company's data."), position: "bottom", + skip_trigger: 'a[data-method=action_open_base_onboarding_company].o_onboarding_step_action__done', }, { trigger: "button[name=action_save_onboarding_company_step]", extra_trigger: "a.o_onboarding_step_action[data-method=action_open_base_onboarding_company]", content: _t("Looks good. Let's continue."), position: "bottom", + skip_trigger: 'a[data-method=action_open_base_onboarding_company].o_onboarding_step_action__done', }, { trigger: "a.o_onboarding_step_action[data-method=action_open_base_document_layout]", content: _t("Customize your layout."), position: "bottom", + skip_trigger: 'a[data-method=action_open_base_document_layout].o_onboarding_step_action__done', }, { trigger: "button[name=document_layout_save]", extra_trigger: "a.o_onboarding_step_action[data-method=action_open_base_document_layout]", content: _t("Once everything is as you want it, validate."), position: "top", + skip_trigger: 'a[data-method=action_open_base_document_layout].o_onboarding_step_action__done', }, { trigger: "a.o_onboarding_step_action[data-method=action_open_account_onboarding_create_invoice]", content: _t("Now, we'll create your first invoice."), diff --git a/addons/sale/static/src/js/tours/sale.js b/addons/sale/static/src/js/tours/sale.js index a3861f15a62..7c9f71c3133 100644 --- a/addons/sale/static/src/js/tours/sale.js +++ b/addons/sale/static/src/js/tours/sale.js @@ -26,30 +26,36 @@ tour.register("sale_tour", { extra_trigger: ".o_sale_order", content: _t("Start by checking your company's data."), position: "bottom", + skip_trigger: 'a[data-method=action_open_base_onboarding_company].o_onboarding_step_action__done', }, { trigger: ".modal-content button[name='action_save_onboarding_company_step']", content: _t("Looks good. Let's continue."), position: "left", + skip_trigger: 'a[data-method=action_open_base_onboarding_company].o_onboarding_step_action__done', }, { trigger: 'a.o_onboarding_step_action.btn[data-method=action_open_base_document_layout]', extra_trigger: ".o_sale_order", content: _t("Customize your quotes and orders."), position: "bottom", + skip_trigger: 'a[data-method=action_open_base_document_layout].o_onboarding_step_action__done', }, { trigger: "button[name='document_layout_save']", extra_trigger: ".o_sale_order", content: _t("Good job, let's continue."), position: "top", // dot NOT move to bottom, it would cause a resize flicker + skip_trigger: 'a[data-method=action_open_base_document_layout].o_onboarding_step_action__done', }, { trigger: 'a.o_onboarding_step_action.btn[data-method=action_open_sale_onboarding_payment_provider]', extra_trigger: ".o_sale_order", content: _t("To speed up order confirmation, we can activate electronic signatures or payments."), position: "bottom", + skip_trigger: 'a[data-method=action_open_sale_onboarding_payment_provider].o_onboarding_step_action__done', }, { trigger: "button[name='add_payment_methods']", extra_trigger: ".o_sale_order", content: _t("Lets keep electronic signature for now."), position: "bottom", + skip_trigger: 'a[data-method=action_open_sale_onboarding_payment_provider].o_onboarding_step_action__done', }, { trigger: 'a.o_onboarding_step_action.btn[data-method=action_open_sale_onboarding_sample_quotation]', extra_trigger: ".o_sale_order", diff --git a/addons/sale_management/tests/test_sale_ui.py b/addons/sale_management/tests/test_sale_ui.py index 151c3109496..96e8f44ef47 100644 --- a/addons/sale_management/tests/test_sale_ui.py +++ b/addons/sale_management/tests/test_sale_ui.py @@ -9,3 +9,7 @@ class TestUi(HttpCase): def test_01_sale_tour(self): self.start_tour("/web", 'sale_tour', login="admin", step_delay=100) + + def test_02_sale_tour_company_onboarding_done(self): + self.env.company.set_onboarding_step_done('base_onboarding_company_state') + self.start_tour("/web", 'sale_tour', login="admin", step_delay=100) diff --git a/addons/web_tour/static/src/js/tour_manager.js b/addons/web_tour/static/src/js/tour_manager.js index f7a2eefff56..b6db120c179 100644 --- a/addons/web_tour/static/src/js/tour_manager.js +++ b/addons/web_tour/static/src/js/tour_manager.js @@ -243,10 +243,12 @@ return core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, { var tour = this.tours[tour_name]; if (!tour || !tour.ready) return; + let self = this; + self._check_for_skipping_step(self.active_tooltips[tour_name], tour_name); + if (this.running_tour && this.running_tour_timeout === undefined) { this._set_running_tour_timeout(this.running_tour, this.active_tooltips[this.running_tour]); } - var self = this; setTimeout(function () { self._check_for_tooltip(self.active_tooltips[tour_name], tour_name); }); @@ -257,11 +259,29 @@ return core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, { let visibleTip = false; for (const tourName of sortedTooltips) { var tip = this.active_tooltips[tourName]; + this._check_for_skipping_step(tip, tourName) tip.hidden = visibleTip; visibleTip = this._check_for_tooltip(tip, tourName) || visibleTip; } } }, + /** + * Check if the current step of a tour needs to be skipped. If so, skip the step and update + * + * @param {Object} step + * @param {string} tour_name + */ + _check_for_skipping_step: function (step, tour_name) { + if (step && step.skip_trigger) { + let $skip_trigger; + $skip_trigger = get_jquery_element_from_selector(step.skip_trigger); + let skipping = get_first_visible_element($skip_trigger).length; + if (skipping) { + this._to_next_step(tour_name); + this.update(tour_name); + } + } + }, /** * Check (and activate or update) a help tooltip for a tour. *