From 6a5497c187cbed7ae33e0433b1c34ea04670af71 Mon Sep 17 00:00:00 2001 From: Mathieu Duckerts-Antoine Date: Thu, 25 Aug 2022 12:46:37 +0000 Subject: [PATCH] [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) --- addons/resource/__manifest__.py | 8 +- .../static/src/section_list_renderer.js | 57 ++++++++++++ .../static/src/section_list_renderer.xml | 10 +++ .../static/src/section_one2many_field.js | 17 ++++ .../section_one2many_field_tests.js | 86 +++++++++++++++++++ 5 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 addons/resource/static/src/section_list_renderer.js create mode 100644 addons/resource/static/src/section_list_renderer.xml create mode 100644 addons/resource/static/src/section_one2many_field.js create mode 100644 addons/resource/static/tests/components/section_one2many_field_tests.js diff --git a/addons/resource/__manifest__.py b/addons/resource/__manifest__.py index b7b9d979fd1..abffc221c01 100644 --- a/addons/resource/__manifest__.py +++ b/addons/resource/__manifest__.py @@ -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', diff --git a/addons/resource/static/src/section_list_renderer.js b/addons/resource/static/src/section_list_renderer.js new file mode 100644 index 00000000000..8364fc7a477 --- /dev/null +++ b/addons/resource/static/src/section_list_renderer.js @@ -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"; diff --git a/addons/resource/static/src/section_list_renderer.xml b/addons/resource/static/src/section_list_renderer.xml new file mode 100644 index 00000000000..cb4fef6d5e6 --- /dev/null +++ b/addons/resource/static/src/section_list_renderer.xml @@ -0,0 +1,10 @@ + + + + + + activeActions and !isSection(record) + + + + diff --git a/addons/resource/static/src/section_one2many_field.js b/addons/resource/static/src/section_one2many_field.js new file mode 100644 index 00000000000..54ab8dd10f1 --- /dev/null +++ b/addons/resource/static/src/section_one2many_field.js @@ -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); diff --git a/addons/resource/static/tests/components/section_one2many_field_tests.js b/addons/resource/static/tests/components/section_one2many_field_tests.js new file mode 100644 index 00000000000..94167d4f121 --- /dev/null +++ b/addons/resource/static/tests/components/section_one2many_field_tests.js @@ -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: ` +
+ + + + + + + +
+ `, + }); + 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"); + }); +});