[FIX] web: optional viewMode in x2m field

Before this commit, when having a x2many field invisible in a view, and displaying
it anyway in studio, there was a crash because some variable was undefined.

This originated from commit f22961a, which did not account
for the fact that viewMode is an optional props.

After this commit, the util function used by the x2m field and where the
crash occur has been refactored.
Moreover, the x2m field template has also been slightly refactored.

closes odoo/odoo#120918

Taskid: 3305808
Related: odoo/enterprise#40852
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
This commit is contained in:
Bruno Boi
2023-05-10 16:36:51 +02:00
parent a25d20ee3e
commit 2ddc7348f2
3 changed files with 31 additions and 12 deletions
@@ -44,7 +44,10 @@ export class X2ManyField extends Component {
);
this.archInfo = this.props.views?.[this.props.viewMode] || {};
this.className = computeViewClassName(this.props.viewMode, this.archInfo.xmlDoc);
const classes = this.props.viewMode
? ["o_field_x2many", `o_field_x2many_${this.props.viewMode}`]
: ["o_field_x2many"];
this.className = computeViewClassName(this.props.viewMode, this.archInfo.xmlDoc, classes);
const { activeActions, creates } = this.archInfo;
if (this.props.viewMode === "kanban") {
@@ -2,7 +2,7 @@
<templates xml:space="preserve">
<t t-name="web.X2ManyField" owl="1">
<div t-att-class="className" t-attf-class="o_field_x2many o_field_x2many_{{props.viewMode}}">
<div t-att-class="className">
<div class="o_x2m_control_panel">
<t t-if="displayControlPanelButtons">
<div class="o_cp_buttons" role="toolbar" aria-label="Control panel buttons" t-ref="buttons">
@@ -15,7 +15,7 @@
t-on-click.stop.prevent="() => this.onAdd({ context: create.context })"
>
<t t-esc="create.string"/>
</a>
</button>
<ViewButton
t-if="create.type === 'button'"
className="`${create.className}`"
+25 -9
View File
@@ -83,17 +83,33 @@ export function archParseBoolean(str, trueIfEmpty = false) {
return str ? !/^false|0$/i.test(str) : trueIfEmpty;
}
/**
* @param {string?} type
* @returns {string | false}
*/
function getViewClass(type) {
const isValidType = Boolean(type) && registry.category("views").contains(type);
return isValidType && `o_${type}_view`;
}
/**
* @param {string?} viewType
* @param {Element?} rootNode
* @param {string[]} additionalClassList
* @returns {string}
*/
export function computeViewClassName(viewType, rootNode, additionalClassList = []) {
const subType = rootNode.getAttribute("js_class");
const isValidSubType = subType && registry.category("views").contains(subType);
const subTypeClass = isValidSubType ? `o_${subType}_view` : "";
const classList = [
`o_${viewType}_view`,
subTypeClass,
...(rootNode.getAttribute("class") || "").split(" "),
const subType = rootNode?.getAttribute("js_class");
const classList = rootNode?.getAttribute("class")?.split(" ") || [];
const uniqueClasses = new Set([
getViewClass(viewType),
getViewClass(subType),
...classList,
...additionalClassList,
];
return [...new Set(classList)].filter((c) => c).join(" ");
]);
return Array.from(uniqueClasses)
.filter((c) => c) // remove falsy values
.join(" ");
}
/**