diff --git a/awesome_dashboard/static/src/dashboard.js b/awesome_dashboard/static/src/dashboard.js
index 637fa4bb972..85ee10249d7 100644
--- a/awesome_dashboard/static/src/dashboard.js
+++ b/awesome_dashboard/static/src/dashboard.js
@@ -1,10 +1,32 @@
-/** @odoo-module **/
-
-import { Component } 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";
+import { DashboardItem } from "./dashboarditem";
+import { PieChart } from "./piechart";
class AwesomeDashboard extends Component {
static template = "awesome_dashboard.AwesomeDashboard";
+ static components = { Layout, DashboardItem, PieChart };
+
+ setup() {
+ this.action = useService("action");
+ this.statistics = useState(useService("awesome_dashboard.statistics"));
+ }
+
+ openCustomersView() {
+ this.action.doAction("base.action_partner_form");
+ }
+
+ async openLeadsView() {
+ 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.scss b/awesome_dashboard/static/src/dashboard.scss
new file mode 100644
index 00000000000..b8d05922ba0
--- /dev/null
+++ b/awesome_dashboard/static/src/dashboard.scss
@@ -0,0 +1,3 @@
+.o_dashboard {
+ background-color: rgb(234, 243, 246);
+}
diff --git a/awesome_dashboard/static/src/dashboard.xml b/awesome_dashboard/static/src/dashboard.xml
index 1a2ac9a2fed..03dbf6a3b33 100644
--- a/awesome_dashboard/static/src/dashboard.xml
+++ b/awesome_dashboard/static/src/dashboard.xml
@@ -2,7 +2,55 @@
- hello dashboard
+
+
+
+
+
+
Number of new orders this month
+
+
+
+
+
+
+
+
Number of cancelled orders this month
+
+
+
+
+
+
+
+
Average amount of t-shirt by order this month
+
+
+
+
+
+
+
+
Average time for an order to go from ‘new’ to ‘sent’ or ‘cancelled’
+
+
+
+
+
+
+
+
Total amount of new orders this month
+
+
+
+
+
+
+
+
+
diff --git a/awesome_dashboard/static/src/dashboarditem.js b/awesome_dashboard/static/src/dashboarditem.js
new file mode 100644
index 00000000000..5733389a547
--- /dev/null
+++ b/awesome_dashboard/static/src/dashboarditem.js
@@ -0,0 +1,13 @@
+import { Component } from "@odoo/owl"
+
+export class DashboardItem extends Component {
+ static template = "awesome_dashboard.dashboarditem";
+ static props = {
+ size: {
+ type: Number,
+ default: 1,
+ optional: true,
+ },
+ slots: Object,
+ };
+}
diff --git a/awesome_dashboard/static/src/dashboarditem.xml b/awesome_dashboard/static/src/dashboarditem.xml
new file mode 100644
index 00000000000..87b49473432
--- /dev/null
+++ b/awesome_dashboard/static/src/dashboarditem.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/awesome_dashboard/static/src/piechart.js b/awesome_dashboard/static/src/piechart.js
new file mode 100644
index 00000000000..ee95a7fa944
--- /dev/null
+++ b/awesome_dashboard/static/src/piechart.js
@@ -0,0 +1,34 @@
+import { Component, onWillStart, onMounted, onWillUnmount, useRef } from "@odoo/owl"
+import { loadJS } from "@web/core/assets"
+import { getColor } from "@web/core/colors/colors"
+
+export class PieChart extends Component {
+ static template = "awesome_dashboard.piechart";
+ static props = {
+ data: Object,
+ }
+
+ setup() {
+ this.canvasRef = useRef("canvas");
+ onWillStart(() => loadJS("/web/static/lib/Chart/Chart.js"));
+ onMounted(() => this.renderChart());
+ onWillUnmount(() => this.chart.destroy());
+ }
+
+ renderChart() {
+ const chartLabels = Object.keys(this.props.data.orders_by_size)
+ this.chart = new Chart(this.canvasRef.el, {
+ type: 'pie',
+ data: {
+ labels: chartLabels,
+ datasets: [
+ {
+ label: "Sizes Chart",
+ data: Object.values(this.props.data.orders_by_size),
+ backgroundColor: chartLabels.map((_, index) => getColor(index)),
+ }
+ ]
+ }
+ });
+ }
+}
diff --git a/awesome_dashboard/static/src/piechart.xml b/awesome_dashboard/static/src/piechart.xml
new file mode 100644
index 00000000000..71b1bca306f
--- /dev/null
+++ b/awesome_dashboard/static/src/piechart.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/awesome_dashboard/static/src/statistics_service.js b/awesome_dashboard/static/src/statistics_service.js
new file mode 100644
index 00000000000..f62ca6f5f37
--- /dev/null
+++ b/awesome_dashboard/static/src/statistics_service.js
@@ -0,0 +1,17 @@
+import { registry } from "@web/core/registry";
+import { rpc } from "@web/core/network/rpc";
+import { memoize } from "@web/core/utils/functions";
+
+async function loadStatistics() {
+ const memoizedRpc = memoize(rpc);
+ const statistics = await memoizedRpc("/awesome_dashboard/statistics");
+ return statistics;
+}
+
+export const statisticsService = {
+ async start() {
+ return await loadStatistics();
+ },
+}
+
+registry.category("services").add("awesome_dashboard.statistics", statisticsService);
diff --git a/awesome_owl/static/src/card.js b/awesome_owl/static/src/card.js
new file mode 100644
index 00000000000..5671e8676cc
--- /dev/null
+++ b/awesome_owl/static/src/card.js
@@ -0,0 +1,17 @@
+import { Component, useState } from "@odoo/owl"
+
+export class Card extends Component {
+ static template = "awesome_owl.card";
+ static props = {
+ title: String,
+ slots: Object,
+ };
+
+ setup() {
+ this.state = useState({ isOpen: true });
+ }
+
+ toggleState() {
+ this.state.isOpen = !this.state.isOpen;
+ }
+}
diff --git a/awesome_owl/static/src/card.xml b/awesome_owl/static/src/card.xml
new file mode 100644
index 00000000000..db66a69a79d
--- /dev/null
+++ b/awesome_owl/static/src/card.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/counter.js b/awesome_owl/static/src/counter.js
new file mode 100644
index 00000000000..2cf1c6040d8
--- /dev/null
+++ b/awesome_owl/static/src/counter.js
@@ -0,0 +1,17 @@
+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.xml b/awesome_owl/static/src/counter.xml
new file mode 100644
index 00000000000..a7df4ecc185
--- /dev/null
+++ b/awesome_owl/static/src/counter.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ Hello World
+
Counter:
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js
index 657fb8b07bb..a99da97ee1d 100644
--- a/awesome_owl/static/src/playground.js
+++ b/awesome_owl/static/src/playground.js
@@ -1,7 +1,20 @@
-/** @odoo-module **/
-
-import { Component } from "@odoo/owl";
+import { Component, useState, markup } from "@odoo/owl";
+import { Counter } from "./counter";
+import { Card } from "./card";
+import { TodoList } from "./todolist";
export class Playground extends Component {
static template = "awesome_owl.playground";
+ static components = { Counter, Card, TodoList };
+
+ setup() {
+ this.state = useState({ sum: 0 });
+ }
+
+ card1Content = markup("Some Text in div Tag
");
+ card2Content = "Some Text in div Tag
";
+
+ incrementSum() {
+ this.state.sum++;
+ }
}
diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml
index 4fb905d59f9..26be130adc1 100644
--- a/awesome_owl/static/src/playground.xml
+++ b/awesome_owl/static/src/playground.xml
@@ -2,9 +2,15 @@
-
- hello world
-
+ Counters Sum:
+
+
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/todoitem.js b/awesome_owl/static/src/todoitem.js
new file mode 100644
index 00000000000..7d31fb33b56
--- /dev/null
+++ b/awesome_owl/static/src/todoitem.js
@@ -0,0 +1,10 @@
+import { Component } from "@odoo/owl";
+
+export class TodoItem extends Component {
+ static template = "awesome_owl.todoitem";
+ static props = {
+ todo: Object,
+ onToggleState: Function,
+ onRemoveTodo: Function,
+ }
+}
diff --git a/awesome_owl/static/src/todoitem.xml b/awesome_owl/static/src/todoitem.xml
new file mode 100644
index 00000000000..fbc388e5f43
--- /dev/null
+++ b/awesome_owl/static/src/todoitem.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/todolist.js b/awesome_owl/static/src/todolist.js
new file mode 100644
index 00000000000..91495e986a1
--- /dev/null
+++ b/awesome_owl/static/src/todolist.js
@@ -0,0 +1,38 @@
+import { Component, useState } from "@odoo/owl";
+import { TodoItem } from "./todoitem";
+import { useAutofocus } from "./utils";
+
+export class TodoList extends Component {
+ static template = "awesome_owl.todolist";
+ static components = { TodoItem };
+
+ setup() {
+ this.state = useState({
+ todos: [],
+ idCounter: 0,
+ });
+ useAutofocus("input_todo");
+ };
+
+ addTodo(ev) {
+ if (ev.keyCode === 13) {
+ this.state.idCounter++
+ this.state.todos.push({
+ "id": this.state.idCounter, "description": ev.target.value, "isCompleted": false
+ });
+ ev.target.value = "";
+ }
+ };
+
+ toggleState(todoId) {
+ const todo = this.state.todos.find(todo => todo.id === todoId);
+ todo.isCompleted = !todo.isCompleted;
+ }
+
+ removeTodo(todoId) {
+ const index = this.state.todos.findIndex(todo => todo.id === todoId);
+ if (index >= 0) {
+ this.state.todos.splice(index, 1);
+ }
+ }
+}
diff --git a/awesome_owl/static/src/todolist.xml b/awesome_owl/static/src/todolist.xml
new file mode 100644
index 00000000000..88c73269506
--- /dev/null
+++ b/awesome_owl/static/src/todolist.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/awesome_owl/static/src/utils.js b/awesome_owl/static/src/utils.js
new file mode 100644
index 00000000000..9c0f35a6353
--- /dev/null
+++ b/awesome_owl/static/src/utils.js
@@ -0,0 +1,9 @@
+import { useEffect, useRef } from "@odoo/owl";
+
+export function useAutofocus(refName) {
+ let ref = useRef(refName);
+ useEffect(
+ (el) => el && el.focus(),
+ () => [ref.el]
+ );
+}