From d44e591ca961015385b1a450187d592fb4fd64ad Mon Sep 17 00:00:00 2001 From: std-odoo Date: Thu, 27 Jan 2022 08:17:56 +0000 Subject: [PATCH] [IMP] web: use Yes/No instead of True/False in views when grouping Purpose ======= When we group the record based on a boolean fields, we want to show "Yes/No" instead of "True/False". This has been done for the list view, the pivot view and the kanban view. Task-2648390 Part-of: odoo/odoo#79911 --- .../static/tests/tours/crm_forecast_tour.js | 2 +- .../legacy/js/views/kanban/kanban_column.js | 6 ++-- .../src/legacy/js/views/list/list_renderer.js | 4 +-- .../web/static/src/views/pivot/pivot_model.js | 11 ++++++- .../static/tests/legacy/views/kanban_tests.js | 32 +++++++++---------- .../static/tests/legacy/views/list_tests.js | 26 +++++++-------- .../static/tests/views/pivot_view_tests.js | 18 +++++------ 7 files changed, 55 insertions(+), 44 deletions(-) diff --git a/addons/crm/static/tests/tours/crm_forecast_tour.js b/addons/crm/static/tests/tours/crm_forecast_tour.js index 730c9c82ac0..27a128e99dc 100644 --- a/addons/crm/static/tests/tours/crm_forecast_tour.js +++ b/addons/crm/static/tests/tours/crm_forecast_tour.js @@ -57,7 +57,7 @@ tour.register('crm_forecast', { trigger: ".o_kanban_record .o_kanban_record_title:contains('Test Opportunity 1')", content: "move to the next month", run: function (actions) { - const undefined_groups = $('.o_column_title:contains("Undefined")').length; + const undefined_groups = $('.o_column_title:contains("None")').length; actions.drag_and_drop(` .o_opportunity_kanban .o_kanban_group:eq(${1 + undefined_groups})`, this.$anchor); } }, { diff --git a/addons/web/static/src/legacy/js/views/kanban/kanban_column.js b/addons/web/static/src/legacy/js/views/kanban/kanban_column.js index 907f23d5918..cd4cdc64c55 100644 --- a/addons/web/static/src/legacy/js/views/kanban/kanban_column.js +++ b/addons/web/static/src/legacy/js/views/kanban/kanban_column.js @@ -80,10 +80,12 @@ var KanbanColumn = Widget.extend({ if (options.grouped_by_m2o || options.grouped_by_date || options.grouped_by_m2m) { // For many2x and datetime, a false value means that the field is not set. - this.title = value ? value : _t('Undefined'); + this.title = value ? value : _t('None'); + } else if (this.groupedBy && this.fields[this.groupedBy].type === 'boolean') { + this.title = value === undefined ? _t('None') : (value ? _t('Yes') : _t('No')); } else { // False and 0 might be valid values for these fields. - this.title = value === undefined ? _t('Undefined') : value; + this.title = value === undefined ? _t('None') : value; } if (options.group_by_tooltip) { diff --git a/addons/web/static/src/legacy/js/views/list/list_renderer.js b/addons/web/static/src/legacy/js/views/list/list_renderer.js index d1b23b58869..6e9647e6ac7 100644 --- a/addons/web/static/src/legacy/js/views/list/list_renderer.js +++ b/addons/web/static/src/legacy/js/views/list/list_renderer.js @@ -718,8 +718,8 @@ var ListRenderer = BasicRenderer.extend({ const groupByFieldName = groupBy.split(':')[0]; const groupByField = group.fields[groupByFieldName]; const name = groupByField.type === "boolean" - ? (group.value === undefined ? _t('Undefined') : group.value) - : (group.value === undefined || group.value === false ? _t('Undefined') : group.value); + ? (group.value === undefined ? _t('None') : (group.value ? _t('Yes') : _t('No'))) + : (group.value === undefined || group.value === false ? _t('None') : group.value); var $th = $('') .addClass('o_group_name') .attr('tabindex', -1) diff --git a/addons/web/static/src/views/pivot/pivot_model.js b/addons/web/static/src/views/pivot/pivot_model.js index fb3b353773d..09d65276ce1 100644 --- a/addons/web/static/src/views/pivot/pivot_model.js +++ b/addons/web/static/src/views/pivot/pivot_model.js @@ -1516,8 +1516,17 @@ export class PivotModel extends Model { _sanitizeLabel(value, groupBy, config) { const { metaData } = config; const fieldName = groupBy.split(":")[0]; + if ( + fieldName && + metaData.fields[fieldName] && + metaData.fields[fieldName].type === "boolean" + ) { + return value === undefined ? + this.env._t('None') + : (value ? this.env._t('Yes') : this.env._t('No')); + } if (value === false) { - return this.env._t("Undefined"); + return this.env._t("None"); } if (value instanceof Array) { return this._getNumberedLabel(value, fieldName, config); diff --git a/addons/web/static/tests/legacy/views/kanban_tests.js b/addons/web/static/tests/legacy/views/kanban_tests.js index 6e48dde3e58..9c637ee51de 100644 --- a/addons/web/static/tests/legacy/views/kanban_tests.js +++ b/addons/web/static/tests/legacy/views/kanban_tests.js @@ -357,7 +357,7 @@ QUnit.module('Views', { assert.deepEqual( [...kanban.el.querySelectorAll(".o_kanban_group")].map(el => el.innerText.replace(/\s/g, " ")), - ["Undefined blork", "gold yopblip", "silver yopgnap"], + ["None blork", "gold yopblip", "silver yopgnap"], ); // check archive/restore all actions in kanban header's config dropdown @@ -5996,7 +5996,7 @@ QUnit.module('Views', { "column should contain 2 record(s)"); assert.strictEqual(kanban.$('.o_kanban_group:nth-child(3) .o_kanban_record').length, 1, "column should contain 1 record(s)"); - assert.ok(kanban.$('.o_kanban_group:first span.o_column_title:contains(Undefined)').length, + assert.ok(kanban.$('.o_kanban_group:first span.o_column_title:contains(None)').length, "first column should have a default title for when no value is provided"); assert.ok(!kanban.$('.o_kanban_group:first .o_kanban_header_title').data('original-title'), "tooltip of first column should not defined, since group_by_tooltip title and the many2one field has no value"); @@ -8068,7 +8068,7 @@ QUnit.module('Views', { assert.containsNone(kanban.el, ".o_kanban_group.o_kanban_group_show"); assert.deepEqual( [...kanban.el.querySelectorAll(".o_column_title")].map(el => el.innerText), - ["false", "true"], + ["No", "Yes"], ); assert.deepEqual( [...kanban.el.querySelectorAll(".o_kanban_group:nth-child(1) .o_kanban_counter .progress-bar")].map(el => el.dataset.originalTitle), @@ -8082,7 +8082,7 @@ QUnit.module('Views', { // Apply an active filter await testUtils.dom.click(kanban.el.querySelector(".o_kanban_group:nth-child(2) .progress-bar[data-filter=yop]")); assert.containsOnce(kanban.el, ".o_kanban_group.o_kanban_group_show"); - assert.strictEqual(kanban.el.querySelector(".o_kanban_group.o_kanban_group_show .o_column_title").innerText, "true"); + assert.strictEqual(kanban.el.querySelector(".o_kanban_group.o_kanban_group_show .o_column_title").innerText, "Yes"); // Add searchdomain to something restricting progressbars' values (records still in filtered group) await kanban.update({ domain: [["foo", "=", "yop"]] }); @@ -8090,7 +8090,7 @@ QUnit.module('Views', { // Check that we have now 1 column only and check its progressbar's state assert.containsOnce(kanban.el, ".o_kanban_group"); assert.containsOnce(kanban.el, ".o_kanban_group.o_kanban_group_show"); - assert.strictEqual(kanban.el.querySelector(".o_column_title").innerText, "true"); + assert.strictEqual(kanban.el.querySelector(".o_column_title").innerText, "Yes"); assert.deepEqual( [...kanban.el.querySelectorAll(".o_kanban_group .o_kanban_counter .progress-bar")].map(el => el.dataset.originalTitle), ["1 yop", "0 blip", "0 __false"], @@ -8104,7 +8104,7 @@ QUnit.module('Views', { assert.containsOnce(kanban.el, ".o_kanban_group.o_kanban_group_show"); assert.deepEqual( [...kanban.el.querySelectorAll(".o_column_title")].map(el => el.innerText), - ["false", "true"], + ["No", "Yes"], ); assert.deepEqual( [...kanban.el.querySelectorAll(".o_kanban_group:nth-child(1) .o_kanban_counter .progress-bar")].map(el => el.dataset.originalTitle), @@ -8147,7 +8147,7 @@ QUnit.module('Views', { assert.containsNone(kanban.el, ".o_kanban_group.o_kanban_group_show"); assert.deepEqual( [...kanban.el.querySelectorAll(".o_column_title")].map(el => el.innerText), - ["false", "true"], + ["No", "Yes"], ); assert.deepEqual( [...kanban.el.querySelectorAll(".o_kanban_group:nth-child(1) .o_kanban_counter .progress-bar")].map(el => el.dataset.originalTitle), @@ -8169,7 +8169,7 @@ QUnit.module('Views', { // Apply an active filter await testUtils.dom.click(kanban.el.querySelector(".o_kanban_group:nth-child(2) .progress-bar[data-filter=yop]")); assert.containsOnce(kanban.el, ".o_kanban_group.o_kanban_group_show"); - assert.strictEqual(kanban.el.querySelector(".o_kanban_group.o_kanban_group_show .o_column_title").innerText, "true"); + assert.strictEqual(kanban.el.querySelector(".o_kanban_group.o_kanban_group_show .o_column_title").innerText, "Yes"); assert.deepEqual( [...kanban.el.querySelectorAll(".o_kanban_group.o_kanban_group_show .o_kanban_counter .progress-bar")].map(el => el.dataset.originalTitle), ["1 yop", "1 blip", "1 __false"], @@ -8187,7 +8187,7 @@ QUnit.module('Views', { assert.containsNone(kanban.el, ".o_kanban_group.o_kanban_group_show"); assert.deepEqual( [...kanban.el.querySelectorAll(".o_column_title")].map(el => el.innerText), - ["false", "true"], + ["No", "Yes"], ); assert.deepEqual( [...kanban.el.querySelectorAll(".o_kanban_group:nth-child(1) .o_kanban_counter .progress-bar")].map(el => el.dataset.originalTitle), @@ -8214,7 +8214,7 @@ QUnit.module('Views', { assert.containsNone(kanban.el, ".o_kanban_group.o_kanban_group_show"); assert.deepEqual( [...kanban.el.querySelectorAll(".o_column_title")].map(el => el.innerText), - ["false", "true"], + ["No", "Yes"], ); assert.deepEqual( [...kanban.el.querySelectorAll(".o_kanban_group:nth-child(1) .o_kanban_counter .progress-bar")].map(el => el.dataset.originalTitle), @@ -8265,7 +8265,7 @@ QUnit.module('Views', { assert.containsNone(kanban.el, ".o_kanban_group.o_kanban_group_show"); assert.deepEqual( [...kanban.el.querySelectorAll(".o_column_title")].map(el => el.innerText), - ["false", "true"], + ["No", "Yes"], ); assert.deepEqual( [...kanban.el.querySelectorAll(".o_kanban_group:nth-child(1) .o_kanban_counter .progress-bar")].map(el => el.dataset.originalTitle), @@ -8288,7 +8288,7 @@ QUnit.module('Views', { await testUtils.dom.click(kanban.el.querySelector(".o_kanban_group:nth-child(2) .progress-bar[data-filter=yop]")); assert.hasClass(kanban.el.querySelector(".o_kanban_group:nth-child(2)"), "o_kanban_group_show"); assert.containsOnce(kanban.el, ".o_kanban_group.o_kanban_group_show"); - assert.strictEqual(kanban.el.querySelector(".o_kanban_group.o_kanban_group_show .o_column_title").innerText, "true"); + assert.strictEqual(kanban.el.querySelector(".o_kanban_group.o_kanban_group_show .o_column_title").innerText, "Yes"); assert.containsOnce(kanban.el, ".o_kanban_group.o_kanban_group_show .o_kanban_record"); assert.strictEqual(kanban.el.querySelector(".o_kanban_group.o_kanban_group_show .o_kanban_record").innerText, "1 yop"); @@ -8303,7 +8303,7 @@ QUnit.module('Views', { assert.containsOnce(kanban.el, ".o_kanban_group.o_kanban_group_show"); assert.deepEqual( [...kanban.el.querySelectorAll(".o_column_title")].map(el => el.innerText), - ["false", "true"], + ["No", "Yes"], ); assert.deepEqual( [...kanban.el.querySelectorAll(".o_kanban_group:nth-child(1) .o_kanban_counter .progress-bar")].map(el => el.dataset.originalTitle), @@ -8358,7 +8358,7 @@ QUnit.module('Views', { assert.containsNone(kanban.el, ".o_kanban_group.o_kanban_group_show"); assert.deepEqual( [...kanban.el.querySelectorAll(".o_column_title")].map(el => el.innerText), - ["false", "true"], + ["No", "Yes"], ); assert.deepEqual( [...kanban.el.querySelectorAll(".o_kanban_group:nth-child(1) .o_kanban_counter .progress-bar")].map(el => el.dataset.originalTitle), @@ -8387,7 +8387,7 @@ QUnit.module('Views', { await testUtils.dom.click(kanban.el.querySelector(".o_kanban_group:nth-child(2) .progress-bar[data-filter=yop]")); assert.hasClass(kanban.el.querySelector(".o_kanban_group:nth-child(2)"), "o_kanban_group_show"); assert.containsOnce(kanban.el, ".o_kanban_group.o_kanban_group_show"); - assert.strictEqual(kanban.el.querySelector(".o_kanban_group.o_kanban_group_show .o_column_title").innerText, "true"); + assert.strictEqual(kanban.el.querySelector(".o_kanban_group.o_kanban_group_show .o_column_title").innerText, "Yes"); assert.containsOnce(kanban.el, ".o_kanban_group.o_kanban_group_show .o_kanban_record"); assert.strictEqual(kanban.el.querySelector(".o_kanban_group.o_kanban_group_show .o_kanban_record").innerText, "1 yop"); assert.verifySteps(["/web/dataset/search_read"]); @@ -8403,7 +8403,7 @@ QUnit.module('Views', { assert.containsNone(kanban.el, ".o_kanban_group.o_kanban_group_show"); assert.deepEqual( [...kanban.el.querySelectorAll(".o_column_title")].map(el => el.innerText), - ["false", "true"], + ["No", "Yes"], ); assert.deepEqual( [...kanban.el.querySelectorAll(".o_kanban_group:nth-child(1) .o_kanban_counter .progress-bar")].map(el => el.dataset.originalTitle), diff --git a/addons/web/static/tests/legacy/views/list_tests.js b/addons/web/static/tests/legacy/views/list_tests.js index 947d9b46027..f3c763a0ab2 100644 --- a/addons/web/static/tests/legacy/views/list_tests.js +++ b/addons/web/static/tests/legacy/views/list_tests.js @@ -1316,7 +1316,7 @@ QUnit.module('Views', { assert.containsNone(list, ".o_group_open", "no group is open"); assert.deepEqual( [...list.el.querySelectorAll(".o_group_header .o_group_name")].map((el) => el.innerText), - ["Value 1 (3)", "Value 2 (2)", "Value 3 (1)", "Undefined (1)"], + ["Value 1 (3)", "Value 2 (2)", "Value 3 (1)", "None (1)"], "should have those group headers", ); @@ -1340,7 +1340,7 @@ QUnit.module('Views', { "​blipValue1Value2Value3", "Value3(1)", "​blipValue1Value2Value3", - "Undefined(1)", + "None(1)", "​gnap" ], "should have these row contents" @@ -9188,7 +9188,7 @@ QUnit.module('Views', { groupBy: ['date:month'], }); - assert.strictEqual(list.$('tbody').text(), "January 2017 (1)Undefined (3)", + assert.strictEqual(list.$('tbody').text(), "January 2017 (1)None (3)", "the group names should be correct"); list.destroy(); @@ -10981,14 +10981,14 @@ QUnit.module('Views', { 'should focus the "Add a line" button'); await testUtils.fields.triggerKeydown($(document.activeElement), 'down'); - assert.strictEqual(document.activeElement.textContent, 'false (1)', + assert.strictEqual(document.activeElement.textContent, 'No (1)', 'focus should be on second group header'); assert.strictEqual(list.$('tr.o_data_row').length, 3, 'should have 3 rows displayed'); await testUtils.fields.triggerKeydown($(document.activeElement), 'enter'); assert.strictEqual(list.$('tr.o_data_row').length, 4, 'should have 4 rows displayed'); - assert.strictEqual(document.activeElement.textContent, 'false (1)', + assert.strictEqual(document.activeElement.textContent, 'No (1)', 'focus should still be on second group header'); await testUtils.fields.triggerKeydown($(document.activeElement), 'down'); @@ -11037,12 +11037,12 @@ QUnit.module('Views', { 'second field of first record should be focused'); await testUtils.fields.triggerKeydown($(document.activeElement), 'up'); - assert.strictEqual(document.activeElement.textContent, 'true (3)', + assert.strictEqual(document.activeElement.textContent, 'Yes (3)', 'focus should be on first group header'); await testUtils.fields.triggerKeydown($(document.activeElement), 'enter'); assert.strictEqual(list.$('tr.o_data_row').length, 2, 'should have 2 rows displayed (first group should be closed)'); - assert.strictEqual(document.activeElement.textContent, 'true (3)', + assert.strictEqual(document.activeElement.textContent, 'Yes (3)', 'focus should still be on first group header'); assert.strictEqual(list.$('tr.o_data_row').length, 2, @@ -11050,27 +11050,27 @@ QUnit.module('Views', { await testUtils.fields.triggerKeydown($(document.activeElement), 'right'); assert.strictEqual(list.$('tr.o_data_row').length, 5, 'should have 5 rows displayed'); - assert.strictEqual(document.activeElement.textContent, 'true (3)', + assert.strictEqual(document.activeElement.textContent, 'Yes (3)', 'focus is still in header'); await testUtils.fields.triggerKeydown($(document.activeElement), 'right'); assert.strictEqual(list.$('tr.o_data_row').length, 5, 'should have 5 rows displayed'); - assert.strictEqual(document.activeElement.textContent, 'true (3)', + assert.strictEqual(document.activeElement.textContent, 'Yes (3)', 'focus is still in header'); await testUtils.fields.triggerKeydown($(document.activeElement), 'left'); assert.strictEqual(list.$('tr.o_data_row').length, 2, 'should have 2 rows displayed'); - assert.strictEqual(document.activeElement.textContent, 'true (3)', + assert.strictEqual(document.activeElement.textContent, 'Yes (3)', 'focus is still in header'); await testUtils.fields.triggerKeydown($(document.activeElement), 'left'); assert.strictEqual(list.$('tr.o_data_row').length, 2, 'should have 2 rows displayed'); - assert.strictEqual(document.activeElement.textContent, 'true (3)', + assert.strictEqual(document.activeElement.textContent, 'Yes (3)', 'focus is still in header'); await testUtils.fields.triggerKeydown($(document.activeElement), 'down'); - assert.strictEqual(document.activeElement.textContent, 'false (2)', + assert.strictEqual(document.activeElement.textContent, 'No (2)', 'focus should now be on second group header'); await testUtils.fields.triggerKeydown($(document.activeElement), 'down'); assert.strictEqual(document.activeElement.tagName, 'TD', @@ -11188,7 +11188,7 @@ QUnit.module('Views', { assert.containsOnce(list, 'tbody:nth(3) .o_data_row'); await testUtils.dom.click(list.$('.o_group_field_row_add a:eq(1)')); // create row in second group - assert.strictEqual(list.$('.o_group_name:eq(1)').text(), 'false (2)', + assert.strictEqual(list.$('.o_group_name:eq(1)').text(), 'No (2)', "group should have correct name and count"); assert.containsN(list, 'tbody:nth(3) .o_data_row', 2); assert.hasClass(list.$('.o_data_row:nth(3)'), 'o_selected_row'); diff --git a/addons/web/static/tests/views/pivot_view_tests.js b/addons/web/static/tests/views/pivot_view_tests.js index 2ca8c08afa5..73a5ea14baa 100644 --- a/addons/web/static/tests/views/pivot_view_tests.js +++ b/addons/web/static/tests/views/pivot_view_tests.js @@ -2102,7 +2102,7 @@ QUnit.module("Views", (hooks) => { await toggleMenuItem(webClient, "Bar"); assert.strictEqual( webClient.el.querySelector("tbody .o_pivot_header_cell_closed").textContent, - "true" + "Yes" ); // remove filter @@ -2110,7 +2110,7 @@ QUnit.module("Views", (hooks) => { assert.strictEqual( webClient.el.querySelector("tbody .o_pivot_header_cell_closed").textContent, - "true" + "Yes" ); }); @@ -2155,7 +2155,7 @@ QUnit.module("Views", (hooks) => { await toggleMenuItem(webClient, "Bar"); assert.strictEqual( webClient.el.querySelector("tbody .o_pivot_header_cell_closed").textContent, - "true" + "Yes" ); // remove groupBy @@ -2280,7 +2280,7 @@ QUnit.module("Views", (hooks) => { assert.strictEqual( webClient.el.querySelector("thead .o_pivot_header_cell_closed").textContent, - "true" + "Yes" ); // desactivate the unique existing favorite @@ -2293,7 +2293,7 @@ QUnit.module("Views", (hooks) => { assert.strictEqual( webClient.el.querySelector("thead .o_pivot_header_cell_closed").textContent, - "true" + "Yes" ); // Let's get rid of the rows and columns groupBy @@ -2321,7 +2321,7 @@ QUnit.module("Views", (hooks) => { assert.strictEqual( webClient.el.querySelector("thead .o_pivot_header_cell_closed").textContent, - "true" + "Yes" ); } ); @@ -4448,7 +4448,7 @@ QUnit.module("Views", (hooks) => { }; serverData.models.partner.records[0].favorite_animal = "Dog"; serverData.models.partner.records[1].favorite_animal = "false"; - serverData.models.partner.records[2].favorite_animal = "Undefined"; + serverData.models.partner.records[2].favorite_animal = "None"; patchDate(2016, 11, 20, 1, 0, 0); const pivot = await makeView({ @@ -4468,7 +4468,7 @@ QUnit.module("Views", (hooks) => { ); assert.deepEqual( [...pivot.el.querySelectorAll("tbody th")].map((th) => th.innerText), - ["Total", "Dog", "false", "Undefined", "Undefined"], + ["Total", "Dog", "false", "None", "None"], "The row headers should be as expected" ); } @@ -4545,7 +4545,7 @@ QUnit.module("Views", (hooks) => { ); assert.deepEqual( [...pivot.el.querySelectorAll("tbody th")].map((th) => th.innerText), - ["Total", "Company", "true", "individual", "true", "Undefined"], + ["Total", "Company", "Yes", "individual", "Yes", "No"], "The row headers should be as expected" ); }