Hi there, I am currently using Odoo 14 to try out the Owl framework, I am able to get my component to work via the client action with the ComponentWrapper.
my question is how do I get the control panel to show (breadcrumbs, search view)
I spend a few days trying to figure this out, I went over example code in Odoo I am pretty much stuck
here is my code
odoo.define("todo", function (require) {
"use strict";
const AbstractAction = require("web.AbstractAction");
const {
ComponentWrapper,
WidgetAdapterMixin,
} = require("web.OwlCompatibility");
const core = require("web.core");
const { Component, tags } = owl;
const { useRef, useState } = owl.hooks;
class Task extends Component {
toggleTask() {
this.trigger("toggle-task", { id: this.props.task.id });
}
deleteTask() {
this.trigger("delete-task", { id: this.props.task.id });
}
}
Task.template = tags.xml`
<div class="task" t-att-class="props.task.isCompleted ? 'done' : ''">
<input type="checkbox" t-att-checked="props.task.isCompleted" t-on-click="toggleTask"/>
<span><t t-esc="props.task.title"/></span>
<span class="delete" t-on-click="deleteTask">🗑</span>
</div>
`;
Task.props = ["task"];
class Todo extends Component {
constructor() {
super(...arguments);
}
tasks = useState([]);
inputRef = useRef("add-input");
mounted() {
this.inputRef.el.focus();
}
async willStart() {
const fields = ["id", "name", "completed"];
const tasks = await this.env.services.rpc({
model: "todo",
method: "search_read",
kwargs: {
fields,
},
});
tasks.map((task) =>
this.tasks.push({
id: task.id,
title: task.name,
isCompleted: task.completed,
})
);
}
async addTask(ev) {
// 13 is keycode for ENTER
if (ev.keyCode === 13) {
const title = ev.target.value.trim();
ev.target.value = "";
if (title) {
const newTask = await this.env.services.rpc({
model: "todo",
method: "create",
args: [
{
name: title,
completed: false,
},
],
});
this.tasks.push({
id: newTask,
title: title,
isCompleted: false,
});
}
}
}
async toggleTask(ev) {
const task = this.tasks.find((t) => t.id === ev.detail.id);
task.isCompleted = !task.isCompleted;
await this.env.services.rpc({
model: "todo",
method: "write",
args: [
[task.id],
{
completed: task.isCompleted,
},
],
});
}
async deleteTask(ev) {
const index = this.tasks.findIndex((t) => t.id === ev.detail.id);
this.tasks.splice(index, 1);
await this.env.services.rpc({
model: "todo",
method: "unlink",
args: [[ev.detail.id]],
});
}
}
Todo.components = { Task };
Todo.template = tags.xml`
<div>
<div class="o_form_view">
<div class="o_form_sheet_bg">
<div class="o_form_sheet">
<div class="todo-app">
<input placeholder="Enter a new task" t-on-keyup="addTask" t-ref="add-input"/>
<div class="task-list" t-on-toggle-task="toggleTask" t-on-delete-task="deleteTask">
<t t-foreach="tasks" t-as="task" t-key="task.id">
<Task task="task"/>
</t>
</div>
</div>
</div>
</div>
</div>
</div>
`;
const ClientAction = AbstractAction.extend(WidgetAdapterMixin, {
start() {
const component = new ComponentWrapper(this, Todo);
return component.mount(this.el.querySelector(".o_content"));
},
});
core.action_registry.add("todo_client_action", ClientAction);
return ClientAction;
});
I am calling the action from a button
def open_client_action(self):
print('open action called')
return {
'res_model': 'todo',
'type': 'ir.actions.client',
'tag': 'todo_client_action',
}