Skip to content
Open

wip #4921

Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions addons/web_client/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
'web_client.assets': [
('include', 'web._assets_helpers'),
('include', 'web._assets_backend_helpers'),
('include', 'web.icons_fonts'),
'web/static/src/scss/pre_variables.scss',
'web/static/lib/bootstrap/scss/_variables.scss',
'web/static/lib/bootstrap/scss/_variables-dark.scss',
Expand Down
120 changes: 120 additions & 0 deletions addons/web_client/static/src/action/action_plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { plugin, Plugin } from "@odoo/owl";
import { DisplayedActionPlugin } from "@web_client/action/displayed_action_plugin";
import { notify } from "@web_core/notification/notification_plugin";
import { RPC } from "@web_core/rpc";
import { serviceRegistry } from "@web_core/services";
import { session } from "@web_core/session";
import { actionRegistry } from "./action_registry";
import { ViewAction } from "@web_client/action/view_action";

export class ActionPlugin extends Plugin {
static id = this.name;
static {
serviceRegistry.addById(this);
}

display = plugin(DisplayedActionPlugin);
rpc = plugin(RPC);

/**
* @param {string | number | Record<string, any>} request
*/
async doAction(request) {
const description = await this._loadActionDescription(request);
switch (description.type) {
case "ir.actions.act_url":
return this._executeUrlAction(description);
case "ir.actions.act_window":
return this._executeWindowAction(description);
case "ir.actions.act_window_close":
return this._executeWindowCloseAction(description);
case "ir.actions.client":
return this._executeClientAction(description);
case "ir.actions.server":
return this._executeServerAction(description);
case "ir.actions.report":
return this._executeReportAction(description);
default:
notify(`Unknown action type "${description.type}"`, { type: "danger" });
}
}

/**
* @private
* @param {string | number | Record<string, any>} request
*/
async _loadActionDescription(request) {
if (typeof request === "string" && actionRegistry.has(request)) {
// request is a tag of a client action.
return {
tag: request,
target: "current",
type: "ir.actions.client",
};
}

if (["string", "number"].includes(typeof request)) {
// request is an action id or a xmlid.
return this.rpc.call("/web/action/load", {
action_id: request,
context: session.user_context,
});
}

// request is an object describing the action.
return request;
}

/**
* @private
* @param {Record<string, any>} description
*/
_executeClientAction(description) {
const actionId = description.tag;
if (actionRegistry.has(actionId)) {
this.display.setDisplay(actionRegistry.get(actionId), description);
} else {
notify("Nope, action does not exist");
}
}

/**
* @private
* @param {Record<string, any>} description
*/
_executeReportAction(description) {
notify(`Not implemented action type "${description.type}"`, { type: "danger" });
}

/**
* @private
* @param {Record<string, any>} description
*/
_executeServerAction(description) {
notify(`Not implemented action type "${description.type}"`, { type: "danger" });
}

/**
* @private
* @param {Record<string, any>} description
*/
_executeUrlAction(description) {
notify(`Not implemented action type "${description.type}"`, { type: "danger" });
}

/**
* @private
* @param {Record<string, any>} description
*/
_executeWindowAction(description) {
this.display.setDisplay(ViewAction, description);
}

/**
* @private
* @param {Record<string, any>} description
*/
_executeWindowCloseAction(description) {
notify(`Not implemented action type "${description.type}"`, { type: "danger" });
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { Component, Registry } from "@odoo/owl";

export const actionRegistry = new Registry("action", Component.prototype);
export const actionRegistry = new Registry("action", Component.prototype);
38 changes: 38 additions & 0 deletions addons/web_client/static/src/action/displayed_action_plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Component, Plugin, signal, xml } from "@odoo/owl";
import { serviceRegistry } from "@web_core/services";

class EmptyAction extends Component {
static template = xml``;
}

export class DisplayedActionPlugin extends Plugin {
static id = this.name;
static {
serviceRegistry.addById(this);
}

/**
* @private
* @type {import("@odoo/owl").Signal<{ component: import("@odoo/owl").ComponentConstructor; description: Record<string, any> }>}
*/
_displayInfo = signal({
component: EmptyAction,
description: {},
});

get component() {
return this._displayInfo().component;
}

get description() {
return this._displayInfo().description;
}

/**
* @param {import("@odoo/owl").ComponentConstructor} component
* @param {Record<string, any>} description
*/
setDisplay(component, description) {
this._displayInfo.set({ component, description });
}
}
65 changes: 65 additions & 0 deletions addons/web_client/static/src/action/view_action.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Component, computed, plugin, signal, usePlugins, useResource, xml } from "@odoo/owl";
import { DisplayedActionPlugin } from "@web_client/action/displayed_action_plugin";
import { DebugPlugin } from "@web_client/debug_menu/debug_plugin";
import { ControlPanel } from "@web_client/views/control_panel";
import { ViewLoaderPlugin } from "@web_client/views/view_loader_plugin";
import { ViewPlugin } from "@web_client/views/view_plugin";
import { viewRegistry } from "@web_client/views/view_registry";

class UnknownViewMode extends Component {
static template = xml`
<ControlPanel/>
<main class="px-3">
Unknown view mode: <t t-out="this.view.mode()"/>
</main>
`;
static components = { ControlPanel };

view = plugin(ViewPlugin);
}

class LoadingView extends Component {
static template = xml`
<ControlPanel/>
<main class="px-3">
Loading...
</main>
`;
static components = { ControlPanel };

view = plugin(ViewPlugin);
}

export class ViewAction extends Component {
static template = xml`<t t-component="this.component()"/>`;

actionDisplay = plugin(DisplayedActionPlugin);
debug = plugin(DebugPlugin);
viewLoader = plugin(ViewLoaderPlugin);

setup() {
useResource(this.debug.items, [
{
label: `Model: ${this.actionDisplay.description.res_model}`,
action: () => console.log("Open Model Info"),
},
{ label: `Action`, action: () => console.log("Open Action Info") },
{ label: `View`, action: () => console.log("Open View Info") },
]);

usePlugins([ViewPlugin]);
const view = plugin(ViewPlugin);
const loaded = signal(false);
this.component = computed(() => {
if (loaded()) {
return viewRegistry.get(view.mode(), UnknownViewMode);
} else {
return LoadingView;
}
});
const action = this.actionDisplay.description;
this.viewLoader.loadView(action.res_model, action.id, action.views).then(() => {
loaded.set(true);
});
}
}
94 changes: 0 additions & 94 deletions addons/web_client/static/src/action_plugin.js

This file was deleted.

24 changes: 24 additions & 0 deletions addons/web_client/static/src/debug_menu/debug_menu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Component, plugin, useResource } from "@odoo/owl";
import { DebugPlugin } from "@web_client/debug_menu/debug_plugin";
import { systrayRegistry } from "@web_client/systray_menu/systray_menu";
import { Dropdown } from "@web_core/dropdown/dropdown";
import { MenuItem } from "@web_core/menu/menu";

export class DebugMenu extends Component {
static {
systrayRegistry.add("DebugMenu", this);
}

static template = "web_client.DebugMenu";
static components = { Dropdown, MenuItem };

debug = plugin(DebugPlugin);

setup() {
useResource(this.debug.items, [
{ label: "Leave Debug Mode", action: () => console.log("Leave Debug Mode") },
{ label: "Run Unit Tests", action: () => console.log("Run Unit Tests") },
{ label: "Open View", action: () => console.log("Open View") },
]);
}
}
21 changes: 21 additions & 0 deletions addons/web_client/static/src/debug_menu/debug_menu.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="web_client.DebugMenu">
<Dropdown t-slot-scope="dropdown">
<div class="d-flex align-items-center cursor-pointer" t-ref="dropdown.toggler">
<span class="text-white">
<i class="fa fa-bug"/>
</span>
</div>
<t t-set-slot="menu">
<t t-foreach="this.debug.items.items()" t-as="item" t-key="item_index">
<MenuItem onSelected="item.action">
<t t-out="item.label"/>
</MenuItem>
</t>
</t>
</Dropdown>
</t>

</templates>
11 changes: 11 additions & 0 deletions addons/web_client/static/src/debug_menu/debug_plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Plugin, Resource } from "@odoo/owl";
import { serviceRegistry } from "@web_core/services";

export class DebugPlugin extends Plugin {
static id = this.name;
static {
serviceRegistry.addById(this);
}

items = new Resource();
}
Loading