Files
odoo_source/addons/web/static/src/views/debug_items.js
T
Denis Ledoux 00a168f1cc [IMP] web: rename "Fields View Get" debug menu in "Get View"
Following the refactoring done in odoo/odoo#87522
renaming `fields_view_get` into `get_view`

closes odoo/odoo#100086

Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
2022-09-14 04:23:44 +02:00

362 lines
12 KiB
JavaScript

/** @odoo-module **/
import { _lt } from "@web/core/l10n/translation";
import { Dialog } from "@web/core/dialog/dialog";
import { editModelDebug } from "@web/core/debug/debug_utils";
import { formatDateTime, parseDateTime } from "@web/core/l10n/dates";
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";
import { formatMany2one } from "@web/views/fields/formatters";
import { evalDomain } from "@web/views/utils";
import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog";
const { Component, onWillStart, useState, xml } = owl;
const debugRegistry = registry.category("debug");
function viewSeparator() {
return { type: "separator", sequence: 300 };
}
debugRegistry.category("view").add("viewSeparator", viewSeparator);
//------------------------------------------------------------------------------
// Get view
//------------------------------------------------------------------------------
class GetViewDialog extends Component {}
GetViewDialog.template = xml`
<Dialog title="this.constructor.title">
<pre t-esc="props.arch"/>
</Dialog>`;
GetViewDialog.components = { Dialog };
GetViewDialog.props = {
arch: { type: String },
close: { type: Function },
};
GetViewDialog.title = _lt("Get View");
export function getView({ component, env }) {
let { arch } = component.props;
if ("viewInfo" in component.props) {
//legacy
arch = component.props.viewInfo.arch;
}
return {
type: "item",
description: env._t("Get View"),
callback: () => {
env.services.dialog.add(GetViewDialog, { arch });
},
sequence: 340,
};
}
debugRegistry.category("view").add("getView", getView);
//------------------------------------------------------------------------------
// Edit View
//------------------------------------------------------------------------------
export function editView({ accessRights, component, env }) {
if (!accessRights.canEditView) {
return null;
}
let { viewId, viewType: type } = component.env.config || {}; // fallback is there for legacy
if ("viewInfo" in component.props) {
// legacy
viewId = component.props.viewInfo.view_id;
type = component.props.viewInfo.type;
type = type === "tree" ? "list" : type;
}
const displayName = type[0].toUpperCase() + type.slice(1);
const description = env._t("Edit View: ") + displayName;
return {
type: "item",
description,
callback: () => {
editModelDebug(env, description, "ir.ui.view", viewId);
},
sequence: 350,
};
}
debugRegistry.category("view").add("editView", editView);
//------------------------------------------------------------------------------
// Edit SearchView
//------------------------------------------------------------------------------
export function editSearchView({ accessRights, component, env }) {
if (!accessRights.canEditView) {
return null;
}
let { searchViewId } = component.props.info || {}; // fallback is there for legacy
if ("viewParams" in component.props) {
//legacy
if (!component.props.viewParams.action.controlPanelFieldsView) {
return null;
}
searchViewId = component.props.viewParams.action.controlPanelFieldsView.view_id;
}
if (searchViewId === undefined) {
return null;
}
const description = env._t("Edit SearchView");
return {
type: "item",
description,
callback: () => {
editModelDebug(env, description, "ir.ui.view", searchViewId);
},
sequence: 360,
};
}
debugRegistry.category("view").add("editSearchView", editSearchView);
// -----------------------------------------------------------------------------
// View Metadata
// -----------------------------------------------------------------------------
class GetMetadataDialog extends Component {
setup() {
this.orm = useService("orm");
this.dialogService = useService("dialog");
this.title = this.env._t("View Metadata");
this.state = useState({});
onWillStart(() => this.loadMetadata());
}
onClickCreateXmlid() {
const context = Object.assign({}, this.context, {
default_module: "__custom__",
default_res_id: this.state.id,
default_model: this.props.resModel,
});
this.dialogService.add(FormViewDialog, {
context,
onRecordSaved: () => this.loadMetadata(),
resModel: "ir.model.data",
});
}
async toggleNoupdate() {
await this.env.services.orm.call("ir.model.data", "toggle_noupdate", [
this.props.resModel,
this.state.id,
]);
await this.loadMetadata();
}
async loadMetadata() {
const args = [[this.props.resId]];
const result = await this.orm.call(this.props.resModel, "get_metadata", args);
const metadata = result[0];
this.state.id = metadata.id;
this.state.xmlid = metadata.xmlid;
this.state.xmlids = metadata.xmlids;
this.state.noupdate = metadata.noupdate;
this.state.creator = formatMany2one(metadata.create_uid);
this.state.lastModifiedBy = formatMany2one(metadata.write_uid);
this.state.createDate = formatDateTime(parseDateTime(metadata.create_date));
this.state.writeDate = formatDateTime(parseDateTime(metadata.write_date));
}
}
GetMetadataDialog.template = "web.DebugMenu.GetMetadataDialog";
GetMetadataDialog.components = { Dialog };
export function viewMetadata({ component, env }) {
const resId = component.model.root.resId;
if (!resId) {
return null; // No record
}
return {
type: "item",
description: env._t("View Metadata"),
callback: () => {
env.services.dialog.add(GetMetadataDialog, {
resModel: component.props.resModel,
resId,
});
},
sequence: 320,
};
}
debugRegistry.category("form").add("viewMetadata", viewMetadata);
// -----------------------------------------------------------------------------
// Set Defaults
// -----------------------------------------------------------------------------
class SetDefaultDialog extends Component {
setup() {
this.orm = useService("orm");
this.title = this.env._t("Set Defaults");
this.state = {
fieldToSet: "",
condition: "",
scope: "self",
};
const root = this.props.component.model.root;
this.fields = root.fields;
this.fieldsInfo = root.activeFields;
this.fieldNamesInView = root.fieldNames;
this.fieldNamesBlackList = ["message_attachment_count"];
this.fieldsValues = root.data;
this.modifierDatas = {};
this.fieldNamesInView.forEach((fieldName) => {
this.modifierDatas[fieldName] = this.fieldsInfo[fieldName].modifiers;
});
this.defaultFields = this.getDefaultFields();
this.conditions = this.getConditions();
}
getDefaultFields() {
return this.fieldNamesInView
.filter((fieldName) => !this.fieldNamesBlackList.includes(fieldName))
.map((fieldName) => {
const modifierData = this.modifierDatas[fieldName];
let invisibleOrReadOnly;
if (modifierData) {
const evalContext = this.props.component.model.root.evalContext;
invisibleOrReadOnly =
evalDomain(modifierData.invisible, evalContext) ||
evalDomain(modifierData.readonly, evalContext);
}
const fieldInfo = this.fields[fieldName];
const valueDisplayed = this.display(fieldInfo, this.fieldsValues[fieldName]);
const value = valueDisplayed[0];
const displayed = valueDisplayed[1];
// ignore fields which are empty, invisible, readonly, o2m or m2m
if (
!value ||
invisibleOrReadOnly ||
fieldInfo.type === "one2many" ||
fieldInfo.type === "many2many" ||
fieldInfo.type === "binary" ||
this.fieldsInfo[fieldName].options.isPassword ||
fieldInfo.depends === undefined ||
fieldInfo.depends.length !== 0
) {
return false;
}
return {
name: fieldName,
string: fieldInfo.string,
value,
displayed,
};
})
.filter((val) => val)
.sort((field) => field.string);
}
getConditions() {
return this.fieldNamesInView
.filter((fieldName) => {
const fieldInfo = this.fields[fieldName];
return fieldInfo.change_default;
})
.map((fieldName) => {
const fieldInfo = this.fields[fieldName];
const valueDisplayed = this.display(fieldInfo, this.fieldsValues[fieldName]);
const value = valueDisplayed[0];
const displayed = valueDisplayed[1];
return {
name: fieldName,
string: fieldInfo.string,
value: value,
displayed: displayed,
};
});
}
display(fieldInfo, value) {
let displayed = value;
if (value && fieldInfo.type === "many2one") {
displayed = value[1];
value = value[0];
} else if (value && fieldInfo.type === "selection") {
displayed = fieldInfo.selection.find((option) => {
return option[0] === value;
})[1];
}
return [value, displayed];
}
async saveDefault() {
if (!this.state.fieldToSet) {
return;
}
const fieldToSet = this.defaultFields.find((field) => {
return field.name === this.state.fieldToSet;
}).value;
await this.orm.call("ir.default", "set", [
this.props.resModel,
this.state.fieldToSet,
fieldToSet,
this.state.scope === "self",
true,
this.state.condition || false,
]);
this.props.close();
}
}
SetDefaultDialog.template = "web.DebugMenu.SetDefaultDialog";
SetDefaultDialog.components = { Dialog };
export function setDefaults({ component, env }) {
return {
type: "item",
description: env._t("Set Defaults"),
callback: () => {
env.services.dialog.add(SetDefaultDialog, {
resModel: component.props.resModel,
component,
});
},
sequence: 310,
};
}
debugRegistry.category("form").add("setDefaults", setDefaults);
//------------------------------------------------------------------------------
// Manage Attachments
//------------------------------------------------------------------------------
export function manageAttachments({ component, env }) {
const resId = component.model.root.resId;
if (!resId) {
return null; // No record
}
const description = env._t("Manage Attachments");
return {
type: "item",
description,
callback: () => {
env.services.action.doAction({
res_model: "ir.attachment",
name: description,
views: [
[false, "list"],
[false, "form"],
],
type: "ir.actions.act_window",
domain: [
["res_model", "=", component.props.resModel],
["res_id", "=", resId],
],
context: {
default_res_model: component.props.resModel,
default_res_id: resId,
},
});
},
sequence: 330,
};
}
debugRegistry.category("form").add("manageAttachments", manageAttachments);