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