Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3c4ec5c
[REF] Internal: test setup dalio
dalio-odoo Apr 21, 2026
46f010c
[ADD] estate: add model
dalio-odoo Apr 21, 2026
2a943c1
[ADD] estate: add estate_property
dalio-odoo Apr 22, 2026
25b1b95
[FIX] estate: fix style
dalio-odoo Apr 22, 2026
d9454fb
[ADD] estate: add access right for estate_property
dalio-odoo Apr 22, 2026
c767015
[FIX] estate: add author and license to manifest
dalio-odoo Apr 22, 2026
4faa6cd
[ADD] estate: add menus, actions and property fields logic
dalio-odoo Apr 22, 2026
c626a8c
[IMP] estate: add search features and apply style and security fixes
dalio-odoo Apr 22, 2026
f0442fb
[ADD] estate: add types and tags
dalio-odoo Apr 23, 2026
4ac7f31
[ADD] estate: add offers to properties
dalio-odoo Apr 23, 2026
3bd3578
[ADD] estate: add computed fields and onchanges
dalio-odoo Apr 23, 2026
7061f54
[ADD] estate: add 'Sold' and 'Canceled' buttons
dalio-odoo Apr 23, 2026
a3ebbc7
[ADD] estate: add business logic with buttons and constraints
dalio-odoo Apr 24, 2026
ae62f85
[IMP] estate: Change prices to monetary fields.
Mathilde411 Apr 24, 2026
5aea6e1
[IMP] estate: improve property type view and refactor code standards
dalio-odoo Apr 24, 2026
64b4e23
[IMP] estate: improve UI with editable lists and stat buttons
dalio-odoo Apr 27, 2026
6a5844e
[FIX] estate: add readonly to invisible status field in offer list
dalio-odoo Apr 27, 2026
67c3197
[FIX] estate: remove redundant invisible field
dalio-odoo Apr 27, 2026
6649480
[ADD] estate: add business logic for offers and extend user view
dalio-odoo Apr 28, 2026
9939864
[ADD] estate_account: automate invoices creation on sold properties
dalio-odoo Apr 28, 2026
dd2d610
[IMP] estate: add basic test cases
vandroogenbd Apr 28, 2026
6f8b1c7
[IMP] estate_account: improve syntax
dalio-odoo Apr 28, 2026
a161bf9
[FIX] estate: add missing garden information in test
dalio-odoo Apr 28, 2026
04e2c19
[ADD] estate: add grouped kanban view for properties
dalio-odoo Apr 29, 2026
e5ac3b6
[FIX] estate: fix business logic to ensure all tests are passed
dalio-odoo Apr 29, 2026
83a6497
[ADD] awsome_owl: add counters, counters' sum, cards and todo lists
dalio-odoo Apr 30, 2026
11820f7
[IMP] estate: apply suggestions for performance and constraints
dalio-odoo Apr 30, 2026
24f482b
[ADD] awesome_owl: add counters in cards
dalio-odoo Apr 30, 2026
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,6 @@ dmypy.json

# Pyre type checker
.pyre/

# VSCode preferences
.vscode/
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ tutorial's solutions, and one for the
[Master the Odoo web framework](https://www.odoo.com/documentation/latest/developer/tutorials/master_odoo_web_framework.html)
tutorial's solutions. For example, `17.0`, `17.0-discover-js-framework-solutions` and
`17.0-master-odoo-web-framework-solutions`.
# Test setup dalio
1 change: 1 addition & 0 deletions awesome_owl/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
'assets': {
'awesome_owl.assets_playground': [
('include', 'web._assets_helpers'),
('include', 'web.assets_backend'),
('include', 'web._assets_backend_helpers'),
'web/static/src/scss/pre_variables.scss',
'web/static/lib/bootstrap/scss/_variables.scss',
Expand Down
23 changes: 23 additions & 0 deletions awesome_owl/static/src/card/card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
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: Object,
},
},
};

setup() {
this.state = useState({ isOpen: true });
}

toggleContent() {
this.state.isOpen = !this.state.isOpen;
}
}
19 changes: 19 additions & 0 deletions awesome_owl/static/src/card/card.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="awesome_owl.Card">
<div class="card shadow-sm mb-3" style="width: 18rem;">
<div class="card-header d-flex justify-content-between align-items-center bg-white border-bottom-0">
<h5 class="card-title mb-0" t-esc="props.title"/>
<button class="btn btn-sm" t-on-click="toggleContent">
<i t-attf-class="fa fa-chevron-{{ state.isOpen ? 'up' : 'down' }}"/>
</button>
</div>

<div class="card-body pt-0" t-if="state.isOpen">
<div class="card-text">
<t t-slot="default"/>
</div>
</div>
</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 @@
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: 1 });
}

increment() {
this.state.value++;

if (this.props.onChange) {
this.props.onChange();
}
}
}
13 changes: 13 additions & 0 deletions awesome_owl/static/src/counter/counter.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.Counter">
<div class="d-inline-flex align-items-center gap-2">
<span class="fs-5">
Counter: <t t-esc="state.value"/>
</span>
<button class="btn btn-primary btn-sm" t-on-click="increment">
Increment
</button>
</div>
</t>
</templates>
17 changes: 16 additions & 1 deletion awesome_owl/static/src/playground.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
import { Component } from "@odoo/owl";
import { Component, useState, markup } 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 };
static props = {};

setup() {
this.state = useState({ sum: 2 });
this.normalString = "<div class='text-primary'>some content</div>"
this.markupString = markup("<div class='text-primary'>some content</div>");
}

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

<t t-name="awesome_owl.playground">
<div class="p-3">
hello world
<div class="d-flex align-items-center gap-2 mb-4">
<Counter onChange="() => this.incrementSum()"/>
<Counter onChange="() => this.incrementSum()"/>
<span class="fw-bold">Sum: <t t-esc="state.sum"/></span>
</div>

<div class="d-flex flex-wrap gap-3 align-items-start">
<Card title="'Info'">
<p>Simple content.</p>
</Card>

<Card title="'card 2'">
<div class="d-flex align-items-center gap-2">
<Counter/>
</div>
</Card>
</div>

<hr/>
<div class="row mt-4">
<div class="col-md-6">
<div class="shadow-sm p-3 bg-light rounded">
<TodoList/>
</div>
</div>
</div>
</div>
</t>

</templates>
26 changes: 26 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,26 @@
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,
},
},
toggleState: Function,
removeTodo: Function,
};

onChange() {
this.props.toggleState(this.props.todo.id);
}

onRemove() {
this.props.removeTodo(this.props.todo.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.TodoItem">
<div class="p-2 border-bottom" t-att-class="props.todo.isCompleted ? 'text-muted text-decoration-line-through' : ''">
<input type="checkbox" class="me-2" t-att-checked="props.todo.isCompleted" t-on-change="onChange"/>
<span t-att-class="props.todo.isCompleted ? 'text-muted text-decoration-line-through' : ''">
<t t-esc="props.todo.id"/>. <t t-esc="props.todo.description"/>
</span>
<span class="fa fa-remove ms-3 text-danger" style="cursor: pointer;" t-on-click="onRemove"/>
</div>
</t>
</templates>
48 changes: 48 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,48 @@
import { Component, useState } from "@odoo/owl";
import { TodoItem } from "../todo_item/todo_item";
import { useAutofocus } from "../utils";

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

setup() {
this.todos = useState([]);
this.nextId = 0;
this.inputRef = useAutofocus("todoInput");
}

toggleTodo(todoId) {
const todo = this.todos.find((t) => t.id === todoId);
if (todo) {
todo.isCompleted = !todo.isCompleted;
}
}

addTodo(ev) {

if (ev.keyCode === 13 ) {

const description = ev.target.value.trim();

if (description !== "") {
this.todos.push({
id: this.nextId++,
description,
isCompleted: false,
});

ev.target.value = "";

}
}
}

removeTodo(todoId) {
const index = this.todos.findIndex((t) => t.id === todoId);
if (index >= 0) {
this.todos.splice(index, 1);
}
}
}
22 changes: 22 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,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="awesome_owl.TodoList">
<div class="todo-list bg-white shadow-sm rounded p-3" style="max-width: 400px;">
<h3>Todo List</h3>

<div class="mb-3">
<input type="text"
class="form-control"
placeholder="Enter a new task"
t-ref="todoInput"
t-on-keyup="addTodo"/>
</div>

<div class="list-group">
<t t-foreach="todos" t-as="todo" t-key="todo.id">
<TodoItem todo="todo" toggleState="id => this.toggleTodo(id)" removeTodo="id => this.removeTodo(id)"/>
</t>
</div>
</div>
</t>
</templates>
14 changes: 14 additions & 0 deletions awesome_owl/static/src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useRef, onMounted } from "@odoo/owl";

export function useAutofocus(name) {

const ref = useRef(name);

onMounted(() => {
if (ref.el) {
ref.el.focus();
}
});

return ref;
}
1 change: 1 addition & 0 deletions estate/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
19 changes: 19 additions & 0 deletions estate/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "Real Estate",
"version": "19.0.1.1.0",
"depends": [
"base",
],
"data": [
"security/ir.model.access.csv",
"views/estate_property_offer_views.xml",
"views/estate_property_type_views.xml",
"views/estate_property_tag_views.xml",
"views/estate_property_views.xml",
'views/res_users_views.xml',
"views/estate_menus.xml",
],
"application": True,
"author": "dalio",
"license": "LGPL-3"
}
5 changes: 5 additions & 0 deletions estate/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from . import estate_property
from . import estate_property_type
from . import estate_property_tag
from . import estate_property_offer
from . import res_users
Loading