Skip to content

18.0 Web Framework Tutorials (mbec) #803

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: 18.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d3e64a8
[ADD] awesome_owl: Made Playground a counter
Backendt May 23, 2025
0dd1fe8
[ADD] awesome_owl: Added Counter component
Backendt May 23, 2025
967816b
[ADD] awesome_owl: Added Card component
Backendt May 23, 2025
c7cd317
[ADD] awesome_owl: Made card fields markupable
Backendt May 23, 2025
50a34fe
[ADD] awesome_owl: Added props validation on Card component
Backendt May 23, 2025
96adfed
[FIX] awesome_owl: Removed the invalid Card
Backendt May 23, 2025
b7bd6ee
[ADD] awesome_owl: Added a sum of counters
Backendt May 23, 2025
13e6dd1
[ADD] awesome_owl: Added Todo list
Backendt May 23, 2025
fa2bec9
[ADD] awesome_owl: Displayed completed todo items
Backendt May 23, 2025
ab3a537
[ADD] awesome_owl: Added todo input
Backendt May 23, 2025
c151c0a
[ADD] awesome_owl: Auto focused the todolist input
Backendt May 26, 2025
1fc2fd2
[ADD] awesome_owl: Added completion checkbox to todos
Backendt May 26, 2025
883657b
[ADD] awesome_owl: Added remove button to todo items
Backendt May 27, 2025
5127c60
[ADD] awesome_owl: Added card slots
Backendt May 27, 2025
637889e
[FIX] awesome_owl: Fixed error when counter doesnt have a onChange at…
Backendt May 27, 2025
160427b
[ADD] awesome_owl: Added Toggle button to cards
Backendt May 28, 2025
027240c
[ADD] awesome_dashboard: Added Layout to dashboard
Backendt May 28, 2025
da6d58e
[ADD] awesome_dashboard: Added Customer and Lead buttons to dashboard
Backendt May 30, 2025
f9c56c2
[ADD] awesome_dashboard: Added DashboardItem
Backendt May 30, 2025
8f94a9e
[ADD] awesome_dashboard: Added statistics
Backendt May 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion awesome_dashboard/static/src/dashboard.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,42 @@
/** @odoo-module **/

import { Component } from "@odoo/owl";
import { Component, onWillStart } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { Layout } from "@web/search/layout";
import { useService } from "@web/core/utils/hooks";
import { DashboardItem } from "./dashboard_item/dashboard_item.js";
import { rpc } from "@web/core/network/rpc";

class AwesomeDashboard extends Component {
static template = "awesome_dashboard.AwesomeDashboard";
static components = { Layout, DashboardItem };

setup() {
this.display = {
controlPanel: {}
};
this.action = useService("action");

onWillStart(async () => {
this.statistics = await rpc("/awesome_dashboard/statistics");
});
}

openCustomerView() {
this.action.doAction("base.action_partner_form");
}

openLeadView() {
this.action.doAction({
type: "ir.actions.act_window",
name: "Leads",
res_model: "crm.lead",
views: [
[false, "list"],
[false, "form"]
]
});
}
}

registry.category("actions").add("awesome_dashboard.dashboard", AwesomeDashboard);
3 changes: 3 additions & 0 deletions awesome_dashboard/static/src/dashboard.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.o_dashboard {
background-color: grey;
}
27 changes: 26 additions & 1 deletion awesome_dashboard/static/src/dashboard.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,32 @@
<templates xml:space="preserve">

<t t-name="awesome_dashboard.AwesomeDashboard">
hello dashboard
<Layout display="display" className="'o_dashboard h-100'">
<button t-on-click="openCustomerView">Customers</button>
<button t-on-click="openLeadView">Leads</button>
<div class="d-flex flex-warp">
<DashboardItem>
<p>New orders this month</p>
<t t-esc="statistics.nb_new_orders"/>
</DashboardItem>
<DashboardItem size="1.5">
<p>Total new orders</p>
<t t-esc="statistics.total_amount"/>
</DashboardItem>
<DashboardItem>
<p>Average monthly orders</p>
<t t-esc="statistics.average_quantity"/>
</DashboardItem>
<DashboardItem>
<p>Orders cancelled this month</p>
<t t-esc="statistics.nb_cancelled_orders"/>
</DashboardItem>
<DashboardItem>
<p>Average order processing time</p>
<t t-esc="statistics.average_time"/>
</DashboardItem>
</div>
</Layout>
</t>

</templates>
18 changes: 18 additions & 0 deletions awesome_dashboard/static/src/dashboard_item/dashboard_item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Component } from "@odoo/owl";

export class DashboardItem extends Component {
static template = "awesome_dashboard.DashboardItem";
static props = {
slots: {
type: Object,
shape: {
default: true
}
},
size: {
type: Number,
default: 1,
optional: true
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="awesome_dashboard.DashboardItem">
<div class="border" t-attf-style="width: {{18*props.size}}rem;">
<t t-slot="default"/>
</div>
</t>
</templates>
25 changes: 25 additions & 0 deletions awesome_owl/static/src/card/card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/** @odoo-module **/

import { Component, useState } from "@odoo/owl";

export class Card extends Component {
static template = "awesome_owl.card";
static props = {
title: String,
slots: {
type: Object,
shape: {
default: true
}
}
};

setup() {
this.state = useState({displayed: false});
}

toggleDisplay() {
this.state.displayed = !this.state.displayed;
}

}
11 changes: 11 additions & 0 deletions awesome_owl/static/src/card/card.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_owl.card">
<div class="p-3 border">
<h3><t t-out="props.title"/><button t-on-click="toggleDisplay">Toggle</button></h3>
<t t-if="state.displayed" t-slot="default"/>
</div>
</t>

</templates>
21 changes: 21 additions & 0 deletions awesome_owl/static/src/counter/counter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/** @odoo-module **/

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});
}

increment() {
this.state.value++;
if(this.props.onChange) {
this.props.onChange();
}
}
}
11 changes: 11 additions & 0 deletions awesome_owl/static/src/counter/counter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_owl.counter">
<div class="p-3">
<p>Counter: <t t-esc="state.value"></t></p>
<button t-on-click="increment">Increment</button>
</div>
</t>

</templates>
20 changes: 19 additions & 1 deletion awesome_owl/static/src/playground.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
/** @odoo-module **/

import { Component } from "@odoo/owl";
import { Component, markup, useState } from "@odoo/owl";
import { Counter } from "./counter/counter.js";
import { Card } from "./card/card.js";
import { TodoList } from "./todo/todo_list.js";

export class Playground extends Component {
static template = "awesome_owl.playground";
static components = { Counter, Card, TodoList };

raw_card_title = "<u>Hello</u>";
raw_card_text = "<u>World</u>";

card_title = markup(this.raw_card_title);
card_text = markup(this.raw_card_text);

setup() {
this.state = useState({counter_sum: 2});
}

incrementSum() {
this.state.counter_sum++;
}
}
16 changes: 15 additions & 1 deletion awesome_owl/static/src/playground.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,22 @@
<templates xml:space="preserve">

<t t-name="awesome_owl.playground">
<div class="p-3 border">
<h2>Sum: <t t-esc="state.counter_sum"/></h2>
<Counter onChange.bind="incrementSum"/>
<Counter onChange.bind="incrementSum"/>
</div>
<div class="p-3">
hello world
<Counter/>
<Card title="raw_card_title">
<Counter/>
</Card>
<Card title="card_title">
<p>Lorem ipsum</p>
</Card>
</div>
<div>
<TodoList/>
</div>
</t>

Expand Down
27 changes: 27 additions & 0 deletions awesome_owl/static/src/todo/todo_item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/** @odoo-module **/

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
}
},
removeFromList: Function
};

toggleState() {
this.props.todo.isCompleted = !this.props.todo.isCompleted;
}

removeTodo() {
let todoId = this.props.todo.id;
this.props.removeFromList(todoId);
}
}
12 changes: 12 additions & 0 deletions awesome_owl/static/src/todo/todo_item.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_owl.todo_item">
<div t-att-class="{'text-muted text-decoration-line-through': props.todo.isCompleted}">
<input type="checkbox" t-att-checked="props.todo.isCompleted" t-on-change="toggleState"/>
<t t-esc="props.todo.id"/>. <t t-esc="props.todo.description"/>
<span class="fa fa-remove" t-on-click="removeTodo"/>
</div>
</t>

</templates>
42 changes: 42 additions & 0 deletions awesome_owl/static/src/todo/todo_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/** @odoo-module **/

import { Component, useState, useRef, onMounted } from "@odoo/owl";
import { TodoItem } from "./todo_item.js";

export class TodoList extends Component {
static template = "awesome_owl.todo_list";
static components = { TodoItem };

lastId = 1;

setup() {
this.todos = useState([]);
this.inputRef = useRef("todo_input");
onMounted(() => {
this.inputRef.el.focus();
});
}

addTodo(event) {
const enterKeycode = 13;
if(event.keyCode !== enterKeycode || event.target.value == '') {
return;
}

let newTodo = {
id: this.lastId++,
description: event.target.value,
isCompleted: false
};

this.todos.push(newTodo);
event.target.value = '';
}

removeFromList(todoId) {
let index = this.todos.findIndex(todo => todo.id === todoId);
if(index > -1) {
this.todos.splice(index, 1);
}
}
}
13 changes: 13 additions & 0 deletions awesome_owl/static/src/todo/todo_list.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_owl.todo_list">
<input t-ref="todo_input" type="text" class="form-control" placeholder="Enter a new task" t-on-keyup="addTodo"/>
<div class="p-3">
<t t-foreach="todos" t-as="todo" t-key="todo.id">
<TodoItem todo="todo" removeFromList.bind="removeFromList"/>
</t>
</div>
</t>

</templates>