[REF] resource: convert section_one2many
This commit converts the old "section_one2many" field to the new WOWL field API. closes odoo/odoo#97984 Related: odoo/enterprise#30789 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
@@ -22,7 +22,13 @@ associated to every resource. It also manages the leaves of every resource.
|
||||
],
|
||||
'assets': {
|
||||
'web.assets_backend': [
|
||||
'resource/static/**/*',
|
||||
'resource/static/src/**/*',
|
||||
],
|
||||
'web.qunit_suite_tests': [
|
||||
'resource/static/tests/components/*.js',
|
||||
],
|
||||
'web.assets_qweb': [
|
||||
'resource/static/src/**/*.xml',
|
||||
],
|
||||
},
|
||||
'license': 'LGPL-3',
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { ListRenderer } from "@web/views/list/list_renderer";
|
||||
|
||||
const { useEffect } = owl;
|
||||
|
||||
export class SectionListRenderer extends ListRenderer {
|
||||
setup() {
|
||||
super.setup();
|
||||
|
||||
this.displayType = "line_section";
|
||||
this.titleField = "title";
|
||||
|
||||
useEffect(
|
||||
(table) => {
|
||||
if (table) {
|
||||
table.classList.add("o_section_list_view");
|
||||
}
|
||||
},
|
||||
() => [this.tableRef.el]
|
||||
);
|
||||
}
|
||||
|
||||
getColumns(record) {
|
||||
const columns = super.getColumns(record);
|
||||
if (this.isSection(record)) {
|
||||
return this.getSectionColumns(columns);
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
getRowClass(record) {
|
||||
const classNames = super.getRowClass(record).split(" ");
|
||||
if (this.isSection(record)) {
|
||||
classNames.push(`o_is_${this.displayType}`, `fw-bold`);
|
||||
}
|
||||
return classNames.join(" ");
|
||||
}
|
||||
|
||||
getSectionColumns(columns) {
|
||||
const sectionColumns = columns.filter((col) => col.widget === "handle");
|
||||
let colspan = columns.length - sectionColumns.length;
|
||||
if (this.props.activeActions.onDelete) {
|
||||
colspan++;
|
||||
}
|
||||
const titleCol = columns.find(
|
||||
(col) => col.type === "field" && col.name === this.titleField
|
||||
);
|
||||
sectionColumns.push({ ...titleCol, colspan });
|
||||
return sectionColumns;
|
||||
}
|
||||
|
||||
isSection(record) {
|
||||
return record.data.display_type === this.displayType;
|
||||
}
|
||||
}
|
||||
SectionListRenderer.recordRowTemplate = "resource.SectionListRenderer.RecordRow";
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="resource.SectionListRenderer.RecordRow" t-inherit="web.ListRenderer.RecordRow" owl="1">
|
||||
<xpath expr="//t[@t-if='activeActions']" position="attributes">
|
||||
<attribute name="t-if">activeActions and !isSection(record)</attribute>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -0,0 +1,17 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { SectionListRenderer } from "./section_list_renderer";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { X2ManyField } from "@web/views/fields/x2many/x2many_field";
|
||||
|
||||
class SectionOneToManyField extends X2ManyField {}
|
||||
SectionOneToManyField.components = {
|
||||
...X2ManyField.components,
|
||||
ListRenderer: SectionListRenderer,
|
||||
};
|
||||
SectionOneToManyField.defaultProps = {
|
||||
...X2ManyField.defaultProps,
|
||||
editable: "bottom",
|
||||
};
|
||||
|
||||
registry.category("fields").add("section_one2many", SectionOneToManyField);
|
||||
@@ -0,0 +1,86 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { clickEdit, getFixture } from "@web/../tests/helpers/utils";
|
||||
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
|
||||
|
||||
QUnit.module("SectionOneToManyField", (hooks) => {
|
||||
let serverData;
|
||||
let target;
|
||||
|
||||
hooks.beforeEach(() => {
|
||||
target = getFixture();
|
||||
|
||||
serverData = {
|
||||
models: {
|
||||
partner: {
|
||||
fields: { lines: { type: "one2many", relation: "lines_sections" } },
|
||||
records: [
|
||||
{
|
||||
id: 1,
|
||||
lines: [1, 2],
|
||||
},
|
||||
],
|
||||
},
|
||||
lines_sections: {
|
||||
fields: {
|
||||
display_type: { type: "char" },
|
||||
title: { type: "char", string: "Title" },
|
||||
int: { type: "number", string: "integer" },
|
||||
},
|
||||
records: [
|
||||
{
|
||||
id: 1,
|
||||
display_type: "line_section",
|
||||
title: "firstSectionTitle",
|
||||
int: 4,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
display_type: false,
|
||||
title: "recordTitle",
|
||||
int: 5,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
setupViewRegistries();
|
||||
});
|
||||
|
||||
QUnit.test("basic rendering", async (assert) => {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="lines" widget="section_one2many">
|
||||
<tree>
|
||||
<field name="display_type" invisible="1" />
|
||||
<field name="title" />
|
||||
<field name="int" />
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
assert.containsOnce(target, ".o_field_x2many .o_list_renderer table.o_section_list_view");
|
||||
assert.containsN(target, ".o_data_row", 2);
|
||||
const rows = target.querySelectorAll(".o_data_row");
|
||||
assert.hasClass(rows[0], "o_is_line_section fw-bold");
|
||||
assert.doesNotHaveClass(rows[1], "o_is_line_section fw-bold");
|
||||
assert.strictEqual(rows[0].textContent, "firstSectionTitle");
|
||||
assert.strictEqual(rows[1].textContent, "recordTitle5");
|
||||
assert.strictEqual(rows[0].querySelector("td[name=title]").getAttribute("colspan"), "2");
|
||||
assert.strictEqual(rows[1].querySelector("td[name=title]").getAttribute("colspan"), null);
|
||||
|
||||
assert.containsNone(target, ".o_list_record_remove");
|
||||
|
||||
await clickEdit(target);
|
||||
|
||||
assert.containsOnce(target, ".o_list_record_remove");
|
||||
assert.containsNone(target, ".o_is_line_section .o_list_record_remove");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user