From 3d26fef5f1017bac04a9a19ea60c424d1a487b26 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 10:38:14 +0200 Subject: [PATCH 01/20] [ADD] counter: create counter component --- awesome_owl/static/src/counter/counter.js | 13 +++++++++++++ awesome_owl/static/src/counter/counter.xml | 9 +++++++++ 2 files changed, 22 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..26f8a51d156 --- /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++; + } +} \ No newline at end of file diff --git a/awesome_owl/static/src/counter/counter.xml b/awesome_owl/static/src/counter/counter.xml new file mode 100644 index 00000000000..5e6370933f4 --- /dev/null +++ b/awesome_owl/static/src/counter/counter.xml @@ -0,0 +1,9 @@ + + + + +

Counter:

+ +
+ +
\ No newline at end of file From 1efd503adf293ac12c72c9d8017332ba5d7ef4cb Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 10:38:33 +0200 Subject: [PATCH 02/20] [IMP] playground: add two counters to the playground --- awesome_owl/static/src/playground.js | 2 ++ awesome_owl/static/src/playground.xml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js index 657fb8b07bb..9f85177447d 100644 --- a/awesome_owl/static/src/playground.js +++ b/awesome_owl/static/src/playground.js @@ -1,7 +1,9 @@ /** @odoo-module **/ 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 bc8df7e074bff7b0bb533ad6764c253d2131d88f Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 11:03:31 +0200 Subject: [PATCH 03/20] [IMP] counter: update styling of counter component --- awesome_owl/static/src/counter/counter.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/awesome_owl/static/src/counter/counter.xml b/awesome_owl/static/src/counter/counter.xml index 5e6370933f4..1fa5a39785b 100644 --- a/awesome_owl/static/src/counter/counter.xml +++ b/awesome_owl/static/src/counter/counter.xml @@ -2,8 +2,10 @@ -

Counter:

- +
+ Counter: + +
\ No newline at end of file From 38f3bfbc66a7258ee331d61a5044e68a684cccf9 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 11:05:08 +0200 Subject: [PATCH 04/20] [ADD] card: create card component --- awesome_owl/static/src/card/card.js | 6 ++++++ awesome_owl/static/src/card/card.xml | 15 +++++++++++++++ awesome_owl/static/src/playground.js | 3 ++- awesome_owl/static/src/playground.xml | 8 ++++++-- 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 awesome_owl/static/src/card/card.js create mode 100644 awesome_owl/static/src/card/card.xml diff --git a/awesome_owl/static/src/card/card.js b/awesome_owl/static/src/card/card.js new file mode 100644 index 00000000000..d5acf6e26d8 --- /dev/null +++ b/awesome_owl/static/src/card/card.js @@ -0,0 +1,6 @@ +import { Component } from "@odoo/owl" + +export class Card extends Component { + static template = "awesome_owl.card" + +} \ No newline at end of file diff --git a/awesome_owl/static/src/card/card.xml b/awesome_owl/static/src/card/card.xml new file mode 100644 index 00000000000..8494816ab54 --- /dev/null +++ b/awesome_owl/static/src/card/card.xml @@ -0,0 +1,15 @@ + + + + +
+
+
+

+ +

+
+
+
+ +
diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js index 9f85177447d..a9035a74009 100644 --- a/awesome_owl/static/src/playground.js +++ b/awesome_owl/static/src/playground.js @@ -2,8 +2,9 @@ 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..7c5122dd08c 100644 --- a/awesome_owl/static/src/playground.xml +++ b/awesome_owl/static/src/playground.xml @@ -4,9 +4,13 @@
hello world + + +
+
+ +
- -
From c03255679a5f617be0d602f6e9a7038381fabad1 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 11:10:40 +0200 Subject: [PATCH 05/20] [IMP] card: update card component to use t-out --- awesome_owl/static/src/card/card.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/awesome_owl/static/src/card/card.xml b/awesome_owl/static/src/card/card.xml index 8494816ab54..8d21330e9a3 100644 --- a/awesome_owl/static/src/card/card.xml +++ b/awesome_owl/static/src/card/card.xml @@ -4,9 +4,9 @@
-
+

- +

From 3ef6e224bbfdd54271a166258a3a45ffa7bc403b Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 11:11:11 +0200 Subject: [PATCH 06/20] [IMP] playground: update data displayed on cards and try markup --- awesome_owl/static/src/playground.js | 7 ++++++- awesome_owl/static/src/playground.xml | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js index a9035a74009..ba89cea39f0 100644 --- a/awesome_owl/static/src/playground.js +++ b/awesome_owl/static/src/playground.js @@ -1,10 +1,15 @@ /** @odoo-module **/ -import { Component } from "@odoo/owl"; +import { Component, markup } 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, Card }; + + setup() { + this.normal_string = "
some content
"; + this.markup_string = markup("
some content
"); + } } diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml index 7c5122dd08c..af4385e5a4f 100644 --- a/awesome_owl/static/src/playground.xml +++ b/awesome_owl/static/src/playground.xml @@ -8,8 +8,8 @@
- - + +
From af709688527a28c9a00ebf2a19d237909048294f Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 11:18:17 +0200 Subject: [PATCH 07/20] [IMP] card: add props validation to card component --- awesome_owl/static/src/card/card.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/awesome_owl/static/src/card/card.js b/awesome_owl/static/src/card/card.js index d5acf6e26d8..1c7c66499af 100644 --- a/awesome_owl/static/src/card/card.js +++ b/awesome_owl/static/src/card/card.js @@ -2,5 +2,9 @@ import { Component } from "@odoo/owl" export class Card extends Component { static template = "awesome_owl.card" + static props = { + title: String, + content: String, + } } \ No newline at end of file From 9657d3998b275cdb26899067e471839d64e187c5 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 11:44:32 +0200 Subject: [PATCH 08/20] [IMP] counter: add onChange callback to counters --- awesome_owl/static/src/counter/counter.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/awesome_owl/static/src/counter/counter.js b/awesome_owl/static/src/counter/counter.js index 26f8a51d156..fbbe6400d9e 100644 --- a/awesome_owl/static/src/counter/counter.js +++ b/awesome_owl/static/src/counter/counter.js @@ -2,6 +2,9 @@ import { Component, useState } from "@odoo/owl"; export class Counter extends Component { static template = "awesome_owl.counter" + static props = { + onChange: { type: Function, optional: true } + } setup() { this.state = useState({ value: 0 }); @@ -9,5 +12,8 @@ export class Counter extends Component { increment() { this.state.value++; + if (this.props.onChange) { + this.props.onChange(); + } } } \ No newline at end of file From 6da5f5f74ad3de102a0da134a9491dea8474ff68 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 11:44:59 +0200 Subject: [PATCH 09/20] [IMP] playground: add a sum and increment it using the counters --- awesome_owl/static/src/playground.js | 7 ++++++- awesome_owl/static/src/playground.xml | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js index ba89cea39f0..8a9ee2b3334 100644 --- a/awesome_owl/static/src/playground.js +++ b/awesome_owl/static/src/playground.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { Component, markup } from "@odoo/owl"; +import { Component, useState, markup } from "@odoo/owl"; import { Counter } from "./counter/counter"; import { Card } from "./card/card"; @@ -11,5 +11,10 @@ export class Playground extends Component { setup() { this.normal_string = "
some content
"; this.markup_string = markup("
some content
"); + this.sum = useState({ value: 2 }); + } + + incrementSum() { + this.sum.value++; } } diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml index af4385e5a4f..04ec578652a 100644 --- a/awesome_owl/static/src/playground.xml +++ b/awesome_owl/static/src/playground.xml @@ -4,9 +4,10 @@
hello world - - + +
+

The sum is:

From 8161e3fe1c1fc5973cb0bf0c5ae8e72cfa9a9845 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 13:46:59 +0200 Subject: [PATCH 10/20] [ADD] todo_list: add todo item and todo list components --- awesome_owl/static/src/playground.js | 3 ++- awesome_owl/static/src/playground.xml | 3 +++ awesome_owl/static/src/todo_list/todo_item.js | 15 +++++++++++++++ awesome_owl/static/src/todo_list/todo_item.xml | 11 +++++++++++ awesome_owl/static/src/todo_list/todo_list.js | 11 +++++++++++ awesome_owl/static/src/todo_list/todo_list.xml | 12 ++++++++++++ 6 files changed, 54 insertions(+), 1 deletion(-) 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/playground.js b/awesome_owl/static/src/playground.js index 8a9ee2b3334..fe79bc526b9 100644 --- a/awesome_owl/static/src/playground.js +++ b/awesome_owl/static/src/playground.js @@ -3,10 +3,11 @@ import { Component, useState, markup } 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() { this.normal_string = "
some content
"; diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml index 04ec578652a..492f9ac79d4 100644 --- a/awesome_owl/static/src/playground.xml +++ b/awesome_owl/static/src/playground.xml @@ -12,6 +12,9 @@
+
+ +
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..13845010de3 --- /dev/null +++ b/awesome_owl/static/src/todo_list/todo_item.js @@ -0,0 +1,15 @@ +import { Component } from "@odoo/owl" + +export class TodoItem extends Component { + static template = "awesome_owl.todo_item"; + static props = { + todo: { + type: Object, + shape: { + id: Number, + description: String, + isCompleted: Boolean, + }, + } + } +} 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..167ad5f60bd --- /dev/null +++ b/awesome_owl/static/src/todo_list/todo_item.xml @@ -0,0 +1,11 @@ + + + + +
+ + +
+
+ +
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..7562bf7f0b4 --- /dev/null +++ b/awesome_owl/static/src/todo_list/todo_list.js @@ -0,0 +1,11 @@ +import { Component, useState } from "@odoo/owl"; +import { TodoItem } from "./todo_item"; + +export class TodoList extends Component { + static template = "awesome_owl.todo_list"; + static components = { TodoItem }; + + setup() { + this.todos = useState([{ id: 3, description: "buy milk", isCompleted: false }]); + } +} 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..5060027fbeb --- /dev/null +++ b/awesome_owl/static/src/todo_list/todo_list.xml @@ -0,0 +1,12 @@ + + + + +
+ + + +
+
+ +
From bc5e35d9f992b8f147f24f33604093bc187688bd Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 14:13:28 +0200 Subject: [PATCH 11/20] [IMP] todo_list: add styling to completed todo items --- awesome_owl/static/src/todo_list/todo_item.xml | 4 ++-- awesome_owl/static/src/todo_list/todo_list.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/awesome_owl/static/src/todo_list/todo_item.xml b/awesome_owl/static/src/todo_list/todo_item.xml index 167ad5f60bd..8d08d616d88 100644 --- a/awesome_owl/static/src/todo_list/todo_item.xml +++ b/awesome_owl/static/src/todo_list/todo_item.xml @@ -2,8 +2,8 @@ -
- +
+ .
diff --git a/awesome_owl/static/src/todo_list/todo_list.js b/awesome_owl/static/src/todo_list/todo_list.js index 7562bf7f0b4..6135abacba8 100644 --- a/awesome_owl/static/src/todo_list/todo_list.js +++ b/awesome_owl/static/src/todo_list/todo_list.js @@ -6,6 +6,6 @@ export class TodoList extends Component { static components = { TodoItem }; setup() { - this.todos = useState([{ id: 3, description: "buy milk", isCompleted: false }]); + this.todos = useState([{ id: 2, description: "write tutorial", isCompleted: true }, { id: 3, description: "buy milk", isCompleted: false }]); } } From ea02bb016c0ac981faa45964e24a229f00f6847f Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 14:32:05 +0200 Subject: [PATCH 12/20] [IMP] todo_list: remove hard coded list and allow user to add todo items --- awesome_owl/static/src/todo_list/todo_list.js | 11 ++++++++++- awesome_owl/static/src/todo_list/todo_list.xml | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/awesome_owl/static/src/todo_list/todo_list.js b/awesome_owl/static/src/todo_list/todo_list.js index 6135abacba8..df1817da078 100644 --- a/awesome_owl/static/src/todo_list/todo_list.js +++ b/awesome_owl/static/src/todo_list/todo_list.js @@ -6,6 +6,15 @@ export class TodoList extends Component { static components = { TodoItem }; setup() { - this.todos = useState([{ id: 2, description: "write tutorial", isCompleted: true }, { id: 3, description: "buy milk", isCompleted: false }]); + this.todos = useState([]); + this.todo_idx = useState({ value: 1 }); + } + + addTodo(ev) { + if (ev.keyCode !== 13 || ev.target.value == "") { + return; + } + this.todos.push({ "id": this.todo_idx.value++, "description": ev.target.value, "isCompleted": false }); + ev.target.value = ""; } } diff --git a/awesome_owl/static/src/todo_list/todo_list.xml b/awesome_owl/static/src/todo_list/todo_list.xml index 5060027fbeb..8884df9b357 100644 --- a/awesome_owl/static/src/todo_list/todo_list.xml +++ b/awesome_owl/static/src/todo_list/todo_list.xml @@ -2,6 +2,9 @@ +
+ +
From fd87e8ccffa5f1b70981753933ac2895ce98bc0d Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 15:15:42 +0200 Subject: [PATCH 13/20] [IMP] todo_list: automatically focus on the todo list input when loading the page --- awesome_owl/static/src/todo_list/todo_list.js | 4 +++- awesome_owl/static/src/todo_list/todo_list.xml | 2 +- awesome_owl/static/src/utils.js | 8 ++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 awesome_owl/static/src/utils.js diff --git a/awesome_owl/static/src/todo_list/todo_list.js b/awesome_owl/static/src/todo_list/todo_list.js index df1817da078..4829c847d6e 100644 --- a/awesome_owl/static/src/todo_list/todo_list.js +++ b/awesome_owl/static/src/todo_list/todo_list.js @@ -1,5 +1,6 @@ -import { Component, useState } from "@odoo/owl"; +import { Component, useRef, useState, onMounted } from "@odoo/owl"; import { TodoItem } from "./todo_item"; +import { useAutofocus } from "../utils"; export class TodoList extends Component { static template = "awesome_owl.todo_list"; @@ -8,6 +9,7 @@ export class TodoList extends Component { setup() { this.todos = useState([]); this.todo_idx = useState({ value: 1 }); + useAutofocus("todo_input"); } addTodo(ev) { diff --git a/awesome_owl/static/src/todo_list/todo_list.xml b/awesome_owl/static/src/todo_list/todo_list.xml index 8884df9b357..7ccfa929418 100644 --- a/awesome_owl/static/src/todo_list/todo_list.xml +++ b/awesome_owl/static/src/todo_list/todo_list.xml @@ -3,7 +3,7 @@
- +
diff --git a/awesome_owl/static/src/utils.js b/awesome_owl/static/src/utils.js new file mode 100644 index 00000000000..f1892306b8c --- /dev/null +++ b/awesome_owl/static/src/utils.js @@ -0,0 +1,8 @@ +import { useRef, onMounted } from "@odoo/owl"; + +export function useAutofocus(refName) { + const ref = useRef(refName); + onMounted(() => { + ref.el.focus(); + }) +} \ No newline at end of file From 205a7b427eb1a872f269d022cd29f18e3c8cd1d8 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 15:54:35 +0200 Subject: [PATCH 14/20] [IMP] todo_list: allow toggling of todos --- awesome_owl/static/src/todo_list/todo_item.js | 7 ++++++- awesome_owl/static/src/todo_list/todo_item.xml | 1 + awesome_owl/static/src/todo_list/todo_list.js | 5 +++++ awesome_owl/static/src/todo_list/todo_list.xml | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/awesome_owl/static/src/todo_list/todo_item.js b/awesome_owl/static/src/todo_list/todo_item.js index 13845010de3..218d1e71ad8 100644 --- a/awesome_owl/static/src/todo_list/todo_item.js +++ b/awesome_owl/static/src/todo_list/todo_item.js @@ -10,6 +10,11 @@ export class TodoItem extends Component { description: String, isCompleted: Boolean, }, - } + }, + toggleState: Function, + } + + toggleCheckbox() { + this.props.toggleState(this.props.todo.id); } } diff --git a/awesome_owl/static/src/todo_list/todo_item.xml b/awesome_owl/static/src/todo_list/todo_item.xml index 8d08d616d88..912e6d3616b 100644 --- a/awesome_owl/static/src/todo_list/todo_item.xml +++ b/awesome_owl/static/src/todo_list/todo_item.xml @@ -3,6 +3,7 @@
+ .
diff --git a/awesome_owl/static/src/todo_list/todo_list.js b/awesome_owl/static/src/todo_list/todo_list.js index 4829c847d6e..668d4d6169b 100644 --- a/awesome_owl/static/src/todo_list/todo_list.js +++ b/awesome_owl/static/src/todo_list/todo_list.js @@ -19,4 +19,9 @@ export class TodoList extends Component { this.todos.push({ "id": this.todo_idx.value++, "description": ev.target.value, "isCompleted": false }); ev.target.value = ""; } + + toggleTodo(id) { + const todo = this.todos.find((todo) => todo.id === id); + todo.isCompleted = !todo.isCompleted; + } } diff --git a/awesome_owl/static/src/todo_list/todo_list.xml b/awesome_owl/static/src/todo_list/todo_list.xml index 7ccfa929418..480fabede33 100644 --- a/awesome_owl/static/src/todo_list/todo_list.xml +++ b/awesome_owl/static/src/todo_list/todo_list.xml @@ -7,7 +7,7 @@
- +
From 99d8ecf3ad8b106b0b24680d8b34ae9a2a5ec976 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 16:05:57 +0200 Subject: [PATCH 15/20] [IMP] todo_list: low deletion of todo list items --- awesome_owl/static/src/todo_list/todo_item.js | 5 +++++ awesome_owl/static/src/todo_list/todo_item.xml | 1 + awesome_owl/static/src/todo_list/todo_list.js | 5 +++++ awesome_owl/static/src/todo_list/todo_list.xml | 2 +- 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/awesome_owl/static/src/todo_list/todo_item.js b/awesome_owl/static/src/todo_list/todo_item.js index 218d1e71ad8..a5853614195 100644 --- a/awesome_owl/static/src/todo_list/todo_item.js +++ b/awesome_owl/static/src/todo_list/todo_item.js @@ -12,9 +12,14 @@ export class TodoItem extends Component { }, }, toggleState: Function, + removeTodo: Function } toggleCheckbox() { this.props.toggleState(this.props.todo.id); } + + delete() { + this.props.removeTodo(this.props.todo.id); + } } diff --git a/awesome_owl/static/src/todo_list/todo_item.xml b/awesome_owl/static/src/todo_list/todo_item.xml index 912e6d3616b..d354f6012db 100644 --- a/awesome_owl/static/src/todo_list/todo_item.xml +++ b/awesome_owl/static/src/todo_list/todo_item.xml @@ -6,6 +6,7 @@ . +
diff --git a/awesome_owl/static/src/todo_list/todo_list.js b/awesome_owl/static/src/todo_list/todo_list.js index 668d4d6169b..16f10bdfec9 100644 --- a/awesome_owl/static/src/todo_list/todo_list.js +++ b/awesome_owl/static/src/todo_list/todo_list.js @@ -24,4 +24,9 @@ export class TodoList extends Component { const todo = this.todos.find((todo) => todo.id === id); todo.isCompleted = !todo.isCompleted; } + + deleteTodo(id) { + const index = this.todos.findIndex((todo) => todo.id === id); + 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 index 480fabede33..1b8228d5540 100644 --- a/awesome_owl/static/src/todo_list/todo_list.xml +++ b/awesome_owl/static/src/todo_list/todo_list.xml @@ -7,7 +7,7 @@
- +
From 3c2782a3bd3b1183fdf48399fa2d03e182c92f42 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 17:21:26 +0200 Subject: [PATCH 16/20] [IMP] card: allow generic data inside cards using slots --- awesome_owl/static/src/card/card.js | 3 +-- awesome_owl/static/src/card/card.xml | 2 +- awesome_owl/static/src/playground.xml | 9 +++++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/awesome_owl/static/src/card/card.js b/awesome_owl/static/src/card/card.js index 1c7c66499af..683861e33b8 100644 --- a/awesome_owl/static/src/card/card.js +++ b/awesome_owl/static/src/card/card.js @@ -4,7 +4,6 @@ export class Card extends Component { static template = "awesome_owl.card" static props = { title: String, - content: String, + slots: Object, } - } \ No newline at end of file diff --git a/awesome_owl/static/src/card/card.xml b/awesome_owl/static/src/card/card.xml index 8d21330e9a3..e0aaa1a8526 100644 --- a/awesome_owl/static/src/card/card.xml +++ b/awesome_owl/static/src/card/card.xml @@ -6,7 +6,7 @@

- +

diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml index 492f9ac79d4..c4520307226 100644 --- a/awesome_owl/static/src/playground.xml +++ b/awesome_owl/static/src/playground.xml @@ -9,8 +9,13 @@

The sum is:

- - + + + + + + +
From 3af4e616f937161da68ca4072b7664e6d8d60f1b Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 23 Sep 2025 17:28:58 +0200 Subject: [PATCH 17/20] [IMP] card: allow toggling of cards' content --- awesome_owl/static/src/card/card.js | 10 +++++++++- awesome_owl/static/src/card/card.xml | 7 +++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/awesome_owl/static/src/card/card.js b/awesome_owl/static/src/card/card.js index 683861e33b8..e6a11612cd4 100644 --- a/awesome_owl/static/src/card/card.js +++ b/awesome_owl/static/src/card/card.js @@ -1,4 +1,4 @@ -import { Component } from "@odoo/owl" +import { Component, useState } from "@odoo/owl" export class Card extends Component { static template = "awesome_owl.card" @@ -6,4 +6,12 @@ export class Card extends Component { title: String, slots: Object, } + + setup() { + this.isOpened = useState({ value: true }); + } + + toggle() { + this.isOpened.value = !this.isOpened.value; + } } \ No newline at end of file diff --git a/awesome_owl/static/src/card/card.xml b/awesome_owl/static/src/card/card.xml index e0aaa1a8526..faf4e7d4ffa 100644 --- a/awesome_owl/static/src/card/card.xml +++ b/awesome_owl/static/src/card/card.xml @@ -4,8 +4,11 @@
-
-

+

+ + +
+

From 423ede6f2519b4dfc600faee4408960f2359a501 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Fri, 26 Sep 2025 15:46:06 +0200 Subject: [PATCH 18/20] [IMP] playground: add newlines to files that didn't have them at the end, use ? in js when applicable. --- awesome_owl/static/src/card/card.js | 2 +- awesome_owl/static/src/counter/counter.js | 6 ++---- awesome_owl/static/src/counter/counter.xml | 2 +- awesome_owl/static/src/utils.js | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/awesome_owl/static/src/card/card.js b/awesome_owl/static/src/card/card.js index e6a11612cd4..70b1749aab5 100644 --- a/awesome_owl/static/src/card/card.js +++ b/awesome_owl/static/src/card/card.js @@ -14,4 +14,4 @@ export class Card extends Component { toggle() { this.isOpened.value = !this.isOpened.value; } -} \ No newline at end of file +} diff --git a/awesome_owl/static/src/counter/counter.js b/awesome_owl/static/src/counter/counter.js index fbbe6400d9e..c427b2f224d 100644 --- a/awesome_owl/static/src/counter/counter.js +++ b/awesome_owl/static/src/counter/counter.js @@ -12,8 +12,6 @@ export class Counter extends Component { increment() { this.state.value++; - if (this.props.onChange) { - this.props.onChange(); - } + this.props?.onChange(); } -} \ No newline at end of file +} diff --git a/awesome_owl/static/src/counter/counter.xml b/awesome_owl/static/src/counter/counter.xml index 1fa5a39785b..c1f3ccb092f 100644 --- a/awesome_owl/static/src/counter/counter.xml +++ b/awesome_owl/static/src/counter/counter.xml @@ -8,4 +8,4 @@
- \ No newline at end of file + diff --git a/awesome_owl/static/src/utils.js b/awesome_owl/static/src/utils.js index f1892306b8c..4e62da7c3c2 100644 --- a/awesome_owl/static/src/utils.js +++ b/awesome_owl/static/src/utils.js @@ -5,4 +5,4 @@ export function useAutofocus(refName) { onMounted(() => { ref.el.focus(); }) -} \ No newline at end of file +} From 6131331909954807a171eab37ede68ce2e5804c2 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Fri, 26 Sep 2025 15:49:34 +0200 Subject: [PATCH 19/20] [IMP] todo_list: fix a potential bug with toggling and deleting todos --- awesome_owl/static/src/todo_list/todo_list.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/awesome_owl/static/src/todo_list/todo_list.js b/awesome_owl/static/src/todo_list/todo_list.js index 16f10bdfec9..ac7ff6a7059 100644 --- a/awesome_owl/static/src/todo_list/todo_list.js +++ b/awesome_owl/static/src/todo_list/todo_list.js @@ -22,11 +22,13 @@ export class TodoList extends Component { toggleTodo(id) { const todo = this.todos.find((todo) => todo.id === id); + if (!todo) return; todo.isCompleted = !todo.isCompleted; } deleteTodo(id) { const index = this.todos.findIndex((todo) => todo.id === id); + if (index == -1) return; this.todos.splice(index, 1); } } From 8f6e5edaf64d78853399c9a7bd7e5919f744247a Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Fri, 26 Sep 2025 16:37:19 +0200 Subject: [PATCH 20/20] [IMP] todo_list: add models for todo and use them instead of hard coding stuff --- awesome_owl/static/src/todo_list/todo_item.js | 20 ++--------- .../static/src/todo_list/todo_item.xml | 4 +-- awesome_owl/static/src/todo_list/todo_list.js | 18 ++-------- .../static/src/todo_list/todo_list.xml | 4 +-- .../static/src/todo_list/todo_model.js | 34 +++++++++++++++++++ 5 files changed, 43 insertions(+), 37 deletions(-) create mode 100644 awesome_owl/static/src/todo_list/todo_model.js diff --git a/awesome_owl/static/src/todo_list/todo_item.js b/awesome_owl/static/src/todo_list/todo_item.js index a5853614195..14afdb63cfa 100644 --- a/awesome_owl/static/src/todo_list/todo_item.js +++ b/awesome_owl/static/src/todo_list/todo_item.js @@ -1,25 +1,9 @@ import { Component } from "@odoo/owl" +import { Todo } from "./todo_model"; export class TodoItem extends Component { static template = "awesome_owl.todo_item"; static props = { - todo: { - type: Object, - shape: { - id: Number, - description: String, - isCompleted: Boolean, - }, - }, - toggleState: Function, - removeTodo: Function - } - - toggleCheckbox() { - this.props.toggleState(this.props.todo.id); - } - - delete() { - this.props.removeTodo(this.props.todo.id); + todo: Todo, } } diff --git a/awesome_owl/static/src/todo_list/todo_item.xml b/awesome_owl/static/src/todo_list/todo_item.xml index d354f6012db..5140bb33f5b 100644 --- a/awesome_owl/static/src/todo_list/todo_item.xml +++ b/awesome_owl/static/src/todo_list/todo_item.xml @@ -3,10 +3,10 @@
- + . - +
diff --git a/awesome_owl/static/src/todo_list/todo_list.js b/awesome_owl/static/src/todo_list/todo_list.js index ac7ff6a7059..703c952c610 100644 --- a/awesome_owl/static/src/todo_list/todo_list.js +++ b/awesome_owl/static/src/todo_list/todo_list.js @@ -1,14 +1,14 @@ import { Component, useRef, useState, onMounted } from "@odoo/owl"; import { TodoItem } from "./todo_item"; import { useAutofocus } from "../utils"; +import { TodoModel } from "./todo_model"; export class TodoList extends Component { static template = "awesome_owl.todo_list"; static components = { TodoItem }; setup() { - this.todos = useState([]); - this.todo_idx = useState({ value: 1 }); + this.model = useState(new TodoModel()); useAutofocus("todo_input"); } @@ -16,19 +16,7 @@ export class TodoList extends Component { if (ev.keyCode !== 13 || ev.target.value == "") { return; } - this.todos.push({ "id": this.todo_idx.value++, "description": ev.target.value, "isCompleted": false }); + this.model.add(ev.target.value); ev.target.value = ""; } - - toggleTodo(id) { - const todo = this.todos.find((todo) => todo.id === id); - if (!todo) return; - todo.isCompleted = !todo.isCompleted; - } - - deleteTodo(id) { - const index = this.todos.findIndex((todo) => todo.id === id); - if (index == -1) return; - 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 index 1b8228d5540..54795505d09 100644 --- a/awesome_owl/static/src/todo_list/todo_list.xml +++ b/awesome_owl/static/src/todo_list/todo_list.xml @@ -6,8 +6,8 @@
- - + +
diff --git a/awesome_owl/static/src/todo_list/todo_model.js b/awesome_owl/static/src/todo_list/todo_model.js new file mode 100644 index 00000000000..7c9426c8136 --- /dev/null +++ b/awesome_owl/static/src/todo_list/todo_model.js @@ -0,0 +1,34 @@ +export class Todo { + static nextId = 1; + + constructor(model, description) { + this._model = model; + this.id = Todo.nextId++; + this.description = description; + this.isCompleted = false; + } + + toggle() { + this.isCompleted = !this.isCompleted; + } + + delete() { + this._model.delete(this.id); + } +} + +export class TodoModel { + constructor() { + this.todoList = []; + } + + add(description) { + this.todoList.push(new Todo(this, description)); + } + + delete(id) { + const index = this.todoList.findIndex((todo) => todo.id === id); + if (index == -1) return; + this.todoList.splice(index, 1); + } +}