Quick Setup
Introduction to odoo 18 systray Dropdown
Odoo 18 systray lets you add custom menus at the top-right corner of your interface. First, you’ll learn how to build a dropdown that opens Sale Orders and Purchase Orders. Moreover, you’ll follow clear steps that use the modern Owl framework. Additionally, you’ll see full code examples with explanations. Finally, you’ll test your new menu in a running Odoo instance.
source code : https://github.com/teguhteja/odoo18-addons/tree/master/ttm_web_systray
Prerequisites and Setup Environment
Before we start, make sure you meet these requirements:
- Odoo 18 Community or Enterprise
You need a working Odoo 18 installation. If you don’t have one, follow the official Odoo 18 installation guide{:target=”_blank”}. - Basic Module Structure
Create a custom module folder, for examplemy_systray_menu
. Then add the standard files:__manifest__.py
__init__.py
static/
src/
components/
- Developer Mode Enabled
Activate Developer Mode in Odoo. Go to Settings → Activate the developer mode. - Code Editor and CLI Access
You’ll edit files locally and restart your Odoo server from the command line.
Understand the odoo 18 systray System
What Is the odoo 18 systray?
In Odoo’s web client, the systray (system tray) sits at the top-right. It hosts icons for things like notifications and help. Moreover, you can inject your own components. As a result, you build quick-access menus for users.
Why Customize the systray?
- Boost productivity. Users access key screens in one click.
- Improve UX. You place your app’s features where users look first.
- Stay consistent. You follow Odoo’s style and load assets via the asset bundle.
Creating the JavaScript Component for odoo 18 systray Dropdown
First, we build a JS component that Owl can render in the systray registry. Then, we hook into Odoo’s action service to open windows.
Define the Component File
Create static/src/components/systray_dropdown.js
:
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";
import { Component } from "@odoo/owl";
import { Dropdown } from "@web/core/dropdown/dropdown";
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
class SystrayDropdown extends Component {
setup() {
this.action = useService("action");
}
// Open Sale Orders in list view
openSaleOrders() {
this.action.doAction({
type: "ir.actions.act_window",
name: "Sale Orders",
res_model: "sale.order",
views: [[false, "list"], [false, "form"]],
target: "current",
});
}
// Open Purchase Orders in list view
openPurchaseOrders() {
this.action.doAction({
type: "ir.actions.act_window",
name: "Purchase Orders",
res_model: "purchase.order",
views: [[false, "list"], [false, "form"]],
target: "current",
});
}
}
SystrayDropdown.template = "systray_dropdown";
SystrayDropdown.components = { Dropdown, DropdownItem };
export const systrayItem = {
Component: SystrayDropdown,
};
registry.category("systray").add("SystrayDropdown", systrayItem, { sequence: 1 });
Explanation of the JS Code
- We import registry to register our component.
- We use useService(“action”) to call Odoo’s action dispatcher.
- We define two methods:
openSaleOrders
andopenPurchaseOrders
. Each method triggers anir.actions.act_window
. - We set
template
andcomponents
so Owl knows which template and sub-components to use. - Finally, we register our item under the systray category with a sequence for ordering.
Designing the XML Template for odoo 18 systray Dropdown
Next, we build the XML that defines the HTML structure of our dropdown. We include an icon and two menu items.
Create the XML Template File
Create static/src/components/systray_dropdown.xml
:
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="systray_dropdown" owl="1">
<Dropdown>
<div class="new_icon">
<div class="icon_div">
<div class="toggle-icon" role="button">
<i
id="create_order"
class="fa fa-shopping-cart fa-1.5x"
style="color: black; margin-bottom:10px; padding:13px;"
role="img"
aria-label="Sale/Purchase Order"
/>
</div>
</div>
</div>
<t t-set-slot="content">
<DropdownItem onSelected="() => this.openSaleOrders()">
Sale Orders
</DropdownItem>
<DropdownItem onSelected="() => this.openPurchaseOrders()">
Purchase Orders
</DropdownItem>
</t>
</Dropdown>
</t>
</templates>
Explain Template Slots
- We wrap our markup in
<Dropdown>
, which Owl exports. - We place our icon inside a
<div class="new_icon">
. - We fill the content slot with two
<DropdownItem>
elements. Each item binds itsonSelected
handler to our JS methods.
Registering Assets in manifest
Now, we tell Odoo to load these files in the backend assets.
Update __manifest__.py
Add the paths under the web.assets_backend
key:
{
"name": "My Systray Menu",
"version": "1.0",
"depends": ["web"],
"assets": {
"web.assets_backend": [
"my_systray_menu/static/src/components/systray_dropdown.js",
"my_systray_menu/static/src/components/systray_dropdown.xml",
],
},
}
Explanation
- depends: we depend on the
web
module to get core web assets. - assets: we append our JS and XML to the
web.assets_backend
bundle.
Loading the Module and Testing odoo 18 systray Dropdown
After you add code and assets, restart Odoo and upgrade your module.
Restart the Odoo Server
# Stop the server
pkill -f odoo-bin
# Start the server in developer mode
./odoo-bin -c /etc/odoo/odoo.conf --dev=assets
Upgrade Your Module
- Go to Apps.
- Click Update App List.
- Search for “My Systray Menu”.
- Click Upgrade.
Verify the Dropdown
- Reload your browser with Ctrl+F5.
- Look at the top-right corner.
- You should see a shopping cart icon.
- Click it to open your dropdown.
- Select Sale Orders or Purchase Orders to confirm navigation.
Advanced Customizations for odoo 18 systray Dropdown
Adding Custom Icons
First, you can swap the shopping cart icon. For example, use a bell:
<i class="fa fa-bell fa-lg" role="img" aria-label="Alerts"/>
Changing Menu Items
Next, update your JS to open other models, such as Contacts:
openContacts() {
this.action.doAction({
type: "ir.actions.act_window",
name: "Contacts",
res_model: "res.partner",
views: [[false, "kanban"], [false, "form"]],
target: "current",
});
}
Then, add a <DropdownItem>
for Contacts
in your XML.
Styling the Dropdown
To adjust styles, add CSS under static/src/css/systray_dropdown.scss
:
.new_icon .toggle-icon {
background: #f5f5f5;
border-radius: 4px;
}
.o_SystrayDropdown {
min-width: 200px;
}
And include it in your manifest:
"assets": {
"web.assets_backend": [
"my_systray_menu/static/src/css/systray_dropdown.scss",
],
},
Troubleshooting Common Issues
JS Errors in Console
If you see Uncaught ReferenceError
, ensure you imported the module correctly. Also, check your file paths in __manifest__.py
.
Asset Not Loaded
If your files don’t load, clear your browser cache and restart Odoo in dev mode:
./odoo-bin -c /etc/odoo/odoo.conf --dev=assets
Template Not Found
If you get an Owl template error, confirm your XML file has the correct <templates>
wrapper and t-name
.
Conclusion and Next Steps
In this tutorial, you learned how to extend the odoo 18 systray with a custom dropdown. You saw full code examples for JS, XML, and manifest updates. Moreover, you explored advanced tweaks like icons and CSS. Next, you can:
- Add dynamic content using RPC calls.
- Integrate notifications or real-time counters.
- Share your module on Odoo Apps{:target=”_blank”}.
Feel free to experiment and customize further. Happy coding!
Discover more from teguhteja.id
Subscribe to get the latest posts sent to your email.