From f49b814ab40c1acc1ab11ca6e6fc8b2319f24f8e Mon Sep 17 00:00:00 2001 From: Yousef Allam Date: Tue, 25 Aug 2026 16:32:07 +0200 Subject: [PATCH] [ADD] awesome_owl: Chapter 1 done Added Counters and Todo list --- awesome_owl/static/src/card/card.js | 19 ++++++++++++ awesome_owl/static/src/card/card.xml | 21 +++++++++++++ awesome_owl/static/src/counter/counter.js | 18 +++++++++++ awesome_owl/static/src/counter/counter.xml | 13 ++++++++ awesome_owl/static/src/playground.js | 17 +++++++++- awesome_owl/static/src/playground.xml | 21 +++++++++++-- awesome_owl/static/src/todo/todoItem.js | 15 +++++++++ awesome_owl/static/src/todo/todoItem.xml | 16 ++++++++++ awesome_owl/static/src/todo/todoList.js | 36 ++++++++++++++++++++++ awesome_owl/static/src/todo/todoList.xml | 13 ++++++++ awesome_owl/static/src/utils.js | 13 ++++++++ 11 files changed, 198 insertions(+), 4 deletions(-) create mode 100644 awesome_owl/static/src/card/card.js create mode 100644 awesome_owl/static/src/card/card.xml create mode 100644 awesome_owl/static/src/counter/counter.js create mode 100644 awesome_owl/static/src/counter/counter.xml create mode 100644 awesome_owl/static/src/todo/todoItem.js create mode 100644 awesome_owl/static/src/todo/todoItem.xml create mode 100644 awesome_owl/static/src/todo/todoList.js create mode 100644 awesome_owl/static/src/todo/todoList.xml create mode 100644 awesome_owl/static/src/utils.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..d73f13a37e2 --- /dev/null +++ b/awesome_owl/static/src/card/card.js @@ -0,0 +1,19 @@ +import { Component, useState } from "@odoo/owl"; + +export class Card extends Component { + static template = "awesome_owl.card"; + static props = { + title: { type: String }, + slots: { type: Object, optional: true }, + }; + + setup() { + this.state = useState({ + isOpen: true, + }); + } + + onToggle() { + this.state.isOpen = !this.state.isOpen; + } +} diff --git a/awesome_owl/static/src/card/card.xml b/awesome_owl/static/src/card/card.xml new file mode 100644 index 00000000000..6e898945b4e --- /dev/null +++ b/awesome_owl/static/src/card/card.xml @@ -0,0 +1,21 @@ + + + + +
+
+
+ +
+ +
+ +
+
+ +
+
+
+
+ +
diff --git a/awesome_owl/static/src/counter/counter.js b/awesome_owl/static/src/counter/counter.js new file mode 100644 index 00000000000..e53aafbb2bf --- /dev/null +++ b/awesome_owl/static/src/counter/counter.js @@ -0,0 +1,18 @@ +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({ + count: 0, + }); + } + + increment() { + this.props.onChange?.(++this.state.count); + } +} diff --git a/awesome_owl/static/src/counter/counter.xml b/awesome_owl/static/src/counter/counter.xml new file mode 100644 index 00000000000..3e062458945 --- /dev/null +++ b/awesome_owl/static/src/counter/counter.xml @@ -0,0 +1,13 @@ + + + + +
+

+ +

+ +
+
+ +
diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js index 4ac769b0aa5..129d8faef04 100644 --- a/awesome_owl/static/src/playground.js +++ b/awesome_owl/static/src/playground.js @@ -1,5 +1,20 @@ -import { Component } from "@odoo/owl"; +import { Component, useState } from "@odoo/owl"; +import { Counter } from "./counter/counter"; +import { Card } from "./card/card"; +import { TodoList } from "./todo/todoList"; export class Playground extends Component { static template = "awesome_owl.playground"; + static components = { Counter, Card, TodoList }; + + setup() { + this.state = useState({ + sum: 0, + }); + } + + incrementSum(count) { + this.state.sum += 1; + } + } diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml index 4fb905d59f9..a3b39899e6d 100644 --- a/awesome_owl/static/src/playground.xml +++ b/awesome_owl/static/src/playground.xml @@ -1,9 +1,24 @@ - + -
- hello world +
+ + + + + + + +
+

Sum: +

+
+
+ + + +
diff --git a/awesome_owl/static/src/todo/todoItem.js b/awesome_owl/static/src/todo/todoItem.js new file mode 100644 index 00000000000..afc46c3cab8 --- /dev/null +++ b/awesome_owl/static/src/todo/todoItem.js @@ -0,0 +1,15 @@ +import { Component, markup } from "@odoo/owl"; +import { Counter } from "../counter/counter"; + +export class TodoItem extends Component { + static template = "awesome_owl.todoItem"; + static components = { Counter }; + static props = { + id: { type: Number }, + description: { type: String }, + isCompleted: { type: Boolean}, + toggleState: { type: Function, optional: true }, + removeTodo: { type: Function, optional: true }, + }; + +} diff --git a/awesome_owl/static/src/todo/todoItem.xml b/awesome_owl/static/src/todo/todoItem.xml new file mode 100644 index 00000000000..cadd6b1366f --- /dev/null +++ b/awesome_owl/static/src/todo/todoItem.xml @@ -0,0 +1,16 @@ + + + + +
+ + + +
+
+ +
diff --git a/awesome_owl/static/src/todo/todoList.js b/awesome_owl/static/src/todo/todoList.js new file mode 100644 index 00000000000..547a681e662 --- /dev/null +++ b/awesome_owl/static/src/todo/todoList.js @@ -0,0 +1,36 @@ +import { Component, useState } from "@odoo/owl"; +import { TodoItem } from "./todoItem"; +import { useAutoFocus } from "../utils"; + +export class TodoList extends Component { + static template = "awesome_owl.todoList"; + static components = { TodoItem }; + + setup() { + this.state = useState({todos: []}); + this.idCounter = 1; + this.addTodoRef = useAutoFocus(); + } + + onAddTodo(ev) { + if (ev.key == "Enter" && ev.target.value.trim() !== "") { + const newTodo = { + id: this.idCounter++, + description: ev.target.value, + isCompleted: false, + }; + + this.state.todos.push(newTodo); + ev.target.value = ""; + } + } + + toggleState(todoId) { + const todo = this.state.todos?.find((t) => t.id === todoId); + if (todo) todo.isCompleted = !todo.isCompleted; + } + + removeTodo(todoId) { + this.state.todos = this.state.todos?.filter((t) => t.id !== todoId); + } +} diff --git a/awesome_owl/static/src/todo/todoList.xml b/awesome_owl/static/src/todo/todoList.xml new file mode 100644 index 00000000000..6a37f19dc81 --- /dev/null +++ b/awesome_owl/static/src/todo/todoList.xml @@ -0,0 +1,13 @@ + + + + + +
+
+ +
+
+
+ +
diff --git a/awesome_owl/static/src/utils.js b/awesome_owl/static/src/utils.js new file mode 100644 index 00000000000..001515a3200 --- /dev/null +++ b/awesome_owl/static/src/utils.js @@ -0,0 +1,13 @@ +import { onMounted, useRef } from "@odoo/owl"; + +export function useAutoFocus() { + const ref = useRef("add-todo-input"); + + onMounted(() => { + if (ref.el) { + ref.el.focus(); + } + }); + + return ref; +}