Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
beb6748
[ADD] estate: initialize the estate module
WaleedElgamal Jan 19, 2026
eeaae68
[ADD] estate: create the property model
WaleedElgamal Jan 20, 2026
29c2531
[LINT] estate: format python files
WaleedElgamal Jan 20, 2026
20f824c
[ADD] estate: add access rights
WaleedElgamal Jan 20, 2026
e4fad21
[IMP] estate: add missing configuration
WaleedElgamal Jan 20, 2026
950741f
[IMP] estate: add new menus with basic action
WaleedElgamal Jan 21, 2026
ba5fbc2
[IMP] estate: add custom views
WaleedElgamal Jan 21, 2026
2b20c7e
[IMP] estate: introduce new views and relations
WaleedElgamal Jan 22, 2026
3211963
[IMP] estate: add computed fields and onchanges
WaleedElgamal Jan 22, 2026
6a1ba31
[IMP] estate: add action buttons to property form view
WaleedElgamal Jan 22, 2026
9b9ad98
[IMP] estate: add data constraints
WaleedElgamal Jan 22, 2026
0f67f41
[IMP] estate: add ui enhancements
WaleedElgamal Jan 23, 2026
e251e70
[FIX] estate: remove redundant code
WaleedElgamal Jan 23, 2026
5ede046
[IMP] estate: display salesperson properties in user view
WaleedElgamal Jan 26, 2026
3aa83d3
[IMP] estate: create invoice on property sale
WaleedElgamal Jan 26, 2026
68fbd12
[FIX] estate: fix linting and warnings
WaleedElgamal Jan 27, 2026
8398615
[IMP] estate: create kanban view
WaleedElgamal Jan 27, 2026
666c4ff
[FIX] estate: follow coding guidlines
WaleedElgamal Jan 27, 2026
507ef93
[IMP] awesome_owl: add basic UI components
WaleedElgamal Jan 28, 2026
20752e5
[FIX] awesome_owl: fix styling issues
WaleedElgamal Jan 29, 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
22 changes: 22 additions & 0 deletions awesome_owl/static/src/card/card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
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: true
},
}
}

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

toggleContent() {
this.state.isOpen = !this.state.isOpen;
}
}
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;">
<div class="card-body">
<h5 class="card-title" t-out="props.title"/>
<button class="btn btn-primary" t-on-click="toggleContent">Toggle</button>
<p class="card-text mt-2" t-if="state.isOpen">
<t t-slot="default"/>
</p>
</div>
</div>
</t>

</templates>
20 changes: 20 additions & 0 deletions awesome_owl/static/src/counter/counter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
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({ counter: 0 });
}

increment() {
this.state.counter++;
if(this.props.onChange) {
this.props.onChange();
}
}

}
11 changes: 11 additions & 0 deletions awesome_owl/static/src/counter/counter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_owl.counter">
<div class="p-3">
<span class="ms-3">Counter: <t t-esc="state.counter"/></span>
<button t-on-click="increment" class="btn btn-primary">Increment</button>
</div>
</t>

</templates>
16 changes: 15 additions & 1 deletion awesome_owl/static/src/playground.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
import { Component } from "@odoo/owl";
import { Component, markup, useState} from "@odoo/owl";
import { Card } from "./card/card.js";
import { Counter } from "./counter/counter.js";
import { TodoList } from "./todo/todo_list.js";

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

setup() {
this.state = useState({ sum: 0 });
this.content1 = "<div>some text 1</div>";
this.content2 = markup("<div>some text 2</div>");
}

incrementSum() {
this.state.sum++;
}
}
24 changes: 24 additions & 0 deletions awesome_owl/static/src/playground.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,30 @@
<div class="p-3">
hello world
</div>
<div>
<Counter onChange.bind="incrementSum"/>
<Counter onChange.bind="incrementSum"/>
<span class="ms-3">The sum is: <t t-esc="state.sum"/> </span>
</div>
<div>
<Card title="'Card Title 1'">
Content of card 1
</Card>
<Card title="'Card Title 2'">
Content of card 2
</Card>
</div>
<div>
<TodoList/>
</div>
<div>
<Card title="'Card Title 3'">
Content of card 3
</Card>
<Card title="'Card Title 4'">
<Counter />
</Card>
</div>
</t>

</templates>
25 changes: 25 additions & 0 deletions awesome_owl/static/src/todo/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 = {
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);
}
}
15 changes: 15 additions & 0 deletions awesome_owl/static/src/todo/todo_item.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_owl.todo_item">
<div class="p-2">
<input type="checkbox" t-att-id="props.todo.id" t-att-checked="props.todo.isCompleted" t-on-change="onChange"/>
<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>
<span class="fa fa-remove" t-on-click="onRemove"/>
</div>
</t>

</templates>
44 changes: 44 additions & 0 deletions awesome_owl/static/src/todo/todo_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Component, useState, useRef, onMounted } from "@odoo/owl";
import { TodoItem } from "./todo_item";
import { useAutofocus } from "../utils.js";

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

setup() {
this.todos = useState([]);
this.nextId = 1;
useAutofocus("input");
}

addTodo(ev) {
if (ev.keyCode === 13) {
const input = ev.target;
const description = input.value.trim();

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

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

removeTodo(todoId) {
const index = this.todos.findIndex(t => t.id === todoId);
if (index !== -1) {
this.todos.splice(index, 1);
}
}
}
13 changes: 13 additions & 0 deletions awesome_owl/static/src/todo/todo_list.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.todo_list">
<div class="p-3">
<input type="text" placeholder="Enter a new task" t-on-keyup="addTodo" t-ref="input"/>
<p t-foreach="todos" t-as="todo" t-key="todo.id">
<TodoItem todo="todo" toggleState.bind="toggleState" removeTodo.bind="removeTodo"/>
</p>
</div>
</t>

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

export function useAutofocus(name) {
let ref = useRef(name);
onMounted(() => {
ref.el && ref.el.focus();
});
}
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
17 changes: 17 additions & 0 deletions estate/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
'name': "Real Estate",
'version': '1.0',
'depends': ['base'],
'data': [
'security/ir.model.access.csv',
'views/estate_property_views.xml',
'views/estate_property_offer_views.xml',
'views/estate_property_type_views.xml',
'views/estate_property_tag_views.xml',
'views/res_users_views.xml',
'views/estate_menus.xml',
],
'application': True,
'author': 'Odoo S.A.',
'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_offer
from . import estate_property_tag
from . import estate_property_type
from . import res_users
Loading