From 63c0c186b9d610ec86622beea6f6333c233c23ec Mon Sep 17 00:00:00 2001 From: Lucas Oude Vrielink Date: Fri, 19 Jun 2026 09:22:46 +0200 Subject: [PATCH 1/3] [ADD] awesome_owl: chapter 1.1 & 1.2 --- awesome_owl/static/src/counter/counter.js | 13 +++++++++++++ awesome_owl/static/src/counter/counter.xml | 11 +++++++++++ awesome_owl/static/src/playground.js | 2 ++ awesome_owl/static/src/playground.xml | 2 ++ 4 files changed, 28 insertions(+) create mode 100644 awesome_owl/static/src/counter/counter.js create mode 100644 awesome_owl/static/src/counter/counter.xml diff --git a/awesome_owl/static/src/counter/counter.js b/awesome_owl/static/src/counter/counter.js new file mode 100644 index 00000000000..e65eaed4428 --- /dev/null +++ b/awesome_owl/static/src/counter/counter.js @@ -0,0 +1,13 @@ +import { Component, useState } from "@odoo/owl"; + +export class Counter extends Component { + static template = "awesome_owl.counter"; + + setup() { + this.state = useState({ value: 0 }); + } + + increment() { + this.state.value++ + } +} diff --git a/awesome_owl/static/src/counter/counter.xml b/awesome_owl/static/src/counter/counter.xml new file mode 100644 index 00000000000..f20e162d294 --- /dev/null +++ b/awesome_owl/static/src/counter/counter.xml @@ -0,0 +1,11 @@ + + + + +
+

Counter:

+ +
+
+ +
diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js index 4ac769b0aa5..454e48d8898 100644 --- a/awesome_owl/static/src/playground.js +++ b/awesome_owl/static/src/playground.js @@ -1,5 +1,7 @@ import { Component } from "@odoo/owl"; +import { Counter } from "./counter/counter"; export class Playground extends Component { static template = "awesome_owl.playground"; + static components = { Counter }; } diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml index 4fb905d59f9..e1471b846c8 100644 --- a/awesome_owl/static/src/playground.xml +++ b/awesome_owl/static/src/playground.xml @@ -5,6 +5,8 @@
hello world
+ + From c4361af3a959443c8f37c81420379e2eeb65077b Mon Sep 17 00:00:00 2001 From: Lucas Oude Vrielink Date: Fri, 19 Jun 2026 09:46:09 +0200 Subject: [PATCH 2/3] [ADD] awesome_owl: chapter 1.3 --- awesome_owl/static/src/card/card.js | 12 ++++++++++++ awesome_owl/static/src/playground.js | 3 ++- awesome_owl/static/src/playground.xml | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 awesome_owl/static/src/card/card.js diff --git a/awesome_owl/static/src/card/card.js b/awesome_owl/static/src/card/card.js new file mode 100644 index 00000000000..2e3787f041f --- /dev/null +++ b/awesome_owl/static/src/card/card.js @@ -0,0 +1,12 @@ +import { Component, xml } from "@odoo/owl"; + +export class Card extends Component { + static template = xml` +
+
+
+

+
+
+ `; +} diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js index 454e48d8898..dae12a5231a 100644 --- a/awesome_owl/static/src/playground.js +++ b/awesome_owl/static/src/playground.js @@ -1,7 +1,8 @@ import { Component } from "@odoo/owl"; import { Counter } from "./counter/counter"; +import { Card } from "./card/card"; export class Playground extends Component { static template = "awesome_owl.playground"; - static components = { Counter }; + static components = { Counter, Card }; } diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml index e1471b846c8..10862c79372 100644 --- a/awesome_owl/static/src/playground.xml +++ b/awesome_owl/static/src/playground.xml @@ -7,6 +7,8 @@ + + From 7ba23df8cf4a7361d0d505ac2a536f1701beb5f7 Mon Sep 17 00:00:00 2001 From: Lucas Oude Vrielink Date: Mon, 22 Jun 2026 11:11:37 +0200 Subject: [PATCH 3/3] [ADD] awesome_owl: chapter 1 done --- awesome_owl/static/src/card/card.js | 32 ++++++++++++++-- awesome_owl/static/src/counter/counter.js | 8 ++++ awesome_owl/static/src/playground.js | 19 +++++++++- awesome_owl/static/src/playground.xml | 18 +++++++-- awesome_owl/static/src/todo_list/todo_item.js | 21 ++++++++++ .../static/src/todo_list/todo_item.xml | 13 +++++++ awesome_owl/static/src/todo_list/todo_list.js | 38 +++++++++++++++++++ .../static/src/todo_list/todo_list.xml | 12 ++++++ 8 files changed, 152 insertions(+), 9 deletions(-) create mode 100644 awesome_owl/static/src/todo_list/todo_item.js create mode 100644 awesome_owl/static/src/todo_list/todo_item.xml create mode 100644 awesome_owl/static/src/todo_list/todo_list.js create mode 100644 awesome_owl/static/src/todo_list/todo_list.xml diff --git a/awesome_owl/static/src/card/card.js b/awesome_owl/static/src/card/card.js index 2e3787f041f..a85367bb527 100644 --- a/awesome_owl/static/src/card/card.js +++ b/awesome_owl/static/src/card/card.js @@ -1,12 +1,38 @@ -import { Component, xml } from "@odoo/owl"; +import { Component, xml, useState } from "@odoo/owl"; export class Card extends Component { static template = xml`
-
-

+ +
+
+ +
+ +
+ +
+
`; + + static props = { + title: { type: String }, + slots: { type: Object, optional: true } + }; + + setup() { + this.state = useState({ + isOpen: true + }); + } + + toggle() { + this.state.isOpen = !this.state.isOpen; + } } diff --git a/awesome_owl/static/src/counter/counter.js b/awesome_owl/static/src/counter/counter.js index e65eaed4428..f3cac2e0f4b 100644 --- a/awesome_owl/static/src/counter/counter.js +++ b/awesome_owl/static/src/counter/counter.js @@ -9,5 +9,13 @@ export class Counter extends Component { increment() { this.state.value++ + + if (this.props.onChange) { + this.props.onChange(); + } + } + + static props = { + onChange: { type: Function, optional: true } } } diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js index dae12a5231a..0e7579cb203 100644 --- a/awesome_owl/static/src/playground.js +++ b/awesome_owl/static/src/playground.js @@ -1,8 +1,23 @@ -import { Component } from "@odoo/owl"; +import { Component, markup, useState } from "@odoo/owl"; import { Counter } from "./counter/counter"; import { Card } from "./card/card"; +import { TodoList } from "./todo_list/todo_list"; export class Playground extends Component { static template = "awesome_owl.playground"; - static components = { Counter, Card }; + static components = { Counter, Card, TodoList }; + + setup() { + const productDescriptionFromDB = "

This is a great product!

"; + this.description = markup(productDescriptionFromDB); + this.sum = useState({ value: 0 }); + + this.someExpression = () => { + return true; + } + } + + incrementSum() { + this.sum.value++; + } } diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml index 10862c79372..31daad927b1 100644 --- a/awesome_owl/static/src/playground.xml +++ b/awesome_owl/static/src/playground.xml @@ -5,10 +5,20 @@
hello world
- - - - + + +
+ Total Sum: +
+ +

test

+
description
+
+ +

Content of card 2

+ +
+ diff --git a/awesome_owl/static/src/todo_list/todo_item.js b/awesome_owl/static/src/todo_list/todo_item.js new file mode 100644 index 00000000000..3d8ce1cfdff --- /dev/null +++ b/awesome_owl/static/src/todo_list/todo_item.js @@ -0,0 +1,21 @@ +import { Component, useState } from "@odoo/owl"; + +export class TodoItem extends Component { + static template = "awesome_owl.todo_item"; + static props = { + id: { type: Number }, + description: { type: String }, + isCompleted: { type: Boolean } + }; + + onChange() { + this.state.isCompleted = !this.state.isCompleted; + } + + setup() { + this.state = useState({ + isCompleted: this.props.isCompleted + }) + } + +}; diff --git a/awesome_owl/static/src/todo_list/todo_item.xml b/awesome_owl/static/src/todo_list/todo_item.xml new file mode 100644 index 00000000000..125cd4addd0 --- /dev/null +++ b/awesome_owl/static/src/todo_list/todo_item.xml @@ -0,0 +1,13 @@ + + + + +
+ +

ID:

+

Description:

+

Completed:

+
+
+ +
diff --git a/awesome_owl/static/src/todo_list/todo_list.js b/awesome_owl/static/src/todo_list/todo_list.js new file mode 100644 index 00000000000..f1ae60b87bd --- /dev/null +++ b/awesome_owl/static/src/todo_list/todo_list.js @@ -0,0 +1,38 @@ +import { Component, useState, onMounted, useRef } from "@odoo/owl"; +import { TodoItem } from "./todo_item"; + +export class TodoList extends Component { + static template = "awesome_owl.todo_list"; + static components = { TodoItem }; + + setup() { + this.nextId = 0; + this.todos = useState([]); + + this.inputRef = useRef("input"); + onMounted(() => { + this.inputRef.el.focus(); + }); + } + + addTodo(ev) { + if (ev.keyCode === 13 && ev.target.value != "") { + this.todos.push( + { + "id": this.nextId++, + "description": ev.target.value, + "isCompleted": false + } + ) + ev.target.value = ""; + } + } + + delete(todoId) { + const index = this.todos.findIndex((todo) => todo.id === todoId); + if (index !== -1) { + this.todos.splice(index, 1); + } + } + +} diff --git a/awesome_owl/static/src/todo_list/todo_list.xml b/awesome_owl/static/src/todo_list/todo_list.xml new file mode 100644 index 00000000000..d007b83f232 --- /dev/null +++ b/awesome_owl/static/src/todo_list/todo_list.xml @@ -0,0 +1,12 @@ + + + + + +
+ + +
+
+ +