Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e1d7982
added init and manifest
snoek100 Aug 17, 2026
cb84f6e
added all the functionality until the basic views of server framework
snoek100 Aug 17, 2026
99af35b
end of day 1
snoek100 Aug 17, 2026
a969dc2
server framework 101 end of chapter 6
snoek100 Aug 18, 2026
031009b
finished server framework 101 chapter 9
snoek100 Aug 18, 2026
fa0cc1c
actually finished server framework 101 chapter 9
snoek100 Aug 18, 2026
b4428f5
finished server framework 101 chapter 10
snoek100 Aug 18, 2026
e63118d
finished server framework 101 chapter 11
snoek100 Aug 19, 2026
1ac00c6
finished server framework 101 chapter 12
snoek100 Aug 19, 2026
c3c4378
finished chapter server framework chapter 13
snoek100 Aug 20, 2026
0d07749
finished server framework 101 chapter 14
snoek100 Aug 20, 2026
721c3c7
fixed styling changes
snoek100 Aug 20, 2026
873b465
ammended styling fix
snoek100 Aug 20, 2026
65c6202
[ADD] estate: added test cases for estate class
snoek100 Aug 21, 2026
c1476ea
[REF] estate: separated estate views into seperat files
snoek100 Aug 21, 2026
20f44e2
[FIX] estate: added a field for the property type form so its name ca…
snoek100 Aug 21, 2026
d5e25b3
[ADD] added buttons and counters
snoek100 Aug 21, 2026
ef40a4d
[ADD] finished chapter one of web framework
snoek100 Aug 24, 2026
e734266
[ADD] started the git challenge
snoek100 Aug 24, 2026
cf99a0c
git challenge completed
snoek100 Aug 24, 2026
83db6b4
[ADD] web framework chapter 2 build a dashboard chapter 4 completed
snoek100 Aug 25, 2026
502b3c8
[ADD] [Tutorial] Restrict access to data started
snoek100 Aug 26, 2026
6d5c63e
[ADD] web framework tutorial chapter 2, part 5, added caching
snoek100 Aug 26, 2026
356cd8e
[ADD] web framework tutorial chapter 2, part 7 added chart to dashboard
snoek100 Aug 26, 2026
fdf84cf
[ADD] discover the web framework chapter 2 part 9 made the dashboard …
snoek100 Aug 27, 2026
a22a4ec
[ADD] web framework chapter 2 finished making the dashoard customizable
snoek100 Aug 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,5 @@ dmypy.json

# Pyre type checker
.pyre/

.vscode
6 changes: 5 additions & 1 deletion awesome_dashboard/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
'assets': {
'web.assets_backend': [
'awesome_dashboard/static/src/**/*',
('remove', 'awesome_dashboard/static/src/dashboard/**/*'),
],
'awesome_dashboard.dashboard': [
'awesome_dashboard/static/src/dashboard/**/*',
],
},
'license': 'AGPL-3'
'license': 'AGPL-3',
}
8 changes: 0 additions & 8 deletions awesome_dashboard/static/src/dashboard.js

This file was deleted.

8 changes: 0 additions & 8 deletions awesome_dashboard/static/src/dashboard.xml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { registry, reactive } from "@web/core/registry";
import { rpc } from "@web/core/network/rpc";
import { memoize } from "@web/core/utils/functions"


export async function _loadStatistics() {
// console.log("loading statistics")
const result = await rpc("/awesome_dashboard/statistics")
// console.log(result)
return result
}

export const myCaching = {
start(env) {
return {
loadStatistics() {
let memoLoadStatistics = memoize(_loadStatistics)
return memoLoadStatistics
}
}
},
}

registry.category("services").add("myCaching", myCaching);
72 changes: 72 additions & 0 deletions awesome_dashboard/static/src/dashboard/dashboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Component, onWillStart, useState, onMounted } from "@odoo/owl";
import { Layout } from "@web/search/layout"
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";
import { DashboardItem } from "./dashboardItem/dashboard_item";
import { rpc } from "@web/core/network/rpc";
import { Piechart } from "./piechart/piechart";
import { MyDialog } from "./mydialog/mydialog";
import { browser } from "@web/core/browser/browser";


class AwesomeDashboard extends Component {
static template = "awesome_dashboard.AwesomeDashboard";

static components = {
DashboardItem,
Layout,
Piechart,
MyDialog
}
setup() {
this.action = useService("action")
this.caching = useService("myCaching")
this.statistics = useState({})
this.items = registry.category("awesome_dashboard").get("items");
this.dialog = useService("dialog")
this.state = useState({
disabledItems: JSON.parse(browser.localStorage.getItem("disabledDashboardItems")?.split(",") || "{}")
})

onWillStart(async () => {
const stats = await this.caching.loadStatistics()
Object.assign(this.statistics, await stats());
})
onMounted(() => {
setInterval(async () => {
const stats = await this.caching.loadStatistics()
Object.assign(this.statistics, await stats());
}, 5000)
})
}

_updateConfiguration(newDisabledItems) {
this.state.disabledItems = newDisabledItems
console.log(this.state.disabledItems.average_quantity)
console.log(this.items[0])
}

openConfiguration() {
this.dialog.add(MyDialog, {
items: this.items,
disabledItems: this.state.disabledItems,
updateConfiguration: this._updateConfiguration.bind(this),
})
}

kanban_action() {
this.action.doAction("base.action_partner_form")
}

leads_action() {
this.action.doAction({
type: 'ir.actions.act_window',
name: 'crm action',
target: 'current',
res_model: 'crm.lead',
views: [[false, 'list'], [false, 'form']],
});
}
}

registry.category("lazy_components").add("AwesomeDashboard", AwesomeDashboard);
4 changes: 4 additions & 0 deletions awesome_dashboard/static/src/dashboard/dashboard.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.o_dashboard {
background-color: #7095bb;
height: 100%;
}
28 changes: 28 additions & 0 deletions awesome_dashboard/static/src/dashboard/dashboard.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_dashboard.AwesomeDashboard">
<button class="btn btn-primary me-1" t-on-click="kanban_action">
Customers
</button>
<button class="btn btn-primary" t-on-click="leads_action">
Leads
</button>
<button class="fa fa-cog" t-on-click="openConfiguration">
settings
</button>

<Layout className="'o_dashboard h-100'" display="'{controlPanel: {} }'">
<t t-foreach="items" t-as="item" t-key="item.id">
<t t-if="state.disabledItems[item.id]">
<DashboardItem size="item.size || 1">
<t t-set="itemProp" t-value="item.props ? item.props(statistics) : {'data': statistics}"/>
<t t-component="item.Component" t-props="itemProp" />
</DashboardItem>
</t>
</t>
</Layout>
</t>


</templates>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Component, useState } from "@odoo/owl";

export class DashboardItem extends Component {
static template = "awesome_dashboard.dashboarditem";

static props = {
size: { type: Number, optional: true, default: 1 },
slots: { type: Object, optional: true}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_dashboard.dashboarditem">
<div class="card m-2 d-inline-block align-top" t-attf-style="width: {{ props.size * 18 }}rem;">
<div class="card-body bg-white text-dark border">
<t t-slot="default"/>
</div>
</div>
</t>

</templates>
69 changes: 69 additions & 0 deletions awesome_dashboard/static/src/dashboard/dashboard_items.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { NumberCard } from "./numberCard/number_card";
import { PieChartCard } from "./pieChartCard/piechart_card";
import { registry } from "@web/core/registry";


const items = [
{
id: "average_quantity",
description: "Average amount of t-shirt",
Component: NumberCard,
size: 1,
props: (data) => ({
title: "Average amount of t-shirt by order this month",
value: data.average_quantity
})
},
{
id: "average_time",
description: "Average delivery time",
Component: NumberCard,
size: 1,
props: (data) => ({
title: "Average time it takes to deliver a t-shirt",
value: data.average_time
})
},
{
id: "nb_cancelled_orders",
description: "Number of cancelled orders",
Component: NumberCard,
size: 1,
props: (data) => ({
title: "Number of orders that were cancelled.",
value: data.nb_cancelled_orders
})
},
{
id: "nb_new_orders",
description: "Number of new orders",
Component: NumberCard,
size: 1,
props: (data) => ({
title: "Number of orders that were new.",
value: data.nb_new_orders
})
},
{
id: "total_amount",
description: "Total amount of orders",
Component: NumberCard,
size: 1,
props: (data) => ({
title: "Total number of orders",
value: data.total_amount
})
},
{
id: "pie_chart",
description: "Orders by size",
Component: PieChartCard,
size: 2,
props: (data) => ({
title: "Display the orders in a pie chart by size",
value: data.orders_by_size
})
},
]

registry.category("awesome_dashboard").add("items", items);
37 changes: 37 additions & 0 deletions awesome_dashboard/static/src/dashboard/mydialog/mydialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Component, useState } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { Dialog } from "@web/core/dialog/dialog";
import { CheckBox } from "@web/core/checkbox/checkbox";
import { browser } from "@web/core/browser/browser";


export class MyDialog extends Component {
static template = "awesome_dashboard.mydialog";

static components = {
Dialog,
CheckBox
}

static props = {
disabledItems: Object,
updateConfiguration: Function,
items: Array,
close: Function
}

setup() {
console.log(this.props)
}

onChange(ev, item) {
// this.disabledItems[item.id] = ev
this.props.disabledItems[item.id] = ev
}

done() {
browser.localStorage.setItem("disabledDashboardItems", JSON.stringify(this.props.disabledItems))
this.props.updateConfiguration(this.props.disabledItems)
this.props.close()
}
}
21 changes: 21 additions & 0 deletions awesome_dashboard/static/src/dashboard/mydialog/mydialog.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_dashboard.mydialog">
<Dialog title="'dashboard items'" >
<t t-foreach="props.items" t-as="item" t-key="item.id">
<div>
<CheckBox value="props.disabledItems[item.id]" onChange="(ev) => this.onChange(ev, item)">
<t t-esc="item.description"/>
</CheckBox>
</div>
</t>
<t t-set-slot="footer">
<button class="btn btn-primary" t-on-click="done">
Done
</button>
</t>
</Dialog>
</t>

</templates>
11 changes: 11 additions & 0 deletions awesome_dashboard/static/src/dashboard/numberCard/number_card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { loadJS } from "@web/core/assets"
import { Component, useState, onWillStart, onMounted, useRef, reactive, onWillUnmount, onWillPatch, onWillUpdateProps } from "@odoo/owl";

export class NumberCard extends Component {
static template = "awesome_dashboard.numberCard";

static props = {
title: String,
value: Number
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="awesome_dashboard.numberCard">
<t t-esc="props.title"/>
<t t-esc="props.value"/>
</t>
</templates>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { loadJS } from "@web/core/assets"
import { Component, useState, onWillStart, onMounted, useRef, reactive, onWillUnmount, onWillPatch, onWillUpdateProps } from "@odoo/owl";
import { Piechart } from "../piechart/piechart";

export class PieChartCard extends Component {
static template = "awesome_dashboard.pieChartCard";
static components = { Piechart }

static props = {
title: String,
value: Object
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="awesome_dashboard.pieChartCard">
<t t-esc="props.label"/>
<Piechart pieData="props.value"/>
</t>
</templates>
Loading