Skip to content

Commit 8787087

Browse files
committed
[ADD] awesome_owl: add a small view with a counter and a todolist.
This module contains a view with a simple todo list and a counter with also the components used to make them.
1 parent dd31619 commit 8787087

File tree

12 files changed

+186
-3
lines changed

12 files changed

+186
-3
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Component, useState } from "@odoo/owl";
2+
3+
export class Card extends Component {
4+
static template = "awesome_owl.card";
5+
static props = {
6+
title: String,
7+
slots: Object,
8+
}
9+
10+
setup() {
11+
this.state = useState({ isOpen: true });
12+
}
13+
14+
toggle() {
15+
this.state.isOpen = !this.state.isOpen;
16+
}
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<templates xml:space="preserve">
3+
4+
<t t-name="awesome_owl.card">
5+
<div class="card d-inline-block m-2" style="width: 18rem;">
6+
<div class="card-body">
7+
<h5 class="card-title">
8+
<t t-esc="props.title"/>
9+
<button class="btn" t-on-click="toggle">Toggle</button>
10+
</h5>
11+
<p class="card-text" t-if="this.state.isOpen">
12+
<t t-slot="default"/>
13+
</p>
14+
</div>
15+
</div>
16+
</t>
17+
</templates>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Component, useState } from "@odoo/owl";
2+
3+
export class Counter extends Component {
4+
static template = "awesome_owl.Counter";
5+
static props = {
6+
callback: {
7+
type: Function,
8+
optional: true,
9+
},
10+
};
11+
12+
setup() {
13+
this.state = useState({ value: 0 });
14+
}
15+
16+
increment() {
17+
this.state.value++;
18+
this.props.callback?.();
19+
}
20+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<templates xml:space="preserve">
3+
4+
<t t-name="awesome_owl.Counter">
5+
<div class="card text-center">
6+
<div class="card-body">
7+
<h5 class="card-title">Counter</h5>
8+
<p class="card-text display-4"><t t-esc="state.value"/></p>
9+
<button class="btn btn-primary" t-on-click="increment">Increment</button>
10+
</div>
11+
</div>
12+
</t>
13+
14+
</templates>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
/** @odoo-module **/
22

33
import { Component } from "@odoo/owl";
4+
import { TodoList } from "./todolist/todolist";
5+
import { Card } from "./card/card";
6+
import { Counter } from "./counter/counter";
47

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

awesome_owl/static/src/playground.xml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
<templates xml:space="preserve">
33

44
<t t-name="awesome_owl.playground">
5-
<div class="p-3">
6-
hello world
7-
</div>
5+
<Card title="'My Todo List'">
6+
<TodoList/>
7+
</Card>
8+
<Card title="'My Counter'">
9+
<Counter/>
10+
</Card>
811
</t>
912

1013
</templates>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export class Todo {
2+
constructor(id, description) {
3+
this.id = id;
4+
this.description = description;
5+
this.isCompleted = false;
6+
}
7+
8+
setIsCompleted(isCompleted) {
9+
this.isCompleted = isCompleted;
10+
}
11+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Component } from "@odoo/owl";
2+
import { Todo } from "./todo";
3+
4+
export class TodoItem extends Component {
5+
static template = "awesome_owl.todoitem";
6+
static props = {
7+
todo: Todo,
8+
toggleState: Function,
9+
removeTodo: Function,
10+
};
11+
12+
onChange() {
13+
this.props.toggleState(this.props.todo.id);
14+
}
15+
16+
onRemove() {
17+
this.props.removeTodo(this.props.todo.id);
18+
}
19+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<templates xml:space="preserve">
3+
4+
<t t-name="awesome_owl.todoitem">
5+
<div class="d-flex align-items-center mb-2">
6+
<input class="form-check-input me-2" type="checkbox" t-att-id="props.todo.id" t-on-change="onChange" t-att-checked="props.todo.isCompleted"/>
7+
<p class="mb-0" t-att-class="{'text-muted text-decoration-line-through': props.todo.isCompleted}">
8+
<t t-esc="props.todo.id"/>. <t t-esc="props.todo.description"/>
9+
</p>
10+
<span role="button" class="fa fa-remove ms-3 text-danger" t-on-click="onRemove"/>
11+
</div>
12+
</t>
13+
14+
</templates>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/** @odoo-module **/
2+
3+
import { Component, useState } from "@odoo/owl";
4+
import { TodoItem } from "./todoitem";
5+
import { Todo } from "./todo";
6+
import { useAutofocus } from "../utils";
7+
8+
export class TodoList extends Component {
9+
static template = "awesome_owl.todolist";
10+
static components = { TodoItem };
11+
12+
setup() {
13+
this.todos = useState([]);
14+
this.sequence = 0;
15+
useAutofocus("new-todo");
16+
}
17+
18+
addTodo(event) {
19+
if (event.keyCode === 13 && event.target.value.trim() !== "") {
20+
this.sequence++;
21+
this.todos.push(new Todo(this.sequence, event.target.value));
22+
event.target.value = "";
23+
}
24+
}
25+
26+
toggleState(id) {
27+
const todo = this.todos.find(t => t.id === id);
28+
if (todo) todo.setIsCompleted(!todo.isCompleted);
29+
}
30+
31+
removeTodo(id) {
32+
const index = this.todos.findIndex((elem) => elem.id === id);
33+
if (index !== -1) this.todos.splice(index, 1);
34+
}
35+
}

0 commit comments

Comments
 (0)