Skip to content

18.0 server tutorial frva #737

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 34 commits into
base: 18.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
c12884e
[IMP] estate: End of chapter 4 commit
frva-odoo Apr 22, 2025
d7696ab
[IMP] estate: End of Chapter 5
frva-odoo Apr 22, 2025
8c00a6e
[IMP] estate: End of chapter 6
frva-odoo Apr 23, 2025
4c39311
[FIX] estate: Clean code and correction of reported issues
frva-odoo Apr 23, 2025
6f18a4b
[IMP] estate: End of chapter 7
frva-odoo Apr 23, 2025
438818c
[IMP] estate: End of day 2
frva-odoo Apr 23, 2025
dbbf98e
[IMP] estate: End of chapter 8
frva-odoo Apr 24, 2025
d1cf2bc
[IMP] estate: End of chapter 9
frva-odoo Apr 24, 2025
ecd1179
[IMP] estate: End of chapter 11
frva-odoo Apr 25, 2025
d9ff057
[IMP] estate: End of chapter 12
frva-odoo Apr 25, 2025
10d9c53
[ADD] estate_account: end of tutorial chapter 13
frva-odoo Apr 28, 2025
0475bd5
[IMP] estate: End of tutorial chapter 14
frva-odoo Apr 28, 2025
dda9737
[FIX] estate,estate_account: Correction of issues
frva-odoo Apr 28, 2025
4f9e253
[IMP] awesome_owl: component, subcomponent and props
frva-odoo Apr 29, 2025
89d84e7
[IMP] awesome_owl: markup, props validation and callback prop
frva-odoo Apr 30, 2025
7dd734d
[IMP] awesome_owl: todo, dynamic attributes and adding todos
frva-odoo Apr 30, 2025
5c6eb35
[IMP] awesome_owl: focusing input, togglin and deleting todos
frva-odoo May 2, 2025
3f63141
[IMP] awesome_owl: generic cards and minimizing
frva-odoo May 2, 2025
ea5a464
[IMP] awesome_dashboard: a new layout
frva-odoo May 2, 2025
d48b0ae
[IMP] awesome_dashboard: Add some buttons for quick navigation (2)
frva-odoo May 2, 2025
5a12840
[IMP] awesome_dashboard: Add a dashboard item (3)
frva-odoo May 2, 2025
1b8a7ab
[FIX] awesome_owl, awesome_dashboard, estate_account: correction of r…
frva-odoo May 2, 2025
312a82b
[IMP] awesome_dashboard: Call the server, add some statistics (4)
frva-odoo May 5, 2025
a0c1f27
[IMP] awesome_dashboard: Cache, Pie Chart and Real life update (5_6_7)
frva-odoo May 5, 2025
8716e47
[IMP] awesome_dashboard: Lazy loading and generic dashboard(8_9)
frva-odoo May 5, 2025
98e2e48
[IMP] awesome_dashboard: Extensible Dashboard and Adding/Removing Ite…
frva-odoo May 6, 2025
74d287b
[ADD] estate: Model, fields, security and views
frva-odoo May 7, 2025
627a455
[IMP] estate: form view
frva-odoo May 7, 2025
8ad0af2
[IMP] estate: property types, tags and offers (m2o,m2m,o2m)
frva-odoo May 7, 2025
753c206
[IMP] estate: accept offer (server actions)
frva-odoo May 7, 2025
89687de
[IMP] estate: website controllers
frva-odoo May 7, 2025
bc02bef
[IMP] estate: Adding simple tour and adding basic demo data
frva-odoo May 9, 2025
cd23057
[IMP] estate_classic: tests implementation (not working)
frva-odoo May 9, 2025
a862e0a
[IMP] estate_classic: tests implementation (now working)
frva-odoo May 9, 2025
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
2 changes: 0 additions & 2 deletions awesome_dashboard/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
# -*- coding: utf-8 -*-

from . import controllers
7 changes: 5 additions & 2 deletions awesome_dashboard/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
{
'name': "Awesome Dashboard",

Expand All @@ -24,7 +23,11 @@
'assets': {
'web.assets_backend': [
'awesome_dashboard/static/src/**/*',
],
('remove', 'awesome_dashboard/static/src/dashboard/**/*'),
],
'awesome_dashboard.dashboard': [
'awesome_dashboard/static/src/dashboard/**/*'
],
},
'license': 'AGPL-3'
}
2 changes: 0 additions & 2 deletions awesome_dashboard/controllers/controllers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-

import logging
import random

Expand Down
10 changes: 0 additions & 10 deletions awesome_dashboard/static/src/dashboard.js

This file was deleted.

8 changes: 0 additions & 8 deletions awesome_dashboard/static/src/dashboard.xml

This file was deleted.

13 changes: 13 additions & 0 deletions awesome_dashboard/static/src/dashboard/cards/number_card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Component } from "@odoo/owl";

export class NumberCard extends Component {
static template = "awesome_dashboard.NumberCard";
static props = {
title: {
type: String,
},
value: {
type: Number,
}
}
}
11 changes: 11 additions & 0 deletions awesome_dashboard/static/src/dashboard/cards/number_card.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_dashboard.NumberCard">
<t t-esc="props.title"/>
<div class="fs-1 fw-bold text-success text-center">
<t t-esc="props.value"/>
</div>
</t>

</templates>
11 changes: 11 additions & 0 deletions awesome_dashboard/static/src/dashboard/cards/pie_chart_card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Component } from "@odoo/owl";
import { PieChart } from "../pie_chart";

export class PieChartCard extends Component {
static template = "awesome_dashboard.pie_chart_card";
static components = { PieChart }
static props = {
title: String,
values: Object,
}
}
11 changes: 11 additions & 0 deletions awesome_dashboard/static/src/dashboard/cards/pie_chart_card.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_dashboard.pie_chart_card">
<t t-name="awesome_dashboard.PieChartCard" owl="1">
<t t-esc="props.title"/>
<PieChart data="props.values"/>
</t>
</t>

</templates>
90 changes: 90 additions & 0 deletions awesome_dashboard/static/src/dashboard/dashboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { Component, useState } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { Layout } from "@web/search/layout";
import { useService } from "@web/core/utils/hooks";
import { DashboardItem } from "./dashboard_item";
import { Dialog } from "@web/core/dialog/dialog";
import { CheckBox } from "@web/core/checkbox/checkbox";
import { browser } from "@web/core/browser/browser";

class AwesomeDashboard extends Component {
static template = "awesome_dashboard.AwesomeDashboard";
static components = { Layout, DashboardItem };

setup(){
this.myDisplay = {controlPanel: {}};
this.action = useService("action");
this.dialog = useService("dialog");
this.statistics = useState(useService("awesome_dashboard.statistics"));
this.items = registry.category("awesome_dashboard").getAll();
this.state = useState({
disabledItems: browser.localStorage.getItem("disabledDashboardItems")?.split(",") || []
});
}

openCustomersView(){
this.action.doAction("base.action_partner_form");
}

openLeads(){
this.action.doAction({
type: 'ir.actions.act_window',
name: 'All leads',
res_model: 'crm.lead',
views: [
[false, 'list'],
[false, 'form'],
],
});
}

openDashboardItemsDialog() {
this.dialog.add(ConfigurationDialog, {
items: this.items,
disabledItems: this.state.disabledItems,
onUpdateConfiguration: this.updateDashboardItemsDialog.bind(this),
})
}

updateDashboardItemsDialog(newIgnoredItemsIds) {
this.state.disabledItems = newIgnoredItemsIds;
}
}

registry.category("lazy_components").add("AwesomeDashboard", AwesomeDashboard);

class ConfigurationDialog extends Component {
static template = "awesome_dashboard.ConfigurationDialog";
static components = { Dialog, CheckBox };
static props = ["close", "items", "disabledItems", "onUpdateConfiguration"];

setup() {
this.items = useState(this.props.items.map((item) => {
return {
...item,
enabled: !this.props.disabledItems.includes(item.id),
}
}));
}

done() {
this.props.close();
}

onChange(checked, changedItem) {
changedItem.enabled = checked;
const newDisabledItems = Object.values(this.items).filter(
(item) => !item.enabled
).map((item) => item.id)

browser.localStorage.setItem(
"disabledDashboardItems",
newDisabledItems,
);

this.props.onUpdateConfiguration(newDisabledItems);
}

}


3 changes: 3 additions & 0 deletions awesome_dashboard/static/src/dashboard/dashboard.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.o_dashboard{
background-color: rgb(124, 124, 190);
}
37 changes: 37 additions & 0 deletions awesome_dashboard/static/src/dashboard/dashboard.xml
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_dashboard.AwesomeDashboard">
<Layout className="'o_dashboard h-100'" display="myDisplay">
<t t-set-slot="layout-buttons">
<button t-on-click="openCustomersView">Customers</button>
<button t-on-click="openLeads">Leads</button>
</t>
<t t-set-slot="control-panel-additional-actions">
<span t-on-click="openDashboardItemsDialog" class="fa fa-solid fa-gear fa-2x"/>
</t>
<t t-foreach="items" t-as="item" t-key="item.id">
<DashboardItem t-if="!state.disabledItems.includes(item.id)" size="item.size || 1">
<t t-set="itemProp" t-value="item.props ? item.props(statistics) : {'data': statistics}"/>
<t t-component="item.Component" t-props="itemProp" />
</DashboardItem>
</t>
</Layout>
</t>
<t t-name="awesome_dashboard.ConfigurationDialog">
<Dialog title="'Dashboard items configuration'">
Which cards do you whish to see ?
<t t-foreach="items" t-as="item" t-key="item.id">
<CheckBox value="item.enabled" onChange="(ev) => this.onChange(ev, item)">
<t t-esc="item.description"/>
</CheckBox>
</t>
<t t-set-slot="footer">
<button class="btn btn-primary" t-on-click="done">
Done
</button>
</t>
</Dialog>
</t>

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


export class DashboardItem extends Component {
static template = "awesome_dashboard.dashboard_item";
static props = {
slots: Object,
size: {
type: Number,
optional: true
}
};


calculate_width(){
if (!this.props.size){
this.props.size = 1;
}
this.width = (18*this.props.size);
return this.width;
}
}
14 changes: 14 additions & 0 deletions awesome_dashboard/static/src/dashboard/dashboard_item.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_dashboard.dashboard_item">
<div class="card m-2 border-dark" t-attf-style="width: {{18*props.size}}rem;">
<div class="card-body">
<font size="6">
<t t-slot="default"/>
</font>
</div>
</div>
</t>

</templates>
65 changes: 65 additions & 0 deletions awesome_dashboard/static/src/dashboard/dashboard_items.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { NumberCard } from "./cards/number_card";
import { PieChartCard } from "./cards/pie_chart_card";
import { registry } from "@web/core/registry";

const items = [
{
id: "average_quantity",
description: "Average amount of t-shirt",
Component: NumberCard,
props: (data) => ({
title: "Average amount of t-shirt by order this month",
value: data.average_quantity,
})
},
{
id: "average_time",
description: "Average time for an order",
Component: NumberCard,
props: (data) => ({
title: "Average time for an order to go from 'new' to 'sent' or 'cancelled'",
value: data.average_time,
})
},
{
id: "number_new_orders",
description: "New orders this month",
Component: NumberCard,
props: (data) => ({
title: "Number of new orders this month",
value: data.nb_new_orders,
})
},
{
id: "cancelled_orders",
description: "Cancelled orders this month",
Component: NumberCard,
props: (data) => ({
title: "Number of cancelled orders this month",
value: data.nb_cancelled_orders,
})
},
{
id: "amount_new_orders",
description: "amount orders this month",
Component: NumberCard,
props: (data) => ({
title: "Total amount of new orders this month",
value: data.total_amount,
})
},
{
id: "pie_chart",
description: "Shirt orders by size",
Component: PieChartCard,
size: 2,
props: (data) => ({
title: "Shirt orders by size",
values: data.orders_by_size,
})
}
]

for (const item of items){
registry.category("awesome_dashboard").add(item.id, item);
}
39 changes: 39 additions & 0 deletions awesome_dashboard/static/src/dashboard/pie_chart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Component, onWillStart, useRef, onMounted, onWillUnmount } from "@odoo/owl";
import { loadJS } from "@web/core/assets";
import { getColor } from "@web/core/colors/colors";

export class PieChart extends Component {
static template = "awesome_dashboard.pie_chart";
static props = {
data: Object,
};

setup() {
this.canvasRef = useRef("canvas");
onWillStart(() => loadJS("/web/static/lib/Chart/Chart.js"));
onMounted(() => {
this.renderChart();
});
onWillUnmount(() => {
this.chart.destroy();
});
}

renderChart() {
const labels = Object.keys(this.props.data);
const data = Object.values(this.props.data);
const color = labels.map((_, index) => getColor(index));
this.chart = new Chart(this.canvasRef.el, {
type: "pie",
data: {
labels: labels,
datasets: [
{
data: data,
backgroundColor: color,
},
],
},
});
}
}
10 changes: 10 additions & 0 deletions awesome_dashboard/static/src/dashboard/pie_chart.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="awesome_dashboard.pie_chart">
<div t-att-class="'h-100 ' + props.class" t-ref="root">
<div class="h-100 position-relative" t-ref="container">
<canvas t-ref="canvas" />
</div>
</div>
</t>
</templates>
10 changes: 10 additions & 0 deletions awesome_dashboard/static/src/dashboard_assets_bundle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { registry } from "@web/core/registry";
import { LazyComponent } from "@web/core/assets";
import { Component } from "@odoo/owl";

class DashboardAssetsBundle extends Component {
static components = { LazyComponent };
static template = "awesome_dashboard.DashboardAssetsBundle";
}

registry.category("actions").add("awesome_dashboard.dashboard", DashboardAssetsBundle);
Loading