diff --git a/addons/web/static/src/js/views/list/list_editable_renderer.js b/addons/web/static/src/js/views/list/list_editable_renderer.js index 020f91612ab..2ff25108795 100644 --- a/addons/web/static/src/js/views/list/list_editable_renderer.js +++ b/addons/web/static/src/js/views/list/list_editable_renderer.js @@ -541,7 +541,7 @@ ListRenderer.include({ * @private */ _freezeColumnWidths: function () { - if (!this.state.data.length && !this.columnWidths) { + if (!this._hasVisibleRecords(this.state) && !this.columnWidths) { // there is no record -> don't force column's widths w.r.t. their label return; } @@ -689,6 +689,26 @@ ListRenderer.include({ _getRow: function (recordId) { return this.$('.o_data_row[data-id="' + recordId + '"]'); }, + /** + * This function returns true iff records are visible in the list, i.e. + * if the list is ungrouped: true iff the list isn't empty; + * if the list is grouped: true iff there is at least one unfolded group + * containing records. + * + * @param {Object} list a datapoint + * @returns {boolean} + */ + _hasVisibleRecords: function (list) { + if (!list.groupedBy.length) { + return !!list.data.length; + } else { + var hasVisibleRecords = false; + for (var i = 0; i < list.data.length; i++) { + hasVisibleRecords = hasVisibleRecords || this._hasVisibleRecords(list.data[i]); + } + return hasVisibleRecords; + } + }, /** * Move the cursor on the end of the previous line (or of the last line if * we are on the first one). @@ -913,7 +933,7 @@ ListRenderer.include({ _renderHeader: function () { var $thead = this._super.apply(this, arguments); - if (this.editable && !this.state.data.length && !this.columnWidths) { + if (this.editable && !this._hasVisibleRecords(this.state) && !this.columnWidths) { // we compute the sum of the weights for each columns, excluding // those with an absolute width. var totalWidth = this.columns.reduce(function (acc, column) { @@ -1009,7 +1029,7 @@ ListRenderer.include({ return this._super.apply(this, arguments).then(function () { var table = self.el.getElementsByTagName('table')[0]; if (table) { // no table if no content helper displayed - if (!self.state.data.length) { // FIXME: only handles ungrouped case + if (!self._hasVisibleRecords(self.state)) { table.classList.add('o_empty_list'); } if (self.editable) { diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js index c761993b674..fa78f98ee23 100644 --- a/addons/web/static/tests/views/list_tests.js +++ b/addons/web/static/tests/views/list_tests.js @@ -1497,6 +1497,40 @@ QUnit.module('Views', { list.destroy(); }); + QUnit.test('width of some of the fields should be hardcoded if no data (grouped case)', async function (assert) { + const assertions = [ + { field: 'bar', expected: 40, type: 'Boolean' }, + { field: 'int_field', expected: 74, type: 'Integer' }, + { field: 'qux', expected: 92, type: 'Float' }, + { field: 'date', expected: 92, type: 'Date' }, + { field: 'datetime', expected: 146, type: 'Datetime' }, + ]; + assert.expect(assertions.length + 1); + + var list = await createView({ + View: ListView, + model: 'foo', + data: this.data, + arch: '' + + '' + + '' + + '' + + '' + + '' + + '' + + '', + groupBy: ['int_field'], + }); + + assertions.forEach(a => { + assert.strictEqual(list.$(`th[data-name="${a.field}"]`)[0].offsetWidth, a.expected, + `Field ${a.type} should have a fixed width of ${a.expected} pixels`); + }); + assert.strictEqual(list.$('th[data-name="foo"]')[0].style.width, '100%'); + + list.destroy(); + }); + QUnit.test('column width should depend on the widget', async function (assert) { assert.expect(1);