[REF] *: adapt code to owl 2
Owl 2 changelog: https://github.com/odoo/owl/blob/a9f29c4caad4f32d06be1ec4780572825781cd9b/CHANGELOG.md Part-of: odoo/odoo#80156 Co-authored-by: Aaron Bohy <aab@odoo.com> Co-authored-by: Bruno Boi <boi@odoo.com> Co-authored-by: Géry Debongnie <ged@odoo.com> Co-authored-by: Samuel Degueldre <sad@odoo.com> Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com> Co-authored-by: Simon Genin (ges) <ges@odoo.com> Co-authored-by: Francois (fge) <fge@odoo.com> Co-authored-by: Michael Mattiello (mcm) <mcm@odoo.com> Co-authored-by: Julien Mougenot <jum@odoo.com> Co-authored-by: luvi <luvi@odoo.com> Co-authored-by: Lucas Perais (lpe) <lpe@odoo.com> Co-authored-by: Jorge Pinna Puissant <jpp@odoo.com>
This commit is contained in:
committed by
Samuel Degueldre
co-authored by
Bruno Boi
Géry Debongnie
Samuel Degueldre
Mathieu Duckerts-Antoine
Simon Genin
Francois
Michael Mattiello
Julien Mougenot
luvi
Lucas Perais
Jorge Pinna Puissant
parent
edd79ff560
commit
318cdcc0b8
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</span>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span class="o_tax_group_edit" t-on-click.prevent="setState('edit')">
|
||||
<span class="o_tax_group_edit" t-on-click.prevent="() => this.setState('edit')">
|
||||
<i class="fa fa-pencil"/>
|
||||
<span class="o_tax_group_amount_value">
|
||||
<t t-esc="props.taxGroup.formatted_tax_group_amount"/>
|
||||
@@ -56,8 +56,9 @@
|
||||
<TaxGroupComponent
|
||||
taxGroup="taxGroup"
|
||||
record="record"
|
||||
mode="mode"
|
||||
allowTaxEdition="totals.value.allow_tax_edition"
|
||||
t-on-change-tax-group="_onChangeTaxValueByTaxGroup"
|
||||
onChangeTaxGroup.bind="_onChangeTaxValueByTaxGroup"
|
||||
/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="base_import.ImportRecords" owl="1">
|
||||
<DropdownItem class="o_import_menu dropdown-item" t-on-click="importRecords">
|
||||
<DropdownItem class="'o_import_menu'" onSelected.bind="importRecords">
|
||||
Import records
|
||||
</DropdownItem>
|
||||
</t>
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="board.AddToBoard" owl="1">
|
||||
<Dropdown class="o_add_to_board">
|
||||
<Dropdown class="'o_add_to_board'">
|
||||
<t t-set-slot="toggler">Add to my dashboard</t>
|
||||
<div class="px-3 py-2">
|
||||
<input type="text" class="o_input" autofocus="" t-model.trim="state.name" t-on-keydown="onInputKeydown" />
|
||||
<input type="text" class="o_input" t-ref="autofocus" t-model.trim="state.name" t-on-keydown="onInputKeydown" />
|
||||
</div>
|
||||
<div class="px-3 py-2">
|
||||
<button type="button" class="btn btn-primary" t-on-click="addToBoard">Add</button>
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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) {
|
||||
"</form>",
|
||||
viewOptions: {
|
||||
action: {
|
||||
help: '<p class="hello">click to add a partner</p>',
|
||||
help: markup('<p class="hello">click to add a partner</p>'),
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -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" });
|
||||
});
|
||||
|
||||
@@ -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"]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
role="menuitem"
|
||||
class="o_menu_item oe_share_gdoc_item dropdown-item"
|
||||
>
|
||||
<a href="#" t-esc="gdriveItem.name" t-on-click.prevent="_onGoogleDocItemClick(gdriveItem.id)"/>
|
||||
<a href="#" t-esc="gdriveItem.name" t-on-click.prevent="() => this._onGoogleDocItemClick(gdriveItem.id)"/>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
+2
@@ -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,
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="google_spreadsheet.AddToGoogleSpreadsheet" owl="1">
|
||||
<DropdownItem class="o_add_to_spreadsheet dropdown-item" t-on-click="addToGoogleSpreadsheet">
|
||||
<DropdownItem class="'o_add_to_spreadsheet'" onSelected.bind="addToGoogleSpreadsheet">
|
||||
Add to Google Spreadsheet
|
||||
</DropdownItem>
|
||||
</t>
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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'];
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div t-if="state.leaves.length === 0">
|
||||
None
|
||||
</div>
|
||||
<div t-foreach="state.leaves" t-as="leave" class="d-flex flex-row justify-content-between">
|
||||
<div t-foreach="state.leaves" t-as="leave" t-key="leave_index" class="d-flex flex-row justify-content-between">
|
||||
<span t-esc="leave.holiday_status_id[1]"/>
|
||||
<span><t t-esc="leave.number_of_days"/> day(s)</span>
|
||||
</div>
|
||||
@@ -21,7 +21,7 @@
|
||||
<div t-if="state.departmentLeaves.length === 0">
|
||||
None
|
||||
</div>
|
||||
<div t-foreach="state.departmentLeaves" t-as="leave" t-attf-class="d-flex flex-row justify-content-between {{leave.sameEmployee ? 'font-weight-bold': ''}}">
|
||||
<div t-foreach="state.departmentLeaves" t-as="leave" t-key="leave_index" t-attf-class="d-flex flex-row justify-content-between {{leave.sameEmployee ? 'font-weight-bold': ''}}">
|
||||
<span><t t-esc="leave.employee_id[1]"/>: <t t-esc="leave.number_of_days"/> day(s)</span>
|
||||
<span><t t-esc="leave.dateFrom"/> - <t t-esc="leave.dateTo"/></span>
|
||||
</div>
|
||||
|
||||
@@ -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("<div>Great job! You hired a new colleague!</div><div>Try the Website app to publish job offers online.</div>"),
|
||||
rainbowManMessage: markup(_t("<div>Great job! You hired a new colleague!</div><div>Try the Website app to publish job offers online.</div>")),
|
||||
fadeout: 'very_slow',
|
||||
sequence: 230,
|
||||
}, [tour.stepUtils.showAppsMenuItem(), {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates>
|
||||
<span t-name="LunchWidget">
|
||||
<t t-foreach="widget.alerts" t-as="alert">
|
||||
<t t-foreach="widget.alerts" t-as="alert" t-key="alert_index">
|
||||
<div class="alert alert-warning mb-0" role="alert">
|
||||
<t t-out="alert.message"/>
|
||||
</div>
|
||||
@@ -43,7 +43,7 @@
|
||||
<span t-if="widget.raw_state != 'new'" t-esc="widget.state" t-attf-class="badge badge-pill {{ state_class }}"/>
|
||||
</h4>
|
||||
<ul class="list-unstyled o_lunch_widget_lines">
|
||||
<li t-foreach="widget.lines" t-as="line">
|
||||
<li t-foreach="widget.lines" t-as="line" t-key="line_index">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="flex-grow-0 flex-shrink-0 o_lunch_product_quantity">
|
||||
<button class="btn btn-sm btn-icon btn-link fa fa-minus-circle o_remove_product" t-if="widget.raw_state != 'confirmed'" t-attf-data-id="{{ line.id }}"/>
|
||||
@@ -60,7 +60,7 @@
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<div t-foreach="line.toppings" t-as="topping" class="d-flex flex-row">
|
||||
<div t-foreach="line.toppings" t-as="topping" t-key="topping_index" class="d-flex flex-row">
|
||||
<div class="flex-grow-1 pl-5">
|
||||
<span>+ <t t-esc="topping[0]"/></span>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@ const GeneratePriceList = require('product.generate_pricelist').GeneratePriceLis
|
||||
const testUtils = require('web.test_utils');
|
||||
|
||||
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
|
||||
const { getFixture, patchWithCleanup } = require("@web/../tests/helpers/utils");
|
||||
|
||||
let serverData;
|
||||
|
||||
@@ -38,9 +39,8 @@ QUnit.module('Product Pricelist', {
|
||||
QUnit.test('Pricelist Client Action', async function (assert) {
|
||||
assert.expect(21);
|
||||
|
||||
const self = this;
|
||||
let Qty = [1, 5, 10]; // default quantities
|
||||
testUtils.mock.patch(GeneratePriceList, {
|
||||
patchWithCleanup(GeneratePriceList.prototype, {
|
||||
_onFieldChanged: function (event) {
|
||||
assert.step('field_changed');
|
||||
return this._super.apply(this, arguments);
|
||||
@@ -57,6 +57,7 @@ QUnit.module('Product Pricelist', {
|
||||
}
|
||||
};
|
||||
|
||||
const target = getFixture();
|
||||
const webClient = await createWebClient({ serverData, mockRPC });
|
||||
await doAction(webClient, {
|
||||
id: 1,
|
||||
@@ -72,7 +73,7 @@ QUnit.module('Product Pricelist', {
|
||||
});
|
||||
|
||||
// checking default pricelist
|
||||
assert.strictEqual($(webClient.el).find('.o_field_many2one input').val(), "Public Pricelist",
|
||||
assert.strictEqual($(target).find('.o_field_many2one input').val(), "Public Pricelist",
|
||||
"should have default pricelist");
|
||||
|
||||
// changing pricelist
|
||||
@@ -80,28 +81,28 @@ QUnit.module('Product Pricelist', {
|
||||
await testUtils.fields.many2one.clickItem("pricelist_id", "Test");
|
||||
|
||||
// check wherther pricelist value has been updated or not. along with that check default quantities should be there.
|
||||
assert.strictEqual($(webClient.el).find('.o_field_many2one input').val(), "Test",
|
||||
assert.strictEqual($(target).find('.o_field_many2one input').val(), "Test",
|
||||
"After pricelist change, the pricelist_id field should be updated");
|
||||
assert.strictEqual($(webClient.el).find('.o_badges > .badge').length, 3,
|
||||
assert.strictEqual($(target).find('.o_badges > .badge').length, 3,
|
||||
"There should be 3 default Quantities");
|
||||
|
||||
// existing quantity can not be added.
|
||||
await testUtils.dom.click($(webClient.el).find('.o_add_qty'));
|
||||
await testUtils.dom.click($(target).find('.o_add_qty'));
|
||||
let notificationElement = document.body.querySelector('.o_notification_manager .o_notification.bg-info');
|
||||
assert.strictEqual(notificationElement.querySelector('.o_notification_content').textContent,
|
||||
"Quantity already present (1).", "Existing Quantity can not be added");
|
||||
|
||||
// adding few more quantities to check.
|
||||
$(webClient.el).find('.o_product_qty').val(2);
|
||||
$(target).find('.o_product_qty').val(2);
|
||||
Qty.push(2);
|
||||
await testUtils.dom.click($(webClient.el).find('.o_add_qty'));
|
||||
$(webClient.el).find('.o_product_qty').val(3);
|
||||
await testUtils.dom.click($(target).find('.o_add_qty'));
|
||||
$(target).find('.o_product_qty').val(3);
|
||||
Qty.push(3);
|
||||
await testUtils.dom.click($(webClient.el).find('.o_add_qty'));
|
||||
await testUtils.dom.click($(target).find('.o_add_qty'));
|
||||
|
||||
// should not be added more then 5 quantities.
|
||||
$(webClient.el).find('.o_product_qty').val(4);
|
||||
await testUtils.dom.click($(webClient.el).find('.o_add_qty'));
|
||||
$(target).find('.o_product_qty').val(4);
|
||||
await testUtils.dom.click($(target).find('.o_add_qty'));
|
||||
|
||||
notificationElement = document.body.querySelector('.o_notification_manager .o_notification.bg-warning');
|
||||
assert.strictEqual(notificationElement.querySelector('.o_notification_content').textContent,
|
||||
@@ -110,15 +111,15 @@ QUnit.module('Product Pricelist', {
|
||||
|
||||
// removing all the quantities should work
|
||||
Qty.pop(10);
|
||||
await testUtils.dom.click($(webClient.el).find('.o_badges .badge:contains("10") .o_remove_qty'));
|
||||
await testUtils.dom.click($(target).find('.o_badges .badge:contains("10") .o_remove_qty'));
|
||||
Qty.pop(5);
|
||||
await testUtils.dom.click($(webClient.el).find('.o_badges .badge:contains("5") .o_remove_qty'));
|
||||
await testUtils.dom.click($(target).find('.o_badges .badge:contains("5") .o_remove_qty'));
|
||||
Qty.pop(3);
|
||||
await testUtils.dom.click($(webClient.el).find('.o_badges .badge:contains("3") .o_remove_qty'));
|
||||
await testUtils.dom.click($(target).find('.o_badges .badge:contains("3") .o_remove_qty'));
|
||||
Qty.pop(2);
|
||||
await testUtils.dom.click($(webClient.el).find('.o_badges .badge:contains("2") .o_remove_qty'));
|
||||
await testUtils.dom.click($(target).find('.o_badges .badge:contains("2") .o_remove_qty'));
|
||||
Qty.pop(1);
|
||||
await testUtils.dom.click($(webClient.el).find('.o_badges .badge:contains("1") .o_remove_qty'));
|
||||
await testUtils.dom.click($(target).find('.o_badges .badge:contains("1") .o_remove_qty'));
|
||||
|
||||
assert.verifySteps([
|
||||
'field_changed',
|
||||
@@ -130,8 +131,6 @@ QUnit.module('Product Pricelist', {
|
||||
'qty_changed',
|
||||
'qty_changed'
|
||||
]);
|
||||
|
||||
testUtils.mock.unpatch(GeneratePriceList);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,26 +3,17 @@
|
||||
import ControlPanel from 'web.ControlPanel';
|
||||
import session from 'web.session';
|
||||
|
||||
const { onWillStart, onWillUpdateProps } = owl;
|
||||
|
||||
export class ProjectControlPanel extends ControlPanel {
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.show_project_update = this.env.view.type === "form" || this.props.action.context.show_project_update;
|
||||
setup() {
|
||||
super.setup();
|
||||
this.show_project_update = this.props.view.type === "form" || this.props.action.context.show_project_update;
|
||||
this.project_id = this.show_project_update ? this.props.action.context.active_id : false;
|
||||
}
|
||||
|
||||
async willStart() {
|
||||
const promises = [];
|
||||
promises.push(super.willStart(...arguments));
|
||||
promises.push(this._loadWidgetData());
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
async willUpdateProps() {
|
||||
const promises = [];
|
||||
promises.push(super.willUpdateProps(...arguments));
|
||||
promises.push(this._loadWidgetData());
|
||||
return Promise.all(promises);
|
||||
onWillStart(() => this._loadWidgetData());
|
||||
onWillUpdateProps(() => this._loadWidgetData());
|
||||
}
|
||||
|
||||
async _loadWidgetData() {
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
import { AddMilestone, OpenMilestone } from '@project/js/right_panel/project_utils';
|
||||
import { formatFloat } from "@web/fields/formatters";
|
||||
|
||||
const { Component, useState } = owl;
|
||||
const { Component, onWillStart, onWillUpdateProps, useState } = owl;
|
||||
|
||||
export default class ProjectRightPanel extends Component {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
setup() {
|
||||
this.context = this.props.action.context;
|
||||
this.domain = this.props.action.domain;
|
||||
this.project_id = this.context.active_id;
|
||||
@@ -19,22 +18,15 @@ export default class ProjectRightPanel extends Component {
|
||||
user: {},
|
||||
}
|
||||
});
|
||||
|
||||
onWillStart(() => this._loadQwebContext());
|
||||
onWillUpdateProps(() => this._loadQwebContext());
|
||||
}
|
||||
|
||||
formatFloat(value) {
|
||||
return formatFloat(value, { digits: [false, 1] });
|
||||
}
|
||||
|
||||
async willStart() {
|
||||
await super.willStart(...arguments);
|
||||
await this._loadQwebContext();
|
||||
}
|
||||
|
||||
async willUpdateProps() {
|
||||
await super.willUpdateProps(...arguments);
|
||||
await this._loadQwebContext();
|
||||
}
|
||||
|
||||
async _loadQwebContext() {
|
||||
const data = await this.rpc({
|
||||
model: 'project.project',
|
||||
|
||||
@@ -2,25 +2,17 @@
|
||||
|
||||
import { _lt } from 'web.core';
|
||||
import fieldUtils from 'web.field_utils';
|
||||
import { ComponentAdapter } from 'web.OwlCompatibility';
|
||||
import { ComponentAdapter, standaloneAdapter } from 'web.OwlCompatibility';
|
||||
import { FormViewDialog } from 'web.view_dialogs';
|
||||
|
||||
const { Component, useRef, useState } = owl;
|
||||
const { Component, onWillUpdateProps, useRef, useState } = owl;
|
||||
|
||||
class MilestoneComponent extends Component {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
setup() {
|
||||
super.setup();
|
||||
this.contextValue = Object.assign({}, {
|
||||
'default_project_id': this.props.context.active_id,
|
||||
}, this.props.context);
|
||||
this.FormViewDialog = FormViewDialog;
|
||||
this.state = useState({
|
||||
openDialog: false
|
||||
});
|
||||
this._dialogRef = useRef('dialog');
|
||||
this._isDialogOpen = false;
|
||||
this._createContext = this._createContext.bind(this);
|
||||
this._onDialogSaved = this._onDialogSaved.bind(this);
|
||||
}
|
||||
|
||||
get context() {
|
||||
@@ -33,65 +25,55 @@ class MilestoneComponent extends Component {
|
||||
}, value);
|
||||
}
|
||||
|
||||
dialogClosed() {
|
||||
this._isDialogOpen = false;
|
||||
this.state.openDialog = false;
|
||||
}
|
||||
|
||||
patched() {
|
||||
if (this.state.openDialog && !this._isDialogOpen) {
|
||||
this._isDialogOpen = true;
|
||||
this._dialogRef.comp.widget.on('closed', this, () => {
|
||||
this.dialogClosed();
|
||||
});
|
||||
this._dialogRef.comp.widget.open();
|
||||
}
|
||||
}
|
||||
|
||||
_createContext() {
|
||||
return Object.assign({}, {
|
||||
'default_project_id': this.contextValue.active_id,
|
||||
}, this.contextValue);
|
||||
}
|
||||
|
||||
async _onDialogSaved() {
|
||||
await this.__owl__.parent.willUpdateProps();
|
||||
async openLegacyFormDialog(params) {
|
||||
const adapterParent = standaloneAdapter({ Component });
|
||||
const dialog = new FormViewDialog(adapterParent, {
|
||||
context: this.context,
|
||||
res_model: "project.milestone",
|
||||
res_id: false,
|
||||
on_saved: this.props.onMilestoneUpdate,
|
||||
...params,
|
||||
});
|
||||
await dialog.open();
|
||||
return dialog;
|
||||
}
|
||||
}
|
||||
MilestoneComponent.components = { ComponentAdapter };
|
||||
|
||||
export class AddMilestone extends MilestoneComponent {
|
||||
get NEW_PROJECT_MILESTONE() {
|
||||
return _lt("New Milestone");
|
||||
}
|
||||
|
||||
onAddMilestoneClick(event) {
|
||||
if (!this._isDialogOpen) {
|
||||
event.stopPropagation();
|
||||
this.state.openDialog = true;
|
||||
}
|
||||
event.stopPropagation();
|
||||
this.openLegacyFormDialog({
|
||||
_createContext: () => {
|
||||
return {
|
||||
default_project_id: this.contextValue.active_id,
|
||||
...this.contextValue
|
||||
};
|
||||
},
|
||||
title: this.env._t("New Milestone"),
|
||||
multi_select: true
|
||||
});
|
||||
}
|
||||
}
|
||||
AddMilestone.template = 'project.AddMilestone';
|
||||
|
||||
export class OpenMilestone extends MilestoneComponent {
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
setup() {
|
||||
super.setup();
|
||||
this.milestone = useState(this.props.milestone);
|
||||
this.state.colorClass = this.milestone.is_deadline_exceeded ? "o_milestone_danger" : "";
|
||||
this.state.checkboxIcon = this.milestone.is_reached ? "fa-check-square-o" : "fa-square-o";
|
||||
}
|
||||
|
||||
get OPEN_PROJECT_MILESTONE() {
|
||||
return _lt("Milestone");
|
||||
this.state = useState({
|
||||
colorClass: this.milestone.is_deadline_exceeded ? "o_milestone_danger" : "",
|
||||
checkboxIcon: this.milestone.is_reached ? "fa-check-square-o" : "fa-square-o",
|
||||
});
|
||||
onWillUpdateProps(this.onWillUpdateProps);
|
||||
}
|
||||
|
||||
get deadline() {
|
||||
return fieldUtils.format.date(moment(this.milestone.deadline));
|
||||
}
|
||||
|
||||
willUpdateProps(nextProps) {
|
||||
onWillUpdateProps(nextProps) {
|
||||
if (nextProps.milestone) {
|
||||
this.milestone = nextProps.milestone;
|
||||
this.state.colorClass = this.milestone.is_deadline_exceeded ? "o_milestone_danger" : "";
|
||||
@@ -102,24 +84,27 @@ export class OpenMilestone extends MilestoneComponent {
|
||||
}
|
||||
}
|
||||
|
||||
dialogClosed() {
|
||||
super.dialogClosed();
|
||||
this.write_mutex = false;
|
||||
}
|
||||
|
||||
async onDeleteMilestone() {
|
||||
await this.rpc({
|
||||
model: 'project.milestone',
|
||||
method: 'unlink',
|
||||
args: [this.milestone.id]
|
||||
});
|
||||
await this.__owl__.parent.willUpdateProps();
|
||||
await this.props.onMilestoneUpdate();
|
||||
}
|
||||
|
||||
onOpenMilestone() {
|
||||
if (!this._isDialogOpen && !this.write_mutex) {
|
||||
async onOpenMilestone() {
|
||||
if (!this.write_mutex) {
|
||||
this.write_mutex = true;
|
||||
this.state.openDialog = true;
|
||||
const dialog = await this.openLegacyFormDialog({
|
||||
res_id: this.milestone.id,
|
||||
title: this.env._t("Milestone"),
|
||||
disable_multiple_selection: true,
|
||||
deletable: true
|
||||
});
|
||||
dialog.on('closed', this, () => {
|
||||
this.write_mutex = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ var tour = require('web_tour.tour');
|
||||
tour.register('project_tour', {
|
||||
sequence: 110,
|
||||
url: "/web",
|
||||
rainbowManMessage: "Congratulations, you are now a master of project management.",
|
||||
rainbowManMessage: _t("Congratulations, you are now a master of project management."),
|
||||
}, [tour.stepUtils.showAppsMenuItem(), {
|
||||
trigger: '.o_app[data-menu-xmlid="project.menu_main_pm"]',
|
||||
content: Markup(_t('Want a better way to <b>manage your projects</b>? <i>It starts here.</i>')),
|
||||
|
||||
@@ -3,30 +3,28 @@
|
||||
import { ControlPanel } from "@web/search/control_panel/control_panel";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
|
||||
const { onWillStart, onWillUpdateProps } = owl;
|
||||
|
||||
export class ProjectControlPanel extends ControlPanel {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
setup() {
|
||||
super.setup();
|
||||
this.orm = useService("orm");
|
||||
this.user = useService("user");
|
||||
const { active_id, show_project_update } = this.env.searchModel.globalContext;
|
||||
this.showProjectUpdate = this.env.config.viewType === "form" || show_project_update;
|
||||
this.projectId = this.showProjectUpdate ? active_id : false;
|
||||
}
|
||||
|
||||
async willStart() {
|
||||
const proms = [super.willStart(...arguments)];
|
||||
if (this.showProjectUpdate) {
|
||||
proms.push(this.loadData());
|
||||
}
|
||||
await Promise.all(proms);
|
||||
}
|
||||
onWillStart(async () => {
|
||||
if (this.showProjectUpdate) {
|
||||
await this.loadData();
|
||||
}
|
||||
});
|
||||
|
||||
async willUpdateProps() {
|
||||
const proms = [super.willUpdateProps(...arguments)];
|
||||
if (this.showProjectUpdate) {
|
||||
proms.push(this.loadData());
|
||||
}
|
||||
await Promise.all(proms);
|
||||
onWillUpdateProps(async () => {
|
||||
if (this.showProjectUpdate) {
|
||||
await this.loadData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async loadData() {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { useBus, useEffect, useService } from '@web/core/utils/hooks';
|
||||
import { useBus, useService } from '@web/core/utils/hooks';
|
||||
import { ActionContainer } from '@web/webclient/actions/action_container';
|
||||
import { MainComponentsContainer } from "@web/core/main_components_container";
|
||||
import { useOwnDebugContext } from "@web/core/debug/debug_context";
|
||||
import { ErrorHandler, NotUpdatable } from "@web/core/utils/components";
|
||||
import { session } from '@web/session';
|
||||
|
||||
const { Component } = owl;
|
||||
const { Component, useEffect } = owl;
|
||||
|
||||
export class ProjectSharingWebClient extends Component {
|
||||
setup() {
|
||||
@@ -29,8 +29,6 @@ export class ProjectSharingWebClient extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
mounted() { }
|
||||
|
||||
handleComponentError(error, C) {
|
||||
// remove the faulty component
|
||||
this.Components.splice(this.Components.indexOf(C), 1);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<table class="o_dow_widget">
|
||||
<thead>
|
||||
<tr>
|
||||
<th t-foreach="widget.labels" t-as="label">
|
||||
<th t-foreach="widget.labels" t-as="label" t-key="label_index">
|
||||
<t t-esc="label"/>
|
||||
</th>
|
||||
</tr>
|
||||
@@ -37,7 +37,7 @@
|
||||
<div class="o_rightpanel_section">
|
||||
<div class="o_form_view">
|
||||
<div class="oe_button_box o_full">
|
||||
<t t-foreach="state.data.buttons" t-as="button" t-key="button.order">
|
||||
<t t-foreach="state.data.buttons" t-as="button" t-key="button.action">
|
||||
<button class="btn oe_stat_button" t-if="button.show"
|
||||
t-on-click="onProjectActionClick"
|
||||
t-att-data-action="button.action"
|
||||
@@ -67,12 +67,12 @@
|
||||
Milestones
|
||||
</div>
|
||||
<span class="o_rightpanel_button">
|
||||
<AddMilestone context="context"/>
|
||||
<AddMilestone context="context" onMilestoneUpdate.bind="_loadQwebContext"/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="o_rightpanel_data">
|
||||
<div t-foreach="milestones.data" t-as="milestone" t-key="milestone.id" class="o_rightpanel_data_row">
|
||||
<OpenMilestone context="context" milestone="milestone" t-key="milestone.id"/>
|
||||
<OpenMilestone context="context" milestone="milestone" onMilestoneUpdate.bind="_loadQwebContext"/>
|
||||
</div>
|
||||
<span t-if="milestones.data.length === 0" class="text-muted font-italic">
|
||||
Track major progress points that must be reached to achieve success.
|
||||
@@ -84,21 +84,6 @@
|
||||
<t t-name="project.AddMilestone" owl="1">
|
||||
<div class="o_add_milestone">
|
||||
<a t-on-click="onAddMilestoneClick">Add Milestone</a>
|
||||
<span t-if="state.openDialog" class="o_rightpanel_hidden">
|
||||
<ComponentAdapter
|
||||
Component="FormViewDialog"
|
||||
params="{
|
||||
context: context,
|
||||
_createContext: _createContext,
|
||||
on_saved: _onDialogSaved,
|
||||
res_id: false,
|
||||
res_model: 'project.milestone',
|
||||
title: NEW_PROJECT_MILESTONE,
|
||||
multi_select: true,
|
||||
}"
|
||||
t-ref="dialog"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -118,21 +103,6 @@
|
||||
<span class="o_rightpanel_right_col">
|
||||
<a class="o_delete_icon" t-on-click="onDeleteMilestone" title="Delete Milestone"><i class="fa fa-trash"></i></a>
|
||||
</span>
|
||||
<span t-if="state.openDialog" class="o_rightpanel_hidden">
|
||||
<ComponentAdapter
|
||||
Component="FormViewDialog"
|
||||
params="{
|
||||
context: context,
|
||||
on_saved: _onDialogSaved,
|
||||
res_id: milestone.id,
|
||||
res_model: 'project.milestone',
|
||||
title: OPEN_PROJECT_MILESTONE,
|
||||
disable_multiple_selection: true,
|
||||
deletable: true
|
||||
}"
|
||||
t-ref="dialog"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="project.task.PrivateProjectName">
|
||||
|
||||
@@ -5,6 +5,8 @@ const {_t} = require('web.core');
|
||||
const {Markup} = require('web.utils');
|
||||
var tour = require('web_tour.tour');
|
||||
|
||||
const { markup } = owl;
|
||||
|
||||
tour.register("sale_tour", {
|
||||
url: "/web",
|
||||
rainbowMan: false,
|
||||
@@ -58,7 +60,7 @@ tour.register("sale_tour", {
|
||||
tour.register("sale_quote_tour", {
|
||||
url: "/web#action=sale.action_quotations_with_onboarding&view_type=form",
|
||||
rainbowMan: true,
|
||||
rainbowManMessage: "<b>Congratulations</b>, your first quotation is sent!<br>Check your email to validate the quote.",
|
||||
rainbowManMessage: markup(_t("<b>Congratulations</b>, your first quotation is sent!<br>Check your email to validate the quote.")),
|
||||
sequence: 30,
|
||||
}, [{
|
||||
trigger: ".o_form_editable .o_field_many2one[name='partner_id']",
|
||||
|
||||
@@ -5,12 +5,18 @@ odoo.define('stock.stock_traceability_report_backend_tests', function (require)
|
||||
const dom = require('web.dom');
|
||||
const StockReportGeneric = require('stock.stock_report_generic');
|
||||
const testUtils = require('web.test_utils');
|
||||
const { patch, unpatch } = require('web.utils');
|
||||
|
||||
const { dom: domUtils } = testUtils;
|
||||
const { legacyExtraNextTick } = require("@web/../tests/helpers/utils");
|
||||
const {
|
||||
destroy,
|
||||
getFixture,
|
||||
legacyExtraNextTick,
|
||||
patchWithCleanup,
|
||||
} = require("@web/../tests/helpers/utils");
|
||||
const { createWebClient, doAction } = require('@web/../tests/webclient/helpers');
|
||||
|
||||
const { onMounted, onWillUnmount } = owl;
|
||||
|
||||
/**
|
||||
* Helper function to instantiate a stock report action.
|
||||
* @param {Object} params
|
||||
@@ -80,17 +86,17 @@ odoo.define('stock.stock_traceability_report_backend_tests', function (require)
|
||||
|
||||
let mountCount = 0;
|
||||
|
||||
patch(ControlPanel.prototype, 'test.ControlPanel', {
|
||||
mounted() {
|
||||
mountCount = mountCount + 1;
|
||||
this.__uniqueId = mountCount;
|
||||
assert.step(`mounted ${this.__uniqueId}`);
|
||||
this.__superMounted = this._super.bind(this);
|
||||
this.__superMounted(...arguments);
|
||||
},
|
||||
willUnmount() {
|
||||
assert.step(`willUnmount ${this.__uniqueId}`);
|
||||
this.__superMounted(...arguments);
|
||||
patchWithCleanup(ControlPanel.prototype, {
|
||||
setup() {
|
||||
this._super();
|
||||
onMounted(() => {
|
||||
mountCount = mountCount + 1;
|
||||
this.__uniqueId = mountCount;
|
||||
assert.step(`mounted ${this.__uniqueId}`);
|
||||
});
|
||||
onWillUnmount(() => {
|
||||
assert.step(`willUnmount ${this.__uniqueId}`);
|
||||
});
|
||||
},
|
||||
});
|
||||
const serverData = {
|
||||
@@ -120,6 +126,7 @@ odoo.define('stock.stock_traceability_report_backend_tests', function (require)
|
||||
},
|
||||
};
|
||||
|
||||
const target = getFixture();
|
||||
const webClient = await createWebClient({
|
||||
serverData,
|
||||
mockRPC: function (route) {
|
||||
@@ -132,11 +139,12 @@ odoo.define('stock.stock_traceability_report_backend_tests', function (require)
|
||||
});
|
||||
|
||||
await doAction(webClient, 42);
|
||||
await domUtils.click($(webClient.el).find('.o_stock_reports_web_action'));
|
||||
await domUtils.click(target.querySelector('.o_stock_reports_web_action'));
|
||||
await legacyExtraNextTick();
|
||||
await domUtils.click($(webClient.el).find('.breadcrumb-item:first'));
|
||||
await domUtils.click(target.querySelector('.breadcrumb-item'));
|
||||
await legacyExtraNextTick();
|
||||
webClient.destroy();
|
||||
|
||||
destroy(webClient);
|
||||
|
||||
assert.verifySteps([
|
||||
'mounted 1',
|
||||
@@ -146,8 +154,6 @@ odoo.define('stock.stock_traceability_report_backend_tests', function (require)
|
||||
'mounted 3',
|
||||
'willUnmount 3',
|
||||
]);
|
||||
|
||||
unpatch(ControlPanel.prototype, 'test.ControlPanel');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="tours" t-as="tour">
|
||||
<tr t-foreach="tours" t-as="tour" t-key="tour.name">
|
||||
<td><t t-esc="tour.sequence"/></td>
|
||||
<td><t t-esc="tour.name"/></td>
|
||||
<td><t t-esc="tour.url"/></td>
|
||||
|
||||
@@ -12,8 +12,10 @@ var ServicesMixin = require('web.ServicesMixin');
|
||||
var session = require('web.session');
|
||||
var Tip = require('web_tour.Tip');
|
||||
const {Markup} = require('web.utils');
|
||||
const { config: transitionConfig } = require("@web/core/transition");
|
||||
|
||||
var _t = core._t;
|
||||
const { markup } = owl;
|
||||
|
||||
var RUNNING_TOUR_TIMEOUT = 10000;
|
||||
|
||||
@@ -39,6 +41,12 @@ return core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, {
|
||||
});
|
||||
this.disabled = disabled;
|
||||
this.running_tour = local_storage.getItem(get_running_key());
|
||||
if (this.running_tour) {
|
||||
// Transitions can cause DOM mutations which will cause the tour_service
|
||||
// MutationObserver to wait longer before proceeding to the next step
|
||||
// this can slow down tours
|
||||
transitionConfig.disabled = true;
|
||||
}
|
||||
this.running_step_delay = parseInt(local_storage.getItem(get_running_delay_key()), 10) || 0;
|
||||
this.edition = (_.last(session.server_version_info) === 'e') ? 'enterprise' : 'community';
|
||||
this._log = [];
|
||||
@@ -430,14 +438,13 @@ return core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, {
|
||||
if (message) {
|
||||
message = typeof message === 'function' ? message() : message;
|
||||
} else {
|
||||
message = _t('<strong><b>Good job!</b> You went through all steps of this tour.</strong>');
|
||||
message = markup(_t('<strong><b>Good job!</b> You went through all steps of this tour.</strong>'));
|
||||
}
|
||||
const fadeout = this.tours[tour_name].fadeout;
|
||||
core.bus.trigger('show-effect', {
|
||||
type: "rainbow_man",
|
||||
message,
|
||||
fadeout,
|
||||
messageIsHtml: true,
|
||||
});
|
||||
}
|
||||
this.tours[tour_name].current_step = 0;
|
||||
|
||||
@@ -7,15 +7,12 @@ import { ormService } from "@web/core/orm_service";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { uiService } from "@web/core/ui/ui_service";
|
||||
|
||||
import { click, getFixture } from "@web/../tests/helpers/utils";
|
||||
import { registerCleanup } from "@web/../tests/helpers/cleanup";
|
||||
import { click, getFixture, mount } from "@web/../tests/helpers/utils";
|
||||
import { makeTestEnv } from "@web/../tests/helpers/mock_env";
|
||||
import { makeFakeLocalizationService } from "@web/../tests/helpers/mock_services";
|
||||
import { DebugMenuParent } from "@web/../tests/core/debug/debug_manager_tests";
|
||||
import { fakeCommandService } from "@web/../tests/helpers/mock_services";
|
||||
|
||||
const { mount } = owl;
|
||||
|
||||
const debugRegistry = registry.category("debug");
|
||||
let target;
|
||||
|
||||
@@ -60,8 +57,7 @@ QUnit.module("Tours", (hooks) => {
|
||||
};
|
||||
const env = await makeTestEnv({ mockRPC });
|
||||
|
||||
const debugManager = await mount(DebugMenuParent, { env, target });
|
||||
registerCleanup(() => debugManager.destroy());
|
||||
const debugManager = await mount(DebugMenuParent, target, { env });
|
||||
|
||||
await click(debugManager.el.querySelector("button.dropdown-toggle"));
|
||||
|
||||
|
||||
@@ -79,8 +79,7 @@ odoo.define('web_tour.tour_manager_tests', async function (require) {
|
||||
function onShowEffect(params) {
|
||||
assert.deepEqual(params, {
|
||||
fadeout: "medium",
|
||||
message: "<strong><b>Good job!</b> You went through all steps of this tour.</strong>",
|
||||
messageIsHtml: true,
|
||||
message: owl.markup("<strong><b>Good job!</b> You went through all steps of this tour.</strong>"),
|
||||
type: "rainbow_man"
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,10 +7,11 @@ var view_registry = require('web.view_registry');
|
||||
var createView = testUtils.createView;
|
||||
var BaseSettingsView = view_registry.get('base_settings');
|
||||
|
||||
const { legacyExtraNextTick } = require("@web/../tests/helpers/utils");
|
||||
const { getFixture, legacyExtraNextTick } = require("@web/../tests/helpers/utils");
|
||||
const { createWebClient, doAction } = require("@web/../tests/webclient/helpers");
|
||||
|
||||
let serverData;
|
||||
let target;
|
||||
QUnit.module('base_settings_tests', {
|
||||
beforeEach: function () {
|
||||
this.data = {
|
||||
@@ -26,6 +27,7 @@ QUnit.module('base_settings_tests', {
|
||||
}
|
||||
};
|
||||
serverData = { models: this.data };
|
||||
target = getFixture();
|
||||
}
|
||||
}, function () {
|
||||
|
||||
@@ -137,11 +139,11 @@ QUnit.module('base_settings_tests', {
|
||||
const webClient = await createWebClient({ serverData, mockRPC });
|
||||
|
||||
await doAction(webClient, 1);
|
||||
await testUtils.dom.click($(webClient.el).find('button[name="4"]'));
|
||||
await testUtils.dom.click($(target).find('button[name="4"]'));
|
||||
await legacyExtraNextTick();
|
||||
await testUtils.dom.click($(".o_control_panel .breadcrumb-item a"));
|
||||
await legacyExtraNextTick();
|
||||
assert.hasClass($(webClient.el).find(".o_form_view"), "o_form_editable");
|
||||
assert.hasClass($(target).find(".o_form_view"), "o_form_editable");
|
||||
assert.verifySteps([
|
||||
"load_views", // initial setting action
|
||||
"onchange", // this is a setting view => create new record
|
||||
@@ -222,44 +224,44 @@ QUnit.module('base_settings_tests', {
|
||||
|
||||
await doAction(webClient, 1);
|
||||
assert.containsNone(
|
||||
webClient,
|
||||
target,
|
||||
".o_field_boolean input:checked",
|
||||
"checkbox should not be checked"
|
||||
);
|
||||
|
||||
await testUtils.dom.click($(webClient.el).find("input[type='checkbox']"));
|
||||
await testUtils.dom.click($(target).find("input[type='checkbox']"));
|
||||
assert.containsOnce(
|
||||
webClient,
|
||||
target,
|
||||
".o_field_boolean input:checked",
|
||||
"checkbox should be checked"
|
||||
);
|
||||
|
||||
await testUtils.dom.click($(webClient.el).find('button[name="4"]'));
|
||||
await testUtils.dom.click($(target).find('button[name="4"]'));
|
||||
await legacyExtraNextTick();
|
||||
assert.containsOnce(document.body, ".modal", "should open a warning dialog");
|
||||
|
||||
await testUtils.dom.click($(".modal button:contains(Discard)"));
|
||||
await legacyExtraNextTick();
|
||||
assert.containsOnce(webClient, ".o_list_view", "should be open list view");
|
||||
assert.containsOnce(target, ".o_list_view", "should be open list view");
|
||||
|
||||
await testUtils.dom.click($(".o_control_panel .breadcrumb-item a"));
|
||||
await legacyExtraNextTick();
|
||||
assert.containsNone(
|
||||
webClient,
|
||||
target,
|
||||
".o_field_boolean input:checked",
|
||||
"checkbox should not be checked"
|
||||
);
|
||||
|
||||
await testUtils.dom.click($(webClient.el).find("input[type='checkbox']"));
|
||||
await testUtils.dom.click($(webClient.el).find('button[name="4"]'));
|
||||
await testUtils.dom.click($(target).find("input[type='checkbox']"));
|
||||
await testUtils.dom.click($(target).find('button[name="4"]'));
|
||||
await legacyExtraNextTick();
|
||||
assert.containsOnce(document.body, ".modal", "should open a warning dialog");
|
||||
|
||||
await testUtils.dom.click($(".modal button:contains(Stay Here)"));
|
||||
await legacyExtraNextTick();
|
||||
assert.containsOnce(webClient, ".o_form_view", "should be remain on form view");
|
||||
assert.containsOnce(target, ".o_form_view", "should be remain on form view");
|
||||
|
||||
await testUtils.dom.click($(webClient.el).find("button[name='execute']"));
|
||||
await testUtils.dom.click($(target).find("button[name='execute']"));
|
||||
await legacyExtraNextTick();
|
||||
assert.containsNone(
|
||||
document.body,
|
||||
@@ -267,8 +269,8 @@ QUnit.module('base_settings_tests', {
|
||||
"should not open a warning dialog"
|
||||
);
|
||||
|
||||
await testUtils.dom.click($(webClient.el).find("input[type='checkbox']"));
|
||||
await testUtils.dom.click($(webClient.el).find("button[name='cancel']"));
|
||||
await testUtils.dom.click($(target).find("input[type='checkbox']"));
|
||||
await testUtils.dom.click($(target).find("button[name='cancel']"));
|
||||
await legacyExtraNextTick();
|
||||
assert.containsNone(
|
||||
document.body,
|
||||
@@ -449,19 +451,19 @@ QUnit.module('base_settings_tests', {
|
||||
|
||||
const webClient = await createWebClient({ serverData, mockRPC });
|
||||
await doAction(webClient, 1);
|
||||
assert.strictEqual($(webClient.el).find(".breadcrumb").text(), "First action");
|
||||
assert.strictEqual($(target).find(".breadcrumb").text(), "First action");
|
||||
|
||||
await doAction(webClient, 2);
|
||||
assert.strictEqual(
|
||||
$(webClient.el).find(".breadcrumb").text(),
|
||||
$(target).find(".breadcrumb").text(),
|
||||
"First actionNew"
|
||||
);
|
||||
|
||||
loadViewsDef = testUtils.makeTestPromise();
|
||||
await testUtils.dom.click($(webClient.el).find('button[name="3"]'));
|
||||
await testUtils.dom.click($(target).find('button[name="3"]'));
|
||||
await legacyExtraNextTick();
|
||||
assert.strictEqual(
|
||||
$(webClient.el).find(".breadcrumb").text(),
|
||||
$(target).find(".breadcrumb").text(),
|
||||
"First actionNew"
|
||||
);
|
||||
|
||||
@@ -469,7 +471,7 @@ QUnit.module('base_settings_tests', {
|
||||
await testUtils.nextTick();
|
||||
await legacyExtraNextTick();
|
||||
assert.strictEqual(
|
||||
$(webClient.el).find(".breadcrumb").text(),
|
||||
$(target).find(".breadcrumb").text(),
|
||||
"First actionNewOther action"
|
||||
);
|
||||
}
|
||||
@@ -581,19 +583,19 @@ QUnit.module('base_settings_tests', {
|
||||
|
||||
await doAction(webClient, 1);
|
||||
assert.containsNone(
|
||||
webClient,
|
||||
target,
|
||||
".o_field_boolean input:checked",
|
||||
"checkbox should not be checked"
|
||||
);
|
||||
|
||||
await testUtils.dom.click($(webClient.el).find('input[type="checkbox"]'));
|
||||
await testUtils.dom.click($(target).find('input[type="checkbox"]'));
|
||||
assert.containsOnce(
|
||||
webClient,
|
||||
target,
|
||||
".o_field_boolean input:checked",
|
||||
"checkbox should be checked"
|
||||
);
|
||||
|
||||
await testUtils.dom.click($(webClient.el).find('button[name="4"]'));
|
||||
await testUtils.dom.click($(target).find('button[name="4"]'));
|
||||
assert.containsOnce(document.body, ".modal", "should open a warning dialog");
|
||||
|
||||
await testUtils.dom.click($(".modal-footer .btn-primary"));
|
||||
|
||||
Reference in New Issue
Block a user