Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 1 addition & 3 deletions awesome_owl/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
# -*- coding: utf-8 -*-

from . import controllers
from . import controllers
12 changes: 4 additions & 8 deletions awesome_owl/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
# -*- coding: utf-8 -*-
{
'name': "Awesome Owl",

'summary': """
Starting module for "Discover the JS framework, chapter 1: Owl components"
""",

'description': """
Starting module for "Discover the JS framework, chapter 1: Owl components"
""",

'author': "Odoo",
'website': "https://www.odoo.com",

# Categories can be used to filter modules in modules listing
# Check https://github.com/odoo/odoo/blob/15.0/odoo/addons/base/data/ir_module_category_data.xml
# for the full list
'category': 'Tutorials',
'version': '0.1',

# any module necessary for this one to work correctly
'depends': ['base', 'web'],
'application': True,
Expand All @@ -36,8 +30,10 @@
('include', 'web._assets_bootstrap'),
('include', 'web._assets_core'),
'web/static/src/libs/fontawesome/css/font-awesome.css',
'awesome_owl/static/src/**/*',
'awesome_owl/static/src/**/*.js',
'awesome_owl/static/src/**/*.xml',
'awesome_owl/static/src/**/*.scss',
],
},
'license': 'AGPL-3'
'license': 'AGPL-3',
}
4 changes: 1 addition & 3 deletions awesome_owl/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
# -*- coding: utf-8 -*-

from . import controllers
from . import controllers
5 changes: 3 additions & 2 deletions awesome_owl/controllers/controllers.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from odoo import http
from odoo.http import request, route


class OwlPlayground(http.Controller):
@http.route(['/awesome_owl'], type='http', auth='public')
@http.route(['/awesome_owl/playground'], type='http', auth='user')
def show_playground(self):
"""
Renders the owl playground page
"""
return request.render('awesome_owl.playground')
return request.render('awesome_owl.playground_template')
18 changes: 18 additions & 0 deletions awesome_owl/static/src/card/card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Component, useState } from "@odoo/owl";

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

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

flipCard() {
console.log("Flipping card");
this.state.flipped = !this.state.flipped;
}
}
16 changes: 16 additions & 0 deletions awesome_owl/static/src/card/card.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">

<t t-name="awesome_owl.card">
<div class="card d-inline-block m-2" style="width: 18rem;" t-on-click="flipCard">
<div class="card-body" t-if="!state.flipped">
<h5 class="card-title" t-if="props.title" t-esc="props.title" />
<t t-slot="default"/>
</div>
<div class="card-body" t-else="">
<p class="text-muted">Card is flipped! Click to flip back.</p>
</div>
</div>
</t>

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

export class Counter extends Component {
static template = "awesome_owl.counter";


setup() {
this.state = useState({ value: 0 });
}

increment() {
this.state.value++;
this.props.onChange();
}
}
12 changes: 12 additions & 0 deletions awesome_owl/static/src/counter/counter.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.counter">
<div class="counter p-2 border rounded">
<p>Counter: <t t-esc="state.value"/>
</p>
<button class="btn btn-primary" t-on-click="increment">Increment</button>
</div>
</t>

</templates>
2 changes: 1 addition & 1 deletion awesome_owl/static/src/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { whenReady } from "@odoo/owl";
import { mountComponent } from "@web/env";
import { Playground } from "./playground";
import { Playground } from "./Playground";

const config = {
dev: true,
Expand Down
37 changes: 37 additions & 0 deletions awesome_owl/static/src/owl_test.xml.bk
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!-- <?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="awesome_owl.OwlTest">
<div class="owl-test p-4">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h3 class="mb-0">
<i class="fa fa-magic me-2"/>Awesome Owl Framework Test
</h3>
</div>
<div class="card-body">
<div class="alert alert-info mb-4">
<i class="fa fa-info-circle me-2"/>
<strong t-esc="state.message"/>
</div>

<div class="text-center mb-4">
<h1 class="display-1 fw-bold text-primary" t-esc="state.counter"/>
<p class="text-muted">Current Counter Value</p>
</div>

<div class="d-flex gap-2 justify-content-center">
<button class="btn btn-success btn-lg" t-on-click="increment">
<i class="fa fa-plus me-2"/>Increment
</button>
<button class="btn btn-danger btn-lg" t-on-click="decrement">
<i class="fa fa-minus me-2"/>Decrement
</button>
<button class="btn btn-secondary btn-lg" t-on-click="reset">
<i class="fa fa-refresh me-2"/>Reset
</button>
</div>
</div>
</div>
</div>
</t>
</templates> -->
17 changes: 15 additions & 2 deletions awesome_owl/static/src/playground.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
import { Component } from "@odoo/owl";
import { Component, useState } from "@odoo/owl";
import { Counter } from "./counter/counter";
import { Card } from "./card/card";
import { TodoItem } from "./todo_item/todo_item";
import { TodoList } from "./todo_list/todo_list";

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

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

incrementSum() {
this.state.sum++;
}
}
22 changes: 19 additions & 3 deletions awesome_owl/static/src/playground.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">

<t t-name="awesome_owl.playground">
<div class="p-3">
hello world
<h1>Hello Owl Playground!</h1>
<p>Sum: <t t-esc="state.sum"/>
</p>
<div class="d-flex gap-3 flex-wrap">
<Card title="'Counter Card'">
<Counter onChange.bind="incrementSum"/>
</Card>
<Card title="'Multiple Counters'">
<Counter/>
<Counter/>
</Card>
<Card>
<p class="card-text">This is a card with custom content!</p>
<button class="btn btn-success">Click me</button>
</Card>
<TodoList/>
</div>
</div>
</t>

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

export class TodoItem extends Component {
static template = "awesome_owl.todo_item";
static props = {
id: Number,
text: String,
isCompleted: Boolean,
onToggle: { type: Function, optional: true },
onRemove: { type: Function, optional: true },
};

toggleCompletion() {
console.log("Toggling completion for todo id:", this.props.id);
if (this.props.onToggle) {
console.log("Calling onToggle for todo id:", this.props.id);
this.props.onToggle(this.props.id);
}
}
removeItem(){
if (this.props.onRemove) {
this.props.onRemove(this.props.id);
}
}
}
12 changes: 12 additions & 0 deletions awesome_owl/static/src/todo_item/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 class="d-flex flex-row align-items-center gap-2 mb-2 p-2 border" t-attf-class="{{props.isCompleted ? 'bg-success' : ''}}">
<input type="checkbox" t-att-checked="props.isCompleted" t-on-change="toggleCompletion" />
<div t-esc="props.text" t-attf-class="{{props.isCompleted ? 'text-decoration-line-through' : ''}}"/>
<button class="btn btn-sm btn-danger bg-danger text-white ms-auto" t-on-click="removeItem">X</button>
</div>
</t>

</templates>
45 changes: 45 additions & 0 deletions awesome_owl/static/src/todo_list/todo_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Component, useState, useRef, onMounted } from "@odoo/owl";
import { TodoItem } from "../todo_item/todo_item";
export class TodoList extends Component {
static template = "awesome_owl.todo_list";
static components = { TodoItem };

setup() {
this.todoListRef = useRef("todo_list");
this.todoInputRef = useRef("new_todo_input");
onMounted(() => {
this.todoInputRef.el.focus();
});
this.state = useState({
todos: [
],
newTodoText: "",
});
}
addTodo() {
if (this.state.newTodoText.trim() === "") {
return;
}
const newTodo = {
id: Date.now(),
text: this.state.newTodoText,
isCompleted: false,
};
this.state.todos.push(newTodo);
this.state.newTodoText = "";
this.todoListRef.el.style.backgroundColor = 'white';
}
toggleTodo(todoId) {
const todo = this.state.todos.find(t => t.id === todoId);
if (todo) {
todo.isCompleted = !todo.isCompleted;
}
//change the color of the list
this.todoListRef.el.style.backgroundColor = this.state.todos.every(t => t.isCompleted) ? 'lightgreen' : 'white';
}
onRemoveTodo(todoId) {
this.state.todos = this.state.todos.filter(t => t.id !== todoId);
//change the color of the list
this.todoListRef.el.style.backgroundColor = (this.state.todos.every(t => t.isCompleted) && this.state.todos.length > 0) ? 'lightgreen' : 'white';
}
}
24 changes: 24 additions & 0 deletions awesome_owl/static/src/todo_list/todo_list.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">

<t t-name="awesome_owl.todo_list">
<h1>Hello Owl Playground!</h1>

<div class="card d-inline-block m-2" style="width: 18rem;">
<div class="card-body" t-ref="todo_list">
<form t-on-submit.prevent="addTodo">
<input type="text" t-model="state.newTodoText" placeholder="New todo" t-ref="new_todo_input"/>
<button type="submit" class="btn btn-primary mt-2">Add Todo</button>
</form>

<div class="d-flex flex-column">
<t t-foreach="state.todos" t-as="todo" t-key="todo.id">
<TodoItem t-props="todo" onToggle.bind="toggleTodo" onRemove.bind="onRemoveTodo" />
</t>
</div>
</div>
</div>

</t>

</templates>
14 changes: 12 additions & 2 deletions awesome_owl/views/templates.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<odoo>
<data>
<template id="awesome_owl.playground" name="Awesome T-Shirt thank you">
<template id="playground_template" name="Awesome Owl Playground">
<html>
<head>
<link type="image/x-icon" rel="shortcut icon" href="/web/static/img/favicon.ico"/>
Expand All @@ -10,6 +10,16 @@
<body>
</body>
</html>
</template>
</template>

<record id="action_owl_playground" model="ir.actions.act_url">
<field name="name">Owl Framework Test</field>
<field name="url">/awesome_owl/playground</field>
<field name="target">self</field>
</record>
<menuitem id="menu_owl_test"
name="Owl Test"
action="action_owl_playground"
sequence="100"/>
</data>
</odoo>