diff --git a/awesome_dashboard/static/src/dashboard.js b/awesome_dashboard/static/src/dashboard.js
index c4fb245621b..4109e3d781b 100644
--- a/awesome_dashboard/static/src/dashboard.js
+++ b/awesome_dashboard/static/src/dashboard.js
@@ -1,8 +1,40 @@
-import { Component } from "@odoo/owl";
+import { Component, onWillStart } from "@odoo/owl";
+import { _t } from "@web/core/l10n/translation";
import { registry } from "@web/core/registry";
+import { useService } from "@web/core/utils/hooks";
+import { Layout } from "@web/search/layout";
+
+import { DashboardItem } from "./dashboardItem/dashboardItem";
+import { PieChart } from "./pieChart/pie_chart";
class AwesomeDashboard extends Component {
static template = "awesome_dashboard.AwesomeDashboard";
+ static components = { Layout, DashboardItem, PieChart };
+
+ setup() {
+ this.action = useService("action");
+ const statisticsService = useService("awesome_dashboard.statistics");
+
+ onWillStart(async () => {
+ this.statistics = await statisticsService.loadStatistics();
+ });
+ }
+
+ openCustomers() {
+ this.action.doAction("base.action_partner_form");
+ }
+
+ openLeads() {
+ this.action.doAction({
+ type: 'ir.actions.act_window',
+ name: _t("CRM Leads"),
+ 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 1a2ac9a2fed..90973a9daea 100644
--- a/awesome_dashboard/static/src/dashboard.xml
+++ b/awesome_dashboard/static/src/dashboard.xml
@@ -1,8 +1,69 @@
-
+
-
- hello dashboard
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Number of new orders this month
+
+
+
+
+
+
+
+
+
Total amount of new orders this month
+
+
+
+
+
+
+
+
Average amount of t-shirt by order this month
+
+
+
+
+
+
+
+
+
Number of cancelled orders this month
+
+
+
+
+
+
+
+
+
Average time from 'new' to 'sent' or 'cancelled'
+
+
+
+
+ Shirt orders by size
+
+
+
+
+
+
diff --git a/awesome_dashboard/static/src/dashboardItem/dashboardItem.js b/awesome_dashboard/static/src/dashboardItem/dashboardItem.js
new file mode 100644
index 00000000000..c85498ddca3
--- /dev/null
+++ b/awesome_dashboard/static/src/dashboardItem/dashboardItem.js
@@ -0,0 +1,12 @@
+import { Component } from "@odoo/owl";
+
+export class DashboardItem extends Component {
+ static template = 'awesome_dashboard.AwesomeDashboardItem';
+ static props = {
+ size: { type: Number, optional: true },
+ slots: { type: Object, optional: true },
+ };
+ static defaultProps = {
+ size: 1,
+ };
+}
diff --git a/awesome_dashboard/static/src/dashboardItem/dashboardItem.xml b/awesome_dashboard/static/src/dashboardItem/dashboardItem.xml
new file mode 100644
index 00000000000..946185c0306
--- /dev/null
+++ b/awesome_dashboard/static/src/dashboardItem/dashboardItem.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/awesome_dashboard/static/src/pieChart/pie_chart.js b/awesome_dashboard/static/src/pieChart/pie_chart.js
new file mode 100644
index 00000000000..09c45b25cd8
--- /dev/null
+++ b/awesome_dashboard/static/src/pieChart/pie_chart.js
@@ -0,0 +1,43 @@
+import { loadJS } from "@web/core/assets";
+import { getColor } from "@web/core/colors/colors";
+import { Component, onWillStart, useRef, onMounted, onWillUnmount, onPatched } from "@odoo/owl";
+
+export class PieChart extends Component {
+ static template = "awesome_dashboard.PieChart";
+ static props = {
+ label: String,
+ data: Object,
+ };
+
+ setup() {
+ this.canvasRef = useRef("canvas");
+ onWillStart(() => loadJS("/web/static/lib/Chart/Chart.js"));
+ onMounted(() => {
+ this.renderChart();
+ });
+ onPatched(() => {
+ this.chart.destroy();
+ this.renderChart();
+ });
+ onWillUnmount(() => {
+ this.chart.destroy();
+ });
+ }
+
+ renderChart() {
+ const labels = Object.keys(this.props.data);
+ const data = Object.values(this.props.data);
+ this.chart = new Chart(this.canvasRef.el, {
+ type: "pie",
+ data: {
+ labels: labels,
+ datasets: [
+ {
+ label: this.props.label,
+ data: data,
+ },
+ ],
+ },
+ });
+ }
+}
diff --git a/awesome_dashboard/static/src/pieChart/pie_chart.xml b/awesome_dashboard/static/src/pieChart/pie_chart.xml
new file mode 100644
index 00000000000..14e6684262c
--- /dev/null
+++ b/awesome_dashboard/static/src/pieChart/pie_chart.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/awesome_dashboard/static/src/scss/dashboard.scss b/awesome_dashboard/static/src/scss/dashboard.scss
new file mode 100644
index 00000000000..6be5e0f83c9
--- /dev/null
+++ b/awesome_dashboard/static/src/scss/dashboard.scss
@@ -0,0 +1,3 @@
+.o_dashboard {
+ background-color: gray;
+}
diff --git a/awesome_dashboard/static/src/services/statistics_service.js b/awesome_dashboard/static/src/services/statistics_service.js
new file mode 100644
index 00000000000..526aad9acc6
--- /dev/null
+++ b/awesome_dashboard/static/src/services/statistics_service.js
@@ -0,0 +1,13 @@
+import { registry } from "@web/core/registry";
+import { memoize } from "@web/core/utils/functions";
+import { rpc } from "@web/core/network/rpc";
+
+const statisticsService = {
+ start() {
+ return {
+ loadStatistics: memoize(() => rpc("/awesome_dashboard/statistics")),
+ };
+ },
+};
+
+registry.category("services").add("awesome_dashboard.statistics", statisticsService);
diff --git a/awesome_owl/static/src/card/card.js b/awesome_owl/static/src/card/card.js
new file mode 100644
index 00000000000..3a6b0824382
--- /dev/null
+++ b/awesome_owl/static/src/card/card.js
@@ -0,0 +1,18 @@
+import { Component, useState } from "@odoo/owl";
+
+export class Card extends Component {
+ static template = "awesome_owl.card";
+
+ static props = {
+ title: {type: String},
+ slots: {type: Object, optional: true},
+ };
+
+ setup() {
+ this.state = useState({ isOpen: true });
+ }
+
+ toggleCard() {
+ this.state.isOpen = !this.state.isOpen;
+ }
+}
diff --git a/awesome_owl/static/src/card/card.xml b/awesome_owl/static/src/card/card.xml
new file mode 100644
index 00000000000..db6fd985c68
--- /dev/null
+++ b/awesome_owl/static/src/card/card.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/counter/counter.js b/awesome_owl/static/src/counter/counter.js
new file mode 100644
index 00000000000..6deb801667d
--- /dev/null
+++ b/awesome_owl/static/src/counter/counter.js
@@ -0,0 +1,18 @@
+import { Component, useState } from "@odoo/owl";
+
+export class Counter extends Component {
+ static template = "awesome_owl.counter";
+
+ static props = {
+ onChange: {type: Function, optional: true},
+ }
+
+ setup() {
+ this.state = useState({ value: 0 });
+ }
+
+ increment() {
+ this.state.value++;
+ this.props.onChange?.();
+ }
+}
diff --git a/awesome_owl/static/src/counter/counter.xml b/awesome_owl/static/src/counter/counter.xml
new file mode 100644
index 00000000000..2bfb0bb11e0
--- /dev/null
+++ b/awesome_owl/static/src/counter/counter.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ Counter:
+
+
+
+
+
diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js
index 4ac769b0aa5..c718b81f7b5 100644
--- a/awesome_owl/static/src/playground.js
+++ b/awesome_owl/static/src/playground.js
@@ -1,5 +1,21 @@
-import { Component } from "@odoo/owl";
+import { Component, markup, useState } from "@odoo/owl";
+import { Counter } from "./counter/counter";
+import { Card } from "./card/card";
+import { TodoList } from "./todo/todoList";
export class Playground extends Component {
- static template = "awesome_owl.playground";
+ static template = 'awesome_owl.playground';
+ static components = { Counter, Card, TodoList };
+ static props = {};
+
+ value1 = "
content 1
"
+ value2 = markup("content 2
")
+
+ setup() {
+ this.sum = useState({ value: 0 });
+ }
+
+ incrementSum() {
+ this.sum.value++;
+ }
}
diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml
index 4fb905d59f9..f83edf84aec 100644
--- a/awesome_owl/static/src/playground.xml
+++ b/awesome_owl/static/src/playground.xml
@@ -1,9 +1,19 @@
-
-
- hello world
+
+
+
+
+
+
+
+ The sum is:
+
+
+
+
+
diff --git a/awesome_owl/static/src/todo/todoItem.js b/awesome_owl/static/src/todo/todoItem.js
new file mode 100644
index 00000000000..3c967b2e452
--- /dev/null
+++ b/awesome_owl/static/src/todo/todoItem.js
@@ -0,0 +1,22 @@
+import { Component } from "@odoo/owl"
+
+export class TodoItem extends Component {
+ static template = 'awesome_owl.todoItem';
+
+ static props = {
+ todo: {
+ type: Object,
+ shape: {id: Number, description: String, isCompleted: Boolean},
+ },
+ toggleState: Function,
+ removeTodo: Function,
+ };
+
+ onChange() {
+ this.props.toggleState(this.props.todo.id);
+ }
+
+ onClick() {
+ this.props.removeTodo(this.props.todo.id);
+ }
+}
diff --git a/awesome_owl/static/src/todo/todoItem.xml b/awesome_owl/static/src/todo/todoItem.xml
new file mode 100644
index 00000000000..2562016a15d
--- /dev/null
+++ b/awesome_owl/static/src/todo/todoItem.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+ .
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/todo/todoList.js b/awesome_owl/static/src/todo/todoList.js
new file mode 100644
index 00000000000..8219db7a4f4
--- /dev/null
+++ b/awesome_owl/static/src/todo/todoList.js
@@ -0,0 +1,42 @@
+import { Component, useState, useRef, onMounted } from "@odoo/owl"
+import { TodoItem } from "./todoItem";
+import { useAutofocus } from "../utils";
+
+export class TodoList extends Component {
+ static template = 'awesome_owl.todoList';
+ static components = { TodoItem };
+ static props = {};
+
+ setup() {
+ this.todos = useState([]);
+ this.id = 1;
+
+ this.inputRef = useAutofocus('todo');
+ }
+
+ addTodo(ev) {
+ if (ev.keyCode !== 13)
+ return;
+
+ const value = ev.target.value.trim();
+
+ if (value.length === 0)
+ return;
+
+ this.todos.push({id: this.id++, description: value, isCompleted: false});
+
+ ev.target.value = "";
+ }
+
+ toggleTodo(id) {
+ const todo = this.todos.find((t) => t.id === id);
+ if (todo)
+ todo.isCompleted = !todo.isCompleted;
+ }
+
+ removeTodo(id) {
+ const index = this.todos.findIndex((elem) => elem.id === id);
+ if (index >= 0)
+ this.todos.splice(index, 1);
+ }
+}
diff --git a/awesome_owl/static/src/todo/todoList.xml b/awesome_owl/static/src/todo/todoList.xml
new file mode 100644
index 00000000000..c726be69096
--- /dev/null
+++ b/awesome_owl/static/src/todo/todoList.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/utils.js b/awesome_owl/static/src/utils.js
new file mode 100644
index 00000000000..d9526b63e9d
--- /dev/null
+++ b/awesome_owl/static/src/utils.js
@@ -0,0 +1,9 @@
+import { onMounted, useRef } from "@odoo/owl"
+
+export function useAutofocus(name) {
+ const ref = useRef(name);
+ onMounted(() => {
+ ref.el.focus();
+ });
+ return ref;
+}