Skip to content

Commit 270300f

Browse files
committed
[ADD] awesome_owl: implement counter, card components and todo list in playground.
- Created `Counter` component in playground. - Extracted `Counter` component from playground into Counter component. - Added `<Counter/>`in template of playground to add two counters. - Created a card component and used t-esc and t-out directives to demonstrate the difference between escaped and safe HTML content using the markup function. - Added props validation to the card component - Implemented parent-child communication using a callback prop (onChange) from the Counter component to the Playground component, updating and displaying the sum in local state whenever counters are incremented. - Built a TodoList with hardcoded todos using useState, rendered each using the TodoItem component with t-foreach, and added prop validation for todo. - Updated TodoItem to conditionally apply Bootstrap classes (text-muted, text-decoration-line-through) using t-att-class based on the todo's completion status. - Enabled dynamic todo creation: replaced hardcoded todos with useState([]), added input field for user to enter a task. - Implemented addTask method to add new todos on Enter key (with unique ID and empty check).
1 parent 0f74440 commit 270300f

File tree

10 files changed

+160
-3
lines changed

10 files changed

+160
-3
lines changed

awesome_owl/static/src/card/card.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Component } from "@odoo/owl";
2+
3+
export class Card extends Component {
4+
static template = "awesome_owl.Card"
5+
static props = {
6+
title: {
7+
type: String,
8+
},
9+
content: {
10+
type: String,
11+
}
12+
}
13+
}

awesome_owl/static/src/card/card.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<templates xml:space="preserve">
3+
<t t-name="awesome_owl.Card">
4+
<div class="card d-inline-block m-2" style="width: 18rem;">
5+
<div class="card-body">
6+
<h5 class="card-title">
7+
<t t-esc="props.title"/>
8+
</h5>
9+
<p class="card-text">
10+
<t t-out="props.content"/>
11+
</p>
12+
</div>
13+
</div>
14+
</t>
15+
</templates>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Component, useState } from "@odoo/owl";
2+
3+
export class Counter extends Component {
4+
static template = "awesome_owl.Counter";
5+
static props = {
6+
title: {
7+
type: String,
8+
},
9+
onChange: {
10+
type: Function,
11+
optional: true,
12+
}
13+
}
14+
15+
setup() {
16+
this.state = useState({ value: 1 });
17+
}
18+
19+
increment() {
20+
this.state.value++;
21+
if (this.props.onChange) {
22+
this.props.onChange();
23+
}
24+
}
25+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<templates xml:space="preserve">
3+
<t t-name="awesome_owl.Counter">
4+
<div class="d-flex align-items-center border p-4 gap-4">
5+
<p class="mb-0">
6+
<t t-esc="props.title"/>: <t t-esc="state.value"></t>
7+
</p>
8+
<button class="btn btn-primary text-white" style="background: #714b67" t-on-click="increment">Increment</button>
9+
</div>
10+
</t>
11+
</templates>

awesome_owl/static/src/playground.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
11
/** @odoo-module **/
22

3-
import { Component } from "@odoo/owl";
3+
import { Component, useState, markup } from "@odoo/owl";
4+
import { Counter } from "./counter/counter";
5+
import { Card } from "./card/card";
6+
import { TodoList } from "./todo/todo_list";
47

58
export class Playground extends Component {
69
static template = "awesome_owl.playground";
10+
static components = { Counter, Card, TodoList }
11+
html = ('<h3>hello world</h3>');
12+
markup_html = markup(this.html);
13+
14+
setup() {
15+
this.state = useState({ sum: 2 });
16+
}
17+
18+
incrementSum() {
19+
this.state.sum++;
20+
}
721
}

awesome_owl/static/src/playground.xml

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

44
<t t-name="awesome_owl.playground">
5-
<div class="p-3">
6-
hello world
5+
<div class="d-flex justify-content-center">
6+
<div class="border m-5">
7+
<div class="d-flex gap-4 p-3" style="max-width: fit-content;">
8+
<Counter title="'Counter 1'" onChange.bind="incrementSum"/>
9+
<Counter title="'Counter 2'" onChange.bind="incrementSum"/>
10+
</div>
11+
<p class="ms-3">Sum is: <t t-esc="state.sum"></t></p>
12+
</div>
13+
14+
<!-- Card Component -->
15+
<div class="p-3 border m-5" style="max-width: fit-content;">
16+
<h1>Cards</h1>
17+
<div class="d-flex gap-3">
18+
<Card title="'Gandhinagar'" content="html"/>
19+
<Card title="'Ahmedabad'" content="markup_html"/>
20+
</div>
21+
</div>
22+
</div>
23+
24+
<!-- Todo List Component -->
25+
<div class="mt-5">
26+
<TodoList/>
727
</div>
828
</t>
929

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Component, useState } from "@odoo/owl";
2+
3+
export class TodoItem extends Component {
4+
static template = "awesome_owl.TodoItem";
5+
static props = {
6+
todo: {
7+
type: Object,
8+
shape: {
9+
id: Number,
10+
description: String,
11+
isCompleted: Boolean,
12+
}
13+
},
14+
}
15+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<templates xml:space="preserve">
3+
<t t-name="awesome_owl.TodoItem">
4+
<div class="d-flex mb-1" t-att-class="{'text-muted text-decoration-line-through': props.todo.isCompleted}">
5+
<span><t t-esc="props.todo.id"></t>.</span>
6+
<span class="ms-1"><t t-esc="props.todo.description"></t></span>
7+
</div>
8+
</t>
9+
</templates>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Component, useState } from "@odoo/owl";
2+
import { TodoItem } from "./todo_item";
3+
4+
export class TodoList extends Component {
5+
static template = "awesome_owl.TodoList"
6+
static components = { TodoItem }
7+
id = 1;
8+
9+
setup () {
10+
this.todos = useState([]);
11+
}
12+
13+
addTask(event) {
14+
const { target: { value }, keyCode } = event;
15+
if (keyCode != 13 || !value.trim()) return;
16+
this.todos.push({
17+
id: this.id++,
18+
description: value,
19+
isCompleted: false,
20+
});
21+
event.target.value = '';
22+
}
23+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<templates xml:space="preserve">
3+
<t t-name="awesome_owl.TodoList">
4+
<div class="border p-2 m-5" style="width: 400px;">
5+
<h3 class="mb-3">Todo List</h3>
6+
<input id="task-entry" placeholder="Enter a new task" class="form-control" t-on-keyup="addTask"></input>
7+
<t t-foreach="todos" t-as="todo" t-key="todo.id">
8+
<TodoItem todo="todo"/>
9+
</t>
10+
</div>
11+
</t>
12+
</templates>

0 commit comments

Comments
 (0)