From 2c21301d314e4fd7c16ac88162786c096e9d80bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Hennecart?= Date: Wed, 22 Jul 2020 07:31:08 +0000 Subject: [PATCH 1/2] [IMP] web: manage invisible fields in graph and pivot view PURPOSE Be able to remove some measures from graph / pivot views. Currently fields are automatically added but some of them make no sense. SPECIFICATIONS Add the possibility to not display some fields in the measures dropdown for the graph and pivot views. When a field is not displayed in the measures of a pivot views we remove them also from the list of groupable fields. LINKS Task ID-2288381 Community PR #54774 Enterprise PR odoo/enterprise#11970 Upgrade PR odoo/upgrade#1519 --- .../static/src/js/views/graph/graph_view.js | 16 +++++- .../static/src/js/views/pivot/pivot_view.js | 12 +++-- addons/web/static/tests/views/graph_tests.js | 54 ++++++++++++++++--- addons/web/static/tests/views/pivot_tests.js | 5 +- doc/reference/views.rst | 17 ++++++ 5 files changed, 92 insertions(+), 12 deletions(-) diff --git a/addons/web/static/src/js/views/graph/graph_view.js b/addons/web/static/src/js/views/graph/graph_view.js index 5293409cb8b..759817c898f 100644 --- a/addons/web/static/src/js/views/graph/graph_view.js +++ b/addons/web/static/src/js/views/graph/graph_view.js @@ -43,7 +43,7 @@ var GraphView = AbstractView.extend({ let measure; const measures = {}; const measureStrings = {}; - const groupBys = []; + let groupBys = []; const groupableFields = {}; this.fields.__count__ = { string: _t("Count"), type: 'integer' }; @@ -100,6 +100,20 @@ var GraphView = AbstractView.extend({ } } + // Remove invisible fields from the measures + this.arch.children.forEach(field => { + let fieldName = field.attrs.name; + if (field.attrs.invisible && py.eval(field.attrs.invisible)) { + groupBys = groupBys.filter(groupBy => groupBy !== fieldName); + if (fieldName in groupableFields) { + delete groupableFields[fieldName]; + } + if (!additionalMeasures.includes(fieldName)) { + delete measures[fieldName]; + } + } + }); + const sortedMeasures = Object.values(measures).sort((a, b) => { const descA = a.description.toLowerCase(); const descB = b.description.toLowerCase(); diff --git a/addons/web/static/src/js/views/pivot/pivot_view.js b/addons/web/static/src/js/views/pivot/pivot_view.js index 7c021d6e3c0..ea3ab9c7442 100644 --- a/addons/web/static/src/js/views/pivot/pivot_view.js +++ b/addons/web/static/src/js/views/pivot/pivot_view.js @@ -67,11 +67,15 @@ odoo.define('web.PivotView', function (require) { this.arch.children.forEach(field => { let name = field.attrs.name; - - // Remove invisible fields from the measures + // Remove invisible fields from the measures if not in additionalMeasures if (field.attrs.invisible && py.eval(field.attrs.invisible)) { - delete measures[name]; - return; + if (name in groupableFields) { + delete groupableFields[name]; + } + if (!additionalMeasures.includes(name)) { + delete measures[name]; + return; + } } if (field.attrs.interval) { name += ':' + field.attrs.interval; diff --git a/addons/web/static/tests/views/graph_tests.js b/addons/web/static/tests/views/graph_tests.js index 253c98d706a..fda4c5cb190 100644 --- a/addons/web/static/tests/views/graph_tests.js +++ b/addons/web/static/tests/views/graph_tests.js @@ -97,16 +97,17 @@ QUnit.module('Views', { product_id: {string: "Product", type: "many2one", relation: 'product', store: true}, color_id: {string: "Color", type: "many2one", relation: 'color'}, date: {string: "Date", type: 'date', store: true, sortable: true}, + revenue: {string: "Revenue", type: 'integer', store: true}, }, records: [ - {id: 1, foo: 3, bar: true, product_id: 37, date: "2016-01-01"}, - {id: 2, foo: 53, bar: true, product_id: 37, color_id: 7, date: "2016-01-03"}, - {id: 3, foo: 2, bar: true, product_id: 37, date: "2016-03-04"}, - {id: 4, foo: 24, bar: false, product_id: 37, date: "2016-03-07"}, - {id: 5, foo: 4, bar: false, product_id: 41, date: "2016-05-01"}, + {id: 1, foo: 3, bar: true, product_id: 37, date: "2016-01-01", revenue: 1}, + {id: 2, foo: 53, bar: true, product_id: 37, color_id: 7, date: "2016-01-03", revenue: 2}, + {id: 3, foo: 2, bar: true, product_id: 37, date: "2016-03-04", revenue: 3}, + {id: 4, foo: 24, bar: false, product_id: 37, date: "2016-03-07", revenue: 4}, + {id: 5, foo: 4, bar: false, product_id: 41, date: "2016-05-01", revenue: 5}, {id: 6, foo: 63, bar: false, product_id: 41}, {id: 7, foo: 42, bar: false, product_id: 41}, - {id: 8, foo: 48, bar: false, product_id: 41, date: "2016-04-01"}, + {id: 8, foo: 48, bar: false, product_id: 41, date: "2016-04-01", revenue: 8}, ] }, product: { @@ -1216,6 +1217,47 @@ QUnit.module('Views', { graph.destroy(); }); + QUnit.test('graph view without invisible attribute on field', async function (assert) { + assert.expect(4); + + const graph = await createView({ + View: GraphView, + model: "foo", + data: this.data, + arch: ``, + }); + + await testUtils.dom.click(graph.$('.btn-group:first button')); + assert.containsN(graph, 'li.o_menu_item', 3, + "there should be three menu item in the measures dropdown (count, revenue and foo)"); + assert.containsOnce(graph, 'li.o_menu_item a:contains("Revenue")'); + assert.containsOnce(graph, 'li.o_menu_item a:contains("Foo")'); + assert.containsOnce(graph, 'li.o_menu_item a:contains("Count")'); + + graph.destroy(); + }); + + QUnit.test('graph view with invisible attribute on field', async function (assert) { + assert.expect(2); + + const graph = await createView({ + View: GraphView, + model: "foo", + data: this.data, + arch: ` + + + `, + }); + + await testUtils.dom.click(graph.$('.btn-group:first button')); + assert.containsN(graph, 'li.o_menu_item', 2, + "there should be only two menu item in the measures dropdown (count and foo)"); + assert.containsNone(graph, 'li.o_menu_item a:contains("Revenue")'); + + graph.destroy(); + }); + QUnit.test('graph view sort by measure', async function (assert) { assert.expect(18); diff --git a/addons/web/static/tests/views/pivot_tests.js b/addons/web/static/tests/views/pivot_tests.js index 48e67e8641e..026741ac682 100644 --- a/addons/web/static/tests/views/pivot_tests.js +++ b/addons/web/static/tests/views/pivot_tests.js @@ -192,7 +192,7 @@ QUnit.module('Views', { }); QUnit.test('pivot rendering with invisible attribute on field', async function (assert) { - assert.expect(2); + assert.expect(3); // when invisible, a field should neither be an active measure, // nor be a selectable measure. _.extend(this.data.partner.fields, { @@ -214,6 +214,9 @@ QUnit.module('Views', { assert.containsOnce(pivot, '.o_pivot_measure_row'); // there should be only one measure besides count, as the other one is invisible assert.containsN(pivot, '.o_cp_bottom_left .dropdown-item', 2); + // the invisible field souldn't be in the groupable fields neither + await testUtils.dom.click(pivot.$('.o_pivot_header_cell_closed:first')); + assert.containsNone(pivot, '.o_pivot_field_menu a[data-field="foo2"]'); pivot.destroy(); }); diff --git a/doc/reference/views.rst b/doc/reference/views.rst index a336af9dbf6..1ad8253b3f1 100644 --- a/doc/reference/views.rst +++ b/doc/reference/views.rst @@ -497,6 +497,19 @@ attributes: A field that can be aggregated. This field will be used to compute the values for each cell. If not set, the cohort view will count the number of occurrences. +```` (optional) + allows to specify a particular field in order to manage it from the available measures, it's + main use is for hiding a field from the selectable measures: + * ``name`` (required) + the name of the field to use in the view. + * ``string`` (optional) + the name that would be used to display the field in the cohort view, overrides the + default python String attribute of the field. + * ``invisible`` (optional) + if true, the field will not appear either in the active measures nor in the selectable + measures (useful for fields that do not make sense aggregated, such as fields in different + units, e.g. € and $). + .. _reference/views/dashboard: Dashboard @@ -1109,6 +1122,10 @@ following attributes: ``title`` (optional) string displayed on the top of the graph. +``invisible`` (optional) + if true, the field will not appear either in the active measures nor in the + selectable measures. + ``type`` indicates whether the field should be used as a grouping criteria or as an aggregated value within a group. Possible values are: From d8635586630ff8c47fff26ca9c6a20a6bb459489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Hennecart?= Date: Thu, 13 Aug 2020 07:45:57 +0000 Subject: [PATCH 2/2] [IMP] crm(_iap_lead_website), website_crm_partner_assign: remove incoherent measures for pivot/graph PURPOSE Adapt CRM views now that some measures can be set invisible. SPECIFICATIONS Adapt the views and implementing the new invisible attribute on some fields. It allows to hide unnecessary measures. In this commit we remove some measures in inheriting CRM apps * crm: do not use color as measure; * crm_iap_lead_website: do not use reveal_iap_credits as measure; * website_crm_partner_assign: do not use partner_latitude and partner longitude as measures; LINKS Task ID-2288381 Community PR #54774 Enterprise PR odoo/enterprise#11970 Upgrade PR odoo/upgrade#1519 --- .../report/crm_opportunity_report_views.xml | 2 + addons/crm/views/crm_lead_views.xml | 1 + .../views/crm_lead_view.xml | 44 +++++++++++++++++ .../views/crm_lead_views.xml | 47 +++++++++++++++++++ 4 files changed, 94 insertions(+) diff --git a/addons/crm/report/crm_opportunity_report_views.xml b/addons/crm/report/crm_opportunity_report_views.xml index b97a0f6fc14..b6dbedda40b 100644 --- a/addons/crm/report/crm_opportunity_report_views.xml +++ b/addons/crm/report/crm_opportunity_report_views.xml @@ -36,6 +36,7 @@ + @@ -48,6 +49,7 @@ + diff --git a/addons/crm/views/crm_lead_views.xml b/addons/crm/views/crm_lead_views.xml index 0f0d55f1e75..1291ef671b9 100644 --- a/addons/crm/views/crm_lead_views.xml +++ b/addons/crm/views/crm_lead_views.xml @@ -746,6 +746,7 @@ + diff --git a/addons/crm_iap_lead_website/views/crm_lead_view.xml b/addons/crm_iap_lead_website/views/crm_lead_view.xml index f63d55f8a47..5bb287a5163 100644 --- a/addons/crm_iap_lead_website/views/crm_lead_view.xml +++ b/addons/crm_iap_lead_website/views/crm_lead_view.xml @@ -22,4 +22,48 @@ + + + crm.lead.view.pivot.inherit.lead.website + crm.lead + + + + + + + + + + crm.lead.view.graph.inherit.lead.website + crm.lead + + + + + + + + + + crm.lead.view.graph.report.opportunity.inherit.lead.website + crm.lead + + + + + + + + + + crm.lead.view.graph.report.lead.inherit.lead.website + crm.lead + + + + + + + diff --git a/addons/website_crm_partner_assign/views/crm_lead_views.xml b/addons/website_crm_partner_assign/views/crm_lead_views.xml index 89a564c0985..4645c09afda 100644 --- a/addons/website_crm_partner_assign/views/crm_lead_views.xml +++ b/addons/website_crm_partner_assign/views/crm_lead_views.xml @@ -89,4 +89,51 @@ + + crm.lead.view.pivot.inherit.partner.assign + crm.lead + + + + + + + + + + + crm.lead.view.graph.inherit.partner.assign + crm.lead + + + + + + + + + + + crm.lead.view.graph.report.opportunity.inherit.partner.assign + crm.lead + + + + + + + + + + + crm.lead.view.graph.report.lead.inherit.partner.assign + crm.lead + + + + + + + +