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] + ); +}