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 @@
+
+