diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/web/static/src/js/views/pivot/pivot_view.js | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/web/static/src/js/views/pivot/pivot_view.js')
| -rw-r--r-- | addons/web/static/src/js/views/pivot/pivot_view.js | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/addons/web/static/src/js/views/pivot/pivot_view.js b/addons/web/static/src/js/views/pivot/pivot_view.js new file mode 100644 index 00000000..ea3ab9c7 --- /dev/null +++ b/addons/web/static/src/js/views/pivot/pivot_view.js @@ -0,0 +1,158 @@ +odoo.define('web.PivotView', function (require) { + "use strict"; + + /** + * The Pivot View is a view that represents data in a 'pivot grid' form. It + * aggregates data on 2 dimensions and displays the result, allows the user to + * 'zoom in' data. + */ + + const AbstractView = require('web.AbstractView'); + const config = require('web.config'); + const core = require('web.core'); + const PivotModel = require('web.PivotModel'); + const PivotController = require('web.PivotController'); + const PivotRenderer = require('web.PivotRenderer'); + const RendererWrapper = require('web.RendererWrapper'); + + const _t = core._t; + const _lt = core._lt; + + const searchUtils = require('web.searchUtils'); + const GROUPABLE_TYPES = searchUtils.GROUPABLE_TYPES; + + const PivotView = AbstractView.extend({ + display_name: _lt('Pivot'), + icon: 'fa-table', + config: Object.assign({}, AbstractView.prototype.config, { + Model: PivotModel, + Controller: PivotController, + Renderer: PivotRenderer, + }), + viewType: 'pivot', + searchMenuTypes: ['filter', 'groupBy', 'comparison', 'favorite'], + + /** + * @override + * @param {Object} params + * @param {Array} params.additionalMeasures + */ + init: function (viewInfo, params) { + this._super.apply(this, arguments); + + const activeMeasures = []; // Store the defined active measures + const colGroupBys = []; // Store the defined group_by used on cols + const rowGroupBys = []; // Store the defined group_by used on rows + const measures = {}; // All the available measures + const groupableFields = {}; // The fields which can be used to group data + const widgets = {}; // Wigdets defined in the arch + const additionalMeasures = params.additionalMeasures || []; + + this.fields.__count = { string: _t("Count"), type: "integer" }; + + //Compute the measures and the groupableFields + Object.keys(this.fields).forEach(name => { + const field = this.fields[name]; + if (name !== 'id' && field.store === true) { + if (['integer', 'float', 'monetary'].includes(field.type) || additionalMeasures.includes(name)) { + measures[name] = field; + } + if (GROUPABLE_TYPES.includes(field.type)) { + groupableFields[name] = field; + } + } + }); + measures.__count = { string: _t("Count"), type: "integer" }; + + + this.arch.children.forEach(field => { + let name = field.attrs.name; + // Remove invisible fields from the measures if not in additionalMeasures + if (field.attrs.invisible && py.eval(field.attrs.invisible)) { + if (name in groupableFields) { + delete groupableFields[name]; + } + if (!additionalMeasures.includes(name)) { + delete measures[name]; + return; + } + } + if (field.attrs.interval) { + name += ':' + field.attrs.interval; + } + if (field.attrs.widget) { + widgets[name] = field.attrs.widget; + } + // add active measures to the measure list. This is very rarely + // necessary, but it can be useful if one is working with a + // functional field non stored, but in a model with an overrided + // read_group method. In this case, the pivot view could work, and + // the measure should be allowed. However, be careful if you define + // a measure in your pivot view: non stored functional fields will + // probably not work (their aggregate will always be 0). + if (field.attrs.type === 'measure' && !(name in measures)) { + measures[name] = this.fields[name]; + } + if (field.attrs.string && name in measures) { + measures[name].string = field.attrs.string; + } + if (field.attrs.type === 'measure' || 'operator' in field.attrs) { + activeMeasures.push(name); + measures[name] = this.fields[name]; + } + if (field.attrs.type === 'col') { + colGroupBys.push(name); + } + if (field.attrs.type === 'row') { + rowGroupBys.push(name); + } + }); + if ((!activeMeasures.length) || this.arch.attrs.display_quantity) { + activeMeasures.splice(0, 0, '__count'); + } + + this.loadParams.measures = activeMeasures; + this.loadParams.colGroupBys = config.device.isMobile ? [] : colGroupBys; + this.loadParams.rowGroupBys = rowGroupBys; + this.loadParams.fields = this.fields; + this.loadParams.default_order = params.default_order || this.arch.attrs.default_order; + this.loadParams.groupableFields = groupableFields; + + const disableLinking = !!(this.arch.attrs.disable_linking && + JSON.stringify(this.arch.attrs.disable_linking)); + + this.rendererParams.widgets = widgets; + this.rendererParams.disableLinking = disableLinking; + + this.controllerParams.disableLinking = disableLinking; + this.controllerParams.title = params.title || this.arch.attrs.string || _t("Untitled"); + this.controllerParams.measures = measures; + + // retrieve form and list view ids from the action to open those views + // when a data cell of the pivot view is clicked + this.controllerParams.views = [ + _findView(params.actionViews, 'list'), + _findView(params.actionViews, 'form'), + ]; + + function _findView(views, viewType) { + const view = views.find(view => { + return view.type === viewType; + }); + return [view ? view.viewID : false, viewType]; + } + }, + + /** + * + * @override + */ + getRenderer(parent, state) { + state = Object.assign(state || {}, this.rendererParams); + return new RendererWrapper(parent, this.config.Renderer, state); + }, + }); + + return PivotView; + +}); |
