mirror of
https://github.com/SARL-PACIFIC-ERP/odoo-sh-test.git
synced 2025-06-25 17:42:22 +00:00
Compare commits
5 commits
f61a5c1ed6
...
38c8de3804
Author | SHA1 | Date | |
---|---|---|---|
|
38c8de3804 | ||
|
7fd092b926 | ||
|
6962f20029 | ||
|
1a7973ad13 | ||
|
9dbb08d17e |
3
awesome_owl/__init__.py
Normal file
3
awesome_owl/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import controllers
|
51
awesome_owl/__manifest__.py
Normal file
51
awesome_owl/__manifest__.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# -*- 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/AwesomeOwl',
|
||||||
|
'version': '0.1',
|
||||||
|
|
||||||
|
# any module necessary for this one to work correctly
|
||||||
|
'depends': ['base', 'web'],
|
||||||
|
'application': True,
|
||||||
|
'installable': True,
|
||||||
|
'data': [
|
||||||
|
'views/templates.xml',
|
||||||
|
],
|
||||||
|
'assets': {
|
||||||
|
'awesome_owl.assets_playground': [
|
||||||
|
# bootstrap
|
||||||
|
('include', 'web._assets_helpers'),
|
||||||
|
'web/static/src/scss/pre_variables.scss',
|
||||||
|
'web/static/lib/bootstrap/scss/_variables.scss',
|
||||||
|
('include', 'web._assets_bootstrap_backend'),
|
||||||
|
|
||||||
|
# required for fa icons
|
||||||
|
'web/static/src/libs/fontawesome/css/font-awesome.css',
|
||||||
|
|
||||||
|
# include base files from framework
|
||||||
|
('include', 'web._assets_core'),
|
||||||
|
|
||||||
|
'web/static/src/core/utils/functions.js',
|
||||||
|
'web/static/src/core/browser/browser.js',
|
||||||
|
'web/static/src/core/registry.js',
|
||||||
|
'web/static/src/core/assets.js',
|
||||||
|
'awesome_owl/static/src/**/*',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'license': 'AGPL-3'
|
||||||
|
}
|
3
awesome_owl/controllers/__init__.py
Normal file
3
awesome_owl/controllers/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import controllers
|
10
awesome_owl/controllers/controllers.py
Normal file
10
awesome_owl/controllers/controllers.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from odoo import http
|
||||||
|
from odoo.http import request, route
|
||||||
|
|
||||||
|
class OwlPlayground(http.Controller):
|
||||||
|
@http.route(['/awesome_owl'], type='http', auth='public')
|
||||||
|
def show_playground(self):
|
||||||
|
"""
|
||||||
|
Renders the owl playground page
|
||||||
|
"""
|
||||||
|
return request.render('awesome_owl.playground')
|
8
awesome_owl/static/src/card/card.js
Normal file
8
awesome_owl/static/src/card/card.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/** @odoo-module **/
|
||||||
|
|
||||||
|
import { Component, useState } from "@odoo/owl";
|
||||||
|
|
||||||
|
export class Card extends Component {
|
||||||
|
static template = "awesome_owl.card";
|
||||||
|
static props = ['title', 'content'];
|
||||||
|
}
|
17
awesome_owl/static/src/card/card.xml
Normal file
17
awesome_owl/static/src/card/card.xml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<templates xml:space="preserve">
|
||||||
|
|
||||||
|
<t t-name="awesome_owl.card">
|
||||||
|
<section>
|
||||||
|
<div class="card d-inline-block m-2" style="width: 18rem;">
|
||||||
|
<div class="card-body">
|
||||||
|
<h3 class="card-title"><t t-esc="props.title"/></h3>
|
||||||
|
<p class="card-text">
|
||||||
|
<t t-esc="props.content"/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</t>
|
||||||
|
|
||||||
|
</templates>
|
21
awesome_owl/static/src/counter/counter.js
Normal file
21
awesome_owl/static/src/counter/counter.js
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
awesome_owl/static/src/counter/counter.xml
Normal file
12
awesome_owl/static/src/counter/counter.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<templates xml:space="preserve">
|
||||||
|
|
||||||
|
<t t-name="awesome_owl.counter">
|
||||||
|
<section>
|
||||||
|
<h2>Counter</h2>
|
||||||
|
<p>Counter: <t t-esc="state.value"/></p>
|
||||||
|
<button class="btn btn-primary" t-on-click="increment">Increment</button>
|
||||||
|
</section>
|
||||||
|
</t>
|
||||||
|
|
||||||
|
</templates>
|
41
awesome_owl/static/src/main.js
Normal file
41
awesome_owl/static/src/main.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/** @odoo-module **/
|
||||||
|
|
||||||
|
import { browser } from "@web/core/browser/browser";
|
||||||
|
import { mount, whenReady } from "@odoo/owl";
|
||||||
|
import { Playground } from "./playground";
|
||||||
|
import { templates } from "@web/core/assets";
|
||||||
|
|
||||||
|
// Mount the Playground component when the document.body is ready
|
||||||
|
whenReady( () => {
|
||||||
|
mount(Playground, document.body, { templates, dev: true, name: "Owl Tutorial" });
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This code is iterating over the cause property of an error object to console.error a string
|
||||||
|
* containing the stack trace of the error and any errors that caused it.
|
||||||
|
* @param {Event} ev
|
||||||
|
*/
|
||||||
|
function logError(ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
let error = ev ?.error || ev.reason;
|
||||||
|
|
||||||
|
if (error.seen) {
|
||||||
|
// If an error causes the mount to crash, Owl will reject the mount promise and throw the
|
||||||
|
// error. Therefore, this if statement prevents the same error from appearing twice.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
error.seen = true;
|
||||||
|
|
||||||
|
let errorMessage = error.stack;
|
||||||
|
while (error.cause) {
|
||||||
|
errorMessage += "\nCaused by: "
|
||||||
|
errorMessage += error.cause.stack;
|
||||||
|
error = error.cause;
|
||||||
|
}
|
||||||
|
console.error(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
browser.addEventListener("error", (ev) => {logError(ev)});
|
||||||
|
browser.addEventListener("unhandledrejection", (ev) => {logError(ev)});
|
19
awesome_owl/static/src/playground.js
Normal file
19
awesome_owl/static/src/playground.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/** @odoo-module **/
|
||||||
|
|
||||||
|
import { Component, useState } from "@odoo/owl";
|
||||||
|
import { Counter } from "./counter/counter";
|
||||||
|
import { Card } from "./card/card";
|
||||||
|
import { TodoList } from "./todo_list/todo_list";
|
||||||
|
|
||||||
|
export class Playground extends Component {
|
||||||
|
static template = "awesome_owl.playground";
|
||||||
|
static components = { Counter, Card, TodoList };
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
this.sum = useState({value: 0});
|
||||||
|
}
|
||||||
|
|
||||||
|
incrementSum(){
|
||||||
|
this.sum.value++;
|
||||||
|
}
|
||||||
|
}
|
15
awesome_owl/static/src/playground.xml
Normal file
15
awesome_owl/static/src/playground.xml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<templates xml:space="preserve">
|
||||||
|
|
||||||
|
<t t-name="awesome_owl.playground">
|
||||||
|
<Counter onChange.bind="incrementSum"/>
|
||||||
|
<Counter onChange.bind="incrementSum"/>
|
||||||
|
<p>The sum is <t t-esc="sum.value"/></p>
|
||||||
|
<hr />
|
||||||
|
<Card title="'Card 1'" content="'This is the awesome content of the card 1'" />
|
||||||
|
<Card title="'Card, the 2nd'" content="'Here is another card content. It is the second one.'" />
|
||||||
|
<hr/>
|
||||||
|
<TodoList />
|
||||||
|
</t>
|
||||||
|
|
||||||
|
</templates>
|
18
awesome_owl/static/src/todo_list/todo_item.js
Normal file
18
awesome_owl/static/src/todo_list/todo_item.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/** @odoo-module **/
|
||||||
|
|
||||||
|
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 }
|
||||||
|
},
|
||||||
|
onToggle: Function,
|
||||||
|
};
|
||||||
|
|
||||||
|
toggle() {
|
||||||
|
this.props.onToggle(this.props.todo.id);
|
||||||
|
}
|
||||||
|
}
|
12
awesome_owl/static/src/todo_list/todo_item.xml
Normal file
12
awesome_owl/static/src/todo_list/todo_item.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<templates xml:space="preserve">
|
||||||
|
<t t-name="awesome_owl.TodoItem">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" t-att-id="props.todo.id" t-att-checked="props.todo.isCompleted" t-on-change="toggle"/>
|
||||||
|
<label t-att-for="props.todo.id" t-att-class="props.todo.isCompleted ? 'text-decoration-line-through text-muted' : '' ">
|
||||||
|
<t t-esc="props.todo.id"/>.
|
||||||
|
<t t-esc="props.todo.description"/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</templates>
|
34
awesome_owl/static/src/todo_list/todo_list.js
Normal file
34
awesome_owl/static/src/todo_list/todo_list.js
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/** @odoo-module **/
|
||||||
|
|
||||||
|
import { Component, useState } from "@odoo/owl";
|
||||||
|
import { TodoItem } from "./todo_item";
|
||||||
|
import "../utils.js";
|
||||||
|
import { useAutofocus } from "../utils.js";
|
||||||
|
|
||||||
|
export class TodoList extends Component {
|
||||||
|
static template = "awesome_owl.todo_list";
|
||||||
|
static components = { TodoItem };
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
this.todos = useState([]);
|
||||||
|
useAutofocus('todo_input');
|
||||||
|
}
|
||||||
|
|
||||||
|
addTodo(ev) {
|
||||||
|
// If the key was enter and input isn't empty
|
||||||
|
if(ev.keyCode === 13) {
|
||||||
|
if(ev.target.value !== '') {
|
||||||
|
// Let's create a todo
|
||||||
|
this.todos.push({ id: this.todos.length+1, description: ev.target.value, isCompleted: false });
|
||||||
|
ev.target.value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleState(id) {
|
||||||
|
const todo = this.todos.find((obj) => obj.id === id);
|
||||||
|
if (todo) {
|
||||||
|
todo.isCompleted = !todo.isCompleted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
awesome_owl/static/src/todo_list/todo_list.xml
Normal file
11
awesome_owl/static/src/todo_list/todo_list.xml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<templates xml:space="preserve">
|
||||||
|
<t t-name="awesome_owl.todo_list">
|
||||||
|
<p><input t-ref="todo_input" type="text" name="new-todo" placeholder="Add new todo" t-on-keyup="addTodo" /></p>
|
||||||
|
<div class="d-inline-block border p-2 m-2">
|
||||||
|
<t t-foreach="todos" t-as="todo" t-key="todo.id">
|
||||||
|
<TodoItem todo="todo" onToggle.bind="toggleState"/>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</templates>
|
10
awesome_owl/static/src/utils.js
Normal file
10
awesome_owl/static/src/utils.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
/** @odoo-module */
|
||||||
|
|
||||||
|
import { useRef, onMounted } from "@odoo/owl";
|
||||||
|
|
||||||
|
export function useAutofocus(name) {
|
||||||
|
const ref = useRef(name);
|
||||||
|
onMounted(() => {
|
||||||
|
ref.el.focus();
|
||||||
|
});
|
||||||
|
}
|
15
awesome_owl/views/templates.xml
Normal file
15
awesome_owl/views/templates.xml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<template id="awesome_owl.playground" name="Awesome T-Shirt thank you">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link type="image/x-icon" rel="shortcut icon" href="/web/static/img/favicon.ico"/>
|
||||||
|
<t t-call-assets="awesome_owl.assets_playground"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</template>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
Loading…
Reference in a new issue