diff options
| author | Mathieu Duckerts-Antoine <dam@odoo.com> | 2018-06-11 15:45:30 +0200 |
|---|---|---|
| committer | Géry Debongnie <ged@odoo.com> | 2018-06-12 09:22:20 +0200 |
| commit | e1aac71769c8d07a358b2d8717efa28248e18a34 (patch) | |
| tree | ba63c14ad7aee42fc1e5fbd9b9b25f31ef1e69cc /addons/web/static/src/js/views/graph | |
| parent | 7bf5dd687be3919f6add10b1ac59a9cdee824632 (diff) | |
[IMP] web: add support for interval selection in groupbys
In this commit, we extend the search view to allow the selection
of some intervals for date or datetime fields in groupby menu.
The valid intervals are day, week, month, quarter, and year.
It is also possible to add a button 'Group By' in the control panel
owned by a graph view in case it is declared 'embedded' (e.g. in a
dashboard view).
Note that have three new generic reusable widgets have been introduced
in this commit: DropdownMenu, GroupByMenu, and FiltersMenu.
Diffstat (limited to 'addons/web/static/src/js/views/graph')
| -rw-r--r-- | addons/web/static/src/js/views/graph/graph_controller.js | 53 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/graph/graph_model.js | 11 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/graph/graph_view.js | 24 |
3 files changed, 77 insertions, 11 deletions
diff --git a/addons/web/static/src/js/views/graph/graph_controller.js b/addons/web/static/src/js/views/graph/graph_controller.js index 77e3f1e7a40..e9f933023b1 100644 --- a/addons/web/static/src/js/views/graph/graph_controller.js +++ b/addons/web/static/src/js/views/graph/graph_controller.js @@ -4,13 +4,15 @@ odoo.define('web.GraphController', function (require) { * Odoo Graph view *---------------------------------------------------------*/ -var AbstractController = require('web.AbstractController'); var core = require('web.core'); +var AbstractController = require('web.AbstractController'); +var GroupByMenuInterfaceMixin = require('web.GroupByMenuInterfaceMixin'); var qweb = core.qweb; -var GraphController = AbstractController.extend({ +var GraphController = AbstractController.extend(GroupByMenuInterfaceMixin,{ className: 'o_graph', + /** * @override * @param {Widget} parent @@ -18,10 +20,23 @@ var GraphController = AbstractController.extend({ * @param {GraphRenderer} renderer * @param {Object} params * @param {string[]} params.measures + * @param {boolean} params.isEmbedded + * @param {string[]} params.groupableFields, */ init: function (parent, model, renderer, params) { + GroupByMenuInterfaceMixin.init.call(this); this._super.apply(this, arguments); this.measures = params.measures; + // this parameter condition the appearance of a 'Group By' + // button in the control panel owned by the graph view. + this.isEmbedded = params.isEmbedded; + // this parameter determines what is the list of fields + // that may be used within the groupby menu available when + // the view is embedded + this.groupableFields = params.groupableFields; + // extends custom_events key. This allow the controller + // to listen to information comming from the groupby menu. + // this is used when the view is embedded. }, /** * @todo check if this can be removed (mostly duplicate with @@ -53,6 +68,12 @@ var GraphController = AbstractController.extend({ graph_measure: state.measure, graph_mode: state.mode, graph_groupbys: state.groupedBy, + // this parameter is not used anywher for now + // the idea would be to seperate intervals from + // fieldnames in groupbys. This could be done + // in graph view only or everywhere but this is + // a big refactoring. + graph_intervalMapping: state.intervalMapping, }; }, /** @@ -66,13 +87,18 @@ var GraphController = AbstractController.extend({ */ renderButtons: function ($node) { if ($node) { - var context = {measures: _.pairs(_.omit(this.measures, '__count__'))}; + var context = { + measures: _.pairs(_.omit(this.measures, '__count__')), + }; this.$buttons = $(qweb.render('GraphView.buttons', context)); this.$measureList = this.$buttons.find('.o_graph_measures_list'); this.$buttons.find('button').tooltip(); this.$buttons.click(this._onButtonClick.bind(this)); this._updateButtons(); this.$buttons.appendTo($node); + if (this.isEmbedded) { + this._addGroupByMenu($node, this.groupableFields); + } } }, @@ -80,10 +106,22 @@ var GraphController = AbstractController.extend({ // Private //-------------------------------------------------------------------------- + /* + * override + * + * @private + * @param {string[]} groupbys + */ + _setGroupby: function (groupbys) { + this.update({groupBy: groupbys}); + }, + /** * @todo remove this and directly calls update. Update should be overridden * and modified to call _updateButtons * + * private + * * @param {string} mode one of 'pie', 'line' or 'bar' */ _setMode: function (mode) { @@ -102,6 +140,8 @@ var GraphController = AbstractController.extend({ }); }, /** + * override + * * @private */ _update: function () { @@ -133,17 +173,20 @@ var GraphController = AbstractController.extend({ /** * Do what need to be done when a button from the control panel is clicked. * + * @private * @param {MouseEvent} event */ _onButtonClick: function (event) { var $target = $(event.target); + var parent; + var field; if ($target.hasClass('o_graph_button')) { this._setMode($target.data('mode')); } else if ($target.parents('.o_graph_measures_list').length) { event.preventDefault(); event.stopPropagation(); - var parent = $target.parent(); - var field = parent.data('field'); + parent = $target.parent(); + field = parent.data('field'); this._setMeasure(field); } }, diff --git a/addons/web/static/src/js/views/graph/graph_model.js b/addons/web/static/src/js/views/graph/graph_model.js index 2ffbd4c4cf8..dd7d0efa28f 100644 --- a/addons/web/static/src/js/views/graph/graph_model.js +++ b/addons/web/static/src/js/views/graph/graph_model.js @@ -51,6 +51,8 @@ return AbstractModel.extend({ * @param {string[]} params.groupBys a list of valid field names * @param {Object} params.context * @param {string[]} params.domain + * @param {Object} params.intervalMapping object linking fieldNames with intervals. + * this could be useful to simplify the code. For now this parameter is not used. * @returns {Deferred} The deferred does not return a handle, we don't need * to keep track of various entities. */ @@ -62,6 +64,12 @@ return AbstractModel.extend({ this.chart = { data: [], groupedBy: params.groupedBy.length ? params.groupedBy : groupBys, + // this parameter is not used anywhere for now. + // the idea would be to seperate intervals from + // fieldnames in groupbys. This could be done + // in graph view only or everywhere but this is + // a big refactoring. + intervalMapping: params.intervalMapping, measure: params.context.graph_measure || params.measure, mode: params.context.graph_mode || params.mode, domain: params.domain, @@ -97,6 +105,9 @@ return AbstractModel.extend({ if ('groupBy' in params) { this.chart.groupedBy = params.groupBy.length ? params.groupBy : this.initialGroupBys; } + if ('intervalMapping' in params) { + this.chart.intervalMapping = params.intervalMapping; + } if ('measure' in params) { this.chart.measure = params.measure; } 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 54ff6642b15..07c486cf5b7 100644 --- a/addons/web/static/src/js/views/graph/graph_view.js +++ b/addons/web/static/src/js/views/graph/graph_view.js @@ -16,6 +16,9 @@ var GraphRenderer = require('web.GraphRenderer'); var _t = core._t; var _lt = core._lt; +var GROUPABLE_TYPES = + ['many2one', 'char', 'boolean', 'selection', 'date', 'datetime']; + var GraphView = AbstractView.extend({ display_name: _lt('Graph'), icon: 'fa-bar-chart', @@ -43,18 +46,22 @@ var GraphView = AbstractView.extend({ var measure; var groupBys = []; var measures = {__count__: {string: _t("Count"), type: "integer"}}; + var groupableFields = {}; + var intervalMapping = {}; this.fields.__count__ = {string: _t("Count"), type: "integer"}; this.arch.children.forEach(function (field) { - var name = field.attrs.name; - if (field.attrs.interval) { - name += ':' + field.attrs.interval; + var fieldName = field.attrs.name; + var interval = field.attrs.interval; + if (interval) { + intervalMapping[fieldName] = interval; + fieldName = fieldName + ':' + interval; } if (field.attrs.type === 'measure') { - measure = name; - measures[name] = self.fields[name]; + measure = fieldName; + measures[fieldName] = self.fields[fieldName]; } else { - groupBys.push(name); + groupBys.push(fieldName); } }); @@ -64,15 +71,20 @@ var GraphView = AbstractView.extend({ _.contains(params.additionalMeasures, name)) { measures[name] = field; } + if (_.contains(GROUPABLE_TYPES, field.type)) { + groupableFields[name] = field; + } } }); this.controllerParams.measures = measures; + this.controllerParams.groupableFields = groupableFields; this.rendererParams.stacked = this.arch.attrs.stacked !== "False"; this.loadParams.mode = this.arch.attrs.type || 'bar'; this.loadParams.measure = measure || '__count__'; this.loadParams.groupBys = groupBys || []; + this.loadParams.intervalMapping = intervalMapping; this.loadParams.fields = this.fields; }, }); |
