Skip to content

Commit dbbceca

Browse files
committed
[ADD] awesome_dashboard
1 parent f220d38 commit dbbceca

18 files changed

Lines changed: 365 additions & 16 deletions

awesome_dashboard/__manifest__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
'assets': {
2525
'web.assets_backend': [
2626
'awesome_dashboard/static/src/**/*',
27+
('remove', 'awesome_dashboard/static/src/dashboard/**/*')
28+
],
29+
'awesome_dashboard.dashboard': [
30+
'awesome_dashboard/static/src/dashboard/**/*',
2731
],
2832
},
2933
'license': 'AGPL-3'

awesome_dashboard/static/src/dashboard.js

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

awesome_dashboard/static/src/dashboard.xml

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { Component, useState } from "@odoo/owl";
2+
import { registry } from "@web/core/registry";
3+
import { useService } from "@web/core/utils/hooks";
4+
import { Layout } from "@web/search/layout";
5+
import { DashboardItem } from "./dashboard_item";
6+
import { PieChart } from "./pie_chart";
7+
import { Dialog } from "@web/core/dialog/dialog";
8+
import { CheckBox } from "@web/core/checkbox/checkbox";
9+
import { _t } from "@web/core/l10n/translation";
10+
import { standardActionServiceProps } from "@web/webclient/actions/action_service";
11+
import { browser } from "@web/core/browser/browser";
12+
13+
class AwesomeDashboard extends Component {
14+
static template = "awesome_dashboard.AwesomeDashboard";
15+
static components = { Layout, DashboardItem, PieChart };
16+
static props = { ...standardActionServiceProps };
17+
18+
setup() {
19+
this.items = registry.category("awesome_dashboard").getAll();
20+
this.action = useService("action");
21+
this.statistics = useState(useService("awesome_dashboard.statistic_service"));
22+
this.dialog = useService("dialog");
23+
this.state = useState({
24+
disabledItems: browser.localStorage.getItem("disabledDashboardItems")?.split(",") || []
25+
});
26+
27+
}
28+
29+
30+
openConfiguration() {
31+
this.dialog.add(ConfigurationDialog, {
32+
items: this.items,
33+
disabledItems: this.state.disabledItems,
34+
onUpdateConfiguration: this.updateConfiguration.bind(this),
35+
});
36+
}
37+
38+
updateConfiguration(newDisabledItems) {
39+
this.state.disabledItems = newDisabledItems;
40+
}
41+
42+
openCustomerKanbanView() {
43+
this.action.doAction('base.action_partner_form');
44+
}
45+
46+
openLeads() {
47+
this.action.doAction({
48+
type: 'ir.actions.act_window',
49+
name: _t('Journal Entry'),
50+
target: 'current',
51+
res_model: 'crm.lead',
52+
views: [
53+
[false, 'form'],
54+
[false, 'list'],
55+
],
56+
});
57+
}
58+
}
59+
60+
class ConfigurationDialog extends Component {
61+
static template = "awesome_dashboard.ConfigurationDialog";
62+
static components = { Dialog, CheckBox };
63+
static props = ["close", "items", "disabledItems", "onUpdateConfiguration"];
64+
65+
setup() {
66+
this.items = useState(this.props.items.map((item) => {
67+
return {
68+
item,
69+
enabled: !this.props.disabledItems.includes(item.id),
70+
}
71+
}));
72+
}
73+
74+
Apply() {
75+
this.props.close();
76+
}
77+
78+
onChange(checked, changedItem) {
79+
changedItem.enabled = checked;
80+
const newDisabledItems = Object.values(this.items).filter(
81+
(item) => !item.enabled
82+
).map((item) => item.id)
83+
84+
browser.localStorage.setItem(
85+
"disabledDashboardItems",
86+
newDisabledItems,
87+
);
88+
89+
this.props.onUpdateConfiguration(newDisabledItems);
90+
}
91+
92+
}
93+
94+
registry.category("lazy_components").add("AwesomeDashboard", AwesomeDashboard);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.o_dashboard {
2+
background-color: #bb88bb
3+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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="layout-buttons">
7+
<button class="btn btn-primary" t-on-click="openCustomerKanbanView">Customers</button>
8+
<button class="btn btn-primary" t-on-click="openLeads">Leads</button>
9+
</t>
10+
<t t-set-slot="control-panel-additional-actions">
11+
<button t-on-click="openConfiguration" class="btn p-0 ms-1 border-0">
12+
<i class="fa fa-cog"></i>
13+
</button>
14+
</t>
15+
16+
<div class="d-flex flex-wrap" >
17+
<t t-foreach="items" t-as="item" t-key="item.id">
18+
<DashboardItem size="item.size || 1" t-if="!state.disabledItems.includes(item.id)">
19+
<t t-set="itemProp" t-value="item.props ? item.props(statistics) : {'data': statistics}"/>
20+
<t t-component="item.Component" t-props="itemProp" />
21+
</DashboardItem>
22+
</t>
23+
</div>
24+
25+
</Layout>
26+
</t>
27+
28+
<t t-name="awesome_dashboard.ConfigurationDialog">
29+
<Dialog title="'Dashboard items configuration'">
30+
Which cards do you whish to see ?
31+
<t t-foreach="items" t-as="item" t-key="item.id">
32+
<CheckBox value="item.enabled" onChange="(ev) => this.onChange(ev, item)">
33+
<t t-esc="item.description"/>
34+
</CheckBox>
35+
</t>
36+
<t t-set-slot="footer">
37+
<button class="btn btn-primary" t-on-click='Apply'>
38+
Apply
39+
</button>
40+
</t>
41+
</Dialog>
42+
</t>
43+
44+
</templates>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Component } from "@odoo/owl";
2+
3+
export class DashboardItem extends Component {
4+
static template = "awesome_dashboard.DashboardItem"
5+
static props = {
6+
slots: {
7+
type: Object,
8+
},
9+
10+
size: {
11+
type: Number,
12+
optional: true,
13+
},
14+
};
15+
static defaultProps = {
16+
size: 1
17+
}
18+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<templates xml:space="preserve">
3+
4+
<t t-name="awesome_dashboard.DashboardItem">
5+
<div class="card m-2 border-dark" t-attf-style="width: {{18*props.size}}rem;">
6+
<div class="card-body">
7+
<t t-slot="default"/>
8+
</div>
9+
</div>
10+
</t>
11+
12+
</templates>
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { NumberCard } from "./number_card";
2+
import { PieChartCard } from "./pie_chart_card";
3+
import { registry } from "@web/core/registry";
4+
5+
6+
export const items = [
7+
{
8+
id: "average_quantity",
9+
description: "Average amount of t-shirt",
10+
Component: NumberCard,
11+
props: (data) => ({
12+
title: "Average amount of t-shirt by order this month",
13+
value: data.average_quantity,
14+
})
15+
},
16+
{
17+
id: "average_time",
18+
description: "Average time for an order",
19+
Component: NumberCard,
20+
props: (data) => ({
21+
title: "Average time for an order to go from 'new' to 'sent' or 'cancelled'",
22+
value: data.average_time,
23+
})
24+
},
25+
{
26+
id: "number_new_orders",
27+
description: "New orders this month",
28+
Component: NumberCard,
29+
props: (data) => ({
30+
title: "Number of new orders this month",
31+
value: data.nb_new_orders,
32+
})
33+
},
34+
{
35+
id: "cancelled_orders",
36+
description: "Cancelled orders this month",
37+
Component: NumberCard,
38+
props: (data) => ({
39+
title: "Number of cancelled orders this month",
40+
value: data.nb_cancelled_orders,
41+
})
42+
},
43+
{
44+
id: "amount_new_orders",
45+
description: "amount orders this month",
46+
Component: NumberCard,
47+
props: (data) => ({
48+
title: "Total amount of new orders this month",
49+
value: data.total_amount,
50+
})
51+
},
52+
53+
{
54+
id: "pie_chart",
55+
description: "Shirt orders by size",
56+
Component: PieChartCard,
57+
size: 2,
58+
props: (data) => ({
59+
title: "Shirt orders by size",
60+
values: data.orders_by_size,
61+
})
62+
},
63+
]
64+
65+
66+
items.forEach(item => {
67+
registry.category("awesome_dashboard").add(item.id, item);
68+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Component } from "@odoo/owl";
2+
3+
export class NumberCard extends Component {
4+
static template = "awesome_dashboard.NumberCard";
5+
static props = {
6+
title: {
7+
type: String,
8+
},
9+
value: {
10+
type: Number,
11+
}
12+
}
13+
}

0 commit comments

Comments
 (0)