diff --git a/addons/account/static/src/js/account_resequence_field.js b/addons/account/static/src/js/account_resequence_field.js index ec49f11fde5..cd447bc7df0 100644 --- a/addons/account/static/src/js/account_resequence_field.js +++ b/addons/account/static/src/js/account_resequence_field.js @@ -4,7 +4,7 @@ odoo.define('account.ShowResequenceRenderer', function (require) { const AbstractFieldOwl = require('web.AbstractFieldOwl'); const field_registry = require('web.field_registry_owl'); -const { Component } = owl; +const { Component, onWillUpdateProps } = owl; class ChangeLine extends Component { } ChangeLine.template = 'account.ResequenceChangeLine'; @@ -12,16 +12,15 @@ ChangeLine.props = ["changeLine", 'ordering']; class ShowResequenceRenderer extends AbstractFieldOwl { - constructor(...args) { - super(...args); + setup() { + super.setup(); this.data = this.value ? JSON.parse(this.value) : { changeLines: [], ordering: 'date', }; - } - async willUpdateProps(nextProps) { - await super.willUpdateProps(nextProps); - Object.assign(this.data, JSON.parse(this.value)); + onWillUpdateProps(() => { + Object.assign(this.data, JSON.parse(this.value)); + }); } } ShowResequenceRenderer.template = 'account.ResequenceRenderer'; diff --git a/addons/account/static/src/js/grouped_view_widget.js b/addons/account/static/src/js/grouped_view_widget.js index 3ff897676fd..457bd897c8e 100644 --- a/addons/account/static/src/js/grouped_view_widget.js +++ b/addons/account/static/src/js/grouped_view_widget.js @@ -4,7 +4,7 @@ odoo.define('account.ShowGroupedList', function (require) { const AbstractFieldOwl = require('web.AbstractFieldOwl'); const field_registry = require('web.field_registry_owl'); -const { Component } = owl; +const { Component, onWillUpdateProps } = owl; class ListItem extends Component { } ListItem.template = 'account.GroupedItemTemplate'; @@ -17,8 +17,8 @@ ListGroup.props = ["group_vals", "options"]; class ShowGroupedList extends AbstractFieldOwl { - constructor(...args) { - super(...args); + setup() { + super.setup(); this.data = this.value ? JSON.parse(this.value) : { groups_vals: [], options: { @@ -26,10 +26,9 @@ class ShowGroupedList extends AbstractFieldOwl { columns: [], }, }; - } - async willUpdateProps(nextProps) { - await super.willUpdateProps(nextProps); - Object.assign(this.data, JSON.parse(this.value)); + onWillUpdateProps(() => { + Object.assign(this.data, JSON.parse(this.value)); + }); } } ShowGroupedList.template = 'account.GroupedListTemplate'; diff --git a/addons/account/static/src/js/tax_totals.js b/addons/account/static/src/js/tax_totals.js index 8e50c8bca65..2310c28f27d 100644 --- a/addons/account/static/src/js/tax_totals.js +++ b/addons/account/static/src/js/tax_totals.js @@ -6,29 +6,29 @@ import AbstractFieldOwl from 'web.AbstractFieldOwl'; import fieldUtils from 'web.field_utils'; import field_registry from 'web.field_registry_owl'; -const { Component, useRef, useState } = owl; +const { Component, onPatched, onWillUpdateProps, useRef, useState } = owl; /** A line of some TaxTotalsComponent, giving the values of a tax group. **/ class TaxGroupComponent extends Component { - - constructor(parent, props) { - super(parent, props); + setup() { this.inputTax = useRef('taxValueInput'); this.state = useState({value: 'readonly'}); - this.allowTaxEdition = this.__owl__.parent.mode === 'edit' ? props.allowTaxEdition : false; + this.allowTaxEdition = this.props.mode === 'edit' ? this.props.allowTaxEdition : false; + onPatched(this.onPatched); + onWillUpdateProps(this.onWillUpdateProps); } //-------------------------------------------------------------------------- // Life cycle methods //-------------------------------------------------------------------------- - willUpdateProps(nextProps) { + onWillUpdateProps(nextProps) { this.setState('readonly'); // If props are edited, we set the state to readonly } - patched() { + onPatched() { if (this.state.value === 'edit') { this.inputTax.el.focus(); // Focus the input this.inputTax.el.value = this.props.taxGroup.tax_group_amount; @@ -88,14 +88,14 @@ class TaxGroupComponent extends Component { return; } this.props.taxGroup.tax_group_amount = newValue; - this.trigger('change-tax-group', { + this.props.onChangeTaxGroup({ oldValue: this.props.taxGroup.tax_group_amount, newValue: newValue, taxGroupId: this.props.taxGroup.tax_group_id }); } } -TaxGroupComponent.props = ['taxGroup', 'allowTaxEdition', 'record']; +TaxGroupComponent.props = ['taxGroup', 'allowTaxEdition', 'record', 'onChangeTaxGroup', 'mode']; TaxGroupComponent.template = 'account.TaxGroupComponent'; /** @@ -106,13 +106,14 @@ TaxGroupComponent.template = 'account.TaxGroupComponent'; currency_id field. **/ class TaxTotalsComponent extends AbstractFieldOwl { - constructor(...args) { - super(...args); + setup() { + super.setup(); this.totals = useState({value: this.value ? JSON.parse(this.value) : null}); this.allowTaxEdition = this.nodeOptions['allowTaxEdition']; + onWillUpdateProps(this.onWillUpdateProps); } - willUpdateProps(nextProps) { + onWillUpdateProps(nextProps) { // We only reformat tax groups if there are changed this.totals.value = JSON.parse(nextProps.record.data[this.props.fieldName]); } diff --git a/addons/account/static/src/xml/tax_totals.xml b/addons/account/static/src/xml/tax_totals.xml index bbe780b546d..b46d00425b5 100644 --- a/addons/account/static/src/xml/tax_totals.xml +++ b/addons/account/static/src/xml/tax_totals.xml @@ -21,7 +21,7 @@ - + @@ -56,8 +56,9 @@ diff --git a/addons/base_automation/static/tests/base_automation_error_dialog.js b/addons/base_automation/static/tests/base_automation_error_dialog.js index 462fd92cdba..748a77d8297 100644 --- a/addons/base_automation/static/tests/base_automation_error_dialog.js +++ b/addons/base_automation/static/tests/base_automation_error_dialog.js @@ -15,10 +15,11 @@ import { RPCError } from "@web/core/network/rpc_service"; import { BaseAutomationErrorDialog } from "../src/js/base_automation_error_dialog"; import { patchWithCleanup } from "@web/../tests/helpers/utils"; import { DialogContainer } from "@web/core/dialog/dialog_container"; -import { getFixture } from "@web/../tests/helpers/utils"; +import { getFixture, mount } from "@web/../tests/helpers/utils"; import { nextTick } from "@web/../tests/helpers/utils"; -const { mount } = owl; +const { onMounted } = owl; + const serviceRegistry = registry.category("services"); QUnit.module("base_automation", {}, function () { @@ -80,7 +81,7 @@ QUnit.module("base_automation", {}, function () { const env = await makeTestEnv(); const { Component: Container, props } = registry.category("main_components").get("DialogContainer"); - const dialogContainer = await mount(Container, { target: getFixture(), env, props }); + const dialogContainer = await mount(Container, getFixture(), { env, props }); const errorEvent = new PromiseRejectionEvent("error", { reason: { message: error, @@ -107,15 +108,15 @@ QUnit.module("base_automation", {}, function () { }); patchWithCleanup(DialogContainer.prototype, { - mounted() { + setup() { this._super(); - this.el.classList.add("o_dialog_container"); + onMounted(() => this.el.classList.add("o_dialog_container")); } }); const env = await makeTestEnv(); const { Component: Container, props } = registry.category("main_components").get("DialogContainer"); - const dialogContainer = await mount(Container, { target: getFixture(), env, props }); + const dialogContainer = await mount(Container, getFixture(), { env, props }); const errorEvent = new PromiseRejectionEvent("error", { reason: { message: error, diff --git a/addons/base_import/static/src/import_records/import_records.js b/addons/base_import/static/src/import_records/import_records.js index 6fcf183eb69..4cf1909608f 100644 --- a/addons/base_import/static/src/import_records/import_records.js +++ b/addons/base_import/static/src/import_records/import_records.js @@ -1,5 +1,6 @@ /** @odoo-module **/ +import { DropdownItem } from "@web/core/dropdown/dropdown_item"; import { registry } from "@web/core/registry"; import { useService } from "@web/core/utils/hooks"; @@ -32,6 +33,7 @@ export class ImportRecords extends Component { } ImportRecords.template = "base_import.ImportRecords"; +ImportRecords.components = { DropdownItem }; const importRecordsItem = { Component: ImportRecords, diff --git a/addons/base_import/static/src/import_records/import_records.xml b/addons/base_import/static/src/import_records/import_records.xml index a16a5f9f2f4..d8aa7c6a9b2 100644 --- a/addons/base_import/static/src/import_records/import_records.xml +++ b/addons/base_import/static/src/import_records/import_records.xml @@ -2,7 +2,7 @@ - + Import records diff --git a/addons/base_import/static/src/legacy/js/import_menu.js b/addons/base_import/static/src/legacy/js/import_menu.js index de557592c6f..dae3a738d79 100644 --- a/addons/base_import/static/src/legacy/js/import_menu.js +++ b/addons/base_import/static/src/legacy/js/import_menu.js @@ -1,6 +1,7 @@ odoo.define('base_import.ImportMenu', function (require) { "use strict"; + const { DropdownItem } = require('@web/core/dropdown/dropdown_item'); const FavoriteMenu = require('web.FavoriteMenu'); const { useModel } = require('web.Model'); @@ -12,8 +13,7 @@ odoo.define('base_import.ImportMenu', function (require) { * This component is used to import the records for particular model. */ class ImportMenu extends Component { - constructor() { - super(...arguments); + setup() { this.model = useModel('searchModel'); } @@ -56,6 +56,7 @@ odoo.define('base_import.ImportMenu', function (require) { ImportMenu.props = {}; ImportMenu.template = "base_import.ImportRecords"; + ImportMenu.components = { DropdownItem }; FavoriteMenu.registry.add('import-menu', ImportMenu, 1); diff --git a/addons/board/static/src/add_to_board/add_to_board.js b/addons/board/static/src/add_to_board/add_to_board.js index 3157ffd2070..d20545a0df0 100644 --- a/addons/board/static/src/add_to_board/add_to_board.js +++ b/addons/board/static/src/add_to_board/add_to_board.js @@ -1,5 +1,6 @@ /** @odoo-module **/ +import { Dropdown } from "@web/core/dropdown/dropdown"; import { registry } from "@web/core/registry"; import { useAutofocus, useService } from "@web/core/utils/hooks"; import { sprintf } from "@web/core/utils/strings"; @@ -82,6 +83,7 @@ export class AddToBoard extends Component { } AddToBoard.template = "board.AddToBoard"; +AddToBoard.components = { Dropdown }; const addToBoardItem = { Component: AddToBoard, diff --git a/addons/board/static/src/add_to_board/add_to_board.xml b/addons/board/static/src/add_to_board/add_to_board.xml index 98fdb8aad9b..3f7ebe33e15 100644 --- a/addons/board/static/src/add_to_board/add_to_board.xml +++ b/addons/board/static/src/add_to_board/add_to_board.xml @@ -2,10 +2,10 @@ - + Add to my dashboard
- +
diff --git a/addons/board/static/src/legacy/js/add_to_board_menu.js b/addons/board/static/src/legacy/js/add_to_board_menu.js index 0c6deb4d18b..0059e03619a 100644 --- a/addons/board/static/src/legacy/js/add_to_board_menu.js +++ b/addons/board/static/src/legacy/js/add_to_board_menu.js @@ -3,9 +3,10 @@ odoo.define('board.AddToBoardMenu', function (require) { const Context = require('web.Context'); const Domain = require('web.Domain'); + const { Dropdown } = require('@web/core/dropdown/dropdown'); const FavoriteMenu = require('web.FavoriteMenu'); const { sprintf } = require('web.utils'); - const { useAutofocus } = require('web.custom_hooks'); + const { useAutofocus } = require("@web/core/utils/hooks"); const { Component, useState } = owl; @@ -22,9 +23,7 @@ odoo.define('board.AddToBoardMenu', function (require) { * This component is only available in actions of type 'ir.actions.act_window'. */ class AddToBoardMenu extends Component { - constructor() { - super(...arguments); - + setup() { this.interactive = true; this.state = useState({ name: this.env.action.name || "", @@ -143,6 +142,7 @@ odoo.define('board.AddToBoardMenu', function (require) { AddToBoardMenu.props = {}; AddToBoardMenu.template = 'board.AddToBoard'; + AddToBoardMenu.components = { Dropdown }; FavoriteMenu.registry.add('add-to-board-menu', AddToBoardMenu, 10); diff --git a/addons/board/static/tests/dashboard_tests.js b/addons/board/static/tests/dashboard_tests.js index 06da1a51d63..4e62f5adab7 100644 --- a/addons/board/static/tests/dashboard_tests.js +++ b/addons/board/static/tests/dashboard_tests.js @@ -8,7 +8,7 @@ odoo.define("board.dashboard_tests", function (require) { var ListRenderer = require("web.ListRenderer"); var pyUtils = require("web.py_utils"); const { browser } = require("@web/core/browser/browser"); - const { patchWithCleanup } = require("@web/../tests/helpers/utils"); + const { getFixture, patchWithCleanup } = require("@web/../tests/helpers/utils"); const { registry } = require("@web/core/registry"); const { makeFakeUserService } = require("@web/../tests/helpers/mock_services"); const { @@ -35,7 +35,10 @@ odoo.define("board.dashboard_tests", function (require) { const patchDate = testUtils.mock.patchDate; const favoriteMenuRegistry = registry.category("favoriteMenu"); + const { markup } = owl; + let serverData; + let target; QUnit.module("Dashboard", { beforeEach: function () { this.data = { @@ -93,6 +96,7 @@ odoo.define("board.dashboard_tests", function (require) { { sequence: 10 } ); serverData = { models: this.data }; + target = getFixture(); }, }); @@ -155,7 +159,7 @@ odoo.define("board.dashboard_tests", function (require) { "", viewOptions: { action: { - help: '

click to add a partner

', + help: markup('

click to add a partner

'), }, }, }); @@ -886,18 +890,18 @@ odoo.define("board.dashboard_tests", function (require) { views: [[false, "list"]], }); - assert.containsOnce(webClient, ".o_list_view", "should display the list view"); + assert.containsOnce(target, ".o_list_view", "should display the list view"); // Sort the list await testUtils.dom.click($(".o_column_sortable")); // Group It - await toggleGroupByMenu(webClient); - await toggleAddCustomGroup(webClient); - await applyGroup(webClient); + await toggleGroupByMenu(target); + await toggleAddCustomGroup(target); + await applyGroup(target); // add this action to dashboard - await toggleFavoriteMenu(webClient); + await toggleFavoriteMenu(target); await testUtils.dom.triggerEvent($(".o_add_to_board button.dropdown-toggle"), "mouseenter"); await testUtils.fields.editInput($(".o_add_to_board input"), "a name"); @@ -949,32 +953,32 @@ odoo.define("board.dashboard_tests", function (require) { var filter_count = 0; // Add a first filter - await toggleFilterMenu(webClient); - await toggleAddCustomFilter(webClient); - await editConditionValue(webClient, 0, "a"); - await applyFilter(webClient); + await toggleFilterMenu(target); + await toggleAddCustomFilter(target); + await editConditionValue(target, 0, "a"); + await applyFilter(target); // Add it to dashboard - await toggleFavoriteMenu(webClient); + await toggleFavoriteMenu(target); await testUtils.dom.triggerEvent($(".o_add_to_board button.dropdown-toggle"), "mouseenter"); await testUtils.dom.click($(".o_add_to_board .dropdown-menu button")); // Remove it - await testUtils.dom.click(webClient.el.querySelector(".o_facet_remove")); + await testUtils.dom.click(target.querySelector(".o_facet_remove")); // Add the second filter - await toggleFilterMenu(webClient); - await toggleAddCustomFilter(webClient); - await editConditionValue(webClient, 0, "b"); - await applyFilter(webClient); + await toggleFilterMenu(target); + await toggleAddCustomFilter(target); + await editConditionValue(target, 0, "b"); + await applyFilter(target); // Add it to dashboard - await toggleFavoriteMenu(webClient); + await toggleFavoriteMenu(target); await testUtils.dom.triggerEvent( - webClient.el.querySelector(".o_add_to_board button.dropdown-toggle"), + target.querySelector(".o_add_to_board button.dropdown-toggle"), "mouseenter" ); await testUtils.dom.click( - webClient.el.querySelector(".o_add_to_board .dropdown-menu button") + target.querySelector(".o_add_to_board .dropdown-menu button") ); }); @@ -1012,19 +1016,19 @@ odoo.define("board.dashboard_tests", function (require) { }); // Add a filter - await toggleFilterMenu(webClient); - await toggleAddCustomFilter(webClient); - await editConditionValue(webClient, 0, "b"); - await applyFilter(webClient); + await toggleFilterMenu(target); + await toggleAddCustomFilter(target); + await editConditionValue(target, 0, "b"); + await applyFilter(target); // Add it to dashboard - await toggleFavoriteMenu(webClient); + await toggleFavoriteMenu(target); await testUtils.dom.triggerEvent( - webClient.el.querySelector(".o_add_to_board button.dropdown-toggle"), + target.querySelector(".o_add_to_board button.dropdown-toggle"), "mouseenter" ); // add await testUtils.dom.click( - webClient.el.querySelector(".o_add_to_board .dropdown-menu button") + target.querySelector(".o_add_to_board .dropdown-menu button") ); }); @@ -1253,19 +1257,19 @@ odoo.define("board.dashboard_tests", function (require) { }); // filter on July 2020 - await toggleFilterMenu(webClient); - await toggleMenuItem(webClient, "Date"); - await toggleMenuItemOption(webClient, "Date", "July"); + await toggleFilterMenu(target); + await toggleMenuItem(target, "Date"); + await toggleMenuItemOption(target, "Date", "July"); // compare July 2020 to June 2020 - await toggleComparisonMenu(webClient); - await toggleMenuItem(webClient, 0); + await toggleComparisonMenu(target); + await toggleMenuItem(target, 0); // add the view to the dashboard - await toggleFavoriteMenu(webClient); + await toggleFavoriteMenu(target); - await mouseEnter(webClient.el.querySelector(".o_add_to_board .dropdown-toggle")); - const input = webClient.el.querySelector(".o_add_to_board .dropdown-menu input"); + await mouseEnter(target.querySelector(".o_add_to_board .dropdown-toggle")); + const input = target.querySelector(".o_add_to_board .dropdown-menu input"); await testUtils.fields.editInput(input, "Pipeline"); await testUtils.dom.click($(".o_add_to_board div button")); @@ -1301,9 +1305,9 @@ odoo.define("board.dashboard_tests", function (require) { views: [[false, "pivot"]], }); - await toggleFavoriteMenu(webClient.el); - await mouseEnter(webClient.el.querySelector(".o_add_to_board .dropdown-toggle")); - const input = webClient.el.querySelector(".o_add_to_board .dropdown-menu input"); + await toggleFavoriteMenu(target); + await mouseEnter(target.querySelector(".o_add_to_board .dropdown-toggle")); + const input = target.querySelector(".o_add_to_board .dropdown-menu input"); await testUtils.fields.editInput(input, "Pipeline"); await triggerEvent(input, null, "keydown", { key: "Enter" }); @@ -1411,9 +1415,9 @@ odoo.define("board.dashboard_tests", function (require) { context: { search_default_filter: 1 }, }); - await toggleFavoriteMenu(webClient.el); - await mouseEnter(webClient.el.querySelector(".o_add_to_board .dropdown-toggle")); - const input = webClient.el.querySelector(".o_add_to_board .dropdown-menu input"); + await toggleFavoriteMenu(target); + await mouseEnter(target.querySelector(".o_add_to_board .dropdown-toggle")); + const input = target.querySelector(".o_add_to_board .dropdown-menu input"); await testUtils.fields.editInput(input, "Pipeline"); await triggerEvent(input, null, "keydown", { key: "Enter" }); }); diff --git a/addons/bus/static/tests/assets_watchdog_tests.js b/addons/bus/static/tests/assets_watchdog_tests.js index 4a472cb2342..5c85599dbc8 100644 --- a/addons/bus/static/tests/assets_watchdog_tests.js +++ b/addons/bus/static/tests/assets_watchdog_tests.js @@ -7,25 +7,24 @@ import * as AbstractStorageService from "web.AbstractStorageService"; import { createWebClient } from "@web/../tests/webclient/helpers"; import { assetsWatchdogService } from "@bus/js/services/assets_watchdog_service"; -import { click, nextTick, patchWithCleanup } from "@web/../tests/helpers/utils"; +import { click, getFixture, nextTick, patchWithCleanup } from "@web/../tests/helpers/utils"; import { browser } from "@web/core/browser/browser"; import { registry } from "@web/core/registry"; const LocalStorageService = AbstractStorageService.extend({ storage: new RamStorage(), }); -const mainComponentRegistry = registry.category("main_components"); const serviceRegistry = registry.category("services"); QUnit.module("Bus Assets WatchDog", (hooks) => { let legacyServicesRegistry; + let target; hooks.beforeEach((assert) => { legacyServicesRegistry = new legacyRegistry(); legacyServicesRegistry.add("bus_service", BusService); legacyServicesRegistry.add("local_storage", LocalStorageService); serviceRegistry.add("assetsWatchdog", assetsWatchdogService); - patchWithCleanup(browser, { setTimeout: (fn) => fn(), clearTimeout: () => {}, @@ -33,6 +32,8 @@ QUnit.module("Bus Assets WatchDog", (hooks) => { reload: () => assert.step("reloadPage"), }, }); + + target = getFixture(); }); QUnit.test("can listen on bus and displays notifications in DOM", async (assert) => { @@ -54,21 +55,21 @@ QUnit.module("Bus Assets WatchDog", (hooks) => { } }; - const webClient = await createWebClient({ + await createWebClient({ legacyParams: { serviceRegistry: legacyServicesRegistry }, mockRPC, }); await nextTick(); - assert.containsOnce(webClient.el, ".o_notification_body"); + assert.containsOnce(target, ".o_notification_body"); assert.strictEqual( - webClient.el.querySelector(".o_notification_body .o_notification_content").textContent, + target.querySelector(".o_notification_body .o_notification_content").textContent, "The page appears to be out of date." ); // reload by clicking on the reload button - await click(webClient.el, ".o_notification_buttons .btn-primary"); + await click(target, ".o_notification_buttons .btn-primary"); assert.verifySteps(["reloadPage"]); }); }); diff --git a/addons/calendar/static/tests/calendar_notification_tests.js b/addons/calendar/static/tests/calendar_notification_tests.js index 6d23ae8268c..3992dc5bcb7 100644 --- a/addons/calendar/static/tests/calendar_notification_tests.js +++ b/addons/calendar/static/tests/calendar_notification_tests.js @@ -7,7 +7,7 @@ import * as AbstractStorageService from "web.AbstractStorageService"; import { createWebClient } from "@web/../tests/webclient/helpers"; import { calendarNotificationService } from "@calendar/js/services/calendar_notification_service"; -import { click, nextTick, patchWithCleanup } from "@web/../tests/helpers/utils"; +import { click, getFixture, nextTick, patchWithCleanup } from "@web/../tests/helpers/utils"; import { browser } from "@web/core/browser/browser"; import { registry } from "@web/core/registry"; @@ -18,7 +18,10 @@ const serviceRegistry = registry.category("services"); QUnit.module("Calendar Notification", (hooks) => { let legacyServicesRegistry; + let target; hooks.beforeEach(() => { + target = getFixture(); + legacyServicesRegistry = new legacyRegistry(); legacyServicesRegistry.add("bus_service", BusService); legacyServicesRegistry.add("local_storage", LocalStorageService); @@ -69,23 +72,23 @@ QUnit.module("Calendar Notification", (hooks) => { } }; - const webClient = await createWebClient({ + await createWebClient({ legacyParams: { serviceRegistry: legacyServicesRegistry }, mockRPC, }); await nextTick(); - assert.containsOnce(webClient.el, ".o_notification_body"); + assert.containsOnce(target, ".o_notification_body"); assert.strictEqual( - webClient.el.querySelector(".o_notification_body .o_notification_content") + target.querySelector(".o_notification_body .o_notification_content") .textContent, "Very old meeting message" ); - await click(webClient.el.querySelector(".o_notification_buttons .btn")); + await click(target.querySelector(".o_notification_buttons .btn")); assert.verifySteps(["notifyAck"]); - assert.containsNone(webClient.el, ".o_notification"); + assert.containsNone(target, ".o_notification"); } ); @@ -139,23 +142,23 @@ QUnit.module("Calendar Notification", (hooks) => { }; serviceRegistry.add("action", fakeActionService, { force: true }); - const webClient = await createWebClient({ + await createWebClient({ legacyParams: { serviceRegistry: legacyServicesRegistry }, mockRPC, }); await nextTick(); - assert.containsOnce(webClient.el, ".o_notification_body"); + assert.containsOnce(target, ".o_notification_body"); assert.strictEqual( - webClient.el.querySelector(".o_notification_body .o_notification_content") + target.querySelector(".o_notification_body .o_notification_content") .textContent, "Very old meeting message" ); - await click(webClient.el.querySelectorAll(".o_notification_buttons .btn")[1]); + await click(target.querySelectorAll(".o_notification_buttons .btn")[1]); assert.verifySteps(["calendar.action_calendar_event_notify"]); - assert.containsNone(webClient.el, ".o_notification"); + assert.containsNone(target, ".o_notification"); } ); @@ -197,23 +200,23 @@ QUnit.module("Calendar Notification", (hooks) => { } }; - const webClient = await createWebClient({ + await createWebClient({ legacyParams: { serviceRegistry: legacyServicesRegistry }, mockRPC, }); await nextTick(); - assert.containsOnce(webClient.el, ".o_notification_body"); + assert.containsOnce(target, ".o_notification_body"); assert.strictEqual( - webClient.el.querySelector(".o_notification_body .o_notification_content") + target.querySelector(".o_notification_body .o_notification_content") .textContent, "Very old meeting message" ); - await click(webClient.el.querySelectorAll(".o_notification_buttons .btn")[2]); + await click(target.querySelectorAll(".o_notification_buttons .btn")[2]); assert.verifySteps([], "should only close the notification withtout calling a rpc"); - assert.containsNone(webClient.el, ".o_notification"); + assert.containsNone(target, ".o_notification"); } ); }); diff --git a/addons/crm/static/tests/forecast_view_tests.js b/addons/crm/static/tests/forecast_view_tests.js index b1bfcb86b3f..2d078b3b50c 100644 --- a/addons/crm/static/tests/forecast_view_tests.js +++ b/addons/crm/static/tests/forecast_view_tests.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { legacyExtraNextTick, patchWithCleanup } from "@web/../tests/helpers/utils"; +import { getFixture, legacyExtraNextTick, patchWithCleanup } from "@web/../tests/helpers/utils"; import { setupControlPanelServiceRegistry, switchView, @@ -29,6 +29,7 @@ const forecastDomain = (forecastStart) => { }; let serverData; +let target; QUnit.module("Views", (hooks) => { hooks.beforeEach(async () => { serverData = { @@ -66,6 +67,8 @@ QUnit.module("Views", (hooks) => { }; setupControlPanelServiceRegistry(); serviceRegistry.add("dialog", dialogService); + + target = getFixture(); }); QUnit.module("Forecast views"); @@ -241,24 +244,24 @@ QUnit.module("Views", (hooks) => { }, }); - assert.containsOnce(webClient, ".o_switch_view.o_graph.active"); + assert.containsOnce(target, ".o_switch_view.o_graph.active"); - await toggleGroupByMenu(webClient); - await toggleMenuItem(webClient, "Date Field"); - await toggleMenuItemOption(webClient, "Date Field", "Quarter"); + await toggleGroupByMenu(target); + await toggleMenuItem(target, "Date Field"); + await toggleMenuItemOption(target, "Date Field", "Quarter"); - await switchView(webClient, "legacy_toy"); + await switchView(target, "legacy_toy"); await legacyExtraNextTick(); - assert.containsOnce(webClient, ".o_switch_view.o_legacy_toy.active"); + assert.containsOnce(target, ".o_switch_view.o_legacy_toy.active"); - await cpHelpers.toggleGroupByMenu(webClient); - await toggleMenuItem(webClient, "Date Field"); - await toggleMenuItemOption(webClient, "Date Field", "Year"); + await cpHelpers.toggleGroupByMenu(target); + await toggleMenuItem(target, "Date Field"); + await toggleMenuItemOption(target, "Date Field", "Year"); - await switchView(webClient, "graph"); + await switchView(target, "graph"); - assert.containsOnce(webClient, ".o_switch_view.o_graph.active"); + assert.containsOnce(target, ".o_switch_view.o_graph.active"); // second doAction legacy_toy -> forecast_graph -> legacy_toy @@ -277,24 +280,24 @@ QUnit.module("Views", (hooks) => { }); await legacyExtraNextTick(); - assert.containsOnce(webClient, ".o_switch_view.o_legacy_toy.active"); + assert.containsOnce(target, ".o_switch_view.o_legacy_toy.active"); - await cpHelpers.toggleGroupByMenu(webClient); - await toggleMenuItem(webClient, "Date Field"); - await toggleMenuItemOption(webClient, "Date Field", "Quarter"); + await cpHelpers.toggleGroupByMenu(target); + await toggleMenuItem(target, "Date Field"); + await toggleMenuItemOption(target, "Date Field", "Quarter"); - await switchView(webClient, "graph"); + await switchView(target, "graph"); - assert.containsOnce(webClient, ".o_switch_view.o_graph.active"); + assert.containsOnce(target, ".o_switch_view.o_graph.active"); - await toggleGroupByMenu(webClient); - await toggleMenuItem(webClient, "Date Field"); - await toggleMenuItemOption(webClient, "Date Field", "Year"); + await toggleGroupByMenu(target); + await toggleMenuItem(target, "Date Field"); + await toggleMenuItemOption(target, "Date Field", "Year"); - await switchView(webClient, "legacy_toy"); + await switchView(target, "legacy_toy"); await legacyExtraNextTick(); - assert.containsOnce(webClient, ".o_switch_view.o_legacy_toy.active"); + assert.containsOnce(target, ".o_switch_view.o_legacy_toy.active"); unpatchDate(); } diff --git a/addons/event_sale/static/tests/event_configurator.test.js b/addons/event_sale/static/tests/event_configurator.test.js index 59920a54b82..7a462379bb7 100644 --- a/addons/event_sale/static/tests/event_configurator.test.js +++ b/addons/event_sale/static/tests/event_configurator.test.js @@ -77,6 +77,9 @@ odoo.define('event.configurator.tests', function (require) { } }, function (){ QUnit.test('Select a regular product and verify that the event configurator is not opened', async function (assert) { + // When the module event_booth_sale is installed, it will also call the rpc: read/detailed_type when selecting a product. + // This means that 2 asserts are done when this module is installed. + // Note that: this test will fail if the module event_booth_sale is not installed. assert.expect(2); var form = await createView({ diff --git a/addons/google_drive/static/src/xml/gdrive.xml b/addons/google_drive/static/src/xml/gdrive.xml index db1e3a11c8a..c7765d78a0f 100644 --- a/addons/google_drive/static/src/xml/gdrive.xml +++ b/addons/google_drive/static/src/xml/gdrive.xml @@ -6,7 +6,7 @@ role="menuitem" class="o_menu_item oe_share_gdoc_item dropdown-item" > - + diff --git a/addons/google_spreadsheet/static/src/add_to_google_spreadsheet/add_to_google_spreadsheet.js b/addons/google_spreadsheet/static/src/add_to_google_spreadsheet/add_to_google_spreadsheet.js index 970b6e83ff1..589c127f58d 100644 --- a/addons/google_spreadsheet/static/src/add_to_google_spreadsheet/add_to_google_spreadsheet.js +++ b/addons/google_spreadsheet/static/src/add_to_google_spreadsheet/add_to_google_spreadsheet.js @@ -1,5 +1,6 @@ /** @odoo-module **/ +import { DropdownItem } from "@web/core/dropdown/dropdown_item"; import { registry } from "@web/core/registry"; import { useService } from "@web/core/utils/hooks"; @@ -41,6 +42,7 @@ export class AddToGoogleSpreadsheet extends Component { } AddToGoogleSpreadsheet.template = "google_spreadsheet.AddToGoogleSpreadsheet"; +AddToGoogleSpreadsheet.components = { DropdownItem }; const addToGoogleSpreadsheetItem = { Component: AddToGoogleSpreadsheet, diff --git a/addons/google_spreadsheet/static/src/add_to_google_spreadsheet/add_to_google_spreadsheet.xml b/addons/google_spreadsheet/static/src/add_to_google_spreadsheet/add_to_google_spreadsheet.xml index b5ce85aa399..b32a7a4621f 100644 --- a/addons/google_spreadsheet/static/src/add_to_google_spreadsheet/add_to_google_spreadsheet.xml +++ b/addons/google_spreadsheet/static/src/add_to_google_spreadsheet/add_to_google_spreadsheet.xml @@ -2,7 +2,7 @@ - + Add to Google Spreadsheet diff --git a/addons/google_spreadsheet/static/src/legacy/js/add_to_google_spreadsheet_menu.js b/addons/google_spreadsheet/static/src/legacy/js/add_to_google_spreadsheet_menu.js index 5cd1d75c634..2b74fda6d10 100644 --- a/addons/google_spreadsheet/static/src/legacy/js/add_to_google_spreadsheet_menu.js +++ b/addons/google_spreadsheet/static/src/legacy/js/add_to_google_spreadsheet_menu.js @@ -2,6 +2,7 @@ odoo.define('board.AddToGoogleSpreadsheetMenu', function (require) { "use strict"; const Domain = require('web.Domain'); + const { DropdownItem } = require('@web/core/dropdown/dropdown_item'); const FavoriteMenu = require('web.FavoriteMenu'); const { Component } = owl; @@ -56,6 +57,7 @@ odoo.define('board.AddToGoogleSpreadsheetMenu', function (require) { AddToGoogleSpreadsheetMenu.props = {}; AddToGoogleSpreadsheetMenu.template = "google_spreadsheet.AddToGoogleSpreadsheet"; + AddToGoogleSpreadsheetMenu.components = { DropdownItem }; FavoriteMenu.registry.add('add-to-google-spreadsheet-menu', AddToGoogleSpreadsheetMenu, 20); diff --git a/addons/hr_holidays/static/src/components/thread_view/tests/thread_view_tests.js b/addons/hr_holidays/static/src/components/thread_view/tests/thread_view_tests.js index b8cc907c2ca..809fe732a7a 100644 --- a/addons/hr_holidays/static/src/components/thread_view/tests/thread_view_tests.js +++ b/addons/hr_holidays/static/src/components/thread_view/tests/thread_view_tests.js @@ -16,9 +16,9 @@ QUnit.module('thread_view_tests.js', { this.start = async params => { const res = await start({ ...params, data: this.data }); - const { afterEvent, components, env, widget } = res; + const { afterEvent, apps, env, widget } = res; this.afterEvent = afterEvent; - this.components = components; + this.apps = apps; this.env = env; this.widget = widget; return res; diff --git a/addons/hr_holidays/static/src/dashboard/time_off_card.js b/addons/hr_holidays/static/src/dashboard/time_off_card.js index 6443516b5ef..70440fcd00e 100644 --- a/addons/hr_holidays/static/src/dashboard/time_off_card.js +++ b/addons/hr_holidays/static/src/dashboard/time_off_card.js @@ -1,8 +1,11 @@ /* @odoo-module */ +import Popover from "web.Popover"; + const { Component } = owl; export class TimeOffCardPopover extends Component {} +TimeOffCardPopover.components = { Popover }; TimeOffCardPopover.template = 'hr_holidays.TimeOffCardPopover'; TimeOffCardPopover.props = ['allocated', 'approved', 'planned', 'left']; diff --git a/addons/hr_holidays/static/src/leave_stats/leave_stats.js b/addons/hr_holidays/static/src/leave_stats/leave_stats.js index c67944daecf..534c2cdafc5 100644 --- a/addons/hr_holidays/static/src/leave_stats/leave_stats.js +++ b/addons/hr_holidays/static/src/leave_stats/leave_stats.js @@ -4,37 +4,35 @@ import { useService } from '@web/core/utils/hooks'; import { getLangDateFormat } from 'web.time'; import widgetRegistry from 'web.widgetRegistry'; -const { Component, useState } = owl; +const { Component, useState, onWillStart, onWillUpdateProps } = owl; export class LeaveStatsComponent extends Component { setup() { - super.setup(...arguments); this.rpc = useService('rpc'); this.state = useState({ leaves: [], departmentLeaves: [], }); - } - async willStart() { - await this.loadLeaves(this.date, this.employee); - await this.loadDepartmentLeaves(this.date, this.department, this.employee); - } + onWillStart(async () => { + await this.loadLeaves(this.date, this.employee); + await this.loadDepartmentLeaves(this.date, this.department, this.employee); + }); + onWillUpdateProps(async (nextProps) => { + const dateFrom = nextProps.record.data.date_from || moment(); + const dateChanged = this.date !== dateFrom; + const employee = nextProps.record.data.employee_id.data; + const department = nextProps.record.data.department_id.data; - async willUpdateProps(nextProps) { - const dateFrom = nextProps.record.data.date_from || moment(); - const dateChanged = this.date !== dateFrom; - const employee = nextProps.record.data.employee_id.data; - const department = nextProps.record.data.department_id.data; + if (dateChanged || employee && (this.employee && this.employee.id) !== employee.id) { + await this.loadLeaves(dateFrom, employee); + } - if (dateChanged || employee && (this.employee && this.employee.id) !== employee.id) { - await this.loadLeaves(dateFrom, employee); - } - - if (dateChanged || department && (this.department && this.department.id) !== department.id) { - await this.loadDepartmentLeaves(dateFrom, department, employee); - } + if (dateChanged || department && (this.department && this.department.id) !== department.id) { + await this.loadDepartmentLeaves(dateFrom, department, employee); + } + }) } get date() { diff --git a/addons/hr_holidays/static/src/leave_stats/leave_stats.xml b/addons/hr_holidays/static/src/leave_stats/leave_stats.xml index d0a7e65c400..8611bec818b 100644 --- a/addons/hr_holidays/static/src/leave_stats/leave_stats.xml +++ b/addons/hr_holidays/static/src/leave_stats/leave_stats.xml @@ -8,7 +8,7 @@
None
-
+
day(s)
@@ -21,7 +21,7 @@
None
-
+
: day(s) -
diff --git a/addons/hr_recruitment/static/src/js/tours/hr_recruitment.js b/addons/hr_recruitment/static/src/js/tours/hr_recruitment.js index 0b2874f5fd4..a0819049f11 100644 --- a/addons/hr_recruitment/static/src/js/tours/hr_recruitment.js +++ b/addons/hr_recruitment/static/src/js/tours/hr_recruitment.js @@ -5,9 +5,11 @@ const {_t} = require('web.core'); const {Markup} = require('web.utils'); var tour = require('web_tour.tour'); +const { markup } = owl; + tour.register('hr_recruitment_tour',{ url: "/web", - rainbowManMessage: _t("
Great job! You hired a new colleague!
Try the Website app to publish job offers online.
"), + rainbowManMessage: markup(_t("
Great job! You hired a new colleague!
Try the Website app to publish job offers online.
")), fadeout: 'very_slow', sequence: 230, }, [tour.stepUtils.showAppsMenuItem(), { diff --git a/addons/iap/static/src/js/insufficient_credit_error_handler.js b/addons/iap/static/src/js/insufficient_credit_error_handler.js index 24c76affbf6..3271daa7b54 100644 --- a/addons/iap/static/src/js/insufficient_credit_error_handler.js +++ b/addons/iap/static/src/js/insufficient_credit_error_handler.js @@ -7,9 +7,10 @@ class InsufficientCreditDialog extends Dialog { setup() { super.setup(...arguments); this.orm = useService("orm"); + owl.onWillStart(this.onWillStart); } - async willStart() { + async onWillStart() { const { errorData } = this.props; this.url = await this.orm.call("iap.account", "get_credits_url", [], { base_url: errorData.base_url, diff --git a/addons/im_livechat/__manifest__.py b/addons/im_livechat/__manifest__.py index bdd717fa82f..8274cbdd588 100644 --- a/addons/im_livechat/__manifest__.py +++ b/addons/im_livechat/__manifest__.py @@ -80,7 +80,7 @@ Help your customers with this chat, and analyse their feedback. 'web/static/lib/qweb/qweb2.js', # Odoo JS Framework 'web/static/lib/owl/owl.js', - 'web/static/src/owl_next_adapter.js', + 'web/static/src/owl2_compatibility/*.js', 'web/static/src/legacy/js/promise_extension.js', 'web/static/src/boot.js', 'web/static/src/core/assets.js', @@ -101,6 +101,7 @@ Help your customers with this chat, and analyse their feedback. 'web/static/src/core/notifications/notification_container.js', 'web/static/src/core/notifications/notification_service.js', 'web/static/src/core/registry.js', + 'web/static/src/core/transition.js', 'web/static/src/core/ui/block_ui.js', 'web/static/src/core/ui/ui_service.js', 'web/static/src/core/user_service.js', diff --git a/addons/lunch/static/src/xml/lunch_templates.xml b/addons/lunch/static/src/xml/lunch_templates.xml index 035f5c2da56..264d21b0537 100644 --- a/addons/lunch/static/src/xml/lunch_templates.xml +++ b/addons/lunch/static/src/xml/lunch_templates.xml @@ -1,7 +1,7 @@ - + @@ -43,7 +43,7 @@