Skip to content

Commit 13a2b85

Browse files
committed
[IMP] awesome_dashboard: add piechart real time update,make dynamic dashboard
Create the services for caching using memoize and reactive. Also, implement real-time update data using setinterval function. Implement the lazy loading concept in the dashboard component and make the dynamic dashboard using props.
1 parent 3d8b5a7 commit 13a2b85

File tree

16 files changed

+285
-96
lines changed

16 files changed

+285
-96
lines changed

awesome_dashboard/__manifest__.py

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,29 @@
11
# -*- coding: utf-8 -*-
22
{
3-
'name': "Awesome Dashboard",
4-
5-
'summary': """
3+
"name": "Awesome Dashboard",
4+
"summary": """
65
Starting module for "Discover the JS framework, chapter 2: Build a dashboard"
76
""",
8-
9-
'description': """
7+
"description": """
108
Starting module for "Discover the JS framework, chapter 2: Build a dashboard"
119
""",
12-
13-
'author': "Odoo",
14-
'website': "https://www.odoo.com/",
15-
'category': 'Tutorials/AwesomeDashboard',
16-
'version': '0.1',
17-
'application': True,
18-
'installable': True,
19-
'depends': ['base', 'web', 'mail', 'crm'],
20-
21-
'data': [
22-
'views/views.xml',
10+
"author": "Odoo",
11+
"website": "https://www.odoo.com/",
12+
"category": "Tutorials/AwesomeDashboard",
13+
"version": "0.1",
14+
"application": True,
15+
"installable": True,
16+
"depends": ["base", "web", "mail", "crm"],
17+
"data": [
18+
"views/views.xml",
2319
],
24-
'assets': {
25-
'web.assets_backend': [
26-
'awesome_dashboard/static/src/**/*',
20+
"assets": {
21+
"web.assets_backend": [
22+
"awesome_dashboard/static/src/**/*",
23+
],
24+
"awesome_dashboard.dashboard": [
25+
"awesome_dashboard/static/src/dashboard/**/*",
2726
],
2827
},
29-
'license': 'AGPL-3'
28+
"license": "AGPL-3",
3029
}

awesome_dashboard/static/src/dashboard.xml

Lines changed: 0 additions & 65 deletions
This file was deleted.

awesome_dashboard/static/src/dashboard.js renamed to awesome_dashboard/static/src/dashboard/dashboard.js

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
/** @odoo-module **/
22

3-
import { Component, useState, onWillStart } from "@odoo/owl";
3+
import { Component, useState } from "@odoo/owl";
44
import { registry } from "@web/core/registry";
55
import { Layout } from "@web/search/layout";
66
import { useService } from "@web/core/utils/hooks";
77
import { DashboardItem } from "./dashboardItem/dashboard_item";
8-
import { rpc } from "@web/core/network/rpc";
8+
import { Piechart } from "./pieChart/pieChart";
99
class AwesomeDashboard extends Component {
1010
static template = "awesome_dashboard.AwesomeDashboard";
11-
static components = { Layout, DashboardItem };
11+
static components = { Layout, DashboardItem, Piechart };
1212

1313
setup() {
1414
this.action = useService("action");
15-
this.state = useState({ statistic: null });
16-
17-
onWillStart(async () => {
18-
this.state.statistic = await rpc("/awesome_dashboard/statistics");
19-
});
15+
const dashboardItemsRegistryData = registry.category("awesome_dashboard");
16+
this.items = dashboardItemsRegistryData.getAll();
17+
this.statisticServices = useService("awesome_dashboard.statistics");
18+
this.state = useState({ statistic: this.statisticServices.statistic });
2019
}
2120
openCustomers() {
2221
this.action.doAction("base.action_partner_form");
@@ -37,6 +36,4 @@ class AwesomeDashboard extends Component {
3736
}
3837
}
3938

40-
registry
41-
.category("actions")
42-
.add("awesome_dashboard.dashboard", AwesomeDashboard);
39+
registry.category("lazy_components").add("AwesomeDashboard", AwesomeDashboard);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<templates xml:space="preserve">
3+
4+
<t t-name="awesome_dashboard.AwesomeDashboard">
5+
<Layout display="{controlPanel: {}}" className="'o_dashboard h-100'">
6+
<t t-set-slot="control-panel-create-button">
7+
<button t-on-click="openCustomers" type="button" class="btn btn-primary" title="Customers">Customers</button>
8+
<button t-on-click="openLeads" type="button" class="btn btn-primary" title="Customers">Leads</button>
9+
</t>
10+
<div class="d-flex">
11+
<t t-foreach="items" t-as="item" t-key="item.id">
12+
<DashboardItem size="item.size || 1">
13+
<t t-set="itemProp" t-value="item.props ? item.props(this.state.statistic) : {'data': this.state.statistic}"/>
14+
<t t-component="item.Component" t-props="itemProp" />
15+
</DashboardItem>
16+
</t>
17+
</div>
18+
19+
</Layout>
20+
</t>
21+
22+
</templates>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { registry } from "@web/core/registry";
2+
import { Numbercard } from "./numbercard/numbercard";
3+
import { Piechartcard } from "./piechartcard/piechartcard";
4+
5+
const items = [
6+
{
7+
id: "nb_new_orders",
8+
description: "The number of new orders, this month",
9+
Component: Numbercard,
10+
size: 1,
11+
props: (data) => ({
12+
title: "New Orders This Month:",
13+
value: data.data.nb_new_orders,
14+
}),
15+
},
16+
{
17+
id: "total_amount",
18+
description: "The total amount of orders, this month",
19+
Component: Numbercard,
20+
size: 2,
21+
props: (data) => ({
22+
title: "Total Amount This Month:",
23+
value: data.data.total_amount,
24+
}),
25+
},
26+
{
27+
id: "average_quantity",
28+
description: "The average number of t-shirts by order",
29+
Component: Numbercard,
30+
size: 1,
31+
props: (data) => ({
32+
title: "Avg. T-Shirts per Order:",
33+
value: data.data.average_quantity,
34+
}),
35+
},
36+
{
37+
id: "nb_cancelled_orders",
38+
description: "The number of cancelled orders, this month",
39+
Component: Numbercard,
40+
size: 1,
41+
props: (data) => ({
42+
title: "Cancelled Orders:",
43+
value: data.data.nb_cancelled_orders,
44+
}),
45+
},
46+
{
47+
id: "average_time",
48+
description:
49+
"The average time (in hours) elapsed between the moment an order is created, and the moment is it sent",
50+
Component: Numbercard,
51+
size: 1,
52+
props: (data) => ({
53+
title: "Avg. Time New → Sent/Cancelled:",
54+
value: data.data.average_time,
55+
}),
56+
},
57+
{
58+
id: "orders_by_size",
59+
description: "Number of shirts ordered based on size",
60+
Component: Piechartcard,
61+
size: 3,
62+
props: (data) => ({
63+
title: "Shirt orders by size:",
64+
value: data.data.orders_by_size,
65+
}),
66+
},
67+
];
68+
items.forEach((item) => {
69+
registry.category("awesome_dashboard").add(item.id, item);
70+
});
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Component } from "@odoo/owl";
2+
export class Numbercard extends Component {
3+
static template = "awesome_dashboard.Numbercard";
4+
static props = {
5+
size: {
6+
type: Number,
7+
default: 1,
8+
optional: true,
9+
},
10+
slots: {
11+
type: Object,
12+
shape: { default: true },
13+
},
14+
};
15+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<templates xml:space="preserve">
3+
<t t-name="awesome_dashboard.Numbercard">
4+
<div class="o_dashboard_stat_block">
5+
<span class="o_dashboard_stat_label">
6+
<strong><t t-out="this.props.title"/></strong>
7+
</span>
8+
<span class="o_dashboard_stat_value">
9+
<t t-esc="this.props.value" />
10+
</span>
11+
</div>
12+
</t>
13+
14+
</templates>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {
2+
Component,
3+
onWillStart,
4+
useRef,
5+
onMounted,
6+
onWillUnmount,
7+
useEffect,
8+
} from "@odoo/owl";
9+
import { loadJS } from "@web/core/assets";
10+
11+
export class Piechart extends Component {
12+
static template = "awesome_dashboard.Piechart";
13+
static props = {
14+
data: { type: Object },
15+
};
16+
setup() {
17+
this.chart = null;
18+
this.canvasRef = useRef("canvas");
19+
20+
onWillStart(async () => {
21+
await loadJS("/web/static/lib/Chart/Chart.js");
22+
});
23+
24+
this.chartData = {
25+
labels: Object.keys(this.props.data),
26+
datasets: [
27+
{
28+
data: Object.values(this.props.data),
29+
},
30+
],
31+
};
32+
33+
onMounted(() => {
34+
this.chart = new Chart(this.canvasRef.el, {
35+
type: "pie",
36+
data: this.chartData,
37+
});
38+
});
39+
useEffect(
40+
() => {
41+
if (this.chart && this.props.data) {
42+
this.chart.data.labels = Object.keys(this.props.data);
43+
this.chart.data.datasets[0].data = Object.values(this.props.data);
44+
this.chart.update();
45+
}
46+
},
47+
() => [this.props.data]
48+
);
49+
}
50+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<templates xml:space="preserve">
3+
<t t-name="awesome_dashboard.Piechart">
4+
<canvas t-ref="canvas" />
5+
</t>
6+
</templates>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Component } from "@odoo/owl";
2+
import { Piechart } from "../pieChart/pieChart";
3+
4+
export class Piechartcard extends Component {
5+
static template = "awesome_dashboard.Piechartcard";
6+
static components = { Piechart };
7+
static props = {
8+
title: { type: String },
9+
data: { type: Object },
10+
};
11+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<templates xml:space="preserve">
3+
<t t-name="awesome_dashboard.Piechartcard">
4+
<div class="o_dashboard_stat_block">
5+
<span class="o_dashboard_stat_label">
6+
<strong><t t-esc="this.props.title"/></strong>
7+
</span>
8+
<span class="o_dashboard_stat_value">
9+
<t t-if="this.props.value">
10+
<Piechart data="this.props.value" />
11+
</t>
12+
<t t-else="">
13+
<div>Loading chart...</div>
14+
</t>
15+
</span>
16+
</div>
17+
</t>
18+
</templates>

0 commit comments

Comments
 (0)