diff --git a/addons/web/__manifest__.py b/addons/web/__manifest__.py
index fcbc8875950..ca39386cf0b 100644
--- a/addons/web/__manifest__.py
+++ b/addons/web/__manifest__.py
@@ -61,7 +61,6 @@ This module provides the core of the Odoo Web Client.
'web.assets_common': [
('include', 'web._assets_helpers'),
- 'web/static/src/scss/debug_profiling.scss',
'web/static/lib/bootstrap/scss/_variables.scss',
('include', 'web._assets_common_styles'),
diff --git a/addons/web/static/src/core/debug/debug_menu.js b/addons/web/static/src/core/debug/debug_menu.js
index fad7c8562de..dbdccf2c459 100644
--- a/addons/web/static/src/core/debug/debug_menu.js
+++ b/addons/web/static/src/core/debug/debug_menu.js
@@ -64,7 +64,10 @@ export class DebugMenu extends Component {
}
onDropdownItemSelected(ev) {
- ev.detail.payload.callback();
+ // items of type "component" don't necessarily have a payload/callback
+ if (ev.detail.payload && ev.detail.payload.callback) {
+ ev.detail.payload.callback();
+ }
}
onClickOnTagA(ev) {
diff --git a/addons/web/static/src/core/debug/debug_menu.xml b/addons/web/static/src/core/debug/debug_menu.xml
index 859cd877d83..7abfb4c5d14 100644
--- a/addons/web/static/src/core/debug/debug_menu.xml
+++ b/addons/web/static/src/core/debug/debug_menu.xml
@@ -17,6 +17,7 @@
+
diff --git a/addons/web/static/src/core/debug/debug_menu_items.js b/addons/web/static/src/core/debug/debug_menu_items.js
index 80768303363..eced7c1d768 100644
--- a/addons/web/static/src/core/debug/debug_menu_items.js
+++ b/addons/web/static/src/core/debug/debug_menu_items.js
@@ -103,7 +103,6 @@ function becomeSuperuser({ env }) {
hide: !env.services.user.isAdmin,
href: becomeSuperuserULR,
callback: () => {
- //TODO add /web/become
browser.open(becomeSuperuserULR, "_self");
},
sequence: 440,
diff --git a/addons/web/static/src/core/debug/profiling/profiling_item.js b/addons/web/static/src/core/debug/profiling/profiling_item.js
new file mode 100644
index 00000000000..64eb4f890d1
--- /dev/null
+++ b/addons/web/static/src/core/debug/profiling/profiling_item.js
@@ -0,0 +1,24 @@
+/** @odoo-module **/
+
+import { DropdownItem } from "@web/core/dropdown/dropdown_item";
+import { useBus } from "@web/core/bus_hook";
+import { useService } from "@web/core/service_hook";
+
+const { Component } = owl;
+
+export class ProfilingItem extends Component {
+ setup() {
+ this.profiling = useService("profiling");
+ this.actionService = useService("action");
+ useBus(this.props.bus, "UPDATE", this.render);
+ }
+
+ changeParam(param, ev) {
+ this.profiling.setParam(param, ev.target.value);
+ }
+ openProfiles() {
+ this.actionService.doAction("base.action_menu_ir_profile");
+ }
+}
+ProfilingItem.components = { DropdownItem };
+ProfilingItem.template = "web.DebugMenu.ProfilingItem";
diff --git a/addons/web/static/src/core/debug/profiling/profiling_item.scss b/addons/web/static/src/core/debug/profiling/profiling_item.scss
new file mode 100644
index 00000000000..8644c3e1e5e
--- /dev/null
+++ b/addons/web/static/src/core/debug/profiling/profiling_item.scss
@@ -0,0 +1,25 @@
+.o_debug_profiling_item {
+ .o_profiling_switch {
+ padding-top: 3px;
+ padding-bottom: 3px;
+ .custom-switch {
+ display: inline-block;
+ }
+ .custom-control-label {
+ cursor: pointer;
+ }
+ .o_open_profiling {
+ padding-top: 3px;
+ }
+ }
+}
+
+.o_debug_manager .fa-bug {
+ position: relative;
+ .o_recording {
+ position: absolute;
+ bottom: -0.1em;
+ right: -0.4em;
+ font-size: 0.8em;
+ }
+}
diff --git a/addons/web/static/src/core/debug/profiling/profiling_item.xml b/addons/web/static/src/core/debug/profiling/profiling_item.xml
new file mode 100644
index 00000000000..a6e43a0e4b8
--- /dev/null
+++ b/addons/web/static/src/core/debug/profiling/profiling_item.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+ Enable profiling
+
+
+
+
+
+
+
+
+ Record sql
+
+
+
+ Record traces
+
+
+
+
+
+
+
diff --git a/addons/web/static/src/core/debug/profiling/profiling_service.js b/addons/web/static/src/core/debug/profiling/profiling_service.js
new file mode 100644
index 00000000000..0f67e5e92de
--- /dev/null
+++ b/addons/web/static/src/core/debug/profiling/profiling_service.js
@@ -0,0 +1,104 @@
+/** @odoo-module **/
+
+import { registry } from "@web/core/registry";
+import { ProfilingItem } from "./profiling_item";
+
+const { core } = owl;
+
+const profilingService = {
+ dependencies: ["orm"],
+ start(env, { orm }) {
+ const sessionInfo = odoo.session_info;
+ const state = {
+ session: sessionInfo.profile_session || false,
+ collectors: sessionInfo.profile_collectors || ["sql", "traces_async"],
+ params: sessionInfo.profile_params || {},
+ get isEnabled() {
+ return Boolean(state.session);
+ },
+ };
+ const bus = new core.EventBus();
+
+ let recordingIcon = null;
+ function updateDebugIcon() {
+ const debugItem = document.querySelector(".o_main_navbar .o_debug_manager .fa-bug");
+ if (state.isEnabled) {
+ recordingIcon = document.createElement("span");
+ recordingIcon.classList.add("o_recording", "text-danger", "fa", "fa-circle");
+ debugItem.appendChild(recordingIcon);
+ } else if (recordingIcon) {
+ debugItem.removeChild(recordingIcon);
+ recordingIcon = null;
+ }
+ }
+
+ if (env.debug) {
+ env.bus.on("WEB_CLIENT_READY", null, updateDebugIcon);
+ }
+
+ async function setProfiling(params) {
+ const kwargs = Object.assign(
+ {
+ collectors: state.collectors,
+ params: state.params,
+ profile: state.isEnabled,
+ },
+ params
+ );
+ const resp = await orm.call("ir.profile", "set_profiling", [], kwargs);
+ state.session = resp.session;
+ state.collectors = resp.collectors;
+ state.params = resp.params;
+ bus.trigger("UPDATE");
+ updateDebugIcon();
+ }
+
+ function profilingSeparator() {
+ return {
+ type: "separator",
+ sequence: 500,
+ };
+ }
+
+ function profilingItem() {
+ return {
+ type: "component",
+ Component: ProfilingItem,
+ props: { bus },
+ sequence: 510,
+ };
+ }
+
+ registry
+ .category("debug")
+ .add("profilingSeparator", profilingSeparator)
+ .add("profilingItem", profilingItem);
+
+ return {
+ state,
+ async toggleProfiling() {
+ await setProfiling({ profile: !state.isEnabled });
+ },
+ async toggleCollector(collector) {
+ let nextCollectors = state.collectors.slice();
+ const index = nextCollectors.indexOf(collector);
+ if (index >= 0) {
+ nextCollectors.splice(index, 1);
+ } else {
+ nextCollectors.push(collector);
+ }
+ await setProfiling({ collectors: nextCollectors });
+ },
+ async setParam(key, value) {
+ const nextParams = Object.assign({}, state.params);
+ nextParams[key] = value;
+ await setProfiling({ params: nextParams });
+ },
+ isCollectorEnabled(collector) {
+ return state.collectors.includes(collector);
+ },
+ };
+ },
+};
+
+registry.category("services").add("profiling", profilingService);
diff --git a/addons/web/static/src/legacy/debug_manager.js b/addons/web/static/src/legacy/debug_manager.js
index ed909667243..c1fc6282cc6 100644
--- a/addons/web/static/src/legacy/debug_manager.js
+++ b/addons/web/static/src/legacy/debug_manager.js
@@ -401,9 +401,7 @@ export function editView({ accessRights, action, component, env }) {
return null;
}
const { viewId, viewType } = component.widget;
- const displayName = action.views
- .find((v) => v.type === viewType)
- .name.toString();
+ const displayName = action.views.find((v) => v.type === viewType).name.toString();
const description = env._t("Edit View: ") + displayName;
return {
type: "item",
@@ -424,12 +422,7 @@ function editControlPanelView({ accessRights, component, env }) {
type: "item",
description,
callback: () => {
- editModelDebug(
- env,
- description,
- "ir.ui.view",
- component.props.viewInfo.view_id
- );
+ editModelDebug(env, description, "ir.ui.view", component.props.viewInfo.view_id);
},
sequence: 360,
};
@@ -506,24 +499,24 @@ const debugRegistry = registry.category("debug");
debugRegistry
.category("action")
- .add("actionSeparator", actionSeparator)
- .add("editAction", editAction)
- .add("viewFields", viewFields)
- .add("manageFilters", manageFilters)
- .add("technicalTranslation", technicalTranslation)
- .add("accessSeparator", accessSeparator)
- .add("viewAccessRights", viewAccessRights)
- .add("viewRecordRules", viewRecordRules)
+ .add("actionSeparator", actionSeparator)
+ .add("editAction", editAction)
+ .add("viewFields", viewFields)
+ .add("manageFilters", manageFilters)
+ .add("technicalTranslation", technicalTranslation)
+ .add("accessSeparator", accessSeparator)
+ .add("viewAccessRights", viewAccessRights)
+ .add("viewRecordRules", viewRecordRules);
debugRegistry
.category("view")
- .add("viewSeparator", viewSeparator)
- .add("fieldsViewGet", fieldsViewGet)
- .add("editView", editView)
- .add("editControlPanelView", editControlPanelView)
+ .add("viewSeparator", viewSeparator)
+ .add("fieldsViewGet", fieldsViewGet)
+ .add("editView", editView)
+ .add("editControlPanelView", editControlPanelView);
debugRegistry
.category("form")
- .add("setDefaults", setDefaults)
- .add("viewMetadata", viewMetadata)
- .add("manageAttachments", manageAttachments);
+ .add("setDefaults", setDefaults)
+ .add("viewMetadata", viewMetadata)
+ .add("manageAttachments", manageAttachments);
diff --git a/addons/web/static/src/legacy/frontend/debug_manager/debug.xml b/addons/web/static/src/legacy/frontend/debug_manager/debug.xml
index adae7a7f09c..4e50a483608 100644
--- a/addons/web/static/src/legacy/frontend/debug_manager/debug.xml
+++ b/addons/web/static/src/legacy/frontend/debug_manager/debug.xml
@@ -9,7 +9,9 @@
t-att-aria-label="_devtool_button_title + widget.debug_mode_help"
t-att-data-debug-mode="widget.debug_mode"
data-toggle="dropdown" aria-expanded="false" tabindex="-1" data-display="static">
-
+
+
+
@@ -20,6 +22,48 @@
Regenerate Assets Bundles
Become Superuser
Leave the Developer Tools
+
+
+
+
+
+ Enable profiling
+
+
+
+
+
+
+
+
+
+ Record sql
+
+
+
+
+
+ Record traces
+
+
+
+
+
+
+
+
diff --git a/addons/web/static/src/scss/debug_profiling.scss b/addons/web/static/src/legacy/frontend/debug_manager/debug_manager.scss
similarity index 99%
rename from addons/web/static/src/scss/debug_profiling.scss
rename to addons/web/static/src/legacy/frontend/debug_manager/debug_manager.scss
index b6c62203e34..6b7246e9729 100644
--- a/addons/web/static/src/scss/debug_profiling.scss
+++ b/addons/web/static/src/legacy/frontend/debug_manager/debug_manager.scss
@@ -1,4 +1,3 @@
-
.o_debug_mode .fa { /* Active profiling red dot should be overed on the bottom right corner of the bug icon*/
position: relative;
.fa {