From e610aa00bc48130a9a06f452cec3cda4ebad78ab Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Wed, 24 Sep 2025 09:53:51 +0200 Subject: [PATCH 01/21] [IMP] dashboard: add layout component to dashboard --- awesome_dashboard/static/src/dashboard.js | 2 ++ awesome_dashboard/static/src/dashboard.scss | 3 +++ awesome_dashboard/static/src/dashboard.xml | 4 +++- 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 awesome_dashboard/static/src/dashboard.scss diff --git a/awesome_dashboard/static/src/dashboard.js b/awesome_dashboard/static/src/dashboard.js index 637fa4bb972..37c5f0d6348 100644 --- a/awesome_dashboard/static/src/dashboard.js +++ b/awesome_dashboard/static/src/dashboard.js @@ -2,9 +2,11 @@ import { Component } from "@odoo/owl"; import { registry } from "@web/core/registry"; +import { Layout } from "@web/search/layout"; class AwesomeDashboard extends Component { static template = "awesome_dashboard.AwesomeDashboard"; + static components = { Layout }; } registry.category("actions").add("awesome_dashboard.dashboard", AwesomeDashboard); diff --git a/awesome_dashboard/static/src/dashboard.scss b/awesome_dashboard/static/src/dashboard.scss new file mode 100644 index 00000000000..769fc1e72f9 --- /dev/null +++ b/awesome_dashboard/static/src/dashboard.scss @@ -0,0 +1,3 @@ +.o_dashboard { + background-color: gray; +} \ No newline at end of file diff --git a/awesome_dashboard/static/src/dashboard.xml b/awesome_dashboard/static/src/dashboard.xml index 1a2ac9a2fed..35eefce954c 100644 --- a/awesome_dashboard/static/src/dashboard.xml +++ b/awesome_dashboard/static/src/dashboard.xml @@ -2,7 +2,9 @@ - hello dashboard + + some content + From c1be7a075a219749f40cafe906869e79fd408697 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Wed, 24 Sep 2025 10:47:59 +0200 Subject: [PATCH 02/21] [IMP] dashboard: add quick navigation buttons --- awesome_dashboard/static/src/dashboard.js | 22 ++++++++++++++++++++++ awesome_dashboard/static/src/dashboard.xml | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/awesome_dashboard/static/src/dashboard.js b/awesome_dashboard/static/src/dashboard.js index 37c5f0d6348..dafbd3f1e05 100644 --- a/awesome_dashboard/static/src/dashboard.js +++ b/awesome_dashboard/static/src/dashboard.js @@ -3,10 +3,32 @@ import { Component } from "@odoo/owl"; import { registry } from "@web/core/registry"; import { Layout } from "@web/search/layout"; +import { useService } from "@web/core/utils/hooks"; class AwesomeDashboard extends Component { static template = "awesome_dashboard.AwesomeDashboard"; static components = { Layout }; + + setup() { + this.action = useService("action"); + } + + openCustomers() { + this.action.doAction("base.action_partner_form"); + } + + openLeads() { + this.action.doAction({ + type: 'ir.actions.act_window', + name: "Leads", + target: 'current', + res_model: 'crm.lead', + views: [ + [false, 'list'], + [false, 'form'], + ], + }); + } } registry.category("actions").add("awesome_dashboard.dashboard", AwesomeDashboard); diff --git a/awesome_dashboard/static/src/dashboard.xml b/awesome_dashboard/static/src/dashboard.xml index 35eefce954c..bfe3121859d 100644 --- a/awesome_dashboard/static/src/dashboard.xml +++ b/awesome_dashboard/static/src/dashboard.xml @@ -3,6 +3,10 @@ + + + + some content From ec837002a64c5848d1440582bdc7777347cad0e9 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Wed, 24 Sep 2025 11:37:48 +0200 Subject: [PATCH 03/21] [ADD] Dashboard Item --- awesome_dashboard/static/src/dashboard.js | 3 ++- awesome_dashboard/static/src/dashboard.xml | 12 +++++++++++- awesome_dashboard/static/src/dashboard_item.js | 15 +++++++++++++++ awesome_dashboard/static/src/dashboard_item.xml | 12 ++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 awesome_dashboard/static/src/dashboard_item.js create mode 100644 awesome_dashboard/static/src/dashboard_item.xml diff --git a/awesome_dashboard/static/src/dashboard.js b/awesome_dashboard/static/src/dashboard.js index dafbd3f1e05..d48699f24cc 100644 --- a/awesome_dashboard/static/src/dashboard.js +++ b/awesome_dashboard/static/src/dashboard.js @@ -4,10 +4,11 @@ import { Component } 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"; class AwesomeDashboard extends Component { static template = "awesome_dashboard.AwesomeDashboard"; - static components = { Layout }; + static components = { Layout, DashboardItem }; setup() { this.action = useService("action"); diff --git a/awesome_dashboard/static/src/dashboard.xml b/awesome_dashboard/static/src/dashboard.xml index bfe3121859d..69be5dfc64f 100644 --- a/awesome_dashboard/static/src/dashboard.xml +++ b/awesome_dashboard/static/src/dashboard.xml @@ -7,7 +7,17 @@ - some content +
+ + some content + + + I love milk + + + some content + +
diff --git a/awesome_dashboard/static/src/dashboard_item.js b/awesome_dashboard/static/src/dashboard_item.js new file mode 100644 index 00000000000..8230bd52176 --- /dev/null +++ b/awesome_dashboard/static/src/dashboard_item.js @@ -0,0 +1,15 @@ +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, + } + } + static defaultProps = { + size: 1, + } +} \ No newline at end of file diff --git a/awesome_dashboard/static/src/dashboard_item.xml b/awesome_dashboard/static/src/dashboard_item.xml new file mode 100644 index 00000000000..60d473564fa --- /dev/null +++ b/awesome_dashboard/static/src/dashboard_item.xml @@ -0,0 +1,12 @@ + + + + +
+
+ +
+
+
+ +
From 379d84d1dc16d4c0d102d8b942562cc165dbe7e4 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Wed, 24 Sep 2025 11:56:33 +0200 Subject: [PATCH 04/21] [IMP] Dashboard: add some statistics to the dashboard, get the data from an rpc call --- awesome_dashboard/static/src/dashboard.js | 6 ++++- awesome_dashboard/static/src/dashboard.xml | 27 +++++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/awesome_dashboard/static/src/dashboard.js b/awesome_dashboard/static/src/dashboard.js index d48699f24cc..86fb2cbf655 100644 --- a/awesome_dashboard/static/src/dashboard.js +++ b/awesome_dashboard/static/src/dashboard.js @@ -1,10 +1,11 @@ /** @odoo-module **/ -import { Component } from "@odoo/owl"; +import { Component, onWillStart } 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 { rpc } from "@web/core/network/rpc"; class AwesomeDashboard extends Component { static template = "awesome_dashboard.AwesomeDashboard"; @@ -12,6 +13,9 @@ class AwesomeDashboard extends Component { setup() { this.action = useService("action"); + onWillStart(async () => { + this.statistics = await rpc("/awesome_dashboard/statistics"); + }) } openCustomers() { diff --git a/awesome_dashboard/static/src/dashboard.xml b/awesome_dashboard/static/src/dashboard.xml index 69be5dfc64f..0a450e08498 100644 --- a/awesome_dashboard/static/src/dashboard.xml +++ b/awesome_dashboard/static/src/dashboard.xml @@ -9,13 +9,34 @@
- some content + Average amount of t-shirt by order this month +
+ +
- I love milk + Average time for an order to go from 'new' to 'sent' of 'cancelled' +
+ +
- some content + Number of new orders this month +
+ +
+
+ + Number of cancelled orders this month +
+ +
+
+ + Total amount of new orders this month +
+ +
From a6522925115e7460445795f17e99fc1225c67c3f Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Wed, 24 Sep 2025 13:41:30 +0200 Subject: [PATCH 05/21] [IMP] dashboard: add statistics caching --- awesome_dashboard/static/src/dashboard.js | 4 ++-- .../static/src/statistics_service.js | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 awesome_dashboard/static/src/statistics_service.js diff --git a/awesome_dashboard/static/src/dashboard.js b/awesome_dashboard/static/src/dashboard.js index 86fb2cbf655..483e6d70e2a 100644 --- a/awesome_dashboard/static/src/dashboard.js +++ b/awesome_dashboard/static/src/dashboard.js @@ -5,7 +5,6 @@ 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 { rpc } from "@web/core/network/rpc"; class AwesomeDashboard extends Component { static template = "awesome_dashboard.AwesomeDashboard"; @@ -13,8 +12,9 @@ class AwesomeDashboard extends Component { setup() { this.action = useService("action"); + this.statistics_service = useService("statistics_service"); onWillStart(async () => { - this.statistics = await rpc("/awesome_dashboard/statistics"); + this.statistics = await this.statistics_service.loadStatistics() }) } diff --git a/awesome_dashboard/static/src/statistics_service.js b/awesome_dashboard/static/src/statistics_service.js new file mode 100644 index 00000000000..41106ed8078 --- /dev/null +++ b/awesome_dashboard/static/src/statistics_service.js @@ -0,0 +1,17 @@ +import { rpc } from "@web/core/network/rpc"; +import { registry } from "@web/core/registry"; +import { memoize } from "@web/core/utils/functions"; + +const fetchStatistics = () => { + return rpc("/awesome_dashboard/statistics"); +} + +export const statisticsService = { + start() { + return { + loadStatistics: memoize(() => fetchStatistics()), + }; + }, +} + +registry.category("services").add("statistics_service", statisticsService); \ No newline at end of file From c38b2b80f4a57738965e1f20f13c6271ea32c686 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Wed, 24 Sep 2025 15:24:04 +0200 Subject: [PATCH 06/21] [IMP] dashboard: add pie chart for shirt orders by size to the dashboard --- awesome_dashboard/static/src/dashboard.js | 3 +- awesome_dashboard/static/src/dashboard.xml | 4 ++ awesome_dashboard/static/src/pie_chart.js | 59 ++++++++++++++++++++++ awesome_dashboard/static/src/pie_chart.xml | 10 ++++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 awesome_dashboard/static/src/pie_chart.js create mode 100644 awesome_dashboard/static/src/pie_chart.xml diff --git a/awesome_dashboard/static/src/dashboard.js b/awesome_dashboard/static/src/dashboard.js index 483e6d70e2a..47938b07602 100644 --- a/awesome_dashboard/static/src/dashboard.js +++ b/awesome_dashboard/static/src/dashboard.js @@ -5,10 +5,11 @@ 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 { PieChart } from "./pie_chart"; class AwesomeDashboard extends Component { static template = "awesome_dashboard.AwesomeDashboard"; - static components = { Layout, DashboardItem }; + static components = { Layout, DashboardItem, PieChart }; setup() { this.action = useService("action"); diff --git a/awesome_dashboard/static/src/dashboard.xml b/awesome_dashboard/static/src/dashboard.xml index 0a450e08498..da3540c53f0 100644 --- a/awesome_dashboard/static/src/dashboard.xml +++ b/awesome_dashboard/static/src/dashboard.xml @@ -38,6 +38,10 @@ + + Shirt orders by size + + diff --git a/awesome_dashboard/static/src/pie_chart.js b/awesome_dashboard/static/src/pie_chart.js new file mode 100644 index 00000000000..fed152563c7 --- /dev/null +++ b/awesome_dashboard/static/src/pie_chart.js @@ -0,0 +1,59 @@ +import { Component, onWillStart, useRef, useEffect, onWillUnmount } from "@odoo/owl"; +import { loadJS } from "@web/core/assets"; + +export class PieChart extends Component { + static template = "awesome_dashboard.pie_chart" + static props = { + label: String, + data: Object, + } + + setup() { + this.canvasRef = useRef('canvas') + onWillStart(() => { + return loadJS("/web/static/lib/Chart/Chart.js") + }) + useEffect(() => this.renderChart()); + onWillUnmount(() => { + if (this.chart) { + this.chart.destroy(); + } + }) + } + + getChartConfig() { + const { mode } = this.model.metaData; + let data; + switch (mode) { + case "bar": + data = this.getBarChartData(); + break; + case "line": + data = this.getLineChartData(); + break; + case "pie": + data = this.getPieChartData(); + } + const options = this.prepareOptions(); + return { data, options, type: mode }; + } + + renderChart() { + if (this.chart) { + this.chart.destroy(); + } + const config = { + type: "pie", + data: { + labels: Object.keys(this.props.data), + datasets: [{ + label: this.props.label, + data: Object.values(this.props.data) + + }], + } + + }; + this.chart = new Chart(this.canvasRef.el, config); + } +} \ No newline at end of file diff --git a/awesome_dashboard/static/src/pie_chart.xml b/awesome_dashboard/static/src/pie_chart.xml new file mode 100644 index 00000000000..a0f7206bf23 --- /dev/null +++ b/awesome_dashboard/static/src/pie_chart.xml @@ -0,0 +1,10 @@ + + + + +
+ +
+
+ +
From f8818edf0728e78842812c989600afa41da4c223 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Wed, 24 Sep 2025 17:15:23 +0200 Subject: [PATCH 07/21] [IMP] dashboard: periodically update statistics --- awesome_dashboard/static/src/dashboard.js | 7 ++----- awesome_dashboard/static/src/dashboard.xml | 2 +- awesome_dashboard/static/src/statistics_service.js | 12 ++++++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/awesome_dashboard/static/src/dashboard.js b/awesome_dashboard/static/src/dashboard.js index 47938b07602..5f7fcf1ba92 100644 --- a/awesome_dashboard/static/src/dashboard.js +++ b/awesome_dashboard/static/src/dashboard.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { Component, onWillStart } from "@odoo/owl"; +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"; @@ -13,10 +13,7 @@ class AwesomeDashboard extends Component { setup() { this.action = useService("action"); - this.statistics_service = useService("statistics_service"); - onWillStart(async () => { - this.statistics = await this.statistics_service.loadStatistics() - }) + this.statistics = useState(useService("statistics_service")); } openCustomers() { diff --git a/awesome_dashboard/static/src/dashboard.xml b/awesome_dashboard/static/src/dashboard.xml index da3540c53f0..41f329eafb1 100644 --- a/awesome_dashboard/static/src/dashboard.xml +++ b/awesome_dashboard/static/src/dashboard.xml @@ -7,7 +7,7 @@ -
+
Average amount of t-shirt by order this month
diff --git a/awesome_dashboard/static/src/statistics_service.js b/awesome_dashboard/static/src/statistics_service.js index 41106ed8078..9030d04315e 100644 --- a/awesome_dashboard/static/src/statistics_service.js +++ b/awesome_dashboard/static/src/statistics_service.js @@ -1,6 +1,6 @@ +import { reactive } from "@odoo/owl"; import { rpc } from "@web/core/network/rpc"; import { registry } from "@web/core/registry"; -import { memoize } from "@web/core/utils/functions"; const fetchStatistics = () => { return rpc("/awesome_dashboard/statistics"); @@ -8,9 +8,13 @@ const fetchStatistics = () => { export const statisticsService = { start() { - return { - loadStatistics: memoize(() => fetchStatistics()), - }; + const statistics = reactive({ isReady: false }); + const updateData = async () => { + Object.assign(statistics, await fetchStatistics(), { isReady: true }); + } + updateData(); + setInterval(updateData, 1000 * 60 * 10); + return statistics; }, } From 670399fbdd9bf5809233ff97d0755518c2df1efd Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Thu, 25 Sep 2025 10:07:41 +0200 Subject: [PATCH 08/21] [IMP] dashboard: lazy load the dashboard --- awesome_dashboard/__manifest__.py | 1 + .../static/src/{ => dashboard}/dashboard.js | 2 +- .../static/src/{ => dashboard}/dashboard.scss | 0 .../static/src/{ => dashboard}/dashboard.xml | 0 .../static/src/{ => dashboard}/dashboard_item.js | 0 .../static/src/{ => dashboard}/dashboard_item.xml | 0 .../static/src/{ => dashboard}/pie_chart.js | 0 .../static/src/{ => dashboard}/pie_chart.xml | 0 .../static/src/{ => dashboard}/statistics_service.js | 0 awesome_dashboard/static/src/dashboard_loader.js | 10 ++++++++++ awesome_dashboard/static/src/dashboard_loader.xml | 8 ++++++++ 11 files changed, 20 insertions(+), 1 deletion(-) rename awesome_dashboard/static/src/{ => dashboard}/dashboard.js (92%) rename awesome_dashboard/static/src/{ => dashboard}/dashboard.scss (100%) rename awesome_dashboard/static/src/{ => dashboard}/dashboard.xml (100%) rename awesome_dashboard/static/src/{ => dashboard}/dashboard_item.js (100%) rename awesome_dashboard/static/src/{ => dashboard}/dashboard_item.xml (100%) rename awesome_dashboard/static/src/{ => dashboard}/pie_chart.js (100%) rename awesome_dashboard/static/src/{ => dashboard}/pie_chart.xml (100%) rename awesome_dashboard/static/src/{ => dashboard}/statistics_service.js (100%) create mode 100644 awesome_dashboard/static/src/dashboard_loader.js create mode 100644 awesome_dashboard/static/src/dashboard_loader.xml diff --git a/awesome_dashboard/__manifest__.py b/awesome_dashboard/__manifest__.py index 31406e8addb..475bc3eabf1 100644 --- a/awesome_dashboard/__manifest__.py +++ b/awesome_dashboard/__manifest__.py @@ -25,6 +25,7 @@ 'web.assets_backend': [ 'awesome_dashboard/static/src/**/*', ], + 'awesome_dashboard.dashboard': ['awesome_dashboard/static/src/dashboard/**/*'], }, 'license': 'AGPL-3' } diff --git a/awesome_dashboard/static/src/dashboard.js b/awesome_dashboard/static/src/dashboard/dashboard.js similarity index 92% rename from awesome_dashboard/static/src/dashboard.js rename to awesome_dashboard/static/src/dashboard/dashboard.js index 5f7fcf1ba92..6bb6bcbfdcc 100644 --- a/awesome_dashboard/static/src/dashboard.js +++ b/awesome_dashboard/static/src/dashboard/dashboard.js @@ -34,4 +34,4 @@ class AwesomeDashboard extends Component { } } -registry.category("actions").add("awesome_dashboard.dashboard", AwesomeDashboard); +registry.category("lazy_components").add("AwesomeDashboard", AwesomeDashboard); diff --git a/awesome_dashboard/static/src/dashboard.scss b/awesome_dashboard/static/src/dashboard/dashboard.scss similarity index 100% rename from awesome_dashboard/static/src/dashboard.scss rename to awesome_dashboard/static/src/dashboard/dashboard.scss diff --git a/awesome_dashboard/static/src/dashboard.xml b/awesome_dashboard/static/src/dashboard/dashboard.xml similarity index 100% rename from awesome_dashboard/static/src/dashboard.xml rename to awesome_dashboard/static/src/dashboard/dashboard.xml diff --git a/awesome_dashboard/static/src/dashboard_item.js b/awesome_dashboard/static/src/dashboard/dashboard_item.js similarity index 100% rename from awesome_dashboard/static/src/dashboard_item.js rename to awesome_dashboard/static/src/dashboard/dashboard_item.js diff --git a/awesome_dashboard/static/src/dashboard_item.xml b/awesome_dashboard/static/src/dashboard/dashboard_item.xml similarity index 100% rename from awesome_dashboard/static/src/dashboard_item.xml rename to awesome_dashboard/static/src/dashboard/dashboard_item.xml diff --git a/awesome_dashboard/static/src/pie_chart.js b/awesome_dashboard/static/src/dashboard/pie_chart.js similarity index 100% rename from awesome_dashboard/static/src/pie_chart.js rename to awesome_dashboard/static/src/dashboard/pie_chart.js diff --git a/awesome_dashboard/static/src/pie_chart.xml b/awesome_dashboard/static/src/dashboard/pie_chart.xml similarity index 100% rename from awesome_dashboard/static/src/pie_chart.xml rename to awesome_dashboard/static/src/dashboard/pie_chart.xml diff --git a/awesome_dashboard/static/src/statistics_service.js b/awesome_dashboard/static/src/dashboard/statistics_service.js similarity index 100% rename from awesome_dashboard/static/src/statistics_service.js rename to awesome_dashboard/static/src/dashboard/statistics_service.js diff --git a/awesome_dashboard/static/src/dashboard_loader.js b/awesome_dashboard/static/src/dashboard_loader.js new file mode 100644 index 00000000000..663530a5081 --- /dev/null +++ b/awesome_dashboard/static/src/dashboard_loader.js @@ -0,0 +1,10 @@ +import { Component } from "@odoo/owl"; +import { registry } from "@web/core/registry"; +import { LazyComponent } from "@web/core/assets"; + +export class DashboardLoader extends Component { + static components = { LazyComponent }; + static template = "awesome_dashboard.loader"; +} + +registry.category("actions").add("awesome_dashboard.dashboard", DashboardLoader); \ No newline at end of file diff --git a/awesome_dashboard/static/src/dashboard_loader.xml b/awesome_dashboard/static/src/dashboard_loader.xml new file mode 100644 index 00000000000..483a2861565 --- /dev/null +++ b/awesome_dashboard/static/src/dashboard_loader.xml @@ -0,0 +1,8 @@ + + + + + + + + From 704adb34f054c7d7fc967f5923e5fd84eed9bdda Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Thu, 25 Sep 2025 15:05:14 +0200 Subject: [PATCH 09/21] [IMP] dashboard: make the dashboard generic --- .../static/src/dashboard/dashboard.js | 5 +- .../static/src/dashboard/dashboard.xml | 40 ++---------- .../static/src/dashboard/dashboard_items.js | 61 +++++++++++++++++++ .../src/dashboard/number_card/number_card.js | 9 +++ .../src/dashboard/number_card/number_card.xml | 11 ++++ .../pie_chart_card/pie_chart_card.js | 11 ++++ .../pie_chart_card/pie_chart_card.xml | 9 +++ 7 files changed, 110 insertions(+), 36 deletions(-) create mode 100644 awesome_dashboard/static/src/dashboard/dashboard_items.js create mode 100644 awesome_dashboard/static/src/dashboard/number_card/number_card.js create mode 100644 awesome_dashboard/static/src/dashboard/number_card/number_card.xml create mode 100644 awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.js create mode 100644 awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.xml diff --git a/awesome_dashboard/static/src/dashboard/dashboard.js b/awesome_dashboard/static/src/dashboard/dashboard.js index 6bb6bcbfdcc..c931bab60e5 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard.js +++ b/awesome_dashboard/static/src/dashboard/dashboard.js @@ -5,15 +5,16 @@ 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 { PieChart } from "./pie_chart"; +import { items } from "./dashboard_items"; class AwesomeDashboard extends Component { static template = "awesome_dashboard.AwesomeDashboard"; - static components = { Layout, DashboardItem, PieChart }; + static components = { Layout, DashboardItem }; setup() { this.action = useService("action"); this.statistics = useState(useService("statistics_service")); + this.items = items; } openCustomers() { diff --git a/awesome_dashboard/static/src/dashboard/dashboard.xml b/awesome_dashboard/static/src/dashboard/dashboard.xml index 41f329eafb1..3904430cafd 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard.xml +++ b/awesome_dashboard/static/src/dashboard/dashboard.xml @@ -8,40 +8,12 @@
- - Average amount of t-shirt by order this month -
- -
-
- - Average time for an order to go from 'new' to 'sent' of 'cancelled' -
- -
-
- - Number of new orders this month -
- -
-
- - Number of cancelled orders this month -
- -
-
- - Total amount of new orders this month -
- -
-
- - Shirt orders by size - - + + + + + +
diff --git a/awesome_dashboard/static/src/dashboard/dashboard_items.js b/awesome_dashboard/static/src/dashboard/dashboard_items.js new file mode 100644 index 00000000000..9ce60e92171 --- /dev/null +++ b/awesome_dashboard/static/src/dashboard/dashboard_items.js @@ -0,0 +1,61 @@ +import { NumberCard } from "./number_card/number_card"; +import { PieChartCard } from "./pie_chart_card/pie_chart_card"; + + +export 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 order", + Component: NumberCard, + props: (data) => ({ + title: "Average time for an order to go from 'new' to 'sent' of 'cancelled'", + value: data.average_time, + }), + }, + { + id: "nb_new_orders", + description: "Number of new orders", + Component: NumberCard, + props: (data) => ({ + title: "Number of new orders this month", + value: data.nb_new_orders, + }), + }, + { + id: "nb_cancelled_orders", + description: "Number of cancelled orders", + Component: NumberCard, + props: (data) => ({ + title: "Number of cancelled orders this month", + value: data.nb_cancelled_orders, + }), + }, + { + id: "total_amount", + description: "Number of new orders", + Component: NumberCard, + props: (data) => ({ + title: "Total amount of new orders this month", + value: data.total_amount, + }), + }, + { + id: "orders_by_size", + description: "Shirt orders by size", + Component: PieChartCard, + size: 2, + props: (data) => ({ + title: "Shirt orders by size", + value: data['orders_by_size'], + }), + }, +] \ No newline at end of file diff --git a/awesome_dashboard/static/src/dashboard/number_card/number_card.js b/awesome_dashboard/static/src/dashboard/number_card/number_card.js new file mode 100644 index 00000000000..715e3346b01 --- /dev/null +++ b/awesome_dashboard/static/src/dashboard/number_card/number_card.js @@ -0,0 +1,9 @@ +import { Component } from "@odoo/owl"; + +export class NumberCard extends Component { + static template = "awesome_dashboard.number_card"; + static props = { + title: String, + value: Number, + } +} \ No newline at end of file diff --git a/awesome_dashboard/static/src/dashboard/number_card/number_card.xml b/awesome_dashboard/static/src/dashboard/number_card/number_card.xml new file mode 100644 index 00000000000..1b2e1692df1 --- /dev/null +++ b/awesome_dashboard/static/src/dashboard/number_card/number_card.xml @@ -0,0 +1,11 @@ + + + + + +
+ +
+
+ +
diff --git a/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.js b/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.js new file mode 100644 index 00000000000..83fb591ce46 --- /dev/null +++ b/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.js @@ -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, + value: Object, + } +} \ No newline at end of file diff --git a/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.xml b/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.xml new file mode 100644 index 00000000000..90b0d388fd4 --- /dev/null +++ b/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.xml @@ -0,0 +1,9 @@ + + + + + + + + + From aec952094bda9724b40d9b5a32b9017835223457 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Thu, 25 Sep 2025 15:21:05 +0200 Subject: [PATCH 10/21] [IMP] dashbaord: make the dashboard estensible --- awesome_dashboard/static/src/dashboard/dashboard.js | 4 ++-- awesome_dashboard/static/src/dashboard/dashboard_items.js | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/awesome_dashboard/static/src/dashboard/dashboard.js b/awesome_dashboard/static/src/dashboard/dashboard.js index c931bab60e5..da21555c0f5 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard.js +++ b/awesome_dashboard/static/src/dashboard/dashboard.js @@ -5,7 +5,7 @@ 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 { items } from "./dashboard_items"; + class AwesomeDashboard extends Component { static template = "awesome_dashboard.AwesomeDashboard"; @@ -14,7 +14,7 @@ class AwesomeDashboard extends Component { setup() { this.action = useService("action"); this.statistics = useState(useService("statistics_service")); - this.items = items; + this.items = registry.category("awesome_dashboard").getAll(); } openCustomers() { diff --git a/awesome_dashboard/static/src/dashboard/dashboard_items.js b/awesome_dashboard/static/src/dashboard/dashboard_items.js index 9ce60e92171..36624171790 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard_items.js +++ b/awesome_dashboard/static/src/dashboard/dashboard_items.js @@ -1,6 +1,6 @@ import { NumberCard } from "./number_card/number_card"; import { PieChartCard } from "./pie_chart_card/pie_chart_card"; - +import { registry } from "@web/core/registry"; export const items = [ { @@ -58,4 +58,8 @@ export const items = [ value: data['orders_by_size'], }), }, -] \ No newline at end of file +] + +items.forEach(item => { + registry.category("awesome_dashboard").add(item.id, item); +}); \ No newline at end of file From 10d91f01114e262205a3a1ecb923c51ba09aa2b5 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Fri, 26 Sep 2025 14:50:14 +0200 Subject: [PATCH 11/21] [IMP] dashboard: add and remove dashboard items --- .../configuration_dialog.js | 42 +++++++++++++++++++ .../configuration_dialog.xml | 18 ++++++++ .../static/src/dashboard/dashboard.js | 19 +++++++++ .../static/src/dashboard/dashboard.xml | 7 +++- 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.js create mode 100644 awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.xml diff --git a/awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.js b/awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.js new file mode 100644 index 00000000000..8f2d9a6de80 --- /dev/null +++ b/awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.js @@ -0,0 +1,42 @@ +import { Component, useState } from "@odoo/owl"; +import { Dialog } from "@web/core/dialog/dialog"; +import { CheckBox } from "@web/core/checkbox/checkbox"; + + +export class ConfigurationDialog extends Component { + static template = "awesome_dashboard.ConfigurationDialog"; + static components = { Dialog, CheckBox }; + static props = { + items: { type: Array }, + disabledItems: { + type: Array, + element: { + type: { String }, + } + }, + onUpdateConfig: Function, + close: Function, + } + + setup() { + this.items = useState(this.props.items.map((item) => { + return { + id: item.id, + description: item.description, + enabled: !this.props.disabledItems.includes(item.id), + } + })); + } + + onChange(checked, item) { + item.enabled = checked; + const updatedDisabledItems = Object.values(this.items).filter( + (item) => !item.enabled + ).map((item) => item.id); + this.props.onUpdateConfig(updatedDisabledItems); + } + + done() { + this.props.close(); + } +} diff --git a/awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.xml b/awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.xml new file mode 100644 index 00000000000..842689a1e8a --- /dev/null +++ b/awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.xml @@ -0,0 +1,18 @@ + + + + + Which cards do you wish to see? + + + + + + + + + + + diff --git a/awesome_dashboard/static/src/dashboard/dashboard.js b/awesome_dashboard/static/src/dashboard/dashboard.js index da21555c0f5..197210ce401 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard.js +++ b/awesome_dashboard/static/src/dashboard/dashboard.js @@ -5,6 +5,8 @@ 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 { ConfigurationDialog } from "./configuration_dialog/configuration_dialog"; +import { browser } from "@web/core/browser/browser"; class AwesomeDashboard extends Component { @@ -15,6 +17,10 @@ class AwesomeDashboard extends Component { this.action = useService("action"); this.statistics = useState(useService("statistics_service")); this.items = registry.category("awesome_dashboard").getAll(); + this.dialog = useService("dialog"); + this.disabledItems = useState( + { values: browser.localStorage.getItem("disabledDashboardItems")?.split(",") || [] } + ); } openCustomers() { @@ -33,6 +39,19 @@ class AwesomeDashboard extends Component { ], }); } + + updateConfig(newDisabledItems) { + this.disabledItems.values = newDisabledItems; + browser.localStorage.setItem("disabledDashboardItems", newDisabledItems); + } + + openConfig() { + this.dialog.add(ConfigurationDialog, { + items: this.items, + disabledItems: this.disabledItems.values, + onUpdateConfig: this.updateConfig.bind(this), + }); + } } registry.category("lazy_components").add("AwesomeDashboard", AwesomeDashboard); diff --git a/awesome_dashboard/static/src/dashboard/dashboard.xml b/awesome_dashboard/static/src/dashboard/dashboard.xml index 3904430cafd..d7d7eb11fba 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard.xml +++ b/awesome_dashboard/static/src/dashboard/dashboard.xml @@ -7,9 +7,14 @@ + + +
- + From 62a0dcbf54448fa87fac466e2d0334a5a52b2d29 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Fri, 26 Sep 2025 15:23:24 +0200 Subject: [PATCH 12/21] [IMP] dashboard: add new lines to files that didn't have it at the end, make templates use Pascal Case, do some cleanup in some js files --- .../static/src/dashboard/dashboard.js | 2 -- .../static/src/dashboard/dashboard.scss | 2 +- .../static/src/dashboard/dashboard.xml | 2 +- .../static/src/dashboard/dashboard_item.js | 4 +-- .../static/src/dashboard/dashboard_item.xml | 2 +- .../static/src/dashboard/dashboard_items.js | 2 +- .../src/dashboard/number_card/number_card.js | 4 +-- .../src/dashboard/number_card/number_card.xml | 2 +- .../static/src/dashboard/pie_chart.js | 29 +++---------------- .../static/src/dashboard/pie_chart.xml | 2 +- .../pie_chart_card/pie_chart_card.js | 4 +-- .../pie_chart_card/pie_chart_card.xml | 2 +- .../src/dashboard/statistics_service.js | 2 +- .../static/src/dashboard_loader.js | 4 +-- .../static/src/dashboard_loader.xml | 2 +- 15 files changed, 21 insertions(+), 44 deletions(-) diff --git a/awesome_dashboard/static/src/dashboard/dashboard.js b/awesome_dashboard/static/src/dashboard/dashboard.js index 197210ce401..fcb675fb174 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard.js +++ b/awesome_dashboard/static/src/dashboard/dashboard.js @@ -1,5 +1,3 @@ -/** @odoo-module **/ - import { Component, useState } from "@odoo/owl"; import { registry } from "@web/core/registry"; import { Layout } from "@web/search/layout"; diff --git a/awesome_dashboard/static/src/dashboard/dashboard.scss b/awesome_dashboard/static/src/dashboard/dashboard.scss index 769fc1e72f9..32862ec0d82 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard.scss +++ b/awesome_dashboard/static/src/dashboard/dashboard.scss @@ -1,3 +1,3 @@ .o_dashboard { background-color: gray; -} \ No newline at end of file +} diff --git a/awesome_dashboard/static/src/dashboard/dashboard.xml b/awesome_dashboard/static/src/dashboard/dashboard.xml index d7d7eb11fba..ac47651fe02 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard.xml +++ b/awesome_dashboard/static/src/dashboard/dashboard.xml @@ -14,7 +14,7 @@
- + diff --git a/awesome_dashboard/static/src/dashboard/dashboard_item.js b/awesome_dashboard/static/src/dashboard/dashboard_item.js index 8230bd52176..27e17d4e865 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard_item.js +++ b/awesome_dashboard/static/src/dashboard/dashboard_item.js @@ -1,7 +1,7 @@ import { Component } from "@odoo/owl"; export class DashboardItem extends Component { - static template = "awesome_dashboard.dashboard_item"; + static template = "awesome_dashboard.DashboardItem"; static props = { slots: Object, size: { @@ -12,4 +12,4 @@ export class DashboardItem extends Component { static defaultProps = { size: 1, } -} \ No newline at end of file +} diff --git a/awesome_dashboard/static/src/dashboard/dashboard_item.xml b/awesome_dashboard/static/src/dashboard/dashboard_item.xml index 60d473564fa..19401f5a238 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard_item.xml +++ b/awesome_dashboard/static/src/dashboard/dashboard_item.xml @@ -1,7 +1,7 @@ - +
diff --git a/awesome_dashboard/static/src/dashboard/dashboard_items.js b/awesome_dashboard/static/src/dashboard/dashboard_items.js index 36624171790..29045da32d1 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard_items.js +++ b/awesome_dashboard/static/src/dashboard/dashboard_items.js @@ -62,4 +62,4 @@ export const items = [ items.forEach(item => { registry.category("awesome_dashboard").add(item.id, item); -}); \ No newline at end of file +}); diff --git a/awesome_dashboard/static/src/dashboard/number_card/number_card.js b/awesome_dashboard/static/src/dashboard/number_card/number_card.js index 715e3346b01..3296d42cb9b 100644 --- a/awesome_dashboard/static/src/dashboard/number_card/number_card.js +++ b/awesome_dashboard/static/src/dashboard/number_card/number_card.js @@ -1,9 +1,9 @@ import { Component } from "@odoo/owl"; export class NumberCard extends Component { - static template = "awesome_dashboard.number_card"; + static template = "awesome_dashboard.NumberCard"; static props = { title: String, value: Number, } -} \ No newline at end of file +} diff --git a/awesome_dashboard/static/src/dashboard/number_card/number_card.xml b/awesome_dashboard/static/src/dashboard/number_card/number_card.xml index 1b2e1692df1..957fa1ea5ea 100644 --- a/awesome_dashboard/static/src/dashboard/number_card/number_card.xml +++ b/awesome_dashboard/static/src/dashboard/number_card/number_card.xml @@ -1,7 +1,7 @@ - +
diff --git a/awesome_dashboard/static/src/dashboard/pie_chart.js b/awesome_dashboard/static/src/dashboard/pie_chart.js index fed152563c7..662714f3052 100644 --- a/awesome_dashboard/static/src/dashboard/pie_chart.js +++ b/awesome_dashboard/static/src/dashboard/pie_chart.js @@ -2,7 +2,7 @@ import { Component, onWillStart, useRef, useEffect, onWillUnmount } from "@odoo/ import { loadJS } from "@web/core/assets"; export class PieChart extends Component { - static template = "awesome_dashboard.pie_chart" + static template = "awesome_dashboard.PieChart" static props = { label: String, data: Object, @@ -15,33 +15,12 @@ export class PieChart extends Component { }) useEffect(() => this.renderChart()); onWillUnmount(() => { - if (this.chart) { - this.chart.destroy(); - } + this.chart?.destroy(); }) } - getChartConfig() { - const { mode } = this.model.metaData; - let data; - switch (mode) { - case "bar": - data = this.getBarChartData(); - break; - case "line": - data = this.getLineChartData(); - break; - case "pie": - data = this.getPieChartData(); - } - const options = this.prepareOptions(); - return { data, options, type: mode }; - } - renderChart() { - if (this.chart) { - this.chart.destroy(); - } + this.chart?.destroy(); const config = { type: "pie", data: { @@ -56,4 +35,4 @@ export class PieChart extends Component { }; this.chart = new Chart(this.canvasRef.el, config); } -} \ No newline at end of file +} diff --git a/awesome_dashboard/static/src/dashboard/pie_chart.xml b/awesome_dashboard/static/src/dashboard/pie_chart.xml index a0f7206bf23..cd1494e3e87 100644 --- a/awesome_dashboard/static/src/dashboard/pie_chart.xml +++ b/awesome_dashboard/static/src/dashboard/pie_chart.xml @@ -1,7 +1,7 @@ - +
diff --git a/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.js b/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.js index 83fb591ce46..ab16dd33fe1 100644 --- a/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.js +++ b/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.js @@ -2,10 +2,10 @@ import { Component } from "@odoo/owl"; import { PieChart } from "../pie_chart"; export class PieChartCard extends Component { - static template = "awesome_dashboard.pie_chart_card"; + static template = "awesome_dashboard.PieChartCard"; static components = { PieChart }; static props = { title: String, value: Object, } -} \ No newline at end of file +} diff --git a/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.xml b/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.xml index 90b0d388fd4..43e32cf4c24 100644 --- a/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.xml +++ b/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.xml @@ -1,7 +1,7 @@ - + diff --git a/awesome_dashboard/static/src/dashboard/statistics_service.js b/awesome_dashboard/static/src/dashboard/statistics_service.js index 9030d04315e..aa55ee9c731 100644 --- a/awesome_dashboard/static/src/dashboard/statistics_service.js +++ b/awesome_dashboard/static/src/dashboard/statistics_service.js @@ -18,4 +18,4 @@ export const statisticsService = { }, } -registry.category("services").add("statistics_service", statisticsService); \ No newline at end of file +registry.category("services").add("statistics_service", statisticsService); diff --git a/awesome_dashboard/static/src/dashboard_loader.js b/awesome_dashboard/static/src/dashboard_loader.js index 663530a5081..2bfa18bb3c6 100644 --- a/awesome_dashboard/static/src/dashboard_loader.js +++ b/awesome_dashboard/static/src/dashboard_loader.js @@ -4,7 +4,7 @@ import { LazyComponent } from "@web/core/assets"; export class DashboardLoader extends Component { static components = { LazyComponent }; - static template = "awesome_dashboard.loader"; + static template = "awesome_dashboard.Loader"; } -registry.category("actions").add("awesome_dashboard.dashboard", DashboardLoader); \ No newline at end of file +registry.category("actions").add("awesome_dashboard.dashboard", DashboardLoader); diff --git a/awesome_dashboard/static/src/dashboard_loader.xml b/awesome_dashboard/static/src/dashboard_loader.xml index 483a2861565..f17e7127acd 100644 --- a/awesome_dashboard/static/src/dashboard_loader.xml +++ b/awesome_dashboard/static/src/dashboard_loader.xml @@ -1,7 +1,7 @@ - + From 93eba2e44792101c604891fa759c5cbdfc51be64 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Mon, 29 Sep 2025 09:29:08 +0200 Subject: [PATCH 13/21] [IMP] dashboard: allow variable chart type --- .../static/src/dashboard/chart_card/chart_card.js | 12 ++++++++++++ .../pie_chart_card.xml => chart_card/chart_card.xml} | 4 ++-- .../dashboard/{pie_chart.js => dashboard_chart.js} | 7 ++++--- .../dashboard/{pie_chart.xml => dashboard_chart.xml} | 2 +- .../static/src/dashboard/dashboard_items.js | 5 +++-- .../src/dashboard/pie_chart_card/pie_chart_card.js | 11 ----------- 6 files changed, 22 insertions(+), 19 deletions(-) create mode 100644 awesome_dashboard/static/src/dashboard/chart_card/chart_card.js rename awesome_dashboard/static/src/dashboard/{pie_chart_card/pie_chart_card.xml => chart_card/chart_card.xml} (50%) rename awesome_dashboard/static/src/dashboard/{pie_chart.js => dashboard_chart.js} (80%) rename awesome_dashboard/static/src/dashboard/{pie_chart.xml => dashboard_chart.xml} (81%) delete mode 100644 awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.js diff --git a/awesome_dashboard/static/src/dashboard/chart_card/chart_card.js b/awesome_dashboard/static/src/dashboard/chart_card/chart_card.js new file mode 100644 index 00000000000..5a0c4db1fec --- /dev/null +++ b/awesome_dashboard/static/src/dashboard/chart_card/chart_card.js @@ -0,0 +1,12 @@ +import { Component } from "@odoo/owl"; +import { DashboardChart } from "../dashboard_chart"; + +export class ChartCard extends Component { + static template = "awesome_dashboard.ChartCard"; + static components = { DashboardChart }; + static props = { + title: String, + value: Object, + type: String, + } +} diff --git a/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.xml b/awesome_dashboard/static/src/dashboard/chart_card/chart_card.xml similarity index 50% rename from awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.xml rename to awesome_dashboard/static/src/dashboard/chart_card/chart_card.xml index 43e32cf4c24..a1403939c78 100644 --- a/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.xml +++ b/awesome_dashboard/static/src/dashboard/chart_card/chart_card.xml @@ -1,9 +1,9 @@ - + - + diff --git a/awesome_dashboard/static/src/dashboard/pie_chart.js b/awesome_dashboard/static/src/dashboard/dashboard_chart.js similarity index 80% rename from awesome_dashboard/static/src/dashboard/pie_chart.js rename to awesome_dashboard/static/src/dashboard/dashboard_chart.js index 662714f3052..d72b99aa173 100644 --- a/awesome_dashboard/static/src/dashboard/pie_chart.js +++ b/awesome_dashboard/static/src/dashboard/dashboard_chart.js @@ -1,11 +1,12 @@ import { Component, onWillStart, useRef, useEffect, onWillUnmount } from "@odoo/owl"; import { loadJS } from "@web/core/assets"; -export class PieChart extends Component { - static template = "awesome_dashboard.PieChart" +export class DashboardChart extends Component { + static template = "awesome_dashboard.DashboardChart" static props = { label: String, data: Object, + type: { validate: t => ["pie", "bar", "line"].includes(t) }, } setup() { @@ -22,7 +23,7 @@ export class PieChart extends Component { renderChart() { this.chart?.destroy(); const config = { - type: "pie", + type: this.props.type, data: { labels: Object.keys(this.props.data), datasets: [{ diff --git a/awesome_dashboard/static/src/dashboard/pie_chart.xml b/awesome_dashboard/static/src/dashboard/dashboard_chart.xml similarity index 81% rename from awesome_dashboard/static/src/dashboard/pie_chart.xml rename to awesome_dashboard/static/src/dashboard/dashboard_chart.xml index cd1494e3e87..d62b10926dd 100644 --- a/awesome_dashboard/static/src/dashboard/pie_chart.xml +++ b/awesome_dashboard/static/src/dashboard/dashboard_chart.xml @@ -1,7 +1,7 @@ - +
diff --git a/awesome_dashboard/static/src/dashboard/dashboard_items.js b/awesome_dashboard/static/src/dashboard/dashboard_items.js index 29045da32d1..79594c2736c 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard_items.js +++ b/awesome_dashboard/static/src/dashboard/dashboard_items.js @@ -1,5 +1,5 @@ import { NumberCard } from "./number_card/number_card"; -import { PieChartCard } from "./pie_chart_card/pie_chart_card"; +import { ChartCard } from "./chart_card/chart_card"; import { registry } from "@web/core/registry"; export const items = [ @@ -51,11 +51,12 @@ export const items = [ { id: "orders_by_size", description: "Shirt orders by size", - Component: PieChartCard, + Component: ChartCard, size: 2, props: (data) => ({ title: "Shirt orders by size", value: data['orders_by_size'], + type: "pie" }), }, ] diff --git a/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.js b/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.js deleted file mode 100644 index ab16dd33fe1..00000000000 --- a/awesome_dashboard/static/src/dashboard/pie_chart_card/pie_chart_card.js +++ /dev/null @@ -1,11 +0,0 @@ -import { Component } from "@odoo/owl"; -import { PieChart } from "../pie_chart"; - -export class PieChartCard extends Component { - static template = "awesome_dashboard.PieChartCard"; - static components = { PieChart }; - static props = { - title: String, - value: Object, - } -} From bbd55c610ca306913f967c831c3b72abc8bd4ea4 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Mon, 29 Sep 2025 09:33:25 +0200 Subject: [PATCH 14/21] [IMP] dashboard: update formatting in configuration_dialog --- .../src/dashboard/configuration_dialog/configuration_dialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.js b/awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.js index 8f2d9a6de80..3e3cb2433c5 100644 --- a/awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.js +++ b/awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.js @@ -11,7 +11,7 @@ export class ConfigurationDialog extends Component { disabledItems: { type: Array, element: { - type: { String }, + type: String, } }, onUpdateConfig: Function, From 9c6d675d67b2d02cae13fb8d52c7b383fd54dfee Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Mon, 29 Sep 2025 09:33:57 +0200 Subject: [PATCH 15/21] [IMP] dashboard: remove unnecessary browser import --- awesome_dashboard/static/src/dashboard/dashboard.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/awesome_dashboard/static/src/dashboard/dashboard.js b/awesome_dashboard/static/src/dashboard/dashboard.js index fcb675fb174..dcb65a6a8ed 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard.js +++ b/awesome_dashboard/static/src/dashboard/dashboard.js @@ -4,7 +4,6 @@ import { Layout } from "@web/search/layout"; import { useService } from "@web/core/utils/hooks"; import { DashboardItem } from "./dashboard_item"; import { ConfigurationDialog } from "./configuration_dialog/configuration_dialog"; -import { browser } from "@web/core/browser/browser"; class AwesomeDashboard extends Component { @@ -17,7 +16,7 @@ class AwesomeDashboard extends Component { this.items = registry.category("awesome_dashboard").getAll(); this.dialog = useService("dialog"); this.disabledItems = useState( - { values: browser.localStorage.getItem("disabledDashboardItems")?.split(",") || [] } + { values: localStorage.getItem("disabledDashboardItems")?.split(",") || [] } ); } @@ -40,7 +39,7 @@ class AwesomeDashboard extends Component { updateConfig(newDisabledItems) { this.disabledItems.values = newDisabledItems; - browser.localStorage.setItem("disabledDashboardItems", newDisabledItems); + localStorage.setItem("disabledDashboardItems", newDisabledItems); } openConfig() { From e490a773604402f2e360ec9dc9b6090ea841c914 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Mon, 29 Sep 2025 11:16:26 +0200 Subject: [PATCH 16/21] [IMP] dashboard: make titles translatable --- .../static/src/dashboard/dashboard_items.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/awesome_dashboard/static/src/dashboard/dashboard_items.js b/awesome_dashboard/static/src/dashboard/dashboard_items.js index 79594c2736c..da96ca70a73 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard_items.js +++ b/awesome_dashboard/static/src/dashboard/dashboard_items.js @@ -1,6 +1,7 @@ import { NumberCard } from "./number_card/number_card"; import { ChartCard } from "./chart_card/chart_card"; import { registry } from "@web/core/registry"; +import { _t } from "@web/core/l10n/translation"; export const items = [ { @@ -8,7 +9,7 @@ export const items = [ description: "Average amount of t-shirt", Component: NumberCard, props: (data) => ({ - title: "Average amount of t-shirt by order this month", + title: _t("Average amount of t-shirt by order this month"), value: data.average_quantity, }), }, @@ -17,7 +18,7 @@ export const items = [ description: "Average time for order", Component: NumberCard, props: (data) => ({ - title: "Average time for an order to go from 'new' to 'sent' of 'cancelled'", + title: _t("Average time for an order to go from 'new' to 'sent' of 'cancelled'"), value: data.average_time, }), }, @@ -26,7 +27,7 @@ export const items = [ description: "Number of new orders", Component: NumberCard, props: (data) => ({ - title: "Number of new orders this month", + title: _t("Number of new orders this month"), value: data.nb_new_orders, }), }, @@ -35,7 +36,7 @@ export const items = [ description: "Number of cancelled orders", Component: NumberCard, props: (data) => ({ - title: "Number of cancelled orders this month", + title: _t("Number of cancelled orders this month"), value: data.nb_cancelled_orders, }), }, @@ -44,7 +45,7 @@ export const items = [ description: "Number of new orders", Component: NumberCard, props: (data) => ({ - title: "Total amount of new orders this month", + title: _t("Total amount of new orders this month"), value: data.total_amount, }), }, @@ -54,7 +55,7 @@ export const items = [ Component: ChartCard, size: 2, props: (data) => ({ - title: "Shirt orders by size", + title: _t("Shirt orders by size"), value: data['orders_by_size'], type: "pie" }), From 55a69a3a4c6f2c63fd56d677ca7585e490eee322 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Mon, 29 Sep 2025 11:17:42 +0200 Subject: [PATCH 17/21] [I18N] dashboard: add arabic translations --- awesome_dashboard/i18n/ar_001.po | 87 ++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 awesome_dashboard/i18n/ar_001.po diff --git a/awesome_dashboard/i18n/ar_001.po b/awesome_dashboard/i18n/ar_001.po new file mode 100644 index 00000000000..e836bf4fc2b --- /dev/null +++ b/awesome_dashboard/i18n/ar_001.po @@ -0,0 +1,87 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * awesome_dashboard +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-29 07:53+0000\n" +"PO-Revision-Date: 2025-09-29 07:53+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: awesome_dashboard +#. odoo-javascript +#: code:addons/awesome_dashboard/static/src/dashboard/dashboard_items.js:0 +msgid "Average amount of t-shirt by order this month" +msgstr "Average amount of t-shirt by order this month (AR)" + +#. module: awesome_dashboard +#. odoo-javascript +#: code:addons/awesome_dashboard/static/src/dashboard/dashboard_items.js:0 +msgid "Average time for an order to go from 'new' to 'sent' of 'cancelled'" +msgstr "Average time for an order to go from 'new' to 'sent' of 'cancelled' (AR)" + +#. module: awesome_dashboard +#: model:ir.ui.menu,name:awesome_dashboard.menu_root +msgid "Awesome Dashboard" +msgstr "Awesome Dashboard (AR)" + +#. module: awesome_dashboard +#. odoo-javascript +#: code:addons/awesome_dashboard/static/src/dashboard/dashboard.xml:0 +msgid "Customers" +msgstr "Customers (AR)" + +#. module: awesome_dashboard +#: model:ir.actions.client,name:awesome_dashboard.dashboard +#: model:ir.ui.menu,name:awesome_dashboard.dashboard_menu +msgid "Dashboard" +msgstr "Dashboard (AR)" + +#. module: awesome_dashboard +#. odoo-javascript +#: code:addons/awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.xml:0 +msgid "Done" +msgstr "Done (AR)" + +#. module: awesome_dashboard +#. odoo-javascript +#: code:addons/awesome_dashboard/static/src/dashboard/dashboard.xml:0 +msgid "Leads" +msgstr "Leads (AR)" + +#. module: awesome_dashboard +#. odoo-javascript +#: code:addons/awesome_dashboard/static/src/dashboard/dashboard_items.js:0 +msgid "Number of cancelled orders this month" +msgstr "Number of cancelled orders this month (AR)" + +#. module: awesome_dashboard +#. odoo-javascript +#: code:addons/awesome_dashboard/static/src/dashboard/dashboard_items.js:0 +msgid "Number of new orders this month" +msgstr "Number of new orders this month (AR)" + +#. module: awesome_dashboard +#. odoo-javascript +#: code:addons/awesome_dashboard/static/src/dashboard/dashboard_items.js:0 +msgid "Shirt orders by size" +msgstr "Shirt orders by size (AR)" + +#. module: awesome_dashboard +#. odoo-javascript +#: code:addons/awesome_dashboard/static/src/dashboard/dashboard_items.js:0 +msgid "Total amount of new orders this month" +msgstr "Total amount of new orders this month (AR)" + +#. module: awesome_dashboard +#. odoo-javascript +#: code:addons/awesome_dashboard/static/src/dashboard/configuration_dialog/configuration_dialog.xml:0 +msgid "Which cards do you wish to see?" +msgstr "Which cards do you wish to see (AR)?" From f66adc5c039470e570c0dae404e4ef0660ae55a6 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Mon, 29 Sep 2025 15:48:02 +0200 Subject: [PATCH 18/21] [IMP] dashboard: store user dashboard preferences in the DB instead of local storage --- awesome_dashboard/__init__.py | 1 + awesome_dashboard/models/__init__.py | 1 + awesome_dashboard/models/res_users_settings.py | 7 +++++++ .../static/src/dashboard/dashboard.js | 16 ++++++++++++---- 4 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 awesome_dashboard/models/__init__.py create mode 100644 awesome_dashboard/models/res_users_settings.py diff --git a/awesome_dashboard/__init__.py b/awesome_dashboard/__init__.py index b0f26a9a602..aa4d0fd63a9 100644 --- a/awesome_dashboard/__init__.py +++ b/awesome_dashboard/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- from . import controllers +from . import models diff --git a/awesome_dashboard/models/__init__.py b/awesome_dashboard/models/__init__.py new file mode 100644 index 00000000000..82fcc4bfe96 --- /dev/null +++ b/awesome_dashboard/models/__init__.py @@ -0,0 +1 @@ +from . import res_users_settings diff --git a/awesome_dashboard/models/res_users_settings.py b/awesome_dashboard/models/res_users_settings.py new file mode 100644 index 00000000000..eead5b6a8e3 --- /dev/null +++ b/awesome_dashboard/models/res_users_settings.py @@ -0,0 +1,7 @@ +from odoo import models, fields + + +class ResUsersSettings(models.Model): + _inherit = ["res.users.settings"] + + disabled_dashboard_items = fields.Text("Disabled dashboard items") diff --git a/awesome_dashboard/static/src/dashboard/dashboard.js b/awesome_dashboard/static/src/dashboard/dashboard.js index dcb65a6a8ed..017490ba1c8 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard.js +++ b/awesome_dashboard/static/src/dashboard/dashboard.js @@ -4,7 +4,7 @@ import { Layout } from "@web/search/layout"; import { useService } from "@web/core/utils/hooks"; import { DashboardItem } from "./dashboard_item"; import { ConfigurationDialog } from "./configuration_dialog/configuration_dialog"; - +import { user } from "@web/core/user"; class AwesomeDashboard extends Component { static template = "awesome_dashboard.AwesomeDashboard"; @@ -16,8 +16,16 @@ class AwesomeDashboard extends Component { this.items = registry.category("awesome_dashboard").getAll(); this.dialog = useService("dialog"); this.disabledItems = useState( - { values: localStorage.getItem("disabledDashboardItems")?.split(",") || [] } - ); + { + values: this.getDisabledItems() + } + ) + } + + getDisabledItems() { + const disabled_items = user.settings.disabled_dashboard_items; + if (!disabled_items) return []; + return disabled_items.split(","); } openCustomers() { @@ -39,7 +47,7 @@ class AwesomeDashboard extends Component { updateConfig(newDisabledItems) { this.disabledItems.values = newDisabledItems; - localStorage.setItem("disabledDashboardItems", newDisabledItems); + user.setUserSettings("disabled_dashboard_items", this.disabledItems.values.join(",")); } openConfig() { From a7e1441a8db5bbea17f95370ab16dcd8fb3cb114 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 30 Sep 2025 09:42:08 +0200 Subject: [PATCH 19/21] [IMP] dashboard: tidy up the get disabled items function --- awesome_dashboard/static/src/dashboard/dashboard.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/awesome_dashboard/static/src/dashboard/dashboard.js b/awesome_dashboard/static/src/dashboard/dashboard.js index 017490ba1c8..fc4f974a1c0 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard.js +++ b/awesome_dashboard/static/src/dashboard/dashboard.js @@ -24,8 +24,7 @@ class AwesomeDashboard extends Component { getDisabledItems() { const disabled_items = user.settings.disabled_dashboard_items; - if (!disabled_items) return []; - return disabled_items.split(","); + return disabled_items ? disabled_items.split(",") : []; } openCustomers() { From dc5abeb1b5aacf5c922505a2d105b4333817805c Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 30 Sep 2025 10:31:39 +0200 Subject: [PATCH 20/21] [IMP] dashboard: use more concise naming for disabled items variable --- awesome_dashboard/static/src/dashboard/dashboard.js | 12 ++++-------- awesome_dashboard/static/src/dashboard/dashboard.xml | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/awesome_dashboard/static/src/dashboard/dashboard.js b/awesome_dashboard/static/src/dashboard/dashboard.js index fc4f974a1c0..c2e1c669a39 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard.js +++ b/awesome_dashboard/static/src/dashboard/dashboard.js @@ -15,11 +15,7 @@ class AwesomeDashboard extends Component { this.statistics = useState(useService("statistics_service")); this.items = registry.category("awesome_dashboard").getAll(); this.dialog = useService("dialog"); - this.disabledItems = useState( - { - values: this.getDisabledItems() - } - ) + this.state = useState({ disabledItems: this.getDisabledItems() }) } getDisabledItems() { @@ -45,14 +41,14 @@ class AwesomeDashboard extends Component { } updateConfig(newDisabledItems) { - this.disabledItems.values = newDisabledItems; - user.setUserSettings("disabled_dashboard_items", this.disabledItems.values.join(",")); + this.state.disabledItems = newDisabledItems; + user.setUserSettings("disabled_dashboard_items", this.state.disabledItems.join(",")); } openConfig() { this.dialog.add(ConfigurationDialog, { items: this.items, - disabledItems: this.disabledItems.values, + disabledItems: this.state.disabledItems, onUpdateConfig: this.updateConfig.bind(this), }); } diff --git a/awesome_dashboard/static/src/dashboard/dashboard.xml b/awesome_dashboard/static/src/dashboard/dashboard.xml index ac47651fe02..087207dfd50 100644 --- a/awesome_dashboard/static/src/dashboard/dashboard.xml +++ b/awesome_dashboard/static/src/dashboard/dashboard.xml @@ -14,7 +14,7 @@
- + From d8b2a2cf0c9808fe2292b8a32a9df883edd0e673 Mon Sep 17 00:00:00 2001 From: Mohamed Ayman Date: Tue, 30 Sep 2025 10:36:52 +0200 Subject: [PATCH 21/21] [IMP] dashboard: remove unnecessary default string, unnecessary array when inheriting --- awesome_dashboard/models/res_users_settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/awesome_dashboard/models/res_users_settings.py b/awesome_dashboard/models/res_users_settings.py index eead5b6a8e3..3ce39b0d6c0 100644 --- a/awesome_dashboard/models/res_users_settings.py +++ b/awesome_dashboard/models/res_users_settings.py @@ -2,6 +2,6 @@ class ResUsersSettings(models.Model): - _inherit = ["res.users.settings"] + _inherit = "res.users.settings" - disabled_dashboard_items = fields.Text("Disabled dashboard items") + disabled_dashboard_items = fields.Text()