Compare commits

...

1 Commits

Author SHA1 Message Date
Bastien Fafchamps (bafa)
0abfcd2ecf [IMP] web: Update js code to ES6
This commit updates javascript code to be up to date with the codebase
standards:
- use the `static` keyword when possible
- proper owl imports
- removed unecessary `@odoo-module` directives
2024-11-27 13:20:59 +01:00
9 changed files with 110 additions and 102 deletions

View File

@@ -29,8 +29,9 @@ framework and use services, core components, hooks,...
import { Component } from "@odoo/owl"; import { Component } from "@odoo/owl";
class MyClientAction extends Component {} class MyClientAction extends Component {
MyClientAction.template = "my_module.clientaction"; static template = "my_module.clientaction";
}
// remember the tag name we put in the first step // remember the tag name we put in the first step
registry.category("actions").add("my_module.MyClientAction", MyClientAction); registry.category("actions").add("my_module.MyClientAction", MyClientAction);

View File

@@ -18,8 +18,9 @@ displaying "Late!" in red whenever the checkbox is checked.
import { BooleanField } from "@web/views/fields/boolean/boolean_field"; import { BooleanField } from "@web/views/fields/boolean/boolean_field";
import { Component, xml } from "@odoo/owl"; import { Component, xml } from "@odoo/owl";
class LateOrderBooleanField extends BooleanField {} class LateOrderBooleanField extends BooleanField {
LateOrderBooleanField.template = "my_module.LateOrderBooleanField"; static template = "my_module.LateOrderBooleanField";
}
#. Create the field template. #. Create the field template.
@@ -66,23 +67,20 @@ Assume that we want to create a field that displays a simple text in red.
import { registry } from "@web/core/registry"; import { registry } from "@web/core/registry";
export class MyTextField extends Component { export class MyTextField extends Component {
static template = xml`
<input t-att-id="props.id" class="text-danger" t-att-value="props.value" onChange.bind="onChange" />
`;
static props = { ...standardFieldProps };
static supportedTypes = ["char"];
/** /**
* @param {boolean} newValue * @param {boolean} newValue
*/ */
onChange(newValue) { onChange(newValue) {
this.props.update(newValue); this.props.update(newValue);
} }
} }
MyTextField.template = xml`
<input t-att-id="props.id" class="text-danger" t-att-value="props.value" onChange.bind="onChange" />
`;
MyTextField.props = {
...standardFieldProps,
};
MyTextField.supportedTypes = ["char"];
The imported `standardFieldProps` contains the standard props passed by the `View` such as The imported `standardFieldProps` contains the standard props passed by the `View` such as
the `update` function to update the value, the `type` of the field in the model, the the `update` function to update the value, the `type` of the field in the model, the
`readonly` boolean, and others. `readonly` boolean, and others.

View File

@@ -20,12 +20,12 @@ can be done in a few steps:
// the controller usually contains the Layout and the renderer. // the controller usually contains the Layout and the renderer.
class CustomKanbanController extends KanbanController { class CustomKanbanController extends KanbanController {
static template = "my_module.CustomKanbanView";
// Your logic here, override or insert new methods... // Your logic here, override or insert new methods...
// if you override setup(), don't forget to call super.setup() // if you override setup(), don't forget to call super.setup()
} }
CustomKanbanController.template = "my_module.CustomKanbanView";
export const customKanbanView = { export const customKanbanView = {
...kanbanView, // contains the default Renderer/Controller/Model ...kanbanView, // contains the default Renderer/Controller/Model
Controller: CustomKanbanController, Controller: CustomKanbanController,
@@ -85,6 +85,9 @@ Creating a new view is an advanced topic. This guide highlight only the essentia
import { Component, onWillStart, useState} from "@odoo/owl"; import { Component, onWillStart, useState} from "@odoo/owl";
export class BeautifulController extends Component { export class BeautifulController extends Component {
static template = "my_module.View";
static components = { Layout };
setup() { setup() {
this.orm = useService("orm"); this.orm = useService("orm");
@@ -106,9 +109,6 @@ Creating a new view is an advanced topic. This guide highlight only the essentia
} }
} }
BeautifulController.template = "my_module.View";
BeautifulController.components = { Layout };
The template of the Controller displays the control panel with Layout and also the The template of the Controller displays the control panel with Layout and also the
renderer. renderer.
@@ -133,9 +133,9 @@ Creating a new view is an advanced topic. This guide highlight only the essentia
:caption: :file:`beautiful_renderer.js` :caption: :file:`beautiful_renderer.js`
import { Component } from "@odoo/owl"; import { Component } from "@odoo/owl";
export class BeautifulRenderer extends Component {} export class BeautifulRenderer extends Component {
static template = "my_module.Renderer";
BeautifulRenderer.template = "my_module.Renderer"; }
.. code-block:: xml .. code-block:: xml
:caption: :file:`beautiful_renderer.xml` :caption: :file:`beautiful_renderer.xml`

View File

@@ -152,9 +152,10 @@ client can use it. For example, the field registry contains all field components
.. code-block:: javascript .. code-block:: javascript
import { Component } from "@odoo/owl";
import { registry } from "./core/registry"; import { registry } from "./core/registry";
class MyFieldChar extends owl.Component { class MyFieldChar extends Component {
// some code // some code
} }

View File

@@ -193,18 +193,20 @@ the window is resized/scrolled.
.. code-block:: javascript .. code-block:: javascript
import { usePosition } from "@web/core/position_hook"; import { usePosition } from "@web/core/position_hook";
import { Component, xml } from "@odoo/owl";
class MyPopover extends Component {
static template = xml`
<div t-ref="popper">
I am positioned through a wonderful hook!
</div>
`;
class MyPopover extends owl.Component {
setup() { setup() {
// Here, the reference is the target props, which is an HTMLElement // Here, the reference is the target props, which is an HTMLElement
usePosition(this.props.target); usePosition(this.props.target);
} }
} }
MyPopover.template = owl.tags.xml`
<div t-ref="popper">
I am positioned through a wonderful hook!
</div>
`;
.. important:: .. important::
You should indicate your `popper` element using a `t-ref directive <https://github.com/odoo/owl/blob/master/doc/reference/hooks.md#useref>`_. You should indicate your `popper` element using a `t-ref directive <https://github.com/odoo/owl/blob/master/doc/reference/hooks.md#useref>`_.
@@ -260,11 +262,21 @@ API
.. code-block:: javascript .. code-block:: javascript
import { Component, xml, useRef } from "@odoo/owl";
import { usePosition } from "@web/core/position_hook"; import { usePosition } from "@web/core/position_hook";
class DropMenu extends owl.Component { class DropMenu extends Component {
static template = xml`
<button t-ref="toggler">Toggle Menu</button>
<div t-ref="menu">
<t t-slot="default">
This is the menu default content.
</t>
</div>
`;
setup() { setup() {
const toggler = owl.useRef("toggler"); const toggler = useRef("toggler");
usePosition( usePosition(
() => toggler.el, () => toggler.el,
{ {
@@ -278,14 +290,6 @@ API
); );
} }
} }
DropMenu.template = owl.tags.xml`
<button t-ref="toggler">Toggle Menu</button>
<div t-ref="menu">
<t t-slot="default">
This is the menu default content.
</t>
</div>
`;
.. _frontend/hooks/useSpellCheck: .. _frontend/hooks/useSpellCheck:

View File

@@ -154,7 +154,6 @@ This is done by using the `patch` utility function:
.. code-block:: javascript .. code-block:: javascript
/** @odoo-module */
import { Hamster } from "@web/core/hamster" import { Hamster } from "@web/core/hamster"
import { patch } from "@web/core/utils/patch"; import { patch } from "@web/core/utils/patch";

View File

@@ -29,10 +29,15 @@ can make a simple component in Odoo.
.. code-block:: javascript .. code-block:: javascript
const { useState } = owl.hooks; import { Component, xml, useState } from "@odoo/owl";
const { xml } = owl.tags;
class MyComponent extends Component { class MyComponent extends Component {
static template = xml`
<div t-on-click="increment">
<t t-esc="state.value">
</div>
`;
setup() { setup() {
this.state = useState({ value: 1 }); this.state = useState({ value: 1 });
} }
@@ -41,10 +46,6 @@ can make a simple component in Odoo.
this.state.value++; this.state.value++;
} }
} }
MyComponent.template = xml
`<div t-on-click="increment">
<t t-esc="state.value">
</div>`;
This example shows that Owl is available as a library in the global namespace as This example shows that Owl is available as a library in the global namespace as
`owl`: it can simply be used like most libraries in Odoo. Note that we `owl`: it can simply be used like most libraries in Odoo. Note that we
@@ -67,12 +68,13 @@ Here is how the component above should be defined:
.. code-block:: javascript .. code-block:: javascript
const { useState } = owl.hooks; import { Component, useState } from "@odoo/owl";
class MyComponent extends Component { class MyComponent extends Component {
static template = 'myaddon.MyComponent';
... ...
} }
MyComponent.template = 'myaddon.MyComponent';
And the template is now located in the corresponding xml file: And the template is now located in the corresponding xml file:
@@ -768,16 +770,21 @@ Props
.. code-block:: javascript .. code-block:: javascript
import { Component, xml } from "@odoo/owl";
import { Notebook } from "@web/core/notebook/notebook"; import { Notebook } from "@web/core/notebook/notebook";
class MyTemplateComponent extends owl.Component { class MyTemplateComponent extends Component {
static template = owl.tags.xml` static template = xml`
<h1 t-esc="props.title" /> <h1 t-esc="props.title" />
<p t-esc="props.text" /> <p t-esc="props.text" />
`; `;
} }
class MyComponent extends owl.Component { class MyComponent extends Component {
static template = xml`
<Notebook defaultPage="'page_2'" pages="pages" />
`;
get pages() { get pages() {
return [ return [
{ {
@@ -800,9 +807,6 @@ Props
] ]
} }
} }
MyComponent.template = owl.tags.xml`
<Notebook defaultPage="'page_2'" pages="pages" />
`;
Both examples are shown here: Both examples are shown here:
@@ -941,9 +945,18 @@ The shape of a `group` is the following:
.. code-block:: javascript .. code-block:: javascript
import { Component, xml } from "@odoo/owl";
import { SelectMenu } from "@web/core/select_menu/select_menu"; import { SelectMenu } from "@web/core/select_menu/select_menu";
class MyComponent extends owl.Component { class MyComponent extends Component {
static template = xml`
<SelectMenu
choices="choices"
groups="groups"
value="'value_2'"
/>
`;
get choices() { get choices() {
return [ return [
{ {
@@ -979,30 +992,21 @@ The shape of a `group` is the following:
] ]
} }
} }
MyComponent.template = owl.tags.xml`
<SelectMenu
choices="choices"
groups="groups"
value="'value_2'"
/>
`;
You can also customize the appearance of the toggler and set a custom template for the choices, using the appropriate component `slot`'s. You can also customize the appearance of the toggler and set a custom template for the choices, using the appropriate component `slot`'s.
.. code-block:: javascript .. code-block:: xml
MyComponent.template = owl.tags.xml` <SelectMenu
<SelectMenu choices="choices"
choices="choices" groups="groups"
groups="groups" value="'value_2'"
value="'value_2'" >
> Make a choice!
Make a choice! <t t-set-slot="choice" t-slot-scope="choice">
<t t-set-slot="choice" t-slot-scope="choice"> <span class="coolClass" t-esc="'👉 ' + choice.data.label + ' 👈'" />
<span class="coolClass" t-esc="'👉 ' + choice.data.label + ' 👈'" /> </t>
</t> </SelectMenu>
</SelectMenu>
`;
.. image:: owl_components/select_menu.png .. image:: owl_components/select_menu.png
:width: 400 px :width: 400 px
@@ -1019,22 +1023,20 @@ The shape of a `group` is the following:
For more advanced use cases, you can customize the bottom area of the dropdown, using the `bottomArea` slot. Here, we choose to display For more advanced use cases, you can customize the bottom area of the dropdown, using the `bottomArea` slot. Here, we choose to display
a button with the corresponding value set in the search input. a button with the corresponding value set in the search input.
.. code-block:: javascript .. code-block:: xml
MyComponent.template = owl.tags.xml` <SelectMenu
<SelectMenu choices="choices"
choices="choices" >
> <span class="select_menu_test">Select something</span>
<span class="select_menu_test">Select something</span> <t t-set-slot="bottomArea" t-slot-scope="select">
<t t-set-slot="bottomArea" t-slot-scope="select"> <div t-if="select.data.searchValue">
<div t-if="select.data.searchValue"> <button class="btn text-primary" t-on-click="() => this.onCreate(select.data.searchValue)">
<button class="btn text-primary" t-on-click="() => this.onCreate(select.data.searchValue)"> Create this article "<i t-esc="select.data.searchValue" />"
Create this article "<i t-esc="select.data.searchValue" />" </button>
</button> </div>
</div> </t>
</t> </SelectMenu>
</SelectMenu>
`;
.. image:: owl_components/select_menu_bottomArea.png .. image:: owl_components/select_menu_bottomArea.png
:width: 400 px :width: 400 px
@@ -1098,9 +1100,13 @@ The shape of a `tag` is the following:
.. code-block:: javascript .. code-block:: javascript
import { Component, xml } from "@odoo/owl";
import { TagsList } from "@web/core/tags_list/tags_list"; import { TagsList } from "@web/core/tags_list/tags_list";
class Parent extends Component { class Parent extends Component {
static template = xml`<TagsList tags="tags" />`;
static components = { TagsList };
setup() { setup() {
this.tags = [{ this.tags = [{
id: "tag1", id: "tag1",
@@ -1119,8 +1125,6 @@ The shape of a `tag` is the following:
}]; }];
} }
} }
Parent.components = { TagsList };
Parent.template = xml`<TagsList tags="tags" />`;
Depending the attributes given to each tag, their appearance and behavior will differ. Depending the attributes given to each tag, their appearance and behavior will differ.

View File

@@ -313,10 +313,10 @@ Let's say we want to add an effect that add a sepia look at the page.
.. code-block:: javascript .. code-block:: javascript
import { registry } from "@web/core/registry"; import { registry } from "@web/core/registry";
const { Component, tags } = owl; import { Component, xml } from "@odoo/owl";
class SepiaEffect extends Component {} class SepiaEffect extends Component {
SepiaEffect.template = tags.xml` static template = xml`
<div style=" <div style="
position: absolute; position: absolute;
left: 0; left: 0;
@@ -326,7 +326,8 @@ Let's say we want to add an effect that add a sepia look at the page.
pointer-events: none; pointer-events: none;
background: rgba(124,87,0, 0.4); background: rgba(124,87,0, 0.4);
"></div> "></div>
`; `;
}
export function sepiaEffectProvider(env, params = {}) { export function sepiaEffectProvider(env, params = {}) {
return { return {

View File

@@ -51,8 +51,8 @@ class BootstrapTranslator(HTML5Translator):
# Meta # Meta
self.meta = ['', ''] # HTMLWriter strips out the first two items from Translator.meta self.meta = ['', ''] # HTMLWriter strips out the first two items from Translator.meta
self.add_meta('<meta http-equiv="X-UA-Compatible" content="IE=edge">') # self.add_meta('<meta http-equiv="X-UA-Compatible" content="IE=edge">')
self.add_meta('<meta name="viewport" content="width=device-width, initial-scale=1">') # self.add_meta('<meta name="viewport" content="width=device-width, initial-scale=1">')
# Body # Body
self.body = [] self.body = []