From 2846998fe81a1ef52be29868dde5a50810b668fd Mon Sep 17 00:00:00 2001 From: Ait-Mlouk Omar Date: Wed, 24 Sep 2025 22:12:01 +0000 Subject: [PATCH 1/5] [FIX] website_airproof: fix template loading order issue The carousel template file was loaded too late in the manifest data sequence, causing a ParseError when new_page_templates tried to reference it. closes odoo/tutorials#989 X-original-commit: 34d70b5f1c1079bdb9ae64d3fb2f95c95d6cba22 Signed-off-by: Antoine Vandevenne (anv) --- website_airproof/__manifest__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website_airproof/__manifest__.py b/website_airproof/__manifest__.py index f6cd9dc0d5e..2c2c62d6a18 100644 --- a/website_airproof/__manifest__.py +++ b/website_airproof/__manifest__.py @@ -7,6 +7,9 @@ 'license': 'LGPL-3', 'depends': ['website_sale', 'website_sale_wishlist', 'website_blog', 'website_mass_mailing'], 'data': [ + # Snippets + 'views/snippets/options.xml', + 'views/snippets/s_airproof_carousel.xml', # Options 'data/presets.xml', 'data/website.xml', @@ -24,9 +27,6 @@ 'views/website_templates.xml', 'views/website_sale_templates.xml', 'views/website_sale_wishlist_templates.xml', - # Snippets - 'views/snippets/options.xml', - 'views/snippets/s_airproof_carousel.xml', # Images 'data/images.xml', ], From 0f2932fd1296c9beb651dfba349c99da673224f7 Mon Sep 17 00:00:00 2001 From: "Claire (clbr)" Date: Fri, 21 Nov 2025 13:02:18 +0000 Subject: [PATCH 2/5] [FIX] awesome_owl: Fix missing css variables Some imports are missing in the manifest causing some warnings and the css doesn't load properly. Fix was fixed in the master branch, backporting it in 19.0 for the onboarding classes that always happen in the lastest stable. task-none X-original-commit: b7e18c9e94f7ba6e0fb293f050cb76001344d70c Part-of: odoo/tutorials#1038 Signed-off-by: Antoine Vandevenne (anv) --- awesome_owl/__manifest__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/awesome_owl/__manifest__.py b/awesome_owl/__manifest__.py index e8ac1cda552..55002ab81de 100644 --- a/awesome_owl/__manifest__.py +++ b/awesome_owl/__manifest__.py @@ -29,8 +29,10 @@ 'assets': { 'awesome_owl.assets_playground': [ ('include', 'web._assets_helpers'), + ('include', 'web._assets_backend_helpers'), 'web/static/src/scss/pre_variables.scss', 'web/static/lib/bootstrap/scss/_variables.scss', + 'web/static/lib/bootstrap/scss/_maps.scss', ('include', 'web._assets_bootstrap'), ('include', 'web._assets_core'), 'web/static/src/libs/fontawesome/css/font-awesome.css', From 6bdaa36a7d61e7da49ef331baf81dcee22e16392 Mon Sep 17 00:00:00 2001 From: "Claire (clbr)" Date: Fri, 21 Nov 2025 13:18:08 +0000 Subject: [PATCH 3/5] [FIX] awesome_dashboard: Get rid of the deprecated warning `json` routes were deprecated to `jsonrpc` in 19.0, let's get rid of the warning to avoid confusion for the newdoos. task-none closes odoo/tutorials#1038 X-original-commit: 781b5900205cfd7fff9aa3a03ee85b76ad535107 Signed-off-by: Antoine Vandevenne (anv) --- awesome_dashboard/controllers/controllers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awesome_dashboard/controllers/controllers.py b/awesome_dashboard/controllers/controllers.py index 56d4a051287..05977d3bd7f 100644 --- a/awesome_dashboard/controllers/controllers.py +++ b/awesome_dashboard/controllers/controllers.py @@ -9,7 +9,7 @@ logger = logging.getLogger(__name__) class AwesomeDashboard(http.Controller): - @http.route('/awesome_dashboard/statistics', type='json', auth='user') + @http.route('/awesome_dashboard/statistics', type='jsonrpc', auth='user') def get_statistics(self): """ Returns a dict of statistics about the orders: From e5f12da561841681cb9d0c144a2997c07a99970d Mon Sep 17 00:00:00 2001 From: "Manal El Kaidi (maelk)" Date: Fri, 29 May 2026 13:59:10 +0200 Subject: [PATCH 4/5] [IMP] awesome_owl: web framework 101 PROBLEM The playground interface was becoming cluttered and the counter logic wasn't reusable. Additionally, the framework escaped raw HTML by default, preventing rich text rendering in cards. GOAL Extract the UI into reusable components (Counter and Card) and allow secure HTML rendering using OWL's markup function. SOLUTION - Extracted counter logic from Playground into a dedicated Counter component. - Created a reusable Card component accepting 'title' and 'content' props. - Updated Card template to use 't-out' instead of 't-esc' for the content. - Imported and applied the 'markup' function in Playground to safely pass HTML to the Card. task-6254993 [IMP] awesome_owl: web framework 101 --- awesome_owl/static/src/card/card.js | 11 +++++++ awesome_owl/static/src/card/card.xml | 14 +++++++++ awesome_owl/static/src/counter/counter.js | 17 +++++++++++ awesome_owl/static/src/counter/counter.xml | 12 ++++++++ awesome_owl/static/src/playground.js | 16 +++++++++- awesome_owl/static/src/playground.xml | 15 ++++++++++ awesome_owl/static/src/todolist/todo_item.js | 15 ++++++++++ awesome_owl/static/src/todolist/todo_item.xml | 9 ++++++ awesome_owl/static/src/todolist/todolist.js | 29 +++++++++++++++++++ awesome_owl/static/src/todolist/todolist.xml | 17 +++++++++++ 10 files changed, 154 insertions(+), 1 deletion(-) 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/todolist/todo_item.js create mode 100644 awesome_owl/static/src/todolist/todo_item.xml create mode 100644 awesome_owl/static/src/todolist/todolist.js create mode 100644 awesome_owl/static/src/todolist/todolist.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..d1a118e8b40 --- /dev/null +++ b/awesome_owl/static/src/card/card.js @@ -0,0 +1,11 @@ +/** @odoo-module **/ + +import { Component } from "@odoo/owl"; + +export class Card extends Component { + static template = "awesome_owl.card"; + static props = { + title: { type: String }, + content: { type: String }, + }; +} diff --git a/awesome_owl/static/src/card/card.xml b/awesome_owl/static/src/card/card.xml new file mode 100644 index 00000000000..0fadc5dd23d --- /dev/null +++ b/awesome_owl/static/src/card/card.xml @@ -0,0 +1,14 @@ + + +
+
+
+ +
+

+ +

+
+
+
+
diff --git a/awesome_owl/static/src/counter/counter.js b/awesome_owl/static/src/counter/counter.js new file mode 100644 index 00000000000..ecefc44210d --- /dev/null +++ b/awesome_owl/static/src/counter/counter.js @@ -0,0 +1,17 @@ +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: 1 }); + } + + increment() { + this.state.value++; + if (this.props.onChange) { + this.props.onChange(); + } + } +} diff --git a/awesome_owl/static/src/counter/counter.xml b/awesome_owl/static/src/counter/counter.xml new file mode 100644 index 00000000000..672f79ab559 --- /dev/null +++ b/awesome_owl/static/src/counter/counter.xml @@ -0,0 +1,12 @@ + + + + +
+ hello world +

Counter:

+ +
+
+ +
diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js index 4ac769b0aa5..635ac7739e1 100644 --- a/awesome_owl/static/src/playground.js +++ b/awesome_owl/static/src/playground.js @@ -1,5 +1,19 @@ -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 "./todolist/todolist"; export class Playground extends Component { static template = "awesome_owl.playground"; + static components = { Counter, Card, TodoList }; + + setup(){ + this.htmlNormal = "
some content
"; + this.htmlMarkup = markup("
some content
"); + this.state = useState({ sum: 2 }); + } + + incrementSum() { + this.state.sum++; + } } diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml index 4fb905d59f9..1c5b7dac29a 100644 --- a/awesome_owl/static/src/playground.xml +++ b/awesome_owl/static/src/playground.xml @@ -4,6 +4,21 @@
hello world +
+ + +
+
+ The sum is: +
+
+
+ + +
+
+
+
diff --git a/awesome_owl/static/src/todolist/todo_item.js b/awesome_owl/static/src/todolist/todo_item.js new file mode 100644 index 00000000000..9556aa6850a --- /dev/null +++ b/awesome_owl/static/src/todolist/todo_item.js @@ -0,0 +1,15 @@ +import { Component } from "@odoo/owl"; + +export class TodoItem extends Component { + static template = "awesome_owl.TodoItem"; + static props = { + todo: { + type: Object, + shape: { + id: Number, + description: String, + isCompleted: Boolean, + }, + }, + }; +} diff --git a/awesome_owl/static/src/todolist/todo_item.xml b/awesome_owl/static/src/todolist/todo_item.xml new file mode 100644 index 00000000000..e795d4937d3 --- /dev/null +++ b/awesome_owl/static/src/todolist/todo_item.xml @@ -0,0 +1,9 @@ + + + +
+ # + +
+
+
diff --git a/awesome_owl/static/src/todolist/todolist.js b/awesome_owl/static/src/todolist/todolist.js new file mode 100644 index 00000000000..8c8ea8c9a47 --- /dev/null +++ b/awesome_owl/static/src/todolist/todolist.js @@ -0,0 +1,29 @@ +import { Component, useState } from "@odoo/owl"; +import { TodoItem } from "./todo_item"; + +export class TodoList extends Component { + static template = "awesome_owl.TodoList"; + static components = { TodoItem }; + + setup() { + this.todos = useState([]); + } + + addTodo(ev) { + if (ev.keyCode === 13) { + const description = ev.target.value.trim(); + + if (!description) { + return; + } + + this.todos.push({ + id: this.nextId++, + description: description, + isCompleted: false, + }); + + ev.target.value = ""; + } + } +} diff --git a/awesome_owl/static/src/todolist/todolist.xml b/awesome_owl/static/src/todolist/todolist.xml new file mode 100644 index 00000000000..527788027cb --- /dev/null +++ b/awesome_owl/static/src/todolist/todolist.xml @@ -0,0 +1,17 @@ + + + +
+

My Todo List

+
+ +
+ + + +
+
+
From 96e33a02f81091dd7e8b1e2deb785c1c3d340777 Mon Sep 17 00:00:00 2001 From: "Manal El Kaidi (maelk)" Date: Fri, 29 May 2026 13:59:10 +0200 Subject: [PATCH 5/5] [IMP] awesome_owl: web framework 101 PROBLEM The playground interface was becoming cluttered and the counter logic wasn't reusable. Additionally, the framework escaped raw HTML by default, preventing rich text rendering in cards. GOAL Extract the UI into reusable components (Counter and Card) and allow secure HTML rendering using OWL's markup function. SOLUTION - Extracted counter logic from Playground into a dedicated Counter component. - Created a reusable Card component accepting 'title' and 'content' props. - Updated Card template to use 't-out' instead of 't-esc' for the content. - Imported and applied the 'markup' function in Playground to safely pass HTML to the Card. task-6254993 [IMP] awesome_owl: web framework 101